[tor-commits] [ooni-probe/master] Implement UDP and TCP traceroute

art at torproject.org art at torproject.org
Thu May 31 03:01:42 UTC 2012


commit 507d0d141092de53a5a5b9a1a75cb21a421f403d
Author: Arturo Filastò <hellais at torproject.org>
Date:   Thu May 3 02:00:29 2012 +0200

    Implement UDP and TCP traceroute
---
 lib/traceroute.py   |    4 +-
 lib/txtraceroute.py |   87 +++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 83 insertions(+), 8 deletions(-)

diff --git a/lib/traceroute.py b/lib/traceroute.py
index 98015ea..c02722a 100644
--- a/lib/traceroute.py
+++ b/lib/traceroute.py
@@ -18,7 +18,7 @@ def run(target, src_port, dst_port):
     settings = dict(hop_callback=None,
                     timeout=2,
                     max_tries=3,
-                    max_hops=30)
+                    max_hops=30, proto="tcp")
     try:
         target = socket.gethostbyname(target)
     except Exception, e:
@@ -29,4 +29,4 @@ def run(target, src_port, dst_port):
     reactor.run()
     return res
 
-print run("google.com")
+print run("8.8.8.8", 80, 80)
diff --git a/lib/txtraceroute.py b/lib/txtraceroute.py
index f74dfb1..e18b558 100644
--- a/lib/txtraceroute.py
+++ b/lib/txtraceroute.py
@@ -81,6 +81,71 @@ class iphdr(object):
                (self.tos, self.ttl, self.id, self.frag, self.proto,
                 self.length, self.src, self.dst)
 
+class tcphdr(object):
+    def __init__(self, data="", dport=4242, sport=4242):
+        self.seq = 123132
+        self.hlen = 44
+        self.flags = 2
+        self.wsize = 200
+        self.cksum = 123
+        self.options = 0
+        self.mss = 1460
+        self.dport = dport
+        self.sport = sport
+
+    def assemble(self):
+        header = struct.pack("!HHL", self.sport, self.dport, self.seq)
+        header += '\00\00\00\00'
+        header += struct.pack("!HHH", (self.hlen & 0xff) << 10 | (self.flags &
+            0xff), self.wsize, self.cksum)
+        # XXX There is something wrong here fixme
+        options = struct.pack("!LBBBBBB", self.mss, 1, 3, 3, 1, 1, 1)
+        options += struct.pack("!BBL", 8, 10, 1209452188)
+        options += '\00'*4
+        options += struct.pack("!BB", 4, 2)
+        options += '\00'
+        return header+options
+
+    @classmethod
+    def checksum(self, data):
+        pass
+
+    def disassemble(self, data):
+        tcp = tcphdr()
+        pkt = struct.unpack("!HHLH", data[:20])
+        tcp.sport, tcp.dport, tcp.seq = pkt[:3]
+        tcp.hlen = (pkt[4] >> 10 ) & 0xff
+        tcp.flags = pkf[4] & 0xff
+        tcp.wsize, tcp.cksum = struct.unpack("!HH", data[20:28])
+        return tcp
+
+class udphdr(object):
+    def __init__(self, data="", dport=4242, sport=4242):
+        self.dport = dport
+        self.sport = sport
+        self.cksum = 0
+        self.length = 0
+        self.data = data
+
+    def assemble(self):
+        self.length = len(self.data) + 8
+        part1 = struct.pack("!HHH", self.sport, self.dport, self.length)
+        cksum = self.checksum(self.data)
+        cksum = struct.pack("!H", cksum)
+        return part1 + cksum + self.data
+
+    @classmethod
+    def checksum(self, data):
+        # XXX implement proper checksum
+        cksum = 0
+        return cksum
+
+    def disassemble(self, data):
+        udp = udphdr()
+        pkt = struct.unpack("!HHHH", data)
+        udp.src_port, udp.dst_port, udp.length, udp.cksum = pkt
+        return udp
+
 class icmphdr(object):
     def __init__(self, data=""):
         self.type = 8
@@ -142,7 +207,8 @@ def reverse_lookup(ip):
 
 
 class Hop(object):
-    def __init__(self, target, ttl):
+    def __init__(self, target, ttl, proto="icmp"):
+        self.proto = proto
         self.found = False
         self.tries = 0
         self.last_try = 0
@@ -156,9 +222,18 @@ class Hop(object):
         self.ip.ttl = ttl
         self.ip.id += ttl
 
-        self.icmp = icmphdr("traceroute")
-        self.icmp.id = self.ip.id
-        self.ip.data = self.icmp.assemble()
+        if proto is "icmp":
+            self.icmp = icmphdr("traceroute")
+            self.icmp.id = self.ip.id
+            self.ip.data = self.icmp.assemble()
+        elif proto is "udp":
+            self.udp = udphdr("blabla")
+            self.ip.data = self.udp.assemble()
+            self.ip.proto = socket.IPPROTO_UDP
+        elif proto is "tcp":
+            self.tcp = tcphdr()
+            self.ip.data = self.tcp.assemble()
+            self.ip.proto = socket.IPPROTO_TCP
 
         self._pkt = self.ip.assemble()
 
@@ -214,7 +289,7 @@ class TracerouteProtocol(object):
         reactor.addWriter(self)
 
         # send 1st probe packet
-        self.out_queue.append(Hop(self.target, 1))
+        self.out_queue.append(Hop(self.target, 1, settings.get("proto")))
 
     def logPrefix(self):
         return "TracerouteProtocol(%s)" % self.target
@@ -253,7 +328,7 @@ class TracerouteProtocol(object):
                 self.deferred.callback(self.hops)
                 self.deferred = None
         else:
-            self.out_queue.append(Hop(self.target, ttl))
+            self.out_queue.append(Hop(self.target, ttl, self.settings.get("proto")))
 
     def doRead(self):
         if not self.waiting or not self.hops:





More information about the tor-commits mailing list