diff --git a/pathspider/observer.py b/pathspider/observer.py index fecb475..f49bac2 100644 --- a/pathspider/observer.py +++ b/pathspider/observer.py @@ -46,12 +46,20 @@ def _flow6_ids(ip6): quotation_fid = True protos_with_ports = {6, 17, 132, 136} + hdr_opts = {0, 60} if ip6.proto in protos_with_ports: + # key gets the protocol from the IPv6 HBH or Destination Options header + if ip6.next_hdr in hdr_opts: + fid = ip6.src_prefix.addr + ip6.dst_prefix.addr + ip6.data[ + 40:41] + ip6.payload[0:4] + rid = ip6.dst_prefix.addr + ip6.src_prefix.addr + ip6.data[ + 40:41] + ip6.payload[2:4] + ip6.payload[0:2] # key includes ports - fid = ip6.src_prefix.addr + ip6.dst_prefix.addr + ip6.data[ - 6:7] + ip6.payload[0:4] - rid = ip6.dst_prefix.addr + ip6.src_prefix.addr + ip6.data[ - 6:7] + ip6.payload[2:4] + ip6.payload[0:2] + else: + fid = ip6.src_prefix.addr + ip6.dst_prefix.addr + ip6.data[ + 6:7] + ip6.payload[0:4] + rid = ip6.dst_prefix.addr + ip6.src_prefix.addr + ip6.data[ + 6:7] + ip6.payload[2:4] + ip6.payload[0:2] else: # no ports, just 3-tuple fid = ip6.src_prefix.addr + ip6.dst_prefix.addr + ip6.data[6:7] diff --git a/pathspider/plugins/hbhopt.py b/pathspider/plugins/hbhopt.py new file mode 100644 index 0000000..2530b4d --- /dev/null +++ b/pathspider/plugins/hbhopt.py @@ -0,0 +1,46 @@ + +from scapy.all import IPv6 # pylint: disable=E0611 +from scapy.all import UDP # pylint: disable=E0611 +from scapy.all import DNS # pylint: disable=E0611 +from scapy.all import DNSQR # pylint: disable=E0611 +from scapy.all import RandShort # pylint: disable=E0611 + +import pathspider.base +from pathspider.base import PluggableSpider +from pathspider.single import DesynchronizedSpider +from pathspider.chains.basic import BasicChain +from pathspider.chains.dns import DNSChain +from pathspider.helpers.dns import connect_dns_udp +from pathspider.helpers.dns import connect_dns + +class HBHOPT(DesynchronizedSpider, PluggableSpider): + + name = "hbhopt" + description = "Hop-by-hop options testing" + version = pathspider.base.__version__ + chains = [BasicChain, DNSChain] + + + def con_normal(self, job, config): + return connect_dns_udp(self.source, job, self.args.timeout, sockopts=None) + + def con_hhb(self, job, config): + opt =[(41, 54, b'\x00\x00\x00\x00\x00\x00\x00\x00')] + return connect_dns_udp(self.source, job, self.args.timeout, sockopts=opt) + + def con_dopts(self, job, config): + opt =[(41, 59, b'\x00\x00\x00\x00\x00\x00\x00\x00')] + return connect_dns_udp(self.source, job, self.args.timeout, sockopts=opt) + + connections = [con_normal, con_hhb, con_dopts] + + def combine_flows(self, flows): + for flow in flows: + if not flow['observed']: + return ['pathspider.not_observed'] + conditions = [] + conditions.append(self.combine_connectivity(flows[0]['dns_response_valid'], + flows[1]['dns_response_valid'], prefix ='hbh_opts')) + conditions.append(self.combine_connectivity(flows[0]['dns_response_valid'], + flows[2]['dns_response_valid'], prefix='dst_opts')) + return conditions