[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [ooni-probe/master] Move the parasitic traceroute function to the experimental tests.
commit 2e5647cf4a5de7ba83c3c12596661f9007c216b5
Author: Arturo Filastò <art@xxxxxxxxx>
Date: Fri Mar 7 13:42:52 2014 +0100
Move the parasitic traceroute function to the experimental tests.
---
ooni/nettests/experimental/parasitictraceroute.py | 157 +++++----------------
ooni/nettests/manipulation/parasitictraceroute.py | 48 -------
2 files changed, 38 insertions(+), 167 deletions(-)
diff --git a/ooni/nettests/experimental/parasitictraceroute.py b/ooni/nettests/experimental/parasitictraceroute.py
index 631c24b..c8aa3ed 100644
--- a/ooni/nettests/experimental/parasitictraceroute.py
+++ b/ooni/nettests/experimental/parasitictraceroute.py
@@ -1,129 +1,48 @@
-# -*- encoding: utf-8 -*-
-#
-# :authors: Arturo Filastò
-# :licence: see LICENSE
-
from twisted.python import usage
-from twisted.internet import defer
-
+from twisted.internet import defer, reactor
from ooni.templates import scapyt
-
-from scapy.all import *
-
from ooni.utils import log
+from ooni.utils.txscapy import ParasiticTraceroute
+from ooni.settings import config
-class UsageOptions(usage.Options):
- optParameters = [['backend', 'b', 'google.com', 'Test backend to use'],
- ['timeout', 't', 5, 'The timeout for the traceroute test'],
- ['maxttl', 'm', 64, 'The maximum value of ttl to set on packets'],
- ['dstport', 'd', 80, 'Set the destination port of the traceroute test'],
- ['srcport', 'p', None, 'Set the source port to a specific value']]
+from scapy.all import TCPerror, IPerror
-class ParasiticalTracerouteTest(scapyt.BaseScapyTest):
- name = "Parasitic TCP Traceroute Test"
- author = "Arturo Filastò"
- version = "0.1"
+class ParasiticTracerouteTest(scapyt.BaseScapyTest):
+ name = "Parasitic Traceroute Test"
+ description = "Injects duplicate TCP packets with varying TTL values by sniffing traffic"
+ version = '0.1'
- usageOptions = UsageOptions
+ samplePeriod = 40
def setUp(self):
- def get_sport():
- if self.localOptions['srcport']:
- return int(self.localOptions['srcport'])
+ self.report['parasitic_traceroute'] = {}
+
+ def test_parasitic_traceroute(self):
+ self.pt = ParasiticTraceroute()
+ config.scapyFactory.registerProtocol(self.pt)
+ d = defer.Deferred()
+ reactor.callLater(self.samplePeriod, d.callback, self.pt)
+ return d
+
+ def postProcessor(self, *args, **kwargs):
+ self.pt.stopListening()
+ self.report['received_packets'] = self.pt.received_packets
+
+ for packet in self.pt.received_packets:
+ k = (packet[IPerror].id, packet[TCPerror].sport, packet[TCPerror].dport, packet[TCPerror].seq)
+ if k in self.pt.matched_packets:
+ ttl = self.pt.matched_packets[k]['ttl']
else:
- return random.randint(1024, 65535)
- self.get_sport = get_sport
-
- self.dst_ip = socket.gethostbyaddr(self.localOptions['backend'])[2][0]
-
- self.dport = int(self.localOptions['dstport'])
- self.max_ttl = int(self.localOptions['maxttl'])
-
- @defer.inlineCallbacks
- def test_parasitic_tcp_traceroute(self):
- """
- Establishes a TCP stream, then sequentially sends TCP packets with
- increasing TTL until we reach the ttl of the destination.
-
- Requires the backend to respond with an ACK to our SYN packet (i.e.
- the port must be open)
-
- XXX this currently does not work properly. The problem lies in the fact
- that we are currently using the scapy layer 3 socket. This socket makes
- packets received be trapped by the kernel TCP stack, therefore when we
- send out a SYN and get back a SYN-ACK the kernel stack will reply with
- a RST because it did not send a SYN.
-
- The quick fix to this would be to establish a TCP stream using socket
- calls and then "cannibalizing" the TCP session with scapy.
-
- The real fix is to make scapy use libpcap instead of raw sockets
- obviously as we previously did... arg.
- """
- sport = self.get_sport()
- dport = self.dport
- ipid = int(RandShort())
-
- ip_layer = IP(dst=self.dst_ip,
- id=ipid, ttl=self.max_ttl)
-
- syn = ip_layer/TCP(sport=sport, dport=dport, flags="S", seq=0)
-
- log.msg("Sending...")
- syn.show2()
-
- synack = yield self.sr1(syn)
-
- log.msg("Got response...")
- synack.show2()
-
- if not synack:
- log.err("Got no response. Try increasing max_ttl")
- return
-
- if synack[TCP].flags == 11:
- log.msg("Got back a FIN ACK. The destination port is closed")
- return
-
- elif synack[TCP].flags == 18:
- log.msg("Got a SYN ACK. All is well.")
- else:
- log.err("Got an unexpected result")
- return
-
- ack = ip_layer/TCP(sport=synack.dport,
- dport=dport, flags="A",
- seq=synack.ack, ack=synack.seq + 1)
-
- yield self.send(ack)
-
- self.report['hops'] = []
- # For the time being we make the assumption that we are NATted and
- # that the NAT will forward the packet to the destination even if the TTL has
- for ttl in range(1, self.max_ttl):
- log.msg("Sending packet with ttl of %s" % ttl)
- ip_layer.ttl = ttl
- empty_tcp_packet = ip_layer/TCP(sport=synack.dport,
- dport=dport, flags="A",
- seq=synack.ack, ack=synack.seq + 1)
-
- answer = yield self.sr1(empty_tcp_packet)
- if not answer:
- log.err("Got no response for ttl %s" % ttl)
- continue
-
- try:
- icmp = answer[ICMP]
- report = {'ttl': empty_tcp_packet.ttl,
- 'address': answer.src,
- 'rtt': answer.time - empty_tcp_packet.time
- }
- log.msg("%s: %s" % (dport, report))
- self.report['hops'].append(report)
-
- except IndexError:
- if answer.src == self.dst_ip:
- answer.show()
- log.msg("Reached the destination. We have finished the traceroute")
- return
+ ttl = 'unknown'
+ hop = (ttl, packet.src)
+ path = 'hops_%s' % packet[IPerror].dst
+ if path in self.report['parasitic_traceroute']:
+ self.report['parasitic_traceroute'][path].append(hop)
+ else:
+ self.report['parasitic_traceroute'][path] = [hop]
+ for p in self.report['parasitic_traceroute'].keys():
+ self.report['parasitic_traceroute'][p].sort(key=lambda x: x[0])
+
+ self.report['sent_packets'] = self.pt.sent_packets
+ return self.report
diff --git a/ooni/nettests/manipulation/parasitictraceroute.py b/ooni/nettests/manipulation/parasitictraceroute.py
deleted file mode 100644
index c8aa3ed..0000000
--- a/ooni/nettests/manipulation/parasitictraceroute.py
+++ /dev/null
@@ -1,48 +0,0 @@
-from twisted.python import usage
-from twisted.internet import defer, reactor
-from ooni.templates import scapyt
-from ooni.utils import log
-from ooni.utils.txscapy import ParasiticTraceroute
-from ooni.settings import config
-
-from scapy.all import TCPerror, IPerror
-
-class ParasiticTracerouteTest(scapyt.BaseScapyTest):
- name = "Parasitic Traceroute Test"
- description = "Injects duplicate TCP packets with varying TTL values by sniffing traffic"
- version = '0.1'
-
- samplePeriod = 40
-
- def setUp(self):
- self.report['parasitic_traceroute'] = {}
-
- def test_parasitic_traceroute(self):
- self.pt = ParasiticTraceroute()
- config.scapyFactory.registerProtocol(self.pt)
- d = defer.Deferred()
- reactor.callLater(self.samplePeriod, d.callback, self.pt)
- return d
-
- def postProcessor(self, *args, **kwargs):
- self.pt.stopListening()
- self.report['received_packets'] = self.pt.received_packets
-
- for packet in self.pt.received_packets:
- k = (packet[IPerror].id, packet[TCPerror].sport, packet[TCPerror].dport, packet[TCPerror].seq)
- if k in self.pt.matched_packets:
- ttl = self.pt.matched_packets[k]['ttl']
- else:
- ttl = 'unknown'
- hop = (ttl, packet.src)
- path = 'hops_%s' % packet[IPerror].dst
- if path in self.report['parasitic_traceroute']:
- self.report['parasitic_traceroute'][path].append(hop)
- else:
- self.report['parasitic_traceroute'][path] = [hop]
- for p in self.report['parasitic_traceroute'].keys():
- self.report['parasitic_traceroute'][p].sort(key=lambda x: x[0])
-
- self.report['sent_packets'] = self.pt.sent_packets
- return self.report
-
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits