Repository: secdev/scapy

Issue:
traceroute6(): wrong order with Python
With Python3, routers addresses are displayed in the wrong order (likely an alphabetic one):

In [66]: traceroute6("www.free.fr", minttl=8, maxttl=12)
Begin emission:
............Finished to send 5 packets.
***.*.....
Received 22 packets, got 4 answers, remaining 1 packets
   2a01:0e0c:0001:0000:0000:0000:0000:0001   :tcphttp 
10 2001:7f8:1::a501:2322:1                    3       
11 2a01:e04:3::5                              3       
8  ::ffff:194.79.137.174                      3       
9  2001:7f8:1::a501:3193:1                    3


Discussion:
I'll have a look, same for IPv4 traceroute results actually.
PR on its way, I'm writing a test.

Resolving patch:
diff --git a/scapy/utils.py b/scapy/utils.py
--- a/scapy/utils.py
+++ b/scapy/utils.py
@@ -1411,40 +1411,40 @@ def _crop(x, width):
     rt = "\n".join([fmt % x for x in rtlst])
     return rt
 
-def __make_table(yfmtfunc, fmtfunc, endline, list, fxyz, sortx=None, sorty=None, seplinefunc=None):
+def __make_table(yfmtfunc, fmtfunc, endline, data, fxyz, sortx=None, sorty=None, seplinefunc=None):
     vx = {} 
     vy = {} 
     vz = {}
     vxf = {}
     vyf = {}
     l = 0
-    for e in list:
+    for e in data:
         xx, yy, zz = [str(s) for s in fxyz(e)]
         l = max(len(yy),l)
         vx[xx] = max(vx.get(xx,0), len(xx), len(zz))
         vy[yy] = None
         vz[(xx,yy)] = zz
 
-    vxk = sorted(vx.keys())
-    vyk = sorted(vy.keys())
+    vxk = list(vx)
+    vyk = list(vy)
     if sortx:
-        vxk.sort(sortx)
+        vxk.sort(key=sortx)
     else:
         try:
-            vxk.sort(lambda x,y:int(x)-int(y))
+            vxk.sort(key=int)
         except:
             try:
-                vxk.sort(lambda x,y: cmp(atol(x),atol(y)))
+                vxk.sort(key=atol)
             except:
                 vxk.sort()
     if sorty:
-        vyk.sort(sorty)
+        vyk.sort(key=sorty)
     else:
         try:
-            vyk.sort(lambda x,y:int(x)-int(y))
+            vyk.sort(key=int)
         except:
             try:
-                vyk.sort(lambda x,y: cmp(atol(x),atol(y)))
+                vyk.sort(key=atol)
             except:
                 vyk.sort()
 


Test patch:
diff --git a/test/regression.uts b/test/regression.uts
--- a/test/regression.uts
+++ b/test/regression.uts
@@ -3420,14 +3420,14 @@ p.show()
 + TracerouteResult6
 
 = get_trace()
-ip6_hlim = [("2001:db8::%d" % i, i) for i in six.moves.range(1, 10)]
+ip6_hlim = [("2001:db8::%d" % i, i) for i in six.moves.range(1, 12)]
 
 tr6_packets = [ (IPv6(dst="2001:db8::1", src="2001:db8::254", hlim=hlim)/UDP()/"scapy",
                  IPv6(dst="2001:db8::254", src=ip)/ICMPv6TimeExceeded()/IPerror6(dst="2001:db8::1", src="2001:db8::254", hlim=0)/UDPerror()/"scapy")
                    for (ip, hlim) in ip6_hlim ]
 
 tr6 = TracerouteResult6(tr6_packets)
-tr6.get_trace() == {'2001:db8::1': {1: ('2001:db8::1', False), 2: ('2001:db8::2', False), 3: ('2001:db8::3', False), 4: ('2001:db8::4', False), 5: ('2001:db8::5', False), 6: ('2001:db8::6', False), 7: ('2001:db8::7', False), 8: ('2001:db8::8', False), 9: ('2001:db8::9', False)}}
+tr6.get_trace() == {'2001:db8::1': {1: ('2001:db8::1', False), 2: ('2001:db8::2', False), 3: ('2001:db8::3', False), 4: ('2001:db8::4', False), 5: ('2001:db8::5', False), 6: ('2001:db8::6', False), 7: ('2001:db8::7', False), 8: ('2001:db8::8', False), 9: ('2001:db8::9', False), 10: ('2001:db8::10', False), 11: ('2001:db8::11', False)}}
 
 = show()
 def test_show():
@@ -3436,15 +3436,17 @@ def test_show():
         tr6.show()
         result = cmco.get_output()
     expected = "  2001:db8::1                               :udpdomain \n"
-    expected += "1 2001:db8::1                                3         \n"
-    expected += "2 2001:db8::2                                3         \n"
-    expected += "3 2001:db8::3                                3         \n"
-    expected += "4 2001:db8::4                                3         \n"
-    expected += "5 2001:db8::5                                3         \n"
-    expected += "6 2001:db8::6                                3         \n"
-    expected += "7 2001:db8::7                                3         \n"
-    expected += "8 2001:db8::8                                3         \n"
-    expected += "9 2001:db8::9                                3         \n"
+    expected += "1  2001:db8::1                                3         \n"
+    expected += "2  2001:db8::2                                3         \n"
+    expected += "3  2001:db8::3                                3         \n"
+    expected += "4  2001:db8::4                                3         \n"
+    expected += "5  2001:db8::5                                3         \n"
+    expected += "6  2001:db8::6                                3         \n"
+    expected += "7  2001:db8::7                                3         \n"
+    expected += "8  2001:db8::8                                3         \n"
+    expected += "9  2001:db8::9                                3         \n"
+    expected += "10 2001:db8::10                               3         \n"
+    expected += "11 2001:db8::11                               3         \n"
     index_result = result.index("\n1")
     index_expected = expected.index("\n1")
     assert(result[index_result:] == expected[index_expected:])