[tor-commits] [ooni-probe/master] Cleaned up report generation and results/logging display.

isis at torproject.org isis at torproject.org
Tue Dec 18 05:53:46 UTC 2012


commit d6a73bad105ece35794ad3709f17d1740275554c
Author: Isis Lovecruft <isis at torproject.org>
Date:   Tue Nov 20 14:02:23 2012 +0000

    Cleaned up report generation and results/logging display.
---
 nettests/bridge_reachability/tcpsyn.py |  137 +++++++++++++++-----------------
 1 files changed, 64 insertions(+), 73 deletions(-)

diff --git a/nettests/bridge_reachability/tcpsyn.py b/nettests/bridge_reachability/tcpsyn.py
index bc79a93..e261a83 100644
--- a/nettests/bridge_reachability/tcpsyn.py
+++ b/nettests/bridge_reachability/tcpsyn.py
@@ -21,10 +21,10 @@ from twisted.python   import usage
 from twisted.internet import reactor, defer, address
 from ooni             import nettest
 from ooni.utils       import net, log
+from ooni.utils.otime import timestamp
 
 try:
     from scapy.all          import TCP, IP
-    from scapy.all          import sr1
     from ooni.utils         import txscapy
 except:
     log.msg("This test requires scapy, see www.secdev.org/projects/scapy")
@@ -32,11 +32,16 @@ except:
 
 class UsageOptions(usage.Options):
     """Options for TCPSynTest."""
-    optParameters = [['dst', 'd', None, 'Host IP to ping'],
-                     ['port', 'p', None, 'Host port'],
-                     ['count', 'c', 3, 'Number of SYN packets to send', int],
-                     ['interface', 'i', None, 'Network interface to use'],
-                     ['verbose', 'v', False, 'Show hexdump of responses']]
+    optParameters = [
+        ['dst', 'd', None, 'Host IP to ping'],
+        ['port', 'p', None, 'Host port'],
+        ['count', 'c', 3, 'Number of SYN packets to send', int],
+        ['interface', 'i', None, 'Network interface to use'],
+        ['hexdump', 'x', False, 'Show hexdump of responses'],
+        ['pdf', 'y', False,
+         'Create pdf of visual representation of packet conversations'],
+        ['cerealize', 'z', False,
+         'Cerealize scapy objects for further scripting']]
 
 class TCPSynTest(nettest.NetTestCase):
     """
@@ -63,7 +68,6 @@ class TCPSynTest(nettest.NetTestCase):
             for key, value in self.localOptions.items():
                 log.debug("setting self.%s = %s" % (key, value))
                 setattr(self, key, value)
-
         if not self.interface:
             try:
                 iface = net.getDefaultIface()
@@ -75,14 +79,27 @@ class TCPSynTest(nettest.NetTestCase):
                 log.msg("Using system default interface: %s" % iface)
                 self.interface = iface
 
+        if self.cerealize:
+            if True:
+                raise NotImplemented("need handler for type(dictproxy)...")
+            else:
+                from Cerealize import cerealizer
+                self.cheerios = Cerealize.cerealizer()
+                mind = ['scapy.layers.inet.IP',
+                        'scapy.base_classes.Packet_metaclass',
+                        'scapy.plist.SndRcvList']
+                for spoon in mind:
+                    __import__(spoon)
+                    self.cheerios.register(spoon)
+
     def addToDestinations(self, addr, port):
-        try:
-            dst, dport = net.checkIPandPort(addr, port)
-            if not dst in self.destinations.keys():
-                self.destinations[dst] = {'dst': dst, 'dport': dport}
-            return (dst, dport)
-        except Exception, ex:
-            log.exception(ex)
+        dst, dport = net.checkIPandPort(addr, port)
+        if not dst in self.destinations.keys():
+            self.destinations[dst] = {'dst': dst, 'dport': dport}
+        else:
+            ## XXX implement multiple port or portrange options
+            log.msg("Multiple port scanning not yet implemented.")
+        return (dst, dport)
 
     def inputProcessor(self, input_file=None):
         """
@@ -91,11 +108,11 @@ class TCPSynTest(nettest.NetTestCase):
         """
         try:
             ## get the commandline input, if there is one:
-            if self.localOptions['dst'] is not None and self.localOptions['port'] is not None:
+            if self.localOptions['dst'] is not None \
+                    and self.localOptions['port'] is not None:
                 log.debug("processing commandline destination input")
                 yield self.addToDestinations(self.localOptions['dst'],
                                              self.localOptions['port'])
-
             ## get the inputs from inputFile:
             if input_file and os.path.isfile(input_file):
                 log.debug("processing input file %s" % input_file)
@@ -104,7 +121,7 @@ class TCPSynTest(nettest.NetTestCase):
                         if line.startswith('#'):
                             continue
                         one = line.strip()
-                        raw_ip, raw_port = one.rsplit(':', 1)  ## XXX not ipv6 safe!
+                        raw_ip, raw_port = one.rsplit(':', 1) ## XXX not ipv6 safe!
                         yield self.addToDestinations(raw_ip, raw_port)
         except Exception, ex:
             log.exception(ex)
@@ -120,86 +137,59 @@ class TCPSynTest(nettest.NetTestCase):
                     packets.append(pkt)
                 return packets
 
-            def sort_nicely(packets):
-                """Print the summary of each packet in a list."""
-                return [pkt.summary() for pkt in packets]
-
-            def tcp_flags(responses):
-                """Print summary of hosts which responded with a SYN/ACK."""
-                for response in responses:
-                    layer = response.getlayer('TCP') if response.haslayer('TCP') else None
-                    yield layer.sprintf("{TCP:%TCP.flags%}") if layer else None
-
-            def received_syn(responses, flags):
-                yield responses.filter(
-                    lambda x: (x for x in responses if str(flags) in ['S','SA']))
-
             def process_packets(packet_list):
+                """xxx"""
                 results, unanswered = packet_list
 
-                log.debug("RESULTS ARE: %s" % results)
-                log.debug("UNANSWERED: %s" % unanswered)
-
-                for (q, re) in results:
+                if self.pdf:
+                    pdf_name = self.name  +'_'+ timestamp()
+                    try:
+                        results.pdfdump(pdf_name)
+                    except Exception, ex:
+                        log.exception(ex)
+                    else:
+                        log.msg("Visual packet conversation saved to %s.pdf"
+                                % pdf_name)
+
+                for (q, r) in results:
                     request_data = {'summary': q.summary(),
                                     'command': q.command(),
-                                    'object': export_object(q),
                                     'hash': q.hashret(),
                                     'display': q.display(),
                                     'sent_time': q.time}
                     response_data = {'summary': r.summary(),
                                      'command': r.command(),
-                                     'object': export_object(r)
                                      'hash': r.hashret(),
                                      'src': r['IP'].src,
                                      'flags': r['IP'].flags,
                                      'display': r.display(),
                                      'recv_time': r.time,
                                      'delay': r.time - q.time}
-                    if self.verbose:
-                        request_data['hexdump'] = q.hexdump()
-                        response_data['hexdump'] = r.hexdump()
-
+                    if self.hexdump:
+                        request_data.update('hexdump', q.hexdump())
+                        response_data.update('hexdump', r.hexdump())
+                    if self.cerealize:
+                        pass
                     result_data = (request_data, response_data)
 
-                    flags = tcp_flags(response)
                     for dest, data in self.destinations.items():
-                        if data['dst'] == response.src:
-                            if not 'response' in data:
-                                log.msg("%s" % request.summary())
-                                log.msg("%s" % response.summary())
-                                data['response'] = [response.summary()]
+                        if data['dst'] == response_data['src']:
+                            if not 'received_response' in data:
+                                if self.hexdump:
+                                    log.msg("%s" % request.hexdump())
+                                    log.msg("%s" % response.hexdump())
+                                else:
+                                    log.msg("\n    %s\n ==> %s" % (q.summary(),
+                                                                   r.summary()))
+                                data['result'] = [result_data, ]
+                                data['received_response'] = True
                                 data['reachable'] = True
                             else:
-                                data['response'].append(response.summary())
-                    if self.verbose:
-                        log.msg("%s" % request.summary())
-                        log.msg("%s" % response.hexdump())
-
-                for unans in unanswered:
-                    process_unanswered(unans)
-
-                #try:
-                #    response.make_table(
-                #        lambda x:(
-                #            (x.src for x in received_syn(response)),
-                #            (x.dport for x in request),
-                #            (x for x in tcp.flags(response)) )
-                #        )
-                #except Exception, ex:
-                #    log.exception(ex)
+                                data['result'].append(result_data)
 
             def process_unanswered(unanswer):
                 """Callback function to process unanswered packets."""
-                log.msg("unanswered packets:\n%s"
-                        % sort_nicely(unanswer))
-                self.report['unanswered'] = sort_nicely(unanswer)
-
-                for dest, data in self.destinations.items():
-                    if not 'response' in data:
-                        log.msg("No reply from %s." % dest)
-                        data['response'] = None
-                        data['reachable'] = False
+                #log.debug("%s" % str(unanswer))
                 return unanswer
 
             (addr, port) = self.input
@@ -209,6 +199,7 @@ class TCPSynTest(nettest.NetTestCase):
 
             d = txscapy.sr(packets, iface=self.interface)
             d.addCallbacks(process_packets, log.exception)
+            d.addCallbacks(process_unanswered, log.exception)
             self.report['destinations'] = self.destinations
             return d
 





More information about the tor-commits mailing list