[tor-commits] [ooni-probe/master] * Rewrite of echo.
isis at torproject.org
isis at torproject.org
Fri Nov 16 00:50:07 UTC 2012
commit 56ae275afcd3ca2517dd9e8ff8ec6b83448c34a6
Author: Isis Lovecruft <isis at torproject.org>
Date: Thu Nov 15 23:09:46 2012 +0000
* Rewrite of echo.
---
nettests/bridge_reachability/echo.py | 176 ++++++++++++++++------------------
1 files changed, 83 insertions(+), 93 deletions(-)
diff --git a/nettests/bridge_reachability/echo.py b/nettests/bridge_reachability/echo.py
index 5198766..40436e7 100644
--- a/nettests/bridge_reachability/echo.py
+++ b/nettests/bridge_reachability/echo.py
@@ -6,59 +6,57 @@
# +---------+
# A simple ICMP-8 ping test.
#
-# :author: Isis Lovecruft
-# :version: 0.0.1-pre-alpha
-# :license: (c) 2012 Isis Lovecruft
+# @authors: Isis Lovecruft, <isis at torproject.org>
+# @version: 0.0.2-pre-alpha
+# @license: copyright (c) 2012 Isis Lovecruft
# see attached LICENCE file
#
import os
import sys
-from pprint import pprint
-
-from twisted.internet import reactor
-from twisted.plugin import IPlugin
from twisted.python import usage
-from ooni.nettest import NetTestCase
-from ooni.utils import log, Storage
-from ooni.utils.net import PermissionsError, IfaceError
+from twisted.internet import reactor, defer
+from ooni import nettest
+from ooni.utils import log, net, Storage
try:
- from scapy.all import sr1, IP, ICMP ## XXX v4/v6?
+ from scapy.all import IP, ICMP
+ from scapy.all import sr1
from ooni.lib import txscapy
from ooni.lib.txscapy import txsr, txsend
from ooni.templates.scapyt import BaseScapyTest
except:
log.msg("This test requires scapy, see www.secdev.org/projects/scapy")
-class EchoTest(BaseScapyTest):
+class UsageOptions(usage.Options):
+ optParameters = [
+ ['dst', 'd', None, 'Host IP to ping'],
+ ['file', 'f', None, 'File of list of IPs to ping'],
+ ['interface', 'i', None, 'Network interface to use'],
+ ['count', 'c', 1, 'Number of packets to send', int],
+ ['size', 's', 56, 'Number of bytes to send in ICMP data field', int],
+ ['ttl', 'l', 25, 'Set the IP Time to Live', int],
+ ['timeout', 't', 2, 'Seconds until timeout if no response', int],
+ ['pcap', 'p', None, 'Save pcap to this file'],
+ ['receive', 'r', True, 'Receive response packets']]
+
+class EchoTest(nettest.NetTestCase):
"""
xxx fill me in
"""
name = 'echo'
author = 'Isis Lovecruft <isis at torproject.org>'
- description = 'A simple ICMP-8 test to see if a host is reachable.'
- version = '0.0.1'
- inputFile = ['file', 'f', None, 'File of list of IPs to ping']
+ description = 'A simple ping test to see if a host is reachable.'
+ version = '0.0.2'
requiresRoot = True
- optParameters = [
- ['interface', 'i', None, 'Network interface to use'],
- ['count', 'c', 5, 'Number of packets to send', int],
- ['size', 's', 56, 'Number of bytes to send in ICMP data field', int],
- ['ttl', 'l', 25, 'Set the IP Time to Live', int],
- ['timeout', 't', 2, 'Seconds until timeout if no response', int],
- ['pcap', 'p', None, 'Save pcap to this file'],
- ['receive', 'r', True, 'Receive response packets']
- ]
+ usageOptions = UsageOptions
+ #requiredOptions = ['dst']
def setUp(self, *a, **kw):
- '''
- :ivar ifaces:
- Struct returned from getifaddrs(3) and turned into a tuple in the
- form (*ifa_name, AF_FAMILY, *ifa_addr)
- '''
+ self.destinations = {}
+
if self.localOptions:
for key, value in self.localOptions.items():
log.debug("setting self.%s = %s" % (key, value))
@@ -67,76 +65,68 @@ class EchoTest(BaseScapyTest):
self.timeout *= 1000 ## convert to milliseconds
if not self.interface:
- log.msg("No network interface specified!")
+ try:
+ iface = net.getDefaultIface()
+ except Exception, e:
+ log.msg("No network interface specified!")
+ log.err(e)
+ else:
+ log.msg("Using system default interface: %s" % iface)
+ self.interface = iface
if self.pcap:
try:
self.pcapfile = open(self.pcap, 'a+')
except:
log.msg("Unable to write to pcap file %s" % self.pcap)
- self.pcapfile = None
-
- try:
- assert os.path.isfile(self.file)
- fp = open(self.file, 'r')
- except Exception, e:
- hosts = ['8.8.8.8', '38.229.72.14']
- log.err(e)
- else:
- self.inputs = self.inputProcessor(fp)
- self.removePorts(hosts)
-
- log.debug("Initialization of %s test completed with:\n%s"
- % (self.name, ''.join(self.__dict__)))
-
- @staticmethod
- def inputParser(self, one_input):
- log.debug("Removing possible ports from host addresses...")
- log.debug("Initial inputs:\n%s" % pprint(inputs))
-
- #host = [h.rsplit(':', 1)[0] for h in inputs]
- host = h.rsplit(':', 1)[0]
- log.debug("Inputs converted to:\n%s" % hosts)
-
- return host
-
- def tryInterfaces(self, ifaces):
- try:
- from scapy.all import sr1 ## we want this check to be blocking
- except:
- log.msg("This test requires scapy: www.secdev.org/projects/scapy")
- raise SystemExit
-
- ifup = {}
- while ifaces:
- for ifname, ifaddr in ifaces:
- log.debug("Currently testing network capabilities of interface"
- + "%s by sending a packet to our address %s"
- % (ifname, ifaddr))
- try:
- pkt = IP(dst=ifaddr)/ICMP()
- ans, unans = sr(pkt, iface=ifname, timeout=self.timeout)
- except Exception, e:
- raise PermissionsError if e.find("Errno 1") else log.err(e)
- else:
- ## xxx i think this logic might be wrong
- log.debug("Interface test packet\n%s\n\n%s"
- % (pkt.summary(), pkt.show2()))
- if ans.summary():
- log.info("Received answer for test packet on interface"
- +"%s :\n%s" % (ifname, ans.summary()))
- ifup.update(ifname, ifaddr)
- else:
- log.info("Our interface test packet was unanswered:\n%s"
- % unans.summary())
-
- if len(ifup) > 0:
- log.msg("Discovered the following working network interfaces: %s"
- % ifup)
- return ifup
+ else:
+ self.pcap = net.capturePacket(self.pcapfile)
+
+ if not self.dst:
+ if self.file:
+ self.dstProcessor(self.file)
+ for key, value in self.destinations.items():
+ for label, data in value.items():
+ if not 'ans' in data:
+ self.dst = label
else:
- raise IfaceError("Could not find a working network interface.")
+ self.addDest(self.dst)
+ log.debug("self.dst is now: %s" % self.dst)
- def test_icmp(self):
- return self.sr(IP(dst=self.input)/ICMP())
+ log.debug("Initialization of %s test completed." % self.name)
+
+ def addDest(self, dest):
+ d = dest.strip()
+ self.destinations[d] = {'dst_ip': d}
+
+ def dstProcessor(self, inputfile):
+ from ipaddr import IPAddress
+ if os.path.isfile(inputfile):
+ with open(inputfile) as f:
+ for line in f.readlines():
+ if line.startswith('#'):
+ continue
+ self.addDest(line)
+
+ def test_icmp(self):
+ def process_response(echo_reply, dest):
+ ans, unans = echo_reply
+ if ans:
+ log.msg("Recieved echo reply from %s: %s" % (dest, ans))
+ else:
+ log.msg("No reply was received from %s. Possible censorship event." % dest)
+ log.debug("Unanswered packets: %s" % unans)
+ self.report[dest] = echo_reply
+
+ for label, data in self.destinations.items():
+ reply = sr1(IP(dst=lebal)/ICMP())
+ process = process_reponse(reply, label)
+
+ #(ans, unans) = ping
+ #self.destinations[self.dst].update({'ans': ans,
+ # 'unans': unans,
+ # 'response_packet': ping})
+ #return ping
+
+ #return reply
More information about the tor-commits
mailing list