diff options
author | 2016-03-21 16:03:47 +0200 | |
---|---|---|
committer | 2016-03-21 16:03:47 +0200 | |
commit | b89efa188810bf95a9d245e69e2961b5721c3b0f (patch) | |
tree | 454273ac6c4ae972ebb8a2c86b893296970b4fa9 /scripts/external_libs/scapy-python3-0.18/scapy/layers | |
parent | f72c6df9d2e9998ae1f3529d729ab7930b35785a (diff) |
scapy python 2/3
Diffstat (limited to 'scripts/external_libs/scapy-python3-0.18/scapy/layers')
35 files changed, 0 insertions, 13359 deletions
diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/__init__.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/__init__.py deleted file mode 100644 index a3f2afb9..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -Layer package. -""" diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/all.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/all.py deleted file mode 100644 index 8104b6a2..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/all.py +++ /dev/null @@ -1,45 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -All layers. Configurable with conf.load_layers. -""" - -import importlib -from scapy.config import conf -from scapy.error import log_loading -import logging -log = logging.getLogger("scapy.loading") - -#log_loading.info("Please, report issues to https://github.com/phaethon/scapy") - -def _import_star(m): - #mod = __import__("." + m, globals(), locals()) - mod = importlib.import_module("scapy.layers." + m) - for k,v in mod.__dict__.items(): - globals()[k] = v - - -for _l in ['l2','inet','inet6']: - log_loading.debug("Loading layer %s" % _l) - #print "load ",_l - _import_star(_l) - -#def _import_star(m): - #mod = __import__("." + m, globals(), locals()) -# mod = importlib.import_module("scapy.layers." + m) -# for k,v in mod.__dict__.items(): -# globals()[k] = v - -#for _l in conf.load_layers: -# log_loading.debug("Loading layer %s" % _l) -# try: -# _import_star(_l) -# except Exception as e: -# log.warning("can't import layer %s: %s" % (_l,e)) - - - - diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/bluetooth.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/bluetooth.py deleted file mode 100644 index 5dd365a4..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/bluetooth.py +++ /dev/null @@ -1,213 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -Bluetooth layers, sockets and send/receive functions. -""" - -import socket,struct - -from scapy.config import conf -from scapy.packet import * -from scapy.fields import * -from scapy.supersocket import SuperSocket -from scapy.data import MTU - - -class HCI_Hdr(Packet): - name = "HCI header" - fields_desc = [ ByteEnumField("type",2,{1:"command",2:"ACLdata",3:"SCOdata",4:"event",5:"vendor"}),] - - def mysummary(self): - return self.sprintf("HCI %type%") - -class HCI_ACL_Hdr(Packet): - name = "HCI ACL header" - fields_desc = [ ByteField("handle",0), # Actually, handle is 12 bits and flags is 4. - ByteField("flags",0), # I wait to write a LEBitField - LEShortField("len",None), ] - def post_build(self, p, pay): - p += pay - if self.len is None: - l = len(p)-4 - #p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:] - p = p[:2]+bytes([(l&0xff),((l>>8)&0xff)])+p[4:] - return p - - -class L2CAP_Hdr(Packet): - name = "L2CAP header" - fields_desc = [ LEShortField("len",None), - LEShortEnumField("cid",0,{1:"control"}),] - - def post_build(self, p, pay): - p += pay - if self.len is None: - l = len(p)-4 - #p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:] - p = p[:2]+bytes([(l&0xff),((l>>8)&0xff)])+p[4:] - return p - - - -class L2CAP_CmdHdr(Packet): - name = "L2CAP command header" - fields_desc = [ - ByteEnumField("code",8,{1:"rej",2:"conn_req",3:"conn_resp", - 4:"conf_req",5:"conf_resp",6:"disconn_req", - 7:"disconn_resp",8:"echo_req",9:"echo_resp", - 10:"info_req",11:"info_resp"}), - ByteField("id",0), - LEShortField("len",None) ] - def post_build(self, p, pay): - p += pay - if self.len is None: - l = len(p)-4 - #p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:] - p = p[:2]+bytes([(l&0xff),((l>>8)&0xff)])+p[4:] - return p - def answers(self, other): - if other.id == self.id: - if self.code == 1: - return 1 - if other.code in [2,4,6,8,10] and self.code == other.code+1: - if other.code == 8: - return 1 - return self.payload.answers(other.payload) - return 0 - -class L2CAP_ConnReq(Packet): - name = "L2CAP Conn Req" - fields_desc = [ LEShortEnumField("psm",0,{1:"SDP",3:"RFCOMM",5:"telephony control"}), - LEShortField("scid",0), - ] - -class L2CAP_ConnResp(Packet): - name = "L2CAP Conn Resp" - fields_desc = [ LEShortField("dcid",0), - LEShortField("scid",0), - LEShortEnumField("result",0,["no_info","authen_pend","author_pend"]), - LEShortEnumField("status",0,["success","pend","bad_psm", - "cr_sec_block","cr_no_mem"]), - ] - def answers(self, other): - return self.scid == other.scid - -class L2CAP_CmdRej(Packet): - name = "L2CAP Command Rej" - fields_desc = [ LEShortField("reason",0), - ] - - -class L2CAP_ConfReq(Packet): - name = "L2CAP Conf Req" - fields_desc = [ LEShortField("dcid",0), - LEShortField("flags",0), - ] - -class L2CAP_ConfResp(Packet): - name = "L2CAP Conf Resp" - fields_desc = [ LEShortField("scid",0), - LEShortField("flags",0), - LEShortEnumField("result",0,["success","unaccept","reject","unknown"]), - ] - def answers(self, other): - return self.scid == other.scid - - -class L2CAP_DisconnReq(Packet): - name = "L2CAP Disconn Req" - fields_desc = [ LEShortField("dcid",0), - LEShortField("scid",0), ] - -class L2CAP_DisconnResp(Packet): - name = "L2CAP Disconn Resp" - fields_desc = [ LEShortField("dcid",0), - LEShortField("scid",0), ] - def answers(self, other): - return self.scid == other.scid - - - -class L2CAP_InfoReq(Packet): - name = "L2CAP Info Req" - fields_desc = [ LEShortEnumField("type",0,{1:"CL_MTU",2:"FEAT_MASK"}), - StrField("data","") - ] - - -class L2CAP_InfoResp(Packet): - name = "L2CAP Info Resp" - fields_desc = [ LEShortField("type",0), - LEShortEnumField("result",0,["success","not_supp"]), - StrField("data",""), ] - def answers(self, other): - return self.type == other.type - - - -bind_layers( HCI_Hdr, HCI_ACL_Hdr, type=2) -bind_layers( HCI_Hdr, conf.raw_layer, ) -bind_layers( HCI_ACL_Hdr, L2CAP_Hdr, ) -bind_layers( L2CAP_Hdr, L2CAP_CmdHdr, cid=1) -bind_layers( L2CAP_CmdHdr, L2CAP_CmdRej, code=1) -bind_layers( L2CAP_CmdHdr, L2CAP_ConnReq, code=2) -bind_layers( L2CAP_CmdHdr, L2CAP_ConnResp, code=3) -bind_layers( L2CAP_CmdHdr, L2CAP_ConfReq, code=4) -bind_layers( L2CAP_CmdHdr, L2CAP_ConfResp, code=5) -bind_layers( L2CAP_CmdHdr, L2CAP_DisconnReq, code=6) -bind_layers( L2CAP_CmdHdr, L2CAP_DisconnResp, code=7) -bind_layers( L2CAP_CmdHdr, L2CAP_InfoReq, code=10) -bind_layers( L2CAP_CmdHdr, L2CAP_InfoResp, code=11) - -class BluetoothL2CAPSocket(SuperSocket): - desc = "read/write packets on a connected L2CAP socket" - def __init__(self, peer): - s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, - socket.BTPROTO_L2CAP) - s.connect((peer,0)) - - self.ins = self.outs = s - - def recv(self, x=MTU): - return L2CAP_CmdHdr(self.ins.recv(x)) - - -class BluetoothHCISocket(SuperSocket): - desc = "read/write on a BlueTooth HCI socket" - def __init__(self, iface=0x10000, type=None): - s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) - s.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR,1) - s.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP,1) - s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, struct.pack("IIIh2x", 0xffffffff,0xffffffff,0xffffffff,0)) #type mask, event mask, event mask, opcode - s.bind((iface,)) - self.ins = self.outs = s -# s.connect((peer,0)) - - - def recv(self, x): - return HCI_Hdr(self.ins.recv(x)) - -## Bluetooth - - -@conf.commands.register -def srbt(peer, pkts, inter=0.1, *args, **kargs): - """send and receive using a bluetooth socket""" - s = conf.BTsocket(peer=peer) - a,b = sndrcv(s,pkts,inter=inter,*args,**kargs) - s.close() - return a,b - -@conf.commands.register -def srbt1(peer, pkts, *args, **kargs): - """send and receive 1 packet using a bluetooth socket""" - a,b = srbt(peer, pkts, *args, **kargs) - if len(a) > 0: - return a[0][1] - - - -conf.BTsocket = BluetoothL2CAPSocket diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/dhcp.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/dhcp.py deleted file mode 100644 index e2b7c1f1..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/dhcp.py +++ /dev/null @@ -1,381 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -DHCP (Dynamic Host Configuration Protocol) d BOOTP -""" - -import struct - -from scapy.packet import * -from scapy.fields import * -from scapy.ansmachine import * -from scapy.layers.inet import UDP,IP -from scapy.layers.l2 import Ether -from scapy.base_classes import Net -from scapy.volatile import RandField - -from scapy.arch import get_if_raw_hwaddr -from scapy.sendrecv import srp1 -from scapy.utils import str2bytes - -dhcpmagic=b"c\x82Sc" - - -class BOOTP(Packet): - name = "BOOTP" - fields_desc = [ ByteEnumField("op",1, {1:"BOOTREQUEST", 2:"BOOTREPLY"}), - ByteField("htype",1), - ByteField("hlen",6), - ByteField("hops",0), - IntField("xid",0), - ShortField("secs",0), - FlagsField("flags", 0, 16, "???????????????B"), - IPField("ciaddr","0.0.0.0"), - IPField("yiaddr","0.0.0.0"), - IPField("siaddr","0.0.0.0"), - IPField("giaddr","0.0.0.0"), - Field("chaddr",b"", "16s"), - Field("sname",b"","64s"), - Field("file",b"","128s"), - StrField("options",b"") ] - def guess_payload_class(self, payload): - if self.options[:len(dhcpmagic)] == dhcpmagic: - return DHCP - else: - return Packet.guess_payload_class(self, payload) - def extract_padding(self,s): - if self.options[:len(dhcpmagic)] == dhcpmagic: - # set BOOTP options to DHCP magic cookie and make rest a payload of DHCP options - payload = self.options[len(dhcpmagic):] - self.options = self.options[:len(dhcpmagic)] - return payload, None - else: - return b"", None - def hashret(self): - return struct.pack("L", self.xid) - def answers(self, other): - if not isinstance(other, BOOTP): - return 0 - return self.xid == other.xid - - - -#DHCP_UNKNOWN, DHCP_IP, DHCP_IPLIST, DHCP_TYPE \ -#= range(4) -# - -DHCPTypes = { - 1: "discover", - 2: "offer", - 3: "request", - 4: "decline", - 5: "ack", - 6: "nak", - 7: "release", - 8: "inform", - 9: "force_renew", - 10:"lease_query", - 11:"lease_unassigned", - 12:"lease_unknown", - 13:"lease_active", - } - -DHCPOptions = { - 0: "pad", - 1: IPField("subnet_mask", "0.0.0.0"), - 2: "time_zone", - 3: IPField("router","0.0.0.0"), - 4: IPField("time_server","0.0.0.0"), - 5: IPField("IEN_name_server","0.0.0.0"), - 6: IPField("name_server","0.0.0.0"), - 7: IPField("log_server","0.0.0.0"), - 8: IPField("cookie_server","0.0.0.0"), - 9: IPField("lpr_server","0.0.0.0"), - 12: "hostname", - 14: "dump_path", - 15: "domain", - 17: "root_disk_path", - 22: "max_dgram_reass_size", - 23: "default_ttl", - 24: "pmtu_timeout", - 28: IPField("broadcast_address","0.0.0.0"), - 35: "arp_cache_timeout", - 36: "ether_or_dot3", - 37: "tcp_ttl", - 38: "tcp_keepalive_interval", - 39: "tcp_keepalive_garbage", - 40: "NIS_domain", - 41: IPField("NIS_server","0.0.0.0"), - 42: IPField("NTP_server","0.0.0.0"), - 43: "vendor_specific", - 44: IPField("NetBIOS_server","0.0.0.0"), - 45: IPField("NetBIOS_dist_server","0.0.0.0"), - 50: IPField("requested_addr","0.0.0.0"), - 51: IntField("lease_time", 43200), - 54: IPField("server_id","0.0.0.0"), - 55: "param_req_list", - 57: ShortField("max_dhcp_size", 1500), - 58: IntField("renewal_time", 21600), - 59: IntField("rebinding_time", 37800), - 60: "vendor_class_id", - 61: "client_id", - - 64: "NISplus_domain", - 65: IPField("NISplus_server","0.0.0.0"), - 69: IPField("SMTP_server","0.0.0.0"), - 70: IPField("POP3_server","0.0.0.0"), - 71: IPField("NNTP_server","0.0.0.0"), - 72: IPField("WWW_server","0.0.0.0"), - 73: IPField("Finger_server","0.0.0.0"), - 74: IPField("IRC_server","0.0.0.0"), - 75: IPField("StreetTalk_server","0.0.0.0"), - 76: "StreetTalk_Dir_Assistance", - 82: "relay_agent_Information", - 53: ByteEnumField("message-type", 1, DHCPTypes), - # 55: DHCPRequestListField("request-list"), - 255: "end" - } - -DHCPRevOptions = {} - -for k,v in DHCPOptions.items(): - if type(v) is str: - n = v - v = None - else: - n = v.name - DHCPRevOptions[n] = (k,v) -del(n) -del(v) -del(k) - - - - -class RandDHCPOptions(RandField): - def __init__(self, size=None, rndstr=None): - if size is None: - size = RandNumExpo(0.05) - self.size = size - if rndstr is None: - rndstr = RandBin(RandNum(0,255)) - self.rndstr=rndstr - self._opts = list(DHCPOptions.values()) - self._opts.remove("pad") - self._opts.remove("end") - def _fix(self): - op = [] - for k in range(self.size): - o = random.choice(self._opts) - if type(o) is str: - op.append((o,self.rndstr*1)) - else: - op.append((o.name, o.randval()._fix())) - return op - - -class DHCPOptionsField(StrField): - islist=1 - def i2repr(self,pkt,x): - s = [] - for v in x: - if type(v) is tuple and len(v) >= 2: - if v[0] in DHCPRevOptions and isinstance(DHCPRevOptions[v[0]][1],Field): - f = DHCPRevOptions[v[0]][1] - vv = ",".join(f.i2repr(pkt,val) for val in v[1:]) - else: - vv = ",".join(repr(val) for val in v[1:]) - r = "%s=%s" % (v[0],vv) - s.append(r) - else: - s.append(sane(v)) - return "[%s]" % (" ".join(s)) - - def getfield(self, pkt, s): - return b"", self.m2i(pkt, s) - - def m2i(self, pkt, x): - opt = [] - while x: - #o = ord(x[0]) - o = x[0] - if o == 255: - opt.append("end") - x = x[1:] - continue - if o == 0: - opt.append("pad") - x = x[1:] - continue - #if len(x) < 2 or len(x) < ord(x[1])+2: - if len(x) < 2 or len(x) < x[1]+2: - opt.append(x) - break - elif o in DHCPOptions: - f = DHCPOptions[o] - - if isinstance(f, str): - #olen = ord(x[1]) - olen = x[1] - opt.append( (f,x[2:olen+2]) ) - x = x[olen+2:] - else: - olen = x[1] - lval = [f.name] - try: - left = x[2:olen+2] - while left: - left, val = f.getfield(pkt,left) - lval.append(val) - except: - opt.append(x) - break - else: - otuple = tuple(lval) - opt.append(otuple) - x = x[olen+2:] - else: - #olen = ord(x[1]) - olen = x[1] - opt.append((o, x[2:olen+2])) - x = x[olen+2:] - return opt - def i2m(self, pkt, x): - if type(x) is str: - return x - s = b"" - for o in x: - if type(o) is tuple and len(o) >= 2: - name = o[0] - lval = o[1:] - - if isinstance(name, int): - onum, oval = name, b"".join(lval) - elif name in DHCPRevOptions: - onum, f = DHCPRevOptions[name] - if f is not None: - lval = [f.addfield(pkt,b"",f.any2i(pkt,val)) for val in lval] - oval = b"".join(lval) - else: - warning("Unknown field option %s" % name) - continue - - s += bytes([onum]) - s += bytes([len(oval)]) - s += oval - - elif (type(o) is str and o in DHCPRevOptions and - DHCPRevOptions[o][1] == None): - s += bytes([DHCPRevOptions[o][0]]) - elif type(o) is int: - s += chr(o)+b"\0" - elif type(o) is str: - s += str2bytes(o) - elif type(o) is bytes: - s += o - else: - warning("Malformed option %s" % o) - return s - - -class DHCP(Packet): - name = "DHCP options" - fields_desc = [ DHCPOptionsField("options",b"") ] - - -bind_layers( UDP, BOOTP, dport=67, sport=68) -bind_layers( UDP, BOOTP, dport=68, sport=67) -bind_bottom_up( UDP, BOOTP, dport=67, sport=67) -bind_layers( BOOTP, DHCP, options=b'c\x82Sc') - -def dhcp_request(iface=None,**kargs): - if conf.checkIPaddr != 0: - warning("conf.checkIPaddr is not 0, I may not be able to match the answer") - if iface is None: - iface = conf.iface - hw = get_if_raw_hwaddr(iface) - return srp1(Ether(dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67) - /BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"]),iface=iface,**kargs) - - -class BOOTP_am(AnsweringMachine): - function_name = "bootpd" - filter = "udp and port 68 and port 67" - send_function = staticmethod(sendp) - def parse_options(self, pool=Net("192.168.1.128/25"), network="192.168.1.0/24",gw="192.168.1.1", - domain="localnet", renewal_time=60, lease_time=1800): - if type(pool) is str: - poom = Net(pool) - self.domain = domain - netw,msk = (network.split("/")+["32"])[:2] - msk = itom(int(msk)) - self.netmask = ltoa(msk) - self.network = ltoa(atol(netw)&msk) - self.broadcast = ltoa( atol(self.network) | (0xffffffff&~msk) ) - self.gw = gw - if isinstance(pool,Gen): - pool = [k for k in pool if k not in [gw, self.network, self.broadcast]] - pool.reverse() - if len(pool) == 1: - pool, = pool - self.pool = pool - self.lease_time = lease_time - self.renewal_time = renewal_time - self.leases = {} - - def is_request(self, req): - if not req.haslayer(BOOTP): - return 0 - reqb = req.getlayer(BOOTP) - if reqb.op != 1: - return 0 - return 1 - - def print_reply(self, req, reply): - print("Reply %s to %s" % (reply.getlayer(IP).dst,reply.dst)) - - def make_reply(self, req): - mac = req.src - if type(self.pool) is list: - if not mac in self.leases: - self.leases[mac] = self.pool.pop() - ip = self.leases[mac] - else: - ip = self.pool - - repb = req.getlayer(BOOTP).copy() - repb.op="BOOTREPLY" - repb.yiaddr = ip - repb.siaddr = self.gw - repb.ciaddr = self.gw - repb.giaddr = self.gw - del(repb.payload) - rep=Ether(dst=mac)/IP(dst=ip)/UDP(sport=req.dport,dport=req.sport)/repb - return rep - - -class DHCP_am(BOOTP_am): - function_name="dhcpd" - def make_reply(self, req): - resp = BOOTP_am.make_reply(self, req) - if DHCP in req: - dhcp_options = [(op[0],{1:2,3:5}.get(op[1],op[1])) - for op in req[DHCP].options - if type(op) is tuple and op[0] == "message-type"] - dhcp_options += [("server_id",self.gw), - ("domain", self.domain), - ("router", self.gw), - ("name_server", self.gw), - ("broadcast_address", self.broadcast), - ("subnet_mask", self.netmask), - ("renewal_time", self.renewal_time), - ("lease_time", self.lease_time), - "end" - ] - resp /= DHCP(options=dhcp_options) - return resp - - diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/dhcp6.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/dhcp6.py deleted file mode 100644 index a11a4149..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/dhcp6.py +++ /dev/null @@ -1,1718 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -## Copyright (C) 2005 Guillaume Valadon <guedou@hongo.wide.ad.jp> -## Arnaud Ebalard <arnaud.ebalard@eads.net> - -""" -DHCPv6: Dynamic Host Configuration Protocol for IPv6. [RFC 3315] -""" - -import socket -from scapy.packet import * -from scapy.fields import * -from scapy.utils6 import * -from scapy.layers.inet6 import * -from scapy.ansmachine import AnsweringMachine - -############################################################################# -# Helpers ## -############################################################################# - -def get_cls(name, fallback_cls): - return globals().get(name, fallback_cls) - - -############################################################################# -############################################################################# -### DHCPv6 ### -############################################################################# -############################################################################# - -All_DHCP_Relay_Agents_and_Servers = "ff02::1:2" -All_DHCP_Servers = "ff05::1:3" # Site-Local scope : deprecated by 3879 - -dhcp6opts = { 1: "CLIENTID", - 2: "SERVERID", - 3: "IA_NA", - 4: "IA_TA", - 5: "IAADDR", - 6: "ORO", - 7: "PREFERENCE", - 8: "ELAPSED_TIME", - 9: "RELAY_MSG", - 11: "AUTH", - 12: "UNICAST", - 13: "STATUS_CODE", - 14: "RAPID_COMMIT", - 15: "USER_CLASS", - 16: "VENDOR_CLASS", - 17: "VENDOR_OPTS", - 18: "INTERFACE_ID", - 19: "RECONF_MSG", - 20: "RECONF_ACCEPT", - 21: "SIP Servers Domain Name List", #RFC3319 - 22: "SIP Servers IPv6 Address List", #RFC3319 - 23: "DNS Recursive Name Server Option", #RFC3646 - 24: "Domain Search List option", #RFC3646 - 25: "OPTION_IA_PD", #RFC3633 - 26: "OPTION_IAPREFIX", #RFC3633 - 27: "OPTION_NIS_SERVERS", #RFC3898 - 28: "OPTION_NISP_SERVERS", #RFC3898 - 29: "OPTION_NIS_DOMAIN_NAME", #RFC3898 - 30: "OPTION_NISP_DOMAIN_NAME", #RFC3898 - 31: "OPTION_SNTP_SERVERS", #RFC4075 - 32: "OPTION_INFORMATION_REFRESH_TIME", #RFC4242 - 33: "OPTION_BCMCS_SERVER_D", #RFC4280 - 34: "OPTION_BCMCS_SERVER_A", #RFC4280 - 36: "OPTION_GEOCONF_CIVIC", #RFC-ietf-geopriv-dhcp-civil-09.txt - 37: "OPTION_REMOTE_ID", #RFC4649 - 38: "OPTION_SUBSCRIBER_ID", #RFC4580 - 39: "OPTION_CLIENT_FQDN" } #RFC4704 - -dhcp6opts_by_code = { 1: "DHCP6OptClientId", - 2: "DHCP6OptServerId", - 3: "DHCP6OptIA_NA", - 4: "DHCP6OptIA_TA", - 5: "DHCP6OptIAAddress", - 6: "DHCP6OptOptReq", - 7: "DHCP6OptPref", - 8: "DHCP6OptElapsedTime", - 9: "DHCP6OptRelayMsg", - 11: "DHCP6OptAuth", - 12: "DHCP6OptServerUnicast", - 13: "DHCP6OptStatusCode", - 14: "DHCP6OptRapidCommit", - 15: "DHCP6OptUserClass", - 16: "DHCP6OptVendorClass", - 17: "DHCP6OptVendorSpecificInfo", - 18: "DHCP6OptIfaceId", - 19: "DHCP6OptReconfMsg", - 20: "DHCP6OptReconfAccept", - 21: "DHCP6OptSIPDomains", #RFC3319 - 22: "DHCP6OptSIPServers", #RFC3319 - 23: "DHCP6OptDNSServers", #RFC3646 - 24: "DHCP6OptDNSDomains", #RFC3646 - 25: "DHCP6OptIA_PD", #RFC3633 - 26: "DHCP6OptIAPrefix", #RFC3633 - 27: "DHCP6OptNISServers", #RFC3898 - 28: "DHCP6OptNISPServers", #RFC3898 - 29: "DHCP6OptNISDomain", #RFC3898 - 30: "DHCP6OptNISPDomain", #RFC3898 - 31: "DHCP6OptSNTPServers", #RFC4075 - 32: "DHCP6OptInfoRefreshTime", #RFC4242 - 33: "DHCP6OptBCMCSDomains", #RFC4280 - 34: "DHCP6OptBCMCSServers", #RFC4280 - #36: "DHCP6OptGeoConf", #RFC-ietf-geopriv-dhcp-civil-09.txt - 37: "DHCP6OptRemoteID", #RFC4649 - 38: "DHCP6OptSubscriberID", #RFC4580 - 39: "DHCP6OptClientFQDN", #RFC4704 - #40: "DHCP6OptPANAAgent", #RFC-ietf-dhc-paa-option-05.txt - #41: "DHCP6OptNewPOSIXTimeZone, #RFC4833 - #42: "DHCP6OptNewTZDBTimeZone, #RFC4833 - 43: "DHCP6OptRelayAgentERO" #RFC4994 - #44: "DHCP6OptLQQuery", #RFC5007 - #45: "DHCP6OptLQClientData", #RFC5007 - #46: "DHCP6OptLQClientTime", #RFC5007 - #47: "DHCP6OptLQRelayData", #RFC5007 - #48: "DHCP6OptLQClientLink", #RFC5007 -} - - -# sect 5.3 RFC 3315 : DHCP6 Messages types -dhcp6types = { 1:"SOLICIT", - 2:"ADVERTISE", - 3:"REQUEST", - 4:"CONFIRM", - 5:"RENEW", - 6:"REBIND", - 7:"REPLY", - 8:"RELEASE", - 9:"DECLINE", - 10:"RECONFIGURE", - 11:"INFORMATION-REQUEST", - 12:"RELAY-FORW", - 13:"RELAY-REPL" } - - -##################################################################### -### DHCPv6 DUID related stuff ### -##################################################################### - -duidtypes = { 1: "Link-layer address plus time", - 2: "Vendor-assigned unique ID based on Enterprise Number", - 3: "Link-layer Address" } - -# DUID hardware types - RFC 826 - Extracted from -# http://www.iana.org/assignments/arp-parameters on 31/10/06 -# We should add the length of every kind of address. -duidhwtypes = { 0: "NET/ROM pseudo", # Not referenced by IANA - 1: "Ethernet (10Mb)", - 2: "Experimental Ethernet (3Mb)", - 3: "Amateur Radio AX.25", - 4: "Proteon ProNET Token Ring", - 5: "Chaos", - 6: "IEEE 802 Networks", - 7: "ARCNET", - 8: "Hyperchannel", - 9: "Lanstar", - 10: "Autonet Short Address", - 11: "LocalTalk", - 12: "LocalNet (IBM PCNet or SYTEK LocalNET)", - 13: "Ultra link", - 14: "SMDS", - 15: "Frame Relay", - 16: "Asynchronous Transmission Mode (ATM)", - 17: "HDLC", - 18: "Fibre Channel", - 19: "Asynchronous Transmission Mode (ATM)", - 20: "Serial Line", - 21: "Asynchronous Transmission Mode (ATM)", - 22: "MIL-STD-188-220", - 23: "Metricom", - 24: "IEEE 1394.1995", - 25: "MAPOS", - 26: "Twinaxial", - 27: "EUI-64", - 28: "HIPARP", - 29: "IP and ARP over ISO 7816-3", - 30: "ARPSec", - 31: "IPsec tunnel", - 32: "InfiniBand (TM)", - 33: "TIA-102 Project 25 Common Air Interface (CAI)" } - -class UTCTimeField(IntField): - epoch = (2000, 1, 1, 0, 0, 0, 5, 1, 0) # required Epoch - def i2repr(self, pkt, x): - x = self.i2h(pkt, x) - from time import gmtime, strftime, mktime - delta = mktime(self.epoch) - mktime(gmtime(0)) - x = x + delta - t = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime(x)) - return "%s (%d)" % (t, x) - -class _LLAddrField(MACField): - pass - -# XXX We only support Ethernet addresses at the moment. _LLAddrField -# will be modified when needed. Ask us. --arno -class DUID_LLT(Packet): # sect 9.2 RFC 3315 - name = "DUID - Link-layer address plus time" - fields_desc = [ ShortEnumField("type", 1, duidtypes), - XShortEnumField("hwtype", 1, duidhwtypes), - UTCTimeField("timeval", 0), # i.e. 01 Jan 2000 - _LLAddrField("lladdr", ETHER_ANY) ] - -# In fact, IANA enterprise-numbers file available at -# http//www.iana.org/asignments/enterprise-numbers) -# is simply huge (more than 2Mo and 600Ko in bz2). I'll -# add only most common vendors, and encountered values. -# -- arno -iana_enterprise_num = { 9: "ciscoSystems", - 35: "Nortel Networks", - 43: "3Com", - 311: "Microsoft", - 2636: "Juniper Networks, Inc.", - 4526: "Netgear", - 5771: "Cisco Systems, Inc.", - 5842: "Cisco Systems", - 16885: "Nortel Networks" } - -class DUID_EN(Packet): # sect 9.3 RFC 3315 - name = "DUID - Assigned by Vendor Based on Enterprise Number" - fields_desc = [ ShortEnumField("type", 2, duidtypes), - IntEnumField("enterprisenum", 311, iana_enterprise_num), - StrField("id",b"") ] - -class DUID_LL(Packet): # sect 9.4 RFC 3315 - name = "DUID - Based on Link-layer Address" - fields_desc = [ ShortEnumField("type", 3, duidtypes), - XShortEnumField("hwtype", 1, duidhwtypes), - _LLAddrField("lladdr", ETHER_ANY) ] - -duid_cls = { 1: "DUID_LLT", - 2: "DUID_EN", - 3: "DUID_LL"} - -##################################################################### -### DHCPv6 Options classes ### -##################################################################### - -class _DHCP6OptGuessPayload(Packet): - def guess_payload_class(self, payload): - cls = conf.raw_layer - if len(payload) > 2 : - opt = struct.unpack("!H", payload[:2])[0] - cls = get_cls(dhcp6opts_by_code.get(opt, "DHCP6OptUnknown"), DHCP6OptUnknown) - return cls - -class DHCP6OptUnknown(_DHCP6OptGuessPayload): # A generic DHCPv6 Option - name = "Unknown DHCPv6 OPtion" - fields_desc = [ ShortEnumField("optcode", 0, dhcp6opts), - FieldLenField("optlen", None, length_of="data", fmt="!H"), - StrLenField("data", b"", - length_from = lambda pkt: pkt.optlen)] - -class _DUIDField(PacketField): - holds_packets=1 - def __init__(self, name, default, length_from=None): - StrField.__init__(self, name, default) - self.length_from = length_from - - def i2m(self, pkt, i): - return bytes(i) - - def m2i(self, pkt, x): - cls = conf.raw_layer - if len(x) > 4: - o = struct.unpack("!H", x[:2])[0] - cls = get_cls(duid_cls.get(o, conf.raw_layer), conf.raw_layer) - return cls(x) - - def getfield(self, pkt, s): - l = self.length_from(pkt) - return s[l:], self.m2i(pkt,s[:l]) - - -class DHCP6OptClientId(_DHCP6OptGuessPayload): # RFC sect 22.2 - name = "DHCP6 Client Identifier Option" - fields_desc = [ ShortEnumField("optcode", 1, dhcp6opts), - FieldLenField("optlen", None, length_of="duid", fmt="!H"), - _DUIDField("duid", "", - length_from = lambda pkt: pkt.optlen) ] - - -class DHCP6OptServerId(DHCP6OptClientId): # RFC sect 22.3 - name = "DHCP6 Server Identifier Option" - optcode = 2 - -# Should be encapsulated in the option field of IA_NA or IA_TA options -# Can only appear at that location. -# TODO : last field IAaddr-options is not defined in the reference document -class DHCP6OptIAAddress(_DHCP6OptGuessPayload): # RFC sect 22.6 - name = "DHCP6 IA Address Option (IA_TA or IA_NA suboption)" - fields_desc = [ ShortEnumField("optcode", 5, dhcp6opts), - FieldLenField("optlen", None, length_of="iaaddropts", - fmt="!H", adjust = lambda pkt,x: x+24), - IP6Field("addr", "::"), - IntField("preflft", 0), - IntField("validlft", 0), - XIntField("iaid", None), - StrLenField("iaaddropts", b"", - length_from = lambda pkt: pkt.optlen - 24) ] - def guess_payload_class(self, payload): - return conf.padding_layer - -class _IANAOptField(PacketListField): - def i2len(self, pkt, z): - if z is None or z == []: - return 0 - return sum(map(lambda x: len(bytes(x)) ,z)) - - def getfield(self, pkt, s): - l = self.length_from(pkt) - lst = [] - remain, payl = s[:l], s[l:] - while len(remain)>0: - p = self.m2i(pkt,remain) - if conf.padding_layer in p: - pad = p[conf.padding_layer] - remain = pad.load - del(pad.underlayer.payload) - else: - remain = "" - lst.append(p) - return payl,lst - -class DHCP6OptIA_NA(_DHCP6OptGuessPayload): # RFC sect 22.4 - name = "DHCP6 Identity Association for Non-temporary Addresses Option" - fields_desc = [ ShortEnumField("optcode", 3, dhcp6opts), - FieldLenField("optlen", None, length_of="ianaopts", - fmt="!H", adjust = lambda pkt,x: x+12), - XIntField("iaid", None), - IntField("T1", None), - IntField("T2", None), - _IANAOptField("ianaopts", [], DHCP6OptIAAddress, - length_from = lambda pkt: pkt.optlen-12) ] - -class _IATAOptField(_IANAOptField): - pass - -class DHCP6OptIA_TA(_DHCP6OptGuessPayload): # RFC sect 22.5 - name = "DHCP6 Identity Association for Temporary Addresses Option" - fields_desc = [ ShortEnumField("optcode", 4, dhcp6opts), - FieldLenField("optlen", None, length_of="iataopts", - fmt="!H", adjust = lambda pkt,x: x+4), - XIntField("iaid", None), - _IATAOptField("iataopts", [], DHCP6OptIAAddress, - length_from = lambda pkt: pkt.optlen-4) ] - - -#### DHCPv6 Option Request Option ################################### - -class _OptReqListField(StrLenField): - islist = 1 - def i2h(self, pkt, x): - if x is None: - return [] - return x - - def i2len(self, pkt, x): - return 2*len(x) - - def any2i(self, pkt, x): - return x - - def i2repr(self, pkt, x): - s = [] - for y in self.i2h(pkt, x): - if y in dhcp6opts: - s.append(dhcp6opts[y]) - else: - s.append("%d" % y) - return "[%s]" % ", ".join(s) - - def m2i(self, pkt, x): - r = [] - while len(x) != 0: - if len(x)<2: - warning("Odd length for requested option field. Rejecting last byte") - return r - r.append(struct.unpack("!H", x[:2])[0]) - x = x[2:] - return r - - def i2m(self, pkt, x): - return b"".join(map(lambda y: struct.pack("!H", y), x)) - -# A client may include an ORO in a solicit, Request, Renew, Rebind, -# Confirm or Information-request -class DHCP6OptOptReq(_DHCP6OptGuessPayload): # RFC sect 22.7 - name = "DHCP6 Option Request Option" - fields_desc = [ ShortEnumField("optcode", 6, dhcp6opts), - FieldLenField("optlen", None, length_of="reqopts", fmt="!H"), - _OptReqListField("reqopts", [23, 24], - length_from = lambda pkt: pkt.optlen) ] - - -#### DHCPv6 Preference Option ####################################### - -# emise par un serveur pour affecter le choix fait par le client. Dans -# les messages Advertise, a priori -class DHCP6OptPref(_DHCP6OptGuessPayload): # RFC sect 22.8 - name = "DHCP6 Preference Option" - fields_desc = [ ShortEnumField("optcode", 7, dhcp6opts), - ShortField("optlen", 1 ), - ByteField("prefval",255) ] - - -#### DHCPv6 Elapsed Time Option ##################################### - -class _ElapsedTimeField(ShortField): - def i2repr(self, pkt, x): - if x == 0xffff: - return "infinity (0xffff)" - return "%.2f sec" % (self.i2h(pkt, x)/100.) - -class DHCP6OptElapsedTime(_DHCP6OptGuessPayload):# RFC sect 22.9 - name = "DHCP6 Elapsed Time Option" - fields_desc = [ ShortEnumField("optcode", 8, dhcp6opts), - ShortField("optlen", 2), - _ElapsedTimeField("elapsedtime", 0) ] - - -#### DHCPv6 Relay Message Option #################################### - -# Relayed message is seen as a payload. -class DHCP6OptRelayMsg(_DHCP6OptGuessPayload):# RFC sect 22.10 - name = "DHCP6 Relay Message Option" - fields_desc = [ ShortEnumField("optcode", 9, dhcp6opts), - ShortField("optlen", None ) ] - def post_build(self, p, pay): - if self.optlen is None: - l = len(pay) - p = p[:2]+struct.pack("!H", l) - return p + pay - - -#### DHCPv6 Authentication Option ################################### - -# The following fields are set in an Authentication option for the -# Reconfigure Key Authentication Protocol: -# -# protocol 3 -# -# algorithm 1 -# -# RDM 0 -# -# The format of the Authentication information for the Reconfigure Key -# Authentication Protocol is: -# -# 0 1 2 3 -# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -# | Type | Value (128 bits) | -# +-+-+-+-+-+-+-+-+ | -# . . -# . . -# . +-+-+-+-+-+-+-+-+ -# | | -# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -# -# Type Type of data in Value field carried in this option: -# -# 1 Reconfigure Key value (used in Reply message). -# -# 2 HMAC-MD5 digest of the message (used in Reconfigure -# message). -# -# Value Data as defined by field. - - -# TODO : Decoding only at the moment -class DHCP6OptAuth(_DHCP6OptGuessPayload): # RFC sect 22.11 - name = "DHCP6 Option - Authentication" - fields_desc = [ ShortEnumField("optcode", 11, dhcp6opts), - FieldLenField("optlen", None, length_of="authinfo", - adjust = lambda pkt,x: x+11), - ByteField("proto", 3), # TODO : XXX - ByteField("alg", 1), # TODO : XXX - ByteField("rdm", 0), # TODO : XXX - StrFixedLenField("replay", b"A"*8, 8), # TODO: XXX - StrLenField("authinfo", b"", - length_from = lambda pkt: pkt.optlen - 11) ] - -#### DHCPv6 Server Unicast Option ################################### - -class _SrvAddrField(IP6Field): - def i2h(self, pkt, x): - if x is None: - return "::" - return x - - def i2m(self, pkt, x): - return inet_pton(socket.AF_INET6, self.i2h(pkt,x)) - -class DHCP6OptServerUnicast(_DHCP6OptGuessPayload):# RFC sect 22.12 - name = "DHCP6 Server Unicast Option" - fields_desc = [ ShortEnumField("optcode", 12, dhcp6opts), - ShortField("optlen", 16 ), - _SrvAddrField("srvaddr",None) ] - - -#### DHCPv6 Status Code Option ###################################### - -dhcp6statuscodes = { 0:"Success", # sect 24.4 - 1:"UnspecFail", - 2:"NoAddrsAvail", - 3:"NoBinding", - 4:"NotOnLink", - 5:"UseMulticast", - 6:"NoPrefixAvail"} # From RFC3633 - -class DHCP6OptStatusCode(_DHCP6OptGuessPayload):# RFC sect 22.13 - name = "DHCP6 Status Code Option" - fields_desc = [ ShortEnumField("optcode", 13, dhcp6opts), - FieldLenField("optlen", None, length_of="statusmsg", - fmt="!H", adjust = lambda pkt,x:x+2), - ShortEnumField("statuscode",None,dhcp6statuscodes), - StrLenField("statusmsg", b"", - length_from = lambda pkt: pkt.optlen-2) ] - - -#### DHCPv6 Rapid Commit Option ##################################### - -class DHCP6OptRapidCommit(_DHCP6OptGuessPayload): # RFC sect 22.14 - name = "DHCP6 Rapid Commit Option" - fields_desc = [ ShortEnumField("optcode", 14, dhcp6opts), - ShortField("optlen", 0)] - - -#### DHCPv6 User Class Option ####################################### - -class _UserClassDataField(PacketListField): - def i2len(self, pkt, z): - if z is None or z == []: - return 0 - return sum(map(lambda x: len(bytes(x)) ,z)) - - def getfield(self, pkt, s): - l = self.length_from(pkt) - lst = [] - remain, payl = s[:l], s[l:] - while len(remain)>0: - p = self.m2i(pkt,remain) - if conf.padding_layer in p: - pad = p[conf.padding_layer] - remain = pad.load - del(pad.underlayer.payload) - else: - remain = b"" - lst.append(p) - return payl,lst - - -class USER_CLASS_DATA(Packet): - name = "user class data" - fields_desc = [ FieldLenField("len", None, length_of="data"), - StrLenField("data", b"", - length_from = lambda pkt: pkt.len) ] - def guess_payload_class(self, payload): - return conf.padding_layer - -class DHCP6OptUserClass(_DHCP6OptGuessPayload):# RFC sect 22.15 - name = "DHCP6 User Class Option" - fields_desc = [ ShortEnumField("optcode", 15, dhcp6opts), - FieldLenField("optlen", None, fmt="!H", - length_of="userclassdata"), - _UserClassDataField("userclassdata", [], USER_CLASS_DATA, - length_from = lambda pkt: pkt.optlen) ] - - -#### DHCPv6 Vendor Class Option ##################################### - -class _VendorClassDataField(_UserClassDataField): - pass - -class VENDOR_CLASS_DATA(USER_CLASS_DATA): - name = "vendor class data" - -class DHCP6OptVendorClass(_DHCP6OptGuessPayload):# RFC sect 22.16 - name = "DHCP6 Vendor Class Option" - fields_desc = [ ShortEnumField("optcode", 16, dhcp6opts), - FieldLenField("optlen", None, length_of="vcdata", fmt="!H", - adjust = lambda pkt,x: x+4), - IntEnumField("enterprisenum",None , iana_enterprise_num ), - _VendorClassDataField("vcdata", [], VENDOR_CLASS_DATA, - length_from = lambda pkt: pkt.optlen-4) ] - -#### DHCPv6 Vendor-Specific Information Option ###################### - -class VENDOR_SPECIFIC_OPTION(_DHCP6OptGuessPayload): - name = "vendor specific option data" - fields_desc = [ ShortField("optcode", None), - FieldLenField("optlen", None, length_of="optdata"), - StrLenField("optdata", b"", - length_from = lambda pkt: pkt.optlen) ] - def guess_payload_class(self, payload): - return conf.padding_layer - -# The third one that will be used for nothing interesting -class DHCP6OptVendorSpecificInfo(_DHCP6OptGuessPayload):# RFC sect 22.17 - name = "DHCP6 Vendor-specific Information Option" - fields_desc = [ ShortEnumField("optcode", 17, dhcp6opts), - FieldLenField("optlen", None, length_of="vso", fmt="!H", - adjust = lambda pkt,x: x+4), - IntEnumField("enterprisenum",None , iana_enterprise_num), - _VendorClassDataField("vso", [], VENDOR_SPECIFIC_OPTION, - length_from = lambda pkt: pkt.optlen-4) ] - -#### DHCPv6 Interface-ID Option ##################################### - -# Repasser sur cette option a la fin. Elle a pas l'air d'etre des -# masses critique. -class DHCP6OptIfaceId(_DHCP6OptGuessPayload):# RFC sect 22.18 - name = "DHCP6 Interface-Id Option" - fields_desc = [ ShortEnumField("optcode", 18, dhcp6opts), - FieldLenField("optlen", None, fmt="!H", - length_of="ifaceid"), - StrLenField("ifaceid", b"", - length_from = lambda pkt: pkt.optlen) ] - - -#### DHCPv6 Reconfigure Message Option ############################## - -# A server includes a Reconfigure Message option in a Reconfigure -# message to indicate to the client whether the client responds with a -# renew message or an Informatiion-request message. -class DHCP6OptReconfMsg(_DHCP6OptGuessPayload): # RFC sect 22.19 - name = "DHCP6 Reconfigure Message Option" - fields_desc = [ ShortEnumField("optcode", 19, dhcp6opts), - ShortField("optlen", 1 ), - ByteEnumField("msgtype", 11, { 5:"Renew Message", - 11:"Information Request"}) ] - - -#### DHCPv6 Reconfigure Accept Option ############################### - -# A client uses the Reconfigure Accept option to announce to the -# server whether the client is willing to accept Recoonfigure -# messages, and a server uses this option to tell the client whether -# or not to accept Reconfigure messages. The default behavior in the -# absence of this option, means unwillingness to accept reconfigure -# messages, or instruction not to accept Reconfigure messages, for the -# client and server messages, respectively. -class DHCP6OptReconfAccept(_DHCP6OptGuessPayload): # RFC sect 22.20 - name = "DHCP6 Reconfigure Accept Option" - fields_desc = [ ShortEnumField("optcode", 20, dhcp6opts), - ShortField("optlen", 0)] - -# As required in Sect 8. of RFC 3315, Domain Names must be encoded as -# described in section 3.1 of RFC 1035 -# XXX Label should be at most 63 octets in length : we do not enforce it -# Total length of domain should be 255 : we do not enforce it either -class DomainNameListField(StrLenField): - islist = 1 - - def i2len(self, pkt, x): - return len(self.i2m(pkt, x)) - - def m2i(self, pkt, x): - res = [] - while x: - cur = [] - #while x and x[0] != b'\x00': - while x and x[0] != 0: - l = (x[0]) - cur.append(x[1:l+1]) - x = x[l+1:] - res.append(b".".join(cur)) - if x and x[0] == 0: - x = x[1:] - return res - - def i2m(self, pkt, x): - def conditionalTrailingDot(z): - if z and z[-1] == 0: - return z - return z+b'\x00' - res = b"" - x = [ i.encode('ascii') for i in x if type(i) is str ] - tmp = map(lambda y: map((lambda z: chr(len(z)).encode('ascii')+z), y.split(b'.')), x) - return b"".join(map(lambda x: conditionalTrailingDot(b"".join(x)), tmp)) - -class DHCP6OptSIPDomains(_DHCP6OptGuessPayload): #RFC3319 - name = "DHCP6 Option - SIP Servers Domain Name List" - fields_desc = [ ShortEnumField("optcode", 21, dhcp6opts), - FieldLenField("optlen", None, length_of="sipdomains"), - DomainNameListField("sipdomains", [], - length_from = lambda pkt: pkt.optlen) ] - -class DHCP6OptSIPServers(_DHCP6OptGuessPayload): #RFC3319 - name = "DHCP6 Option - SIP Servers IPv6 Address List" - fields_desc = [ ShortEnumField("optcode", 22, dhcp6opts), - FieldLenField("optlen", None, length_of="sipservers"), - IP6ListField("sipservers", [], - length_from = lambda pkt: pkt.optlen) ] - -class DHCP6OptDNSServers(_DHCP6OptGuessPayload): #RFC3646 - name = "DHCP6 Option - DNS Recursive Name Server" - fields_desc = [ ShortEnumField("optcode", 23, dhcp6opts), - FieldLenField("optlen", None, length_of="dnsservers"), - IP6ListField("dnsservers", [], - length_from = lambda pkt: pkt.optlen) ] - -class DHCP6OptDNSDomains(_DHCP6OptGuessPayload): #RFC3646 - name = "DHCP6 Option - Domain Search List option" - fields_desc = [ ShortEnumField("optcode", 24, dhcp6opts), - FieldLenField("optlen", None, length_of="dnsdomains"), - DomainNameListField("dnsdomains", [], - length_from = lambda pkt: pkt.optlen) ] - -# TODO: Implement iaprefopts correctly when provided with more -# information about it. -class DHCP6OptIAPrefix(_DHCP6OptGuessPayload): #RFC3633 - name = "DHCP6 Option - IA_PD Prefix option" - fields_desc = [ ShortEnumField("optcode", 26, dhcp6opts), - FieldLenField("optlen", None, length_of="iaprefopts", - adjust = lambda pkt,x: x+26), - IntField("preflft", 0), - IntField("validlft", 0), - ByteField("plen", 48), # TODO: Challenge that default value - IP6Field("prefix", "2001:db8::"), # At least, global and won't hurt - StrLenField("iaprefopts", b"", - length_from = lambda pkt: pkt.optlen-26) ] - -class DHCP6OptIA_PD(_DHCP6OptGuessPayload): #RFC3633 - name = "DHCP6 Option - Identity Association for Prefix Delegation" - fields_desc = [ ShortEnumField("optcode", 25, dhcp6opts), - FieldLenField("optlen", None, length_of="iapdopt", - adjust = lambda pkt,x: x+12), - IntField("iaid", 0), - IntField("T1", 0), - IntField("T2", 0), - PacketListField("iapdopt", [], DHCP6OptIAPrefix, - length_from = lambda pkt: pkt.optlen-12) ] - -class DHCP6OptNISServers(_DHCP6OptGuessPayload): #RFC3898 - name = "DHCP6 Option - NIS Servers" - fields_desc = [ ShortEnumField("optcode", 27, dhcp6opts), - FieldLenField("optlen", None, length_of="nisservers"), - IP6ListField("nisservers", [], - length_from = lambda pkt: pkt.optlen) ] - -class DHCP6OptNISPServers(_DHCP6OptGuessPayload): #RFC3898 - name = "DHCP6 Option - NIS+ Servers" - fields_desc = [ ShortEnumField("optcode", 28, dhcp6opts), - FieldLenField("optlen", None, length_of="nispservers"), - IP6ListField("nispservers", [], - length_from = lambda pkt: pkt.optlen) ] - -class DomainNameField(StrLenField): - def getfield(self, pkt, s): - l = self.length_from(pkt) - return s[l:], self.m2i(pkt,s[:l]) - - def i2len(self, pkt, x): - return len(self.i2m(pkt, x)) - - def m2i(self, pkt, x): - cur = [] - while x: - l = (x[0]) - cur.append(x[1:1+l]) - x = x[l+1:] - ret_str = b".".join(cur) - return ret_str - - def i2m(self, pkt, x): - if not x: - return b"" - tmp = b"".join(map(lambda z: chr(len(z)).encode('ascii')+z, x.split(b'.'))) - return tmp - -class DHCP6OptNISDomain(_DHCP6OptGuessPayload): #RFC3898 - name = "DHCP6 Option - NIS Domain Name" - fields_desc = [ ShortEnumField("optcode", 29, dhcp6opts), - FieldLenField("optlen", None, length_of="nisdomain"), - DomainNameField("nisdomain", "", - length_from = lambda pkt: pkt.optlen) ] - -class DHCP6OptNISPDomain(_DHCP6OptGuessPayload): #RFC3898 - name = "DHCP6 Option - NIS+ Domain Name" - fields_desc = [ ShortEnumField("optcode", 30, dhcp6opts), - FieldLenField("optlen", None, length_of="nispdomain"), - DomainNameField("nispdomain", "", - length_from= lambda pkt: pkt.optlen) ] - -class DHCP6OptSNTPServers(_DHCP6OptGuessPayload): #RFC4075 - name = "DHCP6 option - SNTP Servers" - fields_desc = [ ShortEnumField("optcode", 31, dhcp6opts), - FieldLenField("optlen", None, length_of="sntpservers"), - IP6ListField("sntpservers", [], - length_from = lambda pkt: pkt.optlen) ] - -IRT_DEFAULT=86400 -IRT_MINIMUM=600 -class DHCP6OptInfoRefreshTime(_DHCP6OptGuessPayload): #RFC4242 - name = "DHCP6 Option - Information Refresh Time" - fields_desc = [ ShortEnumField("optcode", 32, dhcp6opts), - ShortField("optlen", 4), - IntField("reftime", IRT_DEFAULT)] # One day - -class DHCP6OptBCMCSDomains(_DHCP6OptGuessPayload): #RFC4280 - name = "DHCP6 Option - BCMCS Domain Name List" - fields_desc = [ ShortEnumField("optcode", 33, dhcp6opts), - FieldLenField("optlen", None, length_of="bcmcsdomains"), - DomainNameListField("bcmcsdomains", [], - length_from = lambda pkt: pkt.optlen) ] - -class DHCP6OptBCMCSServers(_DHCP6OptGuessPayload): #RFC4280 - name = "DHCP6 Option - BCMCS Addresses List" - fields_desc = [ ShortEnumField("optcode", 34, dhcp6opts), - FieldLenField("optlen", None, length_of="bcmcsservers"), - IP6ListField("bcmcsservers", [], - length_from= lambda pkt: pkt.optlen) ] - -# TODO : Does Nothing at the moment -class DHCP6OptGeoConf(_DHCP6OptGuessPayload): #RFC-ietf-geopriv-dhcp-civil-09.txt - name = "" - fields_desc = [ ShortEnumField("optcode", 36, dhcp6opts), - FieldLenField("optlen", None, length_of="optdata"), - StrLenField("optdata", "", - length_from = lambda pkt: pkt.optlen) ] - -# TODO: see if we encounter opaque values from vendor devices -class DHCP6OptRemoteID(_DHCP6OptGuessPayload): #RFC4649 - name = "DHCP6 Option - Relay Agent Remote-ID" - fields_desc = [ ShortEnumField("optcode", 37, dhcp6opts), - FieldLenField("optlen", None, length_of="remoteid", - adjust = lambda pkt,x: x+4), - IntEnumField("enterprisenum", None, iana_enterprise_num), - StrLenField("remoteid", b"", - length_from = lambda pkt: pkt.optlen-4) ] - -# TODO : 'subscriberid' default value should be at least 1 byte long -class DHCP6OptSubscriberID(_DHCP6OptGuessPayload): #RFC4580 - name = "DHCP6 Option - Subscriber ID" - fields_desc = [ ShortEnumField("optcode", 38, dhcp6opts), - FieldLenField("optlen", None, length_of="subscriberid"), - StrLenField("subscriberid", b"", - length_from = lambda pkt: pkt.optlen) ] - -# TODO : "The data in the Domain Name field MUST be encoded -# as described in Section 8 of [5]" -class DHCP6OptClientFQDN(_DHCP6OptGuessPayload): #RFC4704 - name = "DHCP6 Option - Client FQDN" - fields_desc = [ ShortEnumField("optcode", 39, dhcp6opts), - FieldLenField("optlen", None, length_of="fqdn", - adjust = lambda pkt,x: x+1), - BitField("res", 0, 5), - FlagsField("flags", 0, 3, "SON" ), - DomainNameField("fqdn", "", - length_from = lambda pkt: pkt.optlen-1) ] - -class DHCP6OptRelayAgentERO(_DHCP6OptGuessPayload): # RFC4994 - name = "DHCP6 Option - RelayRequest Option" - fields_desc = [ ShortEnumField("optcode", 43, dhcp6opts), - FieldLenField("optlen", None, length_of="reqopts", fmt="!H"), - _OptReqListField("reqopts", [23, 24], - length_from = lambda pkt: pkt.optlen) ] - -##################################################################### -### DHCPv6 messages ### -##################################################################### - -# Some state parameters of the protocols that should probably be -# useful to have in the configuration (and keep up-to-date) -DHCP6RelayAgentUnicastAddr="" -DHCP6RelayHopCount="" -DHCP6ServerUnicastAddr="" -DHCP6ClientUnicastAddr="" -DHCP6ClientIA_TA="" -DHCP6ClientIA_NA="" -DHCP6ClientIAID="" -T1="" # Voir 2462 -T2="" # Voir 2462 -DHCP6ServerDUID="" -DHCP6CurrentTransactionID="" # devrait etre utilise pour matcher une -# reponse et mis a jour en mode client par une valeur aleatoire pour -# laquelle on attend un retour de la part d'un serveur. -DHCP6PrefVal="" # la valeur de preference a utiliser dans -# les options preference - -# Emitted by : -# - server : ADVERTISE, REPLY, RECONFIGURE, RELAY-REPL (vers relay) -# - client : SOLICIT, REQUEST, CONFIRM, RENEW, REBIND, RELEASE, DECLINE, -# INFORMATION REQUEST -# - relay : RELAY-FORW (toward server) - -class _DHCP6GuessPayload(Packet): - def guess_payload_class(self, payload): - if len(payload) > 1 : - print((payload[0])) - return get_cls(dhcp6opts.get(ord(payload[0]),"DHCP6OptUnknown"), conf.raw_layer) - return conf.raw_layer - -##################################################################### -## DHCPv6 messages sent between Clients and Servers (types 1 to 11) -# Comme specifie en section 15.1 de la RFC 3315, les valeurs de -# transaction id sont selectionnees de maniere aleatoire par le client -# a chaque emission et doivent matcher dans les reponses faites par -# les clients -class DHCP6(_DHCP6OptGuessPayload): - name = "DHCPv6 Generic Message)" - fields_desc = [ ByteEnumField("msgtype",None,dhcp6types), - X3BytesField("trid",0x000000) ] - overload_fields = { UDP: {"sport": 546, "dport": 547} } - - def hashret(self): - return struct.pack("!I", self.trid)[1:4] - -##################################################################### -# Solicit Message : sect 17.1.1 RFC3315 -# - sent by client -# - must include a client identifier option -# - the client may include IA options for any IAs to which it wants the -# server to assign address -# - The client use IA_NA options to request the assignment of -# non-temporary addresses and uses IA_TA options to request the -# assignment of temporary addresses -# - The client should include an Option Request option to indicate the -# options the client is interested in receiving (eventually -# including hints) -# - The client includes a Reconfigure Accept option if is willing to -# accept Reconfigure messages from the server. -# Le cas du send and reply est assez particulier car suivant la -# presence d'une option rapid commit dans le solicit, l'attente -# s'arrete au premier message de reponse recu ou alors apres un -# timeout. De la meme maniere, si un message Advertise arrive avec une -# valeur de preference de 255, il arrete l'attente et envoie une -# Request. -# - The client announces its intention to use DHCP authentication by -# including an Authentication option in its solicit message. The -# server selects a key for the client based on the client's DUID. The -# client and server use that key to authenticate all DHCP messages -# exchanged during the session - -class DHCP6_Solicit(DHCP6): - name = "DHCPv6 Solicit Message" - msgtype = 1 - overload_fields = { UDP: {"sport": 546, "dport": 547} } - -##################################################################### -# Advertise Message -# - sent by server -# - Includes a server identifier option -# - Includes a client identifier option -# - the client identifier option must match the client's DUID -# - transaction ID must match - -class DHCP6_Advertise(DHCP6): - name = "DHCPv6 Advertise Message" - msgtype = 2 - overload_fields = { UDP: {"sport": 547, "dport": 546} } - - def answers(self, other): - return (isinstance(other,DHCP6_Solicit) and - other.msgtype == 1 and - self.trid == other.trid) - -##################################################################### -# Request Message -# - sent by clients -# - includes a server identifier option -# - the content of Server Identifier option must match server's DUID -# - includes a client identifier option -# - must include an ORO Option (even with hints) p40 -# - can includes a reconfigure Accept option indicating whether or -# not the client is willing to accept Reconfigure messages from -# the server (p40) -# - When the server receives a Request message via unicast from a -# client to which the server has not sent a unicast option, the server -# discards the Request message and responds with a Reply message -# containinig Status Code option with the value UseMulticast, a Server -# Identifier Option containing the server's DUID, the client -# Identifier option from the client message and no other option. - -class DHCP6_Request(DHCP6): - name = "DHCPv6 Request Message" - msgtype = 3 - -##################################################################### -# Confirm Message -# - sent by clients -# - must include a clien identifier option -# - When the server receives a Confirm Message, the server determines -# whether the addresses in the Confirm message are appropriate for the -# link to which the client is attached. cf p50 - -class DHCP6_Confirm(DHCP6): - name = "DHCPv6 Confirm Message" - msgtype = 4 - -##################################################################### -# Renew Message -# - sent by clients -# - must include a server identifier option -# - content of server identifier option must match the server's identifier -# - must include a client identifier option -# - the clients includes any IA assigned to the interface that may -# have moved to a new link, along with the addresses associated with -# those IAs in its confirm messages -# - When the server receives a Renew message that contains an IA -# option from a client, it locates the client's binding and verifies -# that the information in the IA from the client matches the -# information for that client. If the server cannot find a client -# entry for the IA the server returns the IA containing no addresses -# with a status code option est to NoBinding in the Reply message. cf -# p51 pour le reste. - -class DHCP6_Renew(DHCP6): - name = "DHCPv6 Renew Message" - msgtype = 5 - -##################################################################### -# Rebind Message -# - sent by clients -# - must include a client identifier option -# cf p52 - -class DHCP6_Rebind(DHCP6): - name = "DHCPv6 Rebind Message" - msgtype = 6 - -##################################################################### -# Reply Message -# - sent by servers -# - the message must include a server identifier option -# - transaction-id field must match the value of original message -# The server includes a Rapid Commit option in the Reply message to -# indicate that the reply is in response to a solicit message -# - if the client receives a reply message with a Status code option -# with the value UseMulticast, the client records the receipt of the -# message and sends subsequent messages to the server through the -# interface on which the message was received using multicast. The -# client resends the original message using multicast -# - When the client receives a NotOnLink status from the server in -# response to a Confirm message, the client performs DHCP server -# solicitation as described in section 17 and client-initiated -# configuration as descrribed in section 18 (RFC 3315) -# - when the client receives a NotOnLink status from the server in -# response to a Request, the client can either re-issue the Request -# without specifying any addresses or restart the DHCP server -# discovery process. -# - the server must include a server identifier option containing the -# server's DUID in the Reply message - -class DHCP6_Reply(DHCP6): - name = "DHCPv6 Reply Message" - msgtype = 7 - - overload_fields = { UDP: {"sport": 547, "dport": 546} } - - def answers(self, other): - - types = (DHCP6_InfoRequest, DHCP6_Confirm, DHCP6_Rebind, DHCP6_Decline, DHCP6_Request, DHCP6_Release, DHCP6_Renew) - - return (isinstance(other, types) and - self.trid == other.trid) - -##################################################################### -# Release Message -# - sent by clients -# - must include a server identifier option -# cf p53 - -class DHCP6_Release(DHCP6): - name = "DHCPv6 Release Message" - msgtype = 8 - -##################################################################### -# Decline Message -# - sent by clients -# - must include a client identifier option -# - Server identifier option must match server identifier -# - The addresses to be declined must be included in the IAs. Any -# addresses for the IAs the client wishes to continue to use should -# not be in added to the IAs. -# - cf p54 - -class DHCP6_Decline(DHCP6): - name = "DHCPv6 Decline Message" - msgtype = 9 - -##################################################################### -# Reconfigure Message -# - sent by servers -# - must be unicast to the client -# - must include a server identifier option -# - must include a client identifier option that contains the client DUID -# - must contain a Reconfigure Message Option and the message type -# must be a valid value -# - the server sets the transaction-id to 0 -# - The server must use DHCP Authentication in the Reconfigure -# message. Autant dire que ca va pas etre le type de message qu'on va -# voir le plus souvent. - -class DHCP6_Reconf(DHCP6): - name = "DHCPv6 Reconfigure Message" - msgtype = 10 - overload_fields = { UDP: { "sport": 547, "dport": 546 } } - - -##################################################################### -# Information-Request Message -# - sent by clients when needs configuration information but no -# addresses. -# - client should include a client identifier option to identify -# itself. If it doesn't the server is not able to return client -# specific options or the server can choose to not respond to the -# message at all. The client must include a client identifier option -# if the message will be authenticated. -# - client must include an ORO of option she's interested in receiving -# (can include hints) - -class DHCP6_InfoRequest(DHCP6): - name = "DHCPv6 Information Request Message" - msgtype = 11 - -##################################################################### -# sent between Relay Agents and Servers -# -# Normalement, doit inclure une option "Relay Message Option" -# peut en inclure d'autres. -# voir section 7.1 de la 3315 - -# Relay-Forward Message -# - sent by relay agents to servers -# If the relay agent relays messages to the All_DHCP_Servers multicast -# address or other multicast addresses, it sets the Hop Limit field to -# 32. - -class DHCP6_RelayForward(_DHCP6GuessPayload,Packet): - name = "DHCPv6 Relay Forward Message (Relay Agent/Server Message)" - fields_desc = [ ByteEnumField("msgtype", 12, dhcp6types), - ByteField("hopcount", None), - IP6Field("linkaddr", "::"), - IP6Field("peeraddr", "::") ] - def hashret(self): # we filter on peer address field - return inet_pton(socket.AF_INET6, self.peeraddr) - -##################################################################### -# sent between Relay Agents and Servers -# Normalement, doit inclure une option "Relay Message Option" -# peut en inclure d'autres. -# Les valeurs des champs hop-count, link-addr et peer-addr -# sont copiees du messsage Forward associe. POur le suivi de session. -# Pour le moment, comme decrit dans le commentaire, le hashret -# se limite au contenu du champ peer address. -# Voir section 7.2 de la 3315. - -# Relay-Reply Message -# - sent by servers to relay agents -# - if the solicit message was received in a Relay-Forward message, -# the server constructs a relay-reply message with the Advertise -# message in the payload of a relay-message. cf page 37/101. Envoie de -# ce message en unicast au relay-agent. utilisation de l'adresse ip -# presente en ip source du paquet recu - -class DHCP6_RelayReply(DHCP6_RelayForward): - name = "DHCPv6 Relay Reply Message (Relay Agent/Server Message)" - msgtype = 13 - def hashret(self): # We filter on peer address field. - return inet_pton(socket.AF_INET6, self.peeraddr) - def answers(self, other): - return (isinstance(other, DHCP6_RelayForward) and - self.hopcount == other.hopcount and - self.linkaddr == other.linkaddr and - self.peeraddr == other.peeraddr ) - - -dhcp6_cls_by_type = { 1: "DHCP6_Solicit", - 2: "DHCP6_Advertise", - 3: "DHCP6_Request", - 4: "DHCP6_Confirm", - 5: "DHCP6_Renew", - 6: "DHCP6_Rebind", - 7: "DHCP6_Reply", - 8: "DHCP6_Release", - 9: "DHCP6_Decline", - 10: "DHCP6_Reconf", - 11: "DHCP6_InfoRequest", - 12: "DHCP6_RelayForward", - 13: "DHCP6_RelayReply" } - -def _dhcp6_dispatcher(x, *args, **kargs): - cls = conf.raw_layer - if len(x) >= 2: - cls = get_cls(dhcp6_cls_by_type.get((x[0]), "Raw"), conf.raw_layer) - return cls(x, *args, **kargs) - -bind_bottom_up(UDP, _dhcp6_dispatcher, { "dport": 547 } ) -bind_bottom_up(UDP, _dhcp6_dispatcher, { "dport": 546 } ) - - - -class DHCPv6_am(AnsweringMachine): - function_name = "dhcp6d" - filter = "udp and port 546 and port 547" - send_function = staticmethod(send) - def usage(self): - msg = """ -dhcp6d( dns="2001:500::1035", domain="localdomain, local", duid=None) - iface=conf.iface6, advpref=255, sntpservers=None, - sipdomains=None, sipservers=None, - nisdomain=None, nisservers=None, - nispdomain=None, nispservers=None, - bcmcsdomain=None, bcmcsservers=None) - - debug : When set, additional debugging information is printed. - - duid : some DUID class (DUID_LLT, DUID_LL or DUID_EN). If none - is provided a DUID_LLT is constructed based on the MAC - address of the sending interface and launch time of dhcp6d - answering machine. - - iface : the interface to listen/reply on if you do not want to use - conf.iface6. - - advpref : Value in [0,255] given to Advertise preference field. - By default, 255 is used. Be aware that this specific - value makes clients stops waiting for further Advertise - messages from other servers. - - dns : list of recursive DNS servers addresses (as a string or list). - By default, it is set empty and the associated DHCP6OptDNSServers - option is inactive. See RFC 3646 for details. - domain : a list of DNS search domain (as a string or list). By default, - it is empty and the associated DHCP6OptDomains option is inactive. - See RFC 3646 for details. - - sntpservers : a list of SNTP servers IPv6 addresses. By default, - it is empty and the associated DHCP6OptSNTPServers option - is inactive. - - sipdomains : a list of SIP domains. By default, it is empty and the - associated DHCP6OptSIPDomains option is inactive. See RFC 3319 - for details. - sipservers : a list of SIP servers IPv6 addresses. By default, it is - empty and the associated DHCP6OptSIPDomains option is inactive. - See RFC 3319 for details. - - nisdomain : a list of NIS domains. By default, it is empty and the - associated DHCP6OptNISDomains option is inactive. See RFC 3898 - for details. See RFC 3646 for details. - nisservers : a list of NIS servers IPv6 addresses. By default, it is - empty and the associated DHCP6OptNISServers option is inactive. - See RFC 3646 for details. - - nispdomain : a list of NIS+ domains. By default, it is empty and the - associated DHCP6OptNISPDomains option is inactive. See RFC 3898 - for details. - nispservers : a list of NIS+ servers IPv6 addresses. By default, it is - empty and the associated DHCP6OptNISServers option is inactive. - See RFC 3898 for details. - - bcmcsdomain : a list of BCMCS domains. By default, it is empty and the - associated DHCP6OptBCMCSDomains option is inactive. See RFC 4280 - for details. - bcmcsservers : a list of BCMCS servers IPv6 addresses. By default, it is - empty and the associated DHCP6OptBCMCSServers option is inactive. - See RFC 4280 for details. - - If you have a need for others, just ask ... or provide a patch.""" - print(msg) - - def parse_options(self, dns="2001:500::1035", domain="localdomain, local", - startip="2001:db8::1", endip="2001:db8::20", duid=None, - sntpservers=None, sipdomains=None, sipservers=None, - nisdomain=None, nisservers=None, nispdomain=None, - nispservers=None, bcmcsservers=None, bcmcsdomains=None, - iface=None, debug=0, advpref=255): - def norm_list(val, param_name): - if val is None: - return None - if type(val) is list: - return val - elif type(val) is str: - l = val.split(',') - return map(lambda x: x.strip(), l) - else: - print("Bad '%s' parameter provided." % param_name) - self.usage() - return -1 - - if iface is None: - iface = conf.iface6 - - self.debug = debug - - # Dictionary of provided DHCPv6 options, keyed by option type - self.dhcpv6_options={} - - for o in [(dns, "dns", 23, lambda x: DHCP6OptDNSServers(dnsservers=x)), - (domain, "domain", 24, lambda x: DHCP6OptDNSDomains(dnsdomains=x)), - (sntpservers, "sntpservers", 31, lambda x: DHCP6OptSNTPServers(sntpservers=x)), - (sipservers, "sipservers", 22, lambda x: DHCP6OptSIPServers(sipservers=x)), - (sipdomains, "sipdomains", 21, lambda x: DHCP6OptSIPDomains(sipdomains=x)), - (nisservers, "nisservers", 27, lambda x: DHCP6OptNISServers(nisservers=x)), - (nisdomain, "nisdomain", 29, lambda x: DHCP6OptNISDomain(nisdomain=(x+[""])[0])), - (nispservers, "nispservers", 28, lambda x: DHCP6OptNISPServers(nispservers=x)), - (nispdomain, "nispdomain", 30, lambda x: DHCP6OptNISPDomain(nispdomain=(x+[""])[0])), - (bcmcsservers, "bcmcsservers", 33, lambda x: DHCP6OptBCMCSServers(bcmcsservers=x)), - (bcmcsdomains, "bcmcsdomains", 34, lambda x: DHCP6OptBCMCSDomains(bcmcsdomains=x))]: - - opt = norm_list(o[0], o[1]) - if opt == -1: # Usage() was triggered - return False - elif opt is None: # We won't return that option - pass - else: - self.dhcpv6_options[o[2]] = o[3](opt) - - if self.debug: - print("\n[+] List of active DHCPv6 options:") - opts = self.dhcpv6_options.keys() - opts.sort() - for i in opts: - print(" %d: %s" % (i, repr(self.dhcpv6_options[i]))) - - # Preference value used in Advertise. - self.advpref = advpref - - # IP Pool - self.startip = startip - self.endip = endip - # XXX TODO Check IPs are in same subnet - - #### - # The interface we are listening/replying on - self.iface = iface - - #### - # Generate a server DUID - if duid is not None: - self.duid = duid - else: - # Timeval - from time import gmtime, strftime, mktime - epoch = (2000, 1, 1, 0, 0, 0, 5, 1, 0) - delta = mktime(epoch) - mktime(gmtime(0)) - timeval = time.time() - delta - - # Mac Address - rawmac = get_if_raw_hwaddr(iface) - mac = ":".join(map(lambda x: "%.02x" % x, rawmac)) - - self.duid = DUID_LLT(timeval = timeval, lladdr = mac) - - if self.debug: - print("\n[+] Our server DUID:" ) - self.duid.show(label_lvl=" "*4) - - #### - # Find the source address we will use - #l = filter(lambda x: x[2] == iface and in6_islladdr(x[0]), in6_getifaddr()) - l = [ x for x in in6_getifaddr() if x[2] == iface and in6_islladdr(x[0]) ] - if not l: - warning("Unable to get a Link-Local address") - return - - self.src_addr = l[0][0] - - #### - # Our leases - self.leases = {} - - - if self.debug: - print("\n[+] Starting DHCPv6 service on %s:" % self.iface ) - - def is_request(self, p): - if not IPv6 in p: - return False - - src = p[IPv6].src - dst = p[IPv6].dst - - p = p[IPv6].payload - if not isinstance(p, UDP) or p.sport != 546 or p.dport != 547 : - return False - - p = p.payload - if not isinstance(p, DHCP6): - return False - - # Message we considered client messages : - # Solicit (1), Request (3), Confirm (4), Renew (5), Rebind (6) - # Decline (9), Release (8), Information-request (11), - if not (p.msgtype in [1, 3, 4, 5, 6, 8, 9, 11]): - return False - - # Message validation following section 15 of RFC 3315 - - if ((p.msgtype == 1) or # Solicit - (p.msgtype == 6) or # Rebind - (p.msgtype == 4)): # Confirm - if ((not DHCP6OptClientId in p) or - DHCP6OptServerId in p): - return False - - if (p.msgtype == 6 or # Rebind - p.msgtype == 4): # Confirm - # XXX We do not reply to Confirm or Rebind as we - # XXX do not support address assignment - return False - - elif (p.msgtype == 3 or # Request - p.msgtype == 5 or # Renew - p.msgtype == 8): # Release - - # Both options must be present - if ((not DHCP6OptServerId in p) or - (not DHCP6OptClientId in p)): - return False - # provided server DUID must match ours - duid = p[DHCP6OptServerId].duid - if (type(duid) != type(self.duid)): - return False - if bytes(duid) != bytes(self.duid): - return False - - if (p.msgtype == 5 or # Renew - p.msgtype == 8): # Release - # XXX We do not reply to Renew or Release as we - # XXX do not support address assignment - return False - - elif p.msgtype == 9: # Decline - # XXX We should check if we are tracking that client - if not self.debug: - return False - - bo = Color.bold - g = Color.green + bo - b = Color.blue + bo - n = Color.normal - r = Color.red - - vendor = in6_addrtovendor(src) - if (vendor and vendor != "UNKNOWN"): - vendor = " [" + b + vendor + n + "]" - else: - vendor = "" - src = bo + src + n - - it = p - addrs = [] - while it: - l = [] - if isinstance(it, DHCP6OptIA_NA): - l = it.ianaopts - elif isinstance(it, DHCP6OptIA_TA): - l = it.iataopts - - #opsaddr = filter(lambda x: isinstance(x, DHCP6OptIAAddress),l) - opsaddr = [ x for x in l if isinstance(x, DHCP6OptIAAddress) ] - a=map(lambda x: x.addr, opsaddr) - addrs += a - it = it.payload - - addrs = map(lambda x: bo + x + n, addrs) - if debug: - msg = r + "[DEBUG]" + n + " Received " + g + "Decline" + n - msg += " from " + bo + src + vendor + " for " - msg += ", ".join(addrs)+ n - print(msg) - - # See sect 18.1.7 - - # Sent by a client to warn us she has determined - # one or more addresses assigned to her is already - # used on the link. - # We should simply log that fact. No messaged should - # be sent in return. - - # - Message must include a Server identifier option - # - the content of the Server identifier option must - # match the server's identifier - # - the message must include a Client Identifier option - return False - - elif p.msgtype == 11: # Information-Request - if DHCP6OptServerId in p: - duid = p[DHCP6OptServerId].duid - if (type(duid) != type(self.duid)): - return False - if bytes(duid) != bytes(self.duid): - return False - if ((DHCP6OptIA_NA in p) or - (DHCP6OptIA_TA in p) or - (DHCP6OptIA_PD in p)): - return False - else: - return False - - return True - - def print_reply(self, req, reply): - def norm(s): - if s.startswith("DHCPv6 "): - s = s[7:] - if s.endswith(" Message"): - s = s[:-8] - return s - - if reply is None: - return - - bo = Color.bold - g = Color.green + bo - b = Color.blue + bo - n = Color.normal - reqtype = g + norm(req.getlayer(UDP).payload.name) + n - reqsrc = req.getlayer(IPv6).src - vendor = in6_addrtovendor(reqsrc) - if (vendor and vendor != "UNKNOWN"): - vendor = " [" + b + vendor + n + "]" - else: - vendor = "" - reqsrc = bo + reqsrc + n - reptype = g + norm(reply.getlayer(UDP).payload.name) + n - - print("Sent %s answering to %s from %s%s" % (reptype, reqtype, reqsrc, vendor)) - - def make_reply(self, req): - req_mac_src = req.src - req_mac_dst = req.dst - - p = req[IPv6] - req_src = p.src - req_dst = p.dst - - p = p.payload.payload - - msgtype = p.msgtype - trid = p.trid - - if msgtype == 1: # SOLICIT (See Sect 17.1 and 17.2 of RFC 3315) - - # XXX We don't support address or prefix assignment - # XXX We also do not support relay function --arno - - client_duid = p[DHCP6OptClientId].duid - resp = IPv6(src=self.src_addr, dst=req_src) - resp /= UDP(sport=547, dport=546) - - if p.haslayer(DHCP6OptRapidCommit): - # construct a Reply packet - resp /= DHCP6_Reply(trid=trid) - resp /= DHCP6OptRapidCommit() # See 17.1.2 - resp /= DHCP6OptServerId(duid = self.duid) - resp /= DHCP6OptClientId(duid = client_duid) - - else: # No Rapid Commit in the packet. Reply with an Advertise - - if (p.haslayer(DHCP6OptIA_NA) or - p.haslayer(DHCP6OptIA_TA)): - # XXX We don't assign addresses at the moment - msg = "Scapy6 dhcp6d does not support address assignment" - resp /= DHCP6_Advertise(trid = trid) - resp /= DHCP6OptStatusCode(statuscode=2, statusmsg=msg) - resp /= DHCP6OptServerId(duid = self.duid) - resp /= DHCP6OptClientId(duid = client_duid) - - elif p.haslayer(DHCP6OptIA_PD): - # XXX We don't assign prefixes at the moment - msg = "Scapy6 dhcp6d does not support prefix assignment" - resp /= DHCP6_Advertise(trid = trid) - resp /= DHCP6OptStatusCode(statuscode=6, statusmsg=msg) - resp /= DHCP6OptServerId(duid = self.duid) - resp /= DHCP6OptClientId(duid = client_duid) - - else: # Usual case, no request for prefixes or addresse - resp /= DHCP6_Advertise(trid = trid) - resp /= DHCP6OptPref(prefval = self.advpref) - resp /= DHCP6OptServerId(duid = self.duid) - resp /= DHCP6OptClientId(duid = client_duid) - resp /= DHCP6OptReconfAccept() - - # See which options should be included - reqopts = [] - if p.haslayer(DHCP6OptOptReq): # add only asked ones - reqopts = p[DHCP6OptOptReq].reqopts - for o in self.dhcpv6_options.keys(): - if o in reqopts: - resp /= self.dhcpv6_options[o] - else: # advertise everything we have available - for o in self.dhcpv6_options.keys(): - resp /= self.dhcpv6_options[o] - - return resp - - elif msgtype == 3: #REQUEST (INFO-REQUEST is further below) - client_duid = p[DHCP6OptClientId].duid - resp = IPv6(src=self.src_addr, dst=req_src) - resp /= UDP(sport=547, dport=546) - resp /= DHCP6_Solicit(trid=trid) - resp /= DHCP6OptServerId(duid = self.duid) - resp /= DHCP6OptClientId(duid = client_duid) - - # See which options should be included - reqopts = [] - if p.haslayer(DHCP6OptOptReq): # add only asked ones - reqopts = p[DHCP6OptOptReq].reqopts - for o in self.dhcpv6_options.keys(): - if o in reqopts: - resp /= self.dhcpv6_options[o] - else: - # advertise everything we have available. - # Should not happen has clients MUST include - # and ORO in requests (sec 18.1.1) -- arno - for o in self.dhcpv6_options.keys(): - resp /= self.dhcpv6_options[o] - - return resp - - elif msgtype == 4: # CONFIRM - # see Sect 18.1.2 - - # Client want to check if addresses it was assigned - # are still appropriate - - # Server must discard any Confirm messages that - # do not include a Client Identifier option OR - # THAT DO INCLUDE a Server Identifier Option - - # XXX we must discard the SOLICIT if it is received with - # a unicast destination address - - pass - - elif msgtype == 5: # RENEW - # see Sect 18.1.3 - - # Clients want to extend lifetime of assigned addresses - # and update configuration parameters. This message is sent - # specifically to the server that provided her the info - - # - Received message must include a Server Identifier - # option. - # - the content of server identifier option must match - # the server's identifier. - # - the message must include a Client identifier option - - pass - - elif msgtype == 6: # REBIND - # see Sect 18.1.4 - - # Same purpose as the Renew message but sent to any - # available server after he received no response - # to its previous Renew message. - - - # - Message must include a Client Identifier Option - # - Message can't include a Server identifier option - - # XXX we must discard the SOLICIT if it is received with - # a unicast destination address - - pass - - elif msgtype == 8: # RELEASE - # See section 18.1.6 - - # Message is sent to the server to indicate that - # she will no longer use the addresses that was assigned - # We should parse the message and verify our dictionary - # to log that fact. - - - # - The message must include a server identifier option - # - The content of the Server Identifier option must - # match the server's identifier - # - the message must include a Client Identifier option - - pass - - elif msgtype == 9: # DECLINE - # See section 18.1.7 - pass - - elif msgtype == 11: # INFO-REQUEST - client_duid = None - if not p.haslayer(DHCP6OptClientId): - if self.debug: - warning("Received Info Request message without Client Id option") - else: - client_duid = p[DHCP6OptClientId].duid - - resp = IPv6(src=self.src_addr, dst=req_src) - resp /= UDP(sport=547, dport=546) - resp /= DHCP6_Reply(trid=trid) - resp /= DHCP6OptServerId(duid = self.duid) - - if client_duid: - resp /= DHCP6OptClientId(duid = client_duid) - - # Stack requested options if available - reqopts = [] - if p.haslayer(DHCP6OptOptReq): - reqopts = p[DHCP6OptOptReq].reqopts - for o in self.dhcpv6_options.keys(): - resp /= self.dhcpv6_options[o] - - return resp - - else: - # what else ? - pass - - # - We won't support reemission - # - We won't support relay role, nor relay forwarded messages - # at the beginning diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/dns.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/dns.py deleted file mode 100644 index 8a01e273..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/dns.py +++ /dev/null @@ -1,712 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -DNS: Domain Name System. -""" - -import socket,struct - -from scapy.packet import * -from scapy.fields import * -from scapy.ansmachine import * -from scapy.layers.inet import IP, UDP -from scapy.utils import str2bytes - -class DNSStrField(StrField): - - def h2i(self, pkt, x): - if type(x) == str: - x = x.encode('ascii') - if x == b"": - return b"." - return x - - def i2m(self, pkt, x): - if type(x) == str: - x = x.encode('ascii') - if x == b".": - return b"\x00" - - x = [k[:63] for k in x.split(b".")] # Truncate chunks that cannot be encoded (more than 63 bytes..) - x = map(lambda y: bytes([len(y)]) + y, x) - x = b"".join(x) - if x[-1] != 0: - x += b"\x00" - return x - - def getfield(self, pkt, s): - n = b"" - - #if ord(s[0]) == 0: - if (s[0]) == 0: - return s[1:], b"." - - while 1: - #l = ord(s[0]) - l = (s[0]) - s = s[1:] - if not l: - break - if l & 0xc0: - raise Scapy_Exception("DNS message can't be compressed at this point!") - else: - n += s[:l]+b"." - s = s[l:] - return s, n - - -class DNSRRCountField(ShortField): - holds_packets=1 - def __init__(self, name, default, rr): - ShortField.__init__(self, name, default) - self.rr = rr - def _countRR(self, pkt): - x = getattr(pkt,self.rr) - i = 0 - while isinstance(x, DNSRR) or isinstance(x, DNSQR) or isdnssecRR(x): - x = x.payload - i += 1 - return i - - def i2m(self, pkt, x): - if x is None: - x = self._countRR(pkt) - return x - def i2h(self, pkt, x): - if x is None: - x = self._countRR(pkt) - return x - - -def DNSgetstr(s,p): - name = b"" - q = 0 - jpath = [p] - while 1: - if p >= len(s): - warning("DNS RR prematured end (ofs=%i, len=%i)"%(p,len(s))) - break - #l = ord(s[p]) - l = s[p] - p += 1 - if l & 0xc0: - if not q: - q = p+1 - if p >= len(s): - warning("DNS incomplete jump token at (ofs=%i)" % p) - break - p = ((l & 0x3f) << 8) + s[p] - 12 - if p in jpath: - warning("DNS decompression loop detected") - break - jpath.append(p) - continue - elif l > 0: - name += s[p:p+l]+b"." - p += l - continue - break - if q: - p = q - return name,p - - -class DNSRRField(StrField): - holds_packets=1 - def __init__(self, name, countfld, passon=1): - StrField.__init__(self, name, None) - self.countfld = countfld - self.passon = passon - def i2m(self, pkt, x): - if x is None: - return b"" - return bytes(x) - def decodeRR(self, name, s, p): - ret = s[p:p+10] - type,cls,ttl,rdlen = struct.unpack("!HHIH", ret) - p += 10 - rr = DNSRR(b"\x00"+ret+s[p:p+rdlen]) - if type in [2, 3, 4, 5]: - rr.rdata = DNSgetstr(s,p)[0] - del(rr.rdlen) - elif type in dnsRRdispatcher.keys(): - rr = dnsRRdispatcher[type](b"\x00"+ret+s[p:p+rdlen]) - else: - del(rr.rdlen) - - p += rdlen - - rr.rrname = name - return rr,p - def getfield(self, pkt, s): - if type(s) is tuple : - s,p = s - else: - p = 0 - ret = None - c = getattr(pkt, self.countfld) - if c > len(s): - warning("wrong value: DNS.%s=%i" % (self.countfld,c)) - return s,b"" - while c: - c -= 1 - name,p = DNSgetstr(s,p) - rr,p = self.decodeRR(name, s, p) - if ret is None: - ret = rr - else: - ret.add_payload(rr) - if self.passon: - return (s,p),ret - else: - return s[p:],ret - - -class DNSQRField(DNSRRField): - holds_packets=1 - def decodeRR(self, name, s, p): - ret = s[p:p+4] - p += 4 - rr = DNSQR(b"\x00"+ret) - rr.qname = name - return rr,p - - - -class RDataField(StrLenField): - def m2i(self, pkt, s): - family = None - if pkt.type == 1: # A - family = socket.AF_INET - elif pkt.type == 12: # PTR - s = DNSgetstr(s, 0)[0] - elif pkt.type == 16: # TXT - ret_s = b"" - tmp_s = s - # RDATA contains a list of strings, each are prepended with - # a byte containing the size of the following string. - while tmp_s: - tmp_len = struct.unpack("!B", bytes([tmp_s[0]]))[0] + 1 - if tmp_len > len(tmp_s): - warning("DNS RR TXT prematured end of character-string (size=%i, remaining bytes=%i)" % (tmp_len, len(tmp_s))) - ret_s += tmp_s[1:tmp_len] - tmp_s = tmp_s[tmp_len:] - s = ret_s - elif pkt.type == 28: # AAAA - family = socket.AF_INET6 - if family is not None: - s = inet_ntop(family, s) - return s - def i2m(self, pkt, s): - if pkt.type == 1: # A - if s: - if type(s) is bytes: - s = s.decode('ascii') - s = inet_aton(s) - elif pkt.type in [2,3,4,5]: # NS, MD, MF, CNAME - s = b"".join(map(lambda x: bytes([len(x)]) + x, s.split(b"."))) - #if ord(s[-1]): - if s[-1]: - s += b"\x00" - elif pkt.type == 16: # TXT - if s: - ret_s = b"" - # The initial string must be splitted into a list of strings - # prepended with theirs sizes. - while len(s) >= 255: - ret_s += b"\xff" + s[:255] - s = s[255:] - # The remaining string is less than 255 bytes long - if len(s): - ret_s += struct.pack("!B", len(s)) + s - s = ret_s - elif pkt.type == 28: # AAAA - if s: - s = inet_pton(socket.AF_INET6, s) - return s - -class RDLenField(Field): - def __init__(self, name): - Field.__init__(self, name, None, "H") - def i2m(self, pkt, x): - if x is None: - rdataf = pkt.get_field("rdata") - x = len(rdataf.i2m(pkt, pkt.rdata)) - return x - def i2h(self, pkt, x): - if x is None: - rdataf = pkt.get_field("rdata") - x = len(rdataf.i2m(pkt, pkt.rdata)) - return x - - -class DNS(Packet): - name = "DNS" - fields_desc = [ ShortField("id", 0), - BitField("qr", 0, 1), - BitEnumField("opcode", 0, 4, {0:"QUERY",1:"IQUERY",2:"STATUS"}), - BitField("aa", 0, 1), - BitField("tc", 0, 1), - BitField("rd", 0, 1), - BitField("ra", 0, 1), - BitField("z", 0, 1), - # AD and CD bits are defined in RFC 2535 - BitField("ad", 0, 1), # Authentic Data - BitField("cd", 0, 1), # Checking Disabled - BitEnumField("rcode", 0, 4, {0:"ok", 1:"format-error", 2:"server-failure", 3:"name-error", 4:"not-implemented", 5:"refused"}), - DNSRRCountField("qdcount", None, "qd"), - DNSRRCountField("ancount", None, "an"), - DNSRRCountField("nscount", None, "ns"), - DNSRRCountField("arcount", None, "ar"), - DNSQRField("qd", "qdcount"), - DNSRRField("an", "ancount"), - DNSRRField("ns", "nscount"), - DNSRRField("ar", "arcount",0) ] - def answers(self, other): - return (isinstance(other, DNS) - and self.id == other.id - and self.qr == 1 - and other.qr == 0) - - def mysummary(self): - type = ["Qry","Ans"][self.qr] - name = "" - if self.qr: - type = "Ans" - if self.ancount > 0 and isinstance(self.an, DNSRR): - name = ' "%s"' % self.an.getstrval("rdata") - else: - type = "Qry" - if self.qdcount > 0 and isinstance(self.qd, DNSQR): - name = ' "%s"' % self.qd.getstrval("qname") - return 'DNS %s%s ' % (type, name) - -dnstypes = { 0:"ANY", 255:"ALL", - 1:"A", 2:"NS", 3:"MD", 4:"MF", 5:"CNAME", 6:"SOA", 7: "MB", 8:"MG", - 9:"MR",10:"NULL",11:"WKS",12:"PTR",13:"HINFO",14:"MINFO",15:"MX",16:"TXT", - 17:"RP",18:"AFSDB",28:"AAAA", 33:"SRV",38:"A6",39:"DNAME", - 41:"OPT", 43:"DS", 46:"RRSIG", 47:"NSEC", 48:"DNSKEY", - 50: "NSEC3", 51: "NSEC3PARAM", 32769:"DLV" } - -dnsqtypes = {251:"IXFR",252:"AXFR",253:"MAILB",254:"MAILA",255:"ALL"} -dnsqtypes.update(dnstypes) -dnsclasses = {1: 'IN', 2: 'CS', 3: 'CH', 4: 'HS', 255: 'ANY'} - - -class DNSQR(Packet): - name = "DNS Question Record" - show_indent=0 - fields_desc = [ DNSStrField("qname",b""), - ShortEnumField("qtype", 1, dnsqtypes), - ShortEnumField("qclass", 1, dnsclasses) ] - - - -# RFC 2671 - Extension Mechanisms for DNS (EDNS0) - -class EDNS0TLV(Packet): - name = "DNS EDNS0 TLV" - fields_desc = [ ShortEnumField("optcode", 0, { 0: "Reserved", 1: "LLQ", 2: "UL", 3: "NSID", 4: "Reserved", 5: "PING" }), - FieldLenField("optlen", None, "optdata", fmt="H"), - StrLenField("optdata", b"", length_from=lambda pkt: pkt.optlen) ] - - def extract_padding(self, p): - return b"", p - -class DNSRROPT(Packet): - name = "DNS OPT Resource Record" - fields_desc = [ DNSStrField("rrname",b""), - ShortEnumField("type", 41, dnstypes), - ShortField("rclass", 4096), - ByteField("extrcode", 0), - ByteField("version", 0), - # version 0 means EDNS0 - BitEnumField("z", 32768, 16, { 32768: "D0" }), - # D0 means DNSSEC OK from RFC 3225 - FieldLenField("rdlen", None, length_of="rdata", fmt="H"), - PacketListField("rdata", [], EDNS0TLV, length_from=lambda pkt: pkt.rdlen) ] - -# RFC 4034 - Resource Records for the DNS Security Extensions - -# 09/2013 from http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml -dnssecalgotypes = { 0:"Reserved", 1:"RSA/MD5", 2:"Diffie-Hellman", 3:"DSA/SHA-1", - 4:"Reserved", 5:"RSA/SHA-1", 6:"DSA-NSEC3-SHA1", - 7:"RSASHA1-NSEC3-SHA1", 8:"RSA/SHA-256", 9:"Reserved", - 10:"RSA/SHA-512", 11:"Reserved", 12:"GOST R 34.10-2001", - 13:"ECDSA Curve P-256 with SHA-256", 14: "ECDSA Curve P-384 with SHA-384", - 252:"Reserved for Indirect Keys", 253:"Private algorithms - domain name", - 254:"Private algorithms - OID", 255:"Reserved" } - -# 09/2013 from http://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml -dnssecdigesttypes = { 0:"Reserved", 1:"SHA-1", 2:"SHA-256", 3:"GOST R 34.11-94", 4:"SHA-384" } - - -class TimeField(IntField): - - def any2i(self, pkt, x): - if type(x) == str: - import time, calendar - t = time.strptime(x, "%Y%m%d%H%M%S") - return int(calendar.timegm(t)) - return x - - def i2repr(self, pkt, x): - import time - x = self.i2h(pkt, x) - t = time.strftime("%Y%m%d%H%M%S", time.gmtime(x)) - return "%s (%d)" % (t ,x) - - -def bitmap2RRlist(bitmap): - """ - Decode the 'Type Bit Maps' field of the NSEC Resource Record into an - integer list. - """ - # RFC 4034, 4.1.2. The Type Bit Maps Field - - RRlist = [] - - while bitmap: - - if len(bitmap) < 2: - warning("bitmap too short (%i)" % len(bitmap)) - return - - #window_block = ord(bitmap[0]) # window number - window_block = (bitmap[0]) # window number - offset = 256*window_block # offset of the Ressource Record - #bitmap_len = ord(bitmap[0]) # length of the bitmap in bytes - bitmap_len = (bitmap[1]) # length of the bitmap in bytes - - if bitmap_len <= 0 or bitmap_len > 32: - warning("bitmap length is no valid (%i)" % bitmap_len) - return - - tmp_bitmap = bitmap[2:2+bitmap_len] - - # Let's compare each bit of tmp_bitmap and compute the real RR value - for b in range(len(tmp_bitmap)): - v = 128 - for i in range(8): - #if ord(tmp_bitmap[b]) & v: - if (tmp_bitmap[b]) & v: - # each of the RR is encoded as a bit - RRlist += [ offset + b*8 + i ] - v = v >> 1 - -# Next block if any - bitmap = bitmap[2+bitmap_len:] - - return RRlist - - -def RRlist2bitmap(lst): - """ - Encode a list of integers representing Resource Records to a bitmap field - used in the NSEC Resource Record. - """ - # RFC 4034, 4.1.2. The Type Bit Maps Field - - import math - - bitmap = b"" - lst = list(set(lst)) - lst.sort() - - #lst = filter(lambda x: x <= 65535, lst) - #lst = map(lambda x: abs(x), lst) - lst = [ abs(x) for x in lst if x<= 65535 ] - - # number of window blocks - max_window_blocks = int(math.ceil(lst[-1] / 256.)) - min_window_blocks = int(math.floor(lst[0] / 256.)) - if min_window_blocks == max_window_blocks: - max_window_blocks += 1 - - for wb in range(min_window_blocks, max_window_blocks+1): - # First, filter out RR not encoded in the current window block - # i.e. keep everything between 256*wb <= 256*(wb+1) - #rrlist = filter(lambda x: 256*wb <= x and x < 256*(wb+1), lst) - rrlist = [ x for x in lst if 256*wb <= x and x < 256*(wb+1) ] - rrlist.sort() - if rrlist == []: - continue - - # Compute the number of bytes used to store the bitmap - if rrlist[-1] == 0: # only one element in the list - bs = 1 - else: - max = rrlist[-1] - 256*wb - #bs = int(math.ceil(max / 8)) + 1 # use at least 1 byte - bs = int(max // 8) + 1 # use at least 1 byte - if bs > 32: # Don't encode more than 256 bits / values - bs = 32 - - bitmap += struct.pack("B", wb) - bitmap += struct.pack("B", bs) - - # Generate the bitmap - for tmp in range(bs): - v = 0 - # Remove out of range Ressource Records - #tmp_rrlist = filter(lambda x: 256*wb+8*tmp <= x and x < 256*wb+8*tmp+8, rrlist) - tmp_rrlist = [ x for x in rrlist if 256*wb+8*tmp <= x and x < 256*wb+8*tmp+8 ] - if not tmp_rrlist == []: - # 1. rescale to fit into 8 bits - tmp_rrlist = map(lambda x: (x-256*wb)-(tmp*8), tmp_rrlist) - # 2. x gives the bit position ; compute the corresponding value - tmp_rrlist = map(lambda x: 2**(7-x) , tmp_rrlist) - # 3. sum everything - #v = reduce(lambda x,y: x+y, tmp_rrlist) - v = sum(tmp_rrlist) - bitmap += struct.pack("B", v) - - return bitmap - - -class RRlistField(StrField): - def h2i(self, pkt, x): - if type(x) == list: - return RRlist2bitmap(x) - return x - - def i2repr(self, pkt, x): - x = self.i2h(pkt, x) - rrlist = bitmap2RRlist(x) - return [ dnstypes.get(rr, rr) for rr in rrlist ] - - -class _DNSRRdummy(Packet): - name = "Dummy class that implements post_build() for Ressource Records" - def post_build(self, pkt, pay): - if not self.rdlen == None: - return pkt - - lrrname = len(self.fields_desc[0].i2m(b"", self.getfieldval("rrname"))) - l = len(pkt) - lrrname - 10 - pkt = pkt[:lrrname+8] + struct.pack("!H", l) + pkt[lrrname+8+2:] - - return pkt - -class DNSRRSOA(_DNSRRdummy): - name = "DNS SOA Resource Record" - fields_desc = [ DNSStrField("rrname",b""), - ShortEnumField("type", 6, dnstypes), - ShortEnumField("rclass", 1, dnsclasses), - IntField("ttl", 0), - ShortField("rdlen", None), - DNSStrField("mname", b""), - DNSStrField("rname", b""), - IntField("serial", 0), - IntField("refresh", 0), - IntField("retry", 0), - IntField("expire", 0), - IntField("minimum", 0) - ] - -class DNSRRRSIG(_DNSRRdummy): - name = "DNS RRSIG Resource Record" - fields_desc = [ DNSStrField("rrname",b""), - ShortEnumField("type", 46, dnstypes), - ShortEnumField("rclass", 1, dnsclasses), - IntField("ttl", 0), - ShortField("rdlen", None), - ShortEnumField("typecovered", 1, dnstypes), - ByteEnumField("algorithm", 5, dnssecalgotypes), - ByteField("labels", 0), - IntField("originalttl", 0), - TimeField("expiration", 0), - TimeField("inception", 0), - ShortField("keytag", 0), - DNSStrField("signersname", b""), - StrField("signature", b"") - ] - - -class DNSRRNSEC(_DNSRRdummy): - name = "DNS NSEC Resource Record" - fields_desc = [ DNSStrField("rrname",b""), - ShortEnumField("type", 47, dnstypes), - ShortEnumField("rclass", 1, dnsclasses), - IntField("ttl", 0), - ShortField("rdlen", None), - DNSStrField("nextname", b""), - RRlistField("typebitmaps", b"") - ] - - -class DNSRRDNSKEY(_DNSRRdummy): - name = "DNS DNSKEY Resource Record" - fields_desc = [ DNSStrField("rrname",b""), - ShortEnumField("type", 48, dnstypes), - ShortEnumField("rclass", 1, dnsclasses), - IntField("ttl", 0), - ShortField("rdlen", None), - FlagsField("flags", 256, 16, "S???????Z???????"), - # S: Secure Entry Point - # Z: Zone Key - ByteField("protocol", 3), - ByteEnumField("algorithm", 5, dnssecalgotypes), - StrField("publickey", b"") - ] - - -class DNSRRDS(_DNSRRdummy): - name = "DNS DS Resource Record" - fields_desc = [ DNSStrField("rrname",b""), - ShortEnumField("type", 43, dnstypes), - ShortEnumField("rclass", 1, dnsclasses), - IntField("ttl", 0), - ShortField("rdlen", None), - ShortField("keytag", 0), - ByteEnumField("algorithm", 5, dnssecalgotypes), - ByteEnumField("digesttype", 5, dnssecdigesttypes), - StrField("digest", b"") - ] - - -# RFC 5074 - DNSSEC Lookaside Validation (DLV) -class DNSRRDLV(DNSRRDS): - name = "DNS DLV Resource Record" - def __init__(self, *args, **kargs): - DNSRRDS.__init__(self, *args, **kargs) - if not kargs.get('type', 0): - self.type = 32769 - -# RFC 5155 - DNS Security (DNSSEC) Hashed Authenticated Denial of Existence -class DNSRRNSEC3(_DNSRRdummy): - name = "DNS NSEC3 Resource Record" - fields_desc = [ DNSStrField("rrname",b""), - ShortEnumField("type", 50, dnstypes), - ShortEnumField("rclass", 1, dnsclasses), - IntField("ttl", 0), - ShortField("rdlen", None), - ByteField("hashalg", 0), - BitEnumField("flags", 0, 8, {1:"Opt-Out"}), - ShortField("iterations", 0), - FieldLenField("saltlength", 0, fmt="!B", length_of="salt"), - StrLenField("salt", b"", length_from=lambda x: x.saltlength), - FieldLenField("hashlength", 0, fmt="!B", length_of="nexthashedownername"), - StrLenField("nexthashedownername", b"", length_from=lambda x: x.hashlength), - RRlistField("typebitmaps", b"") - ] - - -class DNSRRNSEC3PARAM(_DNSRRdummy): - name = "DNS NSEC3PARAM Resource Record" - fields_desc = [ DNSStrField("rrname",b""), - ShortEnumField("type", 51, dnstypes), - ShortEnumField("rclass", 1, dnsclasses), - IntField("ttl", 0), - ShortField("rdlen", None), - ByteField("hashalg", 0), - ByteField("flags", 0), - ShortField("iterations", 0), - FieldLenField("saltlength", 0, fmt="!B", length_of="salt"), - StrLenField("salt", b"", length_from=lambda pkt: pkt.saltlength) - ] - - -dnssecclasses = [ DNSRROPT, DNSRRRSIG, DNSRRDLV, DNSRRDNSKEY, DNSRRNSEC, DNSRRDS, DNSRRNSEC3, DNSRRNSEC3PARAM ] - -def isdnssecRR(obj): - list = [ isinstance (obj, cls) for cls in dnssecclasses ] - ret = False - for i in list: - ret = ret or i - return ret - -dnsRRdispatcher = { #6: DNSRRSOA, - 41: DNSRROPT, # RFC 1671 - 43: DNSRRDS, # RFC 4034 - 46: DNSRRRSIG, # RFC 4034 - 47: DNSRRNSEC, # RFC 4034 - 48: DNSRRDNSKEY, # RFC 4034 - 50: DNSRRNSEC3, # RFC 5155 - 51: DNSRRNSEC3PARAM, # RFC 5155 - 32769: DNSRRDLV # RFC 4431 - } - -class DNSRR(Packet): - name = "DNS Resource Record" - show_indent=0 - fields_desc = [ DNSStrField("rrname",""), - ShortEnumField("type", 1, dnstypes), - ShortEnumField("rclass", 1, dnsclasses), - IntField("ttl", 0), - RDLenField("rdlen"), - RDataField("rdata", "", length_from=lambda pkt:pkt.rdlen) ] - -bind_layers( UDP, DNS, dport=53) -bind_layers( UDP, DNS, sport=53) - - -@conf.commands.register -def dyndns_add(nameserver, name, rdata, type="A", ttl=10): - """Send a DNS add message to a nameserver for "name" to have a new "rdata" -dyndns_add(nameserver, name, rdata, type="A", ttl=10) -> result code (0=ok) - -example: dyndns_add("ns1.toto.com", "dyn.toto.com", "127.0.0.1") -RFC2136 -""" - zone = name[name.find(".")+1:] - r=sr1(IP(dst=nameserver)/UDP()/DNS(opcode=5, - qd=[DNSQR(qname=zone, qtype="SOA")], - ns=[DNSRR(rrname=name, type="A", - ttl=ttl, rdata=rdata)]), - verbose=0, timeout=5) - if r and r.haslayer(DNS): - return r.getlayer(DNS).rcode - else: - return -1 - - - - -@conf.commands.register -def dyndns_del(nameserver, name, type="ALL", ttl=10): - """Send a DNS delete message to a nameserver for "name" -dyndns_del(nameserver, name, type="ANY", ttl=10) -> result code (0=ok) - -example: dyndns_del("ns1.toto.com", "dyn.toto.com") -RFC2136 -""" - zone = name[name.find(".")+1:] - r=sr1(IP(dst=nameserver)/UDP()/DNS(opcode=5, - qd=[DNSQR(qname=zone, qtype="SOA")], - ns=[DNSRR(rrname=name, type=type, - rclass="ANY", ttl=0, rdata=b"")]), - verbose=0, timeout=5) - if r and r.haslayer(DNS): - return r.getlayer(DNS).rcode - else: - return -1 - - -class DNS_am(AnsweringMachine): - function_name="dns_spoof" - filter = "udp port 53" - - def parse_options(self, joker="192.168.1.1", match=None): - if match is None: - self.match = {} - else: - self.match = match - self.joker=joker - - def is_request(self, req): - return req.haslayer(DNS) and req.getlayer(DNS).qr == 0 - - def make_reply(self, req): - ip = req.getlayer(IP) - dns = req.getlayer(DNS) - resp = IP(dst=ip.src, src=ip.dst)/UDP(dport=ip.sport,sport=ip.dport) - rdata = self.match.get(dns.qd.qname, self.joker) - resp /= DNS(id=dns.id, qr=1, qd=dns.qd, - an=DNSRR(rrname=dns.qd.qname, ttl=10, rdata=rdata)) - return resp - - diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/dot11.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/dot11.py deleted file mode 100644 index 417a470e..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/dot11.py +++ /dev/null @@ -1,560 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -Wireless LAN according to IEEE 802.11. -""" - -import re,struct - -from scapy.packet import * -from scapy.fields import * -from scapy.plist import PacketList -from scapy.layers.l2 import * - - -try: - from Crypto.Cipher import ARC4 -except ImportError: - log_loading.info("Can't import python Crypto lib. Won't be able to decrypt WEP.") - - -### Fields - -class Dot11AddrMACField(MACField): - def is_applicable(self, pkt): - return 1 - def addfield(self, pkt, s, val): - if self.is_applicable(pkt): - return MACField.addfield(self, pkt, s, val) - else: - return s - def getfield(self, pkt, s): - if self.is_applicable(pkt): - return MACField.getfield(self, pkt, s) - else: - return s,None - -class Dot11Addr2MACField(Dot11AddrMACField): - def is_applicable(self, pkt): - if pkt.type == 1: - return pkt.subtype in [ 0xb, 0xa, 0xe, 0xf] # RTS, PS-Poll, CF-End, CF-End+CF-Ack - return 1 - -class Dot11Addr3MACField(Dot11AddrMACField): - def is_applicable(self, pkt): - if pkt.type in [0,2]: - return 1 - return 0 - -class Dot11Addr4MACField(Dot11AddrMACField): - def is_applicable(self, pkt): - if pkt.type == 2: - if pkt.FCfield & 0x3 == 0x3: # To-DS and From-DS are set - return 1 - return 0 - - -### Layers - - -class PrismHeader(Packet): - """ iwpriv wlan0 monitor 3 """ - name = "Prism header" - fields_desc = [ LEIntField("msgcode",68), - LEIntField("len",144), - StrFixedLenField("dev","",16), - LEIntField("hosttime_did",0), - LEShortField("hosttime_status",0), - LEShortField("hosttime_len",0), - LEIntField("hosttime",0), - LEIntField("mactime_did",0), - LEShortField("mactime_status",0), - LEShortField("mactime_len",0), - LEIntField("mactime",0), - LEIntField("channel_did",0), - LEShortField("channel_status",0), - LEShortField("channel_len",0), - LEIntField("channel",0), - LEIntField("rssi_did",0), - LEShortField("rssi_status",0), - LEShortField("rssi_len",0), - LEIntField("rssi",0), - LEIntField("sq_did",0), - LEShortField("sq_status",0), - LEShortField("sq_len",0), - LEIntField("sq",0), - LEIntField("signal_did",0), - LEShortField("signal_status",0), - LEShortField("signal_len",0), - LESignedIntField("signal",0), - LEIntField("noise_did",0), - LEShortField("noise_status",0), - LEShortField("noise_len",0), - LEIntField("noise",0), - LEIntField("rate_did",0), - LEShortField("rate_status",0), - LEShortField("rate_len",0), - LEIntField("rate",0), - LEIntField("istx_did",0), - LEShortField("istx_status",0), - LEShortField("istx_len",0), - LEIntField("istx",0), - LEIntField("frmlen_did",0), - LEShortField("frmlen_status",0), - LEShortField("frmlen_len",0), - LEIntField("frmlen",0), - ] - def answers(self, other): - if isinstance(other, PrismHeader): - return self.payload.answers(other.payload) - else: - return self.payload.answers(other) - -class RadioTap(Packet): - name = "RadioTap dummy" - fields_desc = [ ByteField('version', 0), - ByteField('pad', 0), - FieldLenField('len', None, 'notdecoded', '<H', adjust=lambda pkt,x:x+8), - FlagsField('present', None, -32, ['TSFT','Flags','Rate','Channel','FHSS','dBm_AntSignal', - 'dBm_AntNoise','Lock_Quality','TX_Attenuation','dB_TX_Attenuation', - 'dBm_TX_Power', 'Antenna', 'dB_AntSignal', 'dB_AntNoise', - 'b14', 'b15','b16','b17','b18','b19','b20','b21','b22','b23', - 'b24','b25','b26','b27','b28','b29','b30','Ext']), - StrLenField('notdecoded', "", length_from= lambda pkt:pkt.len-8) ] - -class PPI(Packet): - name = "Per-Packet Information header (partial)" - fields_desc = [ ByteField("version", 0), - ByteField("flags", 0), - FieldLenField("len", None, fmt="<H", length_of="fields", adjust=lambda pkt,x:x+8), - LEIntField("dlt", 0), - StrLenField("notdecoded", "", length_from = lambda pkt:pkt.len-8) - ] - - - -class Dot11SCField(LEShortField): - def is_applicable(self, pkt): - return pkt.type != 1 # control frame - def addfield(self, pkt, s, val): - if self.is_applicable(pkt): - return LEShortField.addfield(self, pkt, s, val) - else: - return s - def getfield(self, pkt, s): - if self.is_applicable(pkt): - return LEShortField.getfield(self, pkt, s) - else: - return s,None - -class Dot11(Packet): - name = "802.11" - fields_desc = [ - BitField("subtype", 0, 4), - BitEnumField("type", 0, 2, ["Management", "Control", "Data", "Reserved"]), - BitField("proto", 0, 2), - FlagsField("FCfield", 0, 8, ["to-DS", "from-DS", "MF", "retry", "pw-mgt", "MD", "wep", "order"]), - ShortField("ID",0), - MACField("addr1", ETHER_ANY), - Dot11Addr2MACField("addr2", ETHER_ANY), - Dot11Addr3MACField("addr3", ETHER_ANY), - Dot11SCField("SC", 0), - Dot11Addr4MACField("addr4", ETHER_ANY) - ] - def mysummary(self): - return self.sprintf("802.11 %Dot11.type% %Dot11.subtype% %Dot11.addr2% > %Dot11.addr1%") - def guess_payload_class(self, payload): - if self.type == 0x02 and (self.subtype >= 0x08 and self.subtype <=0xF and self.subtype != 0xD): - return Dot11QoS - elif self.FCfield & 0x40: - return Dot11WEP - else: - return Packet.guess_payload_class(self, payload) - def answers(self, other): - if isinstance(other,Dot11): - if self.type == 0: # management - if self.addr1.lower() != other.addr2.lower(): # check resp DA w/ req SA - return 0 - if (other.subtype,self.subtype) in [(0,1),(2,3),(4,5)]: - return 1 - if self.subtype == other.subtype == 11: # auth - return self.payload.answers(other.payload) - elif self.type == 1: # control - return 0 - elif self.type == 2: # data - return self.payload.answers(other.payload) - elif self.type == 3: # reserved - return 0 - return 0 - def unwep(self, key=None, warn=1): - if self.FCfield & 0x40 == 0: - if warn: - warning("No WEP to remove") - return - if isinstance(self.payload.payload, NoPayload): - if key or conf.wepkey: - self.payload.decrypt(key) - if isinstance(self.payload.payload, NoPayload): - if warn: - warning("Dot11 can't be decrypted. Check conf.wepkey.") - return - self.FCfield &= ~0x40 - self.payload=self.payload.payload - - -class Dot11QoS(Packet): - name = "802.11 QoS" - fields_desc = [ BitField("TID",None,4), - BitField("EOSP",None,1), - BitField("Ack Policy",None,2), - BitField("Reserved",None,1), - ByteField("TXOP",None) ] - def guess_payload_class(self, payload): - if isinstance(self.underlayer, Dot11): - if self.underlayer.FCfield & 0x40: - return Dot11WEP - return Packet.guess_payload_class(self, payload) - - -capability_list = [ "res8", "res9", "short-slot", "res11", - "res12", "DSSS-OFDM", "res14", "res15", - "ESS", "IBSS", "CFP", "CFP-req", - "privacy", "short-preamble", "PBCC", "agility"] - -reason_code = {0:"reserved",1:"unspec", 2:"auth-expired", - 3:"deauth-ST-leaving", - 4:"inactivity", 5:"AP-full", 6:"class2-from-nonauth", - 7:"class3-from-nonass", 8:"disas-ST-leaving", - 9:"ST-not-auth"} - -status_code = {0:"success", 1:"failure", 10:"cannot-support-all-cap", - 11:"inexist-asso", 12:"asso-denied", 13:"algo-unsupported", - 14:"bad-seq-num", 15:"challenge-failure", - 16:"timeout", 17:"AP-full",18:"rate-unsupported" } - -class Dot11Beacon(Packet): - name = "802.11 Beacon" - fields_desc = [ LELongField("timestamp", 0), - LEShortField("beacon_interval", 0x0064), - FlagsField("cap", 0, 16, capability_list) ] - - -class Dot11Elt(Packet): - name = "802.11 Information Element" - fields_desc = [ ByteEnumField("ID", 0, {0:"SSID", 1:"Rates", 2: "FHset", 3:"DSset", 4:"CFset", 5:"TIM", 6:"IBSSset", 16:"challenge", - 42:"ERPinfo", 46:"QoS Capability", 47:"ERPinfo", 48:"RSNinfo", 50:"ESRates",221:"vendor",68:"reserved"}), - FieldLenField("len", None, "info", "B"), - StrLenField("info", "", length_from=lambda x:x.len) ] - def mysummary(self): - if self.ID == 0: - return "SSID=%s"%repr(self.info),[Dot11] - else: - return "" - -class Dot11ATIM(Packet): - name = "802.11 ATIM" - -class Dot11Disas(Packet): - name = "802.11 Disassociation" - fields_desc = [ LEShortEnumField("reason", 1, reason_code) ] - -class Dot11AssoReq(Packet): - name = "802.11 Association Request" - fields_desc = [ FlagsField("cap", 0, 16, capability_list), - LEShortField("listen_interval", 0x00c8) ] - - -class Dot11AssoResp(Packet): - name = "802.11 Association Response" - fields_desc = [ FlagsField("cap", 0, 16, capability_list), - LEShortField("status", 0), - LEShortField("AID", 0) ] - -class Dot11ReassoReq(Packet): - name = "802.11 Reassociation Request" - fields_desc = [ FlagsField("cap", 0, 16, capability_list), - LEShortField("listen_interval", 0x00c8), - MACField("current_AP", ETHER_ANY) ] - - -class Dot11ReassoResp(Dot11AssoResp): - name = "802.11 Reassociation Response" - -class Dot11ProbeReq(Packet): - name = "802.11 Probe Request" - -class Dot11ProbeResp(Packet): - name = "802.11 Probe Response" - fields_desc = [ LELongField("timestamp", 0), - LEShortField("beacon_interval", 0x0064), - FlagsField("cap", 0, 16, capability_list) ] - -class Dot11Auth(Packet): - name = "802.11 Authentication" - fields_desc = [ LEShortEnumField("algo", 0, ["open", "sharedkey"]), - LEShortField("seqnum", 0), - LEShortEnumField("status", 0, status_code) ] - def answers(self, other): - if self.seqnum == other.seqnum+1: - return 1 - return 0 - -class Dot11Deauth(Packet): - name = "802.11 Deauthentication" - fields_desc = [ LEShortEnumField("reason", 1, reason_code) ] - - - -class Dot11WEP(Packet): - name = "802.11 WEP packet" - fields_desc = [ StrFixedLenField("iv", b"\0\0\0", 3), - ByteField("keyid", 0), - StrField("wepdata",None,remain=4), - IntField("icv",None) ] - - def post_dissect(self, s): -# self.icv, = struct.unpack("!I",self.wepdata[-4:]) -# self.wepdata = self.wepdata[:-4] - self.decrypt() - - def build_payload(self): - if self.wepdata is None: - return Packet.build_payload(self) - return b"" - - def post_build(self, p, pay): - if self.wepdata is None: - key = conf.wepkey - if key: - if self.icv is None: - pay += struct.pack("<I",crc32(pay)) - icv = b"" - else: - icv = p[4:8] - c = ARC4.new(self.iv+key) - p = p[:4]+c.encrypt(pay)+icv - else: - warning("No WEP key set (conf.wepkey).. strange results expected..") - return p - - - def decrypt(self,key=None): - if key is None: - key = conf.wepkey - if key: - c = ARC4.new(self.iv+key) - self.add_payload(LLC(c.decrypt(self.wepdata))) - - -bind_layers( PrismHeader, Dot11, ) -bind_layers( RadioTap, Dot11, ) -bind_layers( PPI, Dot11, dlt=105) -bind_layers( Dot11, LLC, type=2) -bind_layers( Dot11QoS, LLC, ) -bind_layers( Dot11, Dot11AssoReq, subtype=0, type=0) -bind_layers( Dot11, Dot11AssoResp, subtype=1, type=0) -bind_layers( Dot11, Dot11ReassoReq, subtype=2, type=0) -bind_layers( Dot11, Dot11ReassoResp, subtype=3, type=0) -bind_layers( Dot11, Dot11ProbeReq, subtype=4, type=0) -bind_layers( Dot11, Dot11ProbeResp, subtype=5, type=0) -bind_layers( Dot11, Dot11Beacon, subtype=8, type=0) -bind_layers( Dot11, Dot11ATIM, subtype=9, type=0) -bind_layers( Dot11, Dot11Disas, subtype=10, type=0) -bind_layers( Dot11, Dot11Auth, subtype=11, type=0) -bind_layers( Dot11, Dot11Deauth, subtype=12, type=0) -bind_layers( Dot11Beacon, Dot11Elt, ) -bind_layers( Dot11AssoReq, Dot11Elt, ) -bind_layers( Dot11AssoResp, Dot11Elt, ) -bind_layers( Dot11ReassoReq, Dot11Elt, ) -bind_layers( Dot11ReassoResp, Dot11Elt, ) -bind_layers( Dot11ProbeReq, Dot11Elt, ) -bind_layers( Dot11ProbeResp, Dot11Elt, ) -bind_layers( Dot11Auth, Dot11Elt, ) -bind_layers( Dot11Elt, Dot11Elt, ) - - -conf.l2types.register(105, Dot11) -conf.l2types.register_num2layer(801, Dot11) -conf.l2types.register(119, PrismHeader) -conf.l2types.register_num2layer(802, PrismHeader) -conf.l2types.register(127, RadioTap) -conf.l2types.register(0xc0, PPI) -conf.l2types.register_num2layer(803, RadioTap) - - -class WiFi_am(AnsweringMachine): - """Before using this, initialize "iffrom" and "ifto" interfaces: -iwconfig iffrom mode monitor -iwpriv orig_ifto hostapd 1 -ifconfig ifto up -note: if ifto=wlan0ap then orig_ifto=wlan0 -note: ifto and iffrom must be set on the same channel -ex: -ifconfig eth1 up -iwconfig eth1 mode monitor -iwconfig eth1 channel 11 -iwpriv wlan0 hostapd 1 -ifconfig wlan0ap up -iwconfig wlan0 channel 11 -iwconfig wlan0 essid dontexist -iwconfig wlan0 mode managed -""" - function_name = "airpwn" - filter = None - - def parse_options(self, iffrom, ifto, replace, pattern="", ignorepattern=""): - self.iffrom = iffrom - self.ifto = ifto - ptrn = re.compile(pattern) - iptrn = re.compile(ignorepattern) - - def is_request(self, pkt): - if not isinstance(pkt,Dot11): - return 0 - if not pkt.FCfield & 1: - return 0 - if not pkt.haslayer(TCP): - return 0 - ip = pkt.getlayer(IP) - tcp = pkt.getlayer(TCP) - pay = str(tcp.payload) - if not self.ptrn.match(pay): - return 0 - if self.iptrn.match(pay): - return 0 - - def make_reply(self, p): - ip = p.getlayer(IP) - tcp = p.getlayer(TCP) - pay = str(tcp.payload) - del(p.payload.payload.payload) - p.FCfield="from-DS" - p.addr1,p.addr2 = p.addr2,p.addr1 - p /= IP(src=ip.dst,dst=ip.src) - p /= TCP(sport=tcp.dport, dport=tcp.sport, - seq=tcp.ack, ack=tcp.seq+len(pay), - flags="PA") - q = p.copy() - p /= self.replace - q.ID += 1 - q.getlayer(TCP).flags="RA" - q.getlayer(TCP).seq+=len(replace) - return [p,q] - - def print_reply(self): - print(p.sprintf("Sent %IP.src%:%IP.sport% > %IP.dst%:%TCP.dport%")) - - def send_reply(self, reply): - sendp(reply, iface=self.ifto, **self.optsend) - - def sniff(self): - sniff(iface=self.iffrom, **self.optsniff) - - - -plst=[] -def get_toDS(): - global plst - while 1: - p,=sniff(iface="eth1",count=1) - if not isinstance(p,Dot11): - continue - if p.FCfield & 1: - plst.append(p) - print(".") - - -# if not ifto.endswith("ap"): -# print("iwpriv %s hostapd 1" % ifto) -# os.system("iwpriv %s hostapd 1" % ifto) -# ifto += "ap" -# -# os.system("iwconfig %s mode monitor" % iffrom) -# - -def airpwn(iffrom, ifto, replace, pattern="", ignorepattern=""): - """Before using this, initialize "iffrom" and "ifto" interfaces: -iwconfig iffrom mode monitor -iwpriv orig_ifto hostapd 1 -ifconfig ifto up -note: if ifto=wlan0ap then orig_ifto=wlan0 -note: ifto and iffrom must be set on the same channel -ex: -ifconfig eth1 up -iwconfig eth1 mode monitor -iwconfig eth1 channel 11 -iwpriv wlan0 hostapd 1 -ifconfig wlan0ap up -iwconfig wlan0 channel 11 -iwconfig wlan0 essid dontexist -iwconfig wlan0 mode managed -""" - - ptrn = re.compile(pattern) - iptrn = re.compile(ignorepattern) - def do_airpwn(p, ifto=ifto, replace=replace, ptrn=ptrn, iptrn=iptrn): - if not isinstance(p,Dot11): - return - if not p.FCfield & 1: - return - if not p.haslayer(TCP): - return - ip = p.getlayer(IP) - tcp = p.getlayer(TCP) - pay = str(tcp.payload) -# print "got tcp" - if not ptrn.match(pay): - return -# print "match 1" - if iptrn.match(pay): - return -# print "match 2" - del(p.payload.payload.payload) - p.FCfield="from-DS" - p.addr1,p.addr2 = p.addr2,p.addr1 - q = p.copy() - p /= IP(src=ip.dst,dst=ip.src) - p /= TCP(sport=tcp.dport, dport=tcp.sport, - seq=tcp.ack, ack=tcp.seq+len(pay), - flags="PA") - q = p.copy() - p /= replace - q.ID += 1 - q.getlayer(TCP).flags="RA" - q.getlayer(TCP).seq+=len(replace) - - sendp([p,q], iface=ifto, verbose=0) -# print "send",repr(p) -# print "send",repr(q) - print(p.sprintf("Sent %IP.src%:%IP.sport% > %IP.dst%:%TCP.dport%")) - - sniff(iface=iffrom,prn=do_airpwn) - - - -conf.stats_dot11_protocols += [Dot11WEP, Dot11Beacon, ] - - - - - -class Dot11PacketList(PacketList): - def __init__(self, res=None, name="Dot11List", stats=None): - if stats is None: - stats = conf.stats_dot11_protocols - - PacketList.__init__(self, res, name, stats) - def toEthernet(self): - #data = map(lambda x:x.getlayer(Dot11), filter(lambda x : x.haslayer(Dot11) and x.type == 2, self.res)) - data = [ x.getlayer(Dot11) for x in self.res if x.haslayer(Dot11) and x.type == 2 ] - r2 = [] - for p in data: - q = p.copy() - q.unwep() - r2.append(Ether()/q.payload.payload.payload) #Dot11/LLC/SNAP/IP - return PacketList(r2,name="Ether from %s"%self.listname) - - diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/gprs.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/gprs.py deleted file mode 100644 index 31a931fe..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/gprs.py +++ /dev/null @@ -1,21 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -GPRS (General Packet Radio Service) for mobile data communication. -""" - -from scapy.fields import * -from scapy.packet import * -from scapy.layers.inet import IP - -class GPRS(Packet): - name = "GPRSdummy" - fields_desc = [ - StrStopField("dummy","","\x65\x00\x00",1) - ] - - -bind_layers( GPRS, IP, ) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/hsrp.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/hsrp.py deleted file mode 100644 index 7193b97e..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/hsrp.py +++ /dev/null @@ -1,79 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -############################################################################# -## ## -## hsrp.py --- HSRP protocol support for Scapy ## -## ## -## Copyright (C) 2010 Mathieu RENARD mathieu.renard(at)gmail.com ## -## ## -## This program is free software; you can redistribute it and/or modify it ## -## under the terms of the GNU General Public License version 2 as ## -## published by the Free Software Foundation; version 2. ## -## ## -## This program is distributed in the hope that it will be useful, but ## -## WITHOUT ANY WARRANTY; without even the implied warranty of ## -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## -## General Public License for more details. ## -## ## -############################################################################# -## HSRP Version 1 -## Ref. RFC 2281 -## HSRP Version 2 -## Ref. http://www.smartnetworks.jp/2006/02/hsrp_8_hsrp_version_2.html -## -## $Log: hsrp.py,v $ -## Revision 0.2 2011/05/01 15:23:34 mrenard -## Cleanup code - -""" -HSRP (Hot Standby Router Protocol): proprietary redundancy protocol for Cisco routers. -""" - -from scapy.fields import * -from scapy.packet import * -from scapy.layers.inet import UDP - - -class HSRP(Packet): - name = "HSRP" - fields_desc = [ - ByteField("version", 0), - ByteEnumField("opcode", 0, {0: "Hello", 1: "Coup", 2: "Resign", 3: "Advertise"}), - ByteEnumField("state", 16, {0: "Initial", 1: "Learn", 2: "Listen", 4: "Speak", 8: "Standby", 16: "Active"}), - ByteField("hellotime", 3), - ByteField("holdtime", 10), - ByteField("priority", 120), - ByteField("group", 1), - ByteField("reserved", 0), - StrFixedLenField("auth", "cisco" + "\00" * 3, 8), - IPField("virtualIP", "192.168.1.1")] - - def guess_payload_class(self, payload): - if self.underlayer.len > 28: - return HSRPmd5 - else: - return Packet.guess_payload_class(self, payload) - - -class HSRPmd5(Packet): - name = "HSRP MD5 Authentication" - fields_desc = [ - ByteEnumField("type", 4, {4: "MD5 authentication"}), - ByteField("len", None), - ByteEnumField("algo", 0, {1: "MD5"}), - ByteField("padding", 0x00), - XShortField("flags", 0x00), - IPField("sourceip", None), - XIntField("keyid", 0x00), - StrFixedLenField("authdigest", "\00" * 16, 16)] - - def post_build(self, p, pay): - if self.len is None and pay: - l = len(pay) - p = p[:1] + hex(l)[30:] + p[30:] - return p - -bind_layers(UDP, HSRP, dport=1985, sport=1985) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/inet.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/inet.py deleted file mode 100644 index 04b99e89..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/inet.py +++ /dev/null @@ -1,1569 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -IPv4 (Internet Protocol v4). -""" - -import os,time,struct,re,socket,types -from select import select -from collections import defaultdict -from scapy.utils import checksum -from scapy.layers.l2 import * -from scapy.config import conf -from scapy.fields import * -from scapy.packet import * -from scapy.volatile import * -from scapy.sendrecv import sr,sr1,srp1 -from scapy.plist import PacketList,SndRcvList -from scapy.automaton import Automaton,ATMT - -import scapy.as_resolvers - - -#################### -## IP Tools class ## -#################### - -class IPTools: - """Add more powers to a class that have a "src" attribute.""" - def whois(self): - os.system("whois %s" % self.src) - def ottl(self): - t = [32,64,128,255]+[self.ttl] - t.sort() - return t[t.index(self.ttl)+1] - def hops(self): - return self.ottl()-self.ttl-1 - - -_ip_options_names = { 0: "end_of_list", - 1: "nop", - 2: "security", - 3: "loose_source_route", - 4: "timestamp", - 5: "extended_security", - 6: "commercial_security", - 7: "record_route", - 8: "stream_id", - 9: "strict_source_route", - 10: "experimental_measurement", - 11: "mtu_probe", - 12: "mtu_reply", - 13: "flow_control", - 14: "access_control", - 15: "encode", - 16: "imi_traffic_descriptor", - 17: "extended_IP", - 18: "traceroute", - 19: "address_extension", - 20: "router_alert", - 21: "selective_directed_broadcast_mode", - 23: "dynamic_packet_state", - 24: "upstream_multicast_packet", - 25: "quick_start", - 30: "rfc4727_experiment", - } - - -class _IPOption_HDR(Packet): - fields_desc = [ BitField("copy_flag",0, 1), - BitEnumField("optclass",0,2,{0:"control",2:"debug"}), - BitEnumField("option",0,5, _ip_options_names) ] - -class IPOption(Packet): - name = "IP Option" - fields_desc = [ _IPOption_HDR, - FieldLenField("length", None, fmt="B", # Only option 0 and 1 have no length and value - length_of="value", adjust=lambda pkt,l:l+2), - StrLenField("value", "",length_from=lambda pkt:pkt.length-2) ] - - def extract_padding(self, p): - return b"",p - - registered_ip_options = {} - @classmethod - def register_variant(cls): - cls.registered_ip_options[cls.option.default] = cls - @classmethod - def dispatch_hook(cls, pkt=None, *args, **kargs): - if pkt: - opt = pkt[0]&0x1f - if opt in cls.registered_ip_options: - return cls.registered_ip_options[opt] - return cls - -class IPOption_EOL(IPOption): - name = "IP Option End of Options List" - option = 0 - fields_desc = [ _IPOption_HDR ] - - -class IPOption_NOP(IPOption): - name = "IP Option No Operation" - option=1 - fields_desc = [ _IPOption_HDR ] - -class IPOption_Security(IPOption): - name = "IP Option Security" - copy_flag = 1 - option = 2 - fields_desc = [ _IPOption_HDR, - ByteField("length", 11), - ShortField("security",0), - ShortField("compartment",0), - ShortField("handling_restrictions",0), - StrFixedLenField("transmission_control_code","xxx",3), - ] - -class IPOption_LSRR(IPOption): - name = "IP Option Loose Source and Record Route" - copy_flag = 1 - option = 3 - fields_desc = [ _IPOption_HDR, - FieldLenField("length", None, fmt="B", - length_of="routers", adjust=lambda pkt,l:l+3), - ByteField("pointer",4), # 4 is first IP - FieldListField("routers",[],IPField("","0.0.0.0"), - length_from=lambda pkt:pkt.length-3) - ] - def get_current_router(self): - return self.routers[self.pointer//4-1] - -class IPOption_RR(IPOption_LSRR): - name = "IP Option Record Route" - option = 7 - -class IPOption_SSRR(IPOption_LSRR): - name = "IP Option Strict Source and Record Route" - option = 9 - -class IPOption_Stream_Id(IPOption): - name = "IP Option Stream ID" - option = 8 - fields_desc = [ _IPOption_HDR, - ByteField("length", 4), - ShortField("security",0), ] - -class IPOption_MTU_Probe(IPOption): - name = "IP Option MTU Probe" - option = 11 - fields_desc = [ _IPOption_HDR, - ByteField("length", 4), - ShortField("mtu",0), ] - -class IPOption_MTU_Reply(IPOption_MTU_Probe): - name = "IP Option MTU Reply" - option = 12 - -class IPOption_Traceroute(IPOption): - name = "IP Option Traceroute" - copy_flag = 1 - option = 18 - fields_desc = [ _IPOption_HDR, - ByteField("length", 12), - ShortField("id",0), - ShortField("outbound_hops",0), - ShortField("return_hops",0), - IPField("originator_ip","0.0.0.0") ] - -class IPOption_Address_Extension(IPOption): - name = "IP Option Address Extension" - copy_flag = 1 - option = 19 - fields_desc = [ _IPOption_HDR, - ByteField("length", 10), - IPField("src_ext","0.0.0.0"), - IPField("dst_ext","0.0.0.0") ] - -class IPOption_Router_Alert(IPOption): - name = "IP Option Router Alert" - copy_flag = 1 - option = 20 - fields_desc = [ _IPOption_HDR, - ByteField("length", 4), - ShortEnumField("alert",0, {0:"router_shall_examine_packet"}), ] - - -class IPOption_SDBM(IPOption): - name = "IP Option Selective Directed Broadcast Mode" - copy_flag = 1 - option = 21 - fields_desc = [ _IPOption_HDR, - FieldLenField("length", None, fmt="B", - length_of="addresses", adjust=lambda pkt,l:l+2), - FieldListField("addresses",[],IPField("","0.0.0.0"), - length_from=lambda pkt:pkt.length-2) - ] - - - -TCPOptions = ( - { 0 : ("EOL",None), - 1 : ("NOP",None), - 2 : ("MSS","!H"), - 3 : ("WScale","!B"), - 4 : ("SAckOK",None), - 5 : ("SAck","!"), - 8 : ("Timestamp","!II"), - 14 : ("AltChkSum","!BH"), - 15 : ("AltChkSumOpt",None), - 25 : ("Mood","!p") - }, - { "EOL":0, - "NOP":1, - "MSS":2, - "WScale":3, - "SAckOK":4, - "SAck":5, - "Timestamp":8, - "AltChkSum":14, - "AltChkSumOpt":15, - "Mood":25 - } ) - -class TCPOptionsField(StrField): - islist=1 - def getfield(self, pkt, s): - opsz = (pkt.dataofs-5)*4 - if opsz < 0: - warning("bad dataofs (%i). Assuming dataofs=5"%pkt.dataofs) - opsz = 0 - return s[opsz:],self.m2i(pkt,s[:opsz]) - def m2i(self, pkt, x): - opt = [] - while x: - onum = x[0] - if onum == 0: - opt.append(("EOL",None)) - x=x[1:] - break - if onum == 1: - opt.append(("NOP",None)) - x=x[1:] - continue - olen = x[1] - if olen < 2: - warning("Malformed TCP option (announced length is %i)" % olen) - olen = 2 - oval = x[2:olen] - if onum in TCPOptions[0]: - oname, ofmt = TCPOptions[0][onum] - if onum == 5: #SAck - ofmt += "%iI" % (len(oval)//4) - if ofmt and struct.calcsize(ofmt) == len(oval): - oval = struct.unpack(ofmt, oval) - if len(oval) == 1: - oval = oval[0] - opt.append((oname, oval)) - else: - opt.append((onum, oval)) - x = x[olen:] - return opt - - def i2m(self, pkt, x): - opt = b"" - for oname,oval in x: - if type(oname) is str: - if oname == "NOP": - opt += b"\x01" - continue - elif oname == "EOL": - opt += b"\x00" - continue - elif oname in TCPOptions[1]: - onum = TCPOptions[1][oname] - ofmt = TCPOptions[0][onum][1] - if onum == 5: #SAck - ofmt += b"%iI" % len(oval) - if ofmt is not None and (type(oval) is not str or "s" in ofmt): - if type(oval) is not tuple: - oval = (oval,) - oval = struct.pack(ofmt, *oval) - else: - warning("option [%s] unknown. Skipped."%oname) - continue - else: - onum = oname - if type(oval) is not str: - warning("option [%i] is not string."%onum) - continue - opt += bytes([(onum), (2+len(oval))]) + oval - return opt+b"\x00"*(3-((len(opt)+3)%4)) - def randval(self): - return [] # XXX - - -class ICMPTimeStampField(IntField): - re_hmsm = re.compile("([0-2]?[0-9])[Hh:](([0-5]?[0-9])([Mm:]([0-5]?[0-9])([sS:.]([0-9]{0,3}))?)?)?$") - def i2repr(self, pkt, val): - if val is None: - return "--" - else: - sec, milli = divmod(val, 1000) - min, sec = divmod(sec, 60) - hour, min = divmod(min, 60) - return "%d:%d:%d.%d" %(hour, min, sec, int(milli)) - def any2i(self, pkt, val): - if type(val) is str: - hmsms = self.re_hmsm.match(val) - if hmsms: - h,_,m,_,s,_,ms = hmsms = hmsms.groups() - ms = int(((ms or "")+"000")[:3]) - val = ((int(h)*60+int(m or 0))*60+int(s or 0))*1000+ms - else: - val = 0 - elif val is None: - val = int((time.time()%(24*60*60))*1000) - return val - - -class IP(Packet, IPTools): - name = "IP" - fields_desc = [ BitField("version" , 4 , 4), - BitField("ihl", None, 4), - XByteField("tos", 0), - ShortField("len", None), - ShortField("id", 1), - FlagsField("flags", 0, 3, ["MF","DF","evil"]), - BitField("frag", 0, 13), - ByteField("ttl", 64), - ByteEnumField("proto", 0, IP_PROTOS), - XShortField("chksum", None), - #IPField("src", "127.0.0.1"), - #Emph(SourceIPField("src","dst")), - #Emph(IPField("dst", "127.0.0.1")), - - Emph(IPField("src", "16.0.0.1")), - Emph(IPField("dst", "48.0.0.1")), - PacketListField("options", [], IPOption, length_from=lambda p:p.ihl*4-20) ] - def post_build(self, p, pay): - ihl = self.ihl - p += b"\0"*((-len(p))%4) # pad IP options if needed - if ihl is None: - ihl = len(p)//4 - p = bytes([((self.version&0xf)<<4) | ihl&0x0f])+p[1:] - if self.len is None: - l = len(p)+len(pay) - p = p[:2]+struct.pack("!H", l)+p[4:] - if self.chksum is None: - ck = checksum(p) - p = p[:10]+bytes([ck>>8])+bytes([ck&0xff])+p[12:] - return p+pay - - def extract_padding(self, s): - l = self.len - (self.ihl << 2) - return s[:l],s[l:] - - def send(self, s, slp=0): - for p in self: - try: - s.sendto(bytes(p), (p.dst,0)) - except socket.error as msg: - log_runtime.error(msg) - if slp: - time.sleep(slp) - def route(self): - dst = self.dst - if isinstance(dst,Gen): - dst = next(iter(dst)) - return conf.route.route(dst) - def hashret(self): - if ( (self.proto == socket.IPPROTO_ICMP) - and (isinstance(self.payload, ICMP)) - and (self.payload.type in [3,4,5,11,12]) ): - return self.payload.payload.hashret() - else: - if conf.checkIPsrc and conf.checkIPaddr: - return strxor(inet_aton(self.src),inet_aton(self.dst))+struct.pack("B",self.proto)+self.payload.hashret() - else: - return struct.pack("B", self.proto)+self.payload.hashret() - def answers(self, other): - if not isinstance(other,IP): - return 0 - if conf.checkIPaddr and (self.dst != other.src): - return 0 - if ( (self.proto == socket.IPPROTO_ICMP) and - (isinstance(self.payload, ICMP)) and - (self.payload.type in [3,4,5,11,12]) ): - # ICMP error message - return self.payload.payload.answers(other) - - else: - if ( (conf.checkIPaddr and (self.src != other.dst)) or - (self.proto != other.proto) ): - return 0 - return self.payload.answers(other.payload) - def mysummary(self): - s = self.sprintf("%IP.src% > %IP.dst% %IP.proto%") - if self.frag: - s += " frag:%i" % self.frag - return s - - def fragment(self, fragsize=1480): - """Fragment IP datagrams""" - fragsize = (fragsize+7)//8*8 - lst = [] - fnb = 0 - fl = self - while fl.underlayer is not None: - fnb += 1 - fl = fl.underlayer - - for p in fl: - s = bytes(p[fnb].payload) - nb = (len(s)+fragsize-1)//fragsize - for i in range(nb): - q = p.copy() - del(q[fnb].payload) - del(q[fnb].chksum) - del(q[fnb].len) - if i == nb-1: - q[IP].flags &= ~1 - else: - q[IP].flags |= 1 - q[IP].frag = i*fragsize//8 - r = conf.raw_layer(load=s[i*fragsize:(i+1)*fragsize]) - r.overload_fields = p[IP].payload.overload_fields.copy() - q.add_payload(r) - lst.append(q) - return lst - - -class TCP(Packet): - name = "TCP" - fields_desc = [ ShortEnumField("sport", 20, TCP_SERVICES), - ShortEnumField("dport", 80, TCP_SERVICES), - IntField("seq", 0), - IntField("ack", 0), - BitField("dataofs", None, 4), - BitField("reserved", 0, 4), - FlagsField("flags", 0x2, 8, "FSRPAUEC"), - ShortField("window", 8192), - XShortField("chksum", None), - ShortField("urgptr", 0), - TCPOptionsField("options", {}) ] - def post_build(self, p, pay): - p += pay - dataofs = self.dataofs - if dataofs is None: - dataofs = 5+((len(self.get_field("options").i2m(self,self.options))+3)//4) - p = p[:12]+bytes([(dataofs << 4) | (p[12])&0x0f])+p[13:] - if self.chksum is None: - if isinstance(self.underlayer, IP): - if self.underlayer.len is not None: - ln = self.underlayer.len-20 - else: - ln = len(p) - psdhdr = struct.pack("!4s4sHH", - inet_aton(self.underlayer.src), - inet_aton(self.underlayer.dst), - self.underlayer.proto, - ln) - ck=checksum(psdhdr+p) - p = p[:16]+struct.pack("!H", ck)+p[18:] - elif conf.ipv6_enabled and isinstance(self.underlayer, scapy.layers.inet6.IPv6) or isinstance(self.underlayer, scapy.layers.inet6._IPv6ExtHdr): - ck = scapy.layers.inet6.in6_chksum(socket.IPPROTO_TCP, self.underlayer, p) - p = p[:16]+struct.pack("!H", ck)+p[18:] - else: - warning("No IP underlayer to compute checksum. Leaving null.") - return p - def hashret(self): - if conf.checkIPsrc: - return struct.pack("H",self.sport ^ self.dport)+self.payload.hashret() - else: - return self.payload.hashret() - def answers(self, other): - if not isinstance(other, TCP): - return 0 - if conf.checkIPsrc: - if not ((self.sport == other.dport) and - (self.dport == other.sport)): - return 0 - if (abs(other.seq-self.ack) > 2+len(other.payload)): - return 0 - return 1 - def mysummary(self): - if isinstance(self.underlayer, IP): - return self.underlayer.sprintf("TCP %IP.src%:%TCP.sport% > %IP.dst%:%TCP.dport% %TCP.flags%") - elif conf.ipv6_enabled and isinstance(self.underlayer, scapy.layers.inet6.IPv6): - return self.underlayer.sprintf("TCP %IPv6.src%:%TCP.sport% > %IPv6.dst%:%TCP.dport% %TCP.flags%") - else: - return self.sprintf("TCP %TCP.sport% > %TCP.dport% %TCP.flags%") - -class UDP(Packet): - name = "UDP" - fields_desc = [ ShortEnumField("sport", 53, UDP_SERVICES), - ShortEnumField("dport", 53, UDP_SERVICES), - ShortField("len", None), - XShortField("chksum", None), ] - def post_build(self, p, pay): - p += pay - l = self.len - if l is None: - l = len(p) - p = p[:4]+struct.pack("!H",l)+p[6:] - if self.chksum is None: - if isinstance(self.underlayer, IP): - if self.underlayer.len is not None: - ln = self.underlayer.len-20 - else: - ln = len(p) - psdhdr = struct.pack("!4s4sHH", - inet_aton(self.underlayer.src), - inet_aton(self.underlayer.dst), - self.underlayer.proto, - ln) - ck=checksum(psdhdr+p) - p = p[:6]+struct.pack("!H", ck)+p[8:] - elif isinstance(self.underlayer, scapy.layers.inet6.IPv6) or isinstance(self.underlayer, scapy.layers.inet6._IPv6ExtHdr): - ck = scapy.layers.inet6.in6_chksum(socket.IPPROTO_UDP, self.underlayer, p) - p = p[:6]+struct.pack("!H", ck)+p[8:] - else: - warning("No IP underlayer to compute checksum. Leaving null.") - return p - def extract_padding(self, s): - l = self.len - 8 - return s[:l],s[l:] - def hashret(self): - return self.payload.hashret() - def answers(self, other): - if not isinstance(other, UDP): - return 0 - if conf.checkIPsrc: - if self.dport != other.sport: - return 0 - return self.payload.answers(other.payload) - def mysummary(self): - if isinstance(self.underlayer, IP): - return self.underlayer.sprintf("UDP %IP.src%:%UDP.sport% > %IP.dst%:%UDP.dport%") - elif isinstance(self.underlayer, scapy.layers.inet6.IPv6): - return self.underlayer.sprintf("UDP %IPv6.src%:%UDP.sport% > %IPv6.dst%:%UDP.dport%") - else: - return self.sprintf("UDP %UDP.sport% > %UDP.dport%") - -icmptypes = { 0 : "echo-reply", - 3 : "dest-unreach", - 4 : "source-quench", - 5 : "redirect", - 8 : "echo-request", - 9 : "router-advertisement", - 10 : "router-solicitation", - 11 : "time-exceeded", - 12 : "parameter-problem", - 13 : "timestamp-request", - 14 : "timestamp-reply", - 15 : "information-request", - 16 : "information-response", - 17 : "address-mask-request", - 18 : "address-mask-reply" } - -icmpcodes = { 3 : { 0 : "network-unreachable", - 1 : "host-unreachable", - 2 : "protocol-unreachable", - 3 : "port-unreachable", - 4 : "fragmentation-needed", - 5 : "source-route-failed", - 6 : "network-unknown", - 7 : "host-unknown", - 9 : "network-prohibited", - 10 : "host-prohibited", - 11 : "TOS-network-unreachable", - 12 : "TOS-host-unreachable", - 13 : "communication-prohibited", - 14 : "host-precedence-violation", - 15 : "precedence-cutoff", }, - 5 : { 0 : "network-redirect", - 1 : "host-redirect", - 2 : "TOS-network-redirect", - 3 : "TOS-host-redirect", }, - 11 : { 0 : "ttl-zero-during-transit", - 1 : "ttl-zero-during-reassembly", }, - 12 : { 0 : "ip-header-bad", - 1 : "required-option-missing", }, } - - - - -class ICMP(Packet): - name = "ICMP" - fields_desc = [ ByteEnumField("type",8, icmptypes), - MultiEnumField("code",0, icmpcodes, depends_on=lambda pkt:pkt.type,fmt="B"), - XShortField("chksum", None), - ConditionalField(XShortField("id",0), lambda pkt:pkt.type in [0,8,13,14,15,16,17,18]), - ConditionalField(XShortField("seq",0), lambda pkt:pkt.type in [0,8,13,14,15,16,17,18]), - ConditionalField(ICMPTimeStampField("ts_ori", None), lambda pkt:pkt.type in [13,14]), - ConditionalField(ICMPTimeStampField("ts_rx", None), lambda pkt:pkt.type in [13,14]), - ConditionalField(ICMPTimeStampField("ts_tx", None), lambda pkt:pkt.type in [13,14]), - ConditionalField(IPField("gw","0.0.0.0"), lambda pkt:pkt.type==5), - ConditionalField(ByteField("ptr",0), lambda pkt:pkt.type==12), - ConditionalField(X3BytesField("reserved",0), lambda pkt:pkt.type==12), - ConditionalField(IPField("addr_mask","0.0.0.0"), lambda pkt:pkt.type in [17,18]), - ConditionalField(IntField("unused",0), lambda pkt:pkt.type not in [0,5,8,12,13,14,15,16,17,18]), - - ] - def post_build(self, p, pay): - p += pay - if self.chksum is None: - ck = checksum(p) - p = p[:2]+bytes([ck>>8, ck&0xff])+p[4:] - return p - - def hashret(self): - if self.type in [0,8,13,14,15,16,17,18]: - return struct.pack("HH",self.id,self.seq)+self.payload.hashret() - return self.payload.hashret() - def answers(self, other): - if not isinstance(other,ICMP): - return 0 - if ( (other.type,self.type) in [(8,0),(13,14),(15,16),(17,18)] and - self.id == other.id and - self.seq == other.seq ): - return 1 - return 0 - - def guess_payload_class(self, payload): - if self.type in [3,4,5,11,12]: - return IPerror - else: - return None - def mysummary(self): - if isinstance(self.underlayer, IP): - return self.underlayer.sprintf("ICMP %IP.src% > %IP.dst% %ICMP.type% %ICMP.code%") - else: - return self.sprintf("ICMP %ICMP.type% %ICMP.code%") - - - - - -class IPerror(IP): - name = "IP in ICMP" - def answers(self, other): - if not isinstance(other, IP): - return 0 - if not ( ((conf.checkIPsrc == 0) or (self.dst == other.dst)) and - (self.src == other.src) and - ( ((conf.checkIPID == 0) - or (self.id == other.id) - or (conf.checkIPID == 1 and self.id == socket.htons(other.id)))) and - (self.proto == other.proto) ): - return 0 - return self.payload.answers(other.payload) - def mysummary(self): - return Packet.mysummary(self) - - -class TCPerror(TCP): - fields_desc = [ ShortEnumField("sport", 20, TCP_SERVICES), - ShortEnumField("dport", 80, TCP_SERVICES), - IntField("seq", 0) ] - name = "TCP in ICMP" - def post_build(self, p, pay): - p += pay - return p - def answers(self, other): - if not isinstance(other, TCP): - return 0 - if conf.checkIPsrc: - if not ((self.sport == other.sport) and - (self.dport == other.dport)): - return 0 - if conf.check_TCPerror_seqack: - if self.seq is not None: - if self.seq != other.seq: - return 0 - if self.ack is not None: - if self.ack != other.ack: - return 0 - return 1 - def mysummary(self): - return Packet.mysummary(self) - - -class UDPerror(UDP): - name = "UDP in ICMP" - def answers(self, other): - if not isinstance(other, UDP): - return 0 - if conf.checkIPsrc: - if not ((self.sport == other.sport) and - (self.dport == other.dport)): - return 0 - return 1 - def mysummary(self): - return Packet.mysummary(self) - - - -class ICMPerror(ICMP): - name = "ICMP in ICMP" - def answers(self, other): - if not isinstance(other,ICMP): - return 0 - if not ((self.type == other.type) and - (self.code == other.code)): - return 0 - if self.code in [0,8,13,14,17,18]: - if (self.id == other.id and - self.seq == other.seq): - return 1 - else: - return 0 - else: - return 1 - def mysummary(self): - return Packet.mysummary(self) - -bind_layers( Ether, IP, type=2048) -bind_layers( CookedLinux, IP, proto=2048) -bind_layers( GRE, IP, proto=2048) -bind_layers( SNAP, IP, code=2048) -bind_layers( IPerror, IPerror, frag=0, proto=4) -bind_layers( IPerror, ICMPerror, frag=0, proto=1) -bind_layers( IPerror, TCPerror, frag=0, proto=6) -bind_layers( IPerror, UDPerror, frag=0, proto=17) -bind_layers( IP, IP, frag=0, proto=4) -bind_layers( IP, ICMP, frag=0, proto=1) -bind_layers( IP, TCP, frag=0, proto=6) -bind_layers( IP, UDP, frag=0, proto=17) -bind_layers( IP, GRE, frag=0, proto=47) - -conf.l2types.register(101, IP) -conf.l2types.register_num2layer(12, IP) - -conf.l3types.register(ETH_P_IP, IP) -conf.l3types.register_num2layer(ETH_P_ALL, IP) - - -conf.neighbor.register_l3(Ether, IP, lambda l2,l3: getmacbyip(l3.dst)) -conf.neighbor.register_l3(Dot3, IP, lambda l2,l3: getmacbyip(l3.dst)) - - -################### -## Fragmentation ## -################### - -@conf.commands.register -def fragment(pkt, fragsize=1480): - """Fragment a big IP datagram""" - fragsize = (fragsize+7)//8*8 - lst = [] - for p in pkt: - s = bytes(p[IP].payload) - nb = (len(s)+fragsize-1)//fragsize - for i in range(nb): - q = p.copy() - del(q[IP].payload) - del(q[IP].chksum) - del(q[IP].len) - if i == nb-1: - q[IP].flags &= ~1 - else: - q[IP].flags |= 1 - q[IP].frag = i*fragsize//8 - r = conf.raw_layer(load=s[i*fragsize:(i+1)*fragsize]) - r.overload_fields = p[IP].payload.overload_fields.copy() - q.add_payload(r) - lst.append(q) - return lst - -def overlap_frag(p, overlap, fragsize=8, overlap_fragsize=None): - if overlap_fragsize is None: - overlap_fragsize = fragsize - q = p.copy() - del(q[IP].payload) - q[IP].add_payload(overlap) - - qfrag = fragment(q, overlap_fragsize) - qfrag[-1][IP].flags |= 1 - return qfrag+fragment(p, fragsize) - -@conf.commands.register -def defrag(plist): - """defrag(plist) -> ([not fragmented], [defragmented], - [ [bad fragments], [bad fragments], ... ])""" - frags = defaultdict(PacketList) - nofrag = PacketList() - for p in plist: - ip = p[IP] - if IP not in p: - nofrag.append(p) - continue - if ip.frag == 0 and ip.flags & 1 == 0: - nofrag.append(p) - continue - uniq = (ip.id,ip.src,ip.dst,ip.proto) - frags[uniq].append(p) - defrag = [] - missfrag = [] - for lst in frags.values(): - lst.sort(key=lambda x: x.frag) - p = lst[0] - lastp = lst[-1] - if p.frag > 0 or lastp.flags & 1 != 0: # first or last fragment missing - missfrag.append(lst) - continue - p = p.copy() - if conf.padding_layer in p: - del(p[conf.padding_layer].underlayer.payload) - ip = p[IP] - if ip.len is None or ip.ihl is None: - clen = len(ip.payload) - else: - clen = ip.len - (ip.ihl<<2) - txt = conf.raw_layer() - for q in lst[1:]: - if clen != q.frag<<3: # Wrong fragmentation offset - if clen > q.frag<<3: - warning("Fragment overlap (%i > %i) %r || %r || %r" % (clen, q.frag<<3, p,txt,q)) - missfrag.append(lst) - break - if q[IP].len is None or q[IP].ihl is None: - clen += len(q[IP].payload) - else: - clen += q[IP].len - (q[IP].ihl<<2) - if conf.padding_layer in q: - del(q[conf.padding_layer].underlayer.payload) - txt.add_payload(q[IP].payload.copy()) - else: - ip.flags &= ~1 # !MF - del(ip.chksum) - del(ip.len) - p = p/txt - defrag.append(p) - defrag2=PacketList() - for p in defrag: - defrag2.append(p.__class__(bytes(p))) - return nofrag,defrag2,missfrag - -@conf.commands.register -def defragment(plist): - """defragment(plist) -> plist defragmented as much as possible """ - frags = defaultdict(lambda:[]) - final = [] - - pos = 0 - for p in plist: - p._defrag_pos = pos - pos += 1 - if IP in p: - ip = p[IP] - if ip.frag != 0 or ip.flags & 1: - ip = p[IP] - uniq = (ip.id,ip.src,ip.dst,ip.proto) - frags[uniq].append(p) - continue - final.append(p) - - defrag = [] - missfrag = [] - for lst in frags.values(): - lst.sort(key=lambda x: x.frag) - p = lst[0] - lastp = lst[-1] - if p.frag > 0 or lastp.flags & 1 != 0: # first or last fragment missing - missfrag += lst - continue - p = p.copy() - if conf.padding_layer in p: - del(p[conf.padding_layer].underlayer.payload) - ip = p[IP] - if ip.len is None or ip.ihl is None: - clen = len(ip.payload) - else: - clen = ip.len - (ip.ihl<<2) - txt = conf.raw_layer() - for q in lst[1:]: - if clen != q.frag<<3: # Wrong fragmentation offset - if clen > q.frag<<3: - warning("Fragment overlap (%i > %i) %r || %r || %r" % (clen, q.frag<<3, p,txt,q)) - missfrag += lst - break - if q[IP].len is None or q[IP].ihl is None: - clen += len(q[IP].payload) - else: - clen += q[IP].len - (q[IP].ihl<<2) - if conf.padding_layer in q: - del(q[conf.padding_layer].underlayer.payload) - txt.add_payload(q[IP].payload.copy()) - else: - ip.flags &= ~1 # !MF - del(ip.chksum) - del(ip.len) - p = p/txt - p._defrag_pos = max(x._defrag_pos for x in lst) - defrag.append(p) - defrag2=[] - for p in defrag: - q = p.__class__(bytes(p)) - q._defrag_pos = p._defrag_pos - defrag2.append(q) - final += defrag2 - final += missfrag - final.sort(key=lambda x: x._defrag_pos) - for p in final: - del(p._defrag_pos) - - if hasattr(plist, "listname"): - name = "Defragmented %s" % plist.listname - else: - name = "Defragmented" - - return PacketList(final, name=name) - - - -### Add timeskew_graph() method to PacketList -def _packetlist_timeskew_graph(self, ip, **kargs): - """Tries to graph the timeskew between the timestamps and real time for a given ip""" - res = map(lambda x: self._elt2pkt(x), self.res) - b = filter(lambda x:x.haslayer(IP) and x.getlayer(IP).src == ip and x.haslayer(TCP), res) - c = [] - for p in b: - opts = p.getlayer(TCP).options - for o in opts: - if o[0] == "Timestamp": - c.append((p.time,o[1][0])) - if not c: - warning("No timestamps found in packet list") - return - #d = map(lambda (x,y): (x%2000,((x-c[0][0])-((y-c[0][1])/1000.0))),c) - d = map(lambda a: (a[0]%2000,((a[0]-c[0][0])-((a[1]-c[0][1])/1000.0))),c) - return plt.plot(d, **kargs) - -#PacketList.timeskew_graph = types.MethodType(_packetlist_timeskew_graph, None) - - -### Create a new packet list -class TracerouteResult(SndRcvList): - def __init__(self, res=None, name="Traceroute", stats=None): - PacketList.__init__(self, res, name, stats, vector_index = 1) - self.graphdef = None - self.graphASres = 0 - self.padding = 0 - self.hloc = None - self.nloc = None - - def show(self): - #return self.make_table(lambda (s,r): (s.sprintf("%IP.dst%:{TCP:tcp%ir,TCP.dport%}{UDP:udp%ir,UDP.dport%}{ICMP:ICMP}"), - return self.make_table(lambda s,r: (s.sprintf("%IP.dst%:{TCP:tcp%ir,TCP.dport%}{UDP:udp%ir,UDP.dport%}{ICMP:ICMP}"), - s.ttl, - r.sprintf("%-15s,IP.src% {TCP:%TCP.flags%}{ICMP:%ir,ICMP.type%}"))) - - - def get_trace(self): - raw_trace = {} - for s,r in self.res: - if IP not in s: - continue - d = s[IP].dst - if d not in raw_trace: - raw_trace[d] = {} - raw_trace[d][s[IP].ttl] = r[IP].src, ICMP not in r - - trace = {} - for k in raw_trace.keys(): - m = [ x for x in raw_trace[k].keys() if raw_trace[k][x][1] ] - if not m: - trace[k] = raw_trace[k] - else: - m = min(m) - trace[k] = {i: raw_trace[k][i] for i in raw_trace[k].keys() if not raw_trace[k][i][1] or i<=m} - - return trace - - def trace3D(self): - """Give a 3D representation of the traceroute. - right button: rotate the scene - middle button: zoom - left button: move the scene - left button on a ball: toggle IP displaying - ctrl-left button on a ball: scan ports 21,22,23,25,80 and 443 and display the result""" - trace = self.get_trace() - import visual - - class IPsphere(visual.sphere): - def __init__(self, ip, **kargs): - visual.sphere.__init__(self, **kargs) - self.ip=ip - self.label=None - self.setlabel(self.ip) - def setlabel(self, txt,visible=None): - if self.label is not None: - if visible is None: - visible = self.label.visible - self.label.visible = 0 - elif visible is None: - visible=0 - self.label=visual.label(text=txt, pos=self.pos, space=self.radius, xoffset=10, yoffset=20, visible=visible) - def action(self): - self.label.visible ^= 1 - - visual.scene = visual.display() - visual.scene.exit = True - start = visual.box() - rings={} - tr3d = {} - for i in trace: - tr = trace[i] - tr3d[i] = [] - ttl = tr.keys() - for t in range(1,max(ttl)+1): - if t not in rings: - rings[t] = [] - if t in tr: - if tr[t] not in rings[t]: - rings[t].append(tr[t]) - tr3d[i].append(rings[t].index(tr[t])) - else: - rings[t].append(("unk",-1)) - tr3d[i].append(len(rings[t])-1) - for t in rings: - r = rings[t] - l = len(r) - for i in range(l): - if r[i][1] == -1: - col = (0.75,0.75,0.75) - elif r[i][1]: - col = visual.color.green - else: - col = visual.color.blue - - s = IPsphere(pos=((l-1)*visual.cos(2*i*visual.pi/l),(l-1)*visual.sin(2*i*visual.pi/l),2*t), - ip = r[i][0], - color = col) - for trlst in tr3d.values(): - if t <= len(trlst): - if trlst[t-1] == i: - trlst[t-1] = s - forecol = colgen(0.625, 0.4375, 0.25, 0.125) - for trlst in tr3d.values(): - col = next(forecol) - start = (0,0,0) - for ip in trlst: - visual.cylinder(pos=start,axis=ip.pos-start,color=col,radius=0.2) - start = ip.pos - - movcenter=None - while 1: - visual.rate(50) - if visual.scene.kb.keys: - k = visual.scene.kb.getkey() - if k == "esc" or k == "q": - break - if visual.scene.mouse.events: - ev = visual.scene.mouse.getevent() - if ev.press == "left": - o = ev.pick - if o: - if ev.ctrl: - if o.ip == "unk": - continue - savcolor = o.color - o.color = (1,0,0) - a,b=sr(IP(dst=o.ip)/TCP(dport=[21,22,23,25,80,443]),timeout=2) - o.color = savcolor - if len(a) == 0: - txt = "%s:\nno results" % o.ip - else: - txt = "%s:\n" % o.ip - for s,r in a: - txt += r.sprintf("{TCP:%IP.src%:%TCP.sport% %TCP.flags%}{TCPerror:%IPerror.dst%:%TCPerror.dport% %IP.src% %ir,ICMP.type%}\n") - o.setlabel(txt, visible=1) - else: - if hasattr(o, "action"): - o.action() - elif ev.drag == "left": - movcenter = ev.pos - elif ev.drop == "left": - movcenter = None - if movcenter: - visual.scene.center -= visual.scene.mouse.pos-movcenter - movcenter = visual.scene.mouse.pos - -## world_trace needs to be reimplemented as gnuplot dependency is removed -# def world_trace(self): -# from modules.geo import locate_ip -# ips = {} -# rt = {} -# ports_done = {} -# for s,r in self.res: -# ips[r.src] = None -# if s.haslayer(TCP) or s.haslayer(UDP): -# trace_id = (s.src,s.dst,s.proto,s.dport) -# elif s.haslayer(ICMP): -# trace_id = (s.src,s.dst,s.proto,s.type) -# else: -# trace_id = (s.src,s.dst,s.proto,0) -# trace = rt.get(trace_id,{}) -# if not r.haslayer(ICMP) or r.type != 11: -# if trace_id in ports_done: -# continue -# ports_done[trace_id] = None -# trace[s.ttl] = r.src -# rt[trace_id] = trace -# -# trt = {} -# for trace_id in rt: -# trace = rt[trace_id] -# loctrace = [] -# for i in range(max(trace.keys())): -# ip = trace.get(i,None) -# if ip is None: -# continue -# loc = locate_ip(ip) -# if loc is None: -# continue -## loctrace.append((ip,loc)) # no labels yet -# loctrace.append(loc) -# if loctrace: -# trt[trace_id] = loctrace -# -# tr = map(lambda x: Gnuplot.Data(x,with_="lines"), trt.values()) -# g = Gnuplot.Gnuplot() -# world = Gnuplot.File(conf.gnuplot_world,with_="lines") -# g.plot(world,*tr) -# return g - - def make_graph(self,ASres=None,padding=0): - if ASres is None: - ASres = conf.AS_resolver - self.graphASres = ASres - self.graphpadding = padding - ips = {} - rt = {} - ports = {} - ports_done = {} - for s,r in self.res: - r = r.getlayer(IP) or (conf.ipv6_enabled and r[scapy.layers.inet6.IPv6]) or r - s = s.getlayer(IP) or (conf.ipv6_enabled and s[scapy.layers.inet6.IPv6]) or s - ips[r.src] = None - if TCP in s: - trace_id = (s.src,s.dst,6,s.dport) - elif UDP in s: - trace_id = (s.src,s.dst,17,s.dport) - elif ICMP in s: - trace_id = (s.src,s.dst,1,s.type) - else: - trace_id = (s.src,s.dst,s.proto,0) - trace = rt.get(trace_id,{}) - ttl = conf.ipv6_enabled and scapy.layers.inet6.IPv6 in s and s.hlim or s.ttl - if not (ICMP in r and r[ICMP].type == 11) and not (conf.ipv6_enabled and scapy.layers.inet6.IPv6 in r and scapy.layers.inet6.ICMPv6TimeExceeded in r): - if trace_id in ports_done: - continue - ports_done[trace_id] = None - p = ports.get(r.src,[]) - if TCP in r: - p.append(r.sprintf("<T%ir,TCP.sport%> %TCP.sport% %TCP.flags%")) - trace[ttl] = r.sprintf('"%r,src%":T%ir,TCP.sport%') - elif UDP in r: - p.append(r.sprintf("<U%ir,UDP.sport%> %UDP.sport%")) - trace[ttl] = r.sprintf('"%r,src%":U%ir,UDP.sport%') - elif ICMP in r: - p.append(r.sprintf("<I%ir,ICMP.type%> ICMP %ICMP.type%")) - trace[ttl] = r.sprintf('"%r,src%":I%ir,ICMP.type%') - else: - p.append(r.sprintf("{IP:<P%ir,proto%> IP %proto%}{IPv6:<P%ir,nh%> IPv6 %nh%}")) - trace[ttl] = r.sprintf('"%r,src%":{IP:P%ir,proto%}{IPv6:P%ir,nh%}') - ports[r.src] = p - else: - trace[ttl] = r.sprintf('"%r,src%"') - rt[trace_id] = trace - - # Fill holes with unk%i nodes - unknown_label = incremental_label("unk%i") - blackholes = [] - bhip = {} - for rtk in rt: - trace = rt[rtk] - k = trace.keys() - for n in range(min(k), max(k)): - if not n in trace: - trace[n] = next(unknown_label) - if not rtk in ports_done: - if rtk[2] == 1: #ICMP - bh = "%s %i/icmp" % (rtk[1],rtk[3]) - elif rtk[2] == 6: #TCP - bh = "%s %i/tcp" % (rtk[1],rtk[3]) - elif rtk[2] == 17: #UDP - bh = '%s %i/udp' % (rtk[1],rtk[3]) - else: - bh = '%s %i/proto' % (rtk[1],rtk[2]) - ips[bh] = None - bhip[rtk[1]] = bh - bh = '"%s"' % bh - trace[max(k)+1] = bh - blackholes.append(bh) - - # Find AS numbers - ASN_query_list = dict.fromkeys(map(lambda x:x.rsplit(" ",1)[0],ips)).keys() - if ASres is None: - ASNlist = [] - else: - ASNlist = ASres.resolve(*ASN_query_list) - - ASNs = {} - ASDs = {} - for ip,asn,desc, in ASNlist: - if asn is None: - continue - iplist = ASNs.get(asn,[]) - if ip in bhip: - if ip in ports: - iplist.append(ip) - iplist.append(bhip[ip]) - else: - iplist.append(ip) - ASNs[asn] = iplist - ASDs[asn] = desc - - - backcolorlist=colgen("60","86","ba","ff") - forecolorlist=colgen("a0","70","40","20") - - s = "digraph trace {\n" - - s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n" - - s += "\n#ASN clustering\n" - for asn in ASNs: - s += '\tsubgraph cluster_%s {\n' % asn - col = next(backcolorlist) - s += '\t\tcolor="#%s%s%s";' % col - s += '\t\tnode [fillcolor="#%s%s%s",style=filled];' % col - s += '\t\tfontsize = 10;' - s += '\t\tlabel = "%s\\n[%s]"\n' % (asn,ASDs[asn]) - for ip in ASNs[asn]: - - s += '\t\t"%s";\n'%ip - s += "\t}\n" - - - - - s += "#endpoints\n" - for p in ports: - s += '\t"%s" [shape=record,color=black,fillcolor=green,style=filled,label="%s|%s"];\n' % (p,p,"|".join(ports[p])) - - s += "\n#Blackholes\n" - for bh in blackholes: - s += '\t%s [shape=octagon,color=black,fillcolor=red,style=filled];\n' % bh - - if padding: - s += "\n#Padding\n" - pad={} - for snd,rcv in self.res: - if rcv.src not in ports and rcv.haslayer(conf.padding_layer): - p = rcv.getlayer(conf.padding_layer).load - if p != "\x00"*len(p): - pad[rcv.src]=None - for rcv in pad: - s += '\t"%s" [shape=triangle,color=black,fillcolor=red,style=filled];\n' % rcv - - - - s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n" - - - for rtk in rt: - s += "#---[%s\n" % repr(rtk) - s += '\t\tedge [color="#%s%s%s"];\n' % next(forecolorlist) - trace = rt[rtk] - k = trace.keys() - for n in range(min(k), max(k)): - s += '\t%s ->\n' % trace[n] - s += '\t%s;\n' % trace[max(k)] - - s += "}\n"; - self.graphdef = s - - def graph(self, ASres=None, padding=0, **kargs): - """x.graph(ASres=conf.AS_resolver, other args): - ASres=None : no AS resolver => no clustering - ASres=AS_resolver() : default whois AS resolver (riswhois.ripe.net) - ASres=AS_resolver_cymru(): use whois.cymru.com whois database - ASres=AS_resolver(server="whois.ra.net") - format: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option - figsize: w,h tuple in inches. See matplotlib documentation - target: filename. If None uses matplotlib to display - prog: which graphviz program to use""" - if ASres is None: - ASres = conf.AS_resolver - if (self.graphdef is None or - self.graphASres != ASres or - self.graphpadding != padding): - self.make_graph(ASres,padding) - - return do_graph(self.graphdef, **kargs) - - - -@conf.commands.register -def traceroute(target, dport=80, minttl=1, maxttl=30, sport=RandShort(), l4 = None, filter=None, timeout=2, verbose=None, **kargs): - """Instant TCP traceroute -traceroute(target, [maxttl=30,] [dport=80,] [sport=80,] [verbose=conf.verb]) -> None -""" - if verbose is None: - verbose = conf.verb - if filter is None: - # we only consider ICMP error packets and TCP packets with at - # least the ACK flag set *and* either the SYN or the RST flag - # set - filter="(icmp and (icmp[0]=3 or icmp[0]=4 or icmp[0]=5 or icmp[0]=11 or icmp[0]=12)) or (tcp and (tcp[13] & 0x16 > 0x10))" - if l4 is None: - a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/TCP(seq=RandInt(),sport=sport, dport=dport), - timeout=timeout, filter=filter, verbose=verbose, **kargs) - else: - # this should always work - filter="ip" - a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/l4, - timeout=timeout, filter=filter, verbose=verbose, **kargs) - - a = TracerouteResult(a.res) - - if verbose: - a.show() - return a,b - - - -############################# -## Simple TCP client stack ## -############################# - -class TCP_client(Automaton): - - def parse_args(self, ip, port, *args, **kargs): - self.dst = next(iter(Net(ip))) - self.dport = port - self.sport = random.randrange(0,2**16) - self.l4 = IP(dst=ip)/TCP(sport=self.sport, dport=self.dport, flags=0, - seq=random.randrange(0,2**32)) - self.src = self.l4.src - self.swin=self.l4[TCP].window - self.dwin=1 - self.rcvbuf="" - bpf = "host %s and host %s and port %i and port %i" % (self.src, - self.dst, - self.sport, - self.dport) - -# bpf=None - Automaton.parse_args(self, filter=bpf, **kargs) - - - def master_filter(self, pkt): - return (IP in pkt and - pkt[IP].src == self.dst and - pkt[IP].dst == self.src and - TCP in pkt and - pkt[TCP].sport == self.dport and - pkt[TCP].dport == self.sport and - self.l4[TCP].seq >= pkt[TCP].ack and # XXX: seq/ack 2^32 wrap up - ((self.l4[TCP].ack == 0) or (self.l4[TCP].ack <= pkt[TCP].seq <= self.l4[TCP].ack+self.swin)) ) - - - @ATMT.state(initial=1) - def START(self): - pass - - @ATMT.state() - def SYN_SENT(self): - pass - - @ATMT.state() - def ESTABLISHED(self): - pass - - @ATMT.state() - def LAST_ACK(self): - pass - - @ATMT.state(final=1) - def CLOSED(self): - pass - - - @ATMT.condition(START) - def connect(self): - raise self.SYN_SENT() - @ATMT.action(connect) - def send_syn(self): - self.l4[TCP].flags = "S" - self.send(self.l4) - self.l4[TCP].seq += 1 - - - @ATMT.receive_condition(SYN_SENT) - def synack_received(self, pkt): - if pkt[TCP].flags & 0x3f == 0x12: - raise self.ESTABLISHED().action_parameters(pkt) - @ATMT.action(synack_received) - def send_ack_of_synack(self, pkt): - self.l4[TCP].ack = pkt[TCP].seq+1 - self.l4[TCP].flags = "A" - self.send(self.l4) - - @ATMT.receive_condition(ESTABLISHED) - def incoming_data_received(self, pkt): - if not isinstance(pkt[TCP].payload, NoPayload) and not isinstance(pkt[TCP].payload, conf.padding_layer): - raise self.ESTABLISHED().action_parameters(pkt) - @ATMT.action(incoming_data_received) - def receive_data(self,pkt): - data = (bytes(pkt[TCP].payload)) - if data and self.l4[TCP].ack == pkt[TCP].seq: - self.l4[TCP].ack += len(data) - self.l4[TCP].flags = "A" - self.send(self.l4) - self.rcvbuf += data - if pkt[TCP].flags & 8 != 0: #PUSH - self.oi.tcp.send(self.rcvbuf) - self.rcvbuf = "" - - @ATMT.ioevent(ESTABLISHED,name="tcp", as_supersocket="tcplink") - def outgoing_data_received(self, fd): - raise self.ESTABLISHED().action_parameters(fd.recv()) - @ATMT.action(outgoing_data_received) - def send_data(self, d): - self.l4[TCP].flags = "PA" - self.send(self.l4/d) - self.l4[TCP].seq += len(d) - - - @ATMT.receive_condition(ESTABLISHED) - def reset_received(self, pkt): - if pkt[TCP].flags & 4 != 0: - raise self.CLOSED() - - @ATMT.receive_condition(ESTABLISHED) - def fin_received(self, pkt): - if pkt[TCP].flags & 0x1 == 1: - raise self.LAST_ACK().action_parameters(pkt) - @ATMT.action(fin_received) - def send_finack(self, pkt): - self.l4[TCP].flags = "FA" - self.l4[TCP].ack = pkt[TCP].seq+1 - self.send(self.l4) - self.l4[TCP].seq += 1 - - @ATMT.receive_condition(LAST_ACK) - def ack_of_fin_received(self, pkt): - if pkt[TCP].flags & 0x3f == 0x10: - raise self.CLOSED() - - - - -##################### -## Reporting stuff ## -##################### - -def report_ports(target, ports): - """portscan a target and output a LaTeX table -report_ports(target, ports) -> string""" - ans,unans = sr(IP(dst=target)/TCP(dport=ports),timeout=5) - rep = "\\begin{tabular}{|r|l|l|}\n\\hline\n" - for s,r in ans: - if not r.haslayer(ICMP): - if r.payload.flags == 0x12: - rep += r.sprintf("%TCP.sport% & open & SA \\\\\n") - rep += "\\hline\n" - for s,r in ans: - if r.haslayer(ICMP): - rep += r.sprintf("%TCPerror.dport% & closed & ICMP type %ICMP.type%/%ICMP.code% from %IP.src% \\\\\n") - elif r.payload.flags != 0x12: - rep += r.sprintf("%TCP.sport% & closed & TCP %TCP.flags% \\\\\n") - rep += "\\hline\n" - for i in unans: - rep += i.sprintf("%TCP.dport% & ? & unanswered \\\\\n") - rep += "\\hline\n\\end{tabular}\n" - return rep - - - -def IPID_count(lst, funcID=lambda x:x[1].id, funcpres=lambda x:x[1].summary()): - idlst = map(funcID, lst) - idlst.sort() - #classes = [idlst[0]]+map(lambda x:x[1],filter(lambda (x,y): abs(x-y)>50, map(lambda x,y: (x,y),idlst[:-1], idlst[1:]))) - classes = [idlst[0]]+list(map(lambda x:x[1],filter(lambda a: abs(a[0]-a[1])>50, map(lambda x,y: (x,y),idlst[:-1], idlst[1:])))) - lst = map(lambda x:(funcID(x), funcpres(x)), lst) - lst.sort() - print("Probably %i classes:" % len(classes), classes) - for id,pr in lst: - print("%5i" % id, pr) - - -def fragleak(target,sport=123, dport=123, timeout=0.2, onlyasc=0): - load = "XXXXYYYYYYYYYY" -# getmacbyip(target) -# pkt = IP(dst=target, id=RandShort(), options="\x22"*40)/UDP()/load - pkt = IP(dst=target, id=RandShort(), options="\x00"*40, flags=1)/UDP(sport=sport, dport=sport)/load - s=conf.L3socket() - intr=0 - found={} - try: - while 1: - try: - if not intr: - s.send(pkt) - sin,sout,serr = select([s],[],[],timeout) - if not sin: - continue - ans=s.recv(1600) - if not isinstance(ans, IP): #TODO: IPv6 - continue - if not isinstance(ans.payload, ICMP): - continue - if not isinstance(ans.payload.payload, IPerror): - continue - if ans.payload.payload.dst != target: - continue - if ans.src != target: - print("leak from", ans.src,end=" ") - - -# print repr(ans) - if not ans.haslayer(conf.padding_layer): - continue - - -# print repr(ans.payload.payload.payload.payload) - -# if not isinstance(ans.payload.payload.payload.payload, conf.raw_layer): -# continue -# leak = ans.payload.payload.payload.payload.load[len(load):] - leak = ans.getlayer(conf.padding_layer).load - if leak not in found: - found[leak]=None - linehexdump(leak, onlyasc=onlyasc) - except KeyboardInterrupt: - if intr: - raise - intr=1 - except KeyboardInterrupt: - pass - -def fragleak2(target, timeout=0.4, onlyasc=0): - found={} - try: - while 1: - p = sr1(IP(dst=target, options="\x00"*40, proto=200)/"XXXXYYYYYYYYYYYY",timeout=timeout,verbose=0) - if not p: - continue - if conf.padding_layer in p: - leak = p[conf.padding_layer].load - if leak not in found: - found[leak]=None - linehexdump(leak,onlyasc=onlyasc) - except: - pass - - -conf.stats_classic_protocols += [TCP,UDP,ICMP] -conf.stats_dot11_protocols += [TCP,UDP,ICMP] - -if conf.ipv6_enabled: - import scapy.layers.inet6 diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/inet6.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/inet6.py deleted file mode 100644 index c2e4a037..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/inet6.py +++ /dev/null @@ -1,3047 +0,0 @@ -#! /usr/bin/env python -############################################################################# -## ## -## inet6.py --- IPv6 support for Scapy ## -## see http://natisbad.org/IPv6/ ## -## for more informations ## -## ## -## Copyright (C) 2005 Guillaume Valadon <guedou@hongo.wide.ad.jp> ## -## Arnaud Ebalard <arnaud.ebalard@eads.net> ## -## ## -## This program is free software; you can redistribute it and/or modify it ## -## under the terms of the GNU General Public License version 2 as ## -## published by the Free Software Foundation. ## -## ## -## This program is distributed in the hope that it will be useful, but ## -## WITHOUT ANY WARRANTY; without even the implied warranty of ## -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## -## General Public License for more details. ## -## ## -############################################################################# - -""" -IPv6 (Internet Protocol v6). -""" - - -import socket -if not socket.has_ipv6: - raise socket.error("can't use AF_INET6, IPv6 is disabled") -if not hasattr(socket, "IPPROTO_IPV6"): - # Workaround for http://bugs.python.org/issue6926 - socket.IPPROTO_IPV6 = 41 - -if not hasattr(socket, "IPPROTO_IPIP"): - socket.IPPROTO_IPIP = 4 - -if not ('IPPROTO_IPIP ' in globals()): - IPPROTO_IPIP=4 - - - -from scapy.config import conf -from scapy.layers.l2 import * -from scapy.layers.inet import * -from scapy.fields import * -from scapy.packet import * -from scapy.volatile import * -from scapy.sendrecv import sr,sr1,srp1 -from scapy.as_resolvers import AS_resolver_riswhois -from scapy.supersocket import SuperSocket,L3RawSocket -from scapy.arch import * -from scapy.utils6 import * - - -############################################################################# -# Helpers ## -############################################################################# - -def get_cls(name, fallback_cls): - return globals().get(name, fallback_cls) - - -########################## -## Neighbor cache stuff ## -########################## - -conf.netcache.new_cache("in6_neighbor", 120) - -def neighsol(addr, src, iface, timeout=1, chainCC=0): - """ - Sends an ICMPv6 Neighbor Solicitation message to get the MAC address - of the neighbor with specified IPv6 address addr. 'src' address is - used as source of the message. Message is sent on iface. By default, - timeout waiting for an answer is 1 second. - - If no answer is gathered, None is returned. Else, the answer is - returned (ethernet frame). - """ - - nsma = in6_getnsma(inet_pton(socket.AF_INET6, addr)) - d = inet_ntop(socket.AF_INET6, nsma) - dm = in6_getnsmac(nsma) - p = Ether(dst=dm)/IPv6(dst=d, src=src, hlim=255) - p /= ICMPv6ND_NS(tgt=addr) - p /= ICMPv6NDOptSrcLLAddr(lladdr=get_if_hwaddr(iface)) - res = srp1(p,type=ETH_P_IPV6, iface=iface, timeout=1, verbose=0, - chainCC=chainCC) - - return res - -def getmacbyip6(ip6, chainCC=0): - """ - Returns the mac address to be used for provided 'ip6' peer. - neighborCache.get() method is used on instantiated neighbor cache. - Resolution mechanism is described in associated doc string. - - (chainCC parameter value ends up being passed to sending function - used to perform the resolution, if needed) - """ - - if in6_ismaddr(ip6): # Multicast - mac = in6_getnsmac(inet_pton(socket.AF_INET6, ip6)) - return mac - - iff,a,nh = conf.route6.route(ip6, dev=conf.iface6) - - if iff == LOOPBACK_NAME: - return "ff:ff:ff:ff:ff:ff" - - if nh != '::': - ip6 = nh # Found next hop - - mac = conf.netcache.in6_neighbor.get(ip6) - if mac: - return mac - - res = neighsol(ip6, a, iff, chainCC=chainCC) - - if res is not None: - if ICMPv6NDOptDstLLAddr in res: - mac = res[ICMPv6NDOptDstLLAddr].lladdr - else: - mac = res.src - conf.netcache.in6_neighbor[ip6] = mac - return mac - - return None - - -############################################################################# -############################################################################# -### IPv6 addresses manipulation routines ### -############################################################################# -############################################################################# - -class Net6(Gen): # syntax ex. fec0::/126 - """Generate a list of IPv6s from a network address or a name""" - name = "ipv6" - ipaddress = re.compile(r"^([a-fA-F0-9:]+)(/[1]?[0-3]?[0-9])?$") - - def __init__(self, net): - self.repr = net - - tmp = net.split('/')+["128"] - if not self.ipaddress.match(net): - tmp[0]=socket.getaddrinfo(tmp[0], None, socket.AF_INET6)[0][-1][0] - - netmask = int(tmp[1]) - self.net = inet_pton(socket.AF_INET6, tmp[0]) - self.mask = in6_cidr2mask(netmask) - self.plen = netmask - - def __iter__(self): - def m8(i): - if i % 8 == 0: - return i - #tuple = filter(lambda x: m8(x), range(8, 129)) - tuple = [ x for x in range(8, 129) if m8(x) ] - - a = in6_and(self.net, self.mask) - tmp = map(lambda x: x, struct.unpack('16B', a)) - - def parse_digit(a, netmask): - netmask = min(8,max(netmask,0)) - a = (int(a) & (0xff<<netmask),(int(a) | (0xff>>(8-netmask)))+1) - return a - self.parsed = map(lambda x,y: parse_digit(x,y), tmp, map(lambda x,nm=self.plen: x-nm, tuple)) - - def rec(n, l): - if n and n % 2 == 0: - sep = ':' - else: - sep = '' - if n == 16: - return l - else: - ll = [] - for i in range(*self.parsed[n]): - for y in l: - ll += [y+sep+'%.2x'%i] - return rec(n+1, ll) - - return iter(rec(0, [''])) - - def __repr__(self): - return "<Net6 %s>" % self.repr - - - - - - -############################################################################# -############################################################################# -### IPv6 Class ### -############################################################################# -############################################################################# - -class IP6Field(Field): - def __init__(self, name, default): - Field.__init__(self, name, default, "16s") - def h2i(self, pkt, x): - if type(x) is str: - try: - x = in6_ptop(x) - except socket.error: - x = Net6(x) - elif type(x) is list: - x = map(Net6, x) - return x - def i2m(self, pkt, x): - return inet_pton(socket.AF_INET6, x) - def m2i(self, pkt, x): - return inet_ntop(socket.AF_INET6, x) - def any2i(self, pkt, x): - return self.h2i(pkt,x) - def i2repr(self, pkt, x): - if x is None: - return self.i2h(pkt,x) - elif not isinstance(x, Net6) and not type(x) is list: - if in6_isaddrTeredo(x): # print Teredo info - server, flag, maddr, mport = teredoAddrExtractInfo(x) - return "%s [Teredo srv: %s cli: %s:%s]" % (self.i2h(pkt, x), server, maddr,mport) - elif in6_isaddr6to4(x): # print encapsulated address - vaddr = in6_6to4ExtractAddr(x) - return "%s [6to4 GW: %s]" % (self.i2h(pkt, x), vaddr) - return self.i2h(pkt, x) # No specific information to return - def randval(self): - return RandIP6() - -class SourceIP6Field(IP6Field): - def __init__(self, name, dstname): - IP6Field.__init__(self, name, None) - self.dstname = dstname - def i2m(self, pkt, x): - if x is None: - dst=getattr(pkt,self.dstname) - iff,x,nh = conf.route6.route(dst) - return IP6Field.i2m(self, pkt, x) - def i2h(self, pkt, x): - if x is None: - dst=getattr(pkt,self.dstname) - if isinstance(dst,Gen): - r = map(conf.route6.route, dst) - r.sort() - if r[0] == r[-1]: - x=r[0][1] - else: - warning("More than one possible route for %s"%repr(dst)) - return None - else: - iff,x,nh = conf.route6.route(dst) - return IP6Field.i2h(self, pkt, x) - -ipv6nh = { 0:"Hop-by-Hop Option Header", - 4:"IP", - 6:"TCP", - 17:"UDP", - 41:"IPv6", - 43:"Routing Header", - 44:"Fragment Header", - 47:"GRE", - 50:"ESP Header", - 51:"AH Header", - 58:"ICMPv6", - 59:"No Next Header", - 60:"Destination Option Header", - 135:"Mobility Header"} - -ipv6nhcls = { 0: "IPv6ExtHdrHopByHop", - 4: "IP", - 6: "TCP", - 17: "UDP", - 43: "IPv6ExtHdrRouting", - 44: "IPv6ExtHdrFragment", - #50: "IPv6ExtHrESP", - #51: "IPv6ExtHdrAH", - 58: "ICMPv6Unknown", - 59: "Raw", - 60: "IPv6ExtHdrDestOpt" } - -class IP6ListField(StrField): - islist = 1 - def __init__(self, name, default, count_from=None, length_from=None): - if default is None: - default = [] - StrField.__init__(self, name, default) - self.count_from = count_from - self.length_from = length_from - - def i2len(self, pkt, i): - return 16*len(i) - - def i2count(self, pkt, i): - if type(i) is list: - return len(i) - return 0 - - def getfield(self, pkt, s): - c = l = None - if self.length_from is not None: - l = self.length_from(pkt) - elif self.count_from is not None: - c = self.count_from(pkt) - - lst = [] - ret = b"" - remain = s - if l is not None: - remain,ret = s[:l],s[l:] - while remain: - if c is not None: - if c <= 0: - break - c -= 1 - addr = inet_ntop(socket.AF_INET6, remain[:16]) - lst.append(addr) - remain = remain[16:] - return remain+ret,lst - - def i2m(self, pkt, x): - s = b'' - for y in x: - try: - y = inet_pton(socket.AF_INET6, y) - except: - y = socket.getaddrinfo(y, None, socket.AF_INET6)[0][-1][0] - y = inet_pton(socket.AF_INET6, y) - s += y - return s - - def i2repr(self,pkt,x): - s = [] - if x == None: - return "[]" - for y in x: - s.append('%s' % y) - return "[ %s ]" % (", ".join(s)) - -class _IPv6GuessPayload: - name = "Dummy class that implements guess_payload_class() for IPv6" - def default_payload_class(self,p): - if self.nh == 58: # ICMPv6 - #t = ord(p[0]) - t = p[0] - if len(p) > 2 and t == 139 or t == 140: # Node Info Query - return _niquery_guesser(p) - if len(p) >= icmp6typesminhdrlen.get(t, sys.maxsize): # Other ICMPv6 messages - return get_cls(icmp6typescls.get(t,"Raw"), "Raw") - return Raw - elif self.nh == 135 and len(p) > 3: # Mobile IPv6 - #return _mip6_mhtype2cls.get(ord(p[2]), MIP6MH_Generic) - return _mip6_mhtype2cls.get(p[2], MIP6MH_Generic) - else: - return get_cls(ipv6nhcls.get(self.nh,"Raw"), "Raw") - -class IPv6(_IPv6GuessPayload, Packet, IPTools): - name = "IPv6" - fields_desc = [ BitField("version" , 6 , 4), - BitField("tc", 0, 8), #TODO: IPv6, ByteField ? - BitField("fl", 0, 20), - ShortField("plen", None), - ByteEnumField("nh", 59, ipv6nh), - ByteField("hlim", 64), - IP6Field("src", "::2"), - #SourceIP6Field("src", "dst"), # dst is for src @ selection - IP6Field("dst", "::1") ] - - def route(self): - dst = self.dst - if isinstance(dst,Gen): - dst = next(iter(dst)) - return conf.route6.route(dst) - - def mysummary(self): - return "%s > %s (%i)" % (self.src,self.dst, self.nh) - - def post_build(self, p, pay): - p += pay - if self.plen is None: - l = len(p) - 40 - p = p[:4]+struct.pack("!H", l)+p[6:] - return p - - def extract_padding(self, s): - l = self.plen - return s[:l], s[l:] - - def hashret(self): - if self.nh == 58 and isinstance(self.payload, _ICMPv6): - if self.payload.type < 128: - return self.payload.payload.hashret() - elif (self.payload.type in [133,134,135,136,144,145]): - return struct.pack("B", self.nh)+self.payload.hashret() - - nh = self.nh - sd = self.dst - ss = self.src - if self.nh == 43 and isinstance(self.payload, IPv6ExtHdrRouting): - # With routing header, the destination is the last - # address of the IPv6 list if segleft > 0 - nh = self.payload.nh - try: - sd = self.addresses[-1] - except IndexError: - sd = '::1' - # TODO: big bug with ICMPv6 error messages as the destination of IPerror6 - # could be anything from the original list ... - if 1: - sd = inet_pton(socket.AF_INET6, sd) - for a in self.addresses: - a = inet_pton(socket.AF_INET6, a) - sd = strxor(sd, a) - sd = inet_ntop(socket.AF_INET6, sd) - - if self.nh == 44 and isinstance(self.payload, IPv6ExtHdrFragment): - nh = self.payload.nh - - if self.nh == 0 and isinstance(self.payload, IPv6ExtHdrHopByHop): - nh = self.payload.nh - - if self.nh == 60 and isinstance(self.payload, IPv6ExtHdrDestOpt): - foundhao = None - for o in self.payload.options: - if isinstance(o, HAO): - foundhao = o - if foundhao: - nh = self.payload.nh # XXX what if another extension follows ? - ss = foundhao.hoa - - if conf.checkIPsrc and conf.checkIPaddr: - sd = inet_pton(socket.AF_INET6, sd) - ss = inet_pton(socket.AF_INET6, self.src) - return struct.pack("B",nh)+self.payload.hashret() - else: - return struct.pack("B", nh)+self.payload.hashret() - - def answers(self, other): - if not isinstance(other, IPv6): # self is reply, other is request - return False - if conf.checkIPaddr: - ss = inet_pton(socket.AF_INET6, self.src) - sd = inet_pton(socket.AF_INET6, self.dst) - os = inet_pton(socket.AF_INET6, other.src) - od = inet_pton(socket.AF_INET6, other.dst) - # request was sent to a multicast address (other.dst) - # Check reply destination addr matches request source addr (i.e - # sd == os) except when reply is multicasted too - # XXX test mcast scope matching ? - if in6_ismaddr(other.dst): - if in6_ismaddr(self.dst): - if ((od == sd) or - (in6_isaddrllallnodes(self.dst) and in6_isaddrllallservers(other.dst))): - return self.payload.answers(other.payload) - return False - if (os == sd): - return self.payload.answers(other.payload) - return False - elif (sd != os): # or ss != od): <- removed for ICMP errors - return False - if self.nh == 58 and isinstance(self.payload, _ICMPv6) and self.payload.type < 128: - # ICMPv6 Error message -> generated by IPv6 packet - # Note : at the moment, we jump the ICMPv6 specific class - # to call answers() method of erroneous packet (over - # initial packet). There can be cases where an ICMPv6 error - # class could implement a specific answers method that perform - # a specific task. Currently, don't see any use ... - return self.payload.payload.answers(other) - elif other.nh == 0 and isinstance(other.payload, IPv6ExtHdrHopByHop): - return self.payload.answers(other.payload.payload) - elif other.nh == 44 and isinstance(other.payload, IPv6ExtHdrFragment): - return self.payload.answers(other.payload.payload) - elif other.nh == 43 and isinstance(other.payload, IPv6ExtHdrRouting): - return self.payload.answers(other.payload.payload) # Buggy if self.payload is a IPv6ExtHdrRouting - elif other.nh == 60 and isinstance(other.payload, IPv6ExtHdrDestOpt): - return self.payload.payload.answers(other.payload.payload) - elif self.nh == 60 and isinstance(self.payload, IPv6ExtHdrDestOpt): # BU in reply to BRR, for instance - return self.payload.payload.answers(other.payload) - else: - if (self.nh != other.nh): - return False - return self.payload.answers(other.payload) - - -conf.neighbor.register_l3(Ether, IPv6, lambda l2,l3: getmacbyip6(l3.dst)) - - -class IPerror6(IPv6): - name = "IPv6 in ICMPv6" - def answers(self, other): - if not isinstance(other, IPv6): - return False - sd = inet_pton(socket.AF_INET6, self.dst) - ss = inet_pton(socket.AF_INET6, self.src) - od = inet_pton(socket.AF_INET6, other.dst) - os = inet_pton(socket.AF_INET6, other.src) - - # Make sure that the ICMPv6 error is related to the packet scapy sent - if isinstance(self.underlayer, _ICMPv6) and self.underlayer.type < 128: - - # find upper layer for self (possible citation) - selfup = self.payload - while selfup is not None and isinstance(selfup, _IPv6ExtHdr): - selfup = selfup.payload - - # find upper layer for other (initial packet). Also look for RH - otherup = other.payload - request_has_rh = False - while otherup is not None and isinstance(otherup, _IPv6ExtHdr): - if isinstance(otherup, IPv6ExtHdrRouting): - request_has_rh = True - otherup = otherup.payload - - if ((ss == os and sd == od) or # <- Basic case - (ss == os and request_has_rh)): # <- Request has a RH : - # don't check dst address - - # Let's deal with possible MSS Clamping - if (isinstance(selfup, TCP) and - isinstance(otherup, TCP) and - selfup.options != otherup.options): # seems clamped - - # Save fields modified by MSS clamping - old_otherup_opts = otherup.options - old_otherup_cksum = otherup.chksum - old_otherup_dataofs = otherup.dataofs - old_selfup_opts = selfup.options - old_selfup_cksum = selfup.chksum - old_selfup_dataofs = selfup.dataofs - - # Nullify them - otherup.options = [] - otherup.chksum = 0 - otherup.dataofs = 0 - selfup.options = [] - selfup.chksum = 0 - selfup.dataofs = 0 - - # Test it and save result - s1 = bytes(selfup) - s2 = bytes(otherup) - l = min(len(s1), len(s2)) - res = s1[:l] == s2[:l] - - # recall saved values - otherup.options = old_otherup_opts - otherup.chksum = old_otherup_cksum - otherup.dataofs = old_otherup_dataofs - selfup.options = old_selfup_opts - selfup.chksum = old_selfup_cksum - selfup.dataofs = old_selfup_dataofs - - return res - - s1 = bytes(selfup) - s2 = bytes(otherup) - l = min(len(s1), len(s2)) - return s1[:l] == s2[:l] - - return False - - def mysummary(self): - return Packet.mysummary(self) - - -############################################################################# -############################################################################# -### Upper Layer Checksum computation ### -############################################################################# -############################################################################# - -class PseudoIPv6(Packet): # IPv6 Pseudo-header for checksum computation - name = "Pseudo IPv6 Header" - fields_desc = [ IP6Field("src", "::"), - IP6Field("dst", "::"), - ShortField("uplen", None), - BitField("zero", 0, 24), - ByteField("nh", 0) ] - -def in6_chksum(nh, u, p): - """ - Performs IPv6 Upper Layer checksum computation. Provided parameters are: - - - 'nh' : value of upper layer protocol - - 'u' : upper layer instance (TCP, UDP, ICMPv6*, ). Instance must be - provided with all under layers (IPv6 and all extension headers, - for example) - - 'p' : the payload of the upper layer provided as a string - - Functions operate by filling a pseudo header class instance (PseudoIPv6) - with - - Next Header value - - the address of _final_ destination (if some Routing Header with non - segleft field is present in underlayer classes, last address is used.) - - the address of _real_ source (basically the source address of an - IPv6 class instance available in the underlayer or the source address - in HAO option if some Destination Option header found in underlayer - includes this option). - - the length is the length of provided payload string ('p') - """ - - ph6 = PseudoIPv6() - ph6.nh = nh - rthdr = 0 - hahdr = 0 - final_dest_addr_found = 0 - while u != None and not isinstance(u, IPv6): - if (isinstance(u, IPv6ExtHdrRouting) and - u.segleft != 0 and len(u.addresses) != 0 and - final_dest_addr_found == 0): - rthdr = u.addresses[-1] - final_dest_addr_found = 1 - elif (isinstance(u, IPv6ExtHdrDestOpt) and (len(u.options) == 1) and - isinstance(u.options[0], HAO)): - hahdr = u.options[0].hoa - u = u.underlayer - if u is None: - warning("No IPv6 underlayer to compute checksum. Leaving null.") - return 0 - if hahdr: - ph6.src = hahdr - else: - ph6.src = u.src - if rthdr: - ph6.dst = rthdr - else: - ph6.dst = u.dst - ph6.uplen = len(p) - ph6s = bytes(ph6) - return checksum(ph6s+p) - - -############################################################################# -############################################################################# -### Extension Headers ### -############################################################################# -############################################################################# - - -# Inherited by all extension header classes -class _IPv6ExtHdr(_IPv6GuessPayload, Packet): - name = 'Abstract IPV6 Option Header' - aliastypes = [IPv6, IPerror6] # TODO ... - - -#################### IPv6 options for Extension Headers ##################### - -_hbhopts = { 0x00: "Pad1", - 0x01: "PadN", - 0x04: "Tunnel Encapsulation Limit", - 0x05: "Router Alert", - 0x06: "Quick-Start", - 0xc2: "Jumbo Payload", - 0xc9: "Home Address Option" } - -class _OTypeField(ByteEnumField): - """ - Modified BytEnumField that displays information regarding the IPv6 option - based on its option type value (What should be done by nodes that process - the option if they do not understand it ...) - - It is used by Jumbo, Pad1, PadN, RouterAlert, HAO options - """ - pol = {0x00: "00: skip", - 0x40: "01: discard", - 0x80: "10: discard+ICMP", - 0xC0: "11: discard+ICMP not mcast"} - - enroutechange = {0x00: "0: Don't change en-route", - 0x20: "1: May change en-route" } - - def i2repr(self, pkt, x): - s = self.i2s.get(x, repr(x)) - polstr = self.pol[(x & 0xC0)] - enroutechangestr = self.enroutechange[(x & 0x20)] - return "%s [%s, %s]" % (s, polstr, enroutechangestr) - -class HBHOptUnknown(Packet): # IPv6 Hop-By-Hop Option - name = "Scapy6 Unknown Option" - fields_desc = [_OTypeField("otype", 0x01, _hbhopts), - FieldLenField("optlen", None, length_of="optdata", fmt="B"), - StrLenField("optdata", "", - length_from = lambda pkt: pkt.optlen) ] - def alignment_delta(self, curpos): # By default, no alignment requirement - """ - As specified in section 4.2 of RFC 2460, every options has - an alignment requirement ususally expressed xn+y, meaning - the Option Type must appear at an integer multiple of x octest - from the start of the header, plus y octet. - - That function is provided the current position from the - start of the header and returns required padding length. - """ - return 0 - -class Pad1(Packet): # IPv6 Hop-By-Hop Option - name = "Pad1" - fields_desc = [ _OTypeField("otype", 0x00, _hbhopts) ] - def alignment_delta(self, curpos): # No alignment requirement - return 0 - -class PadN(Packet): # IPv6 Hop-By-Hop Option - name = "PadN" - fields_desc = [_OTypeField("otype", 0x01, _hbhopts), - FieldLenField("optlen", None, length_of="optdata", fmt="B"), - StrLenField("optdata", "", - length_from = lambda pkt: pkt.optlen)] - def alignment_delta(self, curpos): # No alignment requirement - return 0 - -class RouterAlert(Packet): # RFC 2711 - IPv6 Hop-By-Hop Option - name = "Router Alert" - fields_desc = [_OTypeField("otype", 0x05, _hbhopts), - ByteField("optlen", 2), - ShortEnumField("value", None, - { 0: "Datagram contains a MLD message", - 1: "Datagram contains RSVP message", - 2: "Datagram contains an Active Network message" }) ] - # TODO : Check IANA has not defined new values for value field of RouterAlertOption - # TODO : now that we have that option, we should do something in MLD class that need it - def alignment_delta(self, curpos): # alignment requirement : 2n+0 - x = 2 ; y = 0 - delta = x*((curpos - y + x - 1)//x) + y - curpos - return delta - -class Jumbo(Packet): # IPv6 Hop-By-Hop Option - name = "Jumbo Payload" - fields_desc = [_OTypeField("otype", 0xC2, _hbhopts), - ByteField("optlen", 4), - IntField("jumboplen", None) ] - def alignment_delta(self, curpos): # alignment requirement : 4n+2 - x = 4 ; y = 2 - delta = x*((curpos - y + x - 1)//x) + y - curpos - return delta - -class HAO(Packet): # IPv6 Destination Options Header Option - name = "Home Address Option" - fields_desc = [_OTypeField("otype", 0xC9, _hbhopts), - ByteField("optlen", 16), - IP6Field("hoa", "::") ] - def alignment_delta(self, curpos): # alignment requirement : 8n+6 - x = 8 ; y = 6 - delta = x*((curpos - y + x - 1)//x) + y - curpos - return delta - -_hbhoptcls = { 0x00: Pad1, - 0x01: PadN, - 0x05: RouterAlert, - 0xC2: Jumbo, - 0xC9: HAO } - - -######################## Hop-by-Hop Extension Header ######################## - -class _HopByHopOptionsField(PacketListField): - islist = 1 - holds_packet = 1 - def __init__(self, name, default, cls, curpos, count_from=None, length_from=None): - self.curpos = curpos - PacketListField.__init__(self, name, default, cls, count_from=count_from, length_from=length_from) - - def i2len(self, pkt, i): - l = len(self.i2m(pkt, i)) - return l - - def i2count(self, pkt, i): - if type(i) is list: - return len(i) - return 0 - - def getfield(self, pkt, s): - c = l = None - if self.length_from is not None: - l = self.length_from(pkt) - elif self.count_from is not None: - c = self.count_from(pkt) - - opt = [] - ret = b"" - x = s - if l is not None: - x,ret = s[:l],s[l:] - while x: - if c is not None: - if c <= 0: - break - c -= 1 - #o = ord(x[0]) # Option type - o = x[0] # Option type - cls = self.cls - if o in _hbhoptcls: - cls = _hbhoptcls[o] - try: - op = cls(x) - except: - op = self.cls(x) - opt.append(op) - if isinstance(op.payload, conf.raw_layer): - x = op.payload.load - del(op.payload) - else: - x = b"" - return x+ret,opt - - def i2m(self, pkt, x): - autopad = None - try: - autopad = getattr(pkt, "autopad") # Hack : 'autopad' phantom field - except: - autopad = 1 - - if not autopad: - return b"".join(map(bytes, x)) - - curpos = self.curpos - s = b"" - for p in x: - d = p.alignment_delta(curpos) - curpos += d - if d == 1: - s += bytes(Pad1()) - elif d != 0: - s += bytes(PadN(optdata=b'\x00'*(d-2))) - pstr = bytes(p) - curpos += len(pstr) - s += pstr - - # Let's make the class including our option field - # a multiple of 8 octets long - d = curpos % 8 - if d == 0: - return s - d = 8 - d - if d == 1: - s += bytes(Pad1()) - elif d != 0: - s += bytes(PadN(optdata=b'\x00'*(d-2))) - - return s - - def addfield(self, pkt, s, val): - return s+self.i2m(pkt, val) - -class _PhantomAutoPadField(ByteField): - def addfield(self, pkt, s, val): - return s - - def getfield(self, pkt, s): - return s, 1 - - def i2repr(self, pkt, x): - if x: - return "On" - return "Off" - - -class IPv6ExtHdrHopByHop(_IPv6ExtHdr): - name = "IPv6 Extension Header - Hop-by-Hop Options Header" - fields_desc = [ ByteEnumField("nh", 59, ipv6nh), - FieldLenField("len", None, length_of="options", fmt="B", - adjust = lambda pkt,x: (x+2+7)//8 - 1), - _PhantomAutoPadField("autopad", 1), # autopad activated by default - _HopByHopOptionsField("options", [], HBHOptUnknown, 2, - length_from = lambda pkt: (8*(pkt.len+1))-2) ] - overload_fields = {IPv6: { "nh": 0 }} - - -######################## Destination Option Header ########################## - -class IPv6ExtHdrDestOpt(_IPv6ExtHdr): - name = "IPv6 Extension Header - Destination Options Header" - fields_desc = [ ByteEnumField("nh", 59, ipv6nh), - FieldLenField("len", None, length_of="options", fmt="B", - adjust = lambda pkt,x: (x+2+7)//8 - 1), - _PhantomAutoPadField("autopad", 1), # autopad activated by default - _HopByHopOptionsField("options", [], HBHOptUnknown, 2, - length_from = lambda pkt: (8*(pkt.len+1))-2) ] - overload_fields = {IPv6: { "nh": 60 }} - - -############################# Routing Header ################################ - -class IPv6ExtHdrRouting(_IPv6ExtHdr): - name = "IPv6 Option Header Routing" - fields_desc = [ ByteEnumField("nh", 59, ipv6nh), - FieldLenField("len", None, count_of="addresses", fmt="B", - adjust = lambda pkt,x:2*x), # in 8 bytes blocks - ByteField("type", 0), - ByteField("segleft", None), - BitField("reserved", 0, 32), # There is meaning in this field ... - IP6ListField("addresses", [], - length_from = lambda pkt: 8*pkt.len)] - overload_fields = {IPv6: { "nh": 43 }} - - def post_build(self, pkt, pay): - if self.segleft is None: - pkt = pkt[:3]+struct.pack("B", len(self.addresses))+pkt[4:] - return _IPv6ExtHdr.post_build(self, pkt, pay) - -########################### Fragmentation Header ############################ - -class IPv6ExtHdrFragment(_IPv6ExtHdr): - name = "IPv6 Extension Header - Fragmentation header" - fields_desc = [ ByteEnumField("nh", 59, ipv6nh), - BitField("res1", 0, 8), - BitField("offset", 0, 13), - BitField("res2", 0, 2), - BitField("m", 0, 1), - IntField("id", None) ] - overload_fields = {IPv6: { "nh": 44 }} - - -def defragment6(pktlist): - """ - Performs defragmentation of a list of IPv6 packets. Packets are reordered. - Crap is dropped. What lacks is completed by 'X' characters. - """ - - l = [ x for x in pktlist if IPv6ExtHdrFragment in x ] # remove non fragments - if not l: - return [] - - id = l[0][IPv6ExtHdrFragment].id - - llen = len(l) - l = [ x for x in l if x[IPv6ExtHdrFragment].id == id ] - if len(l) != llen: - warning("defragment6: some fragmented packets have been removed from list") - llen = len(l) - - # reorder fragments - i = 0 - res = [] - while l: - min_pos = 0 - min_offset = l[0][IPv6ExtHdrFragment].offset - for p in l: - cur_offset = p[IPv6ExtHdrFragment].offset - if cur_offset < min_offset: - min_pos = 0 - min_offset = cur_offset - res.append(l[min_pos]) - del(l[min_pos]) - - # regenerate the fragmentable part - fragmentable = b"" - for p in res: - q=p[IPv6ExtHdrFragment] - offset = 8*q.offset - if offset != len(fragmentable): - warning("Expected an offset of %d. Found %d. Padding with XXXX" % (len(fragmentable), offset)) - fragmentable += b"X"*(offset - len(fragmentable)) - fragmentable += bytes(q.payload) - - # Regenerate the unfragmentable part. - q = res[0] - nh = q[IPv6ExtHdrFragment].nh - q[IPv6ExtHdrFragment].underlayer.nh = nh - q[IPv6ExtHdrFragment].underlayer.payload = None - q /= conf.raw_layer(load=fragmentable) - - return IPv6(bytes(q)) - - -def fragment6(pkt, fragSize): - """ - Performs fragmentation of an IPv6 packet. Provided packet ('pkt') must already - contain an IPv6ExtHdrFragment() class. 'fragSize' argument is the expected - maximum size of fragments (MTU). The list of packets is returned. - - If packet does not contain an IPv6ExtHdrFragment class, it is returned in - result list. - """ - - pkt = pkt.copy() - - if not IPv6ExtHdrFragment in pkt: - # TODO : automatically add a fragment before upper Layer - # at the moment, we do nothing and return initial packet - # as single element of a list - return [pkt] - - # If the payload is bigger than 65535, a Jumbo payload must be used, as - # an IPv6 packet can't be bigger than 65535 bytes. - if len(bytes(pkt[IPv6ExtHdrFragment])) > 65535: - warning("An IPv6 packet can'be bigger than 65535, please use a Jumbo payload.") - return [] - - s = bytes(pkt) # for instantiation to get upper layer checksum right - - if len(s) <= fragSize: - return [pkt] - - # Fragmentable part : fake IPv6 for Fragmentable part length computation - fragPart = pkt[IPv6ExtHdrFragment].payload - tmp = bytes(IPv6(src="::1", dst="::1")/fragPart) - fragPartLen = len(tmp) - 40 # basic IPv6 header length - fragPartStr = s[-fragPartLen:] - - # Grab Next Header for use in Fragment Header - nh = IPv6(tmp[:40]).nh - - # Keep fragment header - fragHeader = pkt[IPv6ExtHdrFragment] - fragHeader.payload = None # detach payload - - # Unfragmentable Part - unfragPartLen = len(s) - fragPartLen - 8 - unfragPart = pkt - pkt[IPv6ExtHdrFragment].underlayer.payload = None # detach payload - - # Cut the fragmentable part to fit fragSize. Inner fragments have - # a length that is an integer multiple of 8 octets. last Frag MTU - # can be anything below MTU - lastFragSize = fragSize - unfragPartLen - 8 - innerFragSize = lastFragSize - (lastFragSize % 8) - - if lastFragSize <= 0 or innerFragSize == 0: - warning("Provided fragment size value is too low. " + - "Should be more than %d" % (unfragPartLen + 8)) - return [unfragPart/fragHeader/fragPart] - - remain = fragPartStr - res = [] - fragOffset = 0 # offset, incremeted during creation - fragId = random.randint(0,0xffffffff) # random id ... - if fragHeader.id is not None: # ... except id provided by user - fragId = fragHeader.id - fragHeader.m = 1 - fragHeader.id = fragId - fragHeader.nh = nh - - # Main loop : cut, fit to FRAGSIZEs, fragOffset, Id ... - while True: - if (len(remain) > lastFragSize): - tmp = remain[:innerFragSize] - remain = remain[innerFragSize:] - fragHeader.offset = fragOffset # update offset - fragOffset += (innerFragSize // 8) # compute new one - if IPv6 in unfragPart: - unfragPart[IPv6].plen = None - tempo = unfragPart/fragHeader/conf.raw_layer(load=tmp) - res.append(tempo) - else: - fragHeader.offset = fragOffset # update offSet - fragHeader.m = 0 - if IPv6 in unfragPart: - unfragPart[IPv6].plen = None - tempo = unfragPart/fragHeader/conf.raw_layer(load=remain) - res.append(tempo) - break - return res - - -############################### AH Header ################################### - -# class _AHFieldLenField(FieldLenField): -# def getfield(self, pkt, s): -# l = getattr(pkt, self.fld) -# l = (l*8)-self.shift -# i = self.m2i(pkt, s[:l]) -# return s[l:],i - -# class _AHICVStrLenField(StrLenField): -# def i2len(self, pkt, x): - - - -# class IPv6ExtHdrAH(_IPv6ExtHdr): -# name = "IPv6 Extension Header - AH" -# fields_desc = [ ByteEnumField("nh", 59, ipv6nh), -# _AHFieldLenField("len", None, "icv"), -# ShortField("res", 0), -# IntField("spi", 0), -# IntField("sn", 0), -# _AHICVStrLenField("icv", None, "len", shift=2) ] -# overload_fields = {IPv6: { "nh": 51 }} - -# def post_build(self, pkt, pay): -# if self.len is None: -# pkt = pkt[0]+struct.pack("!B", 2*len(self.addresses))+pkt[2:] -# if self.segleft is None: -# pkt = pkt[:3]+struct.pack("!B", len(self.addresses))+pkt[4:] -# return _IPv6ExtHdr.post_build(self, pkt, pay) - - -############################### ESP Header ################################## - -# class IPv6ExtHdrESP(_IPv6extHdr): -# name = "IPv6 Extension Header - ESP" -# fields_desc = [ IntField("spi", 0), -# IntField("sn", 0), -# # there is things to extract from IKE work -# ] -# overloads_fields = {IPv6: { "nh": 50 }} - - - -############################################################################# -############################################################################# -### ICMPv6* Classes ### -############################################################################# -############################################################################# - -icmp6typescls = { 1: "ICMPv6DestUnreach", - 2: "ICMPv6PacketTooBig", - 3: "ICMPv6TimeExceeded", - 4: "ICMPv6ParamProblem", - 128: "ICMPv6EchoRequest", - 129: "ICMPv6EchoReply", - 130: "ICMPv6MLQuery", - 131: "ICMPv6MLReport", - 132: "ICMPv6MLDone", - 133: "ICMPv6ND_RS", - 134: "ICMPv6ND_RA", - 135: "ICMPv6ND_NS", - 136: "ICMPv6ND_NA", - 137: "ICMPv6ND_Redirect", - #138: Do Me - RFC 2894 - Seems painful - 139: "ICMPv6NIQuery", - 140: "ICMPv6NIReply", - 141: "ICMPv6ND_INDSol", - 142: "ICMPv6ND_INDAdv", - #143: Do Me - RFC 3810 - 144: "ICMPv6HAADRequest", - 145: "ICMPv6HAADReply", - 146: "ICMPv6MPSol", - 147: "ICMPv6MPAdv", - #148: Do Me - SEND related - RFC 3971 - #149: Do Me - SEND related - RFC 3971 - 151: "ICMPv6MRD_Advertisement", - 152: "ICMPv6MRD_Solicitation", - 153: "ICMPv6MRD_Termination", - } - -icmp6typesminhdrlen = { 1: 8, - 2: 8, - 3: 8, - 4: 8, - 128: 8, - 129: 8, - 130: 24, - 131: 24, - 132: 24, - 133: 8, - 134: 16, - 135: 24, - 136: 24, - 137: 40, - #139: - #140 - 141: 8, - 142: 8, - 144: 8, - 145: 8, - 146: 8, - 147: 8, - 151: 8, - 152: 4, - 153: 4 - } - -icmp6types = { 1 : "Destination unreachable", - 2 : "Packet too big", - 3 : "Time exceeded", - 4 : "Parameter problem", - 100 : "Private Experimentation", - 101 : "Private Experimentation", - 128 : "Echo Request", - 129 : "Echo Reply", - 130 : "MLD Query", - 131 : "MLD Report", - 132 : "MLD Done", - 133 : "Router Solicitation", - 134 : "Router Advertisement", - 135 : "Neighbor Solicitation", - 136 : "Neighbor Advertisement", - 137 : "Redirect Message", - 138 : "Router Renumbering", - 139 : "ICMP Node Information Query", - 140 : "ICMP Node Information Response", - 141 : "Inverse Neighbor Discovery Solicitation Message", - 142 : "Inverse Neighbor Discovery Advertisement Message", - 143 : "Version 2 Multicast Listener Report", - 144 : "Home Agent Address Discovery Request Message", - 145 : "Home Agent Address Discovery Reply Message", - 146 : "Mobile Prefix Solicitation", - 147 : "Mobile Prefix Advertisement", - 148 : "Certification Path Solicitation", - 149 : "Certification Path Advertisement", - 151 : "Multicast Router Advertisement", - 152 : "Multicast Router Solicitation", - 153 : "Multicast Router Termination", - 200 : "Private Experimentation", - 201 : "Private Experimentation" } - - -class _ICMPv6(Packet): - name = "ICMPv6 dummy class" - overload_fields = {IPv6: {"nh": 58}} - def post_build(self, p, pay): - p += pay - if self.cksum == None: - chksum = in6_chksum(58, self.underlayer, p) - p = p[:2]+struct.pack("!H", chksum)+p[4:] - return p - - def hashret(self): - return self.payload.hashret() - - def answers(self, other): - # isinstance(self.underlayer, _IPv6ExtHdr) may introduce a bug ... - if (isinstance(self.underlayer, IPerror6) or - isinstance(self.underlayer, _IPv6ExtHdr) and - isinstance(other, _ICMPv6)): - if not ((self.type == other.type) and - (self.code == other.code)): - return 0 - return 1 - return 0 - - -class _ICMPv6Error(_ICMPv6): - name = "ICMPv6 errors dummy class" - def guess_payload_class(self,p): - return IPerror6 - -class ICMPv6Unknown(_ICMPv6): - name = "Scapy6 ICMPv6 fallback class" - fields_desc = [ ByteEnumField("type",1, icmp6types), - ByteField("code",0), - XShortField("cksum", None), - StrField("msgbody", "")] - - -################################## RFC 2460 ################################# - -class ICMPv6DestUnreach(_ICMPv6Error): - name = "ICMPv6 Destination Unreachable" - fields_desc = [ ByteEnumField("type",1, icmp6types), - ByteEnumField("code",0, { 0: "No route to destination", - 1: "Communication with destination administratively prohibited", - 2: "Beyond scope of source address", - 3: "Address unreachable", - 4: "Port unreachable" }), - XShortField("cksum", None), - XIntField("unused",0x00000000)] - -class ICMPv6PacketTooBig(_ICMPv6Error): - name = "ICMPv6 Packet Too Big" - fields_desc = [ ByteEnumField("type",2, icmp6types), - ByteField("code",0), - XShortField("cksum", None), - IntField("mtu",1280)] - -class ICMPv6TimeExceeded(_ICMPv6Error): - name = "ICMPv6 Time Exceeded" - fields_desc = [ ByteEnumField("type",3, icmp6types), - ByteEnumField("code",0, { 0: "hop limit exceeded in transit", - 1: "fragment reassembly time exceeded"}), - XShortField("cksum", None), - XIntField("unused",0x00000000)] - -# The default pointer value is set to the next header field of -# the encapsulated IPv6 packet -class ICMPv6ParamProblem(_ICMPv6Error): - name = "ICMPv6 Parameter Problem" - fields_desc = [ ByteEnumField("type",4, icmp6types), - ByteEnumField("code",0, {0: "erroneous header field encountered", - 1: "unrecognized Next Header type encountered", - 2: "unrecognized IPv6 option encountered"}), - XShortField("cksum", None), - IntField("ptr",6)] - -class ICMPv6EchoRequest(_ICMPv6): - name = "ICMPv6 Echo Request" - fields_desc = [ ByteEnumField("type", 128, icmp6types), - ByteField("code", 0), - XShortField("cksum", None), - XShortField("id",0), - XShortField("seq",0), - StrField("data", "")] - def mysummary(self): - return self.sprintf("%name% (id: %id% seq: %seq%)") - def hashret(self): - return struct.pack("HH",self.id,self.seq)+self.payload.hashret() - - -class ICMPv6EchoReply(ICMPv6EchoRequest): - name = "ICMPv6 Echo Reply" - type = 129 - def answers(self, other): - # We could match data content between request and reply. - return (isinstance(other, ICMPv6EchoRequest) and - self.id == other.id and self.seq == other.seq and - self.data == other.data) - - -############ ICMPv6 Multicast Listener Discovery (RFC3810) ################## - -# tous les messages MLD sont emis avec une adresse source lien-locale -# -> Y veiller dans le post_build si aucune n'est specifiee -# La valeur de Hop-Limit doit etre de 1 -# "and an IPv6 Router Alert option in a Hop-by-Hop Options -# header. (The router alert option is necessary to cause routers to -# examine MLD messages sent to multicast addresses in which the router -# itself has no interest" -class _ICMPv6ML(_ICMPv6): - fields_desc = [ ByteEnumField("type", 130, icmp6types), - ByteField("code", 0), - XShortField("cksum", None), - ShortField("mrd", 0), - ShortField("reserved", 0), - IP6Field("mladdr","::")] - -# general queries are sent to the link-scope all-nodes multicast -# address ff02::1, with a multicast address field of 0 and a MRD of -# [Query Response Interval] -# Default value for mladdr is set to 0 for a General Query, and -# overloaded by the user for a Multicast Address specific query -# TODO : See what we can do to automatically include a Router Alert -# Option in a Destination Option Header. -class ICMPv6MLQuery(_ICMPv6ML): # RFC 2710 - name = "MLD - Multicast Listener Query" - type = 130 - mrd = 10000 - mladdr = "::" # 10s for mrd - overload_fields = {IPv6: { "dst": "ff02::1", "hlim": 1, "nh": 58 }} - def hashret(self): - if self.mladdr != "::": - return struct.pack("HH",self.mladdr)+self.payload.hashret() - else: - return self.payload.hashret() - - -# TODO : See what we can do to automatically include a Router Alert -# Option in a Destination Option Header. -class ICMPv6MLReport(_ICMPv6ML): # RFC 2710 - name = "MLD - Multicast Listener Report" - type = 131 - overload_fields = {IPv6: {"hlim": 1, "nh": 58}} - # implementer le hashret et le answers - -# When a node ceases to listen to a multicast address on an interface, -# it SHOULD send a single Done message to the link-scope all-routers -# multicast address (FF02::2), carrying in its multicast address field -# the address to which it is ceasing to listen -# TODO : See what we can do to automatically include a Router Alert -# Option in a Destination Option Header. -class ICMPv6MLDone(_ICMPv6ML): # RFC 2710 - name = "MLD - Multicast Listener Done" - type = 132 - overload_fields = {IPv6: { "dst": "ff02::2", "hlim": 1, "nh": 58}} - - -########## ICMPv6 MRD - Multicast Router Discovery (RFC 4286) ############### - -# TODO: -# - 04/09/06 troglocan : find a way to automatically add a router alert -# option for all MRD packets. This could be done in a specific -# way when IPv6 is the under layer with some specific keyword -# like 'exthdr'. This would allow to keep compatibility with -# providing IPv6 fields to be overloaded in fields_desc. -# -# At the moment, if user inserts an IPv6 Router alert option -# none of the IPv6 default values of IPv6 layer will be set. - -class ICMPv6MRD_Advertisement(_ICMPv6): - name = "ICMPv6 Multicast Router Discovery Advertisement" - fields_desc = [ByteEnumField("type", 151, icmp6types), - ByteField("advinter", 20), - XShortField("cksum", None), - ShortField("queryint", 0), - ShortField("robustness", 0)] - overload_fields = {IPv6: { "nh": 58, "hlim": 1, "dst": "ff02::2"}} - # IPv6 Router Alert requires manual inclusion - def extract_padding(self, s): - return s[:8], s[8:] - -class ICMPv6MRD_Solicitation(_ICMPv6): - name = "ICMPv6 Multicast Router Discovery Solicitation" - fields_desc = [ByteEnumField("type", 152, icmp6types), - ByteField("res", 0), - XShortField("cksum", None) ] - overload_fields = {IPv6: { "nh": 58, "hlim": 1, "dst": "ff02::2"}} - # IPv6 Router Alert requires manual inclusion - def extract_padding(self, s): - return s[:4], s[4:] - -class ICMPv6MRD_Termination(_ICMPv6): - name = "ICMPv6 Multicast Router Discovery Termination" - fields_desc = [ByteEnumField("type", 153, icmp6types), - ByteField("res", 0), - XShortField("cksum", None) ] - overload_fields = {IPv6: { "nh": 58, "hlim": 1, "dst": "ff02::6A"}} - # IPv6 Router Alert requires manual inclusion - def extract_padding(self, s): - return s[:4], s[4:] - - -################### ICMPv6 Neighbor Discovery (RFC 2461) #################### - -icmp6ndopts = { 1: "Source Link-Layer Address", - 2: "Target Link-Layer Address", - 3: "Prefix Information", - 4: "Redirected Header", - 5: "MTU", - 6: "NBMA Shortcut Limit Option", # RFC2491 - 7: "Advertisement Interval Option", - 8: "Home Agent Information Option", - 9: "Source Address List", - 10: "Target Address List", - 11: "CGA Option", # RFC 3971 - 12: "RSA Signature Option", # RFC 3971 - 13: "Timestamp Option", # RFC 3971 - 14: "Nonce option", # RFC 3971 - 15: "Trust Anchor Option", # RFC 3971 - 16: "Certificate Option", # RFC 3971 - 17: "IP Address Option", # RFC 4068 - 18: "New Router Prefix Information Option", # RFC 4068 - 19: "Link-layer Address Option", # RFC 4068 - 20: "Neighbor Advertisement Acknowledgement Option", - 21: "CARD Request Option", # RFC 4065/4066/4067 - 22: "CARD Reply Option", # RFC 4065/4066/4067 - 23: "MAP Option", # RFC 4140 - 24: "Route Information Option", # RFC 4191 - 25: "Recusive DNS Server Option", - 26: "IPv6 Router Advertisement Flags Option" - } - -icmp6ndoptscls = { 1: "ICMPv6NDOptSrcLLAddr", - 2: "ICMPv6NDOptDstLLAddr", - 3: "ICMPv6NDOptPrefixInfo", - 4: "ICMPv6NDOptRedirectedHdr", - 5: "ICMPv6NDOptMTU", - 6: "ICMPv6NDOptShortcutLimit", - 7: "ICMPv6NDOptAdvInterval", - 8: "ICMPv6NDOptHAInfo", - 9: "ICMPv6NDOptSrcAddrList", - 10: "ICMPv6NDOptTgtAddrList", - #11: Do Me, - #12: Do Me, - #13: Do Me, - #14: Do Me, - #15: Do Me, - #16: Do Me, - 17: "ICMPv6NDOptIPAddr", - 18: "ICMPv6NDOptNewRtrPrefix", - 19: "ICMPv6NDOptLLA", - #18: Do Me, - #19: Do Me, - #20: Do Me, - #21: Do Me, - #22: Do Me, - 23: "ICMPv6NDOptMAP", - 24: "ICMPv6NDOptRouteInfo", - 25: "ICMPv6NDOptRDNSS", - 26: "ICMPv6NDOptEFA" - } - -class _ICMPv6NDGuessPayload: - name = "Dummy ND class that implements guess_payload_class()" - def guess_payload_class(self,p): - if len(p) > 1: - #return get_cls(icmp6ndoptscls.get(ord(p[0]),"Raw"), "Raw") # s/Raw/ICMPv6NDOptUnknown/g ? - return get_cls(icmp6ndoptscls.get(p[0],"Raw"), "Raw") # s/Raw/ICMPv6NDOptUnknown/g ? - - -# Beginning of ICMPv6 Neighbor Discovery Options. - -class ICMPv6NDOptUnknown(_ICMPv6NDGuessPayload, Packet): - name = "ICMPv6 Neighbor Discovery Option - Scapy Unimplemented" - fields_desc = [ ByteField("type",None), - FieldLenField("len",None,length_of="data",fmt="B", - adjust = lambda pkt,x: x+2), - StrLenField("data","", - length_from = lambda pkt: pkt.len-2) ] - -# NOTE: len includes type and len field. Expressed in unit of 8 bytes -# TODO: Revoir le coup du ETHER_ANY -class ICMPv6NDOptSrcLLAddr(_ICMPv6NDGuessPayload, Packet): - name = "ICMPv6 Neighbor Discovery Option - Source Link-Layer Address" - fields_desc = [ ByteField("type", 1), - ByteField("len", 1), - MACField("lladdr", ETHER_ANY) ] - def mysummary(self): - return self.sprintf("%name% %lladdr%") - -class ICMPv6NDOptDstLLAddr(ICMPv6NDOptSrcLLAddr): - name = "ICMPv6 Neighbor Discovery Option - Destination Link-Layer Address" - type = 2 - -class ICMPv6NDOptPrefixInfo(_ICMPv6NDGuessPayload, Packet): - name = "ICMPv6 Neighbor Discovery Option - Prefix Information" - fields_desc = [ ByteField("type",3), - ByteField("len",4), - ByteField("prefixlen",None), - BitField("L",1,1), - BitField("A",1,1), - BitField("R",0,1), - BitField("res1",0,5), - XIntField("validlifetime",0xffffffff), - XIntField("preferredlifetime",0xffffffff), - XIntField("res2",0x00000000), - IP6Field("prefix","::") ] - def mysummary(self): - return self.sprintf("%name% %prefix%") - -# TODO: We should also limit the size of included packet to something -# like (initiallen - 40 - 2) -class TruncPktLenField(PacketLenField): - - def __init__(self, name, default, cls, cur_shift, length_from=None, shift=0): - PacketLenField.__init__(self, name, default, cls, length_from=length_from) - self.cur_shift = cur_shift - - def getfield(self, pkt, s): - l = self.length_from(pkt) - i = self.m2i(pkt, s[:l]) - return s[l:],i - - def m2i(self, pkt, m): - s = None - try: # It can happen we have sth shorter than 40 bytes - s = self.cls(m) - except: - return conf.raw_layer(m) - return s - - def i2m(self, pkt, x): - s = bytes(x) - l = len(s) - r = (l + self.cur_shift) % 8 - l = l - r - return s[:l] - - def i2len(self, pkt, i): - return len(self.i2m(pkt, i)) - - -# Faire un post_build pour le recalcul de la taille (en multiple de 8 octets) -class ICMPv6NDOptRedirectedHdr(_ICMPv6NDGuessPayload, Packet): - name = "ICMPv6 Neighbor Discovery Option - Redirected Header" - fields_desc = [ ByteField("type",4), - FieldLenField("len", None, length_of="pkt", fmt="B", - adjust = lambda pkt,x:(x+8)//8), - StrFixedLenField("res", b"\x00"*6, 6), - TruncPktLenField("pkt", b"", IPv6, 8, - length_from = lambda pkt: 8*pkt.len-8) ] - -# See which value should be used for default MTU instead of 1280 -class ICMPv6NDOptMTU(_ICMPv6NDGuessPayload, Packet): - name = "ICMPv6 Neighbor Discovery Option - MTU" - fields_desc = [ ByteField("type",5), - ByteField("len",1), - XShortField("res",0), - IntField("mtu",1280)] - -class ICMPv6NDOptShortcutLimit(_ICMPv6NDGuessPayload, Packet): # RFC 2491 - name = "ICMPv6 Neighbor Discovery Option - NBMA Shortcut Limit" - fields_desc = [ ByteField("type", 6), - ByteField("len", 1), - ByteField("shortcutlim", 40), # XXX - ByteField("res1", 0), - IntField("res2", 0) ] - -class ICMPv6NDOptAdvInterval(_ICMPv6NDGuessPayload, Packet): - name = "ICMPv6 Neighbor Discovery - Interval Advertisement" - fields_desc = [ ByteField("type",7), - ByteField("len",1), - ShortField("res", 0), - IntField("advint", 0) ] - def mysummary(self): - return self.sprintf("%name% %advint% milliseconds") - -class ICMPv6NDOptHAInfo(_ICMPv6NDGuessPayload, Packet): - name = "ICMPv6 Neighbor Discovery - Home Agent Information" - fields_desc = [ ByteField("type",8), - ByteField("len",1), - ShortField("res", 0), - ShortField("pref", 0), - ShortField("lifetime", 1)] - def mysummary(self): - return self.sprintf("%name% %pref% %lifetime% seconds") - -# type 9 : See ICMPv6NDOptSrcAddrList class below in IND (RFC 3122) support - -# type 10 : See ICMPv6NDOptTgtAddrList class below in IND (RFC 3122) support - -class ICMPv6NDOptIPAddr(_ICMPv6NDGuessPayload, Packet): # RFC 4068 - name = "ICMPv6 Neighbor Discovery - IP Address Option (FH for MIPv6)" - fields_desc = [ ByteField("type",17), - ByteField("len", 3), - ByteEnumField("optcode", 1, {1: "Old Care-Of Address", - 2: "New Care-Of Address", - 3: "NAR's IP address" }), - ByteField("plen", 64), - IntField("res", 0), - IP6Field("addr", "::") ] - -class ICMPv6NDOptNewRtrPrefix(_ICMPv6NDGuessPayload, Packet): # RFC 4068 - name = "ICMPv6 Neighbor Discovery - New Router Prefix Information Option (FH for MIPv6)" - fields_desc = [ ByteField("type",18), - ByteField("len", 3), - ByteField("optcode", 0), - ByteField("plen", 64), - IntField("res", 0), - IP6Field("prefix", "::") ] - -_rfc4068_lla_optcode = {0: "Wildcard requesting resolution for all nearby AP", - 1: "LLA for the new AP", - 2: "LLA of the MN", - 3: "LLA of the NAR", - 4: "LLA of the src of TrSolPr or PrRtAdv msg", - 5: "AP identified by LLA belongs to current iface of router", - 6: "No preifx info available for AP identified by the LLA", - 7: "No fast handovers support for AP identified by the LLA" } - -class ICMPv6NDOptLLA(_ICMPv6NDGuessPayload, Packet): # RFC 4068 - name = "ICMPv6 Neighbor Discovery - Link-Layer Address (LLA) Option (FH for MIPv6)" - fields_desc = [ ByteField("type", 19), - ByteField("len", 1), - ByteEnumField("optcode", 0, _rfc4068_lla_optcode), - MACField("lla", ETHER_ANY) ] # We only support ethernet - -class ICMPv6NDOptMAP(_ICMPv6NDGuessPayload, Packet): # RFC 4140 - name = "ICMPv6 Neighbor Discovery - MAP Option" - fields_desc = [ ByteField("type", 23), - ByteField("len", 3), - BitField("dist", 1, 4), - BitField("pref", 15, 4), # highest availability - BitField("R", 1, 1), - BitField("res", 0, 7), - IntField("validlifetime", 0xffffffff), - IP6Field("addr", "::") ] - - -class IP6PrefixField(IP6Field): - def __init__(self, name, default): - IP6Field.__init__(self, name, default) - self.length_from = lambda pkt: 8*(pkt.len - 1) - - def addfield(self, pkt, s, val): - return s + self.i2m(pkt, val) - - def getfield(self, pkt, s): - l = self.length_from(pkt) - p = s[:l] - if l < 16: - p += b'\x00'*(16-l) - return s[l:], self.m2i(pkt,p) - - def i2len(self, pkt, x): - return len(self.i2m(pkt, x)) - - def i2m(self, pkt, x): - l = pkt.len - - if x is None: - x = "::" - if l is None: - l = 1 - x = inet_pton(socket.AF_INET6, x) - - if l is None: - return x - if l in [0, 1]: - return b"" - if l in [2, 3]: - return x[:8*(l-1)] - - return x + b'\x00'*8*(l-3) - -class ICMPv6NDOptRouteInfo(_ICMPv6NDGuessPayload, Packet): # RFC 4191 - name = "ICMPv6 Neighbor Discovery Option - Route Information Option" - fields_desc = [ ByteField("type",24), - FieldLenField("len", None, length_of="prefix", fmt="B", - adjust = lambda pkt,x: x//8 + 1), - ByteField("plen", None), - BitField("res1",0,3), - BitField("prf",0,2), - BitField("res2",0,3), - IntField("rtlifetime", 0xffffffff), - IP6PrefixField("prefix", None) ] - -class ICMPv6NDOptRDNSS(_ICMPv6NDGuessPayload, Packet): # RFC 5006 - name = "ICMPv6 Neighbor Discovery Option - Recursive DNS Server Option" - fields_desc = [ ByteField("type", 25), - FieldLenField("len", None, count_of="dns", fmt="B", - adjust = lambda pkt,x: 2*x+1), - ShortField("res", None), - IntField("lifetime", 0xffffffff), - IP6ListField("dns", [], - length_from = lambda pkt: 8*(pkt.len-1)) ] - -class ICMPv6NDOptEFA(_ICMPv6NDGuessPayload, Packet): # RFC 5175 (prev. 5075) - name = "ICMPv6 Neighbor Discovery Option - Expanded Flags Option" - fields_desc = [ ByteField("type", 26), - ByteField("len", 1), - BitField("res", 0, 48) ] - -# End of ICMPv6 Neighbor Discovery Options. - -class ICMPv6ND_RS(_ICMPv6NDGuessPayload, _ICMPv6): - name = "ICMPv6 Neighbor Discovery - Router Solicitation" - fields_desc = [ ByteEnumField("type", 133, icmp6types), - ByteField("code",0), - XShortField("cksum", None), - IntField("res",0) ] - overload_fields = {IPv6: { "nh": 58, "dst": "ff02::2", "hlim": 255 }} - -class ICMPv6ND_RA(_ICMPv6NDGuessPayload, _ICMPv6): - name = "ICMPv6 Neighbor Discovery - Router Advertisement" - fields_desc = [ ByteEnumField("type", 134, icmp6types), - ByteField("code",0), - XShortField("cksum", None), - ByteField("chlim",0), - BitField("M",0,1), - BitField("O",0,1), - BitField("H",0,1), - BitEnumField("prf",1,2, { 0: "Medium (default)", - 1: "High", - 2: "Reserved", - 3: "Low" } ), # RFC 4191 - BitField("P",0,1), - BitField("res",0,2), - ShortField("routerlifetime",1800), - IntField("reachabletime",0), - IntField("retranstimer",0) ] - overload_fields = {IPv6: { "nh": 58, "dst": "ff02::1", "hlim": 255 }} - - def answers(self, other): - return isinstance(other, ICMPv6ND_RS) - -class ICMPv6ND_NS(_ICMPv6NDGuessPayload, _ICMPv6, Packet): - name = "ICMPv6 Neighbor Discovery - Neighbor Solicitation" - fields_desc = [ ByteEnumField("type",135, icmp6types), - ByteField("code",0), - XShortField("cksum", None), - IntField("res", 0), - IP6Field("tgt","::") ] - overload_fields = {IPv6: { "nh": 58, "dst": "ff02::1", "hlim": 255 }} - - def mysummary(self): - return self.sprintf("%name% (tgt: %tgt%)") - - def hashret(self): - return self.getbyteval("tgt")+self.payload.hashret() - -class ICMPv6ND_NA(_ICMPv6NDGuessPayload, _ICMPv6, Packet): - name = "ICMPv6 Neighbor Discovery - Neighbor Advertisement" - fields_desc = [ ByteEnumField("type",136, icmp6types), - ByteField("code",0), - XShortField("cksum", None), - BitField("R",1,1), - BitField("S",0,1), - BitField("O",1,1), - XBitField("res",0,29), - IP6Field("tgt","::") ] - overload_fields = {IPv6: { "nh": 58, "dst": "ff02::1", "hlim": 255 }} - - def mysummary(self): - return self.sprintf("%name% (tgt: %tgt%)") - - def hashret(self): - return self.getbyteval("tgt")+self.payload.hashret() - - def answers(self, other): - return isinstance(other, ICMPv6ND_NS) and self.tgt == other.tgt - -# associated possible options : target link-layer option, Redirected header -class ICMPv6ND_Redirect(_ICMPv6NDGuessPayload, _ICMPv6, Packet): - name = "ICMPv6 Neighbor Discovery - Redirect" - fields_desc = [ ByteEnumField("type",137, icmp6types), - ByteField("code",0), - XShortField("cksum", None), - XIntField("res",0), - IP6Field("tgt","::"), - IP6Field("dst","::") ] - overload_fields = {IPv6: { "nh": 58, "dst": "ff02::1", "hlim": 255 }} - - - -################ ICMPv6 Inverse Neighbor Discovery (RFC 3122) ############### - -class ICMPv6NDOptSrcAddrList(_ICMPv6NDGuessPayload, Packet): - name = "ICMPv6 Inverse Neighbor Discovery Option - Source Address List" - fields_desc = [ ByteField("type",9), - FieldLenField("len", None, count_of="addrlist", fmt="B", - adjust = lambda pkt,x: 2*x+1), - StrFixedLenField("res", "\x00"*6, 6), - IP6ListField("addrlist", [], - length_from = lambda pkt: 8*(pkt.len-1)) ] - -class ICMPv6NDOptTgtAddrList(ICMPv6NDOptSrcAddrList): - name = "ICMPv6 Inverse Neighbor Discovery Option - Target Address List" - type = 10 - - -# RFC3122 -# Options requises : source lladdr et target lladdr -# Autres options valides : source address list, MTU -# - Comme precise dans le document, il serait bien de prendre l'adresse L2 -# demandee dans l'option requise target lladdr et l'utiliser au niveau -# de l'adresse destination ethernet si aucune adresse n'est precisee -# - ca semble pas forcement pratique si l'utilisateur doit preciser toutes -# les options. -# Ether() must use the target lladdr as destination -class ICMPv6ND_INDSol(_ICMPv6NDGuessPayload, _ICMPv6): - name = "ICMPv6 Inverse Neighbor Discovery Solicitation" - fields_desc = [ ByteEnumField("type",141, icmp6types), - ByteField("code",0), - XShortField("cksum",None), - XIntField("reserved",0) ] - overload_fields = {IPv6: { "nh": 58, "dst": "ff02::1", "hlim": 255 }} - -# Options requises : target lladdr, target address list -# Autres options valides : MTU -class ICMPv6ND_INDAdv(_ICMPv6NDGuessPayload, _ICMPv6): - name = "ICMPv6 Inverse Neighbor Discovery Advertisement" - fields_desc = [ ByteEnumField("type",142, icmp6types), - ByteField("code",0), - XShortField("cksum",None), - XIntField("reserved",0) ] - overload_fields = {IPv6: { "nh": 58, "dst": "ff02::1", "hlim": 255 }} - - -############################################################################### -# ICMPv6 Node Information Queries (RFC 4620) -############################################################################### - -# [ ] Add automatic destination address computation using computeNIGroupAddr -# in IPv6 class (Scapy6 modification when integrated) if : -# - it is not provided -# - upper layer is ICMPv6NIQueryName() with a valid value -# [ ] Try to be liberal in what we accept as internal values for _explicit_ -# DNS elements provided by users. Any string should be considered -# valid and kept like it has been provided. At the moment, i2repr() will -# crash on many inputs -# [ ] Do the documentation -# [ ] Add regression tests -# [ ] Perform test against real machines (NOOP reply is proof of implementation). -# [ ] Check if there are differences between different stacks. Among *BSD, -# with others. -# [ ] Deal with flags in a consistent way. -# [ ] Implement compression in names2dnsrepr() and decompresiion in -# dnsrepr2names(). Should be deactivable. - -icmp6_niqtypes = { 0: "NOOP", - 2: "Node Name", - 3: "IPv6 Address", - 4: "IPv4 Address" } - - -class _ICMPv6NIHashret: - def hashret(self): - return self.nonce - -class _ICMPv6NIAnswers: - def answers(self, other): - return self.nonce == other.nonce - -# Buggy; always returns the same value during a session -class NonceField(StrFixedLenField): - def __init__(self, name, default=None): - StrFixedLenField.__init__(self, name, default, 8) - if default is None: - self.default = self.randval() - -# Compute the NI group Address. Can take a FQDN as input parameter -def computeNIGroupAddr(name): - import md5 - name = name.lower().split(".")[0] - record = chr(len(name))+name - h = md5.new(record) - h = h.digest() - addr = "ff02::2:%2x%2x:%2x%2x" % struct.unpack("BBBB", h[:4]) - return addr - - -# Here is the deal. First, that protocol is a piece of shit. Then, we -# provide 4 classes for the different kinds of Requests (one for every -# valid qtype: NOOP, Node Name, IPv6@, IPv4@). They all share the same -# data field class that is made to be smart by guessing the specifc -# type of value provided : -# -# - IPv6 if acceptable for inet_pton(AF_INET6, ): code is set to 0, -# if not overriden by user -# - IPv4 if acceptable for inet_pton(AF_INET, ): code is set to 2, -# if not overriden -# - Name in the other cases: code is set to 0, if not overriden by user -# -# Internal storage, is not only the value, but the a pair providing -# the type and the value (1 is IPv6@, 1 is Name or string, 2 is IPv4@) -# -# Note : I merged getfield() and m2i(). m2i() should not be called -# directly anyway. Same remark for addfield() and i2m() -# -# -- arno - -# "The type of information present in the Data field of a query is -# declared by the ICMP Code, whereas the type of information in a -# Reply is determined by the Qtype" - -def names2dnsrepr(x): - """ - Take as input a list of DNS names or a single DNS name - and encode it in DNS format (with possible compression) - If a string that is already a DNS name in DNS format - is passed, it is returned unmodified. Result is a string. - !!! At the moment, compression is not implemented !!! - """ - - if type(x) is str: - if x and x[-1] == '\x00': # stupid heuristic - return x.encode('ascii') - x = [x.encode('ascii')] - elif type(x) is bytes: - if x and x[-1] == 0: - return x - x = [x] - - res = [] - for n in x: - if type(n) is str: - n = n.encode('ascii') - termin = b"\x00" - if n.count(b'.') == 0: # single-component gets one more - termin += bytes([0]) - n = b"".join(map(lambda y: chr(len(y)).encode('ascii')+y, n.split(b"."))) + termin - res.append(n) - return b"".join(res) - - -def dnsrepr2names(x): - """ - Take as input a DNS encoded string (possibly compressed) - and returns a list of DNS names contained in it. - If provided string is already in printable format - (does not end with a null character, a one element list - is returned). Result is a list. - """ - res = [] - cur = b"" - if type(x) is str: - x = x.encode('ascii') - while x: - #l = ord(x[0]) - l = x[0] - x = x[1:] - if l == 0: - if cur and cur[-1] == ord('.'): - cur = cur[:-1] - res.append(cur) - cur = b"" - #if x and ord(x[0]) == 0: # single component - if x and x[0] == 0: # single component - x = x[1:] - continue - if l & 0xc0: # XXX TODO : work on that -- arno - raise Exception("DNS message can't be compressed at this point!") - else: - cur += x[:l]+b"." - x = x[l:] - return res - - -class NIQueryDataField(StrField): - def __init__(self, name, default): - StrField.__init__(self, name, default) - - def i2h(self, pkt, x): - if x is None: - return x - t,val = x - if t == 1: - val = dnsrepr2names(val)[0] - return val - - def h2i(self, pkt, x): - if x is tuple and type(x[0]) is int: - return x - - val = None - try: # Try IPv6 - inet_pton(socket.AF_INET6, x) - val = (0, x) - except: - try: # Try IPv4 - inet_pton(socket.AF_INET, x) - val = (2, x) - except: # Try DNS - if x is None: - x = b"" - x = names2dnsrepr(x) - val = (1, x) - return val - - def i2repr(self, pkt, x): - t,val = x - if t == 1: # DNS Name - # we don't use dnsrepr2names() to deal with - # possible weird data extracted info - res = [] - weird = None - while val: - #l = ord(val[0]) - l = val[0] - val = val[1:] - if l == 0: - if (len(res) > 1 and val): # fqdn with data behind - weird = val - elif len(val) > 1: # single label with data behind - weird = val[1:] - break - res.append(val[:l]+".") - val = val[l:] - tmp = "".join(res) - if tmp and tmp[-1] == '.': - tmp = tmp[:-1] - return tmp - return repr(val) - - def getfield(self, pkt, s): - qtype = getattr(pkt, "qtype") - if qtype == 0: # NOOP - return s, (0, b"") - else: - code = getattr(pkt, "code") - if code == 0: # IPv6 Addr - return s[16:], (0, inet_ntop(socket.AF_INET6, s[:16])) - elif code == 2: # IPv4 Addr - return s[4:], (2, inet_ntop(socket.AF_INET, s[:4])) - else: # Name or Unknown - return b"", (1, s) - - def addfield(self, pkt, s, val): - if ((type(val) is tuple and val[1] is None) or - val is None): - val = (1, b"") - t = val[0] - if t == 1: - if type(val[1]) is str: - tmp = val[1].encode('ascii') - else: - tmp = val[1] - return s + tmp - elif t == 0: - return s + inet_pton(socket.AF_INET6, val[1]) - else: - return s + inet_pton(socket.AF_INET, val[1]) - -class NIQueryCodeField(ByteEnumField): - def i2m(self, pkt, x): - if x is None: - d = pkt.getfieldval("data") - if d is None: - return 1 - elif d[0] == 0: # IPv6 address - return 0 - elif d[0] == 1: # Name - return 1 - elif d[0] == 2: # IPv4 address - return 2 - else: - return 1 - return x - - -_niquery_code = {0: "IPv6 Query", 1: "Name Query", 2: "IPv4 Query"} - -#_niquery_flags = { 2: "All unicast addresses", 4: "IPv4 addresses", -# 8: "Link-local addresses", 16: "Site-local addresses", -# 32: "Global addresses" } - -# "This NI type has no defined flags and never has a Data Field". Used -# to know if the destination is up and implements NI protocol. -class ICMPv6NIQueryNOOP(_ICMPv6NIHashret, _ICMPv6): - name = "ICMPv6 Node Information Query - NOOP Query" - fields_desc = [ ByteEnumField("type", 139, icmp6types), - NIQueryCodeField("code", None, _niquery_code), - XShortField("cksum", None), - ShortEnumField("qtype", 0, icmp6_niqtypes), - BitField("unused", 0, 10), - FlagsField("flags", 0, 6, "TACLSG"), - NonceField("nonce", None), - NIQueryDataField("data", None) ] - -class ICMPv6NIQueryName(ICMPv6NIQueryNOOP): - name = "ICMPv6 Node Information Query - IPv6 Name Query" - qtype = 2 - -# We ask for the IPv6 address of the peer -class ICMPv6NIQueryIPv6(ICMPv6NIQueryNOOP): - name = "ICMPv6 Node Information Query - IPv6 Address Query" - qtype = 3 - flags = 0x3E - -class ICMPv6NIQueryIPv4(ICMPv6NIQueryNOOP): - name = "ICMPv6 Node Information Query - IPv4 Address Query" - qtype = 4 - -_nireply_code = { 0: "Successful Reply", - 1: "Response Refusal", - 3: "Unknown query type" } - -_nireply_flags = { 1: "Reply set incomplete", - 2: "All unicast addresses", - 4: "IPv4 addresses", - 8: "Link-local addresses", - 16: "Site-local addresses", - 32: "Global addresses" } - -# Internal repr is one of those : -# (0, "some string") : unknow qtype value are mapped to that one -# (3, [ (ttl, ip6), ... ]) -# (4, [ (ttl, ip4), ... ]) -# (2, [ttl, dns_names]) : dns_names is one string that contains -# all the DNS names. Internally it is kept ready to be sent -# (undissected). i2repr() decode it for user. This is to -# make build after dissection bijective. -# -# I also merged getfield() and m2i(), and addfield() and i2m(). -class NIReplyDataField(StrField): - - def i2h(self, pkt, x): - if x is None: - return x - t,val = x - if t == 2: - ttl, dnsnames = val - val = [ttl] + dnsrepr2names(dnsnames) - return val - - def h2i(self, pkt, x): - qtype = 0 # We will decode it as string if not - # overridden through 'qtype' in pkt - - # No user hint, let's use 'qtype' value for that purpose - if type(x) is not tuple: - if pkt is not None: - qtype = getattr(pkt, "qtype") - else: - qtype = x[0] - x = x[1] - - # From that point on, x is the value (second element of the tuple) - - if qtype == 2: # DNS name - if type(x) is str: # listify the string - x = x.encode('ascii') - x = [x] - elif type(x) is bytes: - x = [x] - if type(x) is list and x and type(x[0]) is not int: # ttl was omitted : use 0 - x = [0] + x - ttl = x[0] - names = x[1:] - return (2, [ttl, names2dnsrepr(names)]) - - elif qtype in [3, 4]: # IPv4 or IPv6 addr - if type(x) is str or type(x) is bytes: - x = [x] # User directly provided an IP, instead of list - - # List elements are not tuples, user probably - # omitted ttl value : we will use 0 instead - def addttl(x): - if type(x) is str or type(x) is bytes: - return (0, x) - return x - - return (qtype, list(map(addttl, x))) - - return (qtype, x) - - - def addfield(self, pkt, s, val): - t,tmp = val - if tmp is None: - tmp = b"" - if t == 2: - ttl,dnsstr = tmp - return s+ struct.pack("!I", ttl) + dnsstr - elif t == 3: - #return s + "".join(map(lambda (x,y): struct.pack("!I", x)+inet_pton(socket.AF_INET6, y), tmp)) - return s + b"".join(map(lambda a: struct.pack("!I", a[0])+inet_pton(socket.AF_INET6, a[1]), tmp)) - elif t == 4: - #return s + "".join(map(lambda (x,y): struct.pack("!I", x)+inet_pton(socket.AF_INET, y), tmp)) - return s + b"".join(map(lambda a: struct.pack("!I", a[0])+inet_pton(socket.AF_INET, a[1]), tmp)) - else: - return s + tmp - - def getfield(self, pkt, s): - code = getattr(pkt, "code") - if code != 0: - return s, (0, b"") - - qtype = getattr(pkt, "qtype") - if qtype == 0: # NOOP - return s, (0, b"") - - elif qtype == 2: - if len(s) < 4: - return s, (0, b"") - ttl = struct.unpack("!I", s[:4])[0] - return b"", (2, [ttl, s[4:]]) - - elif qtype == 3: # IPv6 addresses with TTLs - # XXX TODO : get the real length - res = [] - while len(s) >= 20: # 4 + 16 - ttl = struct.unpack("!I", s[:4])[0] - ip = inet_ntop(socket.AF_INET6, s[4:20]) - res.append((ttl, ip)) - s = s[20:] - return s, (3, res) - - elif qtype == 4: # IPv4 addresses with TTLs - # XXX TODO : get the real length - res = [] - while len(s) >= 8: # 4 + 4 - ttl = struct.unpack("!I", s[:4])[0] - ip = inet_ntop(socket.AF_INET, s[4:8]) - res.append((ttl, ip)) - s = s[8:] - return s, (4, res) - else: - # XXX TODO : implement me and deal with real length - return b"", (0, s) - - def i2repr(self, pkt, x): - if x is None: - return "[]" - - if type(x) is tuple and len(x) == 2: - t, val = x - if t == 2: # DNS names - ttl,l = val - l = dnsrepr2names(l) - return "ttl:%d %s" % (ttl, ", ".join(l)) - elif t == 3 or t == 4: - #return "[ %s ]" % (", ".join(map(lambda (x,y): "(%d, %s)" % (x, y), val))) - return "[ %s ]" % (", ".join(map(lambda a: "(%d, %s)" % a, val))) - return repr(val) - return repr(x) # XXX should not happen - -# By default, sent responses have code set to 0 (successful) -class ICMPv6NIReplyNOOP(_ICMPv6NIAnswers, _ICMPv6NIHashret, _ICMPv6): - name = "ICMPv6 Node Information Reply - NOOP Reply" - fields_desc = [ ByteEnumField("type", 140, icmp6types), - ByteEnumField("code", 0, _nireply_code), - XShortField("cksum", None), - ShortEnumField("qtype", 0, icmp6_niqtypes), - BitField("unused", 0, 10), - FlagsField("flags", 0, 6, "TACLSG"), - NonceField("nonce", None), - NIReplyDataField("data", None)] - -class ICMPv6NIReplyName(ICMPv6NIReplyNOOP): - name = "ICMPv6 Node Information Reply - Node Names" - qtype = 2 - -class ICMPv6NIReplyIPv6(ICMPv6NIReplyNOOP): - name = "ICMPv6 Node Information Reply - IPv6 addresses" - qtype = 3 - -class ICMPv6NIReplyIPv4(ICMPv6NIReplyNOOP): - name = "ICMPv6 Node Information Reply - IPv4 addresses" - qtype = 4 - -class ICMPv6NIReplyRefuse(ICMPv6NIReplyNOOP): - name = "ICMPv6 Node Information Reply - Responder refuses to supply answer" - code = 1 - -class ICMPv6NIReplyUnknown(ICMPv6NIReplyNOOP): - name = "ICMPv6 Node Information Reply - Qtype unknown to the responder" - code = 2 - - -def _niquery_guesser(p): - cls = conf.raw_layer - #type = ord(p[0]) - type = p[0] - if type == 139: # Node Info Query specific stuff - if len(p) > 6: - qtype, = struct.unpack("!H", p[4:6]) - cls = { 0: ICMPv6NIQueryNOOP, - 2: ICMPv6NIQueryName, - 3: ICMPv6NIQueryIPv6, - 4: ICMPv6NIQueryIPv4 }.get(qtype, conf.raw_layer) - elif type == 140: # Node Info Reply specific stuff - #code = ord(p[1]) - code = p[1] - if code == 0: - if len(p) > 6: - qtype, = struct.unpack("!H", p[4:6]) - cls = { 2: ICMPv6NIReplyName, - 3: ICMPv6NIReplyIPv6, - 4: ICMPv6NIReplyIPv4 }.get(qtype, ICMPv6NIReplyNOOP) - elif code == 1: - cls = ICMPv6NIReplyRefuse - elif code == 2: - cls = ICMPv6NIReplyUnknown - return cls - - -############################################################################# -############################################################################# -### Mobile IPv6 (RFC 3775) and Nemo (RFC 3963) ### -############################################################################# -############################################################################# - -# Mobile IPv6 ICMPv6 related classes - -class ICMPv6HAADRequest(_ICMPv6): - name = 'ICMPv6 Home Agent Address Discovery Request' - fields_desc = [ ByteEnumField("type", 144, icmp6types), - ByteField("code", 0), - XShortField("cksum", None), - XShortField("id", None), - BitEnumField("R", 1, 1, {1: 'MR'}), - XBitField("res", 0, 15) ] - def hashret(self): - return struct.pack("!H",self.id)+self.payload.hashret() - -class ICMPv6HAADReply(_ICMPv6): - name = 'ICMPv6 Home Agent Address Discovery Reply' - fields_desc = [ ByteEnumField("type", 145, icmp6types), - ByteField("code", 0), - XShortField("cksum", None), - XShortField("id", None), - BitEnumField("R", 1, 1, {1: 'MR'}), - XBitField("res", 0, 15), - IP6ListField('addresses', None) ] - def hashret(self): - return struct.pack("!H",self.id)+self.payload.hashret() - - def answers(self, other): - if not isinstance(other, ICMPv6HAADRequest): - return 0 - return self.id == other.id - -class ICMPv6MPSol(_ICMPv6): - name = 'ICMPv6 Mobile Prefix Solicitation' - fields_desc = [ ByteEnumField("type", 146, icmp6types), - ByteField("code", 0), - XShortField("cksum", None), - XShortField("id", None), - XShortField("res", 0) ] - def _hashret(self): - return struct.pack("!H",self.id) - -class ICMPv6MPAdv(_ICMPv6NDGuessPayload, _ICMPv6): - name = 'ICMPv6 Mobile Prefix Advertisement' - fields_desc = [ ByteEnumField("type", 147, icmp6types), - ByteField("code", 0), - XShortField("cksum", None), - XShortField("id", None), - BitEnumField("flags", 2, 2, {2: 'M', 1:'O'}), - XBitField("res", 0, 14) ] - def hashret(self): - return struct.pack("!H",self.id) - - def answers(self, other): - return isinstance(other, ICMPv6MPSol) - -# Mobile IPv6 Options classes - - -_mobopttypes = { 2: "Binding Refresh Advice", - 3: "Alternate Care-of Address", - 4: "Nonce Indices", - 5: "Binding Authorization Data", - 6: "Mobile Network Prefix (RFC3963)", - 7: "Link-Layer Address (RFC4068)", - 8: "Mobile Node Identifier (RFC4283)", - 9: "Mobility Message Authentication (RFC4285)", - 10: "Replay Protection (RFC4285)", - 11: "CGA Parameters Request (RFC4866)", - 12: "CGA Parameters (RFC4866)", - 13: "Signature (RFC4866)", - 14: "Home Keygen Token (RFC4866)", - 15: "Care-of Test Init (RFC4866)", - 16: "Care-of Test (RFC4866)" } - - -class _MIP6OptAlign: - """ Mobile IPv6 options have alignment requirements of the form x*n+y. - This class is inherited by all MIPv6 options to help in computing the - required Padding for that option, i.e. the need for a Pad1 or PadN - option before it. They only need to provide x and y as class - parameters. (x=0 and y=0 are used when no alignment is required)""" - def alignment_delta(self, curpos): - x = self.x ; y = self.y - if x == 0 and y ==0: - return 0 - delta = x*((curpos - y + x - 1)//x) + y - curpos - return delta - - -class MIP6OptBRAdvice(_MIP6OptAlign, Packet): - name = 'Mobile IPv6 Option - Binding Refresh Advice' - fields_desc = [ ByteEnumField('otype', 2, _mobopttypes), - ByteField('olen', 2), - ShortField('rinter', 0) ] - x = 2 ; y = 0# alignment requirement: 2n - -class MIP6OptAltCoA(_MIP6OptAlign, Packet): - name = 'MIPv6 Option - Alternate Care-of Address' - fields_desc = [ ByteEnumField('otype', 3, _mobopttypes), - ByteField('olen', 16), - IP6Field("acoa", "::") ] - x = 8 ; y = 6 # alignment requirement: 8n+6 - -class MIP6OptNonceIndices(_MIP6OptAlign, Packet): - name = 'MIPv6 Option - Nonce Indices' - fields_desc = [ ByteEnumField('otype', 4, _mobopttypes), - ByteField('olen', 16), - ShortField('hni', 0), - ShortField('coni', 0) ] - x = 2 ; y = 0 # alignment requirement: 2n - -class MIP6OptBindingAuthData(_MIP6OptAlign, Packet): - name = 'MIPv6 Option - Binding Authorization Data' - fields_desc = [ ByteEnumField('otype', 5, _mobopttypes), - ByteField('olen', 16), - BitField('authenticator', 0, 96) ] - x = 8 ; y = 2 # alignment requirement: 8n+2 - -class MIP6OptMobNetPrefix(_MIP6OptAlign, Packet): # NEMO - RFC 3963 - name = 'NEMO Option - Mobile Network Prefix' - fields_desc = [ ByteEnumField("otype", 6, _mobopttypes), - ByteField("olen", 18), - ByteField("reserved", 0), - ByteField("plen", 64), - IP6Field("prefix", "::") ] - x = 8 ; y = 4 # alignment requirement: 8n+4 - -class MIP6OptLLAddr(_MIP6OptAlign, Packet): # Sect 6.4.4 of RFC 4068 - name = "MIPv6 Option - Link-Layer Address (MH-LLA)" - fields_desc = [ ByteEnumField("otype", 7, _mobopttypes), - ByteField("olen", 7), - ByteEnumField("ocode", 2, _rfc4068_lla_optcode), - ByteField("pad", 0), - MACField("lla", ETHER_ANY) ] # Only support ethernet - x = 0 ; y = 0 # alignment requirement: none - -class MIP6OptMNID(_MIP6OptAlign, Packet): # RFC 4283 - name = "MIPv6 Option - Mobile Node Identifier" - fields_desc = [ ByteEnumField("otype", 8, _mobopttypes), - FieldLenField("olen", None, length_of="id", fmt="B", - adjust = lambda pkt,x: x+1), - ByteEnumField("subtype", 1, {1: "NAI"}), - StrLenField("id", "", - length_from = lambda pkt: pkt.olen-1) ] - x = 0 ; y = 0 # alignment requirement: none - -# We only support decoding and basic build. Automatic HMAC computation is -# too much work for our current needs. It is left to the user (I mean ... -# you). --arno -class MIP6OptMsgAuth(_MIP6OptAlign, Packet): # RFC 4285 (Sect. 5) - name = "MIPv6 Option - Mobility Message Authentication" - fields_desc = [ ByteEnumField("otype", 9, _mobopttypes), - FieldLenField("olen", None, length_of="authdata", fmt="B", - adjust = lambda pkt,x: x+5), - ByteEnumField("subtype", 1, {1: "MN-HA authentication mobility option", - 2: "MN-AAA authentication mobility option"}), - IntField("mspi", None), - StrLenField("authdata", "A"*12, - length_from = lambda pkt: pkt.olen-5) ] - x = 4 ; y = 1 # alignment requirement: 4n+1 - -# Extracted from RFC 1305 (NTP) : -# NTP timestamps are represented as a 64-bit unsigned fixed-point number, -# in seconds relative to 0h on 1 January 1900. The integer part is in the -# first 32 bits and the fraction part in the last 32 bits. -class NTPTimestampField(LongField): - epoch = (1900, 1, 1, 0, 0, 0, 5, 1, 0) - def i2repr(self, pkt, x): - if x < ((50*31536000)<<32): - return "Some date a few decades ago (%d)" % x - - # delta from epoch (= (1900, 1, 1, 0, 0, 0, 5, 1, 0)) to - # January 1st 1970 : - delta = -2209075761 - i = int(x >> 32) - j = float(x & 0xffffffff) * 2.0**-32 - res = i + j + delta - from time import strftime - t = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime(res)) - - return "%s (%d)" % (t, x) - -class MIP6OptReplayProtection(_MIP6OptAlign, Packet): # RFC 4285 (Sect. 6) - name = "MIPv6 option - Replay Protection" - fields_desc = [ ByteEnumField("otype", 10, _mobopttypes), - ByteField("olen", 8), - NTPTimestampField("timestamp", 0) ] - x = 8 ; y = 2 # alignment requirement: 8n+2 - -class MIP6OptCGAParamsReq(_MIP6OptAlign, Packet): # RFC 4866 (Sect. 5.6) - name = "MIPv6 option - CGA Parameters Request" - fields_desc = [ ByteEnumField("otype", 11, _mobopttypes), - ByteField("olen", 0) ] - x = 0 ; y = 0 # alignment requirement: none - -# XXX TODO: deal with CGA param fragmentation and build of defragmented -# XXX version. Passing of a big CGAParam structure should be -# XXX simplified. Make it hold packets, by the way --arno -class MIP6OptCGAParams(_MIP6OptAlign, Packet): # RFC 4866 (Sect. 5.1) - name = "MIPv6 option - CGA Parameters" - fields_desc = [ ByteEnumField("otype", 12, _mobopttypes), - FieldLenField("olen", None, length_of="cgaparams", fmt="B"), - StrLenField("cgaparams", "", - length_from = lambda pkt: pkt.olen) ] - x = 0 ; y = 0 # alignment requirement: none - -class MIP6OptSignature(_MIP6OptAlign, Packet): # RFC 4866 (Sect. 5.2) - name = "MIPv6 option - Signature" - fields_desc = [ ByteEnumField("otype", 13, _mobopttypes), - FieldLenField("olen", None, length_of="sig", fmt="B"), - StrLenField("sig", "", - length_from = lambda pkt: pkt.olen) ] - x = 0 ; y = 0 # alignment requirement: none - -class MIP6OptHomeKeygenToken(_MIP6OptAlign, Packet): # RFC 4866 (Sect. 5.3) - name = "MIPv6 option - Home Keygen Token" - fields_desc = [ ByteEnumField("otype", 14, _mobopttypes), - FieldLenField("olen", None, length_of="hkt", fmt="B"), - StrLenField("hkt", "", - length_from = lambda pkt: pkt.olen) ] - x = 0 ; y = 0 # alignment requirement: none - -class MIP6OptCareOfTestInit(_MIP6OptAlign, Packet): # RFC 4866 (Sect. 5.4) - name = "MIPv6 option - Care-of Test Init" - fields_desc = [ ByteEnumField("otype", 15, _mobopttypes), - ByteField("olen", 0) ] - x = 0 ; y = 0 # alignment requirement: none - -class MIP6OptCareOfTest(_MIP6OptAlign, Packet): # RFC 4866 (Sect. 5.5) - name = "MIPv6 option - Care-of Test" - fields_desc = [ ByteEnumField("otype", 16, _mobopttypes), - FieldLenField("olen", None, length_of="cokt", fmt="B"), - StrLenField("cokt", '\x00'*8, - length_from = lambda pkt: pkt.olen) ] - x = 0 ; y = 0 # alignment requirement: none - -class MIP6OptUnknown(_MIP6OptAlign, Packet): - name = 'Scapy6 - Unknown Mobility Option' - fields_desc = [ ByteEnumField("otype", 6, _mobopttypes), - FieldLenField("olen", None, length_of="odata", fmt="B"), - StrLenField("odata", "", - length_from = lambda pkt: pkt.olen) ] - x = 0 ; y = 0 # alignment requirement: none - -moboptcls = { 0: Pad1, - 1: PadN, - 2: MIP6OptBRAdvice, - 3: MIP6OptAltCoA, - 4: MIP6OptNonceIndices, - 5: MIP6OptBindingAuthData, - 6: MIP6OptMobNetPrefix, - 7: MIP6OptLLAddr, - 8: MIP6OptMNID, - 9: MIP6OptMsgAuth, - 10: MIP6OptReplayProtection, - 11: MIP6OptCGAParamsReq, - 12: MIP6OptCGAParams, - 13: MIP6OptSignature, - 14: MIP6OptHomeKeygenToken, - 15: MIP6OptCareOfTestInit, - 16: MIP6OptCareOfTest } - - -# Main Mobile IPv6 Classes - -mhtypes = { 0: 'BRR', - 1: 'HoTI', - 2: 'CoTI', - 3: 'HoT', - 4: 'CoT', - 5: 'BU', - 6: 'BA', - 7: 'BE', - 8: 'Fast BU', - 9: 'Fast BA', - 10: 'Fast NA' } - -# From http://www.iana.org/assignments/mobility-parameters -bastatus = { 0: 'Binding Update accepted', - 1: 'Accepted but prefix discovery necessary', - 128: 'Reason unspecified', - 129: 'Administratively prohibited', - 130: 'Insufficient resources', - 131: 'Home registration not supported', - 132: 'Not home subnet', - 133: 'Not home agent for this mobile node', - 134: 'Duplicate Address Detection failed', - 135: 'Sequence number out of window', - 136: 'Expired home nonce index', - 137: 'Expired care-of nonce index', - 138: 'Expired nonces', - 139: 'Registration type change disallowed', - 140: 'Mobile Router Operation not permitted', - 141: 'Invalid Prefix', - 142: 'Not Authorized for Prefix', - 143: 'Forwarding Setup failed (prefixes missing)', - 144: 'MIPV6-ID-MISMATCH', - 145: 'MIPV6-MESG-ID-REQD', - 146: 'MIPV6-AUTH-FAIL', - 147: 'Permanent home keygen token unavailable', - 148: 'CGA and signature verification failed', - 149: 'Permanent home keygen token exists', - 150: 'Non-null home nonce index expected' } - - -class _MobilityHeader(Packet): - name = 'Dummy IPv6 Mobility Header' - overload_fields = { IPv6: { "nh": 135 }} - - def post_build(self, p, pay): - p += pay - l = self.len - if self.len is None: - l = (len(p)-8)//8 - p = bytes([p[0]]) + struct.pack("B", l) + p[2:] - if self.cksum is None: - cksum = in6_chksum(135, self.underlayer, p) - else: - cksum = self.cksum - p = p[:4]+struct.pack("!H", cksum)+p[6:] - return p - - -class MIP6MH_Generic(_MobilityHeader): # Mainly for decoding of unknown msg - name = "IPv6 Mobility Header - Generic Message" - fields_desc = [ ByteEnumField("nh", 59, ipv6nh), - ByteField("len", None), - ByteEnumField("mhtype", None, mhtypes), - ByteField("res", None), - XShortField("cksum", None), - StrLenField("msg", b"\x00"*2, - length_from = lambda pkt: 8*pkt.len-6) ] - - - -# TODO: make a generic _OptionsField -class _MobilityOptionsField(PacketListField): - islist = 1 - holds_packet = 1 - - def __init__(self, name, default, cls, curpos, count_from=None, length_from=None): - self.curpos = curpos - PacketListField.__init__(self, name, default, cls, count_from=count_from, length_from=length_from) - - def getfield(self, pkt, s): - l = self.length_from(pkt) - return s[l:],self.m2i(pkt, s[:l]) - - def i2len(self, pkt, i): - return len(self.i2m(pkt, i)) - - def m2i(self, pkt, x): - opt = [] - while x: - #o = ord(x[0]) # Option type - o = x[0] # Option type - cls = self.cls - if o in moboptcls: - cls = moboptcls[o] - try: - op = cls(x) - except: - op = self.cls(x) - opt.append(op) - if isinstance(op.payload, conf.raw_layer): - x = op.payload.load - del(op.payload) - else: - x = b"" - return opt - - def i2m(self, pkt, x): - autopad = None - try: - autopad = getattr(pkt, "autopad") # Hack : 'autopad' phantom field - except: - autopad = 1 - - if not autopad: - return b"".join(map(str, x)) - - curpos = self.curpos - s = b"" - for p in x: - d = p.alignment_delta(curpos) - curpos += d - if d == 1: - s += bytes(Pad1()) - elif d != 0: - s += bytes(PadN(optdata=b'\x00'*(d-2))) - pstr = bytes(p) - curpos += len(pstr) - s += pstr - - # Let's make the class including our option field - # a multiple of 8 octets long - d = curpos % 8 - if d == 0: - return s - d = 8 - d - if d == 1: - s +=bytes(Pad1()) - elif d != 0: - s += bytes(PadN(optdata=b'\x00'*(d-2))) - - return s - - def addfield(self, pkt, s, val): - return s+self.i2m(pkt, val) - -class MIP6MH_BRR(_MobilityHeader): - name = "IPv6 Mobility Header - Binding Refresh Request" - fields_desc = [ ByteEnumField("nh", 59, ipv6nh), - ByteField("len", None), - ByteEnumField("mhtype", 0, mhtypes), - ByteField("res", None), - XShortField("cksum", None), - ShortField("res2", None), - _PhantomAutoPadField("autopad", 1), # autopad activated by default - _MobilityOptionsField("options", [], MIP6OptUnknown, 8, - length_from = lambda pkt: 8*pkt.len) ] - overload_fields = { IPv6: { "nh": 135 } } - def hashret(self): - # Hack: BRR, BU and BA have the same hashret that returns the same - # value "\x00\x08\x09" (concatenation of mhtypes). This is - # because we need match BA with BU and BU with BRR. --arno - return b"\x00\x08\x09" - -class MIP6MH_HoTI(_MobilityHeader): - name = "IPv6 Mobility Header - Home Test Init" - fields_desc = [ ByteEnumField("nh", 59, ipv6nh), - ByteField("len", None), - ByteEnumField("mhtype", 1, mhtypes), - ByteField("res", None), - XShortField("cksum", None), - StrFixedLenField("reserved", "\x00"*2, 2), - StrFixedLenField("cookie", "\x00"*8, 8), - _PhantomAutoPadField("autopad", 1), # autopad activated by default - _MobilityOptionsField("options", [], MIP6OptUnknown, 16, - length_from = lambda pkt: 8*(pkt.len-1)) ] - overload_fields = { IPv6: { "nh": 135 } } - def hashret(self): - return self.cookie - -class MIP6MH_CoTI(MIP6MH_HoTI): - name = "IPv6 Mobility Header - Care-of Test Init" - mhtype = 2 - def hashret(self): - return self.cookie - -class MIP6MH_HoT(_MobilityHeader): - name = "IPv6 Mobility Header - Home Test" - fields_desc = [ ByteEnumField("nh", 59, ipv6nh), - ByteField("len", None), - ByteEnumField("mhtype", 3, mhtypes), - ByteField("res", None), - XShortField("cksum", None), - ShortField("index", None), - StrFixedLenField("cookie", "\x00"*8, 8), - StrFixedLenField("token", "\x00"*8, 8), - _PhantomAutoPadField("autopad", 1), # autopad activated by default - _MobilityOptionsField("options", [], MIP6OptUnknown, 24, - length_from = lambda pkt: 8*(pkt.len-2)) ] - overload_fields = { IPv6: { "nh": 135 } } - def hashret(self): - return self.cookie - def answers(self): - if (isinstance(other, MIP6MH_HoTI) and - self.cookie == other.cookie): - return 1 - return 0 - -class MIP6MH_CoT(MIP6MH_HoT): - name = "IPv6 Mobility Header - Care-of Test" - mhtype = 4 - def hashret(self): - return self.cookie - - def answers(self): - if (isinstance(other, MIP6MH_CoTI) and - self.cookie == other.cookie): - return 1 - return 0 - -class LifetimeField(ShortField): - def i2repr(self, pkt, x): - return "%d sec" % (4*x) - -class MIP6MH_BU(_MobilityHeader): - name = "IPv6 Mobility Header - Binding Update" - fields_desc = [ ByteEnumField("nh", 59, ipv6nh), - ByteField("len", None), # unit == 8 bytes (excluding the first 8 bytes) - ByteEnumField("mhtype", 5, mhtypes), - ByteField("res", None), - XShortField("cksum", None), - XShortField("seq", None), # TODO: ShortNonceField - FlagsField("flags", "KHA", 7, "PRMKLHA"), - XBitField("reserved", 0, 9), - LifetimeField("mhtime", 3), # unit == 4 seconds - _PhantomAutoPadField("autopad", 1), # autopad activated by default - _MobilityOptionsField("options", [], MIP6OptUnknown, 12, - length_from = lambda pkt: 8*pkt.len - 4) ] - overload_fields = { IPv6: { "nh": 135 } } - - def hashret(self): # Hack: see comment in MIP6MH_BRR.hashret() - return "\x00\x08\x09" - - def answers(self, other): - if isinstance(other, MIP6MH_BRR): - return 1 - return 0 - -class MIP6MH_BA(_MobilityHeader): - name = "IPv6 Mobility Header - Binding ACK" - fields_desc = [ ByteEnumField("nh", 59, ipv6nh), - ByteField("len", None), # unit == 8 bytes (excluding the first 8 bytes) - ByteEnumField("mhtype", 6, mhtypes), - ByteField("res", None), - XShortField("cksum", None), - ByteEnumField("status", 0, bastatus), - FlagsField("flags", "K", 3, "PRK"), - XBitField("res2", None, 5), - XShortField("seq", None), # TODO: ShortNonceField - XShortField("mhtime", 0), # unit == 4 seconds - _PhantomAutoPadField("autopad", 1), # autopad activated by default - _MobilityOptionsField("options", [], MIP6OptUnknown, 12, - length_from = lambda pkt: 8*pkt.len-4) ] - overload_fields = { IPv6: { "nh": 135 }} - - def hashret(self): # Hack: see comment in MIP6MH_BRR.hashret() - return "\x00\x08\x09" - - def answers(self, other): - if (isinstance(other, MIP6MH_BU) and - other.mhtype == 5 and - self.mhtype == 6 and - other.flags & 0x1 and # Ack request flags is set - self.seq == other.seq): - return 1 - return 0 - -_bestatus = { 1: 'Unknown binding for Home Address destination option', - 2: 'Unrecognized MH Type value' } - -# TODO: match Binding Error to its stimulus -class MIP6MH_BE(_MobilityHeader): - name = "IPv6 Mobility Header - Binding Error" - fields_desc = [ ByteEnumField("nh", 59, ipv6nh), - ByteField("len", None), # unit == 8 bytes (excluding the first 8 bytes) - ByteEnumField("mhtype", 7, mhtypes), - ByteField("res", 0), - XShortField("cksum", None), - ByteEnumField("status", 0, _bestatus), - ByteField("reserved", 0), - IP6Field("ha", "::"), - _MobilityOptionsField("options", [], MIP6OptUnknown, 24, - length_from = lambda pkt: 8*(pkt.len-2)) ] - overload_fields = { IPv6: { "nh": 135 }} - -_mip6_mhtype2cls = { 0: MIP6MH_BRR, - 1: MIP6MH_HoTI, - 2: MIP6MH_CoTI, - 3: MIP6MH_HoT, - 4: MIP6MH_CoT, - 5: MIP6MH_BU, - 6: MIP6MH_BA, - 7: MIP6MH_BE } - - -############################################################################# -############################################################################# -### Traceroute6 ### -############################################################################# -############################################################################# - -class AS_resolver6(AS_resolver_riswhois): - def _resolve_one(self, ip): - """ - overloaded version to provide a Whois resolution on the - embedded IPv4 address if the address is 6to4 or Teredo. - Otherwise, the native IPv6 address is passed. - """ - - if in6_isaddr6to4(ip): # for 6to4, use embedded @ - tmp = inet_pton(socket.AF_INET6, ip) - addr = inet_ntop(socket.AF_INET, tmp[2:6]) - elif in6_isaddrTeredo(ip): # for Teredo, use mapped address - addr = teredoAddrExtractInfo(ip)[2] - else: - addr = ip - - _, asn, desc = AS_resolver_riswhois._resolve_one(self, addr) - - return ip,asn,desc - -class TracerouteResult6(TracerouteResult): - def show(self): - #return self.make_table(lambda (s,r): (s.sprintf("%-42s,IPv6.dst%:{TCP:tcp%TCP.dport%}{UDP:udp%UDP.dport%}{ICMPv6EchoRequest:IER}"), # TODO: ICMPv6 ! - return self.make_table(lambda s,r: (s.sprintf("%-42s,IPv6.dst%:{TCP:tcp%TCP.dport%}{UDP:udp%UDP.dport%}{ICMPv6EchoRequest:IER}"), # TODO: ICMPv6 ! - s.hlim, - r.sprintf("%-42s,IPv6.src% {TCP:%TCP.flags%}"+ - "{ICMPv6DestUnreach:%ir,type%}{ICMPv6PacketTooBig:%ir,type%}"+ - "{ICMPv6TimeExceeded:%ir,type%}{ICMPv6ParamProblem:%ir,type%}"+ - "{ICMPv6EchoReply:%ir,type%}"))) - - def get_trace(self): - trace = {} - - for s,r in self.res: - if IPv6 not in s: - continue - d = s[IPv6].dst - if d not in trace: - trace[d] = {} - - t = not (ICMPv6TimeExceeded in r or - ICMPv6DestUnreach in r or - ICMPv6PacketTooBig in r or - ICMPv6ParamProblem in r) - - trace[d][s[IPv6].hlim] = r[IPv6].src, t - - for k in trace.values(): - #m = filter(lambda x: k[x][1], k.keys()) - m = [ x for x in k.keys() if k[x][1] ] - if not m: - continue - m = min(m) - for l in k.keys(): - if l > m: - del(k[l]) - - return trace - - def graph(self, ASres=AS_resolver6(), **kargs): - TracerouteResult.graph(self, ASres=ASres, **kargs) - -def traceroute6(target, dport=80, minttl=1, maxttl=30, sport=RandShort(), - l4 = None, timeout=2, verbose=None, **kargs): - """ - Instant TCP traceroute using IPv6 : - traceroute6(target, [maxttl=30], [dport=80], [sport=80]) -> None - """ - if verbose is None: - verbose = conf.verb - - if l4 is None: - a,b = sr(IPv6(dst=target, hlim=(minttl,maxttl))/TCP(seq=RandInt(),sport=sport, dport=dport), - timeout=timeout, filter="icmp6 or tcp", verbose=verbose, **kargs) - else: - a,b = sr(IPv6(dst=target, hlim=(minttl,maxttl))/l4, - timeout=timeout, verbose=verbose, **kargs) - - a = TracerouteResult6(a.res) - - if verbose: - a.display() - - return a,b - -############################################################################# -############################################################################# -### Sockets ### -############################################################################# -############################################################################# - -class L3RawSocket6(L3RawSocket): - def __init__(self, type = ETH_P_IPV6, filter=None, iface=None, promisc=None, nofilter=0): - L3RawSocket.__init__(self, type, filter, iface, promisc) - # NOTE: if fragmentation is needed, it will be done by the kernel (RFC 2292) - self.outs = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_RAW) - self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type)) - -def IPv6inIP(dst='203.178.135.36', src=None): - _IPv6inIP.dst = dst - _IPv6inIP.src = src - if not conf.L3socket == _IPv6inIP: - _IPv6inIP.cls = conf.L3socket - else: - del(conf.L3socket) - return _IPv6inIP - -class _IPv6inIP(SuperSocket): - dst = '127.0.0.1' - src = None - cls = None - - def __init__(self, family=socket.AF_INET6, type=socket.SOCK_STREAM, proto=0, **args): - SuperSocket.__init__(self, family, type, proto) - self.worker = self.cls(**args) - - def set(self, dst, src=None): - _IPv6inIP.src = src - _IPv6inIP.dst = dst - - def nonblock_recv(self): - p = self.worker.nonblock_recv() - return self._recv(p) - - def recv(self, x): - p = self.worker.recv(x) - return self._recv(p, x) - - def _recv(self, p, x=MTU): - if p is None: - return p - elif isinstance(p, IP): - # TODO: verify checksum - if p.src == self.dst and p.proto == socket.IPPROTO_IPV6: - if isinstance(p.payload, IPv6): - return p.payload - return p - - def send(self, x): - return self.worker.send(IP(dst=self.dst, src=self.src, proto=socket.IPPROTO_IPV6)/x) - - -############################################################################# -############################################################################# -### Layers binding ### -############################################################################# -############################################################################# - -conf.l3types.register(ETH_P_IPV6, IPv6) -conf.l2types.register(31, IPv6) - -bind_layers(Ether, IPv6, type = 0x86dd ) -bind_layers(CookedLinux, IPv6, proto = 0x86dd ) -bind_layers(IPerror6, TCPerror, nh = socket.IPPROTO_TCP ) -bind_layers(IPerror6, UDPerror, nh = socket.IPPROTO_UDP ) -bind_layers(IPv6, TCP, nh = socket.IPPROTO_TCP ) -bind_layers(IPv6, UDP, nh = socket.IPPROTO_UDP ) -bind_layers(IP, IPv6, proto = socket.IPPROTO_IPV6 ) -bind_layers(IPv6, IPv6, nh = socket.IPPROTO_IPV6 ) - -bind_layers(IPv6, IP, nh = IPPROTO_IPIP ) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/ipsec.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/ipsec.py deleted file mode 100644 index a14925fb..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/ipsec.py +++ /dev/null @@ -1,995 +0,0 @@ -############################################################################# -## ipsec.py --- IPSec support for Scapy ## -## ## -## Copyright (C) 2014 6WIND ## -## ## -## This program is free software; you can redistribute it and/or modify it ## -## under the terms of the GNU General Public License version 2 as ## -## published by the Free Software Foundation. ## -## ## -## This program is distributed in the hope that it will be useful, but ## -## WITHOUT ANY WARRANTY; without even the implied warranty of ## -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## -## General Public License for more details. ## -############################################################################# -""" -IPSec layer -=========== - -Example of use: - ->>> sa = SecurityAssociation(ESP, spi=0xdeadbeef, crypt_algo='AES-CBC', -... crypt_key='sixteenbytes key') ->>> p = IP(src='1.1.1.1', dst='2.2.2.2') ->>> p /= TCP(sport=45012, dport=80) ->>> p /= Raw(b'testdata') ->>> p = IP(bytes(p)) ->>> p -<IP version=4L ihl=5L tos=0x0 len=48 id=1 flags= frag=0L ttl=64 proto=tcp chksum=0x74c2 src=1.1.1.1 dst=2.2.2.2 options=[] |<TCP sport=45012 dport=http seq=0 ack=0 dataofs=5L reserved=0L flags=S window=8192 chksum=0x1914 urgptr=0 options=[] |<Raw load='testdata' |>>> ->>> ->>> e = sa.encrypt(p) ->>> e -<IP version=4L ihl=5L tos=0x0 len=76 id=1 flags= frag=0L ttl=64 proto=esp chksum=0x747a src=1.1.1.1 dst=2.2.2.2 |<ESP spi=0xdeadbeef seq=1 data='\xf8\xdb\x1e\x83[T\xab\\\xd2\x1b\xed\xd1\xe5\xc8Y\xc2\xa5d\x92\xc1\x05\x17\xa6\x92\x831\xe6\xc1]\x9a\xd6K}W\x8bFfd\xa5B*+\xde\xc8\x89\xbf{\xa9' |>> ->>> ->>> d = sa.decrypt(e) ->>> d -<IP version=4L ihl=5L tos=0x0 len=48 id=1 flags= frag=0L ttl=64 proto=tcp chksum=0x74c2 src=1.1.1.1 dst=2.2.2.2 |<TCP sport=45012 dport=http seq=0 ack=0 dataofs=5L reserved=0L flags=S window=8192 chksum=0x1914 urgptr=0 options=[] |<Raw load='testdata' |>>> ->>> ->>> d == p -True -""" - -import socket - -if not hasattr(socket, 'IPPROTO_AH'): - socket.IPPROTO_AH = 51 -if not hasattr(socket, 'IPPROTO_ESP'): - socket.IPPROTO_ESP = 50 - - -import fractions - -from scapy.data import IP_PROTOS - -from scapy.fields import ByteEnumField, ByteField, StrField, XIntField, IntField, \ - ShortField, PacketField - -from scapy.packet import Packet, bind_layers, Raw - -from scapy.layers.inet import IP, UDP -from scapy.layers.inet6 import IPv6, IPv6ExtHdrHopByHop, IPv6ExtHdrDestOpt, \ - IPv6ExtHdrRouting - - -#------------------------------------------------------------------------------ -class AH(Packet): - """ - Authentication Header - - See https://tools.ietf.org/rfc/rfc4302.txt - """ - - name = 'AH' - - fields_desc = [ - ByteEnumField('nh', None, IP_PROTOS), - ByteField('payloadlen', None), - ShortField('reserved', None), - XIntField('spi', 0x0), - IntField('seq', 0), - StrField('icv', None), - StrField('padding', None), - ] - - overload_fields = { - IP: {'proto': socket.IPPROTO_AH}, - IPv6: {'nh': socket.IPPROTO_AH}, - IPv6ExtHdrHopByHop: {'nh': socket.IPPROTO_AH}, - IPv6ExtHdrDestOpt: {'nh': socket.IPPROTO_AH}, - IPv6ExtHdrRouting: {'nh': socket.IPPROTO_AH}, - } - -bind_layers(IP, AH, proto=socket.IPPROTO_AH) -bind_layers(IPv6, AH, nh=socket.IPPROTO_AH) - -#------------------------------------------------------------------------------ -class ESP(Packet): - """ - Encapsulated Security Payload - - See https://tools.ietf.org/rfc/rfc4303.txt - """ - name = 'ESP' - - fields_desc = [ - XIntField('spi', 0x0), - IntField('seq', 0), - StrField('data', None), - ] - - overload_fields = { - IP: {'proto': socket.IPPROTO_ESP}, - IPv6: {'nh': socket.IPPROTO_ESP}, - IPv6ExtHdrHopByHop: {'nh': socket.IPPROTO_ESP}, - IPv6ExtHdrDestOpt: {'nh': socket.IPPROTO_ESP}, - IPv6ExtHdrRouting: {'nh': socket.IPPROTO_ESP}, - } - -bind_layers(IP, ESP, proto=socket.IPPROTO_ESP) -bind_layers(IPv6, ESP, nh=socket.IPPROTO_ESP) -bind_layers(UDP, ESP, dport=4500) # NAT-Traversal encapsulation -bind_layers(UDP, ESP, sport=4500) # NAT-Traversal encapsulation - -#------------------------------------------------------------------------------ -class _ESPPlain(Packet): - """ - Internal class to represent unencrypted ESP packets. - """ - name = 'ESP' - - fields_desc = [ - XIntField('spi', 0x0), - IntField('seq', 0), - - StrField('iv', ''), - PacketField('data', '', Raw), - StrField('padding', ''), - - ByteField('padlen', 0), - ByteEnumField('nh', 0, IP_PROTOS), - StrField('icv', ''), - ] - - def data_for_encryption(self): - return bytes(self.data) + self.padding + chr(self.padlen).encode('ascii') + chr(self.nh).encode('ascii') - -#------------------------------------------------------------------------------ -try: - from Crypto.Cipher import AES - from Crypto.Cipher import DES - from Crypto.Cipher import DES3 - from Crypto.Cipher import CAST - from Crypto.Cipher import Blowfish - from Crypto.Util import Counter - from Crypto import Random -except ImportError: - # no error if pycrypto is not available but encryption won't be supported - AES = None - DES = None - DES3 = None - CAST = None - Blowfish = None - Random = None - -#------------------------------------------------------------------------------ -def _lcm(a, b): - """ - Least Common Multiple between 2 integers. - """ - if a == 0 or b == 0: - return 0 - else: - return abs(a * b) // fractions.gcd(a, b) - -class CryptAlgo(object): - """ - IPSec encryption algorithm - """ - - def __init__(self, name, cipher, mode, block_size=None, iv_size=None, key_size=None): - """ - @param name: the name of this encryption algorithm - @param cipher: a Cipher module - @param mode: the mode used with the cipher module - @param block_size: the length a block for this algo. Defaults to the - `block_size` of the cipher. - @param iv_size: the length of the initialization vector of this algo. - Defaults to the `block_size` of the cipher. - @param key_size: an integer or list/tuple of integers. If specified, - force the secret keys length to one of the values. - Defaults to the `key_size` of the cipher. - """ - self.name = name - self.cipher = cipher - self.mode = mode - - if block_size is not None: - self.block_size = block_size - elif cipher is not None: - self.block_size = cipher.block_size - else: - self.block_size = 1 - - if iv_size is None: - self.iv_size = self.block_size - else: - self.iv_size = iv_size - - if key_size is not None: - self.key_size = key_size - elif cipher is not None: - self.key_size = cipher.key_size - else: - self.key_size = None - - def check_key(self, key): - """ - Check that the key length is valid. - - @param key: a byte string - """ - if self.key_size and not (len(key) == self.key_size or len(key) in self.key_size): - raise TypeError('invalid key size %s, must be %s' % - (len(key), self.key_size)) - - def generate_iv(self): - """ - Generate a random initialization vector. If pycrypto is not available, - return a buffer of the correct length filled with only '\x00'. - """ - if Random: - return Random.get_random_bytes(self.iv_size) - else: - return chr(0) * self.iv_size - - def new_cipher(self, key, iv): - """ - @param key: the secret key, a byte string - @param iv: the initialization vector, a byte string - @return: an initialized cipher object for this algo - """ - if type(key) is str: - key = key.encode('ascii') - if (hasattr(self.cipher, 'MODE_CTR') and self.mode == self.cipher.MODE_CTR - or hasattr(self.cipher, 'MODE_GCM') and self.mode == self.cipher.MODE_GCM): - # in counter mode, the "iv" must be incremented for each block - # it is calculated like this: - # +---------+------------------+---------+ - # | nonce | IV | counter | - # +---------+------------------+---------+ - # m bytes n bytes 4 bytes - # <--------------------------------------> - # block_size - nonce_size = self.cipher.block_size - self.iv_size - 4 - - # instead of asking for an extra parameter, we extract the last - # nonce_size bytes of the key and use them as the nonce. - # +----------------------------+---------+ - # | cipher key | nonce | - # +----------------------------+---------+ - # <---------> - # nonce_size - cipher_key, nonce = key[:-nonce_size], key[-nonce_size:] - - return self.cipher.new(cipher_key, self.mode, - counter=Counter.new(4 * 8, prefix=nonce + iv)) - else: - return self.cipher.new(key, self.mode, iv) - - def pad(self, esp): - """ - Add the correct amount of padding so that the data to encrypt is - exactly a multiple of the algorithm's block size. - - Also, make sure that the total ESP packet length is a multiple of 4 or - 8 bytes with IP or IPv6 respectively. - - @param esp: an unencrypted _ESPPlain packet - """ - # 2 extra bytes for padlen and nh - data_len = len(esp.data) + 2 - - # according to the RFC4303, section 2.4. Padding (for Encryption) - # the size of the ESP payload must be a multiple of 32 bits - align = _lcm(self.block_size, 4) - - # pad for block size - esp.padlen = -data_len % align - - # padding must be an array of bytes starting from 1 to padlen - esp.padding = '' - for b in range(1, esp.padlen + 1): - esp.padding += bytes([b]) - - # If the following test fails, it means that this algo does not comply - # with the RFC - payload_len = len(esp.iv) + len(esp.data) + len(esp.padding) + 2 - if payload_len % 4 != 0: - raise ValueError('The size of the ESP data is not aligned to 32 bits after padding.') - - return esp - - def encrypt(self, esp, key): - """ - Encrypt an ESP packet - - @param esp: an unencrypted _ESPPlain packet with valid padding - @param key: the secret key used for encryption - - @return: a valid ESP packet encrypted with this algorithm - """ - data = esp.data_for_encryption() - - if self.cipher: - self.check_key(key) - cipher = self.new_cipher(key, esp.iv) - data = cipher.encrypt(data) - - return ESP(spi=esp.spi, seq=esp.seq, data=esp.iv + data) - - def decrypt(self, esp, key, icv_size=0): - """ - Decrypt an ESP packet - - @param esp: an encrypted ESP packet - @param key: the secret key used for encryption - @param icv_size: the length of the icv used for integrity check - - @return: a valid ESP packet encrypted with this algorithm - """ - self.check_key(key) - - iv = esp.data[:self.iv_size] - data = esp.data[self.iv_size:len(esp.data) - icv_size] - icv = esp.data[len(esp.data) - icv_size:] - - if self.cipher: - cipher = self.new_cipher(key, iv) - data = cipher.decrypt(data) - - # extract padlen and nh - #padlen = ord(data[-2]) - padlen = (data[-2]) - #nh = ord(data[-1]) - nh = (data[-1]) - - # then use padlen to determine data and padding - data = data[:len(data) - padlen - 2] - padding = data[len(data) - padlen - 2: len(data) - 2] - - return _ESPPlain(spi=esp.spi, - seq=esp.seq, - iv=iv, - data=data, - padding=padding, - padlen=padlen, - nh=nh, - icv=icv) - -#------------------------------------------------------------------------------ -# The names of the encryption algorithms are the same than in scapy.contrib.ikev2 -# see http://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml - -CRYPT_ALGOS = { - 'NULL': CryptAlgo('NULL', cipher=None, mode=None, iv_size=0), -} - -if AES: - CRYPT_ALGOS['AES-CBC'] = CryptAlgo('AES-CBC', - cipher=AES, - mode=AES.MODE_CBC) - # specific case for counter mode: - # the last 4 bytes of the key are used to carry the nonce of the counter - CRYPT_ALGOS['AES-CTR'] = CryptAlgo('AES-CTR', - cipher=AES, - mode=AES.MODE_CTR, - block_size=1, - iv_size=8, - key_size=(16 + 4, 24 + 4, 32 + 4)) -if DES: - CRYPT_ALGOS['DES'] = CryptAlgo('DES', - cipher=DES, - mode=DES.MODE_CBC) -if Blowfish: - CRYPT_ALGOS['Blowfish'] = CryptAlgo('Blowfish', - cipher=Blowfish, - mode=Blowfish.MODE_CBC) -if DES3: - CRYPT_ALGOS['3DES'] = CryptAlgo('3DES', - cipher=DES3, - mode=DES3.MODE_CBC) -if CAST: - CRYPT_ALGOS['CAST'] = CryptAlgo('CAST', - cipher=CAST, - mode=CAST.MODE_CBC) - -#------------------------------------------------------------------------------ -try: - from Crypto.Hash import HMAC - from Crypto.Hash import SHA - from Crypto.Hash import MD5 - from Crypto.Hash import SHA256 - from Crypto.Hash import SHA384 - from Crypto.Hash import SHA512 -except ImportError: - # no error if pycrypto is not available but authentication won't be supported - HMAC = None - SHA = None - MD5 = None - SHA256 = None - SHA384 = None -try: - from Crypto.Hash import XCBCMAC -except ImportError: - XCBCMAC = None - -#------------------------------------------------------------------------------ -class IPSecIntegrityError(Exception): - """ - Error risen when the integrity check fails. - """ - pass - -class AuthAlgo(object): - """ - IPSec integrity algorithm - """ - - def __init__(self, name, mac, digestmod, icv_size, key_size=None): - """ - @param name: the name of this integrity algorithm - @param mac: a Message Authentication Code module - @param digestmod: a Hash or Cipher module - @param icv_size: the length of the integrity check value of this algo - @param key_size: an integer or list/tuple of integers. If specified, - force the secret keys length to one of the values. - Defaults to the `key_size` of the cipher. - """ - self.name = name - self.mac = mac - self.digestmod = digestmod - self.icv_size = icv_size - self.key_size = key_size - - def check_key(self, key): - """ - Check that the key length is valid. - - @param key: a byte string - """ - if self.key_size and len(key) not in self.key_size: - raise TypeError('invalid key size %s, must be one of %s' % - (len(key), self.key_size)) - - def new_mac(self, key): - """ - @param key: a byte string - @return: an initialized mac object for this algo - """ - if type(key) is str: - key = key.encode('ascii') - if self.mac is XCBCMAC: - # specific case here, ciphermod instead of digestmod - return self.mac.new(key, ciphermod=self.digestmod) - else: - print(self.mac) - return self.mac.new(key, digestmod=self.digestmod) - - def sign(self, pkt, key): - """ - Sign an IPSec (ESP or AH) packet with this algo. - - @param pkt: a packet that contains a valid encrypted ESP or AH layer - @param key: the authentication key, a byte string - - @return: the signed packet - """ - if not self.mac: - return pkt - - self.check_key(key) - - mac = self.new_mac(key) - - if pkt.haslayer(ESP): - mac.update(bytes(pkt[ESP])) - pkt[ESP].data += mac.digest()[:self.icv_size] - - elif pkt.haslayer(AH): - clone = zero_mutable_fields(pkt.copy(), sending=True) - mac.update(bytes(clone)) - pkt[AH].icv = mac.digest()[:self.icv_size] - - return pkt - - def verify(self, pkt, key): - """ - Check that the integrity check value (icv) of a packet is valid. - - @param pkt: a packet that contains a valid encrypted ESP or AH layer - @param key: the authentication key, a byte string - - @raise IPSecIntegrityError: if the integrity check fails - """ - if not self.mac or self.icv_size == 0: - return - - self.check_key(key) - - mac = self.new_mac(key) - - pkt_icv = 'not found' - computed_icv = 'not computed' - - if isinstance(pkt, ESP): - pkt_icv = pkt.data[len(pkt.data) - self.icv_size:] - - pkt = pkt.copy() - pkt.data = pkt.data[:len(pkt.data) - self.icv_size] - mac.update(bytes(pkt)) - computed_icv = mac.digest()[:self.icv_size] - - elif pkt.haslayer(AH): - pkt_icv = pkt[AH].icv[:self.icv_size] - - clone = zero_mutable_fields(pkt.copy(), sending=False) - mac.update(bytes(clone)) - computed_icv = mac.digest()[:self.icv_size] - - if pkt_icv != computed_icv: - raise IPSecIntegrityError('pkt_icv=%r, computed_icv=%r' % - (pkt_icv, computed_icv)) - -#------------------------------------------------------------------------------ -# The names of the integrity algorithms are the same than in scapy.contrib.ikev2 -# see http://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml - -AUTH_ALGOS = { - 'NULL': AuthAlgo('NULL', mac=None, digestmod=None, icv_size=0), -} - -if HMAC: - if SHA: - AUTH_ALGOS['HMAC-SHA1-96'] = AuthAlgo('HMAC-SHA1-96', - mac=HMAC, - digestmod=SHA, - icv_size=12) - if SHA256: - AUTH_ALGOS['SHA2-256-128'] = AuthAlgo('SHA2-256-128', - mac=HMAC, - digestmod=SHA256, - icv_size=16) - if SHA384: - AUTH_ALGOS['SHA2-384-192'] = AuthAlgo('SHA2-384-192', - mac=HMAC, - digestmod=SHA384, - icv_size=24) - if SHA512: - AUTH_ALGOS['SHA2-512-256'] = AuthAlgo('SHA2-512-256', - mac=HMAC, - digestmod=SHA512, - icv_size=32) - if MD5: - AUTH_ALGOS['HMAC-MD5-96'] = AuthAlgo('HMAC-MD5-96', - mac=HMAC, - digestmod=MD5, - icv_size=12) -if AES and XCBCMAC: - AUTH_ALGOS['AES-XCBC-96'] = AuthAlgo('AES-XCBC-96', - mac=XCBCMAC, - digestmod=AES, - icv_size=12, - key_size=(16,)) - -#------------------------------------------------------------------------------ - - -#------------------------------------------------------------------------------ -def split_for_transport(orig_pkt, transport_proto): - """ - Split an IP(v6) packet in the correct location to insert an ESP or AH - header. - - @param orig_pkt: the packet to split. Must be an IP or IPv6 packet - @param transport_proto: the IPSec protocol number that will be inserted - at the split position. - @return: a tuple (header, nh, payload) where nh is the protocol number of - payload. - """ - header = orig_pkt.copy() - next_hdr = header.payload - nh = None - - if header.version == 4: - nh = header.proto - header.proto = transport_proto - header.remove_payload() - del header.chksum - del header.len - - return header, nh, next_hdr - else: - found_rt_hdr = False - prev = header - - # Since the RFC 4302 is vague about where the ESP/AH headers should be - # inserted in IPv6, I chose to follow the linux implementation. - while isinstance(next_hdr, (IPv6ExtHdrHopByHop, IPv6ExtHdrRouting, IPv6ExtHdrDestOpt)): - if isinstance(next_hdr, IPv6ExtHdrHopByHop): - pass - if isinstance(next_hdr, IPv6ExtHdrRouting): - found_rt_hdr = True - elif isinstance(next_hdr, IPv6ExtHdrDestOpt) and found_rt_hdr: - break - - prev = next_hdr - next_hdr = next_hdr.payload - - nh = prev.nh - prev.nh = transport_proto - prev.remove_payload() - del header.plen - - return header, nh, next_hdr - -#------------------------------------------------------------------------------ -# see RFC 4302 - Appendix A. Mutability of IP Options/Extension Headers -IMMUTABLE_IPV4_OPTIONS = ( - 0, # End Of List - 1, # No OPeration - 2, # Security - 5, # Extended Security - 6, # Commercial Security - 20, # Router Alert - 21, # Sender Directed Multi-Destination Delivery -) -def zero_mutable_fields(pkt, sending=False): - """ - When using AH, all "mutable" fields must be "zeroed" before calculating - the ICV. See RFC 4302, Section 3.3.3.1. Handling Mutable Fields. - - @param pkt: an IP(v6) packet containing an AH layer. - NOTE: The packet will be modified - @param sending: if true, ipv6 routing headers will not be reordered - """ - - if pkt.haslayer(AH): - pkt[AH].icv = chr(0) * len(pkt[AH].icv) - else: - raise TypeError('no AH layer found') - - if pkt.version == 4: - # the tos field has been replaced by DSCP and ECN - # Routers may rewrite the DS field as needed to provide a - # desired local or end-to-end service - pkt.tos = 0 - # an intermediate router might set the DF bit, even if the source - # did not select it. - pkt.flags = 0 - # changed en route as a normal course of processing by routers - pkt.ttl = 0 - # will change if any of these other fields change - pkt.chksum = 0 - - immutable_opts = [] - for opt in pkt.options: - if opt.option in IMMUTABLE_IPV4_OPTIONS: - immutable_opts.append(opt) - else: - immutable_opts.append(Raw(chr(0) * len(opt))) - pkt.options = immutable_opts - - else: - # holds DSCP and ECN - pkt.tc = 0 - # The flow label described in AHv1 was mutable, and in RFC 2460 [DH98] - # was potentially mutable. To retain compatibility with existing AH - # implementations, the flow label is not included in the ICV in AHv2. - pkt.fl = 0 - # same as ttl - pkt.hlim = 0 - - next_hdr = pkt.payload - - while isinstance(next_hdr, (IPv6ExtHdrHopByHop, IPv6ExtHdrRouting, IPv6ExtHdrDestOpt)): - if isinstance(next_hdr, (IPv6ExtHdrHopByHop, IPv6ExtHdrDestOpt)): - for opt in next_hdr.options: - if opt.otype & 0x20: - # option data can change en-route and must be zeroed - opt.optdata = chr(0) * opt.optlen - elif isinstance(next_hdr, IPv6ExtHdrRouting) and sending: - # The sender must order the field so that it appears as it - # will at the receiver, prior to performing the ICV computation. - next_hdr.segleft = 0 - if next_hdr.addresses: - final = next_hdr.addresses.pop() - next_hdr.addresses.insert(0, pkt.dst) - pkt.dst = final - else: - break - - next_hdr = next_hdr.payload - - return pkt - -#------------------------------------------------------------------------------ -class SecurityAssociation(object): - """ - This class is responsible of "encryption" and "decryption" of IPSec packets. - """ - - SUPPORTED_PROTOS = (IP, IPv6) - - def __init__(self, proto, spi, seq_num=1, crypt_algo=None, crypt_key=None, - auth_algo=None, auth_key=None, tunnel_header=None, nat_t_header=None): - """ - @param proto: the IPSec proto to use (ESP or AH) - @param spi: the Security Parameters Index of this SA - @param seq_num: the initial value for the sequence number on encrypted - packets - @param crypt_algo: the encryption algorithm name (only used with ESP) - @param crypt_key: the encryption key (only used with ESP) - @param auth_algo: the integrity algorithm name - @param auth_key: the integrity key - @param tunnel_header: an instance of a IP(v6) header that will be used - to encapsulate the encrypted packets. - @param nat_t_header: an instance of a UDP header that will be used - for NAT-Traversal. - """ - - if proto not in (ESP, AH, ESP.name, AH.name): - raise ValueError("proto must be either ESP or AH") - if isinstance(proto, str): - self.proto = eval(proto) - else: - self.proto = proto - - self.spi = spi - self.seq_num = seq_num - - if crypt_algo: - if crypt_algo not in CRYPT_ALGOS: - raise TypeError('unsupported encryption algo %r, try %r' % - (crypt_algo, CRYPT_ALGOS.keys())) - self.crypt_algo = CRYPT_ALGOS[crypt_algo] - self.crypt_algo.check_key(crypt_key) - self.crypt_key = crypt_key - else: - self.crypt_algo = CRYPT_ALGOS['NULL'] - self.crypt_key = None - - if auth_algo: - if auth_algo not in AUTH_ALGOS: - raise TypeError('unsupported integrity algo %r, try %r' % - (auth_algo, AUTH_ALGOS.keys())) - self.auth_algo = AUTH_ALGOS[auth_algo] - self.auth_algo.check_key(auth_key) - self.auth_key = auth_key - else: - self.auth_algo = AUTH_ALGOS['NULL'] - self.auth_key = None - - if tunnel_header and not isinstance(tunnel_header, (IP, IPv6)): - raise TypeError('tunnel_header must be %s or %s' % (IP.name, IPv6.name)) - self.tunnel_header = tunnel_header - - if nat_t_header: - if proto is not ESP: - raise TypeError('nat_t_header is only allowed with ESP') - if not isinstance(nat_t_header, UDP): - raise TypeError('nat_t_header must be %s' % UDP.name) - self.nat_t_header = nat_t_header - - def check_spi(self, pkt): - if pkt.spi != self.spi: - raise TypeError('packet spi=0x%x does not match the SA spi=0x%x' % - (pkt.spi, self.spi)) - - def _encrypt_esp(self, pkt, seq_num=None, iv=None): - - if iv is None: - iv = self.crypt_algo.generate_iv() - else: - if len(iv) != self.crypt_algo.iv_size: - raise TypeError('iv length must be %s' % self.crypt_algo.iv_size) - - esp = _ESPPlain(spi=self.spi, seq=seq_num or self.seq_num, iv=iv) - - if self.tunnel_header: - tunnel = self.tunnel_header.copy() - - if tunnel.version == 4: - del tunnel.proto - del tunnel.len - del tunnel.chksum - else: - del tunnel.nh - del tunnel.plen - - pkt = tunnel.__class__(bytes(tunnel / pkt)) - - ip_header, nh, payload = split_for_transport(pkt, socket.IPPROTO_ESP) - esp.data = payload - esp.nh = nh - - esp = self.crypt_algo.pad(esp) - esp = self.crypt_algo.encrypt(esp, self.crypt_key) - - self.auth_algo.sign(esp, self.auth_key) - - if self.nat_t_header: - nat_t_header = self.nat_t_header.copy() - nat_t_header.chksum = 0 - del nat_t_header.len - if ip_header.version == 4: - del ip_header.proto - else: - del ip_header.nh - ip_header /= nat_t_header - - if ip_header.version == 4: - ip_header.len = len(ip_header) + len(esp) - del ip_header.chksum - ip_header = ip_header.__class__(bytes(ip_header)) - else: - ip_header.plen = len(ip_header.payload) + len(esp) - - # sequence number must always change, unless specified by the user - if seq_num is None: - self.seq_num += 1 - - return ip_header / esp - - def _encrypt_ah(self, pkt, seq_num=None): - - ah = AH(spi=self.spi, seq=seq_num or self.seq_num, - icv=chr(0) * self.auth_algo.icv_size) - - if self.tunnel_header: - tunnel = self.tunnel_header.copy() - - if tunnel.version == 4: - del tunnel.proto - del tunnel.len - del tunnel.chksum - else: - del tunnel.nh - del tunnel.plen - - pkt = tunnel.__class__(bytes(tunnel / pkt)) - - ip_header, nh, payload = split_for_transport(pkt, socket.IPPROTO_AH) - ah.nh = nh - - if ip_header.version == 6 and len(ah) % 8 != 0: - # For IPv6, the total length of the header must be a multiple of - # 8-octet units. - ah.padding = chr(0) * (-len(ah) % 8) - elif len(ah) % 4 != 0: - # For IPv4, the total length of the header must be a multiple of - # 4-octet units. - ah.padding = chr(0) * (-len(ah) % 4) - - # RFC 4302 - Section 2.2. Payload Length - # This 8-bit field specifies the length of AH in 32-bit words (4-byte - # units), minus "2". - ah.payloadlen = len(ah) // 4 - 2 - - if ip_header.version == 4: - ip_header.len = len(ip_header) + len(ah) + len(payload) - del ip_header.chksum - ip_header = ip_header.__class__(bytes(ip_header)) - else: - ip_header.plen = len(ip_header.payload) + len(ah) + len(payload) - - signed_pkt = self.auth_algo.sign(ip_header / ah / payload, self.auth_key) - - # sequence number must always change, unless specified by the user - if seq_num is None: - self.seq_num += 1 - - return signed_pkt - - def encrypt(self, pkt, seq_num=None, iv=None): - """ - Encrypt (and encapsulate) an IP(v6) packet with ESP or AH according - to this SecurityAssociation. - - @param pkt: the packet to encrypt - @param seq_num: if specified, use this sequence number instead of the - generated one - @param iv: if specified, use this initialization vector for - encryption instead of a random one. - - @return: the encrypted/encapsulated packet - """ - if not isinstance(pkt, self.SUPPORTED_PROTOS): - raise TypeError('cannot encrypt %s, supported protos are %s' - % (pkt.__class__, self.SUPPORTED_PROTOS)) - if self.proto is ESP: - return self._encrypt_esp(pkt, seq_num=seq_num, iv=iv) - else: - return self._encrypt_ah(pkt, seq_num=seq_num) - - def _decrypt_esp(self, pkt, verify=True): - - encrypted = pkt[ESP] - - if verify: - self.check_spi(pkt) - self.auth_algo.verify(encrypted, self.auth_key) - - esp = self.crypt_algo.decrypt(encrypted, self.crypt_key, - self.auth_algo.icv_size) - - if self.tunnel_header: - # drop the tunnel header and return the payload untouched - - pkt.remove_payload() - if pkt.version == 4: - pkt.proto = esp.nh - else: - pkt.nh = esp.nh - cls = pkt.guess_payload_class(esp.data) - - return cls(esp.data) - else: - ip_header = pkt - - if ip_header.version == 4: - ip_header.proto = esp.nh - del ip_header.chksum - ip_header.remove_payload() - ip_header.len = len(ip_header) + len(esp.data) - # recompute checksum - ip_header = ip_header.__class__(bytes(ip_header)) - else: - encrypted.underlayer.nh = esp.nh - encrypted.underlayer.remove_payload() - ip_header.plen = len(ip_header.payload) + len(esp.data) - - cls = ip_header.guess_payload_class(esp.data) - - # reassemble the ip_header with the ESP payload - return ip_header / cls(esp.data) - - def _decrypt_ah(self, pkt, verify=True): - - if verify: - self.check_spi(pkt) - self.auth_algo.verify(pkt, self.auth_key) - - ah = pkt[AH] - payload = ah.payload - payload.remove_underlayer(None) # useless argument... - - if self.tunnel_header: - return payload - else: - ip_header = pkt - - if ip_header.version == 4: - ip_header.proto = ah.nh - del ip_header.chksum - ip_header.remove_payload() - ip_header.len = len(ip_header) + len(payload) - # recompute checksum - ip_header = ip_header.__class__(bytes(ip_header)) - else: - ah.underlayer.nh = ah.nh - ah.underlayer.remove_payload() - ip_header.plen = len(ip_header.payload) + len(payload) - - # reassemble the ip_header with the AH payload - return ip_header / payload - - def decrypt(self, pkt, verify=True): - """ - Decrypt (and decapsulate) an IP(v6) packet containing ESP or AH. - - @param pkt: the packet to decrypt - @param verify: if False, do not perform the integrity check - - @return: the decrypted/decapsulated packet - @raise IPSecIntegrityError: if the integrity check fails - """ - if not isinstance(pkt, self.SUPPORTED_PROTOS): - raise TypeError('cannot decrypt %s, supported protos are %s' - % (pkt.__class__, self.SUPPORTED_PROTOS)) - - if self.proto is ESP and pkt.haslayer(ESP): - return self._decrypt_esp(pkt, verify=verify) - elif self.proto is AH and pkt.haslayer(AH): - return self._decrypt_ah(pkt, verify=verify) - else: - raise TypeError('%s has no %s layer' % (pkt, self.proto.name)) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/ir.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/ir.py deleted file mode 100644 index 90935aa3..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/ir.py +++ /dev/null @@ -1,44 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -IrDA infrared data communication. -""" - -from scapy.packet import * -from scapy.fields import * -from scapy.layers.l2 import CookedLinux - - - -# IR - -class IrLAPHead(Packet): - name = "IrDA Link Access Protocol Header" - fields_desc = [ XBitField("Address", 0x7f, 7), - BitEnumField("Type", 1, 1, {"Response":0, - "Command":1})] - -class IrLAPCommand(Packet): - name = "IrDA Link Access Protocol Command" - fields_desc = [ XByteField("Control", 0), - XByteField("Format identifier", 0), - XIntField("Source address", 0), - XIntField("Destination address", 0xffffffff), - XByteField("Discovery flags", 0x1), - ByteEnumField("Slot number", 255, {"final":255}), - XByteField("Version", 0)] - - -class IrLMP(Packet): - name = "IrDA Link Management Protocol" - fields_desc = [ XShortField("Service hints", 0), - XByteField("Character set", 0), - StrField("Device name", "") ] - - -bind_layers( CookedLinux, IrLAPHead, proto=23) -bind_layers( IrLAPHead, IrLAPCommand, Type=1) -bind_layers( IrLAPCommand, IrLMP, ) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/isakmp.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/isakmp.py deleted file mode 100644 index 97def8f5..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/isakmp.py +++ /dev/null @@ -1,355 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -ISAKMP (Internet Security Association and Key Management Protocol). -""" - -import struct -from scapy.packet import * -from scapy.fields import * -from scapy.ansmachine import * -from scapy.layers.inet import IP,UDP -from scapy.sendrecv import sr - - -# see http://www.iana.org/assignments/ipsec-registry for details -ISAKMPAttributeTypes= { "Encryption": (1, { "DES-CBC" : 1, - "IDEA-CBC" : 2, - "Blowfish-CBC" : 3, - "RC5-R16-B64-CBC" : 4, - "3DES-CBC" : 5, - "CAST-CBC" : 6, - "AES-CBC" : 7, - "CAMELLIA-CBC" : 8, }, 0), - "Hash": (2, { "MD5": 1, - "SHA": 2, - "Tiger": 3, - "SHA2-256": 4, - "SHA2-384": 5, - "SHA2-512": 6,}, 0), - "Authentication":(3, { "PSK": 1, - "DSS": 2, - "RSA Sig": 3, - "RSA Encryption": 4, - "RSA Encryption Revised": 5, - "ElGamal Encryption": 6, - "ElGamal Encryption Revised": 7, - "ECDSA Sig": 8, - "HybridInitRSA": 64221, - "HybridRespRSA": 64222, - "HybridInitDSS": 64223, - "HybridRespDSS": 64224, - "XAUTHInitPreShared": 65001, - "XAUTHRespPreShared": 65002, - "XAUTHInitDSS": 65003, - "XAUTHRespDSS": 65004, - "XAUTHInitRSA": 65005, - "XAUTHRespRSA": 65006, - "XAUTHInitRSAEncryption": 65007, - "XAUTHRespRSAEncryption": 65008, - "XAUTHInitRSARevisedEncryption": 65009, - "XAUTHRespRSARevisedEncryptio": 65010, }, 0), - "GroupDesc": (4, { "768MODPgr" : 1, - "1024MODPgr" : 2, - "EC2Ngr155" : 3, - "EC2Ngr185" : 4, - "1536MODPgr" : 5, - "2048MODPgr" : 14, - "3072MODPgr" : 15, - "4096MODPgr" : 16, - "6144MODPgr" : 17, - "8192MODPgr" : 18, }, 0), - "GroupType": (5, {"MODP": 1, - "ECP": 2, - "EC2N": 3}, 0), - "GroupPrime": (6, {}, 1), - "GroupGenerator1":(7, {}, 1), - "GroupGenerator2":(8, {}, 1), - "GroupCurveA": (9, {}, 1), - "GroupCurveB": (10, {}, 1), - "LifeType": (11, {"Seconds": 1, - "Kilobytes": 2, }, 0), - "LifeDuration": (12, {}, 1), - "PRF": (13, {}, 0), - "KeyLength": (14, {}, 0), - "FieldSize": (15, {}, 0), - "GroupOrder": (16, {}, 1), - } - -# the name 'ISAKMPTransformTypes' is actually a misnomer (since the table -# holds info for all ISAKMP Attribute types, not just transforms, but we'll -# keep it for backwards compatibility... for now at least -ISAKMPTransformTypes = ISAKMPAttributeTypes - -ISAKMPTransformNum = {} -for n in ISAKMPTransformTypes: - val = ISAKMPTransformTypes[n] - tmp = {} - for e in val[1]: - tmp[val[1][e]] = e - ISAKMPTransformNum[val[0]] = (n,tmp, val[2]) -del(n) -del(e) -del(tmp) -del(val) - - -class ISAKMPTransformSetField(StrLenField): - islist=1 - #def type2num(self, (typ,val)): - def type2num(self, typval): - typ = typval[0] - val = typval[1] - type_val,enc_dict,tlv = ISAKMPTransformTypes.get(typval[0], (typval[0],{},0)) - val = enc_dict.get(val, val) - s = b"" - if (val & ~0xffff): - if not tlv: - warning("%r should not be TLV but is too big => using TLV encoding" % typval[0]) - n = 0 - while val: - s = bytes([(val&0xff)])+s - val >>= 8 - n += 1 - val = n - else: - type_val |= 0x8000 - return struct.pack("!HH",type_val, val)+s - def num2type(self, typ, enc): - val = ISAKMPTransformNum.get(typ,(typ,{})) - enc = val[1].get(enc,enc) - return (val[0],enc) - def i2m(self, pkt, i): - if i is None: - return b"" - i = map(self.type2num, i) - return b"".join(i) - def m2i(self, pkt, m): - # I try to ensure that we don't read off the end of our packet based - # on bad length fields we're provided in the packet. There are still - # conditions where struct.unpack() may not get enough packet data, but - # worst case that should result in broken attributes (which would - # be expected). (wam) - lst = [] - while len(m) >= 4: - trans_type, = struct.unpack("!H", m[:2]) - is_tlv = not (trans_type & 0x8000) - if is_tlv: - # We should probably check to make sure the attribute type we - # are looking at is allowed to have a TLV format and issue a - # warning if we're given an TLV on a basic attribute. - value_len, = struct.unpack("!H", m[2:4]) - if value_len+4 > len(m): - warning("Bad length for ISAKMP tranform type=%#6x" % trans_type) - value = m[4:4+value_len] - r = 0 - for i in struct.unpack("!%s" % ("B"*len(value),), value): - r = (r << 8) | i - value = r - #value = reduce(lambda x,y: (x<<8)|y, struct.unpack("!%s" % ("B"*len(value),), value),0) - else: - trans_type &= 0x7fff - value_len=0 - value, = struct.unpack("!H", m[2:4]) - m=m[4+value_len:] - lst.append(self.num2type(trans_type, value)) - if len(m) > 0: - warning("Extra bytes after ISAKMP transform dissection [%r]" % m) - return lst - - -ISAKMP_payload_type = ["None","SA","Proposal","Transform","KE","ID","CERT","CR","Hash", - "SIG","Nonce","Notification","Delete","VendorID"] - -ISAKMP_exchange_type = ["None","base","identity prot.", - "auth only", "aggressive", "info"] - - -class ISAKMP_class(Packet): - def guess_payload_class(self, payload): - np = self.next_payload - if np == 0: - return conf.raw_layer - elif np < len(ISAKMP_payload_type): - pt = ISAKMP_payload_type[np] - return globals().get("ISAKMP_payload_%s" % pt, ISAKMP_payload) - else: - return ISAKMP_payload - - -class ISAKMP(ISAKMP_class): # rfc2408 - name = "ISAKMP" - fields_desc = [ - StrFixedLenField("init_cookie","",8), - StrFixedLenField("resp_cookie","",8), - ByteEnumField("next_payload",0,ISAKMP_payload_type), - XByteField("version",0x10), - ByteEnumField("exch_type",0,ISAKMP_exchange_type), - FlagsField("flags",0, 8, ["encryption","commit","auth_only","res3","res4","res5","res6","res7"]), # XXX use a Flag field - IntField("id",0), - IntField("length",None) - ] - - def guess_payload_class(self, payload): - if self.flags & 1: - return conf.raw_layer - return ISAKMP_class.guess_payload_class(self, payload) - - def answers(self, other): - if isinstance(other, ISAKMP): - if other.init_cookie == self.init_cookie: - return 1 - return 0 - def post_build(self, p, pay): - p += pay - if self.length is None: - p = p[:24]+struct.pack("!I",len(p))+p[28:] - return p - - - - -class ISAKMP_payload_Transform(ISAKMP_class): - name = "IKE Transform" - fields_desc = [ - ByteEnumField("next_payload",None,ISAKMP_payload_type), - ByteField("res",0), -# ShortField("len",None), - ShortField("length",None), - ByteField("num",None), - ByteEnumField("id",1,{1:"KEY_IKE"}), - ShortField("res2",0), - ISAKMPTransformSetField("transforms",None,length_from=lambda x:x.length-8) -# XIntField("enc",0x80010005L), -# XIntField("hash",0x80020002L), -# XIntField("auth",0x80030001L), -# XIntField("group",0x80040002L), -# XIntField("life_type",0x800b0001L), -# XIntField("durationh",0x000c0004L), -# XIntField("durationl",0x00007080L), - ] - def post_build(self, p, pay): - if self.length is None: - l = len(p) - p = p[:2]+bytes([((l>>8)&0xff),(l&0xff)])+p[4:] - p += pay - return p - - - - -class ISAKMP_payload_Proposal(ISAKMP_class): - name = "IKE proposal" -# ISAKMP_payload_type = 0 - fields_desc = [ - ByteEnumField("next_payload",None,ISAKMP_payload_type), - ByteField("res",0), - FieldLenField("length",None,"trans","H", adjust=lambda pkt,x:x+8), - ByteField("proposal",1), - ByteEnumField("proto",1,{1:"ISAKMP"}), - FieldLenField("SPIsize",None,"SPI","B"), - ByteField("trans_nb",None), - StrLenField("SPI","",length_from=lambda x:x.SPIsize), - PacketLenField("trans",conf.raw_layer(),ISAKMP_payload_Transform,length_from=lambda x:x.length-8), - ] - - -class ISAKMP_payload(ISAKMP_class): - name = "ISAKMP payload" - fields_desc = [ - ByteEnumField("next_payload",None,ISAKMP_payload_type), - ByteField("res",0), - FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4), - StrLenField("load","",length_from=lambda x:x.length-4), - ] - - -class ISAKMP_payload_VendorID(ISAKMP_class): - name = "ISAKMP Vendor ID" - overload_fields = { ISAKMP: { "next_payload":13 }} - fields_desc = [ - ByteEnumField("next_payload",None,ISAKMP_payload_type), - ByteField("res",0), - FieldLenField("length",None,"vendorID","H", adjust=lambda pkt,x:x+4), - StrLenField("vendorID","",length_from=lambda x:x.length-4), - ] - -class ISAKMP_payload_SA(ISAKMP_class): - name = "ISAKMP SA" - overload_fields = { ISAKMP: { "next_payload":1 }} - fields_desc = [ - ByteEnumField("next_payload",None,ISAKMP_payload_type), - ByteField("res",0), - FieldLenField("length",None,"prop","H", adjust=lambda pkt,x:x+12), - IntEnumField("DOI",1,{1:"IPSEC"}), - IntEnumField("situation",1,{1:"identity"}), - PacketLenField("prop",conf.raw_layer(),ISAKMP_payload_Proposal,length_from=lambda x:x.length-12), - ] - -class ISAKMP_payload_Nonce(ISAKMP_class): - name = "ISAKMP Nonce" - overload_fields = { ISAKMP: { "next_payload":10 }} - fields_desc = [ - ByteEnumField("next_payload",None,ISAKMP_payload_type), - ByteField("res",0), - FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4), - StrLenField("load","",length_from=lambda x:x.length-4), - ] - -class ISAKMP_payload_KE(ISAKMP_class): - name = "ISAKMP Key Exchange" - overload_fields = { ISAKMP: { "next_payload":4 }} - fields_desc = [ - ByteEnumField("next_payload",None,ISAKMP_payload_type), - ByteField("res",0), - FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4), - StrLenField("load","",length_from=lambda x:x.length-4), - ] - -class ISAKMP_payload_ID(ISAKMP_class): - name = "ISAKMP Identification" - overload_fields = { ISAKMP: { "next_payload":5 }} - fields_desc = [ - ByteEnumField("next_payload",None,ISAKMP_payload_type), - ByteField("res",0), - FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8), - ByteEnumField("IDtype",1,{1:"IPv4_addr", 11:"Key"}), - ByteEnumField("ProtoID",0,{0:"Unused"}), - ShortEnumField("Port",0,{0:"Unused"}), -# IPField("IdentData","127.0.0.1"), - StrLenField("load","",length_from=lambda x:x.length-8), - ] - - - -class ISAKMP_payload_Hash(ISAKMP_class): - name = "ISAKMP Hash" - overload_fields = { ISAKMP: { "next_payload":8 }} - fields_desc = [ - ByteEnumField("next_payload",None,ISAKMP_payload_type), - ByteField("res",0), - FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+4), - StrLenField("load","",length_from=lambda x:x.length-4), - ] - - - -ISAKMP_payload_type_overload = {} -for i in range(len(ISAKMP_payload_type)): - name = "ISAKMP_payload_%s" % ISAKMP_payload_type[i] - if name in globals(): - ISAKMP_payload_type_overload[globals()[name]] = {"next_payload":i} - -del(i) -del(name) -ISAKMP_class.overload_fields = ISAKMP_payload_type_overload.copy() - - -bind_layers( UDP, ISAKMP, dport=500, sport=500) -def ikescan(ip): - return sr(IP(dst=ip)/UDP()/ISAKMP(init_cookie=RandString(8), - exch_type=2)/ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal())) - diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/l2.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/l2.py deleted file mode 100644 index 0d0a1c78..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/l2.py +++ /dev/null @@ -1,543 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -Classes and functions for layer 2 protocols. -""" - -import os,struct,time -from scapy.base_classes import Net -from scapy.config import conf -from scapy.packet import * -from scapy.ansmachine import * -from scapy.plist import SndRcvList -from scapy.fields import * -from scapy.sendrecv import srp,srp1 -from scapy.arch import get_if_hwaddr - - - - -################# -## Tools ## -################# - - -class Neighbor: - def __init__(self): - self.resolvers = {} - - def register_l3(self, l2, l3, resolve_method): - self.resolvers[l2,l3]=resolve_method - - def resolve(self, l2inst, l3inst): - k = l2inst.__class__,l3inst.__class__ - if k in self.resolvers: - return self.resolvers[k](l2inst,l3inst) - - def __repr__(self): - return "\n".join("%-15s -> %-15s" % (l2.__name__, l3.__name__) for l2,l3 in self.resolvers) - -conf.neighbor = Neighbor() - -conf.netcache.new_cache("arp_cache", 120) # cache entries expire after 120s - - -@conf.commands.register -def getmacbyip(ip, chainCC=0): - """Return MAC address corresponding to a given IP address""" - if isinstance(ip,Net): - ip = next(iter(ip)) - ip = inet_ntoa(inet_aton(ip)) - tmp = inet_aton(ip) - if (tmp[0] & 0xf0) == 0xe0: # mcast @ - return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3]) - iff,a,gw = conf.route.route(ip) - if ( (iff == "lo") or (ip == conf.route.get_if_bcast(iff)) ): - return "ff:ff:ff:ff:ff:ff" - if gw != "0.0.0.0": - ip = gw - - mac = conf.netcache.arp_cache.get(ip) - if mac: - return mac - - res = srp1(Ether(dst=ETHER_BROADCAST)/ARP(op="who-has", pdst=ip), - type=ETH_P_ARP, - iface = iff, - timeout=2, - verbose=0, - chainCC=chainCC, - nofilter=1) - if res is not None: - mac = res.payload.hwsrc - conf.netcache.arp_cache[ip] = mac - return mac - return None - - - -### Fields - -class DestMACField(MACField): - def __init__(self, name): - MACField.__init__(self, name, None) - def i2h(self, pkt, x): - if x is None: - x = conf.neighbor.resolve(pkt,pkt.payload) - if x is None: - x = "ff:ff:ff:ff:ff:ff" - warning("Mac address to reach destination not found. Using broadcast.") - return MACField.i2h(self, pkt, x) - def i2m(self, pkt, x): - return MACField.i2m(self, pkt, self.i2h(pkt, x)) - -class SourceMACField(MACField): - def __init__(self, name): - MACField.__init__(self, name, None) - def i2h(self, pkt, x): - if x is None: - iff,a,gw = pkt.payload.route() - if iff: - try: - x = get_if_hwaddr(iff) - except: - pass - if x is None: - x = "00:00:00:00:00:00" - return MACField.i2h(self, pkt, x) - def i2m(self, pkt, x): - return MACField.i2m(self, pkt, self.i2h(pkt, x)) - -class ARPSourceMACField(MACField): - def __init__(self, name): - MACField.__init__(self, name, None) - def i2h(self, pkt, x): - if x is None: - iff,a,gw = pkt.route() - if iff: - try: - x = get_if_hwaddr(iff) - except: - pass - if x is None: - x = "00:00:00:00:00:00" - return MACField.i2h(self, pkt, x) - def i2m(self, pkt, x): - return MACField.i2m(self, pkt, self.i2h(pkt, x)) - - - -### Layers - - -class Ether(Packet): - name = "Ethernet" - fields_desc = [ MACField("dst","00:00:00:01:00:00"), - MACField("src","00:00:00:02:00:00"), - XShortEnumField("type", 0x9000, ETHER_TYPES) ] - def hashret(self): - return struct.pack("H",self.type)+self.payload.hashret() - def answers(self, other): - if isinstance(other,Ether): - if self.type == other.type: - return self.payload.answers(other.payload) - return 0 - def mysummary(self): - return self.sprintf("%src% > %dst% (%type%)") - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 14: - if struct.unpack("!H", _pkt[12:14])[0] <= 1500: - return Dot3 - return cls - - -class Dot3(Packet): - name = "802.3" - fields_desc = [ DestMACField("dst"), - MACField("src", ETHER_ANY), - LenField("len", None, "H") ] - def extract_padding(self,s): - l = self.len - return s[:l],s[l:] - def answers(self, other): - if isinstance(other,Dot3): - return self.payload.answers(other.payload) - return 0 - def mysummary(self): - return "802.3 %s > %s" % (self.src, self.dst) - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 14: - if struct.unpack("!H", _pkt[12:14])[0] > 1500: - return Ether - return cls - - -class LLC(Packet): - name = "LLC" - fields_desc = [ XByteField("dsap", 0x00), - XByteField("ssap", 0x00), - ByteField("ctrl", 0) ] - -conf.neighbor.register_l3(Ether, LLC, lambda l2,l3: conf.neighbor.resolve(l2,l3.payload)) -conf.neighbor.register_l3(Dot3, LLC, lambda l2,l3: conf.neighbor.resolve(l2,l3.payload)) - - -class CookedLinux(Packet): - name = "cooked linux" - fields_desc = [ ShortEnumField("pkttype",0, {0: "unicast", - 4:"sent-by-us"}), #XXX incomplete - XShortField("lladdrtype",512), - ShortField("lladdrlen",0), - StrFixedLenField("src","",8), - XShortEnumField("proto",0x800,ETHER_TYPES) ] - - - -class SNAP(Packet): - name = "SNAP" - fields_desc = [ X3BytesField("OUI",0x000000), - XShortEnumField("code", 0x000, ETHER_TYPES) ] - -conf.neighbor.register_l3(Dot3, SNAP, lambda l2,l3: conf.neighbor.resolve(l2,l3.payload)) - - -class Dot1Q(Packet): - name = "802.1Q" - aliastypes = [ Ether ] - fields_desc = [ BitField("prio", 0, 3), - BitField("id", 0, 1), - BitField("vlan", 1, 12), - XShortEnumField("type", 0x0000, ETHER_TYPES) ] - def answers(self, other): - if isinstance(other,Dot1Q): - if ( (self.type == other.type) and - (self.vlan == other.vlan) ): - return self.payload.answers(other.payload) - else: - return self.payload.answers(other) - return 0 - def default_payload_class(self, pay): - if self.type <= 1500: - return LLC - return conf.raw_layer - def extract_padding(self,s): - if self.type <= 1500: - return s[:self.type],s[self.type:] - return s,None - def mysummary(self): - if isinstance(self.underlayer, Ether): - return self.underlayer.sprintf("802.1q %Ether.src% > %Ether.dst% (%Dot1Q.type%) vlan %Dot1Q.vlan%") - else: - return self.sprintf("802.1q (%Dot1Q.type%) vlan %Dot1Q.vlan%") - - -conf.neighbor.register_l3(Ether, Dot1Q, lambda l2,l3: conf.neighbor.resolve(l2,l3.payload)) - -class STP(Packet): - name = "Spanning Tree Protocol" - fields_desc = [ ShortField("proto", 0), - ByteField("version", 0), - ByteField("bpdutype", 0), - ByteField("bpduflags", 0), - ShortField("rootid", 0), - MACField("rootmac", ETHER_ANY), - IntField("pathcost", 0), - ShortField("bridgeid", 0), - MACField("bridgemac", ETHER_ANY), - ShortField("portid", 0), - BCDFloatField("age", 1), - BCDFloatField("maxage", 20), - BCDFloatField("hellotime", 2), - BCDFloatField("fwddelay", 15) ] - - -class EAPOL(Packet): - name = "EAPOL" - fields_desc = [ ByteField("version", 1), - ByteEnumField("type", 0, ["EAP_PACKET", "START", "LOGOFF", "KEY", "ASF"]), - LenField("len", None, "H") ] - - EAP_PACKET= 0 - START = 1 - LOGOFF = 2 - KEY = 3 - ASF = 4 - def extract_padding(self, s): - l = self.len - return s[:l],s[l:] - def hashret(self): - #return chr(self.type)+self.payload.hashret() - return bytes([self.type])+self.payload.hashret() - def answers(self, other): - if isinstance(other,EAPOL): - if ( (self.type == self.EAP_PACKET) and - (other.type == self.EAP_PACKET) ): - return self.payload.answers(other.payload) - return 0 - def mysummary(self): - return self.sprintf("EAPOL %EAPOL.type%") - - -class EAP(Packet): - name = "EAP" - fields_desc = [ ByteEnumField("code", 4, {1:"REQUEST",2:"RESPONSE",3:"SUCCESS",4:"FAILURE"}), - ByteField("id", 0), - ShortField("len",None), - ConditionalField(ByteEnumField("type",0, {1:"ID",4:"MD5"}), lambda pkt:pkt.code not in [EAP.SUCCESS, EAP.FAILURE]) - - ] - - REQUEST = 1 - RESPONSE = 2 - SUCCESS = 3 - FAILURE = 4 - TYPE_ID = 1 - TYPE_MD5 = 4 - def answers(self, other): - if isinstance(other,EAP): - if self.code == self.REQUEST: - return 0 - elif self.code == self.RESPONSE: - if ( (other.code == self.REQUEST) and - (other.type == self.type) ): - return 1 - elif other.code == self.RESPONSE: - return 1 - return 0 - - def post_build(self, p, pay): - if self.len is None: - l = len(p)+len(pay) - p = p[:2]+bytes([((l>>8)&0xff),(l&0xff)])+p[4:] - return p+pay - - -class ARP(Packet): - name = "ARP" - fields_desc = [ XShortField("hwtype", 0x0001), - XShortEnumField("ptype", 0x0800, ETHER_TYPES), - ByteField("hwlen", 6), - ByteField("plen", 4), - ShortEnumField("op", 1, {"who-has":1, "is-at":2, "RARP-req":3, "RARP-rep":4, "Dyn-RARP-req":5, "Dyn-RAR-rep":6, "Dyn-RARP-err":7, "InARP-req":8, "InARP-rep":9}), - ARPSourceMACField("hwsrc"), - SourceIPField("psrc","pdst"), - MACField("hwdst", ETHER_ANY), - IPField("pdst", "0.0.0.0") ] - who_has = 1 - is_at = 2 - def answers(self, other): - if isinstance(other,ARP): - if ( (self.op == self.is_at) and - (other.op == self.who_has) and - (self.psrc == other.pdst) ): - return 1 - return 0 - def route(self): - dst = self.pdst - if isinstance(dst,Gen): - dst = next(iter(dst)) - return conf.route.route(dst) - def extract_padding(self, s): - return b"",s - def mysummary(self): - if self.op == self.is_at: - return self.sprintf("ARP is at %hwsrc% says %psrc%") - elif self.op == self.who_has: - return self.sprintf("ARP who has %pdst% says %psrc%") - else: - return self.sprintf("ARP %op% %psrc% > %pdst%") - -conf.neighbor.register_l3(Ether, ARP, lambda l2,l3: getmacbyip(l3.pdst)) - -class GRErouting(Packet): - name = "GRE routing informations" - fields_desc = [ ShortField("address_family",0), - ByteField("SRE_offset", 0), - FieldLenField("SRE_len", None, "routing_info", "B"), - StrLenField("routing_info", "", "SRE_len"), - ] - - -class GRE(Packet): - name = "GRE" - fields_desc = [ BitField("chksum_present",0,1), - BitField("routing_present",0,1), - BitField("key_present",0,1), - BitField("seqnum_present",0,1), - BitField("strict_route_source",0,1), - BitField("recursion_control",0,3), - BitField("flags",0,5), - BitField("version",0,3), - XShortEnumField("proto", 0x0000, ETHER_TYPES), - ConditionalField(XShortField("chksum",None), lambda pkt:pkt.chksum_present==1 or pkt.routing_present==1), - ConditionalField(XShortField("offset",None), lambda pkt:pkt.chksum_present==1 or pkt.routing_present==1), - ConditionalField(XIntField("key",None), lambda pkt:pkt.key_present==1), - ConditionalField(XIntField("seqence_number",None), lambda pkt:pkt.seqnum_present==1), - ] - def post_build(self, p, pay): - p += pay - if self.chksum_present and self.chksum is None: - c = checksum(p) - p = p[:4]+bytes([((c>>8)&0xff),(c&0xff)])+p[6:] - return p - - - - -bind_layers( Dot3, LLC, ) -bind_layers( Ether, LLC, type=122) -bind_layers( Ether, Dot1Q, type=33024) -bind_layers( Ether, Ether, type=1) -bind_layers( Ether, ARP, type=2054) -bind_layers( Ether, EAPOL, type=34958) -bind_layers( Ether, EAPOL, dst='01:80:c2:00:00:03', type=34958) -bind_layers( CookedLinux, LLC, proto=122) -bind_layers( CookedLinux, Dot1Q, proto=33024) -bind_layers( CookedLinux, Ether, proto=1) -bind_layers( CookedLinux, ARP, proto=2054) -bind_layers( CookedLinux, EAPOL, proto=34958) -bind_layers( GRE, LLC, proto=122) -bind_layers( GRE, Dot1Q, proto=33024) -bind_layers( GRE, Ether, proto=1) -bind_layers( GRE, ARP, proto=2054) -bind_layers( GRE, EAPOL, proto=34958) -bind_layers( GRE, GRErouting, { "routing_present" : 1 } ) -bind_layers( GRErouting, conf.raw_layer,{ "address_family" : 0, "SRE_len" : 0 }) -bind_layers( GRErouting, GRErouting, { } ) -bind_layers( EAPOL, EAP, type=0) -bind_layers( LLC, STP, dsap=66, ssap=66, ctrl=3) -bind_layers( LLC, SNAP, dsap=170, ssap=170, ctrl=3) -bind_layers( SNAP, Dot1Q, code=33024) -bind_layers( SNAP, Ether, code=1) -bind_layers( SNAP, ARP, code=2054) -bind_layers( SNAP, EAPOL, code=34958) -bind_layers( SNAP, STP, code=267) - -conf.l2types.register(ARPHDR_ETHER, Ether) -conf.l2types.register_num2layer(ARPHDR_METRICOM, Ether) -conf.l2types.register_num2layer(ARPHDR_LOOPBACK, Ether) -conf.l2types.register_layer2num(ARPHDR_ETHER, Dot3) -conf.l2types.register(144, CookedLinux) # called LINUX_IRDA, similar to CookedLinux -conf.l2types.register(113, CookedLinux) - -conf.l3types.register(ETH_P_ARP, ARP) - - - - -### Technics - - - -@conf.commands.register -def arpcachepoison(target, victim, interval=60): - """Poison target's cache with (your MAC,victim's IP) couple -arpcachepoison(target, victim, [interval=60]) -> None -""" - tmac = getmacbyip(target) - p = Ether(dst=tmac)/ARP(op="who-has", psrc=victim, pdst=target) - try: - while 1: - sendp(p, iface_hint=target) - if conf.verb > 1: - os.write(1,b".") - time.sleep(interval) - except KeyboardInterrupt: - pass - - -class ARPingResult(SndRcvList): - def __init__(self, res=None, name="ARPing", stats=None): - SndRcvList.__init__(self, res, name, stats) - - def show(self): - for s,r in self.res: - print(r.sprintf("%19s,Ether.src% %ARP.psrc%")) - - - -@conf.commands.register -def arping(net, timeout=2, cache=0, verbose=None, **kargs): - """Send ARP who-has requests to determine which hosts are up -arping(net, [cache=0,] [iface=conf.iface,] [verbose=conf.verb]) -> None -Set cache=True if you want arping to modify internal ARP-Cache""" - if verbose is None: - verbose = conf.verb - ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=net), verbose=verbose, - filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs) - ans = ARPingResult(ans.res) - - if cache and ans is not None: - for pair in ans: - conf.netcache.arp_cache[pair[1].psrc] = (pair[1].hwsrc, time.time()) - if verbose: - ans.show() - return ans,unans - -@conf.commands.register -def is_promisc(ip, fake_bcast="ff:ff:00:00:00:00",**kargs): - """Try to guess if target is in Promisc mode. The target is provided by its ip.""" - - responses = srp1(Ether(dst=fake_bcast) / ARP(op="who-has", pdst=ip),type=ETH_P_ARP, iface_hint=ip, timeout=1, verbose=0,**kargs) - - return responses is not None - -@conf.commands.register -def promiscping(net, timeout=2, fake_bcast="ff:ff:ff:ff:ff:fe", **kargs): - """Send ARP who-has requests to determine which hosts are in promiscuous mode - promiscping(net, iface=conf.iface)""" - ans,unans = srp(Ether(dst=fake_bcast)/ARP(pdst=net), - filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs) - ans = ARPingResult(ans.res, name="PROMISCPing") - - ans.display() - return ans,unans - - -class ARP_am(AnsweringMachine): - function_name="farpd" - filter = "arp" - send_function = staticmethod(sendp) - - def parse_options(self, IP_addr=None, iface=None, ARP_addr=None): - self.IP_addr=IP_addr - self.iface=iface - self.ARP_addr=ARP_addr - - def is_request(self, req): - return (req.haslayer(ARP) and - req.getlayer(ARP).op == 1 and - (self.IP_addr == None or self.IP_addr == req.getlayer(ARP).pdst)) - - def make_reply(self, req): - ether = req.getlayer(Ether) - arp = req.getlayer(ARP) - iff,a,gw = conf.route.route(arp.psrc) - if self.iface != None: - iff = iface - ARP_addr = self.ARP_addr - IP_addr = arp.pdst - resp = Ether(dst=ether.src, - src=ARP_addr)/ARP(op="is-at", - hwsrc=ARP_addr, - psrc=IP_addr, - hwdst=arp.hwsrc, - pdst=arp.pdst) - return resp - - def sniff(self): - sniff(iface=self.iface, **self.optsniff) - -@conf.commands.register -def etherleak(target, **kargs): - """Exploit Etherleak flaw""" - return srpflood(Ether()/ARP(pdst=target), - prn=lambda a: conf.padding_layer in a[1] and hexstr(a[1][conf.padding_layer].load), - filter="arp", **kargs) - - diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/l2tp.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/l2tp.py deleted file mode 100644 index 0b56db21..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/l2tp.py +++ /dev/null @@ -1,36 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -L2TP (Layer 2 Tunneling Protocol) for VPNs. - -[RFC 2661] -""" - -import struct - -from scapy.packet import * -from scapy.fields import * -from scapy.layers.inet import UDP -from scapy.layers.ppp import PPP - -class L2TP(Packet): - fields_desc = [ ShortEnumField("pkt_type",2,{2:"data"}), - ShortField("len", None), - ShortField("tunnel_id", 0), - ShortField("session_id", 0), - ShortField("ns", 0), - ShortField("nr", 0), - ShortField("offset", 0) ] - - def post_build(self, pkt, pay): - if self.len is None: - l = len(pkt)+len(pay) - pkt = pkt[:2]+struct.pack("!H", l)+pkt[4:] - return pkt+pay - - -bind_layers( UDP, L2TP, sport=1701, dport=1701) -bind_layers( L2TP, PPP, ) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/llmnr.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/llmnr.py deleted file mode 100644 index 65ecad41..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/llmnr.py +++ /dev/null @@ -1,65 +0,0 @@ -from scapy.fields import * -from scapy.packet import * -from scapy.layers.inet import UDP -from scapy.layers.dns import DNSQRField, DNSRRField, DNSRRCountField - -""" -LLMNR (Link Local Multicast Node Resolution). - -[RFC 4795] -""" - -############################################################################# -### LLMNR (RFC4795) ### -############################################################################# -# LLMNR is based on the DNS packet format (RFC1035 Section 4) -# RFC also envisions LLMNR over TCP. Like vista, we don't support it -- arno - -_LLMNR_IPv6_mcast_Addr = "FF02:0:0:0:0:0:1:3" -_LLMNR_IPv4_mcast_addr = "224.0.0.252" - -class LLMNRQuery(Packet): - name = "Link Local Multicast Node Resolution - Query" - fields_desc = [ ShortField("id", 0), - BitField("qr", 0, 1), - BitEnumField("opcode", 0, 4, { 0:"QUERY" }), - BitField("c", 0, 1), - BitField("tc", 0, 2), - BitField("z", 0, 4), - BitEnumField("rcode", 0, 4, { 0:"ok" }), - DNSRRCountField("qdcount", None, "qd"), - DNSRRCountField("ancount", None, "an"), - DNSRRCountField("nscount", None, "ns"), - DNSRRCountField("arcount", None, "ar"), - DNSQRField("qd", "qdcount"), - DNSRRField("an", "ancount"), - DNSRRField("ns", "nscount"), - DNSRRField("ar", "arcount",0)] - overload_fields = {UDP: {"sport": 5355, "dport": 5355 }} - def hashret(self): - return struct.pack("!H", self.id) - -class LLMNRResponse(LLMNRQuery): - name = "Link Local Multicast Node Resolution - Response" - qr = 1 - def answers(self, other): - return (isinstance(other, LLMNRQuery) and - self.id == other.id and - self.qr == 1 and - other.qr == 0) - -def _llmnr_dispatcher(x, *args, **kargs): - cls = conf.raw_layer - if len(x) >= 3: - if (ord(x[4]) & 0x80): # Response - cls = LLMNRResponse - else: # Query - cls = LLMNRQuery - return cls(x, *args, **kargs) - -bind_bottom_up(UDP, _llmnr_dispatcher, { "dport": 5355 }) -bind_bottom_up(UDP, _llmnr_dispatcher, { "sport": 5355 }) - -# LLMNRQuery(id=RandShort(), qd=DNSQR(qname="vista."))) - - diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/mgcp.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/mgcp.py deleted file mode 100644 index 5d8a064e..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/mgcp.py +++ /dev/null @@ -1,45 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -MGCP (Media Gateway Control Protocol) - -[RFC 2805] -""" - -from scapy.packet import * -from scapy.fields import * -from scapy.layers.inet import UDP - -class MGCP(Packet): - name = "MGCP" - longname = "Media Gateway Control Protocol" - fields_desc = [ StrStopField("verb","AUEP"," ", -1), - StrFixedLenField("sep1"," ",1), - StrStopField("transaction_id","1234567"," ", -1), - StrFixedLenField("sep2"," ",1), - StrStopField("endpoint","dummy@dummy.net"," ", -1), - StrFixedLenField("sep3"," ",1), - StrStopField("version","MGCP 1.0 NCS 1.0","\x0a", -1), - StrFixedLenField("sep4","\x0a",1), - ] - - -#class MGCP(Packet): -# name = "MGCP" -# longname = "Media Gateway Control Protocol" -# fields_desc = [ ByteEnumField("type",0, ["request","response","others"]), -# ByteField("code0",0), -# ByteField("code1",0), -# ByteField("code2",0), -# ByteField("code3",0), -# ByteField("code4",0), -# IntField("trasid",0), -# IntField("req_time",0), -# ByteField("is_duplicate",0), -# ByteField("req_available",0) ] -# -bind_layers( UDP, MGCP, dport=2727) -bind_layers( UDP, MGCP, sport=2727) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/mobileip.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/mobileip.py deleted file mode 100644 index bbaa8ce7..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/mobileip.py +++ /dev/null @@ -1,47 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -Mobile IP. -""" - -from scapy.fields import * -from scapy.packet import * -from scapy.layers.inet import IP,UDP - - -class MobileIP(Packet): - name = "Mobile IP (RFC3344)" - fields_desc = [ ByteEnumField("type", 1, {1:"RRQ", 3:"RRP"}) ] - -class MobileIPRRQ(Packet): - name = "Mobile IP Registration Request (RFC3344)" - fields_desc = [ XByteField("flags", 0), - ShortField("lifetime", 180), - IPField("homeaddr", "0.0.0.0"), - IPField("haaddr", "0.0.0.0"), - IPField("coaddr", "0.0.0.0"), - LongField("id", 0), ] - -class MobileIPRRP(Packet): - name = "Mobile IP Registration Reply (RFC3344)" - fields_desc = [ ByteField("code", 0), - ShortField("lifetime", 180), - IPField("homeaddr", "0.0.0.0"), - IPField("haaddr", "0.0.0.0"), - LongField("id", 0), ] - -class MobileIPTunnelData(Packet): - name = "Mobile IP Tunnel Data Message (RFC3519)" - fields_desc = [ ByteField("nexthdr", 4), - ShortField("res", 0) ] - - -bind_layers( UDP, MobileIP, sport=434) -bind_layers( UDP, MobileIP, dport=434) -bind_layers( MobileIP, MobileIPRRQ, type=1) -bind_layers( MobileIP, MobileIPRRP, type=3) -bind_layers( MobileIP, MobileIPTunnelData, type=4) -bind_layers( MobileIPTunnelData, IP, nexthdr=4) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/netbios.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/netbios.py deleted file mode 100644 index f06e9307..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/netbios.py +++ /dev/null @@ -1,222 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -NetBIOS over TCP/IP - -[RFC 1001/1002] -""" - -import struct -from scapy.packet import * -from scapy.fields import * -from scapy.layers.inet import UDP,TCP -from scapy.layers.l2 import SourceMACField - -class NetBIOS_DS(Packet): - name = "NetBIOS datagram service" - fields_desc = [ - ByteEnumField("type",17, {17:"direct_group"}), - ByteField("flags",0), - XShortField("id",0), - IPField("src","127.0.0.1"), - ShortField("sport",138), - ShortField("len",None), - ShortField("ofs",0), - NetBIOSNameField("srcname",""), - NetBIOSNameField("dstname",""), - ] - def post_build(self, p, pay): - p += pay - if self.len is None: - l = len(p)-14 - p = p[:10]+struct.pack("!H", l)+p[12:] - return p - -# ShortField("length",0), -# ShortField("Delimitor",0), -# ByteField("command",0), -# ByteField("data1",0), -# ShortField("data2",0), -# ShortField("XMIt",0), -# ShortField("RSPCor",0), -# StrFixedLenField("dest","",16), -# StrFixedLenField("source","",16), -# -# ] -# - -#NetBIOS - - -# Name Query Request -# Node Status Request -class NBNSQueryRequest(Packet): - name="NBNS query request" - fields_desc = [ShortField("NAME_TRN_ID",0), - ShortField("FLAGS", 0x0110), - ShortField("QDCOUNT",1), - ShortField("ANCOUNT",0), - ShortField("NSCOUNT",0), - ShortField("ARCOUNT",0), - NetBIOSNameField("QUESTION_NAME","windows"), - ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}), - ByteField("NULL",0), - ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}), - ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"})] - -# Name Registration Request -# Name Refresh Request -# Name Release Request or Demand -class NBNSRequest(Packet): - name="NBNS request" - fields_desc = [ShortField("NAME_TRN_ID",0), - ShortField("FLAGS", 0x2910), - ShortField("QDCOUNT",1), - ShortField("ANCOUNT",0), - ShortField("NSCOUNT",0), - ShortField("ARCOUNT",1), - NetBIOSNameField("QUESTION_NAME","windows"), - ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}), - ByteField("NULL",0), - ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}), - ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"}), - ShortEnumField("RR_NAME",0xC00C,{0xC00C:"Label String Pointer to QUESTION_NAME"}), - ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}), - ShortEnumField("RR_CLASS",1,{1:"INTERNET"}), - IntField("TTL", 0), - ShortField("RDLENGTH", 6), - BitEnumField("G",0,1,{0:"Unique name",1:"Group name"}), - BitEnumField("OWNER_NODE_TYPE",00,2,{0:"B node",1:"P node",2:"M node",3:"H node"}), - BitEnumField("UNUSED",0,13,{0:"Unused"}), - IPField("NB_ADDRESS", "127.0.0.1")] - -# Name Query Response -# Name Registration Response -class NBNSQueryResponse(Packet): - name="NBNS query response" - fields_desc = [ShortField("NAME_TRN_ID",0), - ShortField("FLAGS", 0x8500), - ShortField("QDCOUNT",0), - ShortField("ANCOUNT",1), - ShortField("NSCOUNT",0), - ShortField("ARCOUNT",0), - NetBIOSNameField("RR_NAME","windows"), - ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}), - ByteField("NULL",0), - ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}), - ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"}), - IntField("TTL", 0x493e0), - ShortField("RDLENGTH", 6), - ShortField("NB_FLAGS", 0), - IPField("NB_ADDRESS", "127.0.0.1")] - -# Name Query Response (negative) -# Name Release Response -class NBNSQueryResponseNegative(Packet): - name="NBNS query response (negative)" - fields_desc = [ShortField("NAME_TRN_ID",0), - ShortField("FLAGS", 0x8506), - ShortField("QDCOUNT",0), - ShortField("ANCOUNT",1), - ShortField("NSCOUNT",0), - ShortField("ARCOUNT",0), - NetBIOSNameField("RR_NAME","windows"), - ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}), - ByteField("NULL",0), - ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}), - ShortEnumField("RR_CLASS",1,{1:"INTERNET"}), - IntField("TTL",0), - ShortField("RDLENGTH",6), - BitEnumField("G",0,1,{0:"Unique name",1:"Group name"}), - BitEnumField("OWNER_NODE_TYPE",00,2,{0:"B node",1:"P node",2:"M node",3:"H node"}), - BitEnumField("UNUSED",0,13,{0:"Unused"}), - IPField("NB_ADDRESS", "127.0.0.1")] - -# Node Status Response -class NBNSNodeStatusResponse(Packet): - name="NBNS Node Status Response" - fields_desc = [ShortField("NAME_TRN_ID",0), - ShortField("FLAGS", 0x8500), - ShortField("QDCOUNT",0), - ShortField("ANCOUNT",1), - ShortField("NSCOUNT",0), - ShortField("ARCOUNT",0), - NetBIOSNameField("RR_NAME","windows"), - ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}), - ByteField("NULL",0), - ShortEnumField("RR_TYPE",0x21, {0x20:"NB",0x21:"NBSTAT"}), - ShortEnumField("RR_CLASS",1,{1:"INTERNET"}), - IntField("TTL",0), - ShortField("RDLENGTH",83), - ByteField("NUM_NAMES",1)] - -# Service for Node Status Response -class NBNSNodeStatusResponseService(Packet): - name="NBNS Node Status Response Service" - fields_desc = [StrFixedLenField("NETBIOS_NAME","WINDOWS ",15), - ByteEnumField("SUFFIX",0,{0:"workstation",0x03:"messenger service",0x20:"file server service",0x1b:"domain master browser",0x1c:"domain controller", 0x1e:"browser election service"}), - ByteField("NAME_FLAGS",0x4), - ByteEnumField("UNUSED",0,{0:"unused"})] - -# End of Node Status Response packet -class NBNSNodeStatusResponseEnd(Packet): - name="NBNS Node Status Response" - fields_desc = [SourceMACField("MAC_ADDRESS"), - BitField("STATISTICS",0,57*8)] - -# Wait for Acknowledgement Response -class NBNSWackResponse(Packet): - name="NBNS Wait for Acknowledgement Response" - fields_desc = [ShortField("NAME_TRN_ID",0), - ShortField("FLAGS", 0xBC07), - ShortField("QDCOUNT",0), - ShortField("ANCOUNT",1), - ShortField("NSCOUNT",0), - ShortField("ARCOUNT",0), - NetBIOSNameField("RR_NAME","windows"), - ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}), - ByteField("NULL",0), - ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}), - ShortEnumField("RR_CLASS",1,{1:"INTERNET"}), - IntField("TTL", 2), - ShortField("RDLENGTH",2), - BitField("RDATA",10512,16)] #10512=0010100100010000 - -class NBTDatagram(Packet): - name="NBT Datagram Packet" - fields_desc= [ByteField("Type", 0x10), - ByteField("Flags", 0x02), - ShortField("ID", 0), - IPField("SourceIP", "127.0.0.1"), - ShortField("SourcePort", 138), - ShortField("Length", 272), - ShortField("Offset", 0), - NetBIOSNameField("SourceName",b"windows"), - ShortEnumField("SUFFIX1",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}), - ByteField("NULL",0), - NetBIOSNameField("DestinationName",b"windows"), - ShortEnumField("SUFFIX2",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}), - ByteField("NULL",0)] - - -class NBTSession(Packet): - name="NBT Session Packet" - fields_desc= [ByteEnumField("TYPE",0,{0x00:"Session Message",0x81:"Session Request",0x82:"Positive Session Response",0x83:"Negative Session Response",0x84:"Retarget Session Response",0x85:"Session Keepalive"}), - BitField("RESERVED",0x00,7), - BitField("LENGTH",0,17)] - -bind_layers( UDP, NBNSQueryRequest, dport=137) -bind_layers( UDP, NBNSRequest, dport=137) -bind_layers( UDP, NBNSQueryResponse, sport=137) -bind_layers( UDP, NBNSQueryResponseNegative, sport=137) -bind_layers( UDP, NBNSNodeStatusResponse, sport=137) -bind_layers( NBNSNodeStatusResponse, NBNSNodeStatusResponseService, ) -bind_layers( NBNSNodeStatusResponse, NBNSNodeStatusResponseService, ) -bind_layers( NBNSNodeStatusResponseService, NBNSNodeStatusResponseService, ) -bind_layers( NBNSNodeStatusResponseService, NBNSNodeStatusResponseEnd, ) -bind_layers( UDP, NBNSWackResponse, sport=137) -bind_layers( UDP, NBTDatagram, dport=138) -bind_layers( TCP, NBTSession, dport=139) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/netflow.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/netflow.py deleted file mode 100644 index 44567737..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/netflow.py +++ /dev/null @@ -1,48 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -Cisco NetFlow protocol v1 -""" - - -from scapy.fields import * -from scapy.packet import * - -# Cisco Netflow Protocol version 1 -class NetflowHeader(Packet): - name = "Netflow Header" - fields_desc = [ ShortField("version", 1) ] - -class NetflowHeaderV1(Packet): - name = "Netflow Header V1" - fields_desc = [ ShortField("count", 0), - IntField("sysUptime", 0), - IntField("unixSecs", 0), - IntField("unixNanoSeconds", 0) ] - - -class NetflowRecordV1(Packet): - name = "Netflow Record" - fields_desc = [ IPField("ipsrc", "0.0.0.0"), - IPField("ipdst", "0.0.0.0"), - IPField("nexthop", "0.0.0.0"), - ShortField("inputIfIndex", 0), - ShortField("outpuIfIndex", 0), - IntField("dpkts", 0), - IntField("dbytes", 0), - IntField("starttime", 0), - IntField("endtime", 0), - ShortField("srcport", 0), - ShortField("dstport", 0), - ShortField("padding", 0), - ByteField("proto", 0), - ByteField("tos", 0), - IntField("padding1", 0), - IntField("padding2", 0) ] - - -bind_layers( NetflowHeader, NetflowHeaderV1, version=1) -bind_layers( NetflowHeaderV1, NetflowRecordV1, ) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/ntp.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/ntp.py deleted file mode 100644 index 6d11966c..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/ntp.py +++ /dev/null @@ -1,77 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -NTP (Network Time Protocol). -""" - -import time -from scapy.packet import * -from scapy.fields import * -from scapy.layers.inet import UDP - - -# seconds between 01-01-1900 and 01-01-1970 -_NTP_BASETIME = 2208988800 - -class TimeStampField(FixedPointField): - def __init__(self, name, default): - FixedPointField.__init__(self, name, default, 64, 32) - - def i2repr(self, pkt, val): - if val is None: - return "--" - val = self.i2h(pkt,val) - if val < _NTP_BASETIME: - return val - return time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime(val-_NTP_BASETIME)) - - def any2i(self, pkt, val): - if type(val) is str: - return int(time.mktime(time.strptime(val))) + _NTP_BASETIME + 3600 # XXX - return FixedPointField.any2i(self,pkt,val) - - def i2m(self, pkt, val): - if val is None: - val = FixedPointField.any2i(self, pkt, time.time()+_NTP_BASETIME) - return FixedPointField.i2m(self, pkt, val) - - - -class NTP(Packet): - # RFC 1769 - name = "NTP" - fields_desc = [ - BitEnumField('leap', 0, 2, - { 0: 'nowarning', - 1: 'longminute', - 2: 'shortminute', - 3: 'notsync'}), - BitField('version', 3, 3), - BitEnumField('mode', 3, 3, - { 0: 'reserved', - 1: 'sym_active', - 2: 'sym_passive', - 3: 'client', - 4: 'server', - 5: 'broadcast', - 6: 'control', - 7: 'private'}), - BitField('stratum', 2, 8), - BitField('poll', 0xa, 8), ### XXX : it's a signed int - BitField('precision', 0, 8), ### XXX : it's a signed int - FixedPointField('delay', 0, size=32, frac_bits=16), - FixedPointField('dispersion', 0, size=32, frac_bits=16), - IPField('id', "127.0.0.1"), - TimeStampField('ref', 0), - TimeStampField('orig', None), # None means current time - TimeStampField('recv', 0), - TimeStampField('sent', None) - ] - def mysummary(self): - return self.sprintf("NTP v%ir,NTP.version%, %NTP.mode%") - - -bind_layers( UDP, NTP, dport=123, sport=123) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/pflog.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/pflog.py deleted file mode 100644 index a8fc9fe0..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/pflog.py +++ /dev/null @@ -1,59 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -PFLog: OpenBSD PF packet filter logging. -""" - -from scapy.packet import * -from scapy.fields import * -from scapy.layers.inet import IP -if conf.ipv6_enabled: - from scapy.layers.inet6 import IPv6 -from scapy.config import conf - -class PFLog(Packet): - name = "PFLog" - # from OpenBSD src/sys/net/pfvar.h and src/sys/net/if_pflog.h - fields_desc = [ ByteField("hdrlen", 0), - ByteEnumField("addrfamily", 2, {socket.AF_INET: "IPv4", - socket.AF_INET6: "IPv6"}), - ByteEnumField("action", 1, {0: "pass", 1: "drop", - 2: "scrub", 3: "no-scrub", - 4: "nat", 5: "no-nat", - 6: "binat", 7: "no-binat", - 8: "rdr", 9: "no-rdr", - 10: "syn-proxy-drop" }), - ByteEnumField("reason", 0, {0: "match", 1: "bad-offset", - 2: "fragment", 3: "short", - 4: "normalize", 5: "memory", - 6: "bad-timestamp", - 7: "congestion", - 8: "ip-options", - 9: "proto-cksum", - 10: "state-mismatch", - 11: "state-insert", - 12: "state-limit", - 13: "src-limit", - 14: "syn-proxy" }), - StrFixedLenField("iface", "", 16), - StrFixedLenField("ruleset", "", 16), - SignedIntField("rulenumber", 0), - SignedIntField("subrulenumber", 0), - SignedIntField("uid", 0), - IntField("pid", 0), - SignedIntField("ruleuid", 0), - IntField("rulepid", 0), - ByteEnumField("direction", 255, {0: "inout", 1: "in", - 2:"out", 255: "unknown"}), - StrFixedLenField("pad", "\x00\x00\x00", 3 ) ] - def mysummary(self): - return self.sprintf("%PFLog.addrfamily% %PFLog.action% on %PFLog.iface% by rule %PFLog.rulenumber%") - -bind_layers(PFLog, IP, addrfamily=socket.AF_INET) -if conf.ipv6_enabled: - bind_layers(PFLog, IPv6, addrfamily=socket.AF_INET6) - -conf.l2types.register(117, PFLog) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/ppp.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/ppp.py deleted file mode 100644 index 08cf62cd..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/ppp.py +++ /dev/null @@ -1,349 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -PPP (Point to Point Protocol) - -[RFC 1661] -""" - -import struct -from scapy.packet import * -from scapy.layers.l2 import * -from scapy.layers.inet import * -from scapy.fields import * - -class PPPoE(Packet): - name = "PPP over Ethernet" - fields_desc = [ BitField("version", 1, 4), - BitField("type", 1, 4), - ByteEnumField("code", 0, {0:"Session"}), - XShortField("sessionid", 0x0), - ShortField("len", None) ] - - def post_build(self, p, pay): - p += pay - if self.len is None: - l = len(p)-6 - p = p[:4]+struct.pack("!H", l)+p[6:] - return p - -class PPPoED(PPPoE): - name = "PPP over Ethernet Discovery" - fields_desc = [ BitField("version", 1, 4), - BitField("type", 1, 4), - ByteEnumField("code", 0x09, {0x09:"PADI",0x07:"PADO",0x19:"PADR",0x65:"PADS",0xa7:"PADT"}), - XShortField("sessionid", 0x0), - ShortField("len", None) ] - - -_PPP_proto = { 0x0001: "Padding Protocol", - 0x0003: "ROHC small-CID [RFC3095]", - 0x0005: "ROHC large-CID [RFC3095]", - 0x0021: "Internet Protocol version 4", - 0x0023: "OSI Network Layer", - 0x0025: "Xerox NS IDP", - 0x0027: "DECnet Phase IV", - 0x0029: "Appletalk", - 0x002b: "Novell IPX", - 0x002d: "Van Jacobson Compressed TCP/IP", - 0x002f: "Van Jacobson Uncompressed TCP/IP", - 0x0031: "Bridging PDU", - 0x0033: "Stream Protocol (ST-II)", - 0x0035: "Banyan Vines", - 0x0037: "reserved (until 1993) [Typo in RFC1172]", - 0x0039: "AppleTalk EDDP", - 0x003b: "AppleTalk SmartBuffered", - 0x003d: "Multi-Link [RFC1717]", - 0x003f: "NETBIOS Framing", - 0x0041: "Cisco Systems", - 0x0043: "Ascom Timeplex", - 0x0045: "Fujitsu Link Backup and Load Balancing (LBLB)", - 0x0047: "DCA Remote Lan", - 0x0049: "Serial Data Transport Protocol (PPP-SDTP)", - 0x004b: "SNA over 802.2", - 0x004d: "SNA", - 0x004f: "IPv6 Header Compression", - 0x0051: "KNX Bridging Data [ianp]", - 0x0053: "Encryption [Meyer]", - 0x0055: "Individual Link Encryption [Meyer]", - 0x0057: "Internet Protocol version 6 [Hinden]", - 0x0059: "PPP Muxing [RFC3153]", - 0x005b: "Vendor-Specific Network Protocol (VSNP) [RFC3772]", - 0x0061: "RTP IPHC Full Header [RFC3544]", - 0x0063: "RTP IPHC Compressed TCP [RFC3544]", - 0x0065: "RTP IPHC Compressed Non TCP [RFC3544]", - 0x0067: "RTP IPHC Compressed UDP 8 [RFC3544]", - 0x0069: "RTP IPHC Compressed RTP 8 [RFC3544]", - 0x006f: "Stampede Bridging", - 0x0071: "Reserved [Fox]", - 0x0073: "MP+ Protocol [Smith]", - 0x007d: "reserved (Control Escape) [RFC1661]", - 0x007f: "reserved (compression inefficient [RFC1662]", - 0x0081: "Reserved Until 20-Oct-2000 [IANA]", - 0x0083: "Reserved Until 20-Oct-2000 [IANA]", - 0x00c1: "NTCITS IPI [Ungar]", - 0x00cf: "reserved (PPP NLID)", - 0x00fb: "single link compression in multilink [RFC1962]", - 0x00fd: "compressed datagram [RFC1962]", - 0x00ff: "reserved (compression inefficient)", - 0x0201: "802.1d Hello Packets", - 0x0203: "IBM Source Routing BPDU", - 0x0205: "DEC LANBridge100 Spanning Tree", - 0x0207: "Cisco Discovery Protocol [Sastry]", - 0x0209: "Netcs Twin Routing [Korfmacher]", - 0x020b: "STP - Scheduled Transfer Protocol [Segal]", - 0x020d: "EDP - Extreme Discovery Protocol [Grosser]", - 0x0211: "Optical Supervisory Channel Protocol (OSCP)[Prasad]", - 0x0213: "Optical Supervisory Channel Protocol (OSCP)[Prasad]", - 0x0231: "Luxcom", - 0x0233: "Sigma Network Systems", - 0x0235: "Apple Client Server Protocol [Ridenour]", - 0x0281: "MPLS Unicast [RFC3032] ", - 0x0283: "MPLS Multicast [RFC3032]", - 0x0285: "IEEE p1284.4 standard - data packets [Batchelder]", - 0x0287: "ETSI TETRA Network Protocol Type 1 [Nieminen]", - 0x0289: "Multichannel Flow Treatment Protocol [McCann]", - 0x2063: "RTP IPHC Compressed TCP No Delta [RFC3544]", - 0x2065: "RTP IPHC Context State [RFC3544]", - 0x2067: "RTP IPHC Compressed UDP 16 [RFC3544]", - 0x2069: "RTP IPHC Compressed RTP 16 [RFC3544]", - 0x4001: "Cray Communications Control Protocol [Stage]", - 0x4003: "CDPD Mobile Network Registration Protocol [Quick]", - 0x4005: "Expand accelerator protocol [Rachmani]", - 0x4007: "ODSICP NCP [Arvind]", - 0x4009: "DOCSIS DLL [Gaedtke]", - 0x400B: "Cetacean Network Detection Protocol [Siller]", - 0x4021: "Stacker LZS [Simpson]", - 0x4023: "RefTek Protocol [Banfill]", - 0x4025: "Fibre Channel [Rajagopal]", - 0x4027: "EMIT Protocols [Eastham]", - 0x405b: "Vendor-Specific Protocol (VSP) [RFC3772]", - 0x8021: "Internet Protocol Control Protocol", - 0x8023: "OSI Network Layer Control Protocol", - 0x8025: "Xerox NS IDP Control Protocol", - 0x8027: "DECnet Phase IV Control Protocol", - 0x8029: "Appletalk Control Protocol", - 0x802b: "Novell IPX Control Protocol", - 0x802d: "reserved", - 0x802f: "reserved", - 0x8031: "Bridging NCP", - 0x8033: "Stream Protocol Control Protocol", - 0x8035: "Banyan Vines Control Protocol", - 0x8037: "reserved (until 1993)", - 0x8039: "reserved", - 0x803b: "reserved", - 0x803d: "Multi-Link Control Protocol", - 0x803f: "NETBIOS Framing Control Protocol", - 0x8041: "Cisco Systems Control Protocol", - 0x8043: "Ascom Timeplex", - 0x8045: "Fujitsu LBLB Control Protocol", - 0x8047: "DCA Remote Lan Network Control Protocol (RLNCP)", - 0x8049: "Serial Data Control Protocol (PPP-SDCP)", - 0x804b: "SNA over 802.2 Control Protocol", - 0x804d: "SNA Control Protocol", - 0x804f: "IP6 Header Compression Control Protocol", - 0x8051: "KNX Bridging Control Protocol [ianp]", - 0x8053: "Encryption Control Protocol [Meyer]", - 0x8055: "Individual Link Encryption Control Protocol [Meyer]", - 0x8057: "IPv6 Control Protovol [Hinden]", - 0x8059: "PPP Muxing Control Protocol [RFC3153]", - 0x805b: "Vendor-Specific Network Control Protocol (VSNCP) [RFC3772]", - 0x806f: "Stampede Bridging Control Protocol", - 0x8073: "MP+ Control Protocol [Smith]", - 0x8071: "Reserved [Fox]", - 0x807d: "Not Used - reserved [RFC1661]", - 0x8081: "Reserved Until 20-Oct-2000 [IANA]", - 0x8083: "Reserved Until 20-Oct-2000 [IANA]", - 0x80c1: "NTCITS IPI Control Protocol [Ungar]", - 0x80cf: "Not Used - reserved [RFC1661]", - 0x80fb: "single link compression in multilink control [RFC1962]", - 0x80fd: "Compression Control Protocol [RFC1962]", - 0x80ff: "Not Used - reserved [RFC1661]", - 0x8207: "Cisco Discovery Protocol Control [Sastry]", - 0x8209: "Netcs Twin Routing [Korfmacher]", - 0x820b: "STP - Control Protocol [Segal]", - 0x820d: "EDPCP - Extreme Discovery Protocol Ctrl Prtcl [Grosser]", - 0x8235: "Apple Client Server Protocol Control [Ridenour]", - 0x8281: "MPLSCP [RFC3032]", - 0x8285: "IEEE p1284.4 standard - Protocol Control [Batchelder]", - 0x8287: "ETSI TETRA TNP1 Control Protocol [Nieminen]", - 0x8289: "Multichannel Flow Treatment Protocol [McCann]", - 0xc021: "Link Control Protocol", - 0xc023: "Password Authentication Protocol", - 0xc025: "Link Quality Report", - 0xc027: "Shiva Password Authentication Protocol", - 0xc029: "CallBack Control Protocol (CBCP)", - 0xc02b: "BACP Bandwidth Allocation Control Protocol [RFC2125]", - 0xc02d: "BAP [RFC2125]", - 0xc05b: "Vendor-Specific Authentication Protocol (VSAP) [RFC3772]", - 0xc081: "Container Control Protocol [KEN]", - 0xc223: "Challenge Handshake Authentication Protocol", - 0xc225: "RSA Authentication Protocol [Narayana]", - 0xc227: "Extensible Authentication Protocol [RFC2284]", - 0xc229: "Mitsubishi Security Info Exch Ptcl (SIEP) [Seno]", - 0xc26f: "Stampede Bridging Authorization Protocol", - 0xc281: "Proprietary Authentication Protocol [KEN]", - 0xc283: "Proprietary Authentication Protocol [Tackabury]", - 0xc481: "Proprietary Node ID Authentication Protocol [KEN]"} - - -class HDLC(Packet): - fields_desc = [ XByteField("address",0xff), - XByteField("control",0x03) ] - -class PPP(Packet): - name = "PPP Link Layer" - fields_desc = [ ShortEnumField("proto", 0x0021, _PPP_proto) ] - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and _pkt[0] == 0xff: - cls = HDLC - return cls - -_PPP_conftypes = { 1:"Configure-Request", - 2:"Configure-Ack", - 3:"Configure-Nak", - 4:"Configure-Reject", - 5:"Terminate-Request", - 6:"Terminate-Ack", - 7:"Code-Reject", - 8:"Protocol-Reject", - 9:"Echo-Request", - 10:"Echo-Reply", - 11:"Discard-Request", - 14:"Reset-Request", - 15:"Reset-Ack", - } - - -### PPP IPCP stuff (RFC 1332) - -# All IPCP options are defined below (names and associated classes) -_PPP_ipcpopttypes = { 1:"IP-Addresses (Deprecated)", - 2:"IP-Compression-Protocol", - 3:"IP-Address", - 4:"Mobile-IPv4", # not implemented, present for completeness - 129:"Primary-DNS-Address", - 130:"Primary-NBNS-Address", - 131:"Secondary-DNS-Address", - 132:"Secondary-NBNS-Address"} - - -class PPP_IPCP_Option(Packet): - name = "PPP IPCP Option" - fields_desc = [ ByteEnumField("type" , None , _PPP_ipcpopttypes), - FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2), - StrLenField("data", b"", length_from=lambda p:max(0,p.len-2)) ] - def extract_padding(self, pay): - return b"",pay - - registered_options = {} - @classmethod - def register_variant(cls): - cls.registered_options[cls.type.default] = cls - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt: - #o = ord(_pkt[0]) - o = (_pkt[0]) - return cls.registered_options.get(o, cls) - return cls - - -class PPP_IPCP_Option_IPAddress(PPP_IPCP_Option): - name = "PPP IPCP Option: IP Address" - fields_desc = [ ByteEnumField("type" , 3 , _PPP_ipcpopttypes), - FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2), - IPField("data","0.0.0.0"), - ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ] - -class PPP_IPCP_Option_DNS1(PPP_IPCP_Option): - name = "PPP IPCP Option: DNS1 Address" - fields_desc = [ ByteEnumField("type" , 129 , _PPP_ipcpopttypes), - FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2), - IPField("data","0.0.0.0"), - ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ] - -class PPP_IPCP_Option_DNS2(PPP_IPCP_Option): - name = "PPP IPCP Option: DNS2 Address" - fields_desc = [ ByteEnumField("type" , 131 , _PPP_ipcpopttypes), - FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2), - IPField("data","0.0.0.0"), - ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ] - -class PPP_IPCP_Option_NBNS1(PPP_IPCP_Option): - name = "PPP IPCP Option: NBNS1 Address" - fields_desc = [ ByteEnumField("type" , 130 , _PPP_ipcpopttypes), - FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2), - IPField("data","0.0.0.0"), - ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ] - -class PPP_IPCP_Option_NBNS2(PPP_IPCP_Option): - name = "PPP IPCP Option: NBNS2 Address" - fields_desc = [ ByteEnumField("type" , 132 , _PPP_ipcpopttypes), - FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2), - IPField("data","0.0.0.0"), - ConditionalField(StrLenField("garbage","", length_from=lambda pkt:pkt.len-6), lambda p:p.len!=6) ] - - -class PPP_IPCP(Packet): - fields_desc = [ ByteEnumField("code" , 1, _PPP_conftypes), - XByteField("id", 0 ), - FieldLenField("len" , None, fmt="H", length_of="options", adjust=lambda p,x:x+4 ), - PacketListField("options", [], PPP_IPCP_Option, length_from=lambda p:p.len-4,) ] - - -### ECP - -_PPP_ecpopttypes = { 0:"OUI", - 1:"DESE", } - -class PPP_ECP_Option(Packet): - name = "PPP ECP Option" - fields_desc = [ ByteEnumField("type" , None , _PPP_ecpopttypes), - FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+2), - StrLenField("data", "", length_from=lambda p:max(0,p.len-2)) ] - def extract_padding(self, pay): - return b"",pay - - registered_options = {} - @classmethod - def register_variant(cls): - cls.registered_options[cls.type.default] = cls - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt: - #o = ord(_pkt[0]) - o = (_pkt[0]) - return cls.registered_options.get(o, cls) - return cls - -class PPP_ECP_Option_OUI(PPP_ECP_Option): - fields_desc = [ ByteEnumField("type" , 0 , _PPP_ecpopttypes), - FieldLenField("len", None, length_of="data", fmt="B", adjust=lambda p,x:x+6), - StrFixedLenField("oui","",3), - ByteField("subtype",0), - StrLenField("data", "", length_from=lambda p:p.len-6) ] - - - -class PPP_ECP(Packet): - fields_desc = [ ByteEnumField("code" , 1, _PPP_conftypes), - XByteField("id", 0 ), - FieldLenField("len" , None, fmt="H", length_of="options", adjust=lambda p,x:x+4 ), - PacketListField("options", [], PPP_ECP_Option, length_from=lambda p:p.len-4,) ] - -bind_layers( Ether, PPPoED, type=0x8863) -bind_layers( Ether, PPPoE, type=0x8864) -bind_layers( CookedLinux, PPPoED, proto=0x8863) -bind_layers( CookedLinux, PPPoE, proto=0x8864) -bind_layers( PPPoE, PPP, code=0) -bind_layers( HDLC, PPP, ) -bind_layers( PPP, IP, proto=33) -bind_layers( PPP, PPP_IPCP, proto=0x8021) -bind_layers( PPP, PPP_ECP, proto=0x8053) -bind_layers( Ether, PPP_IPCP, type=0x8021) -bind_layers( Ether, PPP_ECP, type=0x8053) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/radius.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/radius.py deleted file mode 100644 index 13239603..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/radius.py +++ /dev/null @@ -1,65 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -RADIUS (Remote Authentication Dial In User Service) -""" - -import struct -from scapy.packet import * -from scapy.fields import * - -class Radius(Packet): - name = "Radius" - fields_desc = [ ByteEnumField("code", 1, {1: "Access-Request", - 2: "Access-Accept", - 3: "Access-Reject", - 4: "Accounting-Request", - 5: "Accounting-Accept", - 6: "Accounting-Status", - 7: "Password-Request", - 8: "Password-Ack", - 9: "Password-Reject", - 10: "Accounting-Message", - 11: "Access-Challenge", - 12: "Status-Server", - 13: "Status-Client", - 21: "Resource-Free-Request", - 22: "Resource-Free-Response", - 23: "Resource-Query-Request", - 24: "Resource-Query-Response", - 25: "Alternate-Resource-Reclaim-Request", - 26: "NAS-Reboot-Request", - 27: "NAS-Reboot-Response", - 29: "Next-Passcode", - 30: "New-Pin", - 31: "Terminate-Session", - 32: "Password-Expired", - 33: "Event-Request", - 34: "Event-Response", - 40: "Disconnect-Request", - 41: "Disconnect-ACK", - 42: "Disconnect-NAK", - 43: "CoA-Request", - 44: "CoA-ACK", - 45: "CoA-NAK", - 50: "IP-Address-Allocate", - 51: "IP-Address-Release", - 253: "Experimental-use", - 254: "Reserved", - 255: "Reserved"} ), - ByteField("id", 0), - ShortField("len", None), - StrFixedLenField("authenticator","",16) ] - def post_build(self, p, pay): - p += pay - l = self.len - if l is None: - l = len(p) - p = p[:2]+struct.pack("!H",l)+p[4:] - return p - - - diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/rip.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/rip.py deleted file mode 100644 index 1507fe5c..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/rip.py +++ /dev/null @@ -1,74 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -RIP (Routing Information Protocol). -""" - -from scapy.packet import * -from scapy.fields import * -from scapy.layers.inet import UDP - -class RIP(Packet): - name = "RIP header" - fields_desc = [ - ByteEnumField("cmd", 1, {1:"req", 2:"resp", 3:"traceOn", 4:"traceOff", - 5:"sun", 6:"trigReq", 7:"trigResp", 8:"trigAck", - 9:"updateReq", 10:"updateResp", 11:"updateAck"}), - ByteField("version", 1), - ShortField("null", 0), - ] - - def guess_payload_class(self, payload): - if payload[:2] == "\xff\xff": - return RIPAuth - else: - return Packet.guess_payload_class(self, payload) - -class RIPEntry(RIP): - name = "RIP entry" - fields_desc = [ - ShortEnumField("AF", 2, {2:"IP"}), - ShortField("RouteTag", 0), - IPField("addr", "0.0.0.0"), - IPField("mask", "0.0.0.0"), - IPField("nextHop", "0.0.0.0"), - IntEnumField("metric", 1, {16:"Unreach"}), - ] - -class RIPAuth(Packet): - name = "RIP authentication" - fields_desc = [ - ShortEnumField("AF", 0xffff, {0xffff:"Auth"}), - ShortEnumField("authtype", 2, {1:"md5authdata", 2:"simple", 3:"md5"}), - ConditionalField(StrFixedLenField("password", None, 16), - lambda pkt: pkt.authtype == 2), - ConditionalField(ShortField("digestoffset", 0), - lambda pkt: pkt.authtype == 3), - ConditionalField(ByteField("keyid", 0), - lambda pkt: pkt.authtype == 3), - ConditionalField(ByteField("authdatalen", 0), - lambda pkt: pkt.authtype == 3), - ConditionalField(IntField("seqnum", 0), - lambda pkt: pkt.authtype == 3), - ConditionalField(StrFixedLenField("zeropad", None, 8), - lambda pkt: pkt.authtype == 3), - ConditionalField(StrLenField("authdata", None, - length_from=lambda pkt: pkt.md5datalen), - lambda pkt: pkt.authtype == 1) - ] - - def pre_dissect(self, s): - if s[2:4] == "\x00\x01": - self.md5datalen = len(s) - 4 - - return s - - -bind_layers( UDP, RIP, sport=520) -bind_layers( UDP, RIP, dport=520) -bind_layers( RIP, RIPEntry, ) -bind_layers( RIPEntry, RIPEntry, ) -bind_layers( RIPAuth, RIPEntry, ) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/rtp.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/rtp.py deleted file mode 100644 index 629dccdd..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/rtp.py +++ /dev/null @@ -1,40 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -RTP (Real-time Transport Protocol). -""" - -from scapy.packet import * -from scapy.fields import * - -_rtp_payload_types = { - # http://www.iana.org/assignments/rtp-parameters - 0: 'G.711 PCMU', 3: 'GSM', - 4: 'G723', 5: 'DVI4', - 6: 'DVI4', 7: 'LPC', - 8: 'PCMA', 9: 'G722', - 10: 'L16', 11: 'L16', - 12: 'QCELP', 13: 'CN', - 14: 'MPA', 15: 'G728', - 16: 'DVI4', 17: 'DVI4', - 18: 'G729', 25: 'CelB', - 26: 'JPEG', 28: 'nv', - 31: 'H261', 32: 'MPV', - 33: 'MP2T', 34: 'H263' } - -class RTP(Packet): - name="RTP" - fields_desc = [ BitField('version', 2, 2), - BitField('padding', 0, 1), - BitField('extension', 0, 1), - BitFieldLenField('numsync', None, 4, count_of='sync'), - BitField('marker', 0, 1), - BitEnumField('payload', 0, 7, _rtp_payload_types), - ShortField('sequence', 0), - IntField('timestamp', 0), - IntField('sourcesync', 0), - FieldListField('sync', [], IntField("id",0), count_from=lambda pkt:pkt.numsync) ] - diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/sctp.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/sctp.py deleted file mode 100644 index 57712112..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/sctp.py +++ /dev/null @@ -1,439 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## Copyright (C) 6WIND <olivier.matz@6wind.com> -## This program is published under a GPLv2 license - -""" -SCTP (Stream Control Transmission Protocol). -""" - -import struct - -from scapy.packet import * -from scapy.fields import * -from scapy.layers.inet import IP -from scapy.layers.inet6 import IP6Field - -IPPROTO_SCTP=132 - -# crc32-c (Castagnoli) (crc32c_poly=0x1EDC6F41) -crc32c_table = [ - 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, - 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, - 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, - 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24, - 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, - 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384, - 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, - 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B, - 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, - 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35, - 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, - 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA, - 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, - 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A, - 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, - 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595, - 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, - 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957, - 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, - 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198, - 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, - 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38, - 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, - 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7, - 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, - 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789, - 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, - 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46, - 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, - 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6, - 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, - 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829, - 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, - 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93, - 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, - 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C, - 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, - 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC, - 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, - 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033, - 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, - 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D, - 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, - 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982, - 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, - 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622, - 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, - 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED, - 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, - 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F, - 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, - 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0, - 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, - 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540, - 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, - 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F, - 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, - 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1, - 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, - 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E, - 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, - 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E, - 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, - 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351, - ] - -def crc32c(buf): - crc = 0xffffffff - for c in buf: - #crc = (crc>>8) ^ crc32c_table[(crc^(ord(c))) & 0xFF] - crc = (crc>>8) ^ crc32c_table[(crc^(c)) & 0xFF] - crc = (~crc) & 0xffffffff - # reverse endianness - return struct.unpack(">I",struct.pack("<I", crc))[0] - -# old checksum (RFC2960) -""" -BASE = 65521 # largest prime smaller than 65536 -def update_adler32(adler, buf): - s1 = adler & 0xffff - s2 = (adler >> 16) & 0xffff - print(s1,s2) - - for c in buf: - print(ord(c)) - s1 = (s1 + ord(c)) % BASE - s2 = (s2 + s1) % BASE - print(s1,s2) - return (s2 << 16) + s1 - -def sctp_checksum(buf): - return update_adler32(1, buf) -""" - -sctpchunktypescls = { - 0 : "SCTPChunkData", - 1 : "SCTPChunkInit", - 2 : "SCTPChunkInitAck", - 3 : "SCTPChunkSACK", - 4 : "SCTPChunkHeartbeatReq", - 5 : "SCTPChunkHeartbeatAck", - 6 : "SCTPChunkAbort", - 7 : "SCTPChunkShutdown", - 8 : "SCTPChunkShutdownAck", - 9 : "SCTPChunkError", - 10 : "SCTPChunkCookieEcho", - 11 : "SCTPChunkCookieAck", - 14 : "SCTPChunkShutdownComplete", - } - -sctpchunktypes = { - 0 : "data", - 1 : "init", - 2 : "init-ack", - 3 : "sack", - 4 : "heartbeat-req", - 5 : "heartbeat-ack", - 6 : "abort", - 7 : "shutdown", - 8 : "shutdown-ack", - 9 : "error", - 10 : "cookie-echo", - 11 : "cookie-ack", - 14 : "shutdown-complete", - } - -sctpchunkparamtypescls = { - 1 : "SCTPChunkParamHearbeatInfo", - 5 : "SCTPChunkParamIPv4Addr", - 6 : "SCTPChunkParamIPv6Addr", - 7 : "SCTPChunkParamStateCookie", - 8 : "SCTPChunkParamUnrocognizedParam", - 9 : "SCTPChunkParamCookiePreservative", - 11 : "SCTPChunkParamHostname", - 12 : "SCTPChunkParamSupportedAddrTypes", - 32768 : "SCTPChunkParamECNCapable", - 49152 : "SCTPChunkParamFwdTSN", - 49158 : "SCTPChunkParamAdaptationLayer", - } - -sctpchunkparamtypes = { - 1 : "heartbeat-info", - 5 : "IPv4", - 6 : "IPv6", - 7 : "state-cookie", - 8 : "unrecognized-param", - 9 : "cookie-preservative", - 11 : "hostname", - 12 : "addrtypes", - 32768 : "ecn-capable", - 49152 : "fwd-tsn-supported", - 49158 : "adaptation-layer", - } - -############## SCTP header - -# Dummy class to guess payload type (variable parameters) -class _SCTPChunkGuessPayload: - def default_payload_class(self,p): - if len(p) < 4: - return conf.padding_layer - else: - t = p[0] - return globals().get(sctpchunktypescls.get(t, "Raw"), conf.raw_layer) - - -class SCTP(_SCTPChunkGuessPayload, Packet): - fields_desc = [ ShortField("sport", None), - ShortField("dport", None), - XIntField("tag", None), - XIntField("chksum", None), ] - def answers(self, other): - if not isinstance(other, SCTP): - return 0 - if conf.checkIPsrc: - if not ((self.sport == other.dport) and - (self.dport == other.sport)): - return 0 - return 1 - def post_build(self, p, pay): - p += pay - if self.chksum is None: - crc = crc32c(str(p)) - p = p[:8]+struct.pack(">I", crc)+p[12:] - return p - -############## SCTP Chunk variable params - -class ChunkParamField(PacketListField): - islist = 1 - holds_packets=1 - def __init__(self, name, default, count_from=None, length_from=None): - PacketListField.__init__(self, name, default, conf.raw_layer, count_from=count_from, length_from=length_from) - def m2i(self, p, m): - cls = conf.raw_layer - if len(m) >= 4: - #t = ord(m[0]) * 256 + ord(m[1]) - t = (m[0]) * 256 + (m[1]) - cls = globals().get(sctpchunkparamtypescls.get(t, "Raw"), conf.raw_layer) - return cls(m) - -# dummy class to avoid Raw() after Chunk params -class _SCTPChunkParam: - def extract_padding(self, s): - return b"",s[:] - -class SCTPChunkParamHearbeatInfo(_SCTPChunkParam, Packet): - fields_desc = [ ShortEnumField("type", 1, sctpchunkparamtypes), - FieldLenField("len", None, length_of="data", - adjust = lambda pkt,x:x+4), - PadField(StrLenField("data", b"", - length_from=lambda pkt: pkt.len-4), - 4, padwith=b"\x00"),] - -class SCTPChunkParamIPv4Addr(_SCTPChunkParam, Packet): - fields_desc = [ ShortEnumField("type", 5, sctpchunkparamtypes), - ShortField("len", 8), - IPField("addr","127.0.0.1"), ] - -class SCTPChunkParamIPv6Addr(_SCTPChunkParam, Packet): - fields_desc = [ ShortEnumField("type", 6, sctpchunkparamtypes), - ShortField("len", 20), - IP6Field("addr","::1"), ] - -class SCTPChunkParamStateCookie(_SCTPChunkParam, Packet): - fields_desc = [ ShortEnumField("type", 7, sctpchunkparamtypes), - FieldLenField("len", None, length_of="cookie", - adjust = lambda pkt,x:x+4), - PadField(StrLenField("cookie", b"", - length_from=lambda pkt: pkt.len-4), - 4, padwith=b"\x00"),] - -class SCTPChunkParamUnrocognizedParam(_SCTPChunkParam, Packet): - fields_desc = [ ShortEnumField("type", 8, sctpchunkparamtypes), - FieldLenField("len", None, length_of="param", - adjust = lambda pkt,x:x+4), - PadField(StrLenField("param", b"", - length_from=lambda pkt: pkt.len-4), - 4, padwith=b"\x00"),] - -class SCTPChunkParamCookiePreservative(_SCTPChunkParam, Packet): - fields_desc = [ ShortEnumField("type", 9, sctpchunkparamtypes), - ShortField("len", 8), - XIntField("sug_cookie_inc", None), ] - -class SCTPChunkParamHostname(_SCTPChunkParam, Packet): - fields_desc = [ ShortEnumField("type", 11, sctpchunkparamtypes), - FieldLenField("len", None, length_of="hostname", - adjust = lambda pkt,x:x+4), - PadField(StrLenField("hostname", b"", - length_from=lambda pkt: pkt.len-4), - 4, padwith=b"\x00"), ] - -class SCTPChunkParamSupportedAddrTypes(_SCTPChunkParam, Packet): - fields_desc = [ ShortEnumField("type", 12, sctpchunkparamtypes), - FieldLenField("len", None, length_of="addr_type_list", - adjust = lambda pkt,x:x+4), - PadField(FieldListField("addr_type_list", [ "IPv4" ], - ShortEnumField("addr_type", 5, sctpchunkparamtypes), - length_from=lambda pkt: pkt.len-4), - 4, padwith=b"\x00"), ] - -class SCTPChunkParamECNCapable(_SCTPChunkParam, Packet): - fields_desc = [ ShortEnumField("type", 32768, sctpchunkparamtypes), - ShortField("len", 4), ] - -class SCTPChunkParamFwdTSN(_SCTPChunkParam, Packet): - fields_desc = [ ShortEnumField("type", 49152, sctpchunkparamtypes), - ShortField("len", 4), ] - -class SCTPChunkParamAdaptationLayer(_SCTPChunkParam, Packet): - fields_desc = [ ShortEnumField("type", 49158, sctpchunkparamtypes), - ShortField("len", 8), - XIntField("indication", None), ] - -############## SCTP Chunks - -class SCTPChunkData(_SCTPChunkGuessPayload, Packet): - fields_desc = [ ByteEnumField("type", 0, sctpchunktypes), - BitField("reserved", None, 4), - BitField("delay_sack", 0, 1), - BitField("unordered", 0, 1), - BitField("beginning", 0, 1), - BitField("ending", 0, 1), - FieldLenField("len", None, length_of="data", adjust = lambda pkt,x:x+16), - XIntField("tsn", None), - XShortField("stream_id", None), - XShortField("stream_seq", None), - XIntField("proto_id", None), - PadField(StrLenField("data", None, length_from=lambda pkt: pkt.len-16), - 4, padwith=b"\x00"), - ] - -class SCTPChunkInit(_SCTPChunkGuessPayload, Packet): - fields_desc = [ ByteEnumField("type", 1, sctpchunktypes), - XByteField("flags", None), - FieldLenField("len", None, length_of="params", adjust = lambda pkt,x:x+20), - XIntField("init_tag", None), - IntField("a_rwnd", None), - ShortField("n_out_streams", None), - ShortField("n_in_streams", None), - XIntField("init_tsn", None), - ChunkParamField("params", None, length_from=lambda pkt:pkt.len-20), - ] - -class SCTPChunkInitAck(_SCTPChunkGuessPayload, Packet): - fields_desc = [ ByteEnumField("type", 2, sctpchunktypes), - XByteField("flags", None), - FieldLenField("len", None, length_of="params", adjust = lambda pkt,x:x+20), - XIntField("init_tag", None), - IntField("a_rwnd", None), - ShortField("n_out_streams", None), - ShortField("n_in_streams", None), - XIntField("init_tsn", None), - ChunkParamField("params", None, length_from=lambda pkt:pkt.len-20), - ] - -class GapAckField(Field): - def __init__(self, name, default): - Field.__init__(self, name, default, "4s") - def i2m(self, pkt, x): - if x is None: - return "\0\0\0\0" - sta, end = map(int, x.split(":")) - args = tuple([">HH", sta, end]) - return struct.pack(*args) - def m2i(self, pkt, x): - return "%d:%d"%(struct.unpack(">HH", x)) - def any2i(self, pkt, x): - if type(x) is tuple and len(x) == 2: - return "%d:%d"%(x) - return x - -class SCTPChunkSACK(_SCTPChunkGuessPayload, Packet): - fields_desc = [ ByteEnumField("type", 3, sctpchunktypes), - XByteField("flags", None), - ShortField("len", None), - XIntField("cumul_tsn_ack", None), - IntField("a_rwnd", None), - FieldLenField("n_gap_ack", None, count_of="gap_ack_list"), - FieldLenField("n_dup_tsn", None, count_of="dup_tsn_list"), - FieldListField("gap_ack_list", [ ], GapAckField("gap_ack", None), count_from=lambda pkt:pkt.n_gap_ack), - FieldListField("dup_tsn_list", [ ], XIntField("dup_tsn", None), count_from=lambda pkt:pkt.n_dup_tsn), - ] - - def post_build(self, p, pay): - if self.len is None: - p = p[:2] + struct.pack(">H", len(p)) + p[4:] - return p+pay - - -class SCTPChunkHeartbeatReq(_SCTPChunkGuessPayload, Packet): - fields_desc = [ ByteEnumField("type", 4, sctpchunktypes), - XByteField("flags", None), - FieldLenField("len", None, length_of="params", adjust = lambda pkt,x:x+4), - ChunkParamField("params", None, length_from=lambda pkt:pkt.len-4), - ] - -class SCTPChunkHeartbeatAck(_SCTPChunkGuessPayload, Packet): - fields_desc = [ ByteEnumField("type", 5, sctpchunktypes), - XByteField("flags", None), - FieldLenField("len", None, length_of="params", adjust = lambda pkt,x:x+4), - ChunkParamField("params", None, length_from=lambda pkt:pkt.len-4), - ] - -class SCTPChunkAbort(_SCTPChunkGuessPayload, Packet): - fields_desc = [ ByteEnumField("type", 6, sctpchunktypes), - BitField("reserved", None, 7), - BitField("TCB", 0, 1), - FieldLenField("len", None, length_of="error_causes", adjust = lambda pkt,x:x+4), - PadField(StrLenField("error_causes", b"", length_from=lambda pkt: pkt.len-4), - 4, padwith=b"\x00"), - ] - -class SCTPChunkShutdown(_SCTPChunkGuessPayload, Packet): - fields_desc = [ ByteEnumField("type", 7, sctpchunktypes), - XByteField("flags", None), - ShortField("len", 8), - XIntField("cumul_tsn_ack", None), - ] - -class SCTPChunkShutdownAck(_SCTPChunkGuessPayload, Packet): - fields_desc = [ ByteEnumField("type", 8, sctpchunktypes), - XByteField("flags", None), - ShortField("len", 4), - ] - -class SCTPChunkError(_SCTPChunkGuessPayload, Packet): - fields_desc = [ ByteEnumField("type", 9, sctpchunktypes), - XByteField("flags", None), - FieldLenField("len", None, length_of="error_causes", adjust = lambda pkt,x:x+4), - PadField(StrLenField("error_causes", b"", length_from=lambda pkt: pkt.len-4), - 4, padwith=b"\x00"), - ] - -class SCTPChunkCookieEcho(_SCTPChunkGuessPayload, Packet): - fields_desc = [ ByteEnumField("type", 10, sctpchunktypes), - XByteField("flags", None), - FieldLenField("len", None, length_of="cookie", adjust = lambda pkt,x:x+4), - PadField(StrLenField("cookie", b"", length_from=lambda pkt: pkt.len-4), - 4, padwith=b"\x00"), - ] - -class SCTPChunkCookieAck(_SCTPChunkGuessPayload, Packet): - fields_desc = [ ByteEnumField("type", 11, sctpchunktypes), - XByteField("flags", None), - ShortField("len", 4), - ] - -class SCTPChunkShutdownComplete(_SCTPChunkGuessPayload, Packet): - fields_desc = [ ByteEnumField("type", 12, sctpchunktypes), - BitField("reserved", None, 7), - BitField("TCB", 0, 1), - ShortField("len", 4), - ] - -bind_layers( IP, SCTP, proto=IPPROTO_SCTP) - diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/sebek.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/sebek.py deleted file mode 100644 index c54e6728..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/sebek.py +++ /dev/null @@ -1,109 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -Sebek: Linux kernel module for data collection on honeypots. -""" - -from scapy.fields import * -from scapy.packet import * -from scapy.layers.inet import UDP - - -### SEBEK - - -class SebekHead(Packet): - name = "Sebek header" - fields_desc = [ XIntField("magic", 0xd0d0d0), - ShortField("version", 1), - ShortEnumField("type", 0, {"read":0, "write":1, - "socket":2, "open":3}), - IntField("counter", 0), - IntField("time_sec", 0), - IntField("time_usec", 0) ] - def mysummary(self): - return self.sprintf("Sebek Header v%SebekHead.version% %SebekHead.type%") - -# we need this because Sebek headers differ between v1 and v3, and -# between v3 type socket and v3 others - -class SebekV1(Packet): - name = "Sebek v1" - fields_desc = [ IntField("pid", 0), - IntField("uid", 0), - IntField("fd", 0), - StrFixedLenField("command", "", 12), - FieldLenField("data_length", None, "data",fmt="I"), - StrLenField("data", "", length_from=lambda x:x.data_length) ] - def mysummary(self): - if isinstance(self.underlayer, SebekHead): - return self.underlayer.sprintf("Sebek v1 %SebekHead.type% (%SebekV1.command%)") - else: - return self.sprintf("Sebek v1 (%SebekV1.command%)") - -class SebekV3(Packet): - name = "Sebek v3" - fields_desc = [ IntField("parent_pid", 0), - IntField("pid", 0), - IntField("uid", 0), - IntField("fd", 0), - IntField("inode", 0), - StrFixedLenField("command", "", 12), - FieldLenField("data_length", None, "data",fmt="I"), - StrLenField("data", "", length_from=lambda x:x.data_length) ] - def mysummary(self): - if isinstance(self.underlayer, SebekHead): - return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3.command%)") - else: - return self.sprintf("Sebek v3 (%SebekV3.command%)") - -class SebekV2(SebekV3): - def mysummary(self): - if isinstance(self.underlayer, SebekHead): - return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2.command%)") - else: - return self.sprintf("Sebek v2 (%SebekV2.command%)") - -class SebekV3Sock(Packet): - name = "Sebek v2 socket" - fields_desc = [ IntField("parent_pid", 0), - IntField("pid", 0), - IntField("uid", 0), - IntField("fd", 0), - IntField("inode", 0), - StrFixedLenField("command", "", 12), - IntField("data_length", 15), - IPField("dip", "127.0.0.1"), - ShortField("dport", 0), - IPField("sip", "127.0.0.1"), - ShortField("sport", 0), - ShortEnumField("call", 0, { "bind":2, - "connect":3, "listen":4, - "accept":5, "sendmsg":16, - "recvmsg":17, "sendto":11, - "recvfrom":12}), - ByteEnumField("proto", 0, IP_PROTOS) ] - def mysummary(self): - if isinstance(self.underlayer, SebekHead): - return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3Sock.command%)") - else: - return self.sprintf("Sebek v3 socket (%SebekV3Sock.command%)") - -class SebekV2Sock(SebekV3Sock): - def mysummary(self): - if isinstance(self.underlayer, SebekHead): - return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2Sock.command%)") - else: - return self.sprintf("Sebek v2 socket (%SebekV2Sock.command%)") - -bind_layers( UDP, SebekHead, sport=1101) -bind_layers( UDP, SebekHead, dport=1101) -bind_layers( UDP, SebekHead, dport=1101, sport=1101) -bind_layers( SebekHead, SebekV1, version=1) -bind_layers( SebekHead, SebekV2Sock, version=2, type=2) -bind_layers( SebekHead, SebekV2, version=2) -bind_layers( SebekHead, SebekV3Sock, version=3, type=2) -bind_layers( SebekHead, SebekV3, version=3) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/skinny.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/skinny.py deleted file mode 100644 index 9fb6ac06..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/skinny.py +++ /dev/null @@ -1,161 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -Cisco Skinny protocol. -""" - -from scapy.packet import * -from scapy.fields import * -from scapy.layers.inet import TCP - -# shamelessly ripped from Ethereal dissector -skinny_messages = { -# Station -> Callmanager - 0x0000: "KeepAliveMessage", - 0x0001: "RegisterMessage", - 0x0002: "IpPortMessage", - 0x0003: "KeypadButtonMessage", - 0x0004: "EnblocCallMessage", - 0x0005: "StimulusMessage", - 0x0006: "OffHookMessage", - 0x0007: "OnHookMessage", - 0x0008: "HookFlashMessage", - 0x0009: "ForwardStatReqMessage", - 0x000A: "SpeedDialStatReqMessage", - 0x000B: "LineStatReqMessage", - 0x000C: "ConfigStatReqMessage", - 0x000D: "TimeDateReqMessage", - 0x000E: "ButtonTemplateReqMessage", - 0x000F: "VersionReqMessage", - 0x0010: "CapabilitiesResMessage", - 0x0011: "MediaPortListMessage", - 0x0012: "ServerReqMessage", - 0x0020: "AlarmMessage", - 0x0021: "MulticastMediaReceptionAck", - 0x0022: "OpenReceiveChannelAck", - 0x0023: "ConnectionStatisticsRes", - 0x0024: "OffHookWithCgpnMessage", - 0x0025: "SoftKeySetReqMessage", - 0x0026: "SoftKeyEventMessage", - 0x0027: "UnregisterMessage", - 0x0028: "SoftKeyTemplateReqMessage", - 0x0029: "RegisterTokenReq", - 0x002A: "MediaTransmissionFailure", - 0x002B: "HeadsetStatusMessage", - 0x002C: "MediaResourceNotification", - 0x002D: "RegisterAvailableLinesMessage", - 0x002E: "DeviceToUserDataMessage", - 0x002F: "DeviceToUserDataResponseMessage", - 0x0030: "UpdateCapabilitiesMessage", - 0x0031: "OpenMultiMediaReceiveChannelAckMessage", - 0x0032: "ClearConferenceMessage", - 0x0033: "ServiceURLStatReqMessage", - 0x0034: "FeatureStatReqMessage", - 0x0035: "CreateConferenceResMessage", - 0x0036: "DeleteConferenceResMessage", - 0x0037: "ModifyConferenceResMessage", - 0x0038: "AddParticipantResMessage", - 0x0039: "AuditConferenceResMessage", - 0x0040: "AuditParticipantResMessage", - 0x0041: "DeviceToUserDataVersion1Message", -# Callmanager -> Station */ - 0x0081: "RegisterAckMessage", - 0x0082: "StartToneMessage", - 0x0083: "StopToneMessage", - 0x0085: "SetRingerMessage", - 0x0086: "SetLampMessage", - 0x0087: "SetHkFDetectMessage", - 0x0088: "SetSpeakerModeMessage", - 0x0089: "SetMicroModeMessage", - 0x008A: "StartMediaTransmission", - 0x008B: "StopMediaTransmission", - 0x008C: "StartMediaReception", - 0x008D: "StopMediaReception", - 0x008F: "CallInfoMessage", - 0x0090: "ForwardStatMessage", - 0x0091: "SpeedDialStatMessage", - 0x0092: "LineStatMessage", - 0x0093: "ConfigStatMessage", - 0x0094: "DefineTimeDate", - 0x0095: "StartSessionTransmission", - 0x0096: "StopSessionTransmission", - 0x0097: "ButtonTemplateMessage", - 0x0098: "VersionMessage", - 0x0099: "DisplayTextMessage", - 0x009A: "ClearDisplay", - 0x009B: "CapabilitiesReqMessage", - 0x009C: "EnunciatorCommandMessage", - 0x009D: "RegisterRejectMessage", - 0x009E: "ServerResMessage", - 0x009F: "Reset", - 0x0100: "KeepAliveAckMessage", - 0x0101: "StartMulticastMediaReception", - 0x0102: "StartMulticastMediaTransmission", - 0x0103: "StopMulticastMediaReception", - 0x0104: "StopMulticastMediaTransmission", - 0x0105: "OpenReceiveChannel", - 0x0106: "CloseReceiveChannel", - 0x0107: "ConnectionStatisticsReq", - 0x0108: "SoftKeyTemplateResMessage", - 0x0109: "SoftKeySetResMessage", - 0x0110: "SelectSoftKeysMessage", - 0x0111: "CallStateMessage", - 0x0112: "DisplayPromptStatusMessage", - 0x0113: "ClearPromptStatusMessage", - 0x0114: "DisplayNotifyMessage", - 0x0115: "ClearNotifyMessage", - 0x0116: "ActivateCallPlaneMessage", - 0x0117: "DeactivateCallPlaneMessage", - 0x0118: "UnregisterAckMessage", - 0x0119: "BackSpaceReqMessage", - 0x011A: "RegisterTokenAck", - 0x011B: "RegisterTokenReject", - 0x0042: "DeviceToUserDataResponseVersion1Message", - 0x011C: "StartMediaFailureDetection", - 0x011D: "DialedNumberMessage", - 0x011E: "UserToDeviceDataMessage", - 0x011F: "FeatureStatMessage", - 0x0120: "DisplayPriNotifyMessage", - 0x0121: "ClearPriNotifyMessage", - 0x0122: "StartAnnouncementMessage", - 0x0123: "StopAnnouncementMessage", - 0x0124: "AnnouncementFinishMessage", - 0x0127: "NotifyDtmfToneMessage", - 0x0128: "SendDtmfToneMessage", - 0x0129: "SubscribeDtmfPayloadReqMessage", - 0x012A: "SubscribeDtmfPayloadResMessage", - 0x012B: "SubscribeDtmfPayloadErrMessage", - 0x012C: "UnSubscribeDtmfPayloadReqMessage", - 0x012D: "UnSubscribeDtmfPayloadResMessage", - 0x012E: "UnSubscribeDtmfPayloadErrMessage", - 0x012F: "ServiceURLStatMessage", - 0x0130: "CallSelectStatMessage", - 0x0131: "OpenMultiMediaChannelMessage", - 0x0132: "StartMultiMediaTransmission", - 0x0133: "StopMultiMediaTransmission", - 0x0134: "MiscellaneousCommandMessage", - 0x0135: "FlowControlCommandMessage", - 0x0136: "CloseMultiMediaReceiveChannel", - 0x0137: "CreateConferenceReqMessage", - 0x0138: "DeleteConferenceReqMessage", - 0x0139: "ModifyConferenceReqMessage", - 0x013A: "AddParticipantReqMessage", - 0x013B: "DropParticipantReqMessage", - 0x013C: "AuditConferenceReqMessage", - 0x013D: "AuditParticipantReqMessage", - 0x013F: "UserToDeviceDataVersion1Message", - } - - - -class Skinny(Packet): - name="Skinny" - fields_desc = [ LEIntField("len",0), - LEIntField("res",0), - LEIntEnumField("msg",0,skinny_messages) ] - -bind_layers( TCP, Skinny, dport=2000) -bind_layers( TCP, Skinny, sport=2000) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/smb.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/smb.py deleted file mode 100644 index f8e0da7a..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/smb.py +++ /dev/null @@ -1,354 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -SMB (Server Message Block), also known as CIFS. -""" - -from scapy.packet import * -from scapy.fields import * -from scapy.layers.netbios import NBTSession - - -# SMB NetLogon Response Header -class SMBNetlogon_Protocol_Response_Header(Packet): - name="SMBNetlogon Protocol Response Header" - fields_desc = [StrFixedLenField("Start","\xffSMB",4), - ByteEnumField("Command",0x25,{0x25:"Trans"}), - ByteField("Error_Class",0x02), - ByteField("Reserved",0), - LEShortField("Error_code",4), - ByteField("Flags",0), - LEShortField("Flags2",0x0000), - LEShortField("PIDHigh",0x0000), - LELongField("Signature",0x0), - LEShortField("Unused",0x0), - LEShortField("TID",0), - LEShortField("PID",0), - LEShortField("UID",0), - LEShortField("MID",0), - ByteField("WordCount",17), - LEShortField("TotalParamCount",0), - LEShortField("TotalDataCount",112), - LEShortField("MaxParamCount",0), - LEShortField("MaxDataCount",0), - ByteField("MaxSetupCount",0), - ByteField("unused2",0), - LEShortField("Flags3",0), - ByteField("TimeOut1",0xe8), - ByteField("TimeOut2",0x03), - LEShortField("unused3",0), - LEShortField("unused4",0), - LEShortField("ParamCount2",0), - LEShortField("ParamOffset",0), - LEShortField("DataCount",112), - LEShortField("DataOffset",92), - ByteField("SetupCount", 3), - ByteField("unused5", 0)] - -# SMB MailSlot Protocol -class SMBMailSlot(Packet): - name = "SMB Mail Slot Protocol" - fields_desc = [LEShortField("opcode", 1), - LEShortField("priority", 1), - LEShortField("class", 2), - LEShortField("size", 135), - StrNullField("name","\\MAILSLOT\\NET\\GETDC660")] - -# SMB NetLogon Protocol Response Tail SAM -class SMBNetlogon_Protocol_Response_Tail_SAM(Packet): - name = "SMB Netlogon Protocol Response Tail SAM" - fields_desc = [ByteEnumField("Command", 0x17, {0x12:"SAM logon request", 0x17:"SAM Active directory Response"}), - ByteField("unused", 0), - ShortField("Data1", 0), - ShortField("Data2", 0xfd01), - ShortField("Data3", 0), - ShortField("Data4", 0xacde), - ShortField("Data5", 0x0fe5), - ShortField("Data6", 0xd10a), - ShortField("Data7", 0x374c), - ShortField("Data8", 0x83e2), - ShortField("Data9", 0x7dd9), - ShortField("Data10", 0x3a16), - ShortField("Data11", 0x73ff), - ByteField("Data12", 0x04), - StrFixedLenField("Data13", "rmff", 4), - ByteField("Data14", 0x0), - ShortField("Data16", 0xc018), - ByteField("Data18", 0x0a), - StrFixedLenField("Data20", "rmff-win2k", 10), - ByteField("Data21", 0xc0), - ShortField("Data22", 0x18c0), - ShortField("Data23", 0x180a), - StrFixedLenField("Data24", "RMFF-WIN2K", 10), - ShortField("Data25", 0), - ByteField("Data26", 0x17), - StrFixedLenField("Data27", "Default-First-Site-Name", 23), - ShortField("Data28", 0x00c0), - ShortField("Data29", 0x3c10), - ShortField("Data30", 0x00c0), - ShortField("Data31", 0x0200), - ShortField("Data32", 0x0), - ShortField("Data33", 0xac14), - ShortField("Data34", 0x0064), - ShortField("Data35", 0x0), - ShortField("Data36", 0x0), - ShortField("Data37", 0x0), - ShortField("Data38", 0x0), - ShortField("Data39", 0x0d00), - ShortField("Data40", 0x0), - ShortField("Data41", 0xffff)] - -# SMB NetLogon Protocol Response Tail LM2.0 -class SMBNetlogon_Protocol_Response_Tail_LM20(Packet): - name = "SMB Netlogon Protocol Response Tail LM20" - fields_desc = [ByteEnumField("Command",0x06,{0x06:"LM 2.0 Response to logon request"}), - ByteField("unused", 0), - StrFixedLenField("DblSlash", "\\\\", 2), - StrNullField("ServerName","WIN"), - LEShortField("LM20Token", 0xffff)] - -# SMBNegociate Protocol Request Header -class SMBNegociate_Protocol_Request_Header(Packet): - name="SMBNegociate Protocol Request Header" - fields_desc = [StrFixedLenField("Start","\xffSMB",4), - ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}), - ByteField("Error_Class",0), - ByteField("Reserved",0), - LEShortField("Error_code",0), - ByteField("Flags",0x18), - LEShortField("Flags2",0x0000), - LEShortField("PIDHigh",0x0000), - LELongField("Signature",0x0), - LEShortField("Unused",0x0), - LEShortField("TID",0), - LEShortField("PID",1), - LEShortField("UID",0), - LEShortField("MID",2), - ByteField("WordCount",0), - LEShortField("ByteCount",12)] - -# SMB Negociate Protocol Request Tail -class SMBNegociate_Protocol_Request_Tail(Packet): - name="SMB Negociate Protocol Request Tail" - fields_desc=[ByteField("BufferFormat",0x02), - StrNullField("BufferData","NT LM 0.12")] - -# SMBNegociate Protocol Response Advanced Security -class SMBNegociate_Protocol_Response_Advanced_Security(Packet): - name="SMBNegociate Protocol Response Advanced Security" - fields_desc = [StrFixedLenField("Start","\xffSMB",4), - ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}), - ByteField("Error_Class",0), - ByteField("Reserved",0), - LEShortField("Error_Code",0), - ByteField("Flags",0x98), - LEShortField("Flags2",0x0000), - LEShortField("PIDHigh",0x0000), - LELongField("Signature",0x0), - LEShortField("Unused",0x0), - LEShortField("TID",0), - LEShortField("PID",1), - LEShortField("UID",0), - LEShortField("MID",2), - ByteField("WordCount",17), - LEShortField("DialectIndex",7), - ByteField("SecurityMode",0x03), - LEShortField("MaxMpxCount",50), - LEShortField("MaxNumberVC",1), - LEIntField("MaxBufferSize",16144), - LEIntField("MaxRawSize",65536), - LEIntField("SessionKey",0x0000), - LEShortField("ServerCapabilities",0xf3f9), - BitField("UnixExtensions",0,1), - BitField("Reserved2",0,7), - BitField("ExtendedSecurity",1,1), - BitField("CompBulk",0,2), - BitField("Reserved3",0,5), -# There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94. - LEIntField("ServerTimeHigh",0xD6228000), - LEIntField("ServerTimeLow",0x1C4EF94), - LEShortField("ServerTimeZone",0x3c), - ByteField("EncryptionKeyLength",0), - LEFieldLenField("ByteCount", None, "SecurityBlob", adjust=lambda pkt,x:x-16), - BitField("GUID",0,128), - StrLenField("SecurityBlob", "", length_from=lambda x:x.ByteCount+16)] - -# SMBNegociate Protocol Response No Security -# When using no security, with EncryptionKeyLength=8, you must have an EncryptionKey before the DomainName -class SMBNegociate_Protocol_Response_No_Security(Packet): - name="SMBNegociate Protocol Response No Security" - fields_desc = [StrFixedLenField("Start","\xffSMB",4), - ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}), - ByteField("Error_Class",0), - ByteField("Reserved",0), - LEShortField("Error_Code",0), - ByteField("Flags",0x98), - LEShortField("Flags2",0x0000), - LEShortField("PIDHigh",0x0000), - LELongField("Signature",0x0), - LEShortField("Unused",0x0), - LEShortField("TID",0), - LEShortField("PID",1), - LEShortField("UID",0), - LEShortField("MID",2), - ByteField("WordCount",17), - LEShortField("DialectIndex",7), - ByteField("SecurityMode",0x03), - LEShortField("MaxMpxCount",50), - LEShortField("MaxNumberVC",1), - LEIntField("MaxBufferSize",16144), - LEIntField("MaxRawSize",65536), - LEIntField("SessionKey",0x0000), - LEShortField("ServerCapabilities",0xf3f9), - BitField("UnixExtensions",0,1), - BitField("Reserved2",0,7), - BitField("ExtendedSecurity",0,1), - FlagsField("CompBulk",0,2,"CB"), - BitField("Reserved3",0,5), - # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94. - LEIntField("ServerTimeHigh",0xD6228000), - LEIntField("ServerTimeLow",0x1C4EF94), - LEShortField("ServerTimeZone",0x3c), - ByteField("EncryptionKeyLength",8), - LEShortField("ByteCount",24), - BitField("EncryptionKey",0,64), - StrNullField("DomainName","WORKGROUP"), - StrNullField("ServerName","RMFF1")] - -# SMBNegociate Protocol Response No Security No Key -class SMBNegociate_Protocol_Response_No_Security_No_Key(Packet): - namez="SMBNegociate Protocol Response No Security No Key" - fields_desc = [StrFixedLenField("Start","\xffSMB",4), - ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}), - ByteField("Error_Class",0), - ByteField("Reserved",0), - LEShortField("Error_Code",0), - ByteField("Flags",0x98), - LEShortField("Flags2",0x0000), - LEShortField("PIDHigh",0x0000), - LELongField("Signature",0x0), - LEShortField("Unused",0x0), - LEShortField("TID",0), - LEShortField("PID",1), - LEShortField("UID",0), - LEShortField("MID",2), - ByteField("WordCount",17), - LEShortField("DialectIndex",7), - ByteField("SecurityMode",0x03), - LEShortField("MaxMpxCount",50), - LEShortField("MaxNumberVC",1), - LEIntField("MaxBufferSize",16144), - LEIntField("MaxRawSize",65536), - LEIntField("SessionKey",0x0000), - LEShortField("ServerCapabilities",0xf3f9), - BitField("UnixExtensions",0,1), - BitField("Reserved2",0,7), - BitField("ExtendedSecurity",0,1), - FlagsField("CompBulk",0,2,"CB"), - BitField("Reserved3",0,5), - # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94. - LEIntField("ServerTimeHigh",0xD6228000), - LEIntField("ServerTimeLow",0x1C4EF94), - LEShortField("ServerTimeZone",0x3c), - ByteField("EncryptionKeyLength",0), - LEShortField("ByteCount",16), - StrNullField("DomainName","WORKGROUP"), - StrNullField("ServerName","RMFF1")] - -# Session Setup AndX Request -class SMBSession_Setup_AndX_Request(Packet): - name="Session Setup AndX Request" - fields_desc=[StrFixedLenField("Start","\xffSMB",4), - ByteEnumField("Command",0x73,{0x73:"SMB_COM_SESSION_SETUP_ANDX"}), - ByteField("Error_Class",0), - ByteField("Reserved",0), - LEShortField("Error_Code",0), - ByteField("Flags",0x18), - LEShortField("Flags2",0x0001), - LEShortField("PIDHigh",0x0000), - LELongField("Signature",0x0), - LEShortField("Unused",0x0), - LEShortField("TID",0), - LEShortField("PID",1), - LEShortField("UID",0), - LEShortField("MID",2), - ByteField("WordCount",13), - ByteEnumField("AndXCommand",0x75,{0x75:"SMB_COM_TREE_CONNECT_ANDX"}), - ByteField("Reserved2",0), - LEShortField("AndXOffset",96), - LEShortField("MaxBufferS",2920), - LEShortField("MaxMPXCount",50), - LEShortField("VCNumber",0), - LEIntField("SessionKey",0), - LEFieldLenField("ANSIPasswordLength",None,"ANSIPassword"), - LEShortField("UnicodePasswordLength",0), - LEIntField("Reserved3",0), - LEShortField("ServerCapabilities",0x05), - BitField("UnixExtensions",0,1), - BitField("Reserved4",0,7), - BitField("ExtendedSecurity",0,1), - BitField("CompBulk",0,2), - BitField("Reserved5",0,5), - LEShortField("ByteCount",35), - StrLenField("ANSIPassword", "Pass",length_from=lambda x:x.ANSIPasswordLength), - StrNullField("Account","GUEST"), - StrNullField("PrimaryDomain", ""), - StrNullField("NativeOS","Windows 4.0"), - StrNullField("NativeLanManager","Windows 4.0"), - ByteField("WordCount2",4), - ByteEnumField("AndXCommand2",0xFF,{0xFF:"SMB_COM_NONE"}), - ByteField("Reserved6",0), - LEShortField("AndXOffset2",0), - LEShortField("Flags3",0x2), - LEShortField("PasswordLength",0x1), - LEShortField("ByteCount2",18), - ByteField("Password",0), - StrNullField("Path","\\\\WIN2K\\IPC$"), - StrNullField("Service","IPC")] - -# Session Setup AndX Response -class SMBSession_Setup_AndX_Response(Packet): - name="Session Setup AndX Response" - fields_desc=[StrFixedLenField("Start","\xffSMB",4), - ByteEnumField("Command",0x73,{0x73:"SMB_COM_SESSION_SETUP_ANDX"}), - ByteField("Error_Class",0), - ByteField("Reserved",0), - LEShortField("Error_Code",0), - ByteField("Flags",0x90), - LEShortField("Flags2",0x1001), - LEShortField("PIDHigh",0x0000), - LELongField("Signature",0x0), - LEShortField("Unused",0x0), - LEShortField("TID",0), - LEShortField("PID",1), - LEShortField("UID",0), - LEShortField("MID",2), - ByteField("WordCount",3), - ByteEnumField("AndXCommand",0x75,{0x75:"SMB_COM_TREE_CONNECT_ANDX"}), - ByteField("Reserved2",0), - LEShortField("AndXOffset",66), - LEShortField("Action",0), - LEShortField("ByteCount",25), - StrNullField("NativeOS","Windows 4.0"), - StrNullField("NativeLanManager","Windows 4.0"), - StrNullField("PrimaryDomain",""), - ByteField("WordCount2",3), - ByteEnumField("AndXCommand2",0xFF,{0xFF:"SMB_COM_NONE"}), - ByteField("Reserved3",0), - LEShortField("AndXOffset2",80), - LEShortField("OptionalSupport",0x01), - LEShortField("ByteCount2",5), - StrNullField("Service","IPC"), - StrNullField("NativeFileSystem","")] - -bind_layers( NBTSession, SMBNegociate_Protocol_Request_Header, ) -bind_layers( NBTSession, SMBNegociate_Protocol_Response_Advanced_Security, ExtendedSecurity=1) -bind_layers( NBTSession, SMBNegociate_Protocol_Response_No_Security, ExtendedSecurity=0, EncryptionKeyLength=8) -bind_layers( NBTSession, SMBNegociate_Protocol_Response_No_Security_No_Key, ExtendedSecurity=0, EncryptionKeyLength=0) -bind_layers( NBTSession, SMBSession_Setup_AndX_Request, ) -bind_layers( NBTSession, SMBSession_Setup_AndX_Response, ) -bind_layers( SMBNegociate_Protocol_Request_Header, SMBNegociate_Protocol_Request_Tail, ) -bind_layers( SMBNegociate_Protocol_Request_Tail, SMBNegociate_Protocol_Request_Tail, ) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/snmp.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/snmp.py deleted file mode 100644 index dddd4e27..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/snmp.py +++ /dev/null @@ -1,255 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -SNMP (Simple Network Management Protocol). -""" - -from scapy.asn1packet import * -from scapy.asn1fields import * -from scapy.layers.inet import UDP - -########## -## SNMP ## -########## - -######[ ASN1 class ]###### - -class ASN1_Class_SNMP(ASN1_Class_UNIVERSAL): - name="SNMP" - PDU_GET = 0xa0 - PDU_NEXT = 0xa1 - PDU_RESPONSE = 0xa2 - PDU_SET = 0xa3 - PDU_TRAPv1 = 0xa4 - PDU_BULK = 0xa5 - PDU_INFORM = 0xa6 - PDU_TRAPv2 = 0xa7 - - -class ASN1_SNMP_PDU_GET(ASN1_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_GET - -class ASN1_SNMP_PDU_NEXT(ASN1_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_NEXT - -class ASN1_SNMP_PDU_RESPONSE(ASN1_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_RESPONSE - -class ASN1_SNMP_PDU_SET(ASN1_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_SET - -class ASN1_SNMP_PDU_TRAPv1(ASN1_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_TRAPv1 - -class ASN1_SNMP_PDU_BULK(ASN1_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_BULK - -class ASN1_SNMP_PDU_INFORM(ASN1_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_INFORM - -class ASN1_SNMP_PDU_TRAPv2(ASN1_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_TRAPv2 - - -######[ BER codecs ]####### - -class BERcodec_SNMP_PDU_GET(BERcodec_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_GET - -class BERcodec_SNMP_PDU_NEXT(BERcodec_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_NEXT - -class BERcodec_SNMP_PDU_RESPONSE(BERcodec_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_RESPONSE - -class BERcodec_SNMP_PDU_SET(BERcodec_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_SET - -class BERcodec_SNMP_PDU_TRAPv1(BERcodec_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_TRAPv1 - -class BERcodec_SNMP_PDU_BULK(BERcodec_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_BULK - -class BERcodec_SNMP_PDU_INFORM(BERcodec_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_INFORM - -class BERcodec_SNMP_PDU_TRAPv2(BERcodec_SEQUENCE): - tag = ASN1_Class_SNMP.PDU_TRAPv2 - - - -######[ ASN1 fields ]###### - -class ASN1F_SNMP_PDU_GET(ASN1F_SEQUENCE): - ASN1_tag = ASN1_Class_SNMP.PDU_GET - -class ASN1F_SNMP_PDU_NEXT(ASN1F_SEQUENCE): - ASN1_tag = ASN1_Class_SNMP.PDU_NEXT - -class ASN1F_SNMP_PDU_RESPONSE(ASN1F_SEQUENCE): - ASN1_tag = ASN1_Class_SNMP.PDU_RESPONSE - -class ASN1F_SNMP_PDU_SET(ASN1F_SEQUENCE): - ASN1_tag = ASN1_Class_SNMP.PDU_SET - -class ASN1F_SNMP_PDU_TRAPv1(ASN1F_SEQUENCE): - ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv1 - -class ASN1F_SNMP_PDU_BULK(ASN1F_SEQUENCE): - ASN1_tag = ASN1_Class_SNMP.PDU_BULK - -class ASN1F_SNMP_PDU_INFORM(ASN1F_SEQUENCE): - ASN1_tag = ASN1_Class_SNMP.PDU_INFORM - -class ASN1F_SNMP_PDU_TRAPv2(ASN1F_SEQUENCE): - ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv2 - - - -######[ SNMP Packet ]###### - -SNMP_error = { 0: "no_error", - 1: "too_big", - 2: "no_such_name", - 3: "bad_value", - 4: "read_only", - 5: "generic_error", - 6: "no_access", - 7: "wrong_type", - 8: "wrong_length", - 9: "wrong_encoding", - 10: "wrong_value", - 11: "no_creation", - 12: "inconsistent_value", - 13: "ressource_unavailable", - 14: "commit_failed", - 15: "undo_failed", - 16: "authorization_error", - 17: "not_writable", - 18: "inconsistent_name", - } - -SNMP_trap_types = { 0: "cold_start", - 1: "warm_start", - 2: "link_down", - 3: "link_up", - 4: "auth_failure", - 5: "egp_neigh_loss", - 6: "enterprise_specific", - } - -class SNMPvarbind(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( ASN1F_OID("oid","1.3"), - ASN1F_field("value",ASN1_NULL(0)) - ) - - -class SNMPget(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SNMP_PDU_GET( ASN1F_INTEGER("id",0), - ASN1F_enum_INTEGER("error",0, SNMP_error), - ASN1F_INTEGER("error_index",0), - ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) - ) - -class SNMPnext(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SNMP_PDU_NEXT( ASN1F_INTEGER("id",0), - ASN1F_enum_INTEGER("error",0, SNMP_error), - ASN1F_INTEGER("error_index",0), - ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) - ) - -class SNMPresponse(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SNMP_PDU_RESPONSE( ASN1F_INTEGER("id",0), - ASN1F_enum_INTEGER("error",0, SNMP_error), - ASN1F_INTEGER("error_index",0), - ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) - ) - -class SNMPset(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SNMP_PDU_SET( ASN1F_INTEGER("id",0), - ASN1F_enum_INTEGER("error",0, SNMP_error), - ASN1F_INTEGER("error_index",0), - ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) - ) - -class SNMPtrapv1(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SNMP_PDU_TRAPv1( ASN1F_OID("enterprise", "1.3"), - ASN1F_IPADDRESS("agent_addr","0.0.0.0"), - ASN1F_enum_INTEGER("generic_trap", 0, SNMP_trap_types), - ASN1F_INTEGER("specific_trap", 0), - ASN1F_TIME_TICKS("time_stamp", IntAutoTime()), - ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) - ) - -class SNMPbulk(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SNMP_PDU_BULK( ASN1F_INTEGER("id",0), - ASN1F_INTEGER("non_repeaters",0), - ASN1F_INTEGER("max_repetitions",0), - ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) - ) - -class SNMPinform(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SNMP_PDU_INFORM( ASN1F_INTEGER("id",0), - ASN1F_enum_INTEGER("error",0, SNMP_error), - ASN1F_INTEGER("error_index",0), - ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) - ) - -class SNMPtrapv2(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SNMP_PDU_TRAPv2( ASN1F_INTEGER("id",0), - ASN1F_enum_INTEGER("error",0, SNMP_error), - ASN1F_INTEGER("error_index",0), - ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) - ) - - -class SNMP(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_enum_INTEGER("version", 1, {0:"v1", 1:"v2c", 2:"v2", 3:"v3"}), - ASN1F_STRING("community",b"public"), - ASN1F_CHOICE("PDU", SNMPget(), - SNMPget, SNMPnext, SNMPresponse, SNMPset, - SNMPtrapv1, SNMPbulk, SNMPinform, SNMPtrapv2) - ) - def answers(self, other): - return ( isinstance(self.PDU, SNMPresponse) and - ( isinstance(other.PDU, SNMPget) or - isinstance(other.PDU, SNMPnext) or - isinstance(other.PDU, SNMPset) ) and - self.PDU.id == other.PDU.id ) - -bind_layers( UDP, SNMP, sport=161) -bind_layers( UDP, SNMP, dport=161) -bind_layers( UDP, SNMP, sport=162) -bind_layers( UDP, SNMP, dport=162) - -def snmpwalk(dst, oid="1", community=b"public"): - try: - while 1: - r = sr1(IP(dst=dst)/UDP(sport=RandShort())/SNMP(community=community, PDU=SNMPnext(varbindlist=[SNMPvarbind(oid=oid)])),timeout=2, chainCC=1, verbose=0, retry=2) - if ICMP in r: - print(repr(r)) - break - if r is None: - print("No answers") - break - print("%-40s: %r" % (r[SNMPvarbind].oid.val,r[SNMPvarbind].value)) - oid = r[SNMPvarbind].oid - - except KeyboardInterrupt: - pass - diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/tftp.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/tftp.py deleted file mode 100644 index 1535e99c..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/tftp.py +++ /dev/null @@ -1,477 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -TFTP (Trivial File Transfer Protocol). -""" - -import os,random -from scapy.packet import * -from scapy.fields import * -from scapy.automaton import * -from scapy.layers.inet import UDP - - - -TFTP_operations = { 1:"RRQ",2:"WRQ",3:"DATA",4:"ACK",5:"ERROR",6:"OACK" } - - -class TFTP(Packet): - name = "TFTP opcode" - fields_desc = [ ShortEnumField("op", 1, TFTP_operations), ] - - - -class TFTP_RRQ(Packet): - name = "TFTP Read Request" - fields_desc = [ StrNullField("filename", ""), - StrNullField("mode", "octet") ] - def answers(self, other): - return 0 - def mysummary(self): - return self.sprintf("RRQ %filename%"),[UDP] - - -class TFTP_WRQ(Packet): - name = "TFTP Write Request" - fields_desc = [ StrNullField("filename", ""), - StrNullField("mode", "octet") ] - def answers(self, other): - return 0 - def mysummary(self): - return self.sprintf("WRQ %filename%"),[UDP] - -class TFTP_DATA(Packet): - name = "TFTP Data" - fields_desc = [ ShortField("block", 0) ] - def answers(self, other): - return self.block == 1 and isinstance(other, TFTP_RRQ) - def mysummary(self): - return self.sprintf("DATA %block%"),[UDP] - -class TFTP_Option(Packet): - fields_desc = [ StrNullField("oname",""), - StrNullField("value","") ] - def extract_padding(self, pkt): - return "",pkt - -class TFTP_Options(Packet): - fields_desc = [ PacketListField("options", [], TFTP_Option, length_from=lambda x:None) ] - - -class TFTP_ACK(Packet): - name = "TFTP Ack" - fields_desc = [ ShortField("block", 0) ] - def answers(self, other): - if isinstance(other, TFTP_DATA): - return self.block == other.block - elif isinstance(other, TFTP_RRQ) or isinstance(other, TFTP_WRQ) or isinstance(other, TFTP_OACK): - return self.block == 0 - return 0 - def mysummary(self): - return self.sprintf("ACK %block%"),[UDP] - -TFTP_Error_Codes = { 0: "Not defined", - 1: "File not found", - 2: "Access violation", - 3: "Disk full or allocation exceeded", - 4: "Illegal TFTP operation", - 5: "Unknown transfer ID", - 6: "File already exists", - 7: "No such user", - 8: "Terminate transfer due to option negotiation", - } - -class TFTP_ERROR(Packet): - name = "TFTP Error" - fields_desc = [ ShortEnumField("errorcode", 0, TFTP_Error_Codes), - StrNullField("errormsg", "")] - def answers(self, other): - return (isinstance(other, TFTP_DATA) or - isinstance(other, TFTP_RRQ) or - isinstance(other, TFTP_WRQ) or - isinstance(other, TFTP_ACK)) - def mysummary(self): - return self.sprintf("ERROR %errorcode%: %errormsg%"),[UDP] - - -class TFTP_OACK(Packet): - name = "TFTP Option Ack" - fields_desc = [ ] - def answers(self, other): - return isinstance(other, TFTP_WRQ) or isinstance(other, TFTP_RRQ) - - -bind_layers(UDP, TFTP, dport=69) -bind_layers(TFTP, TFTP_RRQ, op=1) -bind_layers(TFTP, TFTP_WRQ, op=2) -bind_layers(TFTP, TFTP_DATA, op=3) -bind_layers(TFTP, TFTP_ACK, op=4) -bind_layers(TFTP, TFTP_ERROR, op=5) -bind_layers(TFTP, TFTP_OACK, op=6) -bind_layers(TFTP_RRQ, TFTP_Options) -bind_layers(TFTP_WRQ, TFTP_Options) -bind_layers(TFTP_OACK, TFTP_Options) - - -class TFTP_read(Automaton): - def parse_args(self, filename, server, sport = None, port=69, **kargs): - Automaton.parse_args(self, **kargs) - self.filename = filename - self.server = server - self.port = port - self.sport = sport - - - def master_filter(self, pkt): - return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt - and pkt[UDP].dport == self.my_tid - and (self.server_tid is None or pkt[UDP].sport == self.server_tid) ) - - # BEGIN - @ATMT.state(initial=1) - def BEGIN(self): - self.blocksize=512 - self.my_tid = self.sport or RandShort()._fix() - bind_bottom_up(UDP, TFTP, dport=self.my_tid) - self.server_tid = None - self.res = "" - - self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP() - self.last_packet = self.l3/TFTP_RRQ(filename=self.filename, mode="octet") - self.send(self.last_packet) - self.awaiting=1 - - raise self.WAITING() - - # WAITING - @ATMT.state() - def WAITING(self): - pass - - - @ATMT.receive_condition(WAITING) - def receive_data(self, pkt): - if TFTP_DATA in pkt and pkt[TFTP_DATA].block == self.awaiting: - if self.server_tid is None: - self.server_tid = pkt[UDP].sport - self.l3[UDP].dport = self.server_tid - raise self.RECEIVING(pkt) - - @ATMT.receive_condition(WAITING, prio=1) - def receive_error(self, pkt): - if TFTP_ERROR in pkt: - raise self.ERROR(pkt) - - - @ATMT.timeout(WAITING, 3) - def timeout_waiting(self): - raise self.WAITING() - @ATMT.action(timeout_waiting) - def retransmit_last_packet(self): - self.send(self.last_packet) - - @ATMT.action(receive_data) -# @ATMT.action(receive_error) - def send_ack(self): - self.last_packet = self.l3 / TFTP_ACK(block = self.awaiting) - self.send(self.last_packet) - - - # RECEIVED - @ATMT.state() - def RECEIVING(self, pkt): - if conf.raw_layer in pkt: - recvd = pkt[conf.raw_layer].load - else: - recvd = "" - self.res += recvd - self.awaiting += 1 - if len(recvd) == self.blocksize: - raise self.WAITING() - raise self.END() - - # ERROR - @ATMT.state(error=1) - def ERROR(self,pkt): - split_bottom_up(UDP, TFTP, dport=self.my_tid) - return pkt[TFTP_ERROR].summary() - - #END - @ATMT.state(final=1) - def END(self): - split_bottom_up(UDP, TFTP, dport=self.my_tid) - return self.res - - - - -class TFTP_write(Automaton): - def parse_args(self, filename, data, server, sport=None, port=69,**kargs): - Automaton.parse_args(self, **kargs) - self.filename = filename - self.server = server - self.port = port - self.sport = sport - self.blocksize = 512 - self.origdata = data - - def master_filter(self, pkt): - return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt - and pkt[UDP].dport == self.my_tid - and (self.server_tid is None or pkt[UDP].sport == self.server_tid) ) - - - # BEGIN - @ATMT.state(initial=1) - def BEGIN(self): - self.data = [ self.origdata[i*self.blocksize:(i+1)*self.blocksize] - for i in range( len(self.origdata)/self.blocksize+1) ] - self.my_tid = self.sport or RandShort()._fix() - bind_bottom_up(UDP, TFTP, dport=self.my_tid) - self.server_tid = None - - self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP() - self.last_packet = self.l3/TFTP_WRQ(filename=self.filename, mode="octet") - self.send(self.last_packet) - self.res = "" - self.awaiting=0 - - raise self.WAITING_ACK() - - # WAITING_ACK - @ATMT.state() - def WAITING_ACK(self): - pass - - @ATMT.receive_condition(WAITING_ACK) - def received_ack(self,pkt): - if TFTP_ACK in pkt and pkt[TFTP_ACK].block == self.awaiting: - if self.server_tid is None: - self.server_tid = pkt[UDP].sport - self.l3[UDP].dport = self.server_tid - raise self.SEND_DATA() - - @ATMT.receive_condition(WAITING_ACK) - def received_error(self, pkt): - if TFTP_ERROR in pkt: - raise self.ERROR(pkt) - - @ATMT.timeout(WAITING_ACK, 3) - def timeout_waiting(self): - raise self.WAITING_ACK() - @ATMT.action(timeout_waiting) - def retransmit_last_packet(self): - self.send(self.last_packet) - - # SEND_DATA - @ATMT.state() - def SEND_DATA(self): - self.awaiting += 1 - self.last_packet = self.l3/TFTP_DATA(block=self.awaiting)/self.data.pop(0) - self.send(self.last_packet) - if self.data: - raise self.WAITING_ACK() - raise self.END() - - - # ERROR - @ATMT.state(error=1) - def ERROR(self,pkt): - split_bottom_up(UDP, TFTP, dport=self.my_tid) - return pkt[TFTP_ERROR].summary() - - # END - @ATMT.state(final=1) - def END(self): - split_bottom_up(UDP, TFTP, dport=self.my_tid) - - -class TFTP_WRQ_server(Automaton): - - def parse_args(self, ip=None, sport=None, *args, **kargs): - Automaton.parse_args(self, *args, **kargs) - self.ip = ip - self.sport = sport - - def master_filter(self, pkt): - return TFTP in pkt and (not self.ip or pkt[IP].dst == self.ip) - - @ATMT.state(initial=1) - def BEGIN(self): - self.blksize=512 - self.blk=1 - self.filedata="" - self.my_tid = self.sport or random.randint(10000,65500) - bind_bottom_up(UDP, TFTP, dport=self.my_tid) - - @ATMT.receive_condition(BEGIN) - def receive_WRQ(self,pkt): - if TFTP_WRQ in pkt: - raise self.WAIT_DATA().action_parameters(pkt) - - @ATMT.action(receive_WRQ) - def ack_WRQ(self, pkt): - ip = pkt[IP] - self.ip = ip.dst - self.dst = ip.src - self.filename = pkt[TFTP_WRQ].filename - options = pkt[TFTP_Options] - self.l3 = IP(src=ip.dst, dst=ip.src)/UDP(sport=self.my_tid, dport=pkt.sport)/TFTP() - if options is None: - self.last_packet = self.l3/TFTP_ACK(block=0) - self.send(self.last_packet) - else: - opt = [x for x in options.options if x.oname.upper() == "BLKSIZE"] - if opt: - self.blksize = int(opt[0].value) - self.debug(2,"Negotiated new blksize at %i" % self.blksize) - self.last_packet = self.l3/TFTP_OACK()/TFTP_Options(options=opt) - self.send(self.last_packet) - - @ATMT.state() - def WAIT_DATA(self): - pass - - @ATMT.timeout(WAIT_DATA, 1) - def resend_ack(self): - self.send(self.last_packet) - raise self.WAIT_DATA() - - @ATMT.receive_condition(WAIT_DATA) - def receive_data(self, pkt): - if TFTP_DATA in pkt: - data = pkt[TFTP_DATA] - if data.block == self.blk: - raise self.DATA(data) - - @ATMT.action(receive_data) - def ack_data(self): - self.last_packet = self.l3/TFTP_ACK(block = self.blk) - self.send(self.last_packet) - - @ATMT.state() - def DATA(self, data): - self.filedata += data.load - if len(data.load) < self.blksize: - raise self.END() - self.blk += 1 - raise self.WAIT_DATA() - - @ATMT.state(final=1) - def END(self): - return self.filename,self.filedata - split_bottom_up(UDP, TFTP, dport=self.my_tid) - - -class TFTP_RRQ_server(Automaton): - def parse_args(self, store=None, joker=None, dir=None, ip=None, sport=None, serve_one=False, **kargs): - Automaton.parse_args(self,**kargs) - if store is None: - store = {} - if dir is not None: - self.dir = os.path.join(os.path.abspath(dir),"") - else: - self.dir = None - self.store = store - self.joker = joker - self.ip = ip - self.sport = sport - self.serve_one = serve_one - self.my_tid = self.sport or random.randint(10000,65500) - bind_bottom_up(UDP, TFTP, dport=self.my_tid) - - def master_filter(self, pkt): - return TFTP in pkt and (not self.ip or pkt[IP].dst == self.ip) - - @ATMT.state(initial=1) - def WAIT_RRQ(self): - self.blksize=512 - self.blk=0 - - @ATMT.receive_condition(WAIT_RRQ) - def receive_rrq(self, pkt): - if TFTP_RRQ in pkt: - raise self.RECEIVED_RRQ(pkt) - - - @ATMT.state() - def RECEIVED_RRQ(self, pkt): - ip = pkt[IP] - options = pkt[TFTP_Options] - self.l3 = IP(src=ip.dst, dst=ip.src)/UDP(sport=self.my_tid, dport=ip.sport)/TFTP() - self.filename = pkt[TFTP_RRQ].filename - self.blk=1 - self.data = None - if self.filename in self.store: - self.data = self.store[self.filename] - elif self.dir is not None: - fn = os.path.abspath(os.path.join(self.dir, self.filename)) - if fn.startswith(self.dir): # Check we're still in the server's directory - try: - self.data=open(fn).read() - except IOError: - pass - if self.data is None: - self.data = self.joker - - if options: - opt = [x for x in options.options if x.oname.upper() == "BLKSIZE"] - if opt: - self.blksize = int(opt[0].value) - self.debug(2,"Negotiated new blksize at %i" % self.blksize) - self.last_packet = self.l3/TFTP_OACK()/TFTP_Options(options=opt) - self.send(self.last_packet) - - - - - @ATMT.condition(RECEIVED_RRQ) - def file_in_store(self): - if self.data is not None: - self.blknb = len(self.data)/self.blksize+1 - raise self.SEND_FILE() - - @ATMT.condition(RECEIVED_RRQ) - def file_not_found(self): - if self.data is None: - raise self.WAIT_RRQ() - @ATMT.action(file_not_found) - def send_error(self): - self.send(self.l3/TFTP_ERROR(errorcode=1, errormsg=TFTP_Error_Codes[1])) - - @ATMT.state() - def SEND_FILE(self): - self.send(self.l3/TFTP_DATA(block=self.blk)/self.data[(self.blk-1)*self.blksize:self.blk*self.blksize]) - - @ATMT.timeout(SEND_FILE, 3) - def timeout_waiting_ack(self): - raise self.SEND_FILE() - - @ATMT.receive_condition(SEND_FILE) - def received_ack(self, pkt): - if TFTP_ACK in pkt and pkt[TFTP_ACK].block == self.blk: - raise self.RECEIVED_ACK() - @ATMT.state() - def RECEIVED_ACK(self): - self.blk += 1 - - @ATMT.condition(RECEIVED_ACK) - def no_more_data(self): - if self.blk > self.blknb: - if self.serve_one: - raise self.END() - raise self.WAIT_RRQ() - @ATMT.condition(RECEIVED_ACK, prio=2) - def data_remaining(self): - raise self.SEND_FILE() - - @ATMT.state(final=1) - def END(self): - split_bottom_up(UDP, TFTP, dport=self.my_tid) - - - - diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/vrrp.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/vrrp.py deleted file mode 100644 index e2818381..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/vrrp.py +++ /dev/null @@ -1,39 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## Copyright (C) 6WIND <olivier.matz@6wind.com> -## This program is published under a GPLv2 license - -""" -VRRP (Virtual Router Redundancy Protocol). -""" - -from scapy.packet import * -from scapy.fields import * -from scapy.layers.inet import IP - -IPPROTO_VRRP=112 - -# RFC 3768 - Virtual Router Redundancy Protocol (VRRP) -class VRRP(Packet): - fields_desc = [ - BitField("version" , 2, 4), - BitField("type" , 1, 4), - ByteField("vrid", 1), - ByteField("priority", 100), - FieldLenField("ipcount", None, count_of="addrlist", fmt="B"), - ByteField("authtype", 0), - ByteField("adv", 1), - XShortField("chksum", None), - FieldListField("addrlist", [], IPField("", "0.0.0.0"), - count_from = lambda pkt: pkt.ipcount), - IntField("auth1", 0), - IntField("auth2", 0) ] - - def post_build(self, p, pay): - if self.chksum is None: - ck = checksum(p) - p = p[:6]+bytes([(ck>>8),(ck&0xff)])+p[8:] - return p - -bind_layers( IP, VRRP, proto=IPPROTO_VRRP) diff --git a/scripts/external_libs/scapy-python3-0.18/scapy/layers/x509.py b/scripts/external_libs/scapy-python3-0.18/scapy/layers/x509.py deleted file mode 100644 index 18aaa5e3..00000000 --- a/scripts/external_libs/scapy-python3-0.18/scapy/layers/x509.py +++ /dev/null @@ -1,108 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi <phil@secdev.org> -## This program is published under a GPLv2 license - -""" -X.509 certificates. -""" - -from scapy.asn1packet import * -from scapy.asn1fields import * - -########## -## X509 ## -########## - -######[ ASN1 class ]###### - -class ASN1_Class_X509(ASN1_Class_UNIVERSAL): - name="X509" - CONT0 = 0xa0 - CONT1 = 0xa1 - CONT2 = 0xa2 - CONT3 = 0xa3 - -class ASN1_X509_CONT0(ASN1_SEQUENCE): - tag = ASN1_Class_X509.CONT0 - -class ASN1_X509_CONT1(ASN1_SEQUENCE): - tag = ASN1_Class_X509.CONT1 - -class ASN1_X509_CONT2(ASN1_SEQUENCE): - tag = ASN1_Class_X509.CONT2 - -class ASN1_X509_CONT3(ASN1_SEQUENCE): - tag = ASN1_Class_X509.CONT3 - -######[ BER codecs ]####### - -class BERcodec_X509_CONT0(BERcodec_SEQUENCE): - tag = ASN1_Class_X509.CONT0 - -class BERcodec_X509_CONT1(BERcodec_SEQUENCE): - tag = ASN1_Class_X509.CONT1 - -class BERcodec_X509_CONT2(BERcodec_SEQUENCE): - tag = ASN1_Class_X509.CONT2 - -class BERcodec_X509_CONT3(BERcodec_SEQUENCE): - tag = ASN1_Class_X509.CONT3 - -######[ ASN1 fields ]###### - -class ASN1F_X509_CONT0(ASN1F_SEQUENCE): - ASN1_tag = ASN1_Class_X509.CONT0 - -class ASN1F_X509_CONT1(ASN1F_SEQUENCE): - ASN1_tag = ASN1_Class_X509.CONT1 - -class ASN1F_X509_CONT2(ASN1F_SEQUENCE): - ASN1_tag = ASN1_Class_X509.CONT2 - -class ASN1F_X509_CONT3(ASN1F_SEQUENCE): - ASN1_tag = ASN1_Class_X509.CONT3 - -######[ X509 packets ]###### - -class X509RDN(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SET( - ASN1F_SEQUENCE( ASN1F_OID("oid","2.5.4.6"), - ASN1F_PRINTABLE_STRING("value","") - ) - ) - -class X509v3Ext(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_field("val",ASN1_NULL(0)) - - -class X509Cert(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_SEQUENCE( - ASN1F_optionnal(ASN1F_X509_CONT0(ASN1F_INTEGER("version",3))), - ASN1F_INTEGER("sn",1), - ASN1F_SEQUENCE(ASN1F_OID("sign_algo","1.2.840.113549.1.1.5"), - ASN1F_field("sa_value",ASN1_NULL(0))), - ASN1F_SEQUENCE_OF("issuer",[],X509RDN), - ASN1F_SEQUENCE(ASN1F_UTC_TIME("not_before",ZuluTime(-600)), # ten minutes ago - ASN1F_UTC_TIME("not_after",ZuluTime(+86400))), # for 24h - ASN1F_SEQUENCE_OF("subject",[],X509RDN), - ASN1F_SEQUENCE( - ASN1F_SEQUENCE(ASN1F_OID("pubkey_algo","1.2.840.113549.1.1.1"), - ASN1F_field("pk_value",ASN1_NULL(0))), - ASN1F_BIT_STRING("pubkey","") - ), - ASN1F_optionnal(ASN1F_X509_CONT3(ASN1F_SEQUENCE_OF("x509v3ext",[],X509v3Ext))), - - ), - ASN1F_SEQUENCE(ASN1F_OID("sign_algo2","1.2.840.113549.1.1.5"), - ASN1F_field("sa2_value",ASN1_NULL(0))), - ASN1F_BIT_STRING("signature","") - ) - - - - |