diff --git a/scripts/external_libs/scapy-2.4.3/scapy/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/__init__.py deleted file mode 100644 index 9f9a77a435..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/__init__.py +++ /dev/null @@ -1,98 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Scapy: create, send, sniff, dissect and manipulate network packets. - -Usable either from an interactive console or as a Python library. -http://www.secdev.org/projects/scapy -""" - -import os -import re -import subprocess - - -_SCAPY_PKG_DIR = os.path.dirname(__file__) - - -def _version_from_git_describe(): - """ - Read the version from ``git describe``. It returns the latest tag with an - optional suffix if the current directory is not exactly on the tag. - - Example:: - - $ git describe --always - v2.3.2-346-g164a52c075c8 - - The tag prefix (``v``) and the git commit sha1 (``-g164a52c075c8``) are - removed if present. - - If the current directory is not exactly on the tag, a ``.devN`` suffix is - appended where N is the number of commits made after the last tag. - - Example:: - - >>> _version_from_git_describe() - '2.3.2.dev346' - """ - if not os.path.isdir(os.path.join(os.path.dirname(_SCAPY_PKG_DIR), '.git')): # noqa: E501 - raise ValueError('not in scapy git repo') - - process = subprocess.Popen(['git', 'describe', '--always'], - cwd=_SCAPY_PKG_DIR, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - - out, err = process.communicate() - - if process.returncode == 0: - tag = out.decode().strip() - match = re.match('^v?(.+?)-(\\d+)-g[a-f0-9]+$', tag) - if match: - # remove the 'v' prefix and add a '.devN' suffix - return '%s.dev%s' % (match.group(1), match.group(2)) - else: - # just remove the 'v' prefix - return re.sub('^v', '', tag) - else: - raise subprocess.CalledProcessError(process.returncode, err) - - -def _version(): - version_file = os.path.join(_SCAPY_PKG_DIR, 'VERSION') - try: - tag = _version_from_git_describe() - # successfully read the tag from git, write it in VERSION for - # installation and/or archive generation. - with open(version_file, 'w') as fdesc: - fdesc.write(tag) - return tag - except Exception: - # failed to read the tag from git, try to read it from a VERSION file - try: - with open(version_file, 'r') as fdsec: - tag = fdsec.read() - return tag - except Exception: - # Rely on git archive "export-subst" git attribute. - # See 'man gitattributes' for more details. - git_archive_id = '3047580162 (tag: v2.4.3)' - sha1 = git_archive_id.strip().split()[0] - match = re.search('tag:(\\S+)', git_archive_id) - if match: - return "git-archive.dev" + match.group(1) - elif sha1: - return "git-archive.dev" + sha1 - else: - return 'unknown.version' - - -VERSION = __version__ = _version() -VERSION_MAIN = re.search(r"[0-9.]+", VERSION).group() - -if __name__ == "__main__": - from scapy.main import interact - interact() diff --git a/scripts/external_libs/scapy-2.4.3/scapy/__main__.py b/scripts/external_libs/scapy-2.4.3/scapy/__main__.py deleted file mode 100644 index 5a08e1347c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/__main__.py +++ /dev/null @@ -1,15 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Scapy: create, send, sniff, dissect and manipulate network packets. - -Usable either from an interactive console or as a Python library. -http://www.secdev.org/projects/scapy -""" - -from scapy.main import interact - -interact() diff --git a/scripts/external_libs/scapy-2.4.3/scapy/abc.py b/scripts/external_libs/scapy-2.4.3/scapy/abc.py deleted file mode 100644 index 3d5f06e258..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/abc.py +++ /dev/null @@ -1 +0,0 @@ -from config import conf diff --git a/scripts/external_libs/scapy-2.4.3/scapy/all.py b/scripts/external_libs/scapy-2.4.3/scapy/all.py deleted file mode 100644 index 10500b0f92..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/all.py +++ /dev/null @@ -1,55 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Aggregate top level objects from all Scapy modules. -""" - -# flake8: noqa: F403 - -from scapy.base_classes import * -from scapy.config import * -from scapy.dadict import * -from scapy.data import * -from scapy.error import * -# TRex Changes - All the commented lines are TRex changes. -# from scapy.themes import * -from scapy.arch import * - -from scapy.plist import * -from scapy.fields import * -from scapy.packet import * -# from scapy.asn1fields import * -# from scapy.asn1packet import * - -from scapy.utils import * -# from scapy.route import * -# from scapy.sendrecv import * -# from scapy.sessions import * -# from scapy.supersocket import * -# from scapy.volatile import * -# from scapy.as_resolvers import * - -# from scapy.automaton import * -# from scapy.autorun import * - -from scapy.main import * -# from scapy.consts import * -# from scapy.compat import raw # noqa: F401 - -from scapy.layers.all import * - -# from scapy.asn1.asn1 import * -# from scapy.asn1.ber import * -# from scapy.asn1.mib import * - -# from scapy.pipetool import * -# from scapy.scapypipes import * - -# if conf.ipv6_enabled: # noqa: F405 -# from scapy.utils6 import * # noqa: F401 -# from scapy.route6 import * # noqa: F401 - -# from scapy.ansmachine import * diff --git a/scripts/external_libs/scapy-2.4.3/scapy/ansmachine.py b/scripts/external_libs/scapy-2.4.3/scapy/ansmachine.py deleted file mode 100644 index ef78c18449..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/ansmachine.py +++ /dev/null @@ -1,131 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Answering machines. -""" - -######################## -# Answering machines # -######################## - -from __future__ import absolute_import -from __future__ import print_function -from scapy.sendrecv import send, sniff -from scapy.config import conf -from scapy.error import log_interactive -import scapy.modules.six as six - - -class ReferenceAM(type): - def __new__(cls, name, bases, dct): - obj = super(ReferenceAM, cls).__new__(cls, name, bases, dct) - if obj.function_name: - globals()[obj.function_name] = lambda obj=obj, *args, **kargs: obj(*args, **kargs)() # noqa: E501 - return obj - - -class AnsweringMachine(six.with_metaclass(ReferenceAM, object)): - function_name = "" - filter = None - sniff_options = {"store": 0} - sniff_options_list = ["store", "iface", "count", "promisc", "filter", "type", "prn", "stop_filter"] # noqa: E501 - send_options = {"verbose": 0} - send_options_list = ["iface", "inter", "loop", "verbose"] - send_function = staticmethod(send) - - def __init__(self, **kargs): - self.mode = 0 - if self.filter: - kargs.setdefault("filter", self.filter) - kargs.setdefault("prn", self.reply) - self.optam1 = {} - self.optam2 = {} - self.optam0 = {} - doptsend, doptsniff = self.parse_all_options(1, kargs) - self.defoptsend = self.send_options.copy() - self.defoptsend.update(doptsend) - self.defoptsniff = self.sniff_options.copy() - self.defoptsniff.update(doptsniff) - self.optsend, self.optsniff = [{}, {}] - - def __getattr__(self, attr): - for dct in [self.optam2, self.optam1]: - if attr in dct: - return dct[attr] - raise AttributeError(attr) - - def __setattr__(self, attr, val): - mode = self.__dict__.get("mode", 0) - if mode == 0: - self.__dict__[attr] = val - else: - [self.optam1, self.optam2][mode - 1][attr] = val - - def parse_options(self): - pass - - def parse_all_options(self, mode, kargs): - sniffopt = {} - sendopt = {} - for k in list(kargs): # use list(): kargs is modified in the loop - if k in self.sniff_options_list: - sniffopt[k] = kargs[k] - if k in self.send_options_list: - sendopt[k] = kargs[k] - if k in self.sniff_options_list + self.send_options_list: - del kargs[k] - if mode != 2 or kargs: - if mode == 1: - self.optam0 = kargs - elif mode == 2 and kargs: - k = self.optam0.copy() - k.update(kargs) - self.parse_options(**k) - kargs = k - omode = self.__dict__.get("mode", 0) - self.__dict__["mode"] = mode - self.parse_options(**kargs) - self.__dict__["mode"] = omode - return sendopt, sniffopt - - def is_request(self, req): - return 1 - - def make_reply(self, req): - return req - - def send_reply(self, reply): - self.send_function(reply, **self.optsend) - - def print_reply(self, req, reply): - print("%s ==> %s" % (req.summary(), reply.summary())) - - def reply(self, pkt): - if not self.is_request(pkt): - return - reply = self.make_reply(pkt) - self.send_reply(reply) - if conf.verb >= 0: - self.print_reply(pkt, reply) - - def run(self, *args, **kargs): - log_interactive.warning("run() method deprecated. The instance is now callable") # noqa: E501 - self(*args, **kargs) - - def __call__(self, *args, **kargs): - optsend, optsniff = self.parse_all_options(2, kargs) - self.optsend = self.defoptsend.copy() - self.optsend.update(optsend) - self.optsniff = self.defoptsniff.copy() - self.optsniff.update(optsniff) - - try: - self.sniff() - except KeyboardInterrupt: - print("Interrupted by user") - - def sniff(self): - sniff(**self.optsniff) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/__init__.py deleted file mode 100644 index 638df4ac8c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/__init__.py +++ /dev/null @@ -1,99 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Operating system specific functionality. -""" - -from __future__ import absolute_import -import socket - -import scapy.consts -from scapy.consts import LINUX, SOLARIS, WINDOWS, BSD -from scapy.error import Scapy_Exception -from scapy.config import conf, _set_conf_sockets -from scapy.pton_ntop import inet_pton, inet_ntop -from scapy.data import ARPHDR_ETHER, ARPHDR_LOOPBACK, IPV6_ADDR_GLOBAL -from scapy.compat import orb - - -def str2mac(s): - return ("%02x:" * 6)[:-1] % tuple(orb(x) for x in s) - - -if not WINDOWS: - if not conf.use_pcap and not conf.use_dnet: - from scapy.arch.bpf.core import get_if_raw_addr - - -def get_if_addr(iff): - return inet_ntop(socket.AF_INET, get_if_raw_addr(iff)) - - -def get_if_hwaddr(iff): - addrfamily, mac = get_if_raw_hwaddr(iff) # noqa: F405 - if addrfamily in [ARPHDR_ETHER, ARPHDR_LOOPBACK]: - return str2mac(mac) - else: - raise Scapy_Exception("Unsupported address family (%i) for interface [%s]" % (addrfamily, iff)) # noqa: E501 - - -# Next step is to import following architecture specific functions: -# def get_if_raw_hwaddr(iff) -# def get_if_raw_addr(iff): -# def get_if_list(): -# def get_working_if(): -# def attach_filter(s, filter, iface): -# def set_promisc(s,iff,val=1): -# def read_routes(): -# def read_routes6(): -# def get_if(iff,cmd): -# def get_if_index(iff): - -if LINUX: - from scapy.arch.linux import * # noqa F403 -elif BSD: - from scapy.arch.unix import read_routes, read_routes6, in6_getifaddr # noqa: F401, E501 - from scapy.arch.bpf.core import * # noqa F403 - if not (conf.use_pcap or conf.use_dnet): - # Native - from scapy.arch.bpf.supersocket import * # noqa F403 - conf.use_bpf = True -elif SOLARIS: - from scapy.arch.solaris import * # noqa F403 -elif WINDOWS: - # TRex Change - No support for Windows. - pass - # from scapy.arch.windows import * # noqa F403 - # from scapy.arch.windows.native import * # noqa F403 - - -if conf.iface is None: - conf.iface = scapy.consts.LOOPBACK_INTERFACE - -_set_conf_sockets() # Apply config - - -def get_if_addr6(iff): - """ - Returns the main global unicast address associated with provided - interface, in human readable form. If no global address is found, - None is returned. - """ - return next((x[0] for x in in6_getifaddr() - if x[2] == iff and x[1] == IPV6_ADDR_GLOBAL), None) - - -def get_if_raw_addr6(iff): - """ - Returns the main global unicast address associated with provided - interface, in network format. If no global address is found, None - is returned. - """ - ip6 = get_if_addr6(iff) - if ip6 is not None: - return inet_pton(socket.AF_INET6, ip6) - - return None diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/bpf/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/bpf/__init__.py deleted file mode 100644 index c67498a55c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/bpf/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Guillaume Valadon - -""" -Scapy *BSD native support -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/bpf/consts.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/bpf/consts.py deleted file mode 100644 index abb3be59e6..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/bpf/consts.py +++ /dev/null @@ -1,27 +0,0 @@ -# Guillaume Valadon - -""" -Scapy *BSD native support - constants -""" - -from ctypes import sizeof - -from scapy.arch.common import bpf_program -from scapy.data import MTU - - -SIOCGIFFLAGS = 0xc0206911 -BPF_BUFFER_LENGTH = MTU - -# From net/bpf.h -BIOCIMMEDIATE = 0x80044270 -BIOCGSTATS = 0x4008426f -BIOCPROMISC = 0x20004269 -BIOCSETIF = 0x8020426c -BIOCSBLEN = 0xc0044266 -BIOCGBLEN = 0x40044266 -BIOCSETF = 0x80004267 | ((sizeof(bpf_program) & 0x1fff) << 16) -BIOCSDLT = 0x80044278 -BIOCSHDRCMPLT = 0x80044275 -BIOCGDLT = 0x4004426a -DLT_IEEE802_11_RADIO = 127 diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/bpf/core.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/bpf/core.py deleted file mode 100644 index 35ba58d398..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/bpf/core.py +++ /dev/null @@ -1,212 +0,0 @@ -# Guillaume Valadon - -""" -Scapy *BSD native support - core -""" - -from __future__ import absolute_import - -from ctypes import cdll, cast, pointer -from ctypes import c_int, c_ulong, c_char_p -from ctypes.util import find_library -import fcntl -import os -import re -import socket -import struct -import subprocess - -from scapy.arch.bpf.consts import BIOCSETF, SIOCGIFFLAGS, BIOCSETIF -from scapy.arch.common import get_if, compile_filter -from scapy.compat import plain_str -from scapy.config import conf -from scapy.consts import LOOPBACK_NAME -from scapy.data import ARPHDR_LOOPBACK, ARPHDR_ETHER -from scapy.error import Scapy_Exception, warning -from scapy.modules.six.moves import range - - -# ctypes definitions - -LIBC = cdll.LoadLibrary(find_library("c")) -LIBC.ioctl.argtypes = [c_int, c_ulong, c_char_p] -LIBC.ioctl.restype = c_int - - -# Addresses manipulation functions - -def get_if_raw_addr(ifname): - """Returns the IPv4 address configured on 'ifname', packed with inet_pton.""" # noqa: E501 - - # Get ifconfig output - subproc = subprocess.Popen( - [conf.prog.ifconfig, ifname], - close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE - ) - stdout, stderr = subproc.communicate() - if subproc.returncode: - warning("Failed to execute ifconfig: (%s)", plain_str(stderr)) - return b"\0\0\0\0" - # Get IPv4 addresses - - addresses = [ - line for line in plain_str(stdout).splitlines() - if "inet " in line - ] - - if not addresses: - warning("No IPv4 address found on %s !", ifname) - return b"\0\0\0\0" - - # Pack the first address - address = addresses[0].split(' ')[1] - if '/' in address: # NetBSD 8.0 - address = address.split("/")[0] - return socket.inet_pton(socket.AF_INET, address) - - -def get_if_raw_hwaddr(ifname): - """Returns the packed MAC address configured on 'ifname'.""" - - NULL_MAC_ADDRESS = b'\x00' * 6 - - # Handle the loopback interface separately - if ifname == LOOPBACK_NAME: - return (ARPHDR_LOOPBACK, NULL_MAC_ADDRESS) - - # Get ifconfig output - subproc = subprocess.Popen( - [conf.prog.ifconfig, ifname], - close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE - ) - stdout, stderr = subproc.communicate() - if subproc.returncode: - raise Scapy_Exception("Failed to execute ifconfig: (%s)" % - (plain_str(stderr))) - - # Get MAC addresses - addresses = [ - line for line in plain_str(stdout).splitlines() if ( - "ether" in line or "lladdr" in line or "address" in line - ) - ] - if not addresses: - raise Scapy_Exception("No MAC address found on %s !" % ifname) - - # Pack and return the MAC address - mac = addresses[0].split(' ')[1] - mac = [chr(int(b, 16)) for b in mac.split(':')] - return (ARPHDR_ETHER, ''.join(mac)) - - -# BPF specific functions - -def get_dev_bpf(): - """Returns an opened BPF file object""" - - # Get the first available BPF handle - for bpf in range(256): - try: - fd = os.open("/dev/bpf%i" % bpf, os.O_RDWR) - return (fd, bpf) - except OSError: - continue - - raise Scapy_Exception("No /dev/bpf handle is available !") - - -def attach_filter(fd, bpf_filter, iface): - """Attach a BPF filter to the BPF file descriptor""" - bp = compile_filter(bpf_filter, iface) - # Assign the BPF program to the interface - ret = LIBC.ioctl(c_int(fd), BIOCSETF, cast(pointer(bp), c_char_p)) - if ret < 0: - raise Scapy_Exception("Can't attach the BPF filter !") - - -# Interface manipulation functions - -def get_if_list(): - """Returns a list containing all network interfaces.""" - - # Get ifconfig output - subproc = subprocess.Popen( - [conf.prog.ifconfig], - close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE - ) - stdout, stderr = subproc.communicate() - if subproc.returncode: - raise Scapy_Exception("Failed to execute ifconfig: (%s)" % - (plain_str(stderr))) - - interfaces = [ - line[:line.find(':')] for line in plain_str(stdout).splitlines() - if ": flags" in line.lower() - ] - return interfaces - - -_IFNUM = re.compile(r"([0-9]*)([ab]?)$") - - -def get_working_ifaces(): - """ - Returns an ordered list of interfaces that could be used with BPF. - Note: the order mimics pcap_findalldevs() behavior - """ - - # Only root is allowed to perform the following ioctl() call - if os.getuid() != 0: - return [] - - # Test all network interfaces - interfaces = [] - for ifname in get_if_list(): - - # Unlike pcap_findalldevs(), we do not care of loopback interfaces. - if ifname == LOOPBACK_NAME: - continue - - # Get interface flags - try: - result = get_if(ifname, SIOCGIFFLAGS) - except IOError: - warning("ioctl(SIOCGIFFLAGS) failed on %s !", ifname) - continue - - # Convert flags - ifflags = struct.unpack("16xH14x", result)[0] - if ifflags & 0x1: # IFF_UP - - # Get a BPF handle - fd = get_dev_bpf()[0] - if fd is None: - raise Scapy_Exception("No /dev/bpf are available !") - - # Check if the interface can be used - try: - fcntl.ioctl(fd, BIOCSETIF, struct.pack("16s16x", - ifname.encode())) - except IOError: - pass - else: - ifnum, ifab = _IFNUM.search(ifname).groups() - interfaces.append((ifname, int(ifnum) if ifnum else -1, ifab)) - finally: - # Close the file descriptor - os.close(fd) - - # Sort to mimic pcap_findalldevs() order - interfaces.sort(key=lambda elt: (elt[1], elt[2], elt[0])) - - return [iface[0] for iface in interfaces] - - -def get_working_if(): - """Returns the first interface than can be used with BPF""" - - ifaces = get_working_ifaces() - if not ifaces: - # A better interface will be selected later using the routing table - return LOOPBACK_NAME - return ifaces[0] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/bpf/supersocket.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/bpf/supersocket.py deleted file mode 100644 index 7c887ce436..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/bpf/supersocket.py +++ /dev/null @@ -1,400 +0,0 @@ -# Guillaume Valadon - -""" -Scapy *BSD native support - BPF sockets -""" - -import errno -import fcntl -import os -from select import select -import struct -import time - -from scapy.arch.bpf.core import get_dev_bpf, attach_filter -from scapy.arch.bpf.consts import BIOCGBLEN, BIOCGDLT, BIOCGSTATS, \ - BIOCIMMEDIATE, BIOCPROMISC, BIOCSBLEN, BIOCSETIF, BIOCSHDRCMPLT, \ - BPF_BUFFER_LENGTH, BIOCSDLT, DLT_IEEE802_11_RADIO -from scapy.config import conf -from scapy.consts import FREEBSD, NETBSD, DARWIN -from scapy.data import ETH_P_ALL -from scapy.error import Scapy_Exception, warning -from scapy.supersocket import SuperSocket -from scapy.compat import raw - - -if FREEBSD or NETBSD: - BPF_ALIGNMENT = 8 # sizeof(long) -else: - BPF_ALIGNMENT = 4 # sizeof(int32_t) - - -# SuperSockets definitions - -class _L2bpfSocket(SuperSocket): - """"Generic Scapy BPF Super Socket""" - - desc = "read/write packets using BPF" - nonblocking_socket = True - - def __init__(self, iface=None, type=ETH_P_ALL, promisc=None, filter=None, - nofilter=0, monitor=False): - self.fd_flags = None - self.assigned_interface = None - - # SuperSocket mandatory variables - if promisc is None: - self.promisc = conf.sniff_promisc - else: - self.promisc = promisc - - if iface is None: - self.iface = conf.iface - else: - self.iface = iface - - # Get the BPF handle - (self.ins, self.dev_bpf) = get_dev_bpf() - self.outs = self.ins - - # Set the BPF buffer length - try: - fcntl.ioctl(self.ins, BIOCSBLEN, struct.pack('I', BPF_BUFFER_LENGTH)) # noqa: E501 - except IOError: - raise Scapy_Exception("BIOCSBLEN failed on /dev/bpf%i" % - self.dev_bpf) - - # Assign the network interface to the BPF handle - try: - fcntl.ioctl(self.ins, BIOCSETIF, struct.pack("16s16x", self.iface.encode())) # noqa: E501 - except IOError: - raise Scapy_Exception("BIOCSETIF failed on %s" % self.iface) - self.assigned_interface = self.iface - - # Set the interface into promiscuous - if self.promisc: - self.set_promisc(1) - - # Set the interface to monitor mode - # Note: - trick from libpcap/pcap-bpf.c - monitor_mode() - # - it only works on OS X 10.5 and later - if DARWIN and monitor: - dlt_radiotap = struct.pack('I', DLT_IEEE802_11_RADIO) - try: - fcntl.ioctl(self.ins, BIOCSDLT, dlt_radiotap) - except IOError: - raise Scapy_Exception("Can't set %s into monitor mode!" % - self.iface) - - # Don't block on read - try: - fcntl.ioctl(self.ins, BIOCIMMEDIATE, struct.pack('I', 1)) - except IOError: - raise Scapy_Exception("BIOCIMMEDIATE failed on /dev/bpf%i" % - self.dev_bpf) - - # Scapy will provide the link layer source address - # Otherwise, it is written by the kernel - try: - fcntl.ioctl(self.ins, BIOCSHDRCMPLT, struct.pack('i', 1)) - except IOError: - raise Scapy_Exception("BIOCSHDRCMPLT failed on /dev/bpf%i" % - self.dev_bpf) - - # Configure the BPF filter - if not nofilter: - if conf.except_filter: - if filter: - filter = "(%s) and not (%s)" % (filter, conf.except_filter) - else: - filter = "not (%s)" % conf.except_filter - if filter is not None: - attach_filter(self.ins, filter, self.iface) - - # Set the guessed packet class - self.guessed_cls = self.guess_cls() - - def set_promisc(self, value): - """Set the interface in promiscuous mode""" - - try: - fcntl.ioctl(self.ins, BIOCPROMISC, struct.pack('i', value)) - except IOError: - raise Scapy_Exception("Cannot set promiscuous mode on interface " - "(%s)!" % self.iface) - - def __del__(self): - """Close the file descriptor on delete""" - # When the socket is deleted on Scapy exits, __del__ is - # sometimes called "too late", and self is None - if self is not None: - self.close() - - def guess_cls(self): - """Guess the packet class that must be used on the interface""" - - # Get the data link type - try: - ret = fcntl.ioctl(self.ins, BIOCGDLT, struct.pack('I', 0)) - ret = struct.unpack('I', ret)[0] - except IOError: - cls = conf.default_l2 - warning("BIOCGDLT failed: unable to guess type. Using %s !", - cls.name) - return cls - - # Retrieve the corresponding class - try: - return conf.l2types[ret] - except KeyError: - cls = conf.default_l2 - warning("Unable to guess type (type %i). Using %s", ret, cls.name) - - def set_nonblock(self, set_flag=True): - """Set the non blocking flag on the socket""" - - # Get the current flags - if self.fd_flags is None: - try: - self.fd_flags = fcntl.fcntl(self.ins, fcntl.F_GETFL) - except IOError: - warning("Cannot get flags on this file descriptor !") - return - - # Set the non blocking flag - if set_flag: - new_fd_flags = self.fd_flags | os.O_NONBLOCK - else: - new_fd_flags = self.fd_flags & ~os.O_NONBLOCK - - try: - fcntl.fcntl(self.ins, fcntl.F_SETFL, new_fd_flags) - self.fd_flags = new_fd_flags - except Exception: - warning("Can't set flags on this file descriptor !") - - def get_stats(self): - """Get received / dropped statistics""" - - try: - ret = fcntl.ioctl(self.ins, BIOCGSTATS, struct.pack("2I", 0, 0)) - return struct.unpack("2I", ret) - except IOError: - warning("Unable to get stats from BPF !") - return (None, None) - - def get_blen(self): - """Get the BPF buffer length""" - - try: - ret = fcntl.ioctl(self.ins, BIOCGBLEN, struct.pack("I", 0)) - return struct.unpack("I", ret)[0] - except IOError: - warning("Unable to get the BPF buffer length") - return - - def fileno(self): - """Get the underlying file descriptor""" - return self.ins - - def close(self): - """Close the Super Socket""" - - if not self.closed and self.ins is not None: - os.close(self.ins) - self.closed = True - self.ins = None - - def send(self, x): - """Dummy send method""" - raise Exception( - "Can't send anything with %s" % self.__class__.__name__ - ) - - def recv_raw(self, x=BPF_BUFFER_LENGTH): - """Dummy recv method""" - raise Exception( - "Can't recv anything with %s" % self.__class__.__name__ - ) - - @staticmethod - def select(sockets, remain=None): - """This function is called during sendrecv() routine to select - the available sockets. - """ - # sockets, None (means use the socket's recv() ) - return bpf_select(sockets, remain), None - - -class L2bpfListenSocket(_L2bpfSocket): - """"Scapy L2 BPF Listen Super Socket""" - - def __init__(self, *args, **kwargs): - self.received_frames = [] - super(L2bpfListenSocket, self).__init__(*args, **kwargs) - - def buffered_frames(self): - """Return the number of frames in the buffer""" - return len(self.received_frames) - - def get_frame(self): - """Get a frame or packet from the received list""" - if self.received_frames: - return self.received_frames.pop(0) - else: - return None, None, None - - @staticmethod - def bpf_align(bh_h, bh_c): - """Return the index to the end of the current packet""" - - # from - return ((bh_h + bh_c) + (BPF_ALIGNMENT - 1)) & ~(BPF_ALIGNMENT - 1) - - def extract_frames(self, bpf_buffer): - """Extract all frames from the buffer and stored them in the received list.""" # noqa: E501 - - # Ensure that the BPF buffer contains at least the header - len_bb = len(bpf_buffer) - if len_bb < 20: # Note: 20 == sizeof(struct bfp_hdr) - return - - # Extract useful information from the BPF header - if FREEBSD or NETBSD: - # struct bpf_xhdr or struct bpf_hdr32 - bh_tstamp_offset = 16 - else: - # struct bpf_hdr - bh_tstamp_offset = 8 - - # Parse the BPF header - bh_caplen = struct.unpack('I', bpf_buffer[bh_tstamp_offset:bh_tstamp_offset + 4])[0] # noqa: E501 - next_offset = bh_tstamp_offset + 4 - bh_datalen = struct.unpack('I', bpf_buffer[next_offset:next_offset + 4])[0] # noqa: E501 - next_offset += 4 - bh_hdrlen = struct.unpack('H', bpf_buffer[next_offset:next_offset + 2])[0] # noqa: E501 - if bh_datalen == 0: - return - - # Get and store the Scapy object - frame_str = bpf_buffer[bh_hdrlen:bh_hdrlen + bh_caplen] - self.received_frames.append( - (self.guessed_cls, frame_str, None) - ) - - # Extract the next frame - end = self.bpf_align(bh_hdrlen, bh_caplen) - if (len_bb - end) >= 20: - self.extract_frames(bpf_buffer[end:]) - - def recv_raw(self, x=BPF_BUFFER_LENGTH): - """Receive a frame from the network""" - - x = min(x, BPF_BUFFER_LENGTH) - - if self.buffered_frames(): - # Get a frame from the buffer - return self.get_frame() - - # Get data from BPF - try: - bpf_buffer = os.read(self.ins, x) - except EnvironmentError as exc: - if exc.errno != errno.EAGAIN: - warning("BPF recv_raw()", exc_info=True) - return None, None, None - - # Extract all frames from the BPF buffer - self.extract_frames(bpf_buffer) - return self.get_frame() - - -class L2bpfSocket(L2bpfListenSocket): - """"Scapy L2 BPF Super Socket""" - - def send(self, x): - """Send a frame""" - return os.write(self.outs, raw(x)) - - def nonblock_recv(self): - """Non blocking receive""" - - if self.buffered_frames(): - # Get a frame from the buffer - return L2bpfListenSocket.recv(self) - - # Set the non blocking flag, read from the socket, and unset the flag - self.set_nonblock(True) - pkt = L2bpfListenSocket.recv(self) - self.set_nonblock(False) - return pkt - - -class L3bpfSocket(L2bpfSocket): - - def recv(self, x=BPF_BUFFER_LENGTH): - """Receive on layer 3""" - r = SuperSocket.recv(self, x) - if r: - return r.payload - - def send(self, pkt): - """Send a packet""" - - # Use the routing table to find the output interface - iff = pkt.route()[0] - if iff is None: - iff = conf.iface - - # Assign the network interface to the BPF handle - if self.assigned_interface != iff: - try: - fcntl.ioctl(self.outs, BIOCSETIF, struct.pack("16s16x", iff.encode())) # noqa: E501 - except IOError: - raise Scapy_Exception("BIOCSETIF failed on %s" % iff) - self.assigned_interface = iff - - # Build the frame - frame = raw(self.guessed_cls() / pkt) - pkt.sent_time = time.time() - - # Send the frame - L2bpfSocket.send(self, frame) - - -# Sockets manipulation functions - -def isBPFSocket(obj): - """Return True is obj is a BPF Super Socket""" - return isinstance( - obj, - (L2bpfListenSocket, L2bpfListenSocket, L3bpfSocket) - ) - - -def bpf_select(fds_list, timeout=None): - """A call to recv() can return several frames. This functions hides the fact - that some frames are read from the internal buffer.""" - - # Check file descriptors types - bpf_scks_buffered = list() - select_fds = list() - - for tmp_fd in fds_list: - - # Specific BPF sockets: get buffers status - if isBPFSocket(tmp_fd) and tmp_fd.buffered_frames(): - bpf_scks_buffered.append(tmp_fd) - continue - - # Regular file descriptors or empty BPF buffer - select_fds.append(tmp_fd) - - if select_fds: - # Call select for sockets with empty buffers - if timeout is None: - timeout = 0.05 - ready_list, _, _ = select(select_fds, [], [], timeout) - return bpf_scks_buffered + ready_list - else: - return bpf_scks_buffered diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/bsd.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/bsd.py deleted file mode 100644 index c422030874..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/bsd.py +++ /dev/null @@ -1,12 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi -## This program is published under a GPLv2 license - -""" -Support for BSD-like operating systems such as FreeBSD, OpenBSD and Mac OS X. -""" - -LOOPBACK_NAME="lo0" - -from .unix import * diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/cdnet.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/cdnet.py deleted file mode 100644 index 98ebf084c9..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/cdnet.py +++ /dev/null @@ -1,229 +0,0 @@ -from ctypes import * -from ctypes.util import find_library -import sys - -WIN=False - -if sys.platform.startswith('win'): - WIN=True - -if WIN: - SOCKET = c_uint - _lib=CDLL('dnet') -else: - SOCKET = c_int - _lib_name = find_library('dnet') - if not _lib_name: - raise OSError("Cannot find libdnet.so") - _lib=CDLL(_lib_name) - -ETH_ADDR_LEN = 6 -INTF_NAME_LEN = 16 -INTF_NAME_COUNT = 20 -INTF_ALIAS_COUNT = 20 -IP6_ADDR_LEN = 16 - -ADDR_TYPE_NONE = 0 -ADDR_TYPE_ETH = 1 -ADDR_TYPE_IP = 2 -ADDR_TYPE_IP6 = 3 - -INTF_TYPE_OTHER = 1 -INTF_TYPE_ETH = 6 -INTF_TYPE_TOKENRING = 9 -INTF_TYPE_FDDI = 15 -INTF_TYPE_PPP = 23 -INTF_TYPE_LOOPBACK = 24 -INTF_TYPE_SLIP = 28 -INTF_TYPE_TUN = 53 - - -uint8_t = c_ubyte -uint16_t = c_ushort -uint32_t = c_uint -ssize_t = c_long -dnet_ip_addr_t = uint32_t - -dnet_intf_name = c_char * INTF_NAME_LEN - -class dnet_intf_list(Structure): - pass - -dnet_intf_list._fields_ = [ ('length', c_int), - ('interfaces', dnet_intf_name * 20) ] - -class dnet_eth_addr(Structure): - pass - -dnet_eth_addr._fields_ = [ ('data', uint8_t * ETH_ADDR_LEN) ] -dnet_eth_addr_t = dnet_eth_addr - -class dnet_ip6_addr(Structure): - pass - -dnet_ip6_addr._fields_ = [ ('data', uint8_t * IP6_ADDR_LEN) ] -dnet_ip6_addr_t = dnet_ip6_addr - -class dnet_addr_u(Union): - pass - -dnet_addr_u._fields_ = [ ('eth', dnet_eth_addr_t), - ('ip', dnet_ip_addr_t), - ('ip6', dnet_ip6_addr_t), - ('data8', uint8_t * 16), - ('data16', uint16_t * 8), - ('data32', uint32_t * 4) ] - -class dnet_addr(Structure): - pass -dnet_addr._anonymous_ = ('__addr_u', ) -dnet_addr._fields_ = [ ('addr_type', uint16_t), - ('addr_bits', uint16_t), - ('__addr_u', dnet_addr_u) ] - -class dnet_intf_entry(Structure): - pass - -dnet_intf_entry._fields_ = [ ('intf_len', c_uint), - ('intf_name', c_char * INTF_NAME_LEN), - ('intf_type', c_ushort), - ('intf_flags', c_ushort), - ('intf_mtu', c_uint), - ('intf_addr', dnet_addr), - ('intf_dst_addr', dnet_addr), - ('intf_link_addr', dnet_addr), - ('intf_alias_num', c_uint), - ('intf_alias_addrs', dnet_addr * INTF_ALIAS_COUNT) ] - - -eth_t = c_void_p -intf_t = c_void_p -ip_t = c_void_p -dnet_intf_handler = CFUNCTYPE(c_int, POINTER(dnet_intf_entry), POINTER(c_void_p)) - -dnet_eth_open = _lib.eth_open -dnet_eth_open.restype = POINTER(eth_t) -dnet_eth_open.argtypes = [ POINTER(c_char) ] - -dnet_eth_get = _lib.eth_get -dnet_eth_get.restype = c_int -dnet_eth_get.argtypes = [ POINTER(eth_t), POINTER(dnet_eth_addr_t) ] - -dnet_eth_set = _lib.eth_set -dnet_eth_set.restype = c_int -dnet_eth_set.argtypes = [ POINTER(eth_t), POINTER(dnet_eth_addr_t) ] - -dnet_eth_send = _lib.eth_send -dnet_eth_send.restype = ssize_t -dnet_eth_send.argtypes = [ POINTER(eth_t), c_void_p, c_size_t ] - -dnet_eth_close = _lib.eth_close -dnet_eth_close.restype = POINTER(eth_t) -dnet_eth_close.argtypes = [ POINTER(eth_t) ] - -dnet_intf_open = _lib.intf_open -dnet_intf_open.restype = POINTER(intf_t) -dnet_intf_open.argtypes = [ ] - -dnet_intf_get = _lib.intf_get -dnet_intf_get.restype = c_int -dnet_intf_get.argtypes = [ POINTER(intf_t), POINTER(dnet_intf_entry) ] - -dnet_intf_get_src = _lib.intf_get_src -dnet_intf_get_src.restype = c_int -dnet_intf_get_src.argtypes = [ POINTER(intf_t), POINTER(dnet_intf_entry), POINTER(dnet_addr) ] - -dnet_intf_get_dst = _lib.intf_get_dst -dnet_intf_get_dst.restype = c_int -dnet_intf_get_dst.argtypes = [ POINTER(intf_t), POINTER(dnet_intf_entry), POINTER(dnet_addr) ] - -dnet_intf_set = _lib.intf_set -dnet_intf_set.restype = c_int -dnet_intf_set.argtypes = [ POINTER(intf_t), POINTER(dnet_intf_entry) ] - -dnet_intf_loop = _lib.intf_loop -dnet_intf_loop.restype = POINTER(intf_t) -dnet_intf_loop.argtypes = [ POINTER(intf_t), dnet_intf_handler, c_void_p ] - -dnet_intf_close = _lib.intf_close -dnet_intf_close.restype = POINTER(intf_t) -dnet_intf_close.argtypes = [ POINTER(intf_t) ] - -dnet_ip_open = _lib.ip_open -dnet_ip_open.restype = POINTER(ip_t) -dnet_ip_open.argtypes = [ ] - -dnet_ip_add_option = _lib.ip_add_option -dnet_ip_add_option.restype = ssize_t -dnet_ip_add_option.argtypes = [ POINTER(c_void_p), c_size_t, c_int, POINTER(c_void_p), c_size_t ] - -dnet_ip_checksum = _lib.ip_checksum -dnet_ip_checksum.restype = None -dnet_ip_checksum.argtypes = [ POINTER(c_void_p), c_size_t ] - -dnet_ip_send = _lib.ip_send -dnet_ip_send.restype = ssize_t -dnet_ip_send.argtypes = [ POINTER(ip_t), c_void_p, c_size_t ] - -dnet_ip_close = _lib.ip_close -dnet_ip_close.restype = POINTER(ip_t) -dnet_ip_close.argtypes = [ POINTER(ip_t) ] - -class dnet_eth: - def __init__(self, iface): - self.iface_b = create_string_buffer(iface.encode('ascii')) - self.eth = dnet_eth_open(self.iface_b) - def send(self, sx): - dnet_eth_send(self.eth, sx, len(sx)) - def close(self): - return dnet_eth_close(self.eth) - -class dnet_ip: - def __init__(self): - self.ip = dnet_ip_open() - def send(self, sx): - dnet_ip_send(self.ip, sx, len(sx)) - def close(self): - return dnet_ip_close(self.ip) - -def dnet_intf_name_loop(entry, intf_list): - l = cast(intf_list, POINTER(dnet_intf_list)) - if l.contents.length >= INTF_NAME_COUNT: - return -1 - for i in enumerate(entry.contents.intf_name): - l.contents.interfaces[l.contents.length][i[0]] = i[1] - l.contents.length += 1 - return 0 - -class dnet_intf: - def __init__(self): - self.intf = dnet_intf_open() - intf_list = dnet_intf_list() - intf_list.length = 0 - dnet_intf_loop(self.intf, dnet_intf_handler(dnet_intf_name_loop), pointer(intf_list)) - self.names = [] - for i in range(INTF_NAME_COUNT): - if i >= intf_list.length: - break - self.names.append(intf_list.interfaces[i].value.decode('ascii').strip('\0')) - - def close(self): - return dnet_intf_close(self.intf) - - def get(self, iface): - ret = {} - entry = dnet_intf_entry() - entry.intf_name = iface.encode('ascii') - entry.intf_len = sizeof(entry) - r = dnet_intf_get(self.intf, byref(entry)) - if r < 0: - return {} - ret['addr6'] = [] - for i in range(entry.intf_alias_num): - if entry.intf_alias_addrs[i].addr_type == ADDR_TYPE_IP6: - ret['addr6'].append(bytes(entry.intf_alias_addrs[i].data8[:16])) - ret['type'] = entry.intf_type - ret['addr'] = bytes(entry.intf_addr.data8[:4]) - ret['link_addr'] = bytes(entry.intf_link_addr.data8[:6]) - return ret - diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/common.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/common.py deleted file mode 100644 index f2a46cf8b0..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/common.py +++ /dev/null @@ -1,186 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Functions common to different architectures -""" - -import ctypes -import os -import socket -import struct -import subprocess -import time -from ctypes import POINTER, Structure -from ctypes import c_uint, c_uint32, c_ushort, c_ubyte -from scapy.consts import WINDOWS -from scapy.config import conf -from scapy.data import MTU -from scapy.error import Scapy_Exception -from scapy.consts import OPENBSD -import scapy.modules.six as six - -if not WINDOWS: - from fcntl import ioctl - -# BOOT - - -def _check_tcpdump(): - """ - Return True if the tcpdump command can be started - """ - with open(os.devnull, 'wb') as devnull: - try: - proc = subprocess.Popen([conf.prog.tcpdump, "--version"], - stdout=devnull, stderr=subprocess.STDOUT) - except OSError: - return False - - if OPENBSD: - # 'tcpdump --version' returns 1 on OpenBSD 6.4 - return proc.wait() == 1 - else: - return proc.wait() == 0 - - -# This won't be used on Windows -TCPDUMP = WINDOWS or _check_tcpdump() - -# UTILS - - -def get_if(iff, cmd): - """Ease SIOCGIF* ioctl calls""" - - sck = socket.socket() - ifreq = ioctl(sck, cmd, struct.pack("16s16x", iff.encode("utf8"))) - sck.close() - return ifreq - - -def get_if_raw_hwaddr(iff): - """Get the raw MAC address of a local interface. - - This function uses SIOCGIFHWADDR calls, therefore only works - on some distros. - - :param iff: the network interface name as a string - :returns: the corresponding raw MAC address - """ - from scapy.arch import SIOCGIFHWADDR - return struct.unpack("16xh6s8x", get_if(iff, SIOCGIFHWADDR)) - -# SOCKET UTILS - - -def _select_nonblock(sockets, remain=None): - """This function is called during sendrecv() routine to select - the available sockets. - """ - # pcap sockets aren't selectable, so we return all of them - # and ask the selecting functions to use nonblock_recv instead of recv - def _sleep_nonblock_recv(self): - res = self.nonblock_recv() - if res is None: - time.sleep(conf.recv_poll_rate) - return res - # we enforce remain=None: don't wait. - return sockets, _sleep_nonblock_recv - -# BPF HANDLERS - - -class bpf_insn(Structure): - """"The BPF instruction data structure""" - _fields_ = [("code", c_ushort), - ("jt", c_ubyte), - ("jf", c_ubyte), - ("k", c_uint32)] - - -class bpf_program(Structure): - """"Structure for BIOCSETF""" - _fields_ = [("bf_len", c_uint), - ("bf_insns", POINTER(bpf_insn))] - - -def _legacy_bpf_pointer(tcpdump_lines): - """Get old-format BPF Pointer. Deprecated""" - X86_64 = os.uname()[4] in ['x86_64', 'aarch64'] - size = int(tcpdump_lines[0]) - bpf = b"" - for l in tcpdump_lines[1:]: - if six.PY2: - int_type = long # noqa: F821 - else: - int_type = int - bpf += struct.pack("HBBI", *map(int_type, l.split())) - - # Thanks to http://www.netprojects.de/scapy-with-pypy-solved/ for the pypy trick # noqa: E501 - if conf.use_pypy: - str_buffer = ctypes.create_string_buffer(bpf) - return struct.pack('HL', size, ctypes.addressof(str_buffer)) - else: - # XXX. Argl! We need to give the kernel a pointer on the BPF, - # Python object header seems to be 20 bytes. 36 bytes for x86 64bits arch. # noqa: E501 - if X86_64: - return struct.pack("HL", size, id(bpf) + 36) - else: - return struct.pack("HI", size, id(bpf) + 20) - - -def get_bpf_pointer(tcpdump_lines): - """Create a BPF Pointer for TCPDump filter""" - if conf.use_pypy: - return _legacy_bpf_pointer(tcpdump_lines) - - # Allocate BPF instructions - size = int(tcpdump_lines[0]) - bpf_insn_a = bpf_insn * size - bip = bpf_insn_a() - - # Fill the BPF instruction structures with the byte code - tcpdump_lines = tcpdump_lines[1:] - i = 0 - for line in tcpdump_lines: - values = [int(v) for v in line.split()] - bip[i].code = c_ushort(values[0]) - bip[i].jt = c_ubyte(values[1]) - bip[i].jf = c_ubyte(values[2]) - bip[i].k = c_uint(values[3]) - i += 1 - - # Create the BPF program - return bpf_program(size, bip) - - -def compile_filter(bpf_filter, iface=None): - """Asks Tcpdump to parse the filter, then build the matching - BPF bytecode using get_bpf_pointer. - """ - if not TCPDUMP: - raise Scapy_Exception("tcpdump is not available. Cannot use filter !") - try: - process = subprocess.Popen([ - conf.prog.tcpdump, - "-p", - "-i", (conf.iface if iface is None else iface), - "-ddd", - "-s", str(MTU), - bpf_filter], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - except OSError as ex: - raise Scapy_Exception("Failed to attach filter: %s" % ex) - lines, err = process.communicate() - ret = process.returncode - if ret: - raise Scapy_Exception( - "Failed to attach filter: tcpdump returned: %s" % err - ) - lines = lines.strip().split(b"\n") - return get_bpf_pointer(lines) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/linux.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/linux.py deleted file mode 100644 index f9125a0db4..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/linux.py +++ /dev/null @@ -1,669 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Linux specific functions. -""" - -from __future__ import absolute_import - - -import array -import ctypes -from fcntl import ioctl -import os -from select import select -import socket -import struct -import time -import re - -import subprocess - -from scapy.compat import raw, plain_str -from scapy.consts import LOOPBACK_NAME, LINUX -import scapy.utils -import scapy.utils6 -from scapy.packet import Packet, Padding -from scapy.config import conf -from scapy.data import MTU, ETH_P_ALL -from scapy.supersocket import SuperSocket -from scapy.error import warning, Scapy_Exception, \ - ScapyInvalidPlatformException -from scapy.arch.common import get_if, compile_filter -import scapy.modules.six as six -from scapy.modules.six.moves import range - -from scapy.arch.common import get_if_raw_hwaddr # noqa: F401 - -# From bits/ioctls.h -SIOCGIFHWADDR = 0x8927 # Get hardware address -SIOCGIFADDR = 0x8915 # get PA address -SIOCGIFNETMASK = 0x891b # get network PA mask -SIOCGIFNAME = 0x8910 # get iface name -SIOCSIFLINK = 0x8911 # set iface channel -SIOCGIFCONF = 0x8912 # get iface list -SIOCGIFFLAGS = 0x8913 # get flags -SIOCSIFFLAGS = 0x8914 # set flags -SIOCGIFINDEX = 0x8933 # name -> if_index mapping -SIOCGIFCOUNT = 0x8938 # get number of devices -SIOCGSTAMP = 0x8906 # get packet timestamp (as a timeval) - -# From if.h -IFF_UP = 0x1 # Interface is up. -IFF_BROADCAST = 0x2 # Broadcast address valid. -IFF_DEBUG = 0x4 # Turn on debugging. -IFF_LOOPBACK = 0x8 # Is a loopback net. -IFF_POINTOPOINT = 0x10 # Interface is point-to-point link. -IFF_NOTRAILERS = 0x20 # Avoid use of trailers. -IFF_RUNNING = 0x40 # Resources allocated. -IFF_NOARP = 0x80 # No address resolution protocol. -IFF_PROMISC = 0x100 # Receive all packets. - -# From netpacket/packet.h -PACKET_ADD_MEMBERSHIP = 1 -PACKET_DROP_MEMBERSHIP = 2 -PACKET_RECV_OUTPUT = 3 -PACKET_RX_RING = 5 -PACKET_STATISTICS = 6 -PACKET_MR_MULTICAST = 0 -PACKET_MR_PROMISC = 1 -PACKET_MR_ALLMULTI = 2 - -# From bits/socket.h -SOL_PACKET = 263 -# From asm/socket.h -SO_ATTACH_FILTER = 26 - -# From net/route.h -RTF_UP = 0x0001 # Route usable -RTF_REJECT = 0x0200 - -# From if_packet.h -PACKET_HOST = 0 # To us -PACKET_BROADCAST = 1 # To all -PACKET_MULTICAST = 2 # To group -PACKET_OTHERHOST = 3 # To someone else -PACKET_OUTGOING = 4 # Outgoing of any type -PACKET_LOOPBACK = 5 # MC/BRD frame looped back -PACKET_USER = 6 # To user space -PACKET_KERNEL = 7 # To kernel space -PACKET_AUXDATA = 8 -PACKET_FASTROUTE = 6 # Fastrouted frame -# Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space - -# Used to get VLAN data -ETH_P_8021Q = 0x8100 -TP_STATUS_VLAN_VALID = 1 << 4 - - -class tpacket_auxdata(ctypes.Structure): - _fields_ = [ - ("tp_status", ctypes.c_uint), - ("tp_len", ctypes.c_uint), - ("tp_snaplen", ctypes.c_uint), - ("tp_mac", ctypes.c_ushort), - ("tp_net", ctypes.c_ushort), - ("tp_vlan_tci", ctypes.c_ushort), - ("tp_padding", ctypes.c_ushort), - ] - - -# Utils - -def get_if_raw_addr(iff): - try: - return get_if(iff, SIOCGIFADDR)[20:24] - except IOError: - return b"\0\0\0\0" - - -def get_if_list(): - try: - f = open("/proc/net/dev", "rb") - except IOError: - f.close() - warning("Can't open /proc/net/dev !") - return [] - lst = [] - f.readline() - f.readline() - for line in f: - line = plain_str(line) - lst.append(line.split(":")[0].strip()) - f.close() - return lst - - -def get_working_if(): - """ - Return the name of the first network interfcace that is up. - """ - for i in get_if_list(): - if i == LOOPBACK_NAME: - continue - ifflags = struct.unpack("16xH14x", get_if(i, SIOCGIFFLAGS))[0] - if ifflags & IFF_UP: - return i - return LOOPBACK_NAME - - -def attach_filter(sock, bpf_filter, iface): - # XXX We generate the filter on the interface conf.iface - # because tcpdump open the "any" interface and ppp interfaces - # in cooked mode. As we use them in raw mode, the filter will not - # work... one solution could be to use "any" interface and translate - # the filter from cooked mode to raw mode - # mode - bp = compile_filter(bpf_filter, iface) - sock.setsockopt(socket.SOL_SOCKET, SO_ATTACH_FILTER, bp) - - -def set_promisc(s, iff, val=1): - mreq = struct.pack("IHH8s", get_if_index(iff), PACKET_MR_PROMISC, 0, b"") - if val: - cmd = PACKET_ADD_MEMBERSHIP - else: - cmd = PACKET_DROP_MEMBERSHIP - s.setsockopt(SOL_PACKET, cmd, mreq) - - -def get_alias_address(iface_name, ip_mask, gw_str, metric): - """ - Get the correct source IP address of an interface alias - """ - - # Detect the architecture - if scapy.consts.IS_64BITS: - offset, name_len = 16, 40 - else: - offset, name_len = 32, 32 - - # Retrieve interfaces structures - sck = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - names = array.array('B', b'\0' * 4096) - ifreq = ioctl(sck.fileno(), SIOCGIFCONF, - struct.pack("iL", len(names), names.buffer_info()[0])) - - # Extract interfaces names - out = struct.unpack("iL", ifreq)[0] - names = names.tobytes() if six.PY3 else names.tostring() - names = [names[i:i + offset].split(b'\0', 1)[0] for i in range(0, out, name_len)] # noqa: E501 - - # Look for the IP address - for ifname in names: - # Only look for a matching interface name - if not ifname.decode("utf8").startswith(iface_name): - continue - - # Retrieve and convert addresses - ifreq = ioctl(sck, SIOCGIFADDR, struct.pack("16s16x", ifname)) - ifaddr = struct.unpack(">I", ifreq[20:24])[0] - ifreq = ioctl(sck, SIOCGIFNETMASK, struct.pack("16s16x", ifname)) - msk = struct.unpack(">I", ifreq[20:24])[0] - - # Get the full interface name - ifname = plain_str(ifname) - if ':' in ifname: - ifname = ifname[:ifname.index(':')] - else: - continue - - # Check if the source address is included in the network - if (ifaddr & msk) == ip_mask: - sck.close() - return (ifaddr & msk, msk, gw_str, ifname, - scapy.utils.ltoa(ifaddr), metric) - - sck.close() - return - - -def read_routes(): - try: - f = open("/proc/net/route", "rb") - except IOError: - warning("Can't open /proc/net/route !") - return [] - routes = [] - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - try: - ifreq = ioctl(s, SIOCGIFADDR, struct.pack("16s16x", scapy.consts.LOOPBACK_NAME.encode("utf8"))) # noqa: E501 - addrfamily = struct.unpack("h", ifreq[16:18])[0] - if addrfamily == socket.AF_INET: - ifreq2 = ioctl(s, SIOCGIFNETMASK, struct.pack("16s16x", scapy.consts.LOOPBACK_NAME.encode("utf8"))) # noqa: E501 - msk = socket.ntohl(struct.unpack("I", ifreq2[20:24])[0]) - dst = socket.ntohl(struct.unpack("I", ifreq[20:24])[0]) & msk - ifaddr = scapy.utils.inet_ntoa(ifreq[20:24]) - routes.append((dst, msk, "0.0.0.0", scapy.consts.LOOPBACK_NAME, ifaddr, 1)) # noqa: E501 - else: - warning("Interface %s: unknown address family (%i)" % (scapy.consts.LOOPBACK_NAME, addrfamily)) # noqa: E501 - except IOError as err: - if err.errno == 99: - warning("Interface %s: no address assigned" % scapy.consts.LOOPBACK_NAME) # noqa: E501 - else: - warning("Interface %s: failed to get address config (%s)" % (scapy.consts.LOOPBACK_NAME, str(err))) # noqa: E501 - - for line in f.readlines()[1:]: - line = plain_str(line) - iff, dst, gw, flags, _, _, metric, msk, _, _, _ = line.split() - flags = int(flags, 16) - if flags & RTF_UP == 0: - continue - if flags & RTF_REJECT: - continue - try: - ifreq = ioctl(s, SIOCGIFADDR, struct.pack("16s16x", iff.encode("utf8"))) # noqa: E501 - except IOError: # interface is present in routing tables but does not have any assigned IP # noqa: E501 - ifaddr = "0.0.0.0" - ifaddr_int = 0 - else: - addrfamily = struct.unpack("h", ifreq[16:18])[0] - if addrfamily == socket.AF_INET: - ifaddr = scapy.utils.inet_ntoa(ifreq[20:24]) - ifaddr_int = struct.unpack("!I", ifreq[20:24])[0] - else: - warning("Interface %s: unknown address family (%i)", iff, addrfamily) # noqa: E501 - continue - - # Attempt to detect an interface alias based on addresses inconsistencies # noqa: E501 - dst_int = socket.htonl(int(dst, 16)) & 0xffffffff - msk_int = socket.htonl(int(msk, 16)) & 0xffffffff - gw_str = scapy.utils.inet_ntoa(struct.pack("I", int(gw, 16))) - metric = int(metric) - - if ifaddr_int & msk_int != dst_int: - tmp_route = get_alias_address(iff, dst_int, gw_str, metric) - if tmp_route: - routes.append(tmp_route) - else: - routes.append((dst_int, msk_int, gw_str, iff, ifaddr, metric)) - - else: - routes.append((dst_int, msk_int, gw_str, iff, ifaddr, metric)) - - f.close() - s.close() - return routes - -############ -# IPv6 # -############ - - -def in6_getifaddr(): - """ - Returns a list of 3-tuples of the form (addr, scope, iface) where - 'addr' is the address of scope 'scope' associated to the interface - 'iface'. - - This is the list of all addresses of all interfaces available on - the system. - """ - ret = [] - try: - fdesc = open("/proc/net/if_inet6", "rb") - except IOError: - return ret - for line in fdesc: - # addr, index, plen, scope, flags, ifname - tmp = plain_str(line).split() - addr = scapy.utils6.in6_ptop( - b':'.join( - struct.unpack('4s4s4s4s4s4s4s4s', tmp[0].encode()) - ).decode() - ) - # (addr, scope, iface) - ret.append((addr, int(tmp[3], 16), tmp[5])) - fdesc.close() - return ret - - -def read_routes6(): - try: - f = open("/proc/net/ipv6_route", "rb") - except IOError: - return [] - # 1. destination network - # 2. destination prefix length - # 3. source network displayed - # 4. source prefix length - # 5. next hop - # 6. metric - # 7. reference counter (?!?) - # 8. use counter (?!?) - # 9. flags - # 10. device name - routes = [] - - def proc2r(p): - ret = struct.unpack('4s4s4s4s4s4s4s4s', p) - ret = b':'.join(ret).decode() - return scapy.utils6.in6_ptop(ret) - - lifaddr = in6_getifaddr() - for line in f.readlines(): - d, dp, s, sp, nh, metric, rc, us, fl, dev = line.split() - metric = int(metric, 16) - fl = int(fl, 16) - dev = plain_str(dev) - - if fl & RTF_UP == 0: - continue - if fl & RTF_REJECT: - continue - - d = proc2r(d) - dp = int(dp, 16) - s = proc2r(s) - sp = int(sp, 16) - nh = proc2r(nh) - - cset = [] # candidate set (possible source addresses) - if dev == LOOPBACK_NAME: - if d == '::': - continue - cset = ['::1'] - else: - devaddrs = (x for x in lifaddr if x[2] == dev) - cset = scapy.utils6.construct_source_candidate_set(d, dp, devaddrs) - - if len(cset) != 0: - routes.append((d, dp, nh, dev, cset, metric)) - f.close() - return routes - - -def get_if_index(iff): - return int(struct.unpack("I", get_if(iff, SIOCGIFINDEX)[16:20])[0]) - - -if os.uname()[4] in ['x86_64', 'aarch64']: - def get_last_packet_timestamp(sock): - ts = ioctl(sock, SIOCGSTAMP, "1234567890123456") - s, us = struct.unpack("QQ", ts) - return s + us / 1000000.0 -else: - def get_last_packet_timestamp(sock): - ts = ioctl(sock, SIOCGSTAMP, "12345678") - s, us = struct.unpack("II", ts) - return s + us / 1000000.0 - - -def _flush_fd(fd): - if hasattr(fd, 'fileno'): - fd = fd.fileno() - while True: - r, w, e = select([fd], [], [], 0) - if r: - os.read(fd, MTU) - else: - break - - -def get_iface_mode(iface): - """Return the interface mode. - params: - - iface: the iwconfig interface - """ - p = subprocess.Popen(["iwconfig", iface], stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - output, err = p.communicate() - match = re.search(br"mode:([a-zA-Z]*)", output.lower()) - if match: - return plain_str(match.group(1)) - return "unknown" - - -def set_iface_monitor(iface, monitor): - """Sets the monitor mode (or remove it) from an interface. - params: - - iface: the iwconfig interface - - monitor: True if the interface should be set in monitor mode, - False if it should be in managed mode - """ - mode = get_iface_mode(iface) - if mode == "unknown": - warning("Could not parse iwconfig !") - current_monitor = mode == "monitor" - if monitor == current_monitor: - # Already correct - return True - s_mode = "monitor" if monitor else "managed" - - def _check_call(commands): - p = subprocess.Popen(commands, - stderr=subprocess.PIPE, - stdout=subprocess.PIPE) - stdout, stderr = p.communicate() - if p.returncode != 0: - warning("%s failed !" % " ".join(commands)) - return False - return True - if not _check_call(["ifconfig", iface, "down"]): - return False - if not _check_call(["iwconfig", iface, "mode", s_mode]): - return False - if not _check_call(["ifconfig", iface, "up"]): - return False - return True - - -class L2Socket(SuperSocket): - desc = "read/write packets at layer 2 using Linux PF_PACKET sockets" - - def __init__(self, iface=None, type=ETH_P_ALL, promisc=None, filter=None, - nofilter=0, monitor=None): - self.iface = conf.iface if iface is None else iface - self.type = type - self.promisc = conf.sniff_promisc if promisc is None else promisc - if monitor is not None: - warning( - "The monitor argument is ineffective on native linux sockets." - " Use set_iface_monitor instead." - ) - self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type)) # noqa: E501 - if not nofilter: - if conf.except_filter: - if filter: - filter = "(%s) and not (%s)" % (filter, conf.except_filter) - else: - filter = "not (%s)" % conf.except_filter - if filter is not None: - attach_filter(self.ins, filter, iface) - if self.promisc: - set_promisc(self.ins, self.iface) - self.ins.bind((self.iface, type)) - _flush_fd(self.ins) - self.ins.setsockopt( - socket.SOL_SOCKET, - socket.SO_RCVBUF, - conf.bufsize - ) - if not six.PY2: - # Receive Auxiliary Data (VLAN tags) - self.ins.setsockopt(SOL_PACKET, PACKET_AUXDATA, 1) - if isinstance(self, L2ListenSocket): - self.outs = None - else: - self.outs = self.ins - self.outs.setsockopt( - socket.SOL_SOCKET, - socket.SO_SNDBUF, - conf.bufsize - ) - sa_ll = self.ins.getsockname() - if sa_ll[3] in conf.l2types: - self.LL = conf.l2types[sa_ll[3]] - self.lvl = 2 - elif sa_ll[1] in conf.l3types: - self.LL = conf.l3types[sa_ll[1]] - self.lvl = 3 - else: - self.LL = conf.default_l2 - self.lvl = 2 - warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using %s", sa_ll[0], sa_ll[1], sa_ll[3], self.LL.name) # noqa: E501 - - def close(self): - if self.closed: - return - try: - if self.promisc and self.ins: - set_promisc(self.ins, self.iface, 0) - except AttributeError: - pass - SuperSocket.close(self) - - if six.PY2: - def _recv_raw(self, sock, x): - """Internal function to receive a Packet""" - pkt, sa_ll = sock.recvfrom(x) - return pkt, sa_ll - else: - def _recv_raw(self, sock, x): - """Internal function to receive a Packet, - and process ancillary data. - """ - flags_len = socket.CMSG_LEN(4096) - pkt, ancdata, flags, sa_ll = sock.recvmsg(x, flags_len) - if not pkt: - return pkt, sa_ll - for cmsg_lvl, cmsg_type, cmsg_data in ancdata: - # Check available ancillary data - if (cmsg_lvl == SOL_PACKET and cmsg_type == PACKET_AUXDATA): - # Parse AUXDATA - auxdata = tpacket_auxdata.from_buffer_copy(cmsg_data) - if auxdata.tp_vlan_tci != 0 or \ - auxdata.tp_status & TP_STATUS_VLAN_VALID: - # Insert VLAN tag - tag = struct.pack( - "!HH", - ETH_P_8021Q, - auxdata.tp_vlan_tci - ) - pkt = pkt[:12] + tag + pkt[12:] - return pkt, sa_ll - - def recv_raw(self, x=MTU): - """Receives a packet, then returns a tuple containing (cls, pkt_data, time)""" # noqa: E501 - pkt, sa_ll = self._recv_raw(self.ins, x) - if self.outs and sa_ll[2] == socket.PACKET_OUTGOING: - return None, None, None - ts = get_last_packet_timestamp(self.ins) - return self.LL, pkt, ts - - def send(self, x): - try: - return SuperSocket.send(self, x) - except socket.error as msg: - if msg.errno == 22 and len(x) < conf.min_pkt_size: - padding = b"\x00" * (conf.min_pkt_size - len(x)) - if isinstance(x, Packet): - return SuperSocket.send(self, x / Padding(load=padding)) - else: - return SuperSocket.send(self, raw(x) + padding) - raise - - -class L2ListenSocket(L2Socket): - desc = "read packets at layer 2 using Linux PF_PACKET sockets. Also receives the packets going OUT" # noqa: E501 - - def send(self, x): - raise Scapy_Exception("Can't send anything with L2ListenSocket") - - -class L3PacketSocket(L2Socket): - desc = "read/write packets at layer 3 using Linux PF_PACKET sockets" - - def recv(self, x=MTU): - pkt = SuperSocket.recv(self, x) - if pkt and self.lvl == 2: - pkt = pkt.payload - return pkt - - def send(self, x): - iff = x.route()[0] - if iff is None: - iff = conf.iface - sdto = (iff, self.type) - self.outs.bind(sdto) - sn = self.outs.getsockname() - ll = lambda x: x - if type(x) in conf.l3types: - sdto = (iff, conf.l3types[type(x)]) - if sn[3] in conf.l2types: - ll = lambda x: conf.l2types[sn[3]]() / x - sx = raw(ll(x)) - try: - self.outs.sendto(sx, sdto) - except socket.error as msg: - if msg.errno == 22 and len(sx) < conf.min_pkt_size: - self.outs.send(sx + b"\x00" * (conf.min_pkt_size - len(sx))) - elif conf.auto_fragment and msg.errno == 90: - for p in x.fragment(): - self.outs.sendto(raw(ll(p)), sdto) - else: - raise - x.sent_time = time.time() - - -class VEthPair(object): - """ - encapsulates a virtual Ethernet interface pair - """ - - def __init__(self, iface_name, peer_name): - - if not LINUX: - # ToDo: do we need a kernel version check here? - raise ScapyInvalidPlatformException( - 'Virtual Ethernet interface pair only available on Linux' - ) - - self.ifaces = [iface_name, peer_name] - - def iface(self): - return self.ifaces[0] - - def peer(self): - return self.ifaces[1] - - def setup(self): - """ - create veth pair links - :raises subprocess.CalledProcessError if operation fails - """ - subprocess.check_call(['ip', 'link', 'add', self.ifaces[0], 'type', 'veth', 'peer', 'name', self.ifaces[1]]) # noqa: E501 - - def destroy(self): - """ - remove veth pair links - :raises subprocess.CalledProcessError if operation fails - """ - subprocess.check_call(['ip', 'link', 'del', self.ifaces[0]]) - - def up(self): - """ - set veth pair links up - :raises subprocess.CalledProcessError if operation fails - """ - for idx in [0, 1]: - subprocess.check_call(["ip", "link", "set", self.ifaces[idx], "up"]) # noqa: E501 - - def down(self): - """ - set veth pair links down - :raises subprocess.CalledProcessError if operation fails - """ - for idx in [0, 1]: - subprocess.check_call(["ip", "link", "set", self.ifaces[idx], "down"]) # noqa: E501 - - def __enter__(self): - self.setup() - self.up() - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.destroy() diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/pcapdnet.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/pcapdnet.py deleted file mode 100644 index b647b6bc75..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/pcapdnet.py +++ /dev/null @@ -1,459 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Packet sending and receiving with libdnet and libpcap/WinPcap. -""" - -import os -import platform -import socket -import struct -import time - -from scapy.automaton import SelectableObject -from scapy.arch.common import _select_nonblock -from scapy.compat import raw, plain_str, chb -from scapy.config import conf -from scapy.consts import WINDOWS -from scapy.data import MTU, ETH_P_ALL, ARPHDR_ETHER, ARPHDR_LOOPBACK -from scapy.pton_ntop import inet_ntop -from scapy.utils import mac2str -from scapy.supersocket import SuperSocket -from scapy.error import Scapy_Exception, log_loading, warning -import scapy.consts - -if not scapy.consts.WINDOWS: - from fcntl import ioctl - -############ -# COMMON # -############ - -# From BSD net/bpf.h -# BIOCIMMEDIATE = 0x80044270 -BIOCIMMEDIATE = -2147204496 - - -class _L2pcapdnetSocket(SuperSocket, SelectableObject): - nonblocking_socket = True - - def __init__(self): - SelectableObject.__init__(self) - - def check_recv(self): - return True - - def recv_raw(self, x=MTU): - """Receives a packet, then returns a tuple containing (cls, pkt_data, time)""" # noqa: E501 - ll = self.ins.datalink() - if ll in conf.l2types: - cls = conf.l2types[ll] - else: - cls = conf.default_l2 - warning("Unable to guess datalink type (interface=%s linktype=%i). Using %s", # noqa: E501 - self.iface, ll, cls.name) - - pkt = None - while pkt is None: - pkt = self.ins.next() - if pkt is not None: - ts, pkt = pkt - if pkt is None: - return None, None, None - return cls, pkt, ts - - def nonblock_recv(self): - """Receives and dissect a packet in non-blocking mode. - Note: on Windows, this won't do anything.""" - self.ins.setnonblock(1) - p = self.recv(MTU) - self.ins.setnonblock(0) - return p - - @staticmethod - def select(sockets, remain=None): - return _select_nonblock(sockets, remain=None) - -########## -# PCAP # -########## - - -if conf.use_pcap: - if WINDOWS: - # Windows specific - NPCAP_PATH = os.environ["WINDIR"] + "\\System32\\Npcap" - from scapy.modules.winpcapy import pcap_setmintocopy - else: - from scapy.modules.winpcapy import pcap_get_selectable_fd - from ctypes import POINTER, byref, create_string_buffer, c_ubyte, cast - - # Part of the Winpcapy integration was inspired by phaethon/scapy - # but he destroyed the commit history, so there is no link to that - try: - from scapy.modules.winpcapy import PCAP_ERRBUF_SIZE, pcap_if_t, \ - sockaddr_in, sockaddr_in6, pcap_findalldevs, pcap_freealldevs, \ - pcap_lib_version, pcap_close, \ - pcap_open_live, pcap_pkthdr, \ - pcap_next_ex, pcap_datalink, \ - pcap_compile, pcap_setfilter, pcap_setnonblock, pcap_sendpacket, \ - bpf_program as winpcapy_bpf_program - - def load_winpcapy(): - """This functions calls Winpcap/Npcap pcap_findalldevs function, - and extracts and parse all the data scapy will need to use it: - - the Interface List - This data is stored in their respective conf.cache_* subfields: - conf.cache_iflist - """ - err = create_string_buffer(PCAP_ERRBUF_SIZE) - devs = POINTER(pcap_if_t)() - if_list = {} - if pcap_findalldevs(byref(devs), err) < 0: - return - try: - p = devs - # Iterate through the different interfaces - while p: - name = plain_str(p.contents.name) # GUID - description = plain_str(p.contents.description) # NAME - flags = p.contents.flags # FLAGS - ips = [] - a = p.contents.addresses - while a: - # IPv4 address - family = a.contents.addr.contents.sa_family - ap = a.contents.addr - if family == socket.AF_INET: - val = cast(ap, POINTER(sockaddr_in)) - val = val.contents.sin_addr[:] - elif family == socket.AF_INET6: - val = cast(ap, POINTER(sockaddr_in6)) - val = val.contents.sin6_addr[:] - else: - # Unknown address family - # (AF_LINK isn't a thing on Windows) - a = a.contents.next - continue - addr = inet_ntop(family, bytes(bytearray(val))) - if addr != "0.0.0.0": - ips.append(addr) - a = a.contents.next - if_list[name] = (description, ips, flags) - p = p.contents.next - conf.cache_iflist = if_list - except Exception: - raise - finally: - pcap_freealldevs(devs) - except OSError: - conf.use_pcap = False - if WINDOWS: - if conf.interactive: - log_loading.critical( - "Npcap/Winpcap is not installed ! See " - "https://scapy.readthedocs.io/en/latest/installation.html#windows" # noqa: E501 - ) - else: - if conf.interactive: - log_loading.critical( - "Libpcap is not installed!" - ) - else: - if WINDOWS: - # Detect Pcap version: check for Npcap - version = pcap_lib_version() - if b"winpcap" in version.lower(): - if os.path.exists(NPCAP_PATH + "\\wpcap.dll"): - warning("Winpcap is installed over Npcap. " - "Will use Winpcap (see 'Winpcap/Npcap conflicts' " - "in Scapy's docs)") - elif platform.release() != "XP": - warning("WinPcap is now deprecated (not maintained). " - "Please use Npcap instead") - elif b"npcap" in version.lower(): - conf.use_npcap = True - LOOPBACK_NAME = scapy.consts.LOOPBACK_NAME = "Npcap Loopback Adapter" # noqa: E501 - -if conf.use_pcap: - def get_if_list(): - """Returns all pcap names""" - if not conf.cache_iflist: - load_winpcapy() - return list(conf.cache_iflist) - - class _PcapWrapper_winpcap: # noqa: F811 - """Wrapper for the WinPcap calls""" - - def __init__(self, device, snaplen, promisc, to_ms, monitor=None): - self.errbuf = create_string_buffer(PCAP_ERRBUF_SIZE) - self.iface = create_string_buffer(device.encode("utf8")) - if monitor: - if WINDOWS and not conf.use_npcap: - raise OSError("On Windows, this feature requires NPcap !") - # Npcap-only functions - from scapy.modules.winpcapy import pcap_create, \ - pcap_set_snaplen, pcap_set_promisc, \ - pcap_set_timeout, pcap_set_rfmon, pcap_activate - self.pcap = pcap_create(self.iface, self.errbuf) - pcap_set_snaplen(self.pcap, snaplen) - pcap_set_promisc(self.pcap, promisc) - pcap_set_timeout(self.pcap, to_ms) - if pcap_set_rfmon(self.pcap, 1) != 0: - warning("Could not set monitor mode") - if pcap_activate(self.pcap) != 0: - raise OSError("Could not activate the pcap handler") - else: - self.pcap = pcap_open_live(self.iface, - snaplen, promisc, to_ms, - self.errbuf) - - if WINDOWS: - # Winpcap/Npcap exclusive: make every packet to be instantly - # returned, and not buffered within Winpcap/Npcap - pcap_setmintocopy(self.pcap, 0) - - self.header = POINTER(pcap_pkthdr)() - self.pkt_data = POINTER(c_ubyte)() - self.bpf_program = winpcapy_bpf_program() - - def next(self): - c = pcap_next_ex(self.pcap, byref(self.header), byref(self.pkt_data)) # noqa: E501 - if not c > 0: - return - ts = self.header.contents.ts.tv_sec + float(self.header.contents.ts.tv_usec) / 1000000 # noqa: E501 - pkt = b"".join(chb(i) for i in self.pkt_data[:self.header.contents.len]) # noqa: E501 - return ts, pkt - __next__ = next - - def datalink(self): - return pcap_datalink(self.pcap) - - def fileno(self): - if WINDOWS: - log_loading.error("Cannot get selectable PCAP fd on Windows") - return 0 - else: - # This does not exist under Windows - return pcap_get_selectable_fd(self.pcap) - - def setfilter(self, f): - filter_exp = create_string_buffer(f.encode("utf8")) - if pcap_compile(self.pcap, byref(self.bpf_program), filter_exp, 0, -1) == -1: # noqa: E501 - log_loading.error("Could not compile filter expression %s", f) - return False - else: - if pcap_setfilter(self.pcap, byref(self.bpf_program)) == -1: - log_loading.error("Could not install filter %s", f) - return False - return True - - def setnonblock(self, i): - pcap_setnonblock(self.pcap, i, self.errbuf) - - def send(self, x): - pcap_sendpacket(self.pcap, x, len(x)) - - def close(self): - pcap_close(self.pcap) - open_pcap = lambda *args, **kargs: _PcapWrapper_winpcap(*args, **kargs) - - # pcap sockets - - class L2pcapListenSocket(_L2pcapdnetSocket): - desc = "read packets at layer 2 using libpcap" - - def __init__(self, iface=None, type=ETH_P_ALL, promisc=None, filter=None, monitor=None): # noqa: E501 - super(L2pcapListenSocket, self).__init__() - self.type = type - self.outs = None - self.iface = iface - if iface is None: - iface = conf.iface - if promisc is None: - promisc = conf.sniff_promisc - self.promisc = promisc - # Note: Timeout with Winpcap/Npcap - # The 4th argument of open_pcap corresponds to timeout. In an ideal world, we would # noqa: E501 - # set it to 0 ==> blocking pcap_next_ex. - # However, the way it is handled is very poor, and result in a jerky packet stream. # noqa: E501 - # To fix this, we set 100 and the implementation under windows is slightly different, as # noqa: E501 - # everything is always received as non-blocking - self.ins = open_pcap(iface, MTU, self.promisc, 100, - monitor=monitor) - try: - ioctl(self.ins.fileno(), BIOCIMMEDIATE, struct.pack("I", 1)) - except Exception: - pass - if type == ETH_P_ALL: # Do not apply any filter if Ethernet type is given # noqa: E501 - if conf.except_filter: - if filter: - filter = "(%s) and not (%s)" % (filter, conf.except_filter) # noqa: E501 - else: - filter = "not (%s)" % conf.except_filter - if filter: - self.ins.setfilter(filter) - - def send(self, x): - raise Scapy_Exception("Can't send anything with L2pcapListenSocket") # noqa: E501 - - class L2pcapSocket(_L2pcapdnetSocket): - desc = "read/write packets at layer 2 using only libpcap" - - def __init__(self, iface=None, type=ETH_P_ALL, promisc=None, filter=None, nofilter=0, # noqa: E501 - monitor=None): - super(L2pcapSocket, self).__init__() - if iface is None: - iface = conf.iface - self.iface = iface - if promisc is None: - promisc = 0 - self.promisc = promisc - # See L2pcapListenSocket for infos about this line - self.ins = open_pcap(iface, MTU, self.promisc, 100, - monitor=monitor) - self.outs = self.ins - try: - ioctl(self.ins.fileno(), BIOCIMMEDIATE, struct.pack("I", 1)) - except Exception: - pass - if nofilter: - if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap # noqa: E501 - filter = "ether proto %i" % type - else: - filter = None - else: - if conf.except_filter: - if filter: - filter = "(%s) and not (%s)" % (filter, conf.except_filter) # noqa: E501 - else: - filter = "not (%s)" % conf.except_filter - if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap # noqa: E501 - if filter: - filter = "(ether proto %i) and (%s)" % (type, filter) - else: - filter = "ether proto %i" % type - if filter: - self.ins.setfilter(filter) - - def send(self, x): - sx = raw(x) - if hasattr(x, "sent_time"): - x.sent_time = time.time() - return self.outs.send(sx) - - class L3pcapSocket(L2pcapSocket): - desc = "read/write packets at layer 3 using only libpcap" - - def recv(self, x=MTU): - r = L2pcapSocket.recv(self, x) - if r: - return r.payload - - def send(self, x): - # Makes send detects when it should add Loopback(), Dot11... instead of Ether() # noqa: E501 - ll = self.ins.datalink() - if ll in conf.l2types: - cls = conf.l2types[ll] - else: - cls = conf.default_l2 - warning("Unable to guess datalink type (interface=%s linktype=%i). Using %s", self.iface, ll, cls.name) # noqa: E501 - sx = raw(cls() / x) - if hasattr(x, "sent_time"): - x.sent_time = time.time() - return self.ins.send(sx) -else: - # No libpcap installed - get_if_list = lambda: [] - if WINDOWS: - NPCAP_PATH = "" - -########## -# DNET # -########## - -# DEPRECATED - -if conf.use_dnet: - warning("dnet usage with scapy is deprecated, and will be removed in a future version.") # noqa: E501 - try: - try: - # First try to import dnet - import dnet - except ImportError: - # Then, try to import dumbnet as dnet - import dumbnet as dnet - except ImportError as e: - if conf.interactive: - log_loading.error("Unable to import dnet module: %s", e) - conf.use_dnet = False - - def get_if_raw_hwaddr(iff): - "dummy" - return (0, b"\0\0\0\0\0\0") - - def get_if_raw_addr(iff): # noqa: F811 - "dummy" - return b"\0\0\0\0" - - def get_if_list(): - "dummy" - return {} - else: - raise - else: - def get_if_raw_hwaddr(iff): - """Return a tuple containing the link type and the raw hardware - address corresponding to the interface 'iff'""" - - if iff == scapy.arch.LOOPBACK_NAME: - return (ARPHDR_LOOPBACK, b'\x00' * 6) - - # Retrieve interface information - try: - tmp_intf = dnet.intf().get(iff) - link_addr = tmp_intf["link_addr"] - except Exception: - raise Scapy_Exception("Error in attempting to get hw address" - " for interface [%s]" % iff) - - if hasattr(link_addr, "type"): - # Legacy dnet module - return link_addr.type, link_addr.data - - else: - # dumbnet module - mac = mac2str(str(link_addr)) - - # Adjust the link type - if tmp_intf["type"] == 6: # INTF_TYPE_ETH from dnet - return (ARPHDR_ETHER, mac) - - return (tmp_intf["type"], mac) - - def get_if_raw_addr(ifname): # noqa: F811 - i = dnet.intf() - try: - return i.get(ifname)["addr"].data - except (OSError, KeyError): - warning("No MAC address found on %s !" % ifname) - return b"\0\0\0\0" - - def get_if_list(): - """Returns all dnet names""" - return [i.get("name", None) for i in dnet.intf()] - - def get_working_if(): - """Returns the first interface than can be used with dnet""" - - if_iter = iter(dnet.intf()) - - try: - intf = next(if_iter) - except (StopIteration, RuntimeError): - return scapy.consts.LOOPBACK_NAME - - return intf.get("name", scapy.consts.LOOPBACK_NAME) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/solaris.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/solaris.py deleted file mode 100644 index b450c3d5df..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/solaris.py +++ /dev/null @@ -1,36 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Customization for the Solaris operation system. -""" - -import socket -import scapy.consts - -from scapy.config import conf -conf.use_pcap = True - -# IPPROTO_GRE is missing on Solaris -socket.IPPROTO_GRE = 47 - -# From sys/sockio.h and net/if.h -SIOCGIFHWADDR = 0xc02069b9 # Get hardware address - -from scapy.arch.pcapdnet import * # noqa: F401, F403 -from scapy.arch.unix import * # noqa: F401, F403 -from scapy.arch.common import get_if_raw_hwaddr # noqa: F401, F403 - - -def get_working_if(): - """Return an interface that works""" - try: - # return the interface associated with the route with smallest - # mask (route by default if it exists) - iface = min(conf.route.routes, key=lambda x: x[1])[3] - except ValueError: - # no route - iface = scapy.consts.LOOPBACK_INTERFACE - return iface diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/unix.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/unix.py deleted file mode 100644 index 244ddd07c7..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/unix.py +++ /dev/null @@ -1,355 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Common customizations for all Unix-like operating systems other than Linux -""" - -import os -import socket - -import scapy.config -import scapy.utils -from scapy.arch import get_if_addr -from scapy.config import conf -from scapy.consts import FREEBSD, NETBSD, OPENBSD, SOLARIS, LOOPBACK_NAME -from scapy.error import warning, log_interactive -from scapy.pton_ntop import inet_pton -from scapy.utils6 import in6_getscope, construct_source_candidate_set -from scapy.utils6 import in6_isvalid, in6_ismlladdr, in6_ismnladdr - - -################## -# Routes stuff # -################## - -def _guess_iface_name(netif): - """ - We attempt to guess the name of interfaces that are truncated from the - output of ifconfig -l. - If there is only one possible candidate matching the interface name then we - return it. - If there are none or more, then we return None. - """ - with os.popen('%s -l' % conf.prog.ifconfig) as fdesc: - ifaces = fdesc.readline().strip().split(' ') - matches = [iface for iface in ifaces if iface.startswith(netif)] - if len(matches) == 1: - return matches[0] - return None - - -def read_routes(): - """Return a list of IPv4 routes than can be used by Scapy. - - This function parses netstat. - """ - if SOLARIS: - f = os.popen("netstat -rvn -f inet") - elif FREEBSD: - f = os.popen("netstat -rnW") # -W to handle long interface names - else: - f = os.popen("netstat -rn -f inet") - ok = 0 - mtu_present = False - prio_present = False - refs_present = False - use_present = False - routes = [] - pending_if = [] - for line in f.readlines(): - if not line: - break - line = line.strip().lower() - if line.find("----") >= 0: # a separation line - continue - if not ok: - if line.find("destination") >= 0: - ok = 1 - mtu_present = "mtu" in line - prio_present = "prio" in line - refs_present = "ref" in line # There is no s on Solaris - use_present = "use" in line - continue - if not line: - break - rt = line.split() - if SOLARIS: - dest, netmask, gw, netif = rt[:4] - flg = rt[4 + mtu_present + refs_present] - else: - dest, gw, flg = rt[:3] - locked = OPENBSD and rt[6] == "l" - offset = mtu_present + prio_present + refs_present + locked - offset += use_present - netif = rt[3 + offset] - if flg.find("lc") >= 0: - continue - elif dest == "default": - dest = 0 - netmask = 0 - elif SOLARIS: - dest = scapy.utils.atol(dest) - netmask = scapy.utils.atol(netmask) - else: - if "/" in dest: - dest, netmask = dest.split("/") - netmask = scapy.utils.itom(int(netmask)) - else: - netmask = scapy.utils.itom((dest.count(".") + 1) * 8) - dest += ".0" * (3 - dest.count(".")) - dest = scapy.utils.atol(dest) - # XXX: TODO: add metrics for unix.py (use -e option on netstat) - metric = 1 - if "g" not in flg: - gw = '0.0.0.0' - if netif is not None: - try: - ifaddr = get_if_addr(netif) - routes.append((dest, netmask, gw, netif, ifaddr, metric)) - except OSError as exc: - if exc.message == 'Device not configured': - # This means the interface name is probably truncated by - # netstat -nr. We attempt to guess it's name and if not we - # ignore it. - guessed_netif = _guess_iface_name(netif) - if guessed_netif is not None: - ifaddr = get_if_addr(guessed_netif) - routes.append((dest, netmask, gw, guessed_netif, ifaddr, metric)) # noqa: E501 - else: - warning("Could not guess partial interface name: %s", netif) # noqa: E501 - else: - raise - else: - pending_if.append((dest, netmask, gw)) - f.close() - - # On Solaris, netstat does not provide output interfaces for some routes - # We need to parse completely the routing table to route their gw and - # know their output interface - for dest, netmask, gw in pending_if: - gw_l = scapy.utils.atol(gw) - max_rtmask, gw_if, gw_if_addr, = 0, None, None - for rtdst, rtmask, _, rtif, rtaddr in routes[:]: - if gw_l & rtmask == rtdst: - if rtmask >= max_rtmask: - max_rtmask = rtmask - gw_if = rtif - gw_if_addr = rtaddr - # XXX: TODO add metrics - metric = 1 - if gw_if: - routes.append((dest, netmask, gw, gw_if, gw_if_addr, metric)) - else: - warning("Did not find output interface to reach gateway %s", gw) - - return routes - -############ -# IPv6 # -############ - - -def _in6_getifaddr(ifname): - """ - Returns a list of IPv6 addresses configured on the interface ifname. - """ - - # Get the output of ifconfig - try: - f = os.popen("%s %s" % (conf.prog.ifconfig, ifname)) - except OSError: - log_interactive.warning("Failed to execute ifconfig.") - return [] - - # Iterate over lines and extract IPv6 addresses - ret = [] - for line in f: - if "inet6" in line: - addr = line.rstrip().split(None, 2)[1] # The second element is the IPv6 address # noqa: E501 - else: - continue - if '%' in line: # Remove the interface identifier if present - addr = addr.split("%", 1)[0] - - # Check if it is a valid IPv6 address - try: - inet_pton(socket.AF_INET6, addr) - except (socket.error, ValueError): - continue - - # Get the scope and keep the address - scope = in6_getscope(addr) - ret.append((addr, scope, ifname)) - - f.close() - return ret - - -def in6_getifaddr(): - """ - Returns a list of 3-tuples of the form (addr, scope, iface) where - 'addr' is the address of scope 'scope' associated to the interface - 'iface'. - - This is the list of all addresses of all interfaces available on - the system. - """ - - # List all network interfaces - if OPENBSD or SOLARIS: - if SOLARIS: - cmd = "%s -a6" - else: - cmd = "%s" - try: - f = os.popen(cmd % conf.prog.ifconfig) - except OSError: - log_interactive.warning("Failed to execute ifconfig.") - return [] - - # Get the list of network interfaces - splitted_line = [] - for l in f: - if "flags" in l: - iface = l.split()[0].rstrip(':') - splitted_line.append(iface) - - else: # FreeBSD, NetBSD or Darwin - try: - f = os.popen("%s -l" % conf.prog.ifconfig) - except OSError: - log_interactive.warning("Failed to execute ifconfig.") - return [] - - # Get the list of network interfaces - splitted_line = f.readline().rstrip().split() - - ret = [] - for i in splitted_line: - ret += _in6_getifaddr(i) - f.close() - return ret - - -def read_routes6(): - """Return a list of IPv6 routes than can be used by Scapy. - - This function parses netstat. - """ - - # Call netstat to retrieve IPv6 routes - fd_netstat = os.popen("netstat -rn -f inet6") - - # List interfaces IPv6 addresses - lifaddr = in6_getifaddr() - if not lifaddr: - fd_netstat.close() - return [] - - # Routes header information - got_header = False - mtu_present = False - prio_present = False - - # Parse the routes - routes = [] - for line in fd_netstat.readlines(): - - # Parse the routes header and try to identify extra columns - if not got_header: - if "Destination" == line[:11]: - got_header = True - mtu_present = "Mtu" in line - prio_present = "Prio" in line - continue - - # Parse a route entry according to the operating system - splitted_line = line.split() - if OPENBSD or NETBSD: - index = 5 + mtu_present + prio_present - if len(splitted_line) < index: - warning("Not enough columns in route entry !") - continue - destination, next_hop, flags = splitted_line[:3] - dev = splitted_line[index] - else: - # FREEBSD or DARWIN - if len(splitted_line) < 4: - warning("Not enough columns in route entry !") - continue - destination, next_hop, flags, dev = splitted_line[:4] - - # XXX: TODO: add metrics for unix.py (use -e option on netstat) - metric = 1 - - # Check flags - if "U" not in flags: # usable route - continue - if "R" in flags: # Host or net unreachable - continue - if "m" in flags: # multicast address - # Note: multicast routing is handled in Route6.route() - continue - - # Replace link with the default route in next_hop - if "link" in next_hop: - next_hop = "::" - - # Default prefix length - destination_plen = 128 - - # Extract network interface from the zone id - if '%' in destination: - destination, dev = destination.split('%') - if '/' in dev: - # Example: fe80::%lo0/64 ; dev = "lo0/64" - dev, destination_plen = dev.split('/') - if '%' in next_hop: - next_hop, dev = next_hop.split('%') - - # Ensure that the next hop is a valid IPv6 address - if not in6_isvalid(next_hop): - # Note: the 'Gateway' column might contain a MAC address - next_hop = "::" - - # Modify parsed routing entries - # Note: these rules are OS specific and may evolve over time - if destination == "default": - destination, destination_plen = "::", 0 - elif '/' in destination: - # Example: fe80::/10 - destination, destination_plen = destination.split('/') - if '/' in dev: - # Example: ff02::%lo0/32 ; dev = "lo0/32" - dev, destination_plen = dev.split('/') - - # Check route entries parameters consistency - if not in6_isvalid(destination): - warning("Invalid destination IPv6 address in route entry !") - continue - try: - destination_plen = int(destination_plen) - except Exception: - warning("Invalid IPv6 prefix length in route entry !") - continue - if in6_ismlladdr(destination) or in6_ismnladdr(destination): - # Note: multicast routing is handled in Route6.route() - continue - - if LOOPBACK_NAME in dev: - # Handle ::1 separately - cset = ["::1"] - next_hop = "::" - else: - # Get possible IPv6 source addresses - devaddrs = (x for x in lifaddr if x[2] == dev) - cset = construct_source_candidate_set(destination, destination_plen, devaddrs) # noqa: E501 - - if len(cset): - routes.append((destination, destination_plen, next_hop, dev, cset, metric)) # noqa: E501 - - fd_netstat.close() - return routes diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/windows/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/windows/__init__.py deleted file mode 100644 index e36eb091e7..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/windows/__init__.py +++ /dev/null @@ -1,1072 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Copyright (C) Gabriel Potter -# This program is published under a GPLv2 license - -""" -Customizations needed to support Microsoft Windows. -""" - -from __future__ import absolute_import -from __future__ import print_function -import os -import socket -import subprocess as sp -from glob import glob -import struct - -import scapy -import scapy.consts -from scapy.arch.windows.structures import _windows_title, \ - GetAdaptersAddresses, GetIpForwardTable, GetIpForwardTable2, \ - get_service_status -from scapy.consts import WINDOWS, WINDOWS_XP -from scapy.config import conf, ConfClass -from scapy.error import Scapy_Exception, log_loading, log_runtime, warning -from scapy.pton_ntop import inet_ntop, inet_pton -from scapy.utils import atol, itom, pretty_list, mac2str, str2mac -from scapy.utils6 import construct_source_candidate_set, in6_getscope -from scapy.data import ARPHDR_ETHER, load_manuf -import scapy.modules.six as six -from scapy.modules.six.moves import input, winreg, UserDict -from scapy.compat import plain_str -from scapy.supersocket import SuperSocket - -conf.use_pcap = True -conf.use_dnet = False - -# These import must appear after setting conf.use_* variables -from scapy.arch import pcapdnet # noqa: E402 -from scapy.arch.pcapdnet import NPCAP_PATH, get_if_list # noqa: E402 - -# hot-patching socket for missing variables on Windows -if not hasattr(socket, 'IPPROTO_IPIP'): - socket.IPPROTO_IPIP = 4 -if not hasattr(socket, 'IP_RECVTTL'): - socket.IP_RECVTTL = 12 -if not hasattr(socket, 'IPV6_HDRINCL'): - socket.IPV6_HDRINCL = 36 -# https://bugs.python.org/issue29515 -if not hasattr(socket, 'IPPROTO_IPV6'): - socket.SOL_IPV6 = 41 -if not hasattr(socket, 'SOL_IPV6'): - socket.SOL_IPV6 = socket.IPPROTO_IPV6 -if not hasattr(socket, 'IPPROTO_GRE'): - socket.IPPROTO_GRE = 47 -if not hasattr(socket, 'IPPROTO_AH'): - socket.IPPROTO_AH = 51 -if not hasattr(socket, 'IPPROTO_ESP'): - socket.IPPROTO_ESP = 50 - -_WlanHelper = NPCAP_PATH + "\\WlanHelper.exe" - - -def _encapsulate_admin(cmd): - """Encapsulate a command with an Administrator flag""" - # To get admin access, we start a new powershell instance with admin - # rights, which will execute the command. This needs to be done from a - # powershell as we run it from a cmd. - # ! Behold ! - return ("powershell /command \"Start-Process cmd " - "-windowstyle hidden -Wait -PassThru -Verb RunAs " - "-ArgumentList '/c %s'\"" % cmd) - - -def _get_npcap_config(param_key): - """ - Get a Npcap parameter matching key in the registry. - - List: - AdminOnly, DefaultFilterSettings, DltNull, Dot11Adapters, Dot11Support - LoopbackAdapter, LoopbackSupport, NdisImPlatformBindingOptions, VlanSupport - WinPcapCompatible - """ - hkey = winreg.HKEY_LOCAL_MACHINE - node = r"SYSTEM\CurrentControlSet\Services\npcap\Parameters" - try: - key = winreg.OpenKey(hkey, node) - dot11_adapters, _ = winreg.QueryValueEx(key, param_key) - winreg.CloseKey(key) - except WindowsError: - return None - return dot11_adapters - - -def _where(filename, dirs=None, env="PATH"): - """Find file in current dir, in deep_lookup cache or in system path""" - if dirs is None: - dirs = [] - if not isinstance(dirs, list): - dirs = [dirs] - if glob(filename): - return filename - paths = [os.curdir] + os.environ[env].split(os.path.pathsep) + dirs - try: - return next(os.path.normpath(match) - for path in paths - for match in glob(os.path.join(path, filename)) - if match) - except (StopIteration, RuntimeError): - raise IOError("File not found: %s" % filename) - - -def win_find_exe(filename, installsubdir=None, env="ProgramFiles"): - """Find executable in current dir, system path or in the - given ProgramFiles subdir, and retuen its absolute path. - """ - fns = [filename] if filename.endswith(".exe") else [filename + ".exe", filename] # noqa: E501 - for fn in fns: - try: - if installsubdir is None: - path = _where(fn) - else: - path = _where(fn, dirs=[os.path.join(os.environ[env], installsubdir)]) # noqa: E501 - except IOError: - path = None - else: - break - return path - - -class WinProgPath(ConfClass): - _default = "" - - def __init__(self): - self._reload() - - def _reload(self): - self.pdfreader = None - self.psreader = None - self.svgreader = None - # We try some magic to find the appropriate executables - self.dot = win_find_exe("dot") - self.tcpdump = win_find_exe("windump") - self.tshark = win_find_exe("tshark") - self.tcpreplay = win_find_exe("tcpreplay") - self.display = self._default - self.hexedit = win_find_exe("hexer") - self.sox = win_find_exe("sox") - self.wireshark = win_find_exe("wireshark", "wireshark") - self.usbpcapcmd = win_find_exe( - "USBPcapCMD", - installsubdir="USBPcap", - env="programfiles" - ) - self.powershell = win_find_exe( - "powershell", - installsubdir="System32\\WindowsPowerShell\\v1.0", - env="SystemRoot" - ) - self.cscript = win_find_exe("cscript", installsubdir="System32", - env="SystemRoot") - self.cmd = win_find_exe("cmd", installsubdir="System32", - env="SystemRoot") - if self.wireshark: - try: - new_manuf = load_manuf( - os.path.sep.join( - self.wireshark.split(os.path.sep)[:-1] - ) + os.path.sep + "manuf" - ) - except (IOError, OSError): # FileNotFoundError not available on Py2 - using OSError # noqa: E501 - log_loading.warning("Wireshark is installed, but cannot read manuf !") # noqa: E501 - new_manuf = None - if new_manuf: - # Inject new ManufDB - conf.manufdb.__dict__.clear() - conf.manufdb.__dict__.update(new_manuf.__dict__) - - -def _exec_cmd(command): - """Call a CMD command and return the output and returncode""" - proc = sp.Popen(command, - stdout=sp.PIPE, - shell=True) - res = proc.communicate()[0] - return res, proc.returncode - - -conf.prog = WinProgPath() - -if conf.prog.tcpdump and conf.use_npcap: - def test_windump_npcap(): - """Return whether windump version is correct or not""" - try: - p_test_windump = sp.Popen([conf.prog.tcpdump, "-help"], stdout=sp.PIPE, stderr=sp.STDOUT) # noqa: E501 - stdout, err = p_test_windump.communicate() - _windows_title() - _output = stdout.lower() - return b"npcap" in _output and b"winpcap" not in _output - except Exception: - return False - windump_ok = test_windump_npcap() - if not windump_ok: - warning("The installed Windump version does not work with Npcap ! Refer to 'Winpcap/Npcap conflicts' in scapy's doc") # noqa: E501 - del windump_ok - - -def get_windows_if_list(extended=False): - """Returns windows interfaces through GetAdaptersAddresses. - - params: - - extended: include anycast and multicast IPv6 (default False)""" - # Should work on Windows XP+ - def _get_mac(x): - size = x["physical_address_length"] - if size != 6: - return "" - data = bytearray(x["physical_address"]) - return str2mac(bytes(data)[:size]) - - def _get_ips(x): - unicast = x['first_unicast_address'] - anycast = x['first_anycast_address'] - multicast = x['first_multicast_address'] - - def _resolve_ips(y): - if not isinstance(y, list): - return [] - ips = [] - for ip in y: - addr = ip['address']['address'].contents - if addr.si_family == socket.AF_INET6: - ip_key = "Ipv6" - si_key = "sin6_addr" - else: - ip_key = "Ipv4" - si_key = "sin_addr" - data = getattr(addr, ip_key) - data = getattr(data, si_key) - data = bytes(bytearray(data.byte)) - # Build IP - if data: - ips.append(inet_ntop(addr.si_family, data)) - return ips - - ips = [] - ips.extend(_resolve_ips(unicast)) - if extended: - ips.extend(_resolve_ips(anycast)) - ips.extend(_resolve_ips(multicast)) - return ips - - if six.PY2: - _str_decode = lambda x: x.encode('utf8', errors='ignore') - else: - _str_decode = plain_str - return [ - { - "name": _str_decode(x["friendly_name"]), - "win_index": x["interface_index"], - "description": _str_decode(x["description"]), - "guid": _str_decode(x["adapter_name"]), - "mac": _get_mac(x), - "ipv4_metric": 0 if WINDOWS_XP else x["ipv4_metric"], - "ipv6_metric": 0 if WINDOWS_XP else x["ipv6_metric"], - "ips": _get_ips(x) - } for x in GetAdaptersAddresses() - ] - - -def get_ips(v6=False): - """Returns all available IPs matching to interfaces, using the windows system. - Should only be used as a WinPcapy fallback.""" - res = {} - for iface in six.itervalues(IFACES): - ips = [] - for ip in iface.ips: - if v6 and ":" in ip: - ips.append(ip) - elif not v6 and ":" not in ip: - ips.append(ip) - res[iface] = ips - return res - - -def get_ip_from_name(ifname, v6=False): - """Backward compatibility: indirectly calls get_ips - Deprecated.""" - iface = IFACES.dev_from_name(ifname) - return get_ips(v6=v6).get(iface, [""])[0] - - -def _pcapname_to_guid(pcap_name): - """Converts a Winpcap/Npcap pcpaname to its guid counterpart. - e.g. \\DEVICE\\NPF_{...} => {...} - """ - if "{" in pcap_name: - return "{" + pcap_name.split("{")[1] - return pcap_name - - -class NetworkInterface(object): - """A network interface of your local host""" - - def __init__(self, data=None): - self.name = None - self.ip = None - self.mac = None - self.pcap_name = None - self.description = None - self.invalid = False - self.raw80211 = None - self.cache_mode = None - self.ipv4_metric = None - self.ipv6_metric = None - self.ips = None - self.flags = None - if data is not None: - self.update(data) - - def update(self, data): - """Update info about a network interface according - to a given dictionary. Such data is provided by get_windows_if_list - """ - self.data = data - self.name = data['name'] - self.description = data['description'] - self.win_index = data['win_index'] - self.guid = data['guid'] - self.mac = data['mac'] - self.ipv4_metric = data['ipv4_metric'] - self.ipv6_metric = data['ipv6_metric'] - self.ips = data['ips'] - if 'invalid' in data: - self.invalid = data['invalid'] - # Other attributes are optional - self._update_pcapdata() - - try: - # Npcap loopback interface - if conf.use_npcap: - pcap_name_loopback = _get_npcap_config("LoopbackAdapter") - if pcap_name_loopback: # May not be defined - guid = _pcapname_to_guid(pcap_name_loopback) - if self.guid == guid: - # https://nmap.org/npcap/guide/npcap-devguide.html - self.mac = "00:00:00:00:00:00" - self.ip = "127.0.0.1" - return - except KeyError: - pass - - try: - self.ip = next(x for x in self.ips if ":" not in x) - except StopIteration: - pass - - try: - # Windows native loopback interface - if not self.ip and self.name == scapy.consts.LOOPBACK_NAME: - self.ip = "127.0.0.1" - except (KeyError, AttributeError, NameError) as e: - print(e) - - def _update_pcapdata(self): - # https://github.com/nmap/nmap/issues/1422 - # Lookup for the Winpcap/Npcap pcap_name according to the GUID - if self.is_invalid(): - return - for pcap_name, if_data in six.iteritems(conf.cache_iflist): - _, ips, flags = if_data - if pcap_name.endswith(self.guid): - self.pcap_name = pcap_name - self.flags = flags - self.ips.extend(x for x in ips if x not in self.ips) - return - # No matching pcap_name found: won't be able to sniff on it - self.invalid = True - - def is_invalid(self): - return self.invalid - - def _check_npcap_requirement(self): - if not conf.use_npcap: - raise OSError("This operation requires Npcap.") - if self.raw80211 is None: - # The Dot11Adapters is not officially supported anymore. - # we just try/except, and check that it exists globally - val = _get_npcap_config("Dot11Support") - self.raw80211 = bool(int(val)) if val else False - if not self.raw80211: - raise Scapy_Exception("This interface does not support raw 802.11") - - def _npcap_set(self, key, val): - """Internal function. Set a [key] parameter to [value]""" - res, code = _exec_cmd(_encapsulate_admin( - " ".join([_WlanHelper, self.guid[1:-1], key, val]) - )) - _windows_title() # Reset title of the window - if code != 0: - raise OSError(res.decode("utf8", errors="ignore")) - return (code == 0) - - def _npcap_get(self, key): - res, code = _exec_cmd(" ".join([_WlanHelper, self.guid[1:-1], key])) - _windows_title() # Reset title of the window - if code != 0: - raise OSError(res.decode("utf8", errors="ignore")) - return plain_str(res.strip()) - - def mode(self): - """Get the interface operation mode. - Only available with Npcap.""" - self._check_npcap_requirement() - return self._npcap_get("mode") - - def ismonitor(self): - """Returns True if the interface is in monitor mode. - Only available with Npcap.""" - if self.cache_mode is not None: - return self.cache_mode - try: - res = (self.mode() == "monitor") - self.cache_mode = res - return res - except Scapy_Exception: - return False - - def setmonitor(self, enable=True): - """Alias for setmode('monitor') or setmode('managed') - Only available with Npcap""" - # We must reset the monitor cache - if enable: - res = self.setmode('monitor') - else: - res = self.setmode('managed') - if not res: - log_runtime.error("Npcap WlanHelper returned with an error code !") - self.cache_mode = None - tmp = self.cache_mode = self.ismonitor() - return tmp if enable else (not tmp) - - def availablemodes(self): - """Get all available interface modes. - Only available with Npcap.""" - # According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11 # noqa: E501 - self._check_npcap_requirement() - return self._npcap_get("modes").split(",") - - def setmode(self, mode): - """Set the interface mode. It can be: - - 0 or managed: Managed Mode (aka "Extensible Station Mode") - - 1 or monitor: Monitor Mode (aka "Network Monitor Mode") - - 2 or master: Master Mode (aka "Extensible Access Point") - (supported from Windows 7 and later) - - 3 or wfd_device: The Wi-Fi Direct Device operation mode - (supported from Windows 8 and later) - - 4 or wfd_owner: The Wi-Fi Direct Group Owner operation mode - (supported from Windows 8 and later) - - 5 or wfd_client: The Wi-Fi Direct Client operation mode - (supported from Windows 8 and later) - Only available with Npcap.""" - # According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11 # noqa: E501 - self._check_npcap_requirement() - _modes = { - 0: "managed", - 1: "monitor", - 2: "master", - 3: "wfd_device", - 4: "wfd_owner", - 5: "wfd_client" - } - m = _modes.get(mode, "unknown") if isinstance(mode, int) else mode - return self._npcap_set("mode", m) - - def channel(self): - """Get the channel of the interface. - Only available with Npcap.""" - # According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11 # noqa: E501 - self._check_npcap_requirement() - return int(self._npcap_get("channel")) - - def setchannel(self, channel): - """Set the channel of the interface (1-14): - Only available with Npcap.""" - # According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11 # noqa: E501 - self._check_npcap_requirement() - return self._npcap_set("channel", str(channel)) - - def frequence(self): - """Get the frequence of the interface. - Only available with Npcap.""" - # According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11 # noqa: E501 - self._check_npcap_requirement() - return int(self._npcap_get("freq")) - - def setfrequence(self, freq): - """Set the channel of the interface (1-14): - Only available with Npcap.""" - # According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11 # noqa: E501 - self._check_npcap_requirement() - return self._npcap_set("freq", str(freq)) - - def availablemodulations(self): - """Get all available 802.11 interface modulations. - Only available with Npcap.""" - # According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11 # noqa: E501 - self._check_npcap_requirement() - return self._npcap_get("modus").split(",") - - def modulation(self): - """Get the 802.11 modulation of the interface. - Only available with Npcap.""" - # According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11 # noqa: E501 - self._check_npcap_requirement() - return self._npcap_get("modu") - - def setmodulation(self, modu): - """Set the interface modulation. It can be: - - 0: dsss - - 1: fhss - - 2: irbaseband - - 3: ofdm - - 4: hrdss - - 5: erp - - 6: ht - - 7: vht - - 8: ihv - - 9: mimo-ofdm - - 10: mimo-ofdm - - the value directly - Only available with Npcap.""" - # According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11 # noqa: E501 - self._check_npcap_requirement() - _modus = { - 0: "dsss", - 1: "fhss", - 2: "irbaseband", - 3: "ofdm", - 4: "hrdss", - 5: "erp", - 6: "ht", - 7: "vht", - 8: "ihv", - 9: "mimo-ofdm", - 10: "mimo-ofdm", - } - m = _modus.get(modu, "unknown") if isinstance(modu, int) else modu - return self._npcap_set("modu", str(m)) - - def __repr__(self): - return "<%s [%s] %s>" % (self.__class__.__name__, - self.description, - self.guid) - - -def get_if_raw_addr(iff): - """Return the raw IPv4 address of interface""" - if not iff.ip: - return None - return inet_pton(socket.AF_INET, iff.ip) - - -def pcap_service_name(): - """Return the pcap adapter service's name""" - return "npcap" if conf.use_npcap else "npf" - - -def pcap_service_status(): - """Returns whether the windows pcap adapter is running or not""" - status = get_service_status(pcap_service_name()) - return status["dwCurrentState"] == 4 - - -def _pcap_service_control(action, askadmin=True): - """Internal util to run pcap control command""" - command = action + ' ' + pcap_service_name() - res, code = _exec_cmd(_encapsulate_admin(command) if askadmin else command) - if code != 0: - warning(res.decode("utf8", errors="ignore")) - return (code == 0) - - -def pcap_service_start(askadmin=True): - """Starts the pcap adapter. Will ask for admin. Returns True if success""" - return _pcap_service_control('sc start', askadmin=askadmin) - - -def pcap_service_stop(askadmin=True): - """Stops the pcap adapter. Will ask for admin. Returns True if success""" - return _pcap_service_control('sc stop', askadmin=askadmin) - - -class NetworkInterfaceDict(UserDict): - """Store information about network interfaces and convert between names""" - - @classmethod - def _pcap_check(cls): - """Performs checks/restart pcap adapter""" - if not conf.use_pcap: - # Winpcap/Npcap isn't installed - return - - _detect = pcap_service_status() - - def _ask_user(): - if not conf.interactive: - return False - msg = "Do you want to start it ? (yes/no) [y]: " - try: - # Better IPython compatibility - import IPython - return IPython.utils.io.ask_yes_no(msg, default='y') - except (NameError, ImportError): - while True: - _confir = input(msg) - _confir = _confir.lower().strip() - if _confir in ["yes", "y", ""]: - return True - elif _confir in ["no", "n"]: - return False - return False - _error_msg = ("No match between your pcap and windows " - "network interfaces found. ") - if _detect: - # No action needed - return - else: - warning( - "Scapy has detected that your pcap service is not running !" - ) - if not conf.interactive or _ask_user(): - succeed = pcap_service_start(askadmin=conf.interactive) - if succeed: - log_loading.info("Pcap service started !") - return - _error_msg = "Could not start the pcap service ! " - warning(_error_msg + - "You probably won't be able to send packets. " - "Deactivating unneeded interfaces and restarting " - "Scapy might help. Check your winpcap/npcap installation " - "and access rights.") - - def load(self): - if not get_if_list(): - # Try a restart - NetworkInterfaceDict._pcap_check() - - for i in get_windows_if_list(): - try: - interface = NetworkInterface(i) - self.data[interface.guid] = interface - except KeyError: - pass - - # Remove invalid loopback interfaces (not usable) - for key, iface in self.data.copy().items(): - if iface.ip == "127.0.0.1" and iface.is_invalid(): - del self.data[key] - - # Replace LOOPBACK_INTERFACE - try: - scapy.consts.LOOPBACK_INTERFACE = self.dev_from_name( - scapy.consts.LOOPBACK_NAME, - ) - except ValueError: - pass - # Support non-windows cards (e.g. Napatech) - index = 0 - for pcap_name, if_data in six.iteritems(conf.cache_iflist): - name, _, _ = if_data - guid = _pcapname_to_guid(pcap_name) - if guid not in self.data: - index -= 1 - dummy_data = { - 'name': name, - 'description': "[Unknown] %s" % name, - 'win_index': index, - 'guid': guid, - 'invalid': False, - 'mac': 'ff:ff:ff:ff:ff:ff', - 'ipv4_metric': 0, - 'ipv6_metric': 0, - 'ips': [] - } - # No KeyError will happen here, as we get it from cache - self.data[guid] = NetworkInterface(dummy_data) - - def dev_from_name(self, name): - """Return the first pcap device name for a given Windows - device name. - """ - try: - return next(iface for iface in six.itervalues(self) - if (iface.name == name or iface.description == name)) - except (StopIteration, RuntimeError): - raise ValueError("Unknown network interface %r" % name) - - def dev_from_pcapname(self, pcap_name): - """Return Windows device name for given pcap device name.""" - try: - return next(iface for iface in six.itervalues(self) - if iface.pcap_name == pcap_name) - except (StopIteration, RuntimeError): - raise ValueError("Unknown pypcap network interface %r" % pcap_name) - - def dev_from_index(self, if_index): - """Return interface name from interface index""" - try: - if_index = int(if_index) # Backward compatibility - return next(iface for iface in six.itervalues(self) - if iface.win_index == if_index) - except (StopIteration, RuntimeError): - if str(if_index) == "1": - # Test if the loopback interface is set up - if isinstance(scapy.consts.LOOPBACK_INTERFACE, NetworkInterface): # noqa: E501 - return scapy.consts.LOOPBACK_INTERFACE - raise ValueError("Unknown network interface index %r" % if_index) - - def reload(self): - """Reload interface list""" - self.restarted_adapter = False - self.data.clear() - if conf.use_pcap: - # Reload from Winpcapy - from scapy.arch.pcapdnet import load_winpcapy - load_winpcapy() - self.load() - # Reload conf.iface - conf.iface = get_working_if() - - def show(self, resolve_mac=True, print_result=True): - """Print list of available network interfaces in human readable form""" - res = [] - for iface_name in sorted(self.data): - dev = self.data[iface_name] - mac = dev.mac - if resolve_mac and conf.manufdb: - mac = conf.manufdb._resolve_MAC(mac) - validity_color = lambda x: conf.color_theme.red if x else \ - conf.color_theme.green - description = validity_color(dev.is_invalid())( - str(dev.description) - ) - index = str(dev.win_index) - res.append((index, description, str(dev.ip), mac)) - - res = pretty_list(res, [("INDEX", "IFACE", "IP", "MAC")], sortBy=2) - if print_result: - print(res) - else: - return res - - def __repr__(self): - return self.show(print_result=False) - - -IFACES = ifaces = NetworkInterfaceDict() -IFACES.load() - - -def pcapname(dev): - """Get the device pcap name by device name or Scapy NetworkInterface - - """ - if isinstance(dev, NetworkInterface): - if dev.is_invalid(): - return None - return dev.pcap_name - try: - return IFACES.dev_from_name(dev).pcap_name - except ValueError: - return IFACES.dev_from_pcapname(dev).pcap_name - - -def dev_from_pcapname(pcap_name): - """Return Scapy device name for given pcap device name""" - return IFACES.dev_from_pcapname(pcap_name) - - -def dev_from_index(if_index): - """Return Windows adapter name for given Windows interface index""" - return IFACES.dev_from_index(if_index) - - -def show_interfaces(resolve_mac=True): - """Print list of available network interfaces""" - return IFACES.show(resolve_mac) - - -if conf.use_pcap: - _orig_open_pcap = pcapdnet.open_pcap - - def open_pcap(iface, *args, **kargs): - """open_pcap: Windows routine for creating a pcap from an interface. - This function is also responsible for detecting monitor mode. - """ - iface_pcap_name = pcapname(iface) - if not isinstance(iface, NetworkInterface) and \ - iface_pcap_name is not None: - iface = IFACES.dev_from_name(iface) - if iface.is_invalid(): - raise Scapy_Exception( - "Interface is invalid (no pcap match found) !" - ) - # Only check monitor mode when manually specified. - # Checking/setting for monitor mode will slow down the process, and the - # common is case is not to use monitor mode - kw_monitor = kargs.get("monitor", None) - if conf.use_npcap and kw_monitor is not None: - monitored = iface.ismonitor() - if kw_monitor is not monitored: - # The monitor param is specified, and not matching the current - # interface state - iface.setmonitor(kw_monitor) - return _orig_open_pcap(iface_pcap_name, *args, **kargs) - pcapdnet.open_pcap = open_pcap - -get_if_raw_hwaddr = pcapdnet.get_if_raw_hwaddr = lambda iface, *args, **kargs: ( # noqa: E501 - ARPHDR_ETHER, mac2str(IFACES.dev_from_pcapname(pcapname(iface)).mac) -) - - -def _read_routes_c_v1(): - """Retrieve Windows routes through a GetIpForwardTable call. - - This is compatible with XP but won't get IPv6 routes.""" - def _extract_ip(obj): - return inet_ntop(socket.AF_INET, struct.pack(" -# Copyright (C) Gabriel Potter -# This program is published under a GPLv2 license - -""" -Native Microsoft Windows sockets (L3 only) - -## Notice: ICMP packets - -DISCLAIMER: Please use Npcap/Winpcap to send/receive ICMP. It is going to work. -Below is some additional information, mainly implemented in a testing purpose. - -When in native mode, everything goes through the Windows kernel. -This firstly requires that the Firewall is open. Be sure it allows ICMPv4/6 -packets in and out. -Windows may drop packets that it finds wrong. for instance, answers to -ICMP packets with id=0 or seq=0 may be dropped. It means that sent packets -should (most of the time) be perfectly built. - -A perfectly built ICMP req packet on Windows means that its id is 1, its -checksum (IP and ICMP) are correctly built, but also that its seq number is -in the "allowed range". - In fact, every time an ICMP packet is sent on Windows, a global sequence -number is increased, which is only reset at boot time. The seq number of the -received ICMP packet must be in the range [current, current + 3] to be valid, -and received by the socket. The current number is quite hard to get, thus we -provide in this module the get_actual_icmp_seq() function. - -Example: - >>> conf.use_pcap = False - >>> a = conf.L3socket() - # This will (most likely) work: - >>> current = get_current_icmp_seq() - >>> a.sr(IP(dst="www.google.com", ttl=128)/ICMP(id=1, seq=current)) - # This won't: - >>> a.sr(IP(dst="www.google.com", ttl=128)/ICMP()) - -PS: on computers where the firewall isn't open, Windows temporarily opens it -when using the `ping` util from cmd.exe. One can first call a ping on cmd, -then do custom calls through the socket using get_current_icmp_seq(). See -the tests (windows.uts) for an example. -""" - -import io -import os -import socket -import subprocess -import time - -from scapy.automaton import SelectableObject -from scapy.arch.common import _select_nonblock -from scapy.arch.windows.structures import GetIcmpStatistics -from scapy.compat import raw -from scapy.config import conf -from scapy.data import MTU -from scapy.error import Scapy_Exception, warning -from scapy.supersocket import SuperSocket - -# Watch out for import loops (inet...) - - -class L3WinSocket(SuperSocket, SelectableObject): - desc = "a native Layer 3 (IPv4) raw socket under Windows" - nonblocking_socket = True - __slots__ = ["promisc", "cls", "ipv6", "proto"] - - def __init__(self, iface=None, proto=socket.IPPROTO_IP, - ttl=128, ipv6=False, promisc=True, **kwargs): - from scapy.layers.inet import IP - from scapy.layers.inet6 import IPv6 - for kwarg in kwargs: - warning("Dropping unsupported option: %s" % kwarg) - af = socket.AF_INET6 if ipv6 else socket.AF_INET - self.proto = proto - if ipv6: - from scapy.arch import get_if_addr6 - self.host_ip6 = get_if_addr6(conf.iface) or "::1" - if proto == socket.IPPROTO_IP: - # We'll restrict ourselves to UDP, as TCP isn't bindable - # on AF_INET6 - self.proto = socket.IPPROTO_UDP - # On Windows, with promisc=False, you won't get much - self.ipv6 = ipv6 - self.cls = IPv6 if ipv6 else IP - self.promisc = promisc - # Notes: - # - IPPROTO_RAW only works to send packets. - # - IPPROTO_IPV6 exists in MSDN docs, but using it will result in - # no packets being received. Same for its options (IPV6_HDRINCL...) - # However, using IPPROTO_IP with AF_INET6 will still receive - # the IPv6 packets - try: - self.ins = socket.socket(af, - socket.SOCK_RAW, - self.proto) - self.outs = socket.socket(af, - socket.SOCK_RAW, - socket.IPPROTO_RAW) - except OSError as e: - if e.errno == 10013: - raise OSError("Windows native L3 Raw sockets are only " - "usable as administrator ! " - "Install Winpcap/Npcap to workaround !") - raise - self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30) - self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30) - # IOCTL Include IP headers - self.ins.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) - self.outs.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) - # set TTL - self.ins.setsockopt(socket.IPPROTO_IP, socket.IP_TTL, ttl) - self.outs.setsockopt(socket.IPPROTO_IP, socket.IP_TTL, ttl) - # Bind on all ports - iface = iface or conf.iface - host = iface.ip if iface.ip else socket.gethostname() - self.ins.bind((host, 0)) - self.ins.setblocking(False) - # Get as much data as possible: reduce what is cropped - if ipv6: - try: # Not all Windows versions - self.ins.setsockopt(socket.IPPROTO_IPV6, - socket.IPV6_RECVTCLASS, 1) - self.ins.setsockopt(socket.IPPROTO_IPV6, - socket.IPV6_HOPLIMIT, 1) - except (OSError, socket.error): - pass - else: - try: # Not Windows XP - self.ins.setsockopt(socket.IPPROTO_IP, - socket.IP_RECVDSTADDR, 1) - except (OSError, socket.error): - pass - try: # Windows 10+ recent builds only - self.ins.setsockopt(socket.IPPROTO_IP, socket.IP_RECVTTL, 1) - except (OSError, socket.error): - pass - if promisc: - # IOCTL Receive all packets - self.ins.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) - - def send(self, x): - data = raw(x) - if self.cls not in x: - raise Scapy_Exception("L3WinSocket can only send IP/IPv6 packets !" - " Install Npcap/Winpcap to send more") - dst_ip = str(x[self.cls].dst) - self.outs.sendto(data, (dst_ip, 0)) - - def nonblock_recv(self, x=MTU): - return self.recv() - - # https://docs.microsoft.com/en-us/windows/desktop/winsock/tcp-ip-raw-sockets-2 # noqa: E501 - # - For IPv4 (address family of AF_INET), an application receives the IP - # header at the front of each received datagram regardless of the - # IP_HDRINCL socket option. - # - For IPv6 (address family of AF_INET6), an application receives - # everything after the last IPv6 header in each received datagram - # regardless of the IPV6_HDRINCL socket option. The application does - # not receive any IPv6 headers using a raw socket. - - def recv_raw(self, x=MTU): - try: - data, address = self.ins.recvfrom(x) - except io.BlockingIOError: - return None, None, None - from scapy.layers.inet import IP - from scapy.layers.inet6 import IPv6 - if self.ipv6: - # AF_INET6 does not return the IPv6 header. Let's build it - # (host, port, flowinfo, scopeid) - host, _, flowinfo, _ = address - header = raw(IPv6(src=host, - dst=self.host_ip6, - fl=flowinfo, - nh=self.proto, # fixed for AF_INET6 - plen=len(data))) - return IPv6, header + data, time.time() - else: - return IP, data, time.time() - - def check_recv(self): - return True - - def close(self): - if not self.closed and self.promisc: - self.ins.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) - super(L3WinSocket, self).close() - - @staticmethod - def select(sockets, remain=None): - return _select_nonblock(sockets, remain=remain) - - -class L3WinSocket6(L3WinSocket): - desc = "a native Layer 3 (IPv6) raw socket under Windows" - - def __init__(self, **kwargs): - super(L3WinSocket6, self).__init__(ipv6=True, **kwargs) - - -def open_icmp_firewall(host): - """Temporarily open the ICMP firewall. Tricks Windows into allowing - ICMP packets for a short period of time (~ 1 minute)""" - # We call ping with a timeout of 1ms: will return instantly - with open(os.devnull, 'wb') as DEVNULL: - return subprocess.Popen("ping -4 -w 1 -n 1 %s" % host, - shell=True, - stdout=DEVNULL, - stderr=DEVNULL).wait() - - -def get_current_icmp_seq(): - """See help(scapy.arch.windows.native) for more information. - Returns the current ICMP seq number.""" - return GetIcmpStatistics()['stats']['icmpOutStats']['dwEchos'] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/windows/structures.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/windows/structures.py deleted file mode 100644 index af8cfb1165..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/windows/structures.py +++ /dev/null @@ -1,585 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Copyright (C) Gabriel Potter -# This program is published under a GPLv2 license - -# flake8: noqa E266 -# (We keep comment boxes, it's then one-line comments) - -""" -C API calls to Windows DLLs -""" - -import ctypes -import ctypes.wintypes -from ctypes import Structure, POINTER, byref, create_string_buffer, WINFUNCTYPE - -from scapy.config import conf -from scapy.consts import WINDOWS_XP - -ANY_SIZE = 65500 # FIXME quite inefficient :/ -AF_UNSPEC = 0 -NO_ERROR = 0x0 - -CHAR = ctypes.c_char -DWORD = ctypes.wintypes.DWORD -BOOL = ctypes.wintypes.BOOL -BOOLEAN = ctypes.wintypes.BOOLEAN -ULONG = ctypes.wintypes.ULONG -ULONGLONG = ctypes.c_ulonglong -HANDLE = ctypes.wintypes.HANDLE -LPWSTR = ctypes.wintypes.LPWSTR -VOID = ctypes.c_void_p -INT = ctypes.c_int -UINT = ctypes.wintypes.UINT -UINT8 = ctypes.c_uint8 -UINT16 = ctypes.c_uint16 -UINT32 = ctypes.c_uint32 -UINT64 = ctypes.c_uint64 -BYTE = ctypes.c_byte -UCHAR = UBYTE = ctypes.c_ubyte -SHORT = ctypes.c_short -USHORT = ctypes.c_ushort - - -# UTILS - - -def _resolve_list(list_obj): - current = list_obj - _list = [] - while current and hasattr(current, "contents"): - _list.append(_struct_to_dict(current.contents)) - current = current.contents.next - return _list - - -def _struct_to_dict(struct_obj): - results = {} - for fname, ctype in struct_obj.__class__._fields_: - val = getattr(struct_obj, fname) - if fname == "next": - # Already covered by the trick below - continue - if issubclass(ctype, (Structure, ctypes.Union)): - results[fname] = _struct_to_dict(val) - elif val and hasattr(val, "contents"): - # Let's resolve recursive pointers - if hasattr(val.contents, "next"): - results[fname] = _resolve_list(val) - else: - results[fname] = val - else: - results[fname] = val - return results - -############################## -####### WinAPI handles ####### -############################## - -_winapi_SetConsoleTitle = ctypes.windll.kernel32.SetConsoleTitleW -_winapi_SetConsoleTitle.restype = BOOL -_winapi_SetConsoleTitle.argtypes = [LPWSTR] - -def _windows_title(title=None): - """Updates the terminal title with the default one or with `title` - if provided.""" - if conf.interactive: - _winapi_SetConsoleTitle(title or "Scapy v{}".format(conf.version)) - - -SC_HANDLE = HANDLE - -class SERVICE_STATUS(Structure): - """https://docs.microsoft.com/en-us/windows/desktop/api/winsvc/ns-winsvc-_service_status""" # noqa: E501 - _fields_ = [("dwServiceType", DWORD), - ("dwCurrentState", DWORD), - ("dwControlsAccepted", DWORD), - ("dwWin32ExitCode", DWORD), - ("dwServiceSpecificExitCode", DWORD), - ("dwCheckPoint", DWORD), - ("dwWaitHint", DWORD)] - - -OpenServiceW = ctypes.windll.Advapi32.OpenServiceW -OpenServiceW.restype = SC_HANDLE -OpenServiceW.argtypes = [SC_HANDLE, LPWSTR, DWORD] - -CloseServiceHandle = ctypes.windll.Advapi32.CloseServiceHandle -CloseServiceHandle.restype = BOOL -CloseServiceHandle.argtypes = [SC_HANDLE] - -OpenSCManagerW = ctypes.windll.Advapi32.OpenSCManagerW -OpenSCManagerW.restype = SC_HANDLE -OpenSCManagerW.argtypes = [LPWSTR, LPWSTR, DWORD] - -QueryServiceStatus = ctypes.windll.Advapi32.QueryServiceStatus -QueryServiceStatus.restype = BOOL -QueryServiceStatus.argtypes = [SC_HANDLE, POINTER(SERVICE_STATUS)] - -def get_service_status(service): - """Returns content of QueryServiceStatus for a service""" - SERVICE_QUERY_STATUS = 0x0004 - schSCManager = OpenSCManagerW( - None, # Local machine - None, # SERVICES_ACTIVE_DATABASE - SERVICE_QUERY_STATUS - ) - service = OpenServiceW( - schSCManager, - service, - SERVICE_QUERY_STATUS - ) - status = SERVICE_STATUS() - QueryServiceStatus( - service, - status - ) - result = _struct_to_dict(status) - CloseServiceHandle(service) - CloseServiceHandle(schSCManager) - return result - - -############################## -###### Define IPHLPAPI ###### -############################## - - -iphlpapi = ctypes.windll.iphlpapi - -############################## -########### Common ########### -############################## - - -class in_addr(Structure): - _fields_ = [("byte", UBYTE * 4)] - - -class in6_addr(Structure): - _fields_ = [("byte", UBYTE * 16)] - - -class sockaddr_in(Structure): - _fields_ = [("sin_family", SHORT), - ("sin_port", USHORT), - ("sin_addr", in_addr), - ("sin_zero", 8 * CHAR)] - - -class sockaddr_in6(Structure): - _fields_ = [("sin6_family", SHORT), - ("sin6_port", USHORT), - ("sin6_flowinfo", ULONG), - ("sin6_addr", in6_addr), - ("sin6_scope_id", ULONG)] - - -class SOCKADDR_INET(ctypes.Union): - _fields_ = [("Ipv4", sockaddr_in), - ("Ipv6", sockaddr_in6), - ("si_family", USHORT)] - -############################## -######### ICMP stats ######### -############################## - - -class MIBICMPSTATS(Structure): - _fields_ = [("dwMsgs", DWORD), - ("dwErrors", DWORD), - ("dwDestUnreachs", DWORD), - ("dwTimeExcds", DWORD), - ("dwParmProbs", DWORD), - ("dwSrcQuenchs", DWORD), - ("dwRedirects", DWORD), - ("dwEchos", DWORD), - ("dwEchoReps", DWORD), - ("dwTimestamps", DWORD), - ("dwTimestampReps", DWORD), - ("dwAddrMasks", DWORD), - ("dwAddrMaskReps", DWORD)] - - -class MIBICMPINFO(Structure): - _fields_ = [("icmpInStats", MIBICMPSTATS), - ("icmpOutStats", MIBICMPSTATS)] - - -class MIB_ICMP(Structure): - _fields_ = [("stats", MIBICMPINFO)] - - -PMIB_ICMP = POINTER(MIB_ICMP) - -# Func - -_GetIcmpStatistics = WINFUNCTYPE(ULONG, PMIB_ICMP)( - ('GetIcmpStatistics', iphlpapi)) - - -def GetIcmpStatistics(): - """Return all Windows ICMP stats from iphlpapi""" - statistics = MIB_ICMP() - _GetIcmpStatistics(byref(statistics)) - results = _struct_to_dict(statistics) - del(statistics) - return results - -############################## -##### Adapters Addresses ##### -############################## - - -# Our GetAdaptersAddresses implementation is inspired by -# @sphaero 's gist: https://gist.github.com/sphaero/f9da6ebb9a7a6f679157 -# published under a MPL 2.0 License (GPLv2 compatible) - -# from iptypes.h -MAX_ADAPTER_ADDRESS_LENGTH = 8 -MAX_DHCPV6_DUID_LENGTH = 130 - -GAA_FLAG_INCLUDE_PREFIX = ULONG(0x0010) -# for now, just use void * for pointers to unused structures -PIP_ADAPTER_WINS_SERVER_ADDRESS_LH = VOID -PIP_ADAPTER_GATEWAY_ADDRESS_LH = VOID -PIP_ADAPTER_DNS_SUFFIX = VOID - -IF_OPER_STATUS = UINT -IF_LUID = UINT64 - -NET_IF_COMPARTMENT_ID = UINT32 -GUID = BYTE * 16 -NET_IF_NETWORK_GUID = GUID -NET_IF_CONNECTION_TYPE = UINT # enum -TUNNEL_TYPE = UINT # enum - - -class SOCKET_ADDRESS(ctypes.Structure): - _fields_ = [('address', POINTER(SOCKADDR_INET)), - ('length', INT)] - - -class _IP_ADAPTER_ADDRESSES_METRIC(Structure): - _fields_ = [('length', ULONG), - ('interface_index', DWORD)] - - -class IP_ADAPTER_UNICAST_ADDRESS(Structure): - pass - - -PIP_ADAPTER_UNICAST_ADDRESS = POINTER(IP_ADAPTER_UNICAST_ADDRESS) -if WINDOWS_XP: - IP_ADAPTER_UNICAST_ADDRESS._fields_ = [ - ("length", ULONG), - ("flags", DWORD), - ("next", PIP_ADAPTER_UNICAST_ADDRESS), - ("address", SOCKET_ADDRESS), - ("prefix_origin", INT), - ("suffix_origin", INT), - ("dad_state", INT), - ("valid_lifetime", ULONG), - ("preferred_lifetime", ULONG), - ("lease_lifetime", ULONG), - ] -else: - IP_ADAPTER_UNICAST_ADDRESS._fields_ = [ - ("length", ULONG), - ("flags", DWORD), - ("next", PIP_ADAPTER_UNICAST_ADDRESS), - ("address", SOCKET_ADDRESS), - ("prefix_origin", INT), - ("suffix_origin", INT), - ("dad_state", INT), - ("valid_lifetime", ULONG), - ("preferred_lifetime", ULONG), - ("lease_lifetime", ULONG), - ("on_link_prefix_length", UBYTE) - ] - - -class IP_ADAPTER_ANYCAST_ADDRESS(Structure): - pass - - -PIP_ADAPTER_ANYCAST_ADDRESS = POINTER(IP_ADAPTER_ANYCAST_ADDRESS) -IP_ADAPTER_ANYCAST_ADDRESS._fields_ = [ - ("length", ULONG), - ("flags", DWORD), - ("next", PIP_ADAPTER_ANYCAST_ADDRESS), - ("address", SOCKET_ADDRESS), -] - - -class IP_ADAPTER_MULTICAST_ADDRESS(Structure): - pass - - -PIP_ADAPTER_MULTICAST_ADDRESS = POINTER(IP_ADAPTER_MULTICAST_ADDRESS) -IP_ADAPTER_MULTICAST_ADDRESS._fields_ = [ - ("length", ULONG), - ("flags", DWORD), - ("next", PIP_ADAPTER_MULTICAST_ADDRESS), - ("address", SOCKET_ADDRESS), -] - - -class IP_ADAPTER_DNS_SERVER_ADDRESS(Structure): - pass - - -PIP_ADAPTER_DNS_SERVER_ADDRESS = POINTER(IP_ADAPTER_DNS_SERVER_ADDRESS) -IP_ADAPTER_DNS_SERVER_ADDRESS._fields_ = [ - ("length", ULONG), - ("flags", DWORD), - ("next", PIP_ADAPTER_DNS_SERVER_ADDRESS), - ("address", SOCKET_ADDRESS), -] - - -class IP_ADAPTER_PREFIX(Structure): - pass - - -PIP_ADAPTER_PREFIX = ctypes.POINTER(IP_ADAPTER_PREFIX) -IP_ADAPTER_PREFIX._fields_ = [ - ("alignment", ULONGLONG), - ("next", PIP_ADAPTER_PREFIX), - ("address", SOCKET_ADDRESS), - ("prefix_length", ULONG) -] - - -class IP_ADAPTER_ADDRESSES(Structure): - pass - - -LP_IP_ADAPTER_ADDRESSES = POINTER(IP_ADAPTER_ADDRESSES) - -if WINDOWS_XP: - IP_ADAPTER_ADDRESSES._fields_ = [ - ('length', ULONG), - ('interface_index', DWORD), - ('next', LP_IP_ADAPTER_ADDRESSES), - ('adapter_name', ctypes.c_char_p), - ('first_unicast_address', PIP_ADAPTER_UNICAST_ADDRESS), - ('first_anycast_address', PIP_ADAPTER_ANYCAST_ADDRESS), - ('first_multicast_address', PIP_ADAPTER_MULTICAST_ADDRESS), - ('first_dns_server_address', PIP_ADAPTER_DNS_SERVER_ADDRESS), - ('dns_suffix', ctypes.c_wchar_p), - ('description', ctypes.c_wchar_p), - ('friendly_name', ctypes.c_wchar_p), - ('physical_address', BYTE * MAX_ADAPTER_ADDRESS_LENGTH), - ('physical_address_length', ULONG), - ('flags', ULONG), - ('mtu', ULONG), - ('interface_type', DWORD), - ('oper_status', IF_OPER_STATUS), - ('ipv6_interface_index', DWORD), - ('zone_indices', ULONG * 16), - ('first_prefix', PIP_ADAPTER_PREFIX), - ] -else: - IP_ADAPTER_ADDRESSES._fields_ = [ - ('length', ULONG), - ('interface_index', DWORD), - ('next', LP_IP_ADAPTER_ADDRESSES), - ('adapter_name', ctypes.c_char_p), - ('first_unicast_address', PIP_ADAPTER_UNICAST_ADDRESS), - ('first_anycast_address', PIP_ADAPTER_ANYCAST_ADDRESS), - ('first_multicast_address', PIP_ADAPTER_MULTICAST_ADDRESS), - ('first_dns_server_address', PIP_ADAPTER_DNS_SERVER_ADDRESS), - ('dns_suffix', ctypes.c_wchar_p), - ('description', ctypes.c_wchar_p), - ('friendly_name', ctypes.c_wchar_p), - ('physical_address', BYTE * MAX_ADAPTER_ADDRESS_LENGTH), - ('physical_address_length', ULONG), - ('flags', ULONG), - ('mtu', ULONG), - ('interface_type', DWORD), - ('oper_status', IF_OPER_STATUS), - ('ipv6_interface_index', DWORD), - ('zone_indices', ULONG * 16), - ('first_prefix', PIP_ADAPTER_PREFIX), - ('transmit_link_speed', ULONGLONG), - ('receive_link_speed', ULONGLONG), - ('first_wins_server_address', PIP_ADAPTER_WINS_SERVER_ADDRESS_LH), - ('first_gateway_address', PIP_ADAPTER_GATEWAY_ADDRESS_LH), - ('ipv4_metric', ULONG), - ('ipv6_metric', ULONG), - ('luid', IF_LUID), - ('dhcpv4_server', SOCKET_ADDRESS), - ('compartment_id', NET_IF_COMPARTMENT_ID), - ('network_guid', NET_IF_NETWORK_GUID), - ('connection_type', NET_IF_CONNECTION_TYPE), - ('tunnel_type', TUNNEL_TYPE), - ('dhcpv6_server', SOCKET_ADDRESS), - ('dhcpv6_client_duid', BYTE * MAX_DHCPV6_DUID_LENGTH), - ('dhcpv6_client_duid_length', ULONG), - ('dhcpv6_iaid', ULONG), - ('first_dns_suffix', PIP_ADAPTER_DNS_SUFFIX)] - -# Func - -_GetAdaptersAddresses = WINFUNCTYPE(ULONG, ULONG, ULONG, - POINTER(VOID), - LP_IP_ADAPTER_ADDRESSES, - POINTER(ULONG))( - ('GetAdaptersAddresses', iphlpapi)) - - -def GetAdaptersAddresses(AF=AF_UNSPEC): - """Return all Windows Adapters addresses from iphlpapi""" - # We get the size first - size = ULONG() - flags = GAA_FLAG_INCLUDE_PREFIX - res = _GetAdaptersAddresses(AF, flags, - None, None, - byref(size)) - if res != 0x6f: # BUFFER OVERFLOW -> populate size - raise RuntimeError("Error getting structure length (%d)" % res) - # Now let's build our buffer - pointer_type = POINTER(IP_ADAPTER_ADDRESSES) - buffer = create_string_buffer(size.value) - AdapterAddresses = ctypes.cast(buffer, pointer_type) - # And call GetAdaptersAddresses - res = _GetAdaptersAddresses(AF, flags, - None, AdapterAddresses, - byref(size)) - if res != NO_ERROR: - raise RuntimeError("Error retrieving table (%d)" % res) - results = _resolve_list(AdapterAddresses) - del(AdapterAddresses) - return results - -############################## -####### Routing tables ####### -############################## - -### V1 ### - - -class MIB_IPFORWARDROW(Structure): - _fields_ = [('ForwardDest', DWORD), - ('ForwardMask', DWORD), - ('ForwardPolicy', DWORD), - ('ForwardNextHop', DWORD), - ('ForwardIfIndex', DWORD), - ('ForwardType', DWORD), - ('ForwardProto', DWORD), - ('ForwardAge', DWORD), - ('ForwardNextHopAS', DWORD), - ('ForwardMetric1', DWORD), - ('ForwardMetric2', DWORD), - ('ForwardMetric3', DWORD), - ('ForwardMetric4', DWORD), - ('ForwardMetric5', DWORD)] - - -class MIB_IPFORWARDTABLE(Structure): - _fields_ = [('NumEntries', DWORD), - ('Table', MIB_IPFORWARDROW * ANY_SIZE)] - - -PMIB_IPFORWARDTABLE = POINTER(MIB_IPFORWARDTABLE) - -# Func - -_GetIpForwardTable = WINFUNCTYPE(DWORD, - PMIB_IPFORWARDTABLE, POINTER(ULONG), BOOL)( - ('GetIpForwardTable', iphlpapi)) - - -def GetIpForwardTable(): - """Return all Windows routes (IPv4 only) from iphlpapi""" - # We get the size first - size = ULONG() - res = _GetIpForwardTable(None, byref(size), False) - if res != 0x7a: # ERROR_INSUFFICIENT_BUFFER -> populate size - raise RuntimeError("Error getting structure length (%d)" % res) - # Now let's build our buffer - pointer_type = PMIB_IPFORWARDTABLE - buffer = create_string_buffer(size.value) - pIpForwardTable = ctypes.cast(buffer, pointer_type) - # And call GetAdaptersAddresses - res = _GetIpForwardTable(pIpForwardTable, byref(size), True) - if res != NO_ERROR: - raise RuntimeError("Error retrieving table (%d)" % res) - results = [] - for i in range(pIpForwardTable.contents.NumEntries): - results.append(_struct_to_dict(pIpForwardTable.contents.Table[i])) - del(pIpForwardTable) - return results - -### V2 ### - - -NET_IFINDEX = ULONG -NL_ROUTE_PROTOCOL = INT -NL_ROUTE_ORIGIN = INT - - -class NET_LUID(Structure): - _fields_ = [("Value", ULONGLONG)] - - -class IP_ADDRESS_PREFIX(Structure): - _fields_ = [("Prefix", SOCKADDR_INET), - ("PrefixLength", UINT8)] - - -class MIB_IPFORWARD_ROW2(Structure): - _fields_ = [("InterfaceLuid", NET_LUID), - ("InterfaceIndex", NET_IFINDEX), - ("DestinationPrefix", IP_ADDRESS_PREFIX), - ("NextHop", SOCKADDR_INET), - ("SitePrefixLength", UCHAR), - ("ValidLifetime", ULONG), - ("PreferredLifetime", ULONG), - ("Metric", ULONG), - ("Protocol", NL_ROUTE_PROTOCOL), - ("Loopback", BOOLEAN), - ("AutoconfigureAddress", BOOLEAN), - ("Publish", BOOLEAN), - ("Immortal", BOOLEAN), - ("Age", ULONG), - ("Origin", NL_ROUTE_ORIGIN)] - - -class MIB_IPFORWARD_TABLE2(Structure): - _fields_ = [("NumEntries", ULONG), - ("Table", MIB_IPFORWARD_ROW2 * ANY_SIZE)] - - -PMIB_IPFORWARD_TABLE2 = POINTER(MIB_IPFORWARD_TABLE2) - -# Func - -if not WINDOWS_XP: - # GetIpForwardTable2 does not exist under Windows XP - _GetIpForwardTable2 = WINFUNCTYPE( - ULONG, USHORT, - POINTER(PMIB_IPFORWARD_TABLE2))( - ('GetIpForwardTable2', iphlpapi) - ) - _FreeMibTable = WINFUNCTYPE(None, PMIB_IPFORWARD_TABLE2)( - ('FreeMibTable', iphlpapi) - ) - - -def GetIpForwardTable2(AF=AF_UNSPEC): - """Return all Windows routes (IPv4/IPv6) from iphlpapi""" - if WINDOWS_XP: - raise OSError("Not available on Windows XP !") - table = PMIB_IPFORWARD_TABLE2() - res = _GetIpForwardTable2(AF, byref(table)) - if res != NO_ERROR: - raise RuntimeError("Error retrieving table (%d)" % res) - results = [] - for i in range(table.contents.NumEntries): - results.append(_struct_to_dict(table.contents.Table[i])) - _FreeMibTable(table) - return results diff --git a/scripts/external_libs/scapy-2.4.3/scapy/arch/winpcapy.py b/scripts/external_libs/scapy-2.4.3/scapy/arch/winpcapy.py deleted file mode 100644 index fc452a02ce..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/arch/winpcapy.py +++ /dev/null @@ -1,739 +0,0 @@ -#------------------------------------------------------------------------------- -# Name: winpcapy.py -# -# Author: Massimo Ciani -# -# Created: 01/09/2009 -# Copyright: (c) Massimo Ciani 2009 -# -#------------------------------------------------------------------------------- - - -from ctypes import * -from ctypes.util import find_library -import sys - -WIN32=False -HAVE_REMOTE=False - - -if sys.platform.startswith('win'): - WIN32=True - HAVE_REMOTE=True - -if WIN32: - SOCKET = c_uint - _lib=CDLL('wpcap.dll') -else: - SOCKET = c_int - _lib_name = find_library('pcap') - if not _lib_name: - raise OSError("Cannot fine libpcap.so library") - _lib=CDLL(_lib_name) - - - -## -## misc -## -u_short = c_ushort -bpf_int32 = c_int -u_int = c_int -bpf_u_int32 = u_int -pcap = c_void_p -pcap_dumper = c_void_p -u_char = c_ubyte -FILE = c_void_p -STRING = c_char_p - -class bpf_insn(Structure): - _fields_=[("code",c_ushort), - ("jt",c_ubyte), - ("jf",c_ubyte), - ("k",bpf_u_int32)] - -class bpf_program(Structure): - pass -bpf_program._fields_ = [('bf_len', u_int), - ('bf_insns', POINTER(bpf_insn))] - -class bpf_version(Structure): - _fields_=[("bv_major",c_ushort), - ("bv_minor",c_ushort)] - - -class timeval(Structure): - pass -timeval._fields_ = [('tv_sec', c_long), - ('tv_usec', c_long)] - -## sockaddr is used by pcap_addr. -## For exapmle if sa_family==socket.AF_INET then we need cast -## with sockaddr_in -if WIN32: - class sockaddr(Structure): - _fields_ = [("sa_family", c_ushort), - ("sa_data",c_ubyte * 14)] - - class sockaddr_in(Structure): - _fields_ = [("sin_family", c_ushort), - ("sin_port", c_uint16), - ("sin_addr", 4 * c_ubyte)] - - class sockaddr_in6(Structure): - _fields_ = [("sin6_family", c_ushort), - ("sin6_port", c_uint16), - ("sin6_flowinfo", c_uint32), - ("sin6_addr", 16 * c_ubyte), - ("sin6_scope", c_uint32)] -else: - class sockaddr(Structure): - _fields_ = [("sa_len", c_ubyte), - ("sa_family",c_ubyte), - ("sa_data",c_ubyte * 14)] - - class sockaddr_in(Structure): - _fields_ = [("sin_len", c_ubyte), - ("sin_family", c_ubyte), - ("sin_port", c_uint16), - ("sin_addr", 4 * c_ubyte), - ("sin_zero", 8 * c_char)] - - class sockaddr_in6(Structure): - _fields_ = [("sin6_len", c_ubyte), - ("sin6_family", c_ubyte), - ("sin6_port", c_uint16), - ("sin6_flowinfo", c_uint32), - ("sin6_addr", 16 * c_ubyte), - ("sin6_scope", c_uint32)] - - class sockaddr_dl(Structure): - _fields_ = [("sdl_len", c_ubyte), - ("sdl_family", c_ubyte), - ("sdl_index", c_ushort), - ("sdl_type", c_ubyte), - ("sdl_nlen", c_ubyte), - ("sdl_alen", c_ubyte), - ("sdl_slen", c_ubyte), - ("sdl_data", 46 * c_ubyte)] -## -## END misc -## - -## -## Data Structures -## - -## struct pcap_file_header -## Header of a libpcap dump file. -class pcap_file_header(Structure): - _fields_ = [('magic', bpf_u_int32), - ('version_major', u_short), - ('version_minor', u_short), - ('thiszone', bpf_int32), - ('sigfigs', bpf_u_int32), - ('snaplen', bpf_u_int32), - ('linktype', bpf_u_int32)] - -## struct pcap_pkthdr -## Header of a packet in the dump file. -class pcap_pkthdr(Structure): - _fields_ = [('ts', timeval), - ('caplen', bpf_u_int32), - ('len', bpf_u_int32)] - -## struct pcap_stat -## Structure that keeps statistical values on an interface. -class pcap_stat(Structure): - pass -### _fields_ list in Structure is final. -### We need a temp list -_tmpList=[] -_tmpList.append(("ps_recv",c_uint)) -_tmpList.append(("ps_drop",c_uint)) -_tmpList.append(("ps_ifdrop",c_uint)) -if HAVE_REMOTE: - _tmpList.append(("ps_capt",c_uint)) - _tmpList.append(("ps_sent",c_uint)) - _tmpList.append(("ps_netdrop",c_uint)) -pcap_stat._fields_=_tmpList - -## struct pcap_addr -## Representation of an interface address, used by pcap_findalldevs(). -class pcap_addr(Structure): - pass -pcap_addr._fields_ = [('next', POINTER(pcap_addr)), - ('addr', POINTER(sockaddr)), - ('netmask', POINTER(sockaddr)), - ('broadaddr', POINTER(sockaddr)), - ('dstaddr', POINTER(sockaddr))] - -## struct pcap_if -## Item in a list of interfaces, used by pcap_findalldevs(). -class pcap_if(Structure): - pass -pcap_if._fields_ = [('next', POINTER(pcap_if)), - ('name', STRING), - ('description', STRING), - ('addresses', POINTER(pcap_addr)), - ('flags', bpf_u_int32)] - -## -## END Data Structures -## - -## -## Defines -## - -##define PCAP_VERSION_MAJOR 2 -# Major libpcap dump file version. -PCAP_VERSION_MAJOR = 2 -##define PCAP_VERSION_MINOR 4 -# Minor libpcap dump file version. -PCAP_VERSION_MINOR = 4 -##define PCAP_ERRBUF_SIZE 256 -# Size to use when allocating the buffer that contains the libpcap errors. -PCAP_ERRBUF_SIZE = 256 -##define PCAP_IF_LOOPBACK 0x00000001 -# interface is loopback -PCAP_IF_LOOPBACK = 1 -##define MODE_CAPT 0 -# Capture mode, to be used when calling pcap_setmode(). -MODE_CAPT = 0 -##define MODE_STAT 1 -# Statistical mode, to be used when calling pcap_setmode(). -MODE_STAT = 1 - -## -## END Defines -## - -## -## Typedefs -## - -#typedef int bpf_int32 (already defined) -# 32-bit integer -#typedef u_int bpf_u_int32 (already defined) -# 32-bit unsigned integer -#typedef struct pcap pcap_t -# Descriptor of an open capture instance. This structure is opaque to the user, that handles its content through the functions provided by wpcap.dll. -pcap_t = pcap -#typedef struct pcap_dumper pcap_dumper_t -# libpcap savefile descriptor. -pcap_dumper_t = pcap_dumper -#typedef struct pcap_if pcap_if_t -# Item in a list of interfaces, see pcap_if. -pcap_if_t = pcap_if -#typedef struct pcap_addr pcap_addr_t -# Representation of an interface address, see pcap_addr. -pcap_addr_t = pcap_addr - -## -## END Typedefs -## - - - - - -# values for enumeration 'pcap_direction_t' -#pcap_direction_t = c_int # enum - -## -## Unix-compatible Functions -## These functions are part of the libpcap library, and therefore work both on Windows and on Linux. -## - -#typedef void(* pcap_handler )(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) -# Prototype of the callback function that receives the packets. -## This one is defined from programmer -pcap_handler=CFUNCTYPE(None,POINTER(c_ubyte),POINTER(pcap_pkthdr),POINTER(c_ubyte)) - -#pcap_t * pcap_open_live (const char *device, int snaplen, int promisc, int to_ms, char *ebuf) -# Open a live capture from the network. -pcap_open_live = _lib.pcap_open_live -pcap_open_live.restype = POINTER(pcap_t) -pcap_open_live.argtypes = [STRING, c_int, c_int, c_int, STRING] - -#pcap_t * pcap_open_dead (int linktype, int snaplen) -# Create a pcap_t structure without starting a capture. -pcap_open_dead = _lib.pcap_open_dead -pcap_open_dead.restype = POINTER(pcap_t) -pcap_open_dead.argtypes = [c_int, c_int] - -#pcap_t * pcap_open_offline (const char *fname, char *errbuf) -# Open a savefile in the tcpdump/libpcap format to read packets. -pcap_open_offline = _lib.pcap_open_offline -pcap_open_offline.restype = POINTER(pcap_t) -pcap_open_offline.argtypes = [STRING, STRING] - -#pcap_dumper_t * pcap_dump_open (pcap_t *p, const char *fname) -# Open a file to write packets. -pcap_dump_open = _lib.pcap_dump_open -pcap_dump_open.restype = POINTER(pcap_dumper_t) -pcap_dump_open.argtypes = [POINTER(pcap_t), STRING] - -#int pcap_setnonblock (pcap_t *p, int nonblock, char *errbuf) -# Switch between blocking and nonblocking mode. -pcap_setnonblock = _lib.pcap_setnonblock -pcap_setnonblock.restype = c_int -pcap_setnonblock.argtypes = [POINTER(pcap_t), c_int, STRING] - -#int pcap_getnonblock (pcap_t *p, char *errbuf) -# Get the "non-blocking" state of an interface. -pcap_getnonblock = _lib.pcap_getnonblock -pcap_getnonblock.restype = c_int -pcap_getnonblock.argtypes = [POINTER(pcap_t), STRING] - -#int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf) -# Construct a list of network devices that can be opened with pcap_open_live(). -pcap_findalldevs = _lib.pcap_findalldevs -pcap_findalldevs.restype = c_int -pcap_findalldevs.argtypes = [POINTER(POINTER(pcap_if_t)), STRING] - -#void pcap_freealldevs (pcap_if_t *alldevsp) -# Free an interface list returned by pcap_findalldevs(). -pcap_freealldevs = _lib.pcap_freealldevs -pcap_freealldevs.restype = None -pcap_freealldevs.argtypes = [POINTER(pcap_if_t)] - -#char * pcap_lookupdev (char *errbuf) -# Return the first valid device in the system. -pcap_lookupdev = _lib.pcap_lookupdev -pcap_lookupdev.restype = STRING -pcap_lookupdev.argtypes = [STRING] - -#int pcap_lookupnet (const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp, char *errbuf) -# Return the subnet and netmask of an interface. -pcap_lookupnet = _lib.pcap_lookupnet -pcap_lookupnet.restype = c_int -pcap_lookupnet.argtypes = [STRING, POINTER(bpf_u_int32), POINTER(bpf_u_int32), STRING] - -#int pcap_dispatch (pcap_t *p, int cnt, pcap_handler callback, u_char *user) -# Collect a group of packets. -pcap_dispatch = _lib.pcap_dispatch -pcap_dispatch.restype = c_int -pcap_dispatch.argtypes = [POINTER(pcap_t), c_int, pcap_handler, POINTER(u_char)] - -#int pcap_loop (pcap_t *p, int cnt, pcap_handler callback, u_char *user) -# Collect a group of packets. -pcap_loop = _lib.pcap_loop -pcap_loop.restype = c_int -pcap_loop.argtypes = [POINTER(pcap_t), c_int, pcap_handler, POINTER(u_char)] - -#u_char * pcap_next (pcap_t *p, struct pcap_pkthdr *h) -# Return the next available packet. -pcap_next = _lib.pcap_next -pcap_next.restype = POINTER(u_char) -pcap_next.argtypes = [POINTER(pcap_t), POINTER(pcap_pkthdr)] - -#int pcap_next_ex (pcap_t *p, struct pcap_pkthdr **pkt_header, const u_char **pkt_data) -# Read a packet from an interface or from an offline capture. -pcap_next_ex = _lib.pcap_next_ex -pcap_next_ex.restype = c_int -pcap_next_ex.argtypes = [POINTER(pcap_t), POINTER(POINTER(pcap_pkthdr)), POINTER(POINTER(u_char))] - -#void pcap_breakloop (pcap_t *) -# set a flag that will force pcap_dispatch() or pcap_loop() to return rather than looping. -pcap_breakloop = _lib.pcap_breakloop -pcap_breakloop.restype = None -pcap_breakloop.argtypes = [POINTER(pcap_t)] - -#int pcap_sendpacket (pcap_t *p, u_char *buf, int size) -# Send a raw packet. -pcap_sendpacket = _lib.pcap_sendpacket -pcap_sendpacket.restype = c_int -#pcap_sendpacket.argtypes = [POINTER(pcap_t), POINTER(u_char), c_int] -pcap_sendpacket.argtypes = [POINTER(pcap_t), c_void_p, c_int] - -#void pcap_dump (u_char *user, const struct pcap_pkthdr *h, const u_char *sp) -# Save a packet to disk. -pcap_dump = _lib.pcap_dump -pcap_dump.restype = None -pcap_dump.argtypes = [POINTER(pcap_dumper_t), POINTER(pcap_pkthdr), POINTER(u_char)] - -#long pcap_dump_ftell (pcap_dumper_t *) -# Return the file position for a "savefile". -pcap_dump_ftell = _lib.pcap_dump_ftell -pcap_dump_ftell.restype = c_long -pcap_dump_ftell.argtypes = [POINTER(pcap_dumper_t)] - -#int pcap_compile (pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask) -# Compile a packet filter, converting an high level filtering expression (see Filtering expression syntax) in a program that can be interpreted by the kernel-level filtering engine. -pcap_compile = _lib.pcap_compile -pcap_compile.restype = c_int -pcap_compile.argtypes = [POINTER(pcap_t), POINTER(bpf_program), STRING, c_int, bpf_u_int32] - -#int pcap_compile_nopcap (int snaplen_arg, int linktype_arg, struct bpf_program *program, char *buf, int optimize, bpf_u_int32 mask) -# Compile a packet filter without the need of opening an adapter. This function converts an high level filtering expression (see Filtering expression syntax) in a program that can be interpreted by the kernel-level filtering engine. -pcap_compile_nopcap = _lib.pcap_compile_nopcap -pcap_compile_nopcap.restype = c_int -pcap_compile_nopcap.argtypes = [c_int, c_int, POINTER(bpf_program), STRING, c_int, bpf_u_int32] - -#int pcap_setfilter (pcap_t *p, struct bpf_program *fp) -# Associate a filter to a capture. -pcap_setfilter = _lib.pcap_setfilter -pcap_setfilter.restype = c_int -pcap_setfilter.argtypes = [POINTER(pcap_t), POINTER(bpf_program)] - -#void pcap_freecode (struct bpf_program *fp) -# Free a filter. -pcap_freecode = _lib.pcap_freecode -pcap_freecode.restype = None -pcap_freecode.argtypes = [POINTER(bpf_program)] - -#int pcap_datalink (pcap_t *p) -# Return the link layer of an adapter. -pcap_datalink = _lib.pcap_datalink -pcap_datalink.restype = c_int -pcap_datalink.argtypes = [POINTER(pcap_t)] - -#int pcap_list_datalinks (pcap_t *p, int **dlt_buf) -# list datalinks -pcap_list_datalinks = _lib.pcap_list_datalinks -pcap_list_datalinks.restype = c_int -#pcap_list_datalinks.argtypes = [POINTER(pcap_t), POINTER(POINTER(c_int))] - -#int pcap_set_datalink (pcap_t *p, int dlt) -# Set the current data link type of the pcap descriptor to the type specified by dlt. -1 is returned on failure. -pcap_set_datalink = _lib.pcap_set_datalink -pcap_set_datalink.restype = c_int -pcap_set_datalink.argtypes = [POINTER(pcap_t), c_int] - -#int pcap_datalink_name_to_val (const char *name) -# Translates a data link type name, which is a DLT_ name with the DLT_ removed, to the corresponding data link type value. The translation is case-insensitive. -1 is returned on failure. -pcap_datalink_name_to_val = _lib.pcap_datalink_name_to_val -pcap_datalink_name_to_val.restype = c_int -pcap_datalink_name_to_val.argtypes = [STRING] - -#const char * pcap_datalink_val_to_name (int dlt) -# Translates a data link type value to the corresponding data link type name. NULL is returned on failure. -pcap_datalink_val_to_name = _lib.pcap_datalink_val_to_name -pcap_datalink_val_to_name.restype = STRING -pcap_datalink_val_to_name.argtypes = [c_int] - -#const char * pcap_datalink_val_to_description (int dlt) -# Translates a data link type value to a short description of that data link type. NULL is returned on failure. -pcap_datalink_val_to_description = _lib.pcap_datalink_val_to_description -pcap_datalink_val_to_description.restype = STRING -pcap_datalink_val_to_description.argtypes = [c_int] - -#int pcap_snapshot (pcap_t *p) -# Return the dimension of the packet portion (in bytes) that is delivered to the application. -pcap_snapshot = _lib.pcap_snapshot -pcap_snapshot.restype = c_int -pcap_snapshot.argtypes = [POINTER(pcap_t)] - -#int pcap_is_swapped (pcap_t *p) -# returns true if the current savefile uses a different byte order than the current system. -pcap_is_swapped = _lib.pcap_is_swapped -pcap_is_swapped.restype = c_int -pcap_is_swapped.argtypes = [POINTER(pcap_t)] - -#int pcap_major_version (pcap_t *p) -# return the major version number of the pcap library used to write the savefile. -pcap_major_version = _lib.pcap_major_version -pcap_major_version.restype = c_int -pcap_major_version.argtypes = [POINTER(pcap_t)] - -#int pcap_minor_version (pcap_t *p) -# return the minor version number of the pcap library used to write the savefile. -pcap_minor_version = _lib.pcap_minor_version -pcap_minor_version.restype = c_int -pcap_minor_version.argtypes = [POINTER(pcap_t)] - -#FILE * pcap_file (pcap_t *p) -# Return the standard stream of an offline capture. -pcap_file=_lib.pcap_file -pcap_file.restype = FILE -pcap_file.argtypes = [POINTER(pcap_t)] - -#int pcap_stats (pcap_t *p, struct pcap_stat *ps) -# Return statistics on current capture. -pcap_stats = _lib.pcap_stats -pcap_stats.restype = c_int -pcap_stats.argtypes = [POINTER(pcap_t), POINTER(pcap_stat)] - -#void pcap_perror (pcap_t *p, char *prefix) -# print the text of the last pcap library error on stderr, prefixed by prefix. -pcap_perror = _lib.pcap_perror -pcap_perror.restype = None -pcap_perror.argtypes = [POINTER(pcap_t), STRING] - -#char * pcap_geterr (pcap_t *p) -# return the error text pertaining to the last pcap library error. -pcap_geterr = _lib.pcap_geterr -pcap_geterr.restype = STRING -pcap_geterr.argtypes = [POINTER(pcap_t)] - -#char * pcap_strerror (int error) -# Provided in case strerror() isn't available. -pcap_strerror = _lib.pcap_strerror -pcap_strerror.restype = STRING -pcap_strerror.argtypes = [c_int] - -#const char * pcap_lib_version (void) -# Returns a pointer to a string giving information about the version of the libpcap library being used; note that it contains more information than just a version number. -pcap_lib_version = _lib.pcap_lib_version -pcap_lib_version.restype = STRING -pcap_lib_version.argtypes = [] - -#void pcap_close (pcap_t *p) -# close the files associated with p and deallocates resources. -pcap_close = _lib.pcap_close -pcap_close.restype = None -pcap_close.argtypes = [POINTER(pcap_t)] - -#FILE * pcap_dump_file (pcap_dumper_t *p) -# return the standard I/O stream of the 'savefile' opened by pcap_dump_open(). -pcap_dump_file=_lib.pcap_dump_file -pcap_dump_file.restype=FILE -pcap_dump_file.argtypes= [POINTER(pcap_dumper_t)] - -#int pcap_dump_flush (pcap_dumper_t *p) -# Flushes the output buffer to the ``savefile,'' so that any packets written with pcap_dump() but not yet written to the ``savefile'' will be written. -1 is returned on error, 0 on success. -pcap_dump_flush = _lib.pcap_dump_flush -pcap_dump_flush.restype = c_int -pcap_dump_flush.argtypes = [POINTER(pcap_dumper_t)] - -#void pcap_dump_close (pcap_dumper_t *p) -# Closes a savefile. -pcap_dump_close = _lib.pcap_dump_close -pcap_dump_close.restype = None -pcap_dump_close.argtypes = [POINTER(pcap_dumper_t)] - -if not WIN32: - - pcap_get_selectable_fd = _lib.pcap_get_selectable_fd - pcap_get_selectable_fd.restype = c_int - pcap_get_selectable_fd.argtypes = [POINTER(pcap_t)] - -########################################### -## Windows-specific Extensions -## The functions in this section extend libpcap to offer advanced functionalities -## (like remote packet capture, packet buffer size variation or high-precision packet injection). -## Howerver, at the moment they can be used only in Windows. -########################################### -if WIN32: - HANDLE = c_void_p - - ############## - ## Identifiers related to the new source syntax - ############## - #define PCAP_SRC_FILE 2 - #define PCAP_SRC_IFLOCAL 3 - #define PCAP_SRC_IFREMOTE 4 - #Internal representation of the type of source in use (file, remote/local interface). - PCAP_SRC_FILE = 2 - PCAP_SRC_IFLOCAL = 3 - PCAP_SRC_IFREMOTE = 4 - - ############## - ## Strings related to the new source syntax - ############## - #define PCAP_SRC_FILE_STRING "file://" - #define PCAP_SRC_IF_STRING "rpcap://" - #String that will be used to determine the type of source in use (file, remote/local interface). - PCAP_SRC_FILE_STRING="file://" - PCAP_SRC_IF_STRING="rpcap://" - - ############## - ## Flags defined in the pcap_open() function - ############## - # define PCAP_OPENFLAG_PROMISCUOUS 1 - # Defines if the adapter has to go in promiscuous mode. - PCAP_OPENFLAG_PROMISCUOUS=1 - # define PCAP_OPENFLAG_DATATX_UDP 2 - # Defines if the data trasfer (in case of a remote capture) has to be done with UDP protocol. - PCAP_OPENFLAG_DATATX_UDP=2 - # define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4 - PCAP_OPENFLAG_NOCAPTURE_RPCAP=4 - # Defines if the remote probe will capture its own generated traffic. - # define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8 - PCAP_OPENFLAG_NOCAPTURE_LOCAL = 8 - # define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16 - # This flag configures the adapter for maximum responsiveness. - PCAP_OPENFLAG_MAX_RESPONSIVENESS=16 - - ############## - ## Sampling methods defined in the pcap_setsampling() function - ############## - # define PCAP_SAMP_NOSAMP 0 - # No sampling has to be done on the current capture. - PCAP_SAMP_NOSAMP=0 - # define PCAP_SAMP_1_EVERY_N 1 - # It defines that only 1 out of N packets must be returned to the user. - PCAP_SAMP_1_EVERY_N=1 - #define PCAP_SAMP_FIRST_AFTER_N_MS 2 - # It defines that we have to return 1 packet every N milliseconds. - PCAP_SAMP_FIRST_AFTER_N_MS=2 - - ############## - ## Authentication methods supported by the RPCAP protocol - ############## - # define RPCAP_RMTAUTH_NULL 0 - # It defines the NULL authentication. - RPCAP_RMTAUTH_NULL=0 - # define RPCAP_RMTAUTH_PWD 1 - # It defines the username/password authentication. - RPCAP_RMTAUTH_PWD=1 - - - ############## - ## Remote struct and defines - ############## - # define PCAP_BUF_SIZE 1024 - # Defines the maximum buffer size in which address, port, interface names are kept. - PCAP_BUF_SIZE = 1024 - # define RPCAP_HOSTLIST_SIZE 1024 - # Maximum lenght of an host name (needed for the RPCAP active mode). - RPCAP_HOSTLIST_SIZE = 1024 - - class pcap_send_queue(Structure): - _fields_=[("maxlen",c_uint), - ("len",c_uint), - ("buffer",c_char_p)] - - ## struct pcap_rmtauth - ## This structure keeps the information needed to autheticate the user on a remote machine - class pcap_rmtauth(Structure): - _fields_=[("type",c_int), - ("username",c_char_p), - ("password",c_char_p)] - - ## struct pcap_samp - ## This structure defines the information related to sampling - class pcap_samp(Structure): - _fields_=[("method",c_int), - ("value",c_int)] - - #PAirpcapHandle pcap_get_airpcap_handle (pcap_t *p) - # Returns the AirPcap handler associated with an adapter. This handler can be used to change the wireless-related settings of the CACE Technologies AirPcap wireless capture adapters. - - #bool pcap_offline_filter (struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data) - # Returns if a given filter applies to an offline packet. - pcap_offline_filter = _lib.pcap_offline_filter - pcap_offline_filter.restype = c_bool - pcap_offline_filter.argtypes = [POINTER(bpf_program),POINTER(pcap_pkthdr),POINTER(u_char)] - - #int pcap_live_dump (pcap_t *p, char *filename, int maxsize, int maxpacks) - # Save a capture to file. - pcap_live_dump = _lib.pcap_live_dump - pcap_live_dump.restype = c_int - pcap_live_dump.argtypes = [POINTER(pcap_t), POINTER(c_char), c_int,c_int] - - #int pcap_live_dump_ended (pcap_t *p, int sync) - # Return the status of the kernel dump process, i.e. tells if one of the limits defined with pcap_live_dump() has been reached. - pcap_live_dump_ended = _lib.pcap_live_dump_ended - pcap_live_dump_ended.restype = c_int - pcap_live_dump_ended.argtypes = [POINTER(pcap_t), c_int] - - #struct pcap_stat * pcap_stats_ex (pcap_t *p, int *pcap_stat_size) - # Return statistics on current capture. - pcap_stats_ex = _lib.pcap_stats_ex - pcap_stats_ex.restype = POINTER(pcap_stat) - pcap_stats_ex.argtypes = [POINTER(pcap_t), POINTER(c_int)] - - #int pcap_setbuff (pcap_t *p, int dim) - # Set the size of the kernel buffer associated with an adapter. - pcap_setbuff = _lib.pcap_setbuff - pcap_setbuff.restype = c_int - pcap_setbuff.argtypes = [POINTER(pcap_t), c_int] - - #int pcap_setmode (pcap_t *p, int mode) - # Set the working mode of the interface p to mode. - pcap_setmode = _lib.pcap_setmode - pcap_setmode.restype = c_int - pcap_setmode.argtypes = [POINTER(pcap_t), c_int] - - #int pcap_setmintocopy (pcap_t *p, int size) - # Set the minumum amount of data received by the kernel in a single call. - pcap_setmintocopy = _lib.pcap_setmintocopy - pcap_setmintocopy.restype = c_int - pcap_setmintocopy.argtype = [POINTER(pcap_t), c_int] - - #HANDLE pcap_getevent (pcap_t *p) - # Return the handle of the event associated with the interface p. - pcap_getevent = _lib.pcap_getevent - pcap_getevent.restype = HANDLE - pcap_getevent.argtypes = [POINTER(pcap_t)] - - #pcap_send_queue * pcap_sendqueue_alloc (u_int memsize) - # Allocate a send queue. - pcap_sendqueue_alloc = _lib.pcap_sendqueue_alloc - pcap_sendqueue_alloc.restype = POINTER(pcap_send_queue) - pcap_sendqueue_alloc.argtypes = [c_uint] - - #void pcap_sendqueue_destroy (pcap_send_queue *queue) - # Destroy a send queue. - pcap_sendqueue_destroy = _lib.pcap_sendqueue_destroy - pcap_sendqueue_destroy.restype = None - pcap_sendqueue_destroy.argtypes = [POINTER(pcap_send_queue)] - - #int pcap_sendqueue_queue (pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) - # Add a packet to a send queue. - pcap_sendqueue_queue = _lib.pcap_sendqueue_queue - pcap_sendqueue_queue.restype = c_int - pcap_sendqueue_queue.argtypes = [POINTER(pcap_send_queue), POINTER(pcap_pkthdr), POINTER(u_char)] - - #u_int pcap_sendqueue_transmit (pcap_t *p, pcap_send_queue *queue, int sync) - # Send a queue of raw packets to the network. - pcap_sendqueue_transmit = _lib.pcap_sendqueue_transmit - pcap_sendqueue_transmit.retype = u_int - pcap_sendqueue_transmit.argtypes = [POINTER(pcap_t), POINTER(pcap_send_queue), c_int] - - #int pcap_findalldevs_ex (char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf) - # Create a list of network devices that can be opened with pcap_open(). - pcap_findalldevs_ex = _lib.pcap_findalldevs_ex - pcap_findalldevs_ex.retype = c_int - pcap_findalldevs_ex.argtypes = [STRING, POINTER(pcap_rmtauth), POINTER(POINTER(pcap_if_t)), STRING] - - #int pcap_createsrcstr (char *source, int type, const char *host, const char *port, const char *name, char *errbuf) - # Accept a set of strings (host name, port, ...), and it returns the complete source string according to the new format (e.g. 'rpcap://1.2.3.4/eth0'). - pcap_createsrcstr = _lib.pcap_createsrcstr - pcap_createsrcstr.restype = c_int - pcap_createsrcstr.argtypes = [STRING, c_int, STRING, STRING, STRING, STRING] - - #int pcap_parsesrcstr (const char *source, int *type, char *host, char *port, char *name, char *errbuf) - # Parse the source string and returns the pieces in which the source can be split. - pcap_parsesrcstr = _lib.pcap_parsesrcstr - pcap_parsesrcstr.retype = c_int - pcap_parsesrcstr.argtypes = [STRING, POINTER(c_int), STRING, STRING, STRING, STRING] - - #pcap_t * pcap_open (const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf) - # Open a generic source in order to capture / send (WinPcap only) traffic. - pcap_open = _lib.pcap_open - pcap_open.restype = POINTER(pcap_t) - pcap_open.argtypes = [STRING, c_int, c_int, c_int, POINTER(pcap_rmtauth), STRING] - - #struct pcap_samp * pcap_setsampling (pcap_t *p) - # Define a sampling method for packet capture. - pcap_setsampling = _lib.pcap_setsampling - pcap_setsampling.restype = POINTER(pcap_samp) - pcap_setsampling.argtypes = [POINTER(pcap_t)] - - #SOCKET pcap_remoteact_accept (const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf) - # Block until a network connection is accepted (active mode only). - pcap_remoteact_accept = _lib.pcap_remoteact_accept - pcap_remoteact_accept.restype = SOCKET - pcap_remoteact_accept.argtypes = [STRING, STRING, STRING, STRING, POINTER(pcap_rmtauth), STRING] - - #int pcap_remoteact_close (const char *host, char *errbuf) - # Drop an active connection (active mode only). - pcap_remoteact_close = _lib.pcap_remoteact_close - pcap_remoteact_close.restypes = c_int - pcap_remoteact_close.argtypes = [STRING, STRING] - - #void pcap_remoteact_cleanup () - # Clean the socket that is currently used in waiting active connections. - pcap_remoteact_cleanup = _lib.pcap_remoteact_cleanup - pcap_remoteact_cleanup.restypes = None - pcap_remoteact_cleanup.argtypes = [] - - #int pcap_remoteact_list (char *hostlist, char sep, int size, char *errbuf) - # Return the hostname of the host that have an active connection with us (active mode only). - pcap_remoteact_list = _lib.pcap_remoteact_list - pcap_remoteact_list.restype = c_int - pcap_remoteact_list.argtypes = [STRING, c_char, c_int, STRING] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/as_resolvers.py b/scripts/external_libs/scapy-2.4.3/scapy/as_resolvers.py deleted file mode 100644 index 12d8cba50a..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/as_resolvers.py +++ /dev/null @@ -1,142 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Resolve Autonomous Systems (AS). -""" - - -from __future__ import absolute_import -import socket -from scapy.config import conf -from scapy.compat import plain_str - - -class AS_resolver: - server = None - options = "-k" - - def __init__(self, server=None, port=43, options=None): - if server is not None: - self.server = server - self.port = port - if options is not None: - self.options = options - - def _start(self): - self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.s.connect((self.server, self.port)) - if self.options: - self.s.send(self.options.encode("utf8") + b"\n") - self.s.recv(8192) - - def _stop(self): - self.s.close() - - def _parse_whois(self, txt): - asn, desc = None, b"" - for line in txt.splitlines(): - if not asn and line.startswith(b"origin:"): - asn = plain_str(line[7:].strip()) - if line.startswith(b"descr:"): - if desc: - desc += b"\n" - desc += line[6:].strip() - if asn is not None and desc: - break - return asn, plain_str(desc.strip()) - - def _resolve_one(self, ip): - self.s.send(("%s\n" % ip).encode("utf8")) - x = b"" - while not (b"%" in x or b"source" in x): - x += self.s.recv(8192) - asn, desc = self._parse_whois(x) - return ip, asn, desc - - def resolve(self, *ips): - self._start() - ret = [] - for ip in ips: - ip, asn, desc = self._resolve_one(ip) - if asn is not None: - ret.append((ip, asn, desc)) - self._stop() - return ret - - -class AS_resolver_riswhois(AS_resolver): - server = "riswhois.ripe.net" - options = "-k -M -1" - - -class AS_resolver_radb(AS_resolver): - server = "whois.ra.net" - options = "-k -M" - - -class AS_resolver_cymru(AS_resolver): - server = "whois.cymru.com" - options = None - - def resolve(self, *ips): - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((self.server, self.port)) - s.send( - b"begin\r\n" + - b"\r\n".join(ip.encode() for ip in ips) + - b"\r\nend\r\n" - ) - r = b"" - while True: - line = s.recv(8192) - if line == b"": - break - r += line - s.close() - - return self.parse(r) - - def parse(self, data): - """Parse bulk cymru data""" - - ASNlist = [] - for line in data.splitlines()[1:]: - line = plain_str(line) - if "|" not in line: - continue - asn, ip, desc = [elt.strip() for elt in line.split('|')] - if asn == "NA": - continue - asn = "AS%s" % asn - ASNlist.append((ip, asn, desc)) - return ASNlist - - -class AS_resolver_multi(AS_resolver): - resolvers_list = (AS_resolver_riswhois(), AS_resolver_radb(), - AS_resolver_cymru()) - resolvers_list = resolvers_list[1:] - - def __init__(self, *reslist): - if reslist: - self.resolvers_list = reslist - - def resolve(self, *ips): - todo = ips - ret = [] - for ASres in self.resolvers_list: - try: - res = ASres.resolve(*todo) - except socket.error: - continue - todo = [ip for ip in todo if ip not in [r[0] for r in res]] - ret += res - if not todo: - break - return ret - - -conf.AS_resolver = AS_resolver_multi() diff --git a/scripts/external_libs/scapy-2.4.3/scapy/asn1/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/asn1/__init__.py deleted file mode 100644 index e37b01b7cb..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/asn1/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Package holding ASN.1 related modules. -""" - -# We do not import mib.py because it is more bound to scapy and -# less prone to be used in a standalone fashion -__all__ = ["asn1", "ber"] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/asn1/asn1.py b/scripts/external_libs/scapy-2.4.3/scapy/asn1/asn1.py deleted file mode 100644 index e9725597f2..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/asn1/asn1.py +++ /dev/null @@ -1,516 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Modified by Maxence Tury -# This program is published under a GPLv2 license - -""" -ASN.1 (Abstract Syntax Notation One) -""" - -from __future__ import absolute_import -from __future__ import print_function -import random - -from datetime import datetime -from scapy.config import conf -from scapy.error import Scapy_Exception, warning -from scapy.volatile import RandField, RandIP, GeneralizedTime -from scapy.utils import Enum_metaclass, EnumElement, binrepr -from scapy.compat import plain_str, chb, orb -import scapy.modules.six as six -from scapy.modules.six.moves import range - - -class RandASN1Object(RandField): - def __init__(self, objlist=None): - self.objlist = [ - x._asn1_obj - for x in six.itervalues(ASN1_Class_UNIVERSAL.__rdict__) - if hasattr(x, "_asn1_obj") - ] if objlist is None else objlist - self.chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" # noqa: E501 - - def _fix(self, n=0): - o = random.choice(self.objlist) - if issubclass(o, ASN1_INTEGER): - return o(int(random.gauss(0, 1000))) - elif issubclass(o, ASN1_IPADDRESS): - z = RandIP()._fix() - return o(z) - elif issubclass(o, ASN1_GENERALIZED_TIME) or issubclass(o, ASN1_UTC_TIME): # noqa: E501 - z = GeneralizedTime()._fix() - return o(z) - elif issubclass(o, ASN1_STRING): - z = int(random.expovariate(0.05) + 1) - return o("".join(random.choice(self.chars) for _ in range(z))) - elif issubclass(o, ASN1_SEQUENCE) and (n < 10): - z = int(random.expovariate(0.08) + 1) - return o([self.__class__(objlist=self.objlist)._fix(n + 1) - for _ in range(z)]) - return ASN1_INTEGER(int(random.gauss(0, 1000))) - - -############## -# ASN1 # -############## - -class ASN1_Error(Scapy_Exception): - pass - - -class ASN1_Encoding_Error(ASN1_Error): - pass - - -class ASN1_Decoding_Error(ASN1_Error): - pass - - -class ASN1_BadTag_Decoding_Error(ASN1_Decoding_Error): - pass - - -class ASN1Codec(EnumElement): - def register_stem(cls, stem): - cls._stem = stem - - def dec(cls, s, context=None): - return cls._stem.dec(s, context=context) - - def safedec(cls, s, context=None): - return cls._stem.safedec(s, context=context) - - def get_stem(cls): - return cls.stem - - -class ASN1_Codecs_metaclass(Enum_metaclass): - element_class = ASN1Codec - - -class ASN1_Codecs(six.with_metaclass(ASN1_Codecs_metaclass)): - BER = 1 - DER = 2 - PER = 3 - CER = 4 - LWER = 5 - BACnet = 6 - OER = 7 - SER = 8 - XER = 9 - - -class ASN1Tag(EnumElement): - def __init__(self, key, value, context=None, codec=None): - EnumElement.__init__(self, key, value) - self._context = context - if codec is None: - codec = {} - self._codec = codec - - def clone(self): # not a real deep copy. self.codec is shared - return self.__class__(self._key, self._value, self._context, self._codec) # noqa: E501 - - def register_asn1_object(self, asn1obj): - self._asn1_obj = asn1obj - - def asn1_object(self, val): - if hasattr(self, "_asn1_obj"): - return self._asn1_obj(val) - raise ASN1_Error("%r does not have any assigned ASN1 object" % self) - - def register(self, codecnum, codec): - self._codec[codecnum] = codec - - def get_codec(self, codec): - try: - c = self._codec[codec] - except KeyError: - raise ASN1_Error("Codec %r not found for tag %r" % (codec, self)) - return c - - -class ASN1_Class_metaclass(Enum_metaclass): - element_class = ASN1Tag - - def __new__(cls, name, bases, dct): # XXX factorise a bit with Enum_metaclass.__new__() # noqa: E501 - for b in bases: - for k, v in six.iteritems(b.__dict__): - if k not in dct and isinstance(v, ASN1Tag): - dct[k] = v.clone() - - rdict = {} - for k, v in six.iteritems(dct): - if isinstance(v, int): - v = ASN1Tag(k, v) - dct[k] = v - rdict[v] = v - elif isinstance(v, ASN1Tag): - rdict[v] = v - dct["__rdict__"] = rdict - - cls = type.__new__(cls, name, bases, dct) - for v in six.itervalues(cls.__dict__): - if isinstance(v, ASN1Tag): - v.context = cls # overwrite ASN1Tag contexts, even cloned ones - return cls - - -class ASN1_Class(six.with_metaclass(ASN1_Class_metaclass)): - pass - - -class ASN1_Class_UNIVERSAL(ASN1_Class): - name = "UNIVERSAL" - ERROR = -3 - RAW = -2 - NONE = -1 - ANY = 0 - BOOLEAN = 1 - INTEGER = 2 - BIT_STRING = 3 - STRING = 4 - NULL = 5 - OID = 6 - OBJECT_DESCRIPTOR = 7 - EXTERNAL = 8 - REAL = 9 - ENUMERATED = 10 - EMBEDDED_PDF = 11 - UTF8_STRING = 12 - RELATIVE_OID = 13 - SEQUENCE = 16 | 0x20 # constructed encoding - SET = 17 | 0x20 # constructed encoding - NUMERIC_STRING = 18 - PRINTABLE_STRING = 19 - T61_STRING = 20 # aka TELETEX_STRING - VIDEOTEX_STRING = 21 - IA5_STRING = 22 - UTC_TIME = 23 - GENERALIZED_TIME = 24 - GRAPHIC_STRING = 25 - ISO646_STRING = 26 # aka VISIBLE_STRING - GENERAL_STRING = 27 - UNIVERSAL_STRING = 28 - CHAR_STRING = 29 - BMP_STRING = 30 - IPADDRESS = 0 | 0x40 # application-specific encoding - COUNTER32 = 1 | 0x40 # application-specific encoding - GAUGE32 = 2 | 0x40 # application-specific encoding - TIME_TICKS = 3 | 0x40 # application-specific encoding - - -class ASN1_Object_metaclass(type): - def __new__(cls, name, bases, dct): - c = super(ASN1_Object_metaclass, cls).__new__(cls, name, bases, dct) - try: - c.tag.register_asn1_object(c) - except Exception: - warning("Error registering %r for %r" % (c.tag, c.codec)) - return c - - -class ASN1_Object(six.with_metaclass(ASN1_Object_metaclass)): - tag = ASN1_Class_UNIVERSAL.ANY - - def __init__(self, val): - self.val = val - - def enc(self, codec): - return self.tag.get_codec(codec).enc(self.val) - - def __repr__(self): - return "<%s[%r]>" % (self.__dict__.get("name", self.__class__.__name__), self.val) # noqa: E501 - - def __str__(self): - return self.enc(conf.ASN1_default_codec) - - def __bytes__(self): - return self.enc(conf.ASN1_default_codec) - - def strshow(self, lvl=0): - return (" " * lvl) + repr(self) + "\n" - - def show(self, lvl=0): - print(self.strshow(lvl)) - - def __eq__(self, other): - return self.val == other - - def __lt__(self, other): - return self.val < other - - def __le__(self, other): - return self.val <= other - - def __gt__(self, other): - return self.val > other - - def __ge__(self, other): - return self.val >= other - - def __ne__(self, other): - return self.val != other - - -####################### -# ASN1 objects # -####################### - -# on the whole, we order the classes by ASN1_Class_UNIVERSAL tag value - -class ASN1_DECODING_ERROR(ASN1_Object): - tag = ASN1_Class_UNIVERSAL.ERROR - - def __init__(self, val, exc=None): - ASN1_Object.__init__(self, val) - self.exc = exc - - def __repr__(self): - return "<%s[%r]{{%r}}>" % (self.__dict__.get("name", self.__class__.__name__), # noqa: E501 - self.val, self.exc.args[0]) - - def enc(self, codec): - if isinstance(self.val, ASN1_Object): - return self.val.enc(codec) - return self.val - - -class ASN1_force(ASN1_Object): - tag = ASN1_Class_UNIVERSAL.RAW - - def enc(self, codec): - if isinstance(self.val, ASN1_Object): - return self.val.enc(codec) - return self.val - - -class ASN1_BADTAG(ASN1_force): - pass - - -class ASN1_INTEGER(ASN1_Object): - tag = ASN1_Class_UNIVERSAL.INTEGER - - def __repr__(self): - h = hex(int(self.val)) - if h[-1] == "L": - h = h[:-1] - # cut at 22 because with leading '0x', x509 serials should be < 23 - if len(h) > 22: - h = h[:12] + "..." + h[-10:] - r = repr(self.val) - if len(r) > 20: - r = r[:10] + "..." + r[-10:] - return h + " <%s[%s]>" % (self.__dict__.get("name", self.__class__.__name__), r) # noqa: E501 - - -class ASN1_BOOLEAN(ASN1_INTEGER): - tag = ASN1_Class_UNIVERSAL.BOOLEAN - # BER: 0 means False, anything else means True - - def __repr__(self): - return '%s %s' % (not (self.val == 0), ASN1_Object.__repr__(self)) - - -class ASN1_BIT_STRING(ASN1_Object): - """ - ASN1_BIT_STRING values are bit strings like "011101". - A zero-bit padded readable string is provided nonetheless, - which is stored in val_readable - """ - tag = ASN1_Class_UNIVERSAL.BIT_STRING - - def __init__(self, val, readable=False): - if not readable: - self.val = val - else: - self.val_readable = val - - def __setattr__(self, name, value): - if name == "val_readable": - if isinstance(value, (str, bytes)): - val = "".join(binrepr(orb(x)).zfill(8) for x in value) - else: - warning("Invalid val: should be bytes") - val = "" - super(ASN1_Object, self).__setattr__("val", val) - super(ASN1_Object, self).__setattr__(name, value) - super(ASN1_Object, self).__setattr__("unused_bits", 0) - elif name == "val": - value = plain_str(value) - if isinstance(value, str): - if any(c for c in value if c not in ["0", "1"]): - warning("Invalid operation: 'val' is not a valid bit string.") # noqa: E501 - return - else: - if len(value) % 8 == 0: - unused_bits = 0 - else: - unused_bits = 8 - (len(value) % 8) - padded_value = value + ("0" * unused_bits) - bytes_arr = zip(*[iter(padded_value)] * 8) - val_readable = b"".join(chb(int("".join(x), 2)) for x in bytes_arr) # noqa: E501 - else: - warning("Invalid val: should be str") - val_readable = b"" - unused_bits = 0 - super(ASN1_Object, self).__setattr__("val_readable", val_readable) - super(ASN1_Object, self).__setattr__(name, value) - super(ASN1_Object, self).__setattr__("unused_bits", unused_bits) - elif name == "unused_bits": - warning("Invalid operation: unused_bits rewriting " - "is not supported.") - else: - super(ASN1_Object, self).__setattr__(name, value) - - def __repr__(self): - s = self.val_readable - if len(s) > 16: - s = s[:10] + b"..." + s[-10:] - v = self.val - if len(v) > 20: - v = v[:10] + "..." + v[-10:] - return "<%s[%s]=%s (%d unused bit%s)>" % ( - self.__dict__.get("name", self.__class__.__name__), - v, - s, - self.unused_bits, - "s" if self.unused_bits > 1 else "" - ) - - -class ASN1_STRING(ASN1_Object): - tag = ASN1_Class_UNIVERSAL.STRING - - -class ASN1_NULL(ASN1_Object): - tag = ASN1_Class_UNIVERSAL.NULL - - def __repr__(self): - return ASN1_Object.__repr__(self) - - -class ASN1_OID(ASN1_Object): - tag = ASN1_Class_UNIVERSAL.OID - - def __init__(self, val): - val = conf.mib._oid(plain_str(val)) - ASN1_Object.__init__(self, val) - self.oidname = conf.mib._oidname(val) - - def __repr__(self): - return "<%s[%r]>" % (self.__dict__.get("name", self.__class__.__name__), self.oidname) # noqa: E501 - - -class ASN1_ENUMERATED(ASN1_INTEGER): - tag = ASN1_Class_UNIVERSAL.ENUMERATED - - -class ASN1_UTF8_STRING(ASN1_STRING): - tag = ASN1_Class_UNIVERSAL.UTF8_STRING - - -class ASN1_NUMERIC_STRING(ASN1_STRING): - tag = ASN1_Class_UNIVERSAL.NUMERIC_STRING - - -class ASN1_PRINTABLE_STRING(ASN1_STRING): - tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING - - -class ASN1_T61_STRING(ASN1_STRING): - tag = ASN1_Class_UNIVERSAL.T61_STRING - - -class ASN1_VIDEOTEX_STRING(ASN1_STRING): - tag = ASN1_Class_UNIVERSAL.VIDEOTEX_STRING - - -class ASN1_IA5_STRING(ASN1_STRING): - tag = ASN1_Class_UNIVERSAL.IA5_STRING - - -class ASN1_UTC_TIME(ASN1_STRING): - tag = ASN1_Class_UNIVERSAL.UTC_TIME - - def __init__(self, val): - ASN1_STRING.__init__(self, val) - - def __setattr__(self, name, value): - if isinstance(value, bytes): - value = plain_str(value) - if name == "val": - pretty_time = None - if isinstance(self, ASN1_GENERALIZED_TIME): - _len = 15 - self._format = "%Y%m%d%H%M%S" - else: - _len = 13 - self._format = "%y%m%d%H%M%S" - _nam = self.tag._asn1_obj.__name__[4:].lower() - if (isinstance(value, str) and - len(value) == _len and value[-1] == "Z"): - dt = datetime.strptime(value[:-1], self._format) - pretty_time = dt.strftime("%b %d %H:%M:%S %Y GMT") - else: - pretty_time = "%s [invalid %s]" % (value, _nam) - ASN1_STRING.__setattr__(self, "pretty_time", pretty_time) - ASN1_STRING.__setattr__(self, name, value) - elif name == "pretty_time": - print("Invalid operation: pretty_time rewriting is not supported.") - else: - ASN1_STRING.__setattr__(self, name, value) - - def __repr__(self): - return "%s %s" % (self.pretty_time, ASN1_STRING.__repr__(self)) - - -class ASN1_GENERALIZED_TIME(ASN1_UTC_TIME): - tag = ASN1_Class_UNIVERSAL.GENERALIZED_TIME - - -class ASN1_ISO646_STRING(ASN1_STRING): - tag = ASN1_Class_UNIVERSAL.ISO646_STRING - - -class ASN1_UNIVERSAL_STRING(ASN1_STRING): - tag = ASN1_Class_UNIVERSAL.UNIVERSAL_STRING - - -class ASN1_BMP_STRING(ASN1_STRING): - tag = ASN1_Class_UNIVERSAL.BMP_STRING - - -class ASN1_SEQUENCE(ASN1_Object): - tag = ASN1_Class_UNIVERSAL.SEQUENCE - - def strshow(self, lvl=0): - s = (" " * lvl) + ("# %s:" % self.__class__.__name__) + "\n" - for o in self.val: - s += o.strshow(lvl=lvl + 1) - return s - - -class ASN1_SET(ASN1_SEQUENCE): - tag = ASN1_Class_UNIVERSAL.SET - - -class ASN1_IPADDRESS(ASN1_STRING): - tag = ASN1_Class_UNIVERSAL.IPADDRESS - - -class ASN1_COUNTER32(ASN1_INTEGER): - tag = ASN1_Class_UNIVERSAL.COUNTER32 - - -class ASN1_GAUGE32(ASN1_INTEGER): - tag = ASN1_Class_UNIVERSAL.GAUGE32 - - -class ASN1_TIME_TICKS(ASN1_INTEGER): - tag = ASN1_Class_UNIVERSAL.TIME_TICKS - - -conf.ASN1_default_codec = ASN1_Codecs.BER diff --git a/scripts/external_libs/scapy-2.4.3/scapy/asn1/ber.py b/scripts/external_libs/scapy-2.4.3/scapy/asn1/ber.py deleted file mode 100644 index d6c6b1498c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/asn1/ber.py +++ /dev/null @@ -1,565 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Modified by Maxence Tury -# Acknowledgment: Ralph Broenink -# This program is published under a GPLv2 license - -""" -Basic Encoding Rules (BER) for ASN.1 -""" - -from __future__ import absolute_import -from scapy.error import warning -from scapy.compat import chb, orb, bytes_encode -from scapy.utils import binrepr, inet_aton, inet_ntoa -from scapy.asn1.asn1 import ASN1_Decoding_Error, ASN1_Encoding_Error, \ - ASN1_BadTag_Decoding_Error, ASN1_Codecs, ASN1_Class_UNIVERSAL, \ - ASN1_Error, ASN1_DECODING_ERROR, ASN1_BADTAG -from scapy.modules import six - -################## -# BER encoding # -################## - - -# [ BER tools ] # - - -class BER_Exception(Exception): - pass - - -class BER_Encoding_Error(ASN1_Encoding_Error): - def __init__(self, msg, encoded=None, remaining=None): - Exception.__init__(self, msg) - self.remaining = remaining - self.encoded = encoded - - def __str__(self): - s = Exception.__str__(self) - if isinstance(self.encoded, BERcodec_Object): - s += "\n### Already encoded ###\n%s" % self.encoded.strshow() - else: - s += "\n### Already encoded ###\n%r" % self.encoded - s += "\n### Remaining ###\n%r" % self.remaining - return s - - -class BER_Decoding_Error(ASN1_Decoding_Error): - def __init__(self, msg, decoded=None, remaining=None): - Exception.__init__(self, msg) - self.remaining = remaining - self.decoded = decoded - - def __str__(self): - s = Exception.__str__(self) - if isinstance(self.decoded, BERcodec_Object): - s += "\n### Already decoded ###\n%s" % self.decoded.strshow() - else: - s += "\n### Already decoded ###\n%r" % self.decoded - s += "\n### Remaining ###\n%r" % self.remaining - return s - - -class BER_BadTag_Decoding_Error(BER_Decoding_Error, - ASN1_BadTag_Decoding_Error): - pass - - -def BER_len_enc(ll, size=0): - if ll <= 127 and size == 0: - return chb(ll) - s = b"" - while ll or size > 0: - s = chb(ll & 0xff) + s - ll >>= 8 - size -= 1 - if len(s) > 127: - raise BER_Exception( - "BER_len_enc: Length too long (%i) to be encoded [%r]" % - (len(s), s) - ) - return chb(len(s) | 0x80) + s - - -def BER_len_dec(s): - tmp_len = orb(s[0]) - if not tmp_len & 0x80: - return tmp_len, s[1:] - tmp_len &= 0x7f - if len(s) <= tmp_len: - raise BER_Decoding_Error( - "BER_len_dec: Got %i bytes while expecting %i" % - (len(s) - 1, tmp_len), - remaining=s - ) - ll = 0 - for c in s[1:tmp_len + 1]: - ll <<= 8 - ll |= orb(c) - return ll, s[tmp_len + 1:] - - -def BER_num_enc(ll, size=1): - x = [] - while ll or size > 0: - x.insert(0, ll & 0x7f) - if len(x) > 1: - x[0] |= 0x80 - ll >>= 7 - size -= 1 - return b"".join(chb(k) for k in x) - - -def BER_num_dec(s, cls_id=0): - if len(s) == 0: - raise BER_Decoding_Error("BER_num_dec: got empty string", remaining=s) - x = cls_id - for i, c in enumerate(s): - c = orb(c) - x <<= 7 - x |= c & 0x7f - if not c & 0x80: - break - if c & 0x80: - raise BER_Decoding_Error("BER_num_dec: unfinished number description", - remaining=s) - return x, s[i + 1:] - - -def BER_id_dec(s): - # This returns the tag ALONG WITH THE PADDED CLASS+CONSTRUCTIVE INFO. - # Let's recall that bits 8-7 from the first byte of the tag encode - # the class information, while bit 6 means primitive or constructive. - # - # For instance, with low-tag-number b'\x81', class would be 0b10 - # ('context-specific') and tag 0x01, but we return 0x81 as a whole. - # For b'\xff\x22', class would be 0b11 ('private'), constructed, then - # padding, then tag 0x22, but we return (0xff>>5)*128^1 + 0x22*128^0. - # Why the 5-bit-shifting? Because it provides an unequivocal encoding - # on base 128 (note that 0xff would equal 1*128^1 + 127*128^0...), - # as we know that bits 5 to 1 are fixed to 1 anyway. - # - # As long as there is no class differentiation, we have to keep this info - # encoded in scapy's tag in order to reuse it for packet building. - # Note that tags thus may have to be hard-coded with their extended - # information, e.g. a SEQUENCE from asn1.py has a direct tag 0x20|16. - x = orb(s[0]) - if x & 0x1f != 0x1f: - # low-tag-number - return x, s[1:] - else: - # high-tag-number - return BER_num_dec(s[1:], cls_id=x >> 5) - - -def BER_id_enc(n): - if n < 256: - # low-tag-number - return chb(n) - else: - # high-tag-number - s = BER_num_enc(n) - tag = orb(s[0]) # first byte, as an int - tag &= 0x07 # reset every bit from 8 to 4 - tag <<= 5 # move back the info bits on top - tag |= 0x1f # pad with 1s every bit from 5 to 1 - return chb(tag) + s[1:] - -# The functions below provide implicit and explicit tagging support. - - -def BER_tagging_dec(s, hidden_tag=None, implicit_tag=None, - explicit_tag=None, safe=False): - # We output the 'real_tag' if it is different from the (im|ex)plicit_tag. - real_tag = None - if len(s) > 0: - err_msg = "BER_tagging_dec: observed tag does not match expected tag" - if implicit_tag is not None: - ber_id, s = BER_id_dec(s) - if ber_id != implicit_tag: - if not safe: - raise BER_Decoding_Error(err_msg, remaining=s) - else: - real_tag = ber_id - s = chb(hash(hidden_tag)) + s - elif explicit_tag is not None: - ber_id, s = BER_id_dec(s) - if ber_id != explicit_tag: - if not safe: - raise BER_Decoding_Error(err_msg, remaining=s) - else: - real_tag = ber_id - l, s = BER_len_dec(s) - return real_tag, s - - -def BER_tagging_enc(s, implicit_tag=None, explicit_tag=None): - if len(s) > 0: - if implicit_tag is not None: - s = BER_id_enc(implicit_tag) + s[1:] - elif explicit_tag is not None: - s = BER_id_enc(explicit_tag) + BER_len_enc(len(s)) + s - return s - -# [ BER classes ] # - - -class BERcodec_metaclass(type): - def __new__(cls, name, bases, dct): - c = super(BERcodec_metaclass, cls).__new__(cls, name, bases, dct) - try: - c.tag.register(c.codec, c) - except Exception: - warning("Error registering %r for %r" % (c.tag, c.codec)) - return c - - -class BERcodec_Object(six.with_metaclass(BERcodec_metaclass)): - codec = ASN1_Codecs.BER - tag = ASN1_Class_UNIVERSAL.ANY - - @classmethod - def asn1_object(cls, val): - return cls.tag.asn1_object(val) - - @classmethod - def check_string(cls, s): - if not s: - raise BER_Decoding_Error( - "%s: Got empty object while expecting tag %r" % - (cls.__name__, cls.tag), remaining=s - ) - - @classmethod - def check_type(cls, s): - cls.check_string(s) - tag, remainder = BER_id_dec(s) - if not isinstance(tag, int) or cls.tag != tag: - raise BER_BadTag_Decoding_Error( - "%s: Got tag [%i/%#x] while expecting %r" % - (cls.__name__, tag, tag, cls.tag), remaining=s - ) - return remainder - - @classmethod - def check_type_get_len(cls, s): - s2 = cls.check_type(s) - if not s2: - raise BER_Decoding_Error("%s: No bytes while expecting a length" % - cls.__name__, remaining=s) - return BER_len_dec(s2) - - @classmethod - def check_type_check_len(cls, s): - l, s3 = cls.check_type_get_len(s) - if len(s3) < l: - raise BER_Decoding_Error("%s: Got %i bytes while expecting %i" % - (cls.__name__, len(s3), l), remaining=s) - return l, s3[:l], s3[l:] - - @classmethod - def do_dec(cls, s, context=None, safe=False): - if context is None: - context = cls.tag.context - cls.check_string(s) - p, remainder = BER_id_dec(s) - if p not in context: - t = s - if len(t) > 18: - t = t[:15] + b"..." - raise BER_Decoding_Error("Unknown prefix [%02x] for [%r]" % - (p, t), remaining=s) - codec = context[p].get_codec(ASN1_Codecs.BER) - if codec == BERcodec_Object: - # Value type defined as Unknown - l, s = BER_num_dec(remainder) - return ASN1_BADTAG(s[:l]), s[l:] - return codec.dec(s, context, safe) - - @classmethod - def dec(cls, s, context=None, safe=False): - if not safe: - return cls.do_dec(s, context, safe) - try: - return cls.do_dec(s, context, safe) - except BER_BadTag_Decoding_Error as e: - o, remain = BERcodec_Object.dec(e.remaining, context, safe) - return ASN1_BADTAG(o), remain - except BER_Decoding_Error as e: - return ASN1_DECODING_ERROR(s, exc=e), "" - except ASN1_Error as e: - return ASN1_DECODING_ERROR(s, exc=e), "" - - @classmethod - def safedec(cls, s, context=None): - return cls.dec(s, context, safe=True) - - @classmethod - def enc(cls, s): - if isinstance(s, six.string_types + (bytes,)): - return BERcodec_STRING.enc(s) - else: - return BERcodec_INTEGER.enc(int(s)) - - -ASN1_Codecs.BER.register_stem(BERcodec_Object) - - -########################## -# BERcodec objects # -########################## - -class BERcodec_INTEGER(BERcodec_Object): - tag = ASN1_Class_UNIVERSAL.INTEGER - - @classmethod - def enc(cls, i): - s = [] - while True: - s.append(i & 0xff) - if -127 <= i < 0: - break - if 128 <= i <= 255: - s.append(0) - i >>= 8 - if not i: - break - s = [chb(hash(c)) for c in s] - s.append(BER_len_enc(len(s))) - s.append(chb(hash(cls.tag))) - s.reverse() - return b"".join(s) - - @classmethod - def do_dec(cls, s, context=None, safe=False): - l, s, t = cls.check_type_check_len(s) - x = 0 - if s: - if orb(s[0]) & 0x80: # negative int - x = -1 - for c in s: - x <<= 8 - x |= orb(c) - return cls.asn1_object(x), t - - -class BERcodec_BOOLEAN(BERcodec_INTEGER): - tag = ASN1_Class_UNIVERSAL.BOOLEAN - - -class BERcodec_BIT_STRING(BERcodec_Object): - tag = ASN1_Class_UNIVERSAL.BIT_STRING - - @classmethod - def do_dec(cls, s, context=None, safe=False): - # /!\ the unused_bits information is lost after this decoding - l, s, t = cls.check_type_check_len(s) - if len(s) > 0: - unused_bits = orb(s[0]) - if safe and unused_bits > 7: - raise BER_Decoding_Error( - "BERcodec_BIT_STRING: too many unused_bits advertised", - remaining=s - ) - s = "".join(binrepr(orb(x)).zfill(8) for x in s[1:]) - if unused_bits > 0: - s = s[:-unused_bits] - return cls.tag.asn1_object(s), t - else: - raise BER_Decoding_Error( - "BERcodec_BIT_STRING found no content " - "(not even unused_bits byte)", - remaining=s - ) - - @classmethod - def enc(cls, s): - # /!\ this is DER encoding (bit strings are only zero-bit padded) - s = bytes_encode(s) - if len(s) % 8 == 0: - unused_bits = 0 - else: - unused_bits = 8 - len(s) % 8 - s += b"0" * unused_bits - s = b"".join(chb(int(b"".join(chb(y) for y in x), 2)) - for x in zip(*[iter(s)] * 8)) - s = chb(unused_bits) + s - return chb(hash(cls.tag)) + BER_len_enc(len(s)) + s - - -class BERcodec_STRING(BERcodec_Object): - tag = ASN1_Class_UNIVERSAL.STRING - - @classmethod - def enc(cls, s): - s = bytes_encode(s) - # Be sure we are encoding bytes - return chb(hash(cls.tag)) + BER_len_enc(len(s)) + s - - @classmethod - def do_dec(cls, s, context=None, safe=False): - l, s, t = cls.check_type_check_len(s) - return cls.tag.asn1_object(s), t - - -class BERcodec_NULL(BERcodec_INTEGER): - tag = ASN1_Class_UNIVERSAL.NULL - - @classmethod - def enc(cls, i): - if i == 0: - return chb(hash(cls.tag)) + b"\0" - else: - return super(cls, cls).enc(i) - - -class BERcodec_OID(BERcodec_Object): - tag = ASN1_Class_UNIVERSAL.OID - - @classmethod - def enc(cls, oid): - oid = bytes_encode(oid) - if oid: - lst = [int(x) for x in oid.strip(b".").split(b".")] - else: - lst = list() - if len(lst) >= 2: - lst[1] += 40 * lst[0] - del(lst[0]) - s = b"".join(BER_num_enc(k) for k in lst) - return chb(hash(cls.tag)) + BER_len_enc(len(s)) + s - - @classmethod - def do_dec(cls, s, context=None, safe=False): - l, s, t = cls.check_type_check_len(s) - lst = [] - while s: - l, s = BER_num_dec(s) - lst.append(l) - if (len(lst) > 0): - lst.insert(0, lst[0] // 40) - lst[1] %= 40 - return ( - cls.asn1_object(b".".join(str(k).encode('ascii') for k in lst)), - t, - ) - - -class BERcodec_ENUMERATED(BERcodec_INTEGER): - tag = ASN1_Class_UNIVERSAL.ENUMERATED - - -class BERcodec_UTF8_STRING(BERcodec_STRING): - tag = ASN1_Class_UNIVERSAL.UTF8_STRING - - -class BERcodec_NUMERIC_STRING(BERcodec_STRING): - tag = ASN1_Class_UNIVERSAL.NUMERIC_STRING - - -class BERcodec_PRINTABLE_STRING(BERcodec_STRING): - tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING - - -class BERcodec_T61_STRING(BERcodec_STRING): - tag = ASN1_Class_UNIVERSAL.T61_STRING - - -class BERcodec_VIDEOTEX_STRING(BERcodec_STRING): - tag = ASN1_Class_UNIVERSAL.VIDEOTEX_STRING - - -class BERcodec_IA5_STRING(BERcodec_STRING): - tag = ASN1_Class_UNIVERSAL.IA5_STRING - - -class BERcodec_UTC_TIME(BERcodec_STRING): - tag = ASN1_Class_UNIVERSAL.UTC_TIME - - -class BERcodec_GENERALIZED_TIME(BERcodec_STRING): - tag = ASN1_Class_UNIVERSAL.GENERALIZED_TIME - - -class BERcodec_ISO646_STRING(BERcodec_STRING): - tag = ASN1_Class_UNIVERSAL.ISO646_STRING - - -class BERcodec_UNIVERSAL_STRING(BERcodec_STRING): - tag = ASN1_Class_UNIVERSAL.UNIVERSAL_STRING - - -class BERcodec_BMP_STRING(BERcodec_STRING): - tag = ASN1_Class_UNIVERSAL.BMP_STRING - - -class BERcodec_SEQUENCE(BERcodec_Object): - tag = ASN1_Class_UNIVERSAL.SEQUENCE - - @classmethod - def enc(cls, ll): - if not isinstance(ll, bytes): - ll = b"".join(x.enc(cls.codec) for x in ll) - return chb(hash(cls.tag)) + BER_len_enc(len(ll)) + ll - - @classmethod - def do_dec(cls, s, context=None, safe=False): - if context is None: - context = cls.tag.context - ll, st = cls.check_type_get_len(s) # we may have len(s) < ll - s, t = st[:ll], st[ll:] - obj = [] - while s: - try: - o, s = BERcodec_Object.dec(s, context, safe) - except BER_Decoding_Error as err: - err.remaining += t - if err.decoded is not None: - obj.append(err.decoded) - err.decoded = obj - raise - obj.append(o) - if len(st) < ll: - raise BER_Decoding_Error("Not enough bytes to decode sequence", - decoded=obj) - return cls.asn1_object(obj), t - - -class BERcodec_SET(BERcodec_SEQUENCE): - tag = ASN1_Class_UNIVERSAL.SET - - -class BERcodec_IPADDRESS(BERcodec_STRING): - tag = ASN1_Class_UNIVERSAL.IPADDRESS - - @classmethod - def enc(cls, ipaddr_ascii): - try: - s = inet_aton(ipaddr_ascii) - except Exception: - raise BER_Encoding_Error("IPv4 address could not be encoded") - return chb(hash(cls.tag)) + BER_len_enc(len(s)) + s - - @classmethod - def do_dec(cls, s, context=None, safe=False): - l, s, t = cls.check_type_check_len(s) - try: - ipaddr_ascii = inet_ntoa(s) - except Exception: - raise BER_Decoding_Error("IP address could not be decoded", - remaining=s) - return cls.asn1_object(ipaddr_ascii), t - - -class BERcodec_COUNTER32(BERcodec_INTEGER): - tag = ASN1_Class_UNIVERSAL.COUNTER32 - - -class BERcodec_GAUGE32(BERcodec_INTEGER): - tag = ASN1_Class_UNIVERSAL.GAUGE32 - - -class BERcodec_TIME_TICKS(BERcodec_INTEGER): - tag = ASN1_Class_UNIVERSAL.TIME_TICKS diff --git a/scripts/external_libs/scapy-2.4.3/scapy/asn1/mib.py b/scripts/external_libs/scapy-2.4.3/scapy/asn1/mib.py deleted file mode 100644 index 4945ceea08..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/asn1/mib.py +++ /dev/null @@ -1,623 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Modified by Maxence Tury -# This program is published under a GPLv2 license - -""" -Management Information Base (MIB) parsing -""" - -from __future__ import absolute_import -import re -from glob import glob -from scapy.dadict import DADict, fixname -from scapy.config import conf -from scapy.utils import do_graph -import scapy.modules.six as six -from scapy.compat import plain_str - -################# -# MIB parsing # -################# - -_mib_re_integer = re.compile(r"^[0-9]+$") -_mib_re_both = re.compile(r"^([a-zA-Z_][a-zA-Z0-9_-]*)\(([0-9]+)\)$") -_mib_re_oiddecl = re.compile(r"$\s*([a-zA-Z0-9_-]+)\s+OBJECT([^:\{\}]|\{[^:]+\})+::=\s*\{([^\}]+)\}", re.M) # noqa: E501 -_mib_re_strings = re.compile(r'"[^"]*"') -_mib_re_comments = re.compile(r'--.*(\r|\n)') - - -class MIBDict(DADict): - def fixname(self, val): - # We overwrite DADict fixname method as we want to keep - in names - return val - - def _findroot(self, x): - """Internal MIBDict function used to find a partial OID""" - if x.startswith("."): - x = x[1:] - if not x.endswith("."): - x += "." - max = 0 - root = "." - root_key = "" - for k in six.iterkeys(self): - if x.startswith(k + "."): - if max < len(k): - max = len(k) - root = self[k] - root_key = k - return root, root_key, x[max:-1] - - def _oidname(self, x): - """Deduce the OID name from its OID ID""" - root, _, remainder = self._findroot(x) - return root + remainder - - def _oid(self, x): - """Parse the OID id/OID generator, and return real OID""" - xl = x.strip(".").split(".") - p = len(xl) - 1 - while p >= 0 and _mib_re_integer.match(xl[p]): - p -= 1 - if p != 0 or xl[p] not in six.itervalues(self.__dict__): - return x - xl[p] = next(k for k, v in six.iteritems(self.__dict__) if v == xl[p]) - return ".".join(xl[p:]) - - def _make_graph(self, other_keys=None, **kargs): - if other_keys is None: - other_keys = [] - nodes = [(self[key], key) for key in self.iterkeys()] - oids = set(self.iterkeys()) - for k in other_keys: - if k not in oids: - nodes.append(self.oidname(k), k) - s = 'digraph "mib" {\n\trankdir=LR;\n\n' - for k, o in nodes: - s += '\t"%s" [ label="%s" ];\n' % (o, k) - s += "\n" - for k, o in nodes: - parent, parent_key, remainder = self._findroot(o[:-1]) - remainder = remainder[1:] + o[-1] - if parent != ".": - parent = parent_key - s += '\t"%s" -> "%s" [label="%s"];\n' % (parent, o, remainder) - s += "}\n" - do_graph(s, **kargs) - - -def _mib_register(ident, value, the_mib, unresolved): - """Internal function used to register an OID and its name in a MIBDict""" - if ident in the_mib or ident in unresolved: - return ident in the_mib - resval = [] - not_resolved = 0 - for v in value: - if _mib_re_integer.match(v): - resval.append(v) - else: - v = fixname(plain_str(v)) - if v not in the_mib: - not_resolved = 1 - if v in the_mib: - v = the_mib[v] - elif v in unresolved: - v = unresolved[v] - if isinstance(v, list): - resval += v - else: - resval.append(v) - if not_resolved: - unresolved[ident] = resval - return False - else: - the_mib[ident] = resval - keys = list(unresolved) - i = 0 - while i < len(keys): - k = keys[i] - if _mib_register(k, unresolved[k], the_mib, {}): - del(unresolved[k]) - del(keys[i]) - i = 0 - else: - i += 1 - - return True - - -def load_mib(filenames): - """Load the conf.mib dict from a list of filenames""" - the_mib = {'iso': ['1']} - unresolved = {} - for k in six.iterkeys(conf.mib): - _mib_register(conf.mib[k], k.split("."), the_mib, unresolved) - - if isinstance(filenames, (str, bytes)): - filenames = [filenames] - for fnames in filenames: - for fname in glob(fnames): - f = open(fname) - text = f.read() - cleantext = " ".join(_mib_re_strings.split(" ".join(_mib_re_comments.split(text)))) # noqa: E501 - for m in _mib_re_oiddecl.finditer(cleantext): - gr = m.groups() - ident, oid = gr[0], gr[-1] - ident = fixname(ident) - oid = oid.split() - for i, elt in enumerate(oid): - m = _mib_re_both.match(elt) - if m: - oid[i] = m.groups()[1] - _mib_register(ident, oid, the_mib, unresolved) - - newmib = MIBDict(_name="MIB") - for oid, key in six.iteritems(the_mib): - newmib[".".join(key)] = oid - for oid, key in six.iteritems(unresolved): - newmib[".".join(key)] = oid - - conf.mib = newmib - - -#################### -# OID references # -#################### - -# pkcs1 # - -pkcs1_oids = { - "1.2.840.113549.1.1.1": "rsaEncryption", - "1.2.840.113549.1.1.2": "md2WithRSAEncryption", - "1.2.840.113549.1.1.3": "md4WithRSAEncryption", - "1.2.840.113549.1.1.4": "md5WithRSAEncryption", - "1.2.840.113549.1.1.5": "sha1-with-rsa-signature", - "1.2.840.113549.1.1.6": "rsaOAEPEncryptionSET", - "1.2.840.113549.1.1.7": "id-RSAES-OAEP", - "1.2.840.113549.1.1.8": "id-mgf1", - "1.2.840.113549.1.1.9": "id-pSpecified", - "1.2.840.113549.1.1.10": "rsassa-pss", - "1.2.840.113549.1.1.11": "sha256WithRSAEncryption", - "1.2.840.113549.1.1.12": "sha384WithRSAEncryption", - "1.2.840.113549.1.1.13": "sha512WithRSAEncryption", - "1.2.840.113549.1.1.14": "sha224WithRSAEncryption" -} - -# secsig oiw # - -secsig_oids = { - "1.3.14.3.2.26": "sha1" -} - -# pkcs9 # - -pkcs9_oids = { - "1.2.840.113549.1.9.0": "modules", - "1.2.840.113549.1.9.1": "emailAddress", - "1.2.840.113549.1.9.2": "unstructuredName", - "1.2.840.113549.1.9.3": "contentType", - "1.2.840.113549.1.9.4": "messageDigest", - "1.2.840.113549.1.9.5": "signing-time", - "1.2.840.113549.1.9.6": "countersignature", - "1.2.840.113549.1.9.7": "challengePassword", - "1.2.840.113549.1.9.8": "unstructuredAddress", - "1.2.840.113549.1.9.9": "extendedCertificateAttributes", - "1.2.840.113549.1.9.13": "signingDescription", - "1.2.840.113549.1.9.14": "extensionRequest", - "1.2.840.113549.1.9.15": "smimeCapabilities", - "1.2.840.113549.1.9.16": "smime", - "1.2.840.113549.1.9.17": "pgpKeyID", - "1.2.840.113549.1.9.20": "friendlyName", - "1.2.840.113549.1.9.21": "localKeyID", - "1.2.840.113549.1.9.22": "certTypes", - "1.2.840.113549.1.9.23": "crlTypes", - "1.2.840.113549.1.9.24": "pkcs-9-oc", - "1.2.840.113549.1.9.25": "pkcs-9-at", - "1.2.840.113549.1.9.26": "pkcs-9-sx", - "1.2.840.113549.1.9.27": "pkcs-9-mr", - "1.2.840.113549.1.9.52": "id-aa-CMSAlgorithmProtection" -} - -# x509 # - -attributeType_oids = { - "2.5.4.0": "objectClass", - "2.5.4.1": "aliasedEntryName", - "2.5.4.2": "knowledgeInformation", - "2.5.4.3": "commonName", - "2.5.4.4": "surname", - "2.5.4.5": "serialNumber", - "2.5.4.6": "countryName", - "2.5.4.7": "localityName", - "2.5.4.8": "stateOrProvinceName", - "2.5.4.9": "streetAddress", - "2.5.4.10": "organizationName", - "2.5.4.11": "organizationUnitName", - "2.5.4.12": "title", - "2.5.4.13": "description", - "2.5.4.14": "searchGuide", - "2.5.4.15": "businessCategory", - "2.5.4.16": "postalAddress", - "2.5.4.17": "postalCode", - "2.5.4.18": "postOfficeBox", - "2.5.4.19": "physicalDeliveryOfficeName", - "2.5.4.20": "telephoneNumber", - "2.5.4.21": "telexNumber", - "2.5.4.22": "teletexTerminalIdentifier", - "2.5.4.23": "facsimileTelephoneNumber", - "2.5.4.24": "x121Address", - "2.5.4.25": "internationalISDNNumber", - "2.5.4.26": "registeredAddress", - "2.5.4.27": "destinationIndicator", - "2.5.4.28": "preferredDeliveryMethod", - "2.5.4.29": "presentationAddress", - "2.5.4.30": "supportedApplicationContext", - "2.5.4.31": "member", - "2.5.4.32": "owner", - "2.5.4.33": "roleOccupant", - "2.5.4.34": "seeAlso", - "2.5.4.35": "userPassword", - "2.5.4.36": "userCertificate", - "2.5.4.37": "cACertificate", - "2.5.4.38": "authorityRevocationList", - "2.5.4.39": "certificateRevocationList", - "2.5.4.40": "crossCertificatePair", - "2.5.4.41": "name", - "2.5.4.42": "givenName", - "2.5.4.43": "initials", - "2.5.4.44": "generationQualifier", - "2.5.4.45": "uniqueIdentifier", - "2.5.4.46": "dnQualifier", - "2.5.4.47": "enhancedSearchGuide", - "2.5.4.48": "protocolInformation", - "2.5.4.49": "distinguishedName", - "2.5.4.50": "uniqueMember", - "2.5.4.51": "houseIdentifier", - "2.5.4.52": "supportedAlgorithms", - "2.5.4.53": "deltaRevocationList", - "2.5.4.54": "dmdName", - "2.5.4.55": "clearance", - "2.5.4.56": "defaultDirQop", - "2.5.4.57": "attributeIntegrityInfo", - "2.5.4.58": "attributeCertificate", - "2.5.4.59": "attributeCertificateRevocationList", - "2.5.4.60": "confKeyInfo", - "2.5.4.61": "aACertificate", - "2.5.4.62": "attributeDescriptorCertificate", - "2.5.4.63": "attributeAuthorityRevocationList", - "2.5.4.64": "family-information", - "2.5.4.65": "pseudonym", - "2.5.4.66": "communicationsService", - "2.5.4.67": "communicationsNetwork", - "2.5.4.68": "certificationPracticeStmt", - "2.5.4.69": "certificatePolicy", - "2.5.4.70": "pkiPath", - "2.5.4.71": "privPolicy", - "2.5.4.72": "role", - "2.5.4.73": "delegationPath", - "2.5.4.74": "protPrivPolicy", - "2.5.4.75": "xMLPrivilegeInfo", - "2.5.4.76": "xmlPrivPolicy", - "2.5.4.77": "uuidpair", - "2.5.4.78": "tagOid", - "2.5.4.79": "uiiFormat", - "2.5.4.80": "uiiInUrh", - "2.5.4.81": "contentUrl", - "2.5.4.82": "permission", - "2.5.4.83": "uri", - "2.5.4.84": "pwdAttribute", - "2.5.4.85": "userPwd", - "2.5.4.86": "urn", - "2.5.4.87": "url", - "2.5.4.88": "utmCoordinates", - "2.5.4.89": "urnC", - "2.5.4.90": "uii", - "2.5.4.91": "epc", - "2.5.4.92": "tagAfi", - "2.5.4.93": "epcFormat", - "2.5.4.94": "epcInUrn", - "2.5.4.95": "ldapUrl", - "2.5.4.96": "ldapUrl", - "2.5.4.97": "organizationIdentifier" -} - -certificateExtension_oids = { - "2.5.29.1": "authorityKeyIdentifier", - "2.5.29.2": "keyAttributes", - "2.5.29.3": "certificatePolicies", - "2.5.29.4": "keyUsageRestriction", - "2.5.29.5": "policyMapping", - "2.5.29.6": "subtreesConstraint", - "2.5.29.7": "subjectAltName", - "2.5.29.8": "issuerAltName", - "2.5.29.9": "subjectDirectoryAttributes", - "2.5.29.10": "basicConstraints", - "2.5.29.14": "subjectKeyIdentifier", - "2.5.29.15": "keyUsage", - "2.5.29.16": "privateKeyUsagePeriod", - "2.5.29.17": "subjectAltName", - "2.5.29.18": "issuerAltName", - "2.5.29.19": "basicConstraints", - "2.5.29.20": "cRLNumber", - "2.5.29.21": "reasonCode", - "2.5.29.22": "expirationDate", - "2.5.29.23": "instructionCode", - "2.5.29.24": "invalidityDate", - "2.5.29.25": "cRLDistributionPoints", - "2.5.29.26": "issuingDistributionPoint", - "2.5.29.27": "deltaCRLIndicator", - "2.5.29.28": "issuingDistributionPoint", - "2.5.29.29": "certificateIssuer", - "2.5.29.30": "nameConstraints", - "2.5.29.31": "cRLDistributionPoints", - "2.5.29.32": "certificatePolicies", - "2.5.29.33": "policyMappings", - "2.5.29.34": "policyConstraints", - "2.5.29.35": "authorityKeyIdentifier", - "2.5.29.36": "policyConstraints", - "2.5.29.37": "extKeyUsage", - "2.5.29.38": "authorityAttributeIdentifier", - "2.5.29.39": "roleSpecCertIdentifier", - "2.5.29.40": "cRLStreamIdentifier", - "2.5.29.41": "basicAttConstraints", - "2.5.29.42": "delegatedNameConstraints", - "2.5.29.43": "timeSpecification", - "2.5.29.44": "cRLScope", - "2.5.29.45": "statusReferrals", - "2.5.29.46": "freshestCRL", - "2.5.29.47": "orderedList", - "2.5.29.48": "attributeDescriptor", - "2.5.29.49": "userNotice", - "2.5.29.50": "sOAIdentifier", - "2.5.29.51": "baseUpdateTime", - "2.5.29.52": "acceptableCertPolicies", - "2.5.29.53": "deltaInfo", - "2.5.29.54": "inhibitAnyPolicy", - "2.5.29.55": "targetInformation", - "2.5.29.56": "noRevAvail", - "2.5.29.57": "acceptablePrivilegePolicies", - "2.5.29.58": "id-ce-toBeRevoked", - "2.5.29.59": "id-ce-RevokedGroups", - "2.5.29.60": "id-ce-expiredCertsOnCRL", - "2.5.29.61": "indirectIssuer", - "2.5.29.62": "id-ce-noAssertion", - "2.5.29.63": "id-ce-aAissuingDistributionPoint", - "2.5.29.64": "id-ce-issuedOnBehaIFOF", - "2.5.29.65": "id-ce-singleUse", - "2.5.29.66": "id-ce-groupAC", - "2.5.29.67": "id-ce-allowedAttAss", - "2.5.29.68": "id-ce-attributeMappings", - "2.5.29.69": "id-ce-holderNameConstraints" -} - -certExt_oids = { - "2.16.840.1.113730.1.1": "cert-type", - "2.16.840.1.113730.1.2": "base-url", - "2.16.840.1.113730.1.3": "revocation-url", - "2.16.840.1.113730.1.4": "ca-revocation-url", - "2.16.840.1.113730.1.5": "ca-crl-url", - "2.16.840.1.113730.1.6": "ca-cert-url", - "2.16.840.1.113730.1.7": "renewal-url", - "2.16.840.1.113730.1.8": "ca-policy-url", - "2.16.840.1.113730.1.9": "homepage-url", - "2.16.840.1.113730.1.10": "entity-logo", - "2.16.840.1.113730.1.11": "user-picture", - "2.16.840.1.113730.1.12": "ssl-server-name", - "2.16.840.1.113730.1.13": "comment", - "2.16.840.1.113730.1.14": "lost-password-url", - "2.16.840.1.113730.1.15": "cert-renewal-time", - "2.16.840.1.113730.1.16": "aia", - "2.16.840.1.113730.1.17": "cert-scope-of-use", -} - -certPkixPe_oids = { - "1.3.6.1.5.5.7.1.1": "authorityInfoAccess", - "1.3.6.1.5.5.7.1.2": "biometricInfo", - "1.3.6.1.5.5.7.1.3": "qcStatements", - "1.3.6.1.5.5.7.1.4": "auditIdentity", - "1.3.6.1.5.5.7.1.6": "aaControls", - "1.3.6.1.5.5.7.1.10": "proxying", - "1.3.6.1.5.5.7.1.11": "subjectInfoAccess" -} - -certPkixQt_oids = { - "1.3.6.1.5.5.7.2.1": "cps", - "1.3.6.1.5.5.7.2.2": "unotice" -} - -certPkixKp_oids = { - "1.3.6.1.5.5.7.3.1": "serverAuth", - "1.3.6.1.5.5.7.3.2": "clientAuth", - "1.3.6.1.5.5.7.3.3": "codeSigning", - "1.3.6.1.5.5.7.3.4": "emailProtection", - "1.3.6.1.5.5.7.3.5": "ipsecEndSystem", - "1.3.6.1.5.5.7.3.6": "ipsecTunnel", - "1.3.6.1.5.5.7.3.7": "ipsecUser", - "1.3.6.1.5.5.7.3.8": "timeStamping", - "1.3.6.1.5.5.7.3.9": "ocspSigning", - "1.3.6.1.5.5.7.3.10": "dvcs", - "1.3.6.1.5.5.7.3.21": "secureShellClient", - "1.3.6.1.5.5.7.3.22": "secureShellServer" -} - -certPkixAd_oids = { - "1.3.6.1.5.5.7.48.1": "ocsp", - "1.3.6.1.5.5.7.48.2": "caIssuers", - "1.3.6.1.5.5.7.48.3": "timestamping", - "1.3.6.1.5.5.7.48.4": "id-ad-dvcs", - "1.3.6.1.5.5.7.48.5": "id-ad-caRepository", - "1.3.6.1.5.5.7.48.6": "id-pkix-ocsp-archive-cutoff", - "1.3.6.1.5.5.7.48.7": "id-pkix-ocsp-service-locator", - "1.3.6.1.5.5.7.48.12": "id-ad-cmc", - "1.3.6.1.5.5.7.48.1.1": "basic-response" -} - -# ansi-x962 # - -x962KeyType_oids = { - "1.2.840.10045.1.1": "prime-field", - "1.2.840.10045.1.2": "characteristic-two-field", - "1.2.840.10045.2.1": "ecPublicKey", -} - -x962Signature_oids = { - "1.2.840.10045.4.1": "ecdsa-with-SHA1", - "1.2.840.10045.4.2": "ecdsa-with-Recommended", - "1.2.840.10045.4.3.1": "ecdsa-with-SHA224", - "1.2.840.10045.4.3.2": "ecdsa-with-SHA256", - "1.2.840.10045.4.3.3": "ecdsa-with-SHA384", - "1.2.840.10045.4.3.4": "ecdsa-with-SHA512" -} - -# elliptic curves # - -ansiX962Curve_oids = { - "1.2.840.10045.3.1.1": "prime192v1", - "1.2.840.10045.3.1.2": "prime192v2", - "1.2.840.10045.3.1.3": "prime192v3", - "1.2.840.10045.3.1.4": "prime239v1", - "1.2.840.10045.3.1.5": "prime239v2", - "1.2.840.10045.3.1.6": "prime239v3", - "1.2.840.10045.3.1.7": "prime256v1" -} - -certicomCurve_oids = { - "1.3.132.0.1": "ansit163k1", - "1.3.132.0.2": "ansit163r1", - "1.3.132.0.3": "ansit239k1", - "1.3.132.0.4": "sect113r1", - "1.3.132.0.5": "sect113r2", - "1.3.132.0.6": "secp112r1", - "1.3.132.0.7": "secp112r2", - "1.3.132.0.8": "ansip160r1", - "1.3.132.0.9": "ansip160k1", - "1.3.132.0.10": "ansip256k1", - "1.3.132.0.15": "ansit163r2", - "1.3.132.0.16": "ansit283k1", - "1.3.132.0.17": "ansit283r1", - "1.3.132.0.22": "sect131r1", - "1.3.132.0.24": "ansit193r1", - "1.3.132.0.25": "ansit193r2", - "1.3.132.0.26": "ansit233k1", - "1.3.132.0.27": "ansit233r1", - "1.3.132.0.28": "secp128r1", - "1.3.132.0.29": "secp128r2", - "1.3.132.0.30": "ansip160r2", - "1.3.132.0.31": "ansip192k1", - "1.3.132.0.32": "ansip224k1", - "1.3.132.0.33": "ansip224r1", - "1.3.132.0.34": "ansip384r1", - "1.3.132.0.35": "ansip521r1", - "1.3.132.0.36": "ansit409k1", - "1.3.132.0.37": "ansit409r1", - "1.3.132.0.38": "ansit571k1", - "1.3.132.0.39": "ansit571r1" -} - -# policies # - -certPolicy_oids = { - "anyPolicy": "2.5.29.32.0" -} - -# from Chromium source code (ev_root_ca_metadata.cc) -evPolicy_oids = { - '1.2.392.200091.100.721.1': 'EV Security Communication RootCA1', - '1.2.616.1.113527.2.5.1.1': 'EV Certum Trusted Network CA', - '1.3.159.1.17.1': 'EV Actualis Authentication Root CA', - '1.3.6.1.4.1.13177.10.1.3.10': 'EV Autoridad de Certificacion Firmaprofesional CIF A62634068', # noqa: E501 - '1.3.6.1.4.1.14370.1.6': 'EV GeoTrust Primary Certification Authority', - '1.3.6.1.4.1.14777.6.1.1': 'EV Izenpe.com roots Business', - '1.3.6.1.4.1.14777.6.1.2': 'EV Izenpe.com roots Government', - '1.3.6.1.4.1.17326.10.14.2.1.2': 'EV AC Camerfirma S.A. Chambers of Commerce Root - 2008', # noqa: E501 - '1.3.6.1.4.1.17326.10.14.2.2.2': 'EV AC Camerfirma S.A. Chambers of Commerce Root - 2008', # noqa: E501 - '1.3.6.1.4.1.17326.10.8.12.1.2': 'EV AC Camerfirma S.A. Global Chambersign Root - 2008', # noqa: E501 - '1.3.6.1.4.1.17326.10.8.12.2.2': 'EV AC Camerfirma S.A. Global Chambersign Root - 2008', # noqa: E501 - '1.3.6.1.4.1.22234.2.5.2.3.1': 'EV CertPlus Class 2 Primary CA (KEYNECTIS)', # noqa: E501 - '1.3.6.1.4.1.23223.1.1.1': 'EV StartCom Certification Authority', - '1.3.6.1.4.1.29836.1.10': 'EV China Internet Network Information Center EV Certificates Root', # noqa: E501 - '1.3.6.1.4.1.311.60.2.1.1': 'jurisdictionOfIncorporationLocalityName', - '1.3.6.1.4.1.311.60.2.1.2': 'jurisdictionOfIncorporationStateOrProvinceName', # noqa: E501 - '1.3.6.1.4.1.311.60.2.1.3': 'jurisdictionOfIncorporationCountryName', - '1.3.6.1.4.1.34697.2.1': 'EV AffirmTrust Commercial', - '1.3.6.1.4.1.34697.2.2': 'EV AffirmTrust Networking', - '1.3.6.1.4.1.34697.2.3': 'EV AffirmTrust Premium', - '1.3.6.1.4.1.34697.2.4': 'EV AffirmTrust Premium ECC', - '1.3.6.1.4.1.36305.2': 'EV Certificate Authority of WoSign', - '1.3.6.1.4.1.40869.1.1.22.3': 'EV TWCA Roots', - '1.3.6.1.4.1.4146.1.1': 'EV GlobalSign Root CAs', - '1.3.6.1.4.1.4788.2.202.1': 'EV D-TRUST Root Class 3 CA 2 EV 2009', - '1.3.6.1.4.1.6334.1.100.1': 'EV Cybertrust Global Root', - '1.3.6.1.4.1.6449.1.2.1.5.1': 'EV USERTrust Certification Authorities', - '1.3.6.1.4.1.781.1.2.1.8.1': 'EV Network Solutions Certificate Authority', - '1.3.6.1.4.1.782.1.2.1.8.1': 'EV AddTrust External CA Root', - '1.3.6.1.4.1.7879.13.24.1': 'EV T-Telessec GlobalRoot Class 3', - '1.3.6.1.4.1.8024.0.2.100.1.2': 'EV QuoVadis Roots', - '2.16.528.1.1003.1.2.7': 'EV Staat der Nederlanden EV Root CA', - '2.16.578.1.26.1.3.3': 'EV Buypass Class 3', - '2.16.756.1.83.21.0': 'EV Swisscom Root EV CA 2', - '2.16.756.1.89.1.2.1.1': 'EV SwissSign Gold CA - G2', - '2.16.792.3.0.4.1.1.4': 'EV E-Tugra Certification Authority', - '2.16.840.1.113733.1.7.23.6': 'EV VeriSign Certification Authorities', - '2.16.840.1.113733.1.7.48.1': 'EV thawte CAs', - '2.16.840.1.114028.10.1.2': 'EV Entrust Certification Authority', - '2.16.840.1.114171.500.9': 'EV Wells Fargo WellsSecure Public Root Certification Authority', # noqa: E501 - '2.16.840.1.114404.1.1.2.4.1': 'EV XRamp Global Certification Authority', - '2.16.840.1.114412.2.1': 'EV DigiCert High Assurance EV Root CA', - '2.16.840.1.114413.1.7.23.3': 'EV ValiCert Class 2 Policy Validation Authority', # noqa: E501 - '2.16.840.1.114414.1.7.23.3': 'EV Starfield Certificate Authority', - '2.16.840.1.114414.1.7.24.3': 'EV Starfield Service Certificate Authority' # noqa: E501 -} - - -x509_oids_sets = [ - pkcs1_oids, - secsig_oids, - pkcs9_oids, - attributeType_oids, - certificateExtension_oids, - certExt_oids, - certPkixPe_oids, - certPkixQt_oids, - certPkixKp_oids, - certPkixAd_oids, - certPolicy_oids, - evPolicy_oids, - x962KeyType_oids, - x962Signature_oids, - ansiX962Curve_oids, - certicomCurve_oids -] - -x509_oids = {} - -for oids_set in x509_oids_sets: - x509_oids.update(oids_set) - -conf.mib = MIBDict(_name="MIB", **x509_oids) - - -######################### -# Hash mapping helper # -######################### - -# This dict enables static access to string references to the hash functions -# of some algorithms from pkcs1_oids and x962Signature_oids. - -hash_by_oid = { - "1.2.840.113549.1.1.2": "md2", - "1.2.840.113549.1.1.3": "md4", - "1.2.840.113549.1.1.4": "md5", - "1.2.840.113549.1.1.5": "sha1", - "1.2.840.113549.1.1.11": "sha256", - "1.2.840.113549.1.1.12": "sha384", - "1.2.840.113549.1.1.13": "sha512", - "1.2.840.113549.1.1.14": "sha224", - "1.2.840.10045.4.1": "sha1", - "1.2.840.10045.4.3.1": "sha224", - "1.2.840.10045.4.3.2": "sha256", - "1.2.840.10045.4.3.3": "sha384", - "1.2.840.10045.4.3.4": "sha512" -} diff --git a/scripts/external_libs/scapy-2.4.3/scapy/asn1fields.py b/scripts/external_libs/scapy-2.4.3/scapy/asn1fields.py deleted file mode 100644 index 0e01b7e6b1..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/asn1fields.py +++ /dev/null @@ -1,668 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Enhanced by Maxence Tury -# This program is published under a GPLv2 license - -""" -Classes that implement ASN.1 data structures. -""" - -from __future__ import absolute_import -from scapy.asn1.asn1 import ASN1_Class_UNIVERSAL, ASN1_NULL, ASN1_Error, \ - ASN1_Object, ASN1_INTEGER -from scapy.asn1.ber import BER_tagging_dec, BER_Decoding_Error, BER_id_dec, \ - BER_tagging_enc -from scapy.volatile import RandInt, RandChoice, RandNum, RandString, RandOID, \ - GeneralizedTime -from scapy.compat import orb, raw -from scapy.base_classes import BasePacket -from scapy.utils import binrepr -from scapy import packet -from functools import reduce -import scapy.modules.six as six -from scapy.modules.six.moves import range - - -class ASN1F_badsequence(Exception): - pass - - -class ASN1F_element(object): - pass - - -########################## -# Basic ASN1 Field # -########################## - -class ASN1F_field(ASN1F_element): - holds_packets = 0 - islist = 0 - ASN1_tag = ASN1_Class_UNIVERSAL.ANY - context = ASN1_Class_UNIVERSAL - - def __init__(self, name, default, context=None, - implicit_tag=None, explicit_tag=None, - flexible_tag=False): - self.context = context - self.name = name - if default is None: - self.default = None - elif isinstance(default, ASN1_NULL): - self.default = default - else: - self.default = self.ASN1_tag.asn1_object(default) - self.flexible_tag = flexible_tag - if (implicit_tag is not None) and (explicit_tag is not None): - err_msg = "field cannot be both implicitly and explicitly tagged" - raise ASN1_Error(err_msg) - self.implicit_tag = implicit_tag - self.explicit_tag = explicit_tag - # network_tag gets useful for ASN1F_CHOICE - self.network_tag = implicit_tag or explicit_tag or self.ASN1_tag - - def i2repr(self, pkt, x): - return repr(x) - - def i2h(self, pkt, x): - return x - - def any2i(self, pkt, x): - return x - - def m2i(self, pkt, s): - """ - The good thing about safedec is that it may still decode ASN1 - even if there is a mismatch between the expected tag (self.ASN1_tag) - and the actual tag; the decoded ASN1 object will simply be put - into an ASN1_BADTAG object. However, safedec prevents the raising of - exceptions needed for ASN1F_optional processing. - Thus we use 'flexible_tag', which should be False with ASN1F_optional. - - Regarding other fields, we might need to know whether encoding went - as expected or not. Noticeably, input methods from cert.py expect - certain exceptions to be raised. Hence default flexible_tag is False. - """ - diff_tag, s = BER_tagging_dec(s, hidden_tag=self.ASN1_tag, - implicit_tag=self.implicit_tag, - explicit_tag=self.explicit_tag, - safe=self.flexible_tag) - if diff_tag is not None: - # this implies that flexible_tag was True - if self.implicit_tag is not None: - self.implicit_tag = diff_tag - elif self.explicit_tag is not None: - self.explicit_tag = diff_tag - codec = self.ASN1_tag.get_codec(pkt.ASN1_codec) - if self.flexible_tag: - return codec.safedec(s, context=self.context) - else: - return codec.dec(s, context=self.context) - - def i2m(self, pkt, x): - if x is None: - return b"" - if isinstance(x, ASN1_Object): - if (self.ASN1_tag == ASN1_Class_UNIVERSAL.ANY or - x.tag == ASN1_Class_UNIVERSAL.RAW or - x.tag == ASN1_Class_UNIVERSAL.ERROR or - self.ASN1_tag == x.tag): - s = x.enc(pkt.ASN1_codec) - else: - raise ASN1_Error("Encoding Error: got %r instead of an %r for field [%s]" % (x, self.ASN1_tag, self.name)) # noqa: E501 - else: - s = self.ASN1_tag.get_codec(pkt.ASN1_codec).enc(x) - return BER_tagging_enc(s, implicit_tag=self.implicit_tag, - explicit_tag=self.explicit_tag) - - def extract_packet(self, cls, s): - if len(s) > 0: - try: - c = cls(s) - except ASN1F_badsequence: - c = packet.Raw(s) - cpad = c.getlayer(packet.Raw) - s = b"" - if cpad is not None: - s = cpad.load - del(cpad.underlayer.payload) - return c, s - else: - return None, s - - def build(self, pkt): - return self.i2m(pkt, getattr(pkt, self.name)) - - def dissect(self, pkt, s): - v, s = self.m2i(pkt, s) - self.set_val(pkt, v) - return s - - def do_copy(self, x): - if hasattr(x, "copy"): - return x.copy() - if isinstance(x, list): - x = x[:] - for i in range(len(x)): - if isinstance(x[i], BasePacket): - x[i] = x[i].copy() - return x - - def set_val(self, pkt, val): - setattr(pkt, self.name, val) - - def is_empty(self, pkt): - return getattr(pkt, self.name) is None - - def get_fields_list(self): - return [self] - - def __hash__(self): - return hash(self.name) - - def __str__(self): - return repr(self) - - def randval(self): - return RandInt() - - -############################ -# Simple ASN1 Fields # -############################ - -class ASN1F_BOOLEAN(ASN1F_field): - ASN1_tag = ASN1_Class_UNIVERSAL.BOOLEAN - - def randval(self): - return RandChoice(True, False) - - -class ASN1F_INTEGER(ASN1F_field): - ASN1_tag = ASN1_Class_UNIVERSAL.INTEGER - - def randval(self): - return RandNum(-2**64, 2**64 - 1) - - -class ASN1F_enum_INTEGER(ASN1F_INTEGER): - def __init__(self, name, default, enum, context=None, - implicit_tag=None, explicit_tag=None): - ASN1F_INTEGER.__init__(self, name, default, context=context, - implicit_tag=implicit_tag, - explicit_tag=explicit_tag) - i2s = self.i2s = {} - s2i = self.s2i = {} - if isinstance(enum, list): - keys = range(len(enum)) - else: - keys = list(enum) - if any(isinstance(x, six.string_types) for x in keys): - i2s, s2i = s2i, i2s - for k in keys: - i2s[k] = enum[k] - s2i[enum[k]] = k - - def i2m(self, pkt, s): - if isinstance(s, str): - s = self.s2i.get(s) - return super(ASN1F_enum_INTEGER, self).i2m(pkt, s) - - def i2repr(self, pkt, x): - if x is not None and isinstance(x, ASN1_INTEGER): - r = self.i2s.get(x.val) - if r: - return "'%s' %s" % (r, repr(x)) - return repr(x) - - -class ASN1F_BIT_STRING(ASN1F_field): - ASN1_tag = ASN1_Class_UNIVERSAL.BIT_STRING - - def __init__(self, name, default, default_readable=True, context=None, - implicit_tag=None, explicit_tag=None): - if default is not None and default_readable: - default = b"".join(binrepr(orb(x)).zfill(8).encode("utf8") for x in default) # noqa: E501 - ASN1F_field.__init__(self, name, default, context=context, - implicit_tag=implicit_tag, - explicit_tag=explicit_tag) - - def randval(self): - return RandString(RandNum(0, 1000)) - - -class ASN1F_STRING(ASN1F_field): - ASN1_tag = ASN1_Class_UNIVERSAL.STRING - - def randval(self): - return RandString(RandNum(0, 1000)) - - -class ASN1F_NULL(ASN1F_INTEGER): - ASN1_tag = ASN1_Class_UNIVERSAL.NULL - - -class ASN1F_OID(ASN1F_field): - ASN1_tag = ASN1_Class_UNIVERSAL.OID - - def randval(self): - return RandOID() - - -class ASN1F_ENUMERATED(ASN1F_enum_INTEGER): - ASN1_tag = ASN1_Class_UNIVERSAL.ENUMERATED - - -class ASN1F_UTF8_STRING(ASN1F_STRING): - ASN1_tag = ASN1_Class_UNIVERSAL.UTF8_STRING - - -class ASN1F_NUMERIC_STRING(ASN1F_STRING): - ASN1_tag = ASN1_Class_UNIVERSAL.NUMERIC_STRING - - -class ASN1F_PRINTABLE_STRING(ASN1F_STRING): - ASN1_tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING - - -class ASN1F_T61_STRING(ASN1F_STRING): - ASN1_tag = ASN1_Class_UNIVERSAL.T61_STRING - - -class ASN1F_VIDEOTEX_STRING(ASN1F_STRING): - ASN1_tag = ASN1_Class_UNIVERSAL.VIDEOTEX_STRING - - -class ASN1F_IA5_STRING(ASN1F_STRING): - ASN1_tag = ASN1_Class_UNIVERSAL.IA5_STRING - - -class ASN1F_UTC_TIME(ASN1F_STRING): - ASN1_tag = ASN1_Class_UNIVERSAL.UTC_TIME - - def randval(self): - return GeneralizedTime() - - -class ASN1F_GENERALIZED_TIME(ASN1F_STRING): - ASN1_tag = ASN1_Class_UNIVERSAL.GENERALIZED_TIME - - def randval(self): - return GeneralizedTime() - - -class ASN1F_ISO646_STRING(ASN1F_STRING): - ASN1_tag = ASN1_Class_UNIVERSAL.ISO646_STRING - - -class ASN1F_UNIVERSAL_STRING(ASN1F_STRING): - ASN1_tag = ASN1_Class_UNIVERSAL.UNIVERSAL_STRING - - -class ASN1F_BMP_STRING(ASN1F_STRING): - ASN1_tag = ASN1_Class_UNIVERSAL.BMP_STRING - - -class ASN1F_SEQUENCE(ASN1F_field): - # Here is how you could decode a SEQUENCE - # with an unknown, private high-tag prefix : - # class PrivSeq(ASN1_Packet): - # ASN1_codec = ASN1_Codecs.BER - # ASN1_root = ASN1F_SEQUENCE( - # , - # ... - # , - # explicit_tag=0, - # flexible_tag=True) - # Because we use flexible_tag, the value of the explicit_tag does not matter. # noqa: E501 - ASN1_tag = ASN1_Class_UNIVERSAL.SEQUENCE - holds_packets = 1 - - def __init__(self, *seq, **kwargs): - name = "dummy_seq_name" - default = [field.default for field in seq] - for kwarg in ["context", "implicit_tag", - "explicit_tag", "flexible_tag"]: - setattr(self, kwarg, kwargs.get(kwarg)) - ASN1F_field.__init__(self, name, default, context=self.context, - implicit_tag=self.implicit_tag, - explicit_tag=self.explicit_tag, - flexible_tag=self.flexible_tag) - self.seq = seq - self.islist = len(seq) > 1 - - def __repr__(self): - return "<%s%r>" % (self.__class__.__name__, self.seq) - - def is_empty(self, pkt): - return all(f.is_empty(pkt) for f in self.seq) - - def get_fields_list(self): - return reduce(lambda x, y: x + y.get_fields_list(), self.seq, []) - - def m2i(self, pkt, s): - """ - ASN1F_SEQUENCE behaves transparently, with nested ASN1_objects being - dissected one by one. Because we use obj.dissect (see loop below) - instead of obj.m2i (as we trust dissect to do the appropriate set_vals) - we do not directly retrieve the list of nested objects. - Thus m2i returns an empty list (along with the proper remainder). - It is discarded by dissect() and should not be missed elsewhere. - """ - diff_tag, s = BER_tagging_dec(s, hidden_tag=self.ASN1_tag, - implicit_tag=self.implicit_tag, - explicit_tag=self.explicit_tag, - safe=self.flexible_tag) - if diff_tag is not None: - if self.implicit_tag is not None: - self.implicit_tag = diff_tag - elif self.explicit_tag is not None: - self.explicit_tag = diff_tag - codec = self.ASN1_tag.get_codec(pkt.ASN1_codec) - i, s, remain = codec.check_type_check_len(s) - if len(s) == 0: - for obj in self.seq: - obj.set_val(pkt, None) - else: - for obj in self.seq: - try: - s = obj.dissect(pkt, s) - except ASN1F_badsequence: - break - if len(s) > 0: - raise BER_Decoding_Error("unexpected remainder", remaining=s) - return [], remain - - def dissect(self, pkt, s): - _, x = self.m2i(pkt, s) - return x - - def build(self, pkt): - s = reduce(lambda x, y: x + y.build(pkt), self.seq, b"") - return self.i2m(pkt, s) - - -class ASN1F_SET(ASN1F_SEQUENCE): - ASN1_tag = ASN1_Class_UNIVERSAL.SET - - -class ASN1F_SEQUENCE_OF(ASN1F_field): - ASN1_tag = ASN1_Class_UNIVERSAL.SEQUENCE - holds_packets = 1 - islist = 1 - - def __init__(self, name, default, cls, context=None, - implicit_tag=None, explicit_tag=None): - self.cls = cls - ASN1F_field.__init__(self, name, None, context=context, - implicit_tag=implicit_tag, explicit_tag=explicit_tag) # noqa: E501 - self.default = default - - def is_empty(self, pkt): - return ASN1F_field.is_empty(self, pkt) - - def m2i(self, pkt, s): - diff_tag, s = BER_tagging_dec(s, hidden_tag=self.ASN1_tag, - implicit_tag=self.implicit_tag, - explicit_tag=self.explicit_tag, - safe=self.flexible_tag) - if diff_tag is not None: - if self.implicit_tag is not None: - self.implicit_tag = diff_tag - elif self.explicit_tag is not None: - self.explicit_tag = diff_tag - codec = self.ASN1_tag.get_codec(pkt.ASN1_codec) - i, s, remain = codec.check_type_check_len(s) - lst = [] - while s: - c, s = self.extract_packet(self.cls, s) - lst.append(c) - if len(s) > 0: - raise BER_Decoding_Error("unexpected remainder", remaining=s) - return lst, remain - - def build(self, pkt): - val = getattr(pkt, self.name) - if isinstance(val, ASN1_Object) and val.tag == ASN1_Class_UNIVERSAL.RAW: # noqa: E501 - s = val - elif val is None: - s = b"" - else: - s = b"".join(raw(i) for i in val) - return self.i2m(pkt, s) - - def randval(self): - return packet.fuzz(self.cls()) - - def __repr__(self): - return "<%s %s>" % (self.__class__.__name__, self.name) - - -class ASN1F_SET_OF(ASN1F_SEQUENCE_OF): - ASN1_tag = ASN1_Class_UNIVERSAL.SET - - -class ASN1F_IPADDRESS(ASN1F_STRING): - ASN1_tag = ASN1_Class_UNIVERSAL.IPADDRESS - - -class ASN1F_TIME_TICKS(ASN1F_INTEGER): - ASN1_tag = ASN1_Class_UNIVERSAL.TIME_TICKS - - -############################# -# Complex ASN1 Fields # -############################# - -class ASN1F_optional(ASN1F_element): - def __init__(self, field): - field.flexible_tag = False - self._field = field - - def __getattr__(self, attr): - return getattr(self._field, attr) - - def m2i(self, pkt, s): - try: - return self._field.m2i(pkt, s) - except (ASN1_Error, ASN1F_badsequence, BER_Decoding_Error): - # ASN1_Error may be raised by ASN1F_CHOICE - return None, s - - def dissect(self, pkt, s): - try: - return self._field.dissect(pkt, s) - except (ASN1_Error, ASN1F_badsequence, BER_Decoding_Error): - self._field.set_val(pkt, None) - return s - - def build(self, pkt): - if self._field.is_empty(pkt): - return b"" - return self._field.build(pkt) - - def any2i(self, pkt, x): - return self._field.any2i(pkt, x) - - def i2repr(self, pkt, x): - return self._field.i2repr(pkt, x) - - -class ASN1F_CHOICE(ASN1F_field): - """ - Multiple types are allowed: ASN1_Packet, ASN1F_field and ASN1F_PACKET(), - See layers/x509.py for examples. - Other ASN1F_field instances than ASN1F_PACKET instances must not be used. - """ - holds_packets = 1 - ASN1_tag = ASN1_Class_UNIVERSAL.ANY - - def __init__(self, name, default, *args, **kwargs): - if "implicit_tag" in kwargs: - err_msg = "ASN1F_CHOICE has been called with an implicit_tag" - raise ASN1_Error(err_msg) - self.implicit_tag = None - for kwarg in ["context", "explicit_tag"]: - setattr(self, kwarg, kwargs.get(kwarg)) - ASN1F_field.__init__(self, name, None, context=self.context, - explicit_tag=self.explicit_tag) - self.default = default - self.current_choice = None - self.choices = {} - self.pktchoices = {} - for p in args: - if hasattr(p, "ASN1_root"): # should be ASN1_Packet - if hasattr(p.ASN1_root, "choices"): - for k, v in six.iteritems(p.ASN1_root.choices): - self.choices[k] = v # ASN1F_CHOICE recursion - else: - self.choices[p.ASN1_root.network_tag] = p - elif hasattr(p, "ASN1_tag"): - if isinstance(p, type): # should be ASN1F_field class - self.choices[p.ASN1_tag] = p - else: # should be ASN1F_PACKET instance - self.choices[p.network_tag] = p - self.pktchoices[hash(p.cls)] = (p.implicit_tag, p.explicit_tag) # noqa: E501 - else: - raise ASN1_Error("ASN1F_CHOICE: no tag found for one field") - - def m2i(self, pkt, s): - """ - First we have to retrieve the appropriate choice. - Then we extract the field/packet, according to this choice. - """ - if len(s) == 0: - raise ASN1_Error("ASN1F_CHOICE: got empty string") - _, s = BER_tagging_dec(s, hidden_tag=self.ASN1_tag, - explicit_tag=self.explicit_tag) - tag, _ = BER_id_dec(s) - if tag not in self.choices: - if self.flexible_tag: - choice = ASN1F_field - else: - raise ASN1_Error("ASN1F_CHOICE: unexpected field") - else: - choice = self.choices[tag] - if hasattr(choice, "ASN1_root"): - # we don't want to import ASN1_Packet in this module... - return self.extract_packet(choice, s) - elif isinstance(choice, type): - # XXX find a way not to instantiate the ASN1F_field - return choice(self.name, b"").m2i(pkt, s) - else: - # XXX check properly if this is an ASN1F_PACKET - return choice.m2i(pkt, s) - - def i2m(self, pkt, x): - if x is None: - s = b"" - else: - s = raw(x) - if hash(type(x)) in self.pktchoices: - imp, exp = self.pktchoices[hash(type(x))] - s = BER_tagging_enc(s, implicit_tag=imp, - explicit_tag=exp) - return BER_tagging_enc(s, explicit_tag=self.explicit_tag) - - def randval(self): - randchoices = [] - for p in six.itervalues(self.choices): - if hasattr(p, "ASN1_root"): # should be ASN1_Packet class - randchoices.append(packet.fuzz(p())) - elif hasattr(p, "ASN1_tag"): - if isinstance(p, type): # should be (basic) ASN1F_field class # noqa: E501 - randchoices.append(p("dummy", None).randval()) - else: # should be ASN1F_PACKET instance - randchoices.append(p.randval()) - return RandChoice(*randchoices) - - -class ASN1F_PACKET(ASN1F_field): - holds_packets = 1 - - def __init__(self, name, default, cls, context=None, - implicit_tag=None, explicit_tag=None): - self.cls = cls - ASN1F_field.__init__(self, name, None, context=context, - implicit_tag=implicit_tag, explicit_tag=explicit_tag) # noqa: E501 - if cls.ASN1_root.ASN1_tag == ASN1_Class_UNIVERSAL.SEQUENCE: - if implicit_tag is None and explicit_tag is None: - self.network_tag = 16 | 0x20 - self.default = default - - def m2i(self, pkt, s): - diff_tag, s = BER_tagging_dec(s, hidden_tag=self.cls.ASN1_root.ASN1_tag, # noqa: E501 - implicit_tag=self.implicit_tag, - explicit_tag=self.explicit_tag, - safe=self.flexible_tag) - if diff_tag is not None: - if self.implicit_tag is not None: - self.implicit_tag = diff_tag - elif self.explicit_tag is not None: - self.explicit_tag = diff_tag - p, s = self.extract_packet(self.cls, s) - return p, s - - def i2m(self, pkt, x): - if x is None: - s = b"" - else: - s = raw(x) - return BER_tagging_enc(s, implicit_tag=self.implicit_tag, - explicit_tag=self.explicit_tag) - - def randval(self): - return packet.fuzz(self.cls()) - - -class ASN1F_BIT_STRING_ENCAPS(ASN1F_BIT_STRING): - """ - We may emulate simple string encapsulation with explicit_tag=0x04, - but we need a specific class for bit strings because of unused bits, etc. - """ - holds_packets = 1 - - def __init__(self, name, default, cls, context=None, - implicit_tag=None, explicit_tag=None): - self.cls = cls - ASN1F_BIT_STRING.__init__(self, name, None, context=context, - implicit_tag=implicit_tag, - explicit_tag=explicit_tag) - self.default = default - - def m2i(self, pkt, s): - bit_string, remain = ASN1F_BIT_STRING.m2i(self, pkt, s) - if len(bit_string.val) % 8 != 0: - raise BER_Decoding_Error("wrong bit string", remaining=s) - p, s = self.extract_packet(self.cls, bit_string.val_readable) - if len(s) > 0: - raise BER_Decoding_Error("unexpected remainder", remaining=s) - return p, remain - - def i2m(self, pkt, x): - s = b"" if x is None else raw(x) - s = b"".join(binrepr(orb(x)).zfill(8).encode("utf8") for x in s) - return ASN1F_BIT_STRING.i2m(self, pkt, s) - - -class ASN1F_FLAGS(ASN1F_BIT_STRING): - def __init__(self, name, default, mapping, context=None, - implicit_tag=None, explicit_tag=None): - self.mapping = mapping - ASN1F_BIT_STRING.__init__(self, name, default, - default_readable=False, - context=context, - implicit_tag=implicit_tag, - explicit_tag=explicit_tag) - - def get_flags(self, pkt): - fbytes = getattr(pkt, self.name).val - return [self.mapping[i] for i, positional in enumerate(fbytes) - if positional == '1' and i < len(self.mapping)] - - def i2repr(self, pkt, x): - if x is not None: - pretty_s = ", ".join(self.get_flags(pkt)) - return pretty_s + " " + repr(x) - return repr(x) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/asn1packet.py b/scripts/external_libs/scapy-2.4.3/scapy/asn1packet.py deleted file mode 100644 index 759ec58f68..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/asn1packet.py +++ /dev/null @@ -1,35 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -ASN.1 Packet - -Packet holding data in Abstract Syntax Notation (ASN.1). -""" - -from __future__ import absolute_import -from scapy.base_classes import Packet_metaclass -from scapy.packet import Packet -import scapy.modules.six as six - - -class ASN1Packet_metaclass(Packet_metaclass): - def __new__(cls, name, bases, dct): - if dct["ASN1_root"] is not None: - dct["fields_desc"] = dct["ASN1_root"].get_fields_list() - return super(ASN1Packet_metaclass, cls).__new__(cls, name, bases, dct) - - -class ASN1_Packet(six.with_metaclass(ASN1Packet_metaclass, Packet)): - ASN1_root = None - ASN1_codec = None - - def self_build(self): - if self.raw_packet_cache is not None: - return self.raw_packet_cache - return self.ASN1_root.build(self) - - def do_dissect(self, x): - return self.ASN1_root.dissect(self, x) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/automaton.py b/scripts/external_libs/scapy-2.4.3/scapy/automaton.py deleted file mode 100644 index 344c45e85d..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/automaton.py +++ /dev/null @@ -1,1029 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Copyright (C) Gabriel Potter -# This program is published under a GPLv2 license - -""" -Automata with states, transitions and actions. -""" - -from __future__ import absolute_import -import types -import itertools -import time -import os -import sys -import traceback -from select import select -from collections import deque -import threading -from scapy.config import conf -from scapy.utils import do_graph -from scapy.error import log_interactive, warning -from scapy.plist import PacketList -from scapy.data import MTU -from scapy.supersocket import SuperSocket -from scapy.consts import WINDOWS -import scapy.modules.six as six - -if WINDOWS: - from scapy.error import Scapy_Exception - recv_error = Scapy_Exception -else: - recv_error = () - -""" In Windows, select.select is not available for custom objects. Here's the implementation of scapy to re-create this functionality # noqa: E501 -# Passive way: using no-ressources locks - +---------+ +---------------+ +-------------------------+ # noqa: E501 - | Start +------------->Select_objects +----->+Linux: call select.select| # noqa: E501 - +---------+ |(select.select)| +-------------------------+ # noqa: E501 - +-------+-------+ - | - +----v----+ +--------+ - | Windows | |Time Out+----------------------------------+ # noqa: E501 - +----+----+ +----+---+ | # noqa: E501 - | ^ | # noqa: E501 - Event | | | # noqa: E501 - + | | | # noqa: E501 - | +-------v-------+ | | # noqa: E501 - | +------+Selectable Sel.+-----+-----------------+-----------+ | # noqa: E501 - | | +-------+-------+ | | | v +-----v-----+ # noqa: E501 -+-------v----------+ | | | | | Passive lock<-----+release_all<------+ # noqa: E501 -|Data added to list| +----v-----+ +-----v-----+ +----v-----+ v v + +-----------+ | # noqa: E501 -+--------+---------+ |Selectable| |Selectable | |Selectable| ............ | | # noqa: E501 - | +----+-----+ +-----------+ +----------+ | | # noqa: E501 - | v | | # noqa: E501 - v +----+------+ +------------------+ +-------------v-------------------+ | # noqa: E501 - +-----+------+ |wait_return+-->+ check_recv: | | | | # noqa: E501 - |call_release| +----+------+ |If data is in list| | END state: selectable returned | +---+--------+ # noqa: E501 - +-----+-------- v +-------+----------+ | | | exit door | # noqa: E501 - | else | +---------------------------------+ +---+--------+ # noqa: E501 - | + | | # noqa: E501 - | +----v-------+ | | # noqa: E501 - +--------->free -->Passive lock| | | # noqa: E501 - +----+-------+ | | # noqa: E501 - | | | # noqa: E501 - | v | # noqa: E501 - +------------------Selectable-Selector-is-advertised-that-the-selectable-is-readable---------+ -""" - - -class SelectableObject(object): - """DEV: to implement one of those, you need to add 2 things to your object: - - add "check_recv" function - - call "self.call_release" once you are ready to be read - - You can set the __selectable_force_select__ to True in the class, if you want to # noqa: E501 - force the handler to use fileno(). This may only be usable on sockets created using # noqa: E501 - the builtin socket API.""" - __selectable_force_select__ = False - - def __init__(self): - self.hooks = [] - - def check_recv(self): - """DEV: will be called only once (at beginning) to check if the object is ready.""" # noqa: E501 - raise OSError("This method must be overwritten.") - - def _wait_non_ressources(self, callback): - """This get started as a thread, and waits for the data lock to be freed then advertise itself to the SelectableSelector using the callback""" # noqa: E501 - self.trigger = threading.Lock() - self.was_ended = False - self.trigger.acquire() - self.trigger.acquire() - if not self.was_ended: - callback(self) - - def wait_return(self, callback): - """Entry point of SelectableObject: register the callback""" - if self.check_recv(): - return callback(self) - _t = threading.Thread(target=self._wait_non_ressources, args=(callback,)) # noqa: E501 - _t.setDaemon(True) - _t.start() - - def register_hook(self, hook): - """DEV: When call_release() will be called, the hook will also""" - self.hooks.append(hook) - - def call_release(self, arborted=False): - """DEV: Must be call when the object becomes ready to read. - Relesases the lock of _wait_non_ressources""" - self.was_ended = arborted - try: - self.trigger.release() - except (threading.ThreadError, AttributeError): - pass - # Trigger hooks - for hook in self.hooks: - hook() - - -class SelectableSelector(object): - """ - Select SelectableObject objects. - - inputs: objects to process - remain: timeout. If 0, return []. - customTypes: types of the objects that have the check_recv function. - """ - - def _release_all(self): - """Releases all locks to kill all threads""" - for i in self.inputs: - i.call_release(True) - self.available_lock.release() - - def _timeout_thread(self, remain): - """Timeout before releasing every thing, if nothing was returned""" - time.sleep(remain) - if not self._ended: - self._ended = True - self._release_all() - - def _exit_door(self, _input): - """This function is passed to each SelectableObject as a callback - The SelectableObjects have to call it once there are ready""" - self.results.append(_input) - if self._ended: - return - self._ended = True - self._release_all() - - def __init__(self, inputs, remain): - self.results = [] - self.inputs = list(inputs) - self.remain = remain - self.available_lock = threading.Lock() - self.available_lock.acquire() - self._ended = False - - def process(self): - """Entry point of SelectableSelector""" - if WINDOWS: - select_inputs = [] - for i in self.inputs: - if not isinstance(i, SelectableObject): - warning("Unknown ignored object type: %s", type(i)) - elif i.__selectable_force_select__: - # Then use select.select - select_inputs.append(i) - elif not self.remain and i.check_recv(): - self.results.append(i) - elif self.remain: - i.wait_return(self._exit_door) - if select_inputs: - # Use default select function - self.results.extend(select(select_inputs, [], [], self.remain)[0]) # noqa: E501 - if not self.remain: - return self.results - - threading.Thread(target=self._timeout_thread, args=(self.remain,)).start() # noqa: E501 - if not self._ended: - self.available_lock.acquire() - return self.results - else: - r, _, _ = select(self.inputs, [], [], self.remain) - return r - - -def select_objects(inputs, remain): - """ - Select SelectableObject objects. Same than: - select.select([inputs], [], [], remain) - But also works on Windows, only on SelectableObject. - - inputs: objects to process - remain: timeout. If 0, return []. - """ - handler = SelectableSelector(inputs, remain) - return handler.process() - - -class ObjectPipe(SelectableObject): - read_allowed_exceptions = () - - def __init__(self): - self.closed = False - self.rd, self.wr = os.pipe() - self.queue = deque() - SelectableObject.__init__(self) - - def fileno(self): - return self.rd - - def check_recv(self): - return len(self.queue) > 0 - - def send(self, obj): - self.queue.append(obj) - os.write(self.wr, b"X") - self.call_release() - - def write(self, obj): - self.send(obj) - - def recv(self, n=0): - if self.closed: - if self.check_recv(): - return self.queue.popleft() - return None - os.read(self.rd, 1) - return self.queue.popleft() - - def read(self, n=0): - return self.recv(n) - - def close(self): - if not self.closed: - self.closed = True - os.close(self.rd) - os.close(self.wr) - self.queue.clear() - - @staticmethod - def select(sockets, remain=conf.recv_poll_rate): - # Only handle ObjectPipes - results = [] - for s in sockets: - if s.closed: - results.append(s) - if results: - return results, None - return select_objects(sockets, remain), None - - -class Message: - def __init__(self, **args): - self.__dict__.update(args) - - def __repr__(self): - return "" % " ".join("%s=%r" % (k, v) - for (k, v) in six.iteritems(self.__dict__) # noqa: E501 - if not k.startswith("_")) - - -class _instance_state: - def __init__(self, instance): - self.__self__ = instance.__self__ - self.__func__ = instance.__func__ - self.__self__.__class__ = instance.__self__.__class__ - - def __getattr__(self, attr): - return getattr(self.__func__, attr) - - def __call__(self, *args, **kargs): - return self.__func__(self.__self__, *args, **kargs) - - def breaks(self): - return self.__self__.add_breakpoints(self.__func__) - - def intercepts(self): - return self.__self__.add_interception_points(self.__func__) - - def unbreaks(self): - return self.__self__.remove_breakpoints(self.__func__) - - def unintercepts(self): - return self.__self__.remove_interception_points(self.__func__) - - -############## -# Automata # -############## - -class ATMT: - STATE = "State" - ACTION = "Action" - CONDITION = "Condition" - RECV = "Receive condition" - TIMEOUT = "Timeout condition" - IOEVENT = "I/O event" - - class NewStateRequested(Exception): - def __init__(self, state_func, automaton, *args, **kargs): - self.func = state_func - self.state = state_func.atmt_state - self.initial = state_func.atmt_initial - self.error = state_func.atmt_error - self.final = state_func.atmt_final - Exception.__init__(self, "Request state [%s]" % self.state) - self.automaton = automaton - self.args = args - self.kargs = kargs - self.action_parameters() # init action parameters - - def action_parameters(self, *args, **kargs): - self.action_args = args - self.action_kargs = kargs - return self - - def run(self): - return self.func(self.automaton, *self.args, **self.kargs) - - def __repr__(self): - return "NewStateRequested(%s)" % self.state - - @staticmethod - def state(initial=0, final=0, error=0): - def deco(f, initial=initial, final=final): - f.atmt_type = ATMT.STATE - f.atmt_state = f.__name__ - f.atmt_initial = initial - f.atmt_final = final - f.atmt_error = error - - def state_wrapper(self, *args, **kargs): - return ATMT.NewStateRequested(f, self, *args, **kargs) - - state_wrapper.__name__ = "%s_wrapper" % f.__name__ - state_wrapper.atmt_type = ATMT.STATE - state_wrapper.atmt_state = f.__name__ - state_wrapper.atmt_initial = initial - state_wrapper.atmt_final = final - state_wrapper.atmt_error = error - state_wrapper.atmt_origfunc = f - return state_wrapper - return deco - - @staticmethod - def action(cond, prio=0): - def deco(f, cond=cond): - if not hasattr(f, "atmt_type"): - f.atmt_cond = {} - f.atmt_type = ATMT.ACTION - f.atmt_cond[cond.atmt_condname] = prio - return f - return deco - - @staticmethod - def condition(state, prio=0): - def deco(f, state=state): - f.atmt_type = ATMT.CONDITION - f.atmt_state = state.atmt_state - f.atmt_condname = f.__name__ - f.atmt_prio = prio - return f - return deco - - @staticmethod - def receive_condition(state, prio=0): - def deco(f, state=state): - f.atmt_type = ATMT.RECV - f.atmt_state = state.atmt_state - f.atmt_condname = f.__name__ - f.atmt_prio = prio - return f - return deco - - @staticmethod - def ioevent(state, name, prio=0, as_supersocket=None): - def deco(f, state=state): - f.atmt_type = ATMT.IOEVENT - f.atmt_state = state.atmt_state - f.atmt_condname = f.__name__ - f.atmt_ioname = name - f.atmt_prio = prio - f.atmt_as_supersocket = as_supersocket - return f - return deco - - @staticmethod - def timeout(state, timeout): - def deco(f, state=state, timeout=timeout): - f.atmt_type = ATMT.TIMEOUT - f.atmt_state = state.atmt_state - f.atmt_timeout = timeout - f.atmt_condname = f.__name__ - return f - return deco - - -class _ATMT_Command: - RUN = "RUN" - NEXT = "NEXT" - FREEZE = "FREEZE" - STOP = "STOP" - END = "END" - EXCEPTION = "EXCEPTION" - SINGLESTEP = "SINGLESTEP" - BREAKPOINT = "BREAKPOINT" - INTERCEPT = "INTERCEPT" - ACCEPT = "ACCEPT" - REPLACE = "REPLACE" - REJECT = "REJECT" - - -class _ATMT_supersocket(SuperSocket, SelectableObject): - def __init__(self, name, ioevent, automaton, proto, *args, **kargs): - SelectableObject.__init__(self) - self.name = name - self.ioevent = ioevent - self.proto = proto - # write, read - self.spa, self.spb = ObjectPipe(), ObjectPipe() - # Register recv hook - self.spb.register_hook(self.call_release) - kargs["external_fd"] = {ioevent: (self.spa, self.spb)} - self.atmt = automaton(*args, **kargs) - self.atmt.runbg() - - def fileno(self): - return self.spb.fileno() - - def send(self, s): - if not isinstance(s, bytes): - s = bytes(s) - return self.spa.send(s) - - def check_recv(self): - return self.spb.check_recv() - - def recv(self, n=MTU): - r = self.spb.recv(n) - if self.proto is not None: - r = self.proto(r) - return r - - def close(self): - pass - - @staticmethod - def select(sockets, remain=conf.recv_poll_rate): - return select_objects(sockets, remain), None - - -class _ATMT_to_supersocket: - def __init__(self, name, ioevent, automaton): - self.name = name - self.ioevent = ioevent - self.automaton = automaton - - def __call__(self, proto, *args, **kargs): - return _ATMT_supersocket( - self.name, self.ioevent, self.automaton, - proto, *args, **kargs - ) - - -class Automaton_metaclass(type): - def __new__(cls, name, bases, dct): - cls = super(Automaton_metaclass, cls).__new__(cls, name, bases, dct) - cls.states = {} - cls.state = None - cls.recv_conditions = {} - cls.conditions = {} - cls.ioevents = {} - cls.timeout = {} - cls.actions = {} - cls.initial_states = [] - cls.ionames = [] - cls.iosupersockets = [] - - members = {} - classes = [cls] - while classes: - c = classes.pop(0) # order is important to avoid breaking method overloading # noqa: E501 - classes += list(c.__bases__) - for k, v in six.iteritems(c.__dict__): - if k not in members: - members[k] = v - - decorated = [v for v in six.itervalues(members) - if isinstance(v, types.FunctionType) and hasattr(v, "atmt_type")] # noqa: E501 - - for m in decorated: - if m.atmt_type == ATMT.STATE: - s = m.atmt_state - cls.states[s] = m - cls.recv_conditions[s] = [] - cls.ioevents[s] = [] - cls.conditions[s] = [] - cls.timeout[s] = [] - if m.atmt_initial: - cls.initial_states.append(m) - elif m.atmt_type in [ATMT.CONDITION, ATMT.RECV, ATMT.TIMEOUT, ATMT.IOEVENT]: # noqa: E501 - cls.actions[m.atmt_condname] = [] - - for m in decorated: - if m.atmt_type == ATMT.CONDITION: - cls.conditions[m.atmt_state].append(m) - elif m.atmt_type == ATMT.RECV: - cls.recv_conditions[m.atmt_state].append(m) - elif m.atmt_type == ATMT.IOEVENT: - cls.ioevents[m.atmt_state].append(m) - cls.ionames.append(m.atmt_ioname) - if m.atmt_as_supersocket is not None: - cls.iosupersockets.append(m) - elif m.atmt_type == ATMT.TIMEOUT: - cls.timeout[m.atmt_state].append((m.atmt_timeout, m)) - elif m.atmt_type == ATMT.ACTION: - for c in m.atmt_cond: - cls.actions[c].append(m) - - for v in six.itervalues(cls.timeout): - v.sort(key=lambda x: x[0]) - v.append((None, None)) - for v in itertools.chain(six.itervalues(cls.conditions), - six.itervalues(cls.recv_conditions), - six.itervalues(cls.ioevents)): - v.sort(key=lambda x: x.atmt_prio) - for condname, actlst in six.iteritems(cls.actions): - actlst.sort(key=lambda x: x.atmt_cond[condname]) - - for ioev in cls.iosupersockets: - setattr(cls, ioev.atmt_as_supersocket, _ATMT_to_supersocket(ioev.atmt_as_supersocket, ioev.atmt_ioname, cls)) # noqa: E501 - - return cls - - def build_graph(self): - s = 'digraph "%s" {\n' % self.__class__.__name__ - - se = "" # Keep initial nodes at the beginning for better rendering - for st in six.itervalues(self.states): - if st.atmt_initial: - se = ('\t"%s" [ style=filled, fillcolor=blue, shape=box, root=true];\n' % st.atmt_state) + se # noqa: E501 - elif st.atmt_final: - se += '\t"%s" [ style=filled, fillcolor=green, shape=octagon ];\n' % st.atmt_state # noqa: E501 - elif st.atmt_error: - se += '\t"%s" [ style=filled, fillcolor=red, shape=octagon ];\n' % st.atmt_state # noqa: E501 - s += se - - for st in six.itervalues(self.states): - for n in st.atmt_origfunc.__code__.co_names + st.atmt_origfunc.__code__.co_consts: # noqa: E501 - if n in self.states: - s += '\t"%s" -> "%s" [ color=green ];\n' % (st.atmt_state, n) # noqa: E501 - - for c, k, v in ([("purple", k, v) for k, v in self.conditions.items()] + # noqa: E501 - [("red", k, v) for k, v in self.recv_conditions.items()] + # noqa: E501 - [("orange", k, v) for k, v in self.ioevents.items()]): - for f in v: - for n in f.__code__.co_names + f.__code__.co_consts: - if n in self.states: - line = f.atmt_condname - for x in self.actions[f.atmt_condname]: - line += "\\l>[%s]" % x.__name__ - s += '\t"%s" -> "%s" [label="%s", color=%s];\n' % (k, n, line, c) # noqa: E501 - for k, v in six.iteritems(self.timeout): - for t, f in v: - if f is None: - continue - for n in f.__code__.co_names + f.__code__.co_consts: - if n in self.states: - line = "%s/%.1fs" % (f.atmt_condname, t) - for x in self.actions[f.atmt_condname]: - line += "\\l>[%s]" % x.__name__ - s += '\t"%s" -> "%s" [label="%s",color=blue];\n' % (k, n, line) # noqa: E501 - s += "}\n" - return s - - def graph(self, **kargs): - s = self.build_graph() - return do_graph(s, **kargs) - - -class Automaton(six.with_metaclass(Automaton_metaclass)): - def parse_args(self, debug=0, store=1, **kargs): - self.debug_level = debug - self.socket_kargs = kargs - self.store_packets = store - - def master_filter(self, pkt): - return True - - def my_send(self, pkt): - self.send_sock.send(pkt) - - # Utility classes and exceptions - class _IO_fdwrapper(SelectableObject): - def __init__(self, rd, wr): - if rd is not None and not isinstance(rd, (int, ObjectPipe)): - rd = rd.fileno() - if wr is not None and not isinstance(wr, (int, ObjectPipe)): - wr = wr.fileno() - self.rd = rd - self.wr = wr - SelectableObject.__init__(self) - - def fileno(self): - if isinstance(self.rd, ObjectPipe): - return self.rd.fileno() - return self.rd - - def check_recv(self): - return self.rd.check_recv() - - def read(self, n=65535): - if isinstance(self.rd, ObjectPipe): - return self.rd.recv(n) - return os.read(self.rd, n) - - def write(self, msg): - self.call_release() - if isinstance(self.wr, ObjectPipe): - self.wr.send(msg) - return - return os.write(self.wr, msg) - - def recv(self, n=65535): - return self.read(n) - - def send(self, msg): - return self.write(msg) - - class _IO_mixer(SelectableObject): - def __init__(self, rd, wr): - self.rd = rd - self.wr = wr - SelectableObject.__init__(self) - - def fileno(self): - if isinstance(self.rd, int): - return self.rd - return self.rd.fileno() - - def check_recv(self): - return self.rd.check_recv() - - def recv(self, n=None): - return self.rd.recv(n) - - def read(self, n=None): - return self.recv(n) - - def send(self, msg): - self.wr.send(msg) - return self.call_release() - - def write(self, msg): - return self.send(msg) - - class AutomatonException(Exception): - def __init__(self, msg, state=None, result=None): - Exception.__init__(self, msg) - self.state = state - self.result = result - - class AutomatonError(AutomatonException): - pass - - class ErrorState(AutomatonException): - pass - - class Stuck(AutomatonException): - pass - - class AutomatonStopped(AutomatonException): - pass - - class Breakpoint(AutomatonStopped): - pass - - class Singlestep(AutomatonStopped): - pass - - class InterceptionPoint(AutomatonStopped): - def __init__(self, msg, state=None, result=None, packet=None): - Automaton.AutomatonStopped.__init__(self, msg, state=state, result=result) # noqa: E501 - self.packet = packet - - class CommandMessage(AutomatonException): - pass - - # Services - def debug(self, lvl, msg): - if self.debug_level >= lvl: - log_interactive.debug(msg) - - def send(self, pkt): - if self.state.state in self.interception_points: - self.debug(3, "INTERCEPT: packet intercepted: %s" % pkt.summary()) - self.intercepted_packet = pkt - cmd = Message(type=_ATMT_Command.INTERCEPT, state=self.state, pkt=pkt) # noqa: E501 - self.cmdout.send(cmd) - cmd = self.cmdin.recv() - self.intercepted_packet = None - if cmd.type == _ATMT_Command.REJECT: - self.debug(3, "INTERCEPT: packet rejected") - return - elif cmd.type == _ATMT_Command.REPLACE: - pkt = cmd.pkt - self.debug(3, "INTERCEPT: packet replaced by: %s" % pkt.summary()) # noqa: E501 - elif cmd.type == _ATMT_Command.ACCEPT: - self.debug(3, "INTERCEPT: packet accepted") - else: - raise self.AutomatonError("INTERCEPT: unknown verdict: %r" % cmd.type) # noqa: E501 - self.my_send(pkt) - self.debug(3, "SENT : %s" % pkt.summary()) - - if self.store_packets: - self.packets.append(pkt.copy()) - - # Internals - def __init__(self, *args, **kargs): - external_fd = kargs.pop("external_fd", {}) - self.send_sock_class = kargs.pop("ll", conf.L3socket) - self.recv_sock_class = kargs.pop("recvsock", conf.L2listen) - self.started = threading.Lock() - self.threadid = None - self.breakpointed = None - self.breakpoints = set() - self.interception_points = set() - self.intercepted_packet = None - self.debug_level = 0 - self.init_args = args - self.init_kargs = kargs - self.io = type.__new__(type, "IOnamespace", (), {}) - self.oi = type.__new__(type, "IOnamespace", (), {}) - self.cmdin = ObjectPipe() - self.cmdout = ObjectPipe() - self.ioin = {} - self.ioout = {} - for n in self.ionames: - extfd = external_fd.get(n) - if not isinstance(extfd, tuple): - extfd = (extfd, extfd) - ioin, ioout = extfd - if ioin is None: - ioin = ObjectPipe() - elif not isinstance(ioin, SelectableObject): - ioin = self._IO_fdwrapper(ioin, None) - if ioout is None: - ioout = ObjectPipe() - elif not isinstance(ioout, SelectableObject): - ioout = self._IO_fdwrapper(None, ioout) - - self.ioin[n] = ioin - self.ioout[n] = ioout - ioin.ioname = n - ioout.ioname = n - setattr(self.io, n, self._IO_mixer(ioout, ioin)) - setattr(self.oi, n, self._IO_mixer(ioin, ioout)) - - for stname in self.states: - setattr(self, stname, - _instance_state(getattr(self, stname))) - - self.start() - - def __iter__(self): - return self - - def __del__(self): - self.stop() - - def _run_condition(self, cond, *args, **kargs): - try: - self.debug(5, "Trying %s [%s]" % (cond.atmt_type, cond.atmt_condname)) # noqa: E501 - cond(self, *args, **kargs) - except ATMT.NewStateRequested as state_req: - self.debug(2, "%s [%s] taken to state [%s]" % (cond.atmt_type, cond.atmt_condname, state_req.state)) # noqa: E501 - if cond.atmt_type == ATMT.RECV: - if self.store_packets: - self.packets.append(args[0]) - for action in self.actions[cond.atmt_condname]: - self.debug(2, " + Running action [%s]" % action.__name__) - action(self, *state_req.action_args, **state_req.action_kargs) - raise - except Exception as e: - self.debug(2, "%s [%s] raised exception [%s]" % (cond.atmt_type, cond.atmt_condname, e)) # noqa: E501 - raise - else: - self.debug(2, "%s [%s] not taken" % (cond.atmt_type, cond.atmt_condname)) # noqa: E501 - - def _do_start(self, *args, **kargs): - ready = threading.Event() - _t = threading.Thread(target=self._do_control, args=(ready,) + (args), kwargs=kargs) # noqa: E501 - _t.setDaemon(True) - _t.start() - ready.wait() - - def _do_control(self, ready, *args, **kargs): - with self.started: - self.threadid = threading.currentThread().ident - - # Update default parameters - a = args + self.init_args[len(args):] - k = self.init_kargs.copy() - k.update(kargs) - self.parse_args(*a, **k) - - # Start the automaton - self.state = self.initial_states[0](self) - self.send_sock = self.send_sock_class(**self.socket_kargs) - self.listen_sock = self.recv_sock_class(**self.socket_kargs) - self.packets = PacketList(name="session[%s]" % self.__class__.__name__) # noqa: E501 - - singlestep = True - iterator = self._do_iter() - self.debug(3, "Starting control thread [tid=%i]" % self.threadid) - # Sync threads - ready.set() - try: - while True: - c = self.cmdin.recv() - self.debug(5, "Received command %s" % c.type) - if c.type == _ATMT_Command.RUN: - singlestep = False - elif c.type == _ATMT_Command.NEXT: - singlestep = True - elif c.type == _ATMT_Command.FREEZE: - continue - elif c.type == _ATMT_Command.STOP: - break - while True: - state = next(iterator) - if isinstance(state, self.CommandMessage): - break - elif isinstance(state, self.Breakpoint): - c = Message(type=_ATMT_Command.BREAKPOINT, state=state) # noqa: E501 - self.cmdout.send(c) - break - if singlestep: - c = Message(type=_ATMT_Command.SINGLESTEP, state=state) # noqa: E501 - self.cmdout.send(c) - break - except (StopIteration, RuntimeError): - c = Message(type=_ATMT_Command.END, - result=self.final_state_output) - self.cmdout.send(c) - except Exception as e: - exc_info = sys.exc_info() - self.debug(3, "Transferring exception from tid=%i:\n%s" % (self.threadid, traceback.format_exception(*exc_info))) # noqa: E501 - m = Message(type=_ATMT_Command.EXCEPTION, exception=e, exc_info=exc_info) # noqa: E501 - self.cmdout.send(m) - self.debug(3, "Stopping control thread (tid=%i)" % self.threadid) - self.threadid = None - - def _do_iter(self): - while True: - try: - self.debug(1, "## state=[%s]" % self.state.state) - - # Entering a new state. First, call new state function - if self.state.state in self.breakpoints and self.state.state != self.breakpointed: # noqa: E501 - self.breakpointed = self.state.state - yield self.Breakpoint("breakpoint triggered on state %s" % self.state.state, # noqa: E501 - state=self.state.state) - self.breakpointed = None - state_output = self.state.run() - if self.state.error: - raise self.ErrorState("Reached %s: [%r]" % (self.state.state, state_output), # noqa: E501 - result=state_output, state=self.state.state) # noqa: E501 - if self.state.final: - self.final_state_output = state_output - return - - if state_output is None: - state_output = () - elif not isinstance(state_output, list): - state_output = state_output, - - # Then check immediate conditions - for cond in self.conditions[self.state.state]: - self._run_condition(cond, *state_output) - - # If still there and no conditions left, we are stuck! - if (len(self.recv_conditions[self.state.state]) == 0 and - len(self.ioevents[self.state.state]) == 0 and - len(self.timeout[self.state.state]) == 1): - raise self.Stuck("stuck in [%s]" % self.state.state, - state=self.state.state, result=state_output) # noqa: E501 - - # Finally listen and pay attention to timeouts - expirations = iter(self.timeout[self.state.state]) - next_timeout, timeout_func = next(expirations) - t0 = time.time() - - fds = [self.cmdin] - if len(self.recv_conditions[self.state.state]) > 0: - fds.append(self.listen_sock) - for ioev in self.ioevents[self.state.state]: - fds.append(self.ioin[ioev.atmt_ioname]) - while True: - t = time.time() - t0 - if next_timeout is not None: - if next_timeout <= t: - self._run_condition(timeout_func, *state_output) - next_timeout, timeout_func = next(expirations) - if next_timeout is None: - remain = None - else: - remain = next_timeout - t - - self.debug(5, "Select on %r" % fds) - r = select_objects(fds, remain) - self.debug(5, "Selected %r" % r) - for fd in r: - self.debug(5, "Looking at %r" % fd) - if fd == self.cmdin: - yield self.CommandMessage("Received command message") # noqa: E501 - elif fd == self.listen_sock: - try: - pkt = self.listen_sock.recv(MTU) - except recv_error: - pass - else: - if pkt is not None: - if self.master_filter(pkt): - self.debug(3, "RECVD: %s" % pkt.summary()) # noqa: E501 - for rcvcond in self.recv_conditions[self.state.state]: # noqa: E501 - self._run_condition(rcvcond, pkt, *state_output) # noqa: E501 - else: - self.debug(4, "FILTR: %s" % pkt.summary()) # noqa: E501 - else: - self.debug(3, "IOEVENT on %s" % fd.ioname) - for ioevt in self.ioevents[self.state.state]: - if ioevt.atmt_ioname == fd.ioname: - self._run_condition(ioevt, fd, *state_output) # noqa: E501 - - except ATMT.NewStateRequested as state_req: - self.debug(2, "switching from [%s] to [%s]" % (self.state.state, state_req.state)) # noqa: E501 - self.state = state_req - yield state_req - - # Public API - def add_interception_points(self, *ipts): - for ipt in ipts: - if hasattr(ipt, "atmt_state"): - ipt = ipt.atmt_state - self.interception_points.add(ipt) - - def remove_interception_points(self, *ipts): - for ipt in ipts: - if hasattr(ipt, "atmt_state"): - ipt = ipt.atmt_state - self.interception_points.discard(ipt) - - def add_breakpoints(self, *bps): - for bp in bps: - if hasattr(bp, "atmt_state"): - bp = bp.atmt_state - self.breakpoints.add(bp) - - def remove_breakpoints(self, *bps): - for bp in bps: - if hasattr(bp, "atmt_state"): - bp = bp.atmt_state - self.breakpoints.discard(bp) - - def start(self, *args, **kargs): - if not self.started.locked(): - self._do_start(*args, **kargs) - - def run(self, resume=None, wait=True): - if resume is None: - resume = Message(type=_ATMT_Command.RUN) - self.cmdin.send(resume) - if wait: - try: - c = self.cmdout.recv() - except KeyboardInterrupt: - self.cmdin.send(Message(type=_ATMT_Command.FREEZE)) - return - if c.type == _ATMT_Command.END: - return c.result - elif c.type == _ATMT_Command.INTERCEPT: - raise self.InterceptionPoint("packet intercepted", state=c.state.state, packet=c.pkt) # noqa: E501 - elif c.type == _ATMT_Command.SINGLESTEP: - raise self.Singlestep("singlestep state=[%s]" % c.state.state, state=c.state.state) # noqa: E501 - elif c.type == _ATMT_Command.BREAKPOINT: - raise self.Breakpoint("breakpoint triggered on state [%s]" % c.state.state, state=c.state.state) # noqa: E501 - elif c.type == _ATMT_Command.EXCEPTION: - six.reraise(c.exc_info[0], c.exc_info[1], c.exc_info[2]) - - def runbg(self, resume=None, wait=False): - self.run(resume, wait) - - def next(self): - return self.run(resume=Message(type=_ATMT_Command.NEXT)) - __next__ = next - - def stop(self): - self.cmdin.send(Message(type=_ATMT_Command.STOP)) - with self.started: - # Flush command pipes - while True: - r = select_objects([self.cmdin, self.cmdout], 0) - if not r: - break - for fd in r: - fd.recv() - - def restart(self, *args, **kargs): - self.stop() - self.start(*args, **kargs) - - def accept_packet(self, pkt=None, wait=False): - rsm = Message() - if pkt is None: - rsm.type = _ATMT_Command.ACCEPT - else: - rsm.type = _ATMT_Command.REPLACE - rsm.pkt = pkt - return self.run(resume=rsm, wait=wait) - - def reject_packet(self, wait=False): - rsm = Message(type=_ATMT_Command.REJECT) - return self.run(resume=rsm, wait=wait) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/autorun.py b/scripts/external_libs/scapy-2.4.3/scapy/autorun.py deleted file mode 100644 index 399cf1456a..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/autorun.py +++ /dev/null @@ -1,174 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Run commands when the Scapy interpreter starts. -""" - -from __future__ import print_function -import code -import sys -import importlib -from scapy.config import conf -from scapy.themes import NoTheme, DefaultTheme, HTMLTheme2, LatexTheme2 -from scapy.error import Scapy_Exception -from scapy.utils import tex_escape -import scapy.modules.six as six - - -######################### -# Autorun stuff # -######################### - -class StopAutorun(Scapy_Exception): - code_run = "" - - -class ScapyAutorunInterpreter(code.InteractiveInterpreter): - def __init__(self, *args, **kargs): - code.InteractiveInterpreter.__init__(self, *args, **kargs) - self.error = 0 - - def showsyntaxerror(self, *args, **kargs): - self.error = 1 - return code.InteractiveInterpreter.showsyntaxerror(self, *args, **kargs) # noqa: E501 - - def showtraceback(self, *args, **kargs): - self.error = 1 - exc_type, exc_value, exc_tb = sys.exc_info() - if isinstance(exc_value, StopAutorun): - raise exc_value - return code.InteractiveInterpreter.showtraceback(self, *args, **kargs) - - -def autorun_commands(cmds, my_globals=None, ignore_globals=None, verb=None): - sv = conf.verb - try: - try: - if my_globals is None: - my_globals = importlib.import_module(".all", "scapy").__dict__ - if ignore_globals: - for ig in ignore_globals: - my_globals.pop(ig, None) - if verb is not None: - conf.verb = verb - interp = ScapyAutorunInterpreter(my_globals) - cmd = "" - cmds = cmds.splitlines() - cmds.append("") # ensure we finish multi-line commands - cmds.reverse() - six.moves.builtins.__dict__["_"] = None - while True: - if cmd: - sys.stderr.write(sys.__dict__.get("ps2", "... ")) - else: - sys.stderr.write(str(sys.__dict__.get("ps1", sys.ps1))) - - line = cmds.pop() - print(line) - cmd += "\n" + line - if interp.runsource(cmd): - continue - if interp.error: - return 0 - cmd = "" - if len(cmds) <= 1: - break - except SystemExit: - pass - finally: - conf.verb = sv - return _ # noqa: F821 - - -class StringWriter(object): - """Util to mock sys.stdout and sys.stderr, and - store their output in a 's' var.""" - def __init__(self, debug=None): - self.s = "" - self.debug = debug - - def write(self, x): - if self.debug: - self.debug.write(x) - self.s += x - - def flush(self): - if self.debug: - self.debug.flush() - - -def autorun_get_interactive_session(cmds, **kargs): - """Create an interactive session and execute the - commands passed as "cmds" and return all output - - params: - - cmds: a list of commands to run - returns: (output, returned) - - The output contains both sys.stdout and sys.stderr logs""" - sstdout, sstderr = sys.stdout, sys.stderr - sw = StringWriter() - try: - try: - sys.stdout = sys.stderr = sw - res = autorun_commands(cmds, **kargs) - except StopAutorun as e: - e.code_run = sw.s - raise - finally: - sys.stdout, sys.stderr = sstdout, sstderr - return sw.s, res - - -def autorun_get_text_interactive_session(cmds, **kargs): - ct = conf.color_theme - try: - conf.color_theme = NoTheme() - s, res = autorun_get_interactive_session(cmds, **kargs) - finally: - conf.color_theme = ct - return s, res - - -def autorun_get_ansi_interactive_session(cmds, **kargs): - ct = conf.color_theme - try: - conf.color_theme = DefaultTheme() - s, res = autorun_get_interactive_session(cmds, **kargs) - finally: - conf.color_theme = ct - return s, res - - -def autorun_get_html_interactive_session(cmds, **kargs): - ct = conf.color_theme - to_html = lambda s: s.replace("<", "<").replace(">", ">").replace("#[#", "<").replace("#]#", ">") # noqa: E501 - try: - try: - conf.color_theme = HTMLTheme2() - s, res = autorun_get_interactive_session(cmds, **kargs) - except StopAutorun as e: - e.code_run = to_html(e.code_run) - raise - finally: - conf.color_theme = ct - - return to_html(s), res - - -def autorun_get_latex_interactive_session(cmds, **kargs): - ct = conf.color_theme - to_latex = lambda s: tex_escape(s).replace("@[@", "{").replace("@]@", "}").replace("@`@", "\\") # noqa: E501 - try: - try: - conf.color_theme = LatexTheme2() - s, res = autorun_get_interactive_session(cmds, **kargs) - except StopAutorun as e: - e.code_run = to_latex(e.code_run) - raise - finally: - conf.color_theme = ct - return to_latex(s), res diff --git a/scripts/external_libs/scapy-2.4.3/scapy/base_classes.py b/scripts/external_libs/scapy-2.4.3/scapy/base_classes.py deleted file mode 100644 index b2f9e170b0..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/base_classes.py +++ /dev/null @@ -1,378 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Generators and packet meta classes. -""" - -################ -# Generators # -################ - -from __future__ import absolute_import - -from functools import reduce -import operator -import os -import re -import random -import socket -import subprocess -import types - -from scapy.consts import WINDOWS -from scapy.modules.six.moves import range - - -class Gen(object): - __slots__ = [] - - def __iter__(self): - return iter([]) - - def __iterlen__(self): - return sum(1 for _ in iter(self)) - - -def _get_values(value): - """Generate a range object from (start, stop[, step]) tuples, or - return value. - - """ - if (isinstance(value, tuple) and (2 <= len(value) <= 3) and - all(hasattr(i, "__int__") for i in value)): - # We use values[1] + 1 as stop value for (x)range to maintain - # the behavior of using tuples as field `values` - return range(*((int(value[0]), int(value[1]) + 1) + - tuple(int(v) for v in value[2:]))) - return value - - -class SetGen(Gen): - def __init__(self, values, _iterpacket=1): - self._iterpacket = _iterpacket - if isinstance(values, (list, BasePacketList)): - self.values = [_get_values(val) for val in values] - else: - self.values = [_get_values(values)] - - def transf(self, element): - return element - - def __iter__(self): - for i in self.values: - if (isinstance(i, Gen) and - (self._iterpacket or not isinstance(i, BasePacket))) or ( - isinstance(i, (range, types.GeneratorType))): - for j in i: - yield j - else: - yield i - - def __repr__(self): - return "" % self.values - - -class Net(Gen): - """Generate a list of IPs from a network address or a name""" - name = "ip" - ip_regex = re.compile(r"^(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)(/[0-3]?[0-9])?$") # noqa: E501 - - @staticmethod - def _parse_digit(a, netmask): - netmask = min(8, max(netmask, 0)) - if a == "*": - a = (0, 256) - elif a.find("-") >= 0: - x, y = [int(d) for d in a.split('-')] - if x > y: - y = x - a = (x & (0xff << netmask), max(y, (x | (0xff >> (8 - netmask)))) + 1) # noqa: E501 - else: - a = (int(a) & (0xff << netmask), (int(a) | (0xff >> (8 - netmask))) + 1) # noqa: E501 - return a - - @classmethod - def _parse_net(cls, net): - tmp = net.split('/') + ["32"] - # TRex Change - # if not cls.ip_regex.match(net): - # tmp[0] = socket.gethostbyname(tmp[0]) - netmask = int(tmp[1]) - ret_list = [cls._parse_digit(x, y - netmask) for (x, y) in zip(tmp[0].split('.'), [8, 16, 24, 32])] # noqa: E501 - return ret_list, netmask - - def __init__(self, net): - self.repr = net - self.parsed, self.netmask = self._parse_net(net) - - def __str__(self): - return next(self.__iter__(), None) - - def __iter__(self): - for d in range(*self.parsed[3]): - for c in range(*self.parsed[2]): - for b in range(*self.parsed[1]): - for a in range(*self.parsed[0]): - yield "%i.%i.%i.%i" % (a, b, c, d) - - def __iterlen__(self): - return reduce(operator.mul, ((y - x) for (x, y) in self.parsed), 1) - - def choice(self): - return ".".join(str(random.randint(v[0], v[1] - 1)) for v in self.parsed) # noqa: E501 - - def __repr__(self): - return "Net(%r)" % self.repr - - def __eq__(self, other): - if hasattr(other, "parsed"): - p2 = other.parsed - else: - p2, nm2 = self._parse_net(other) - return self.parsed == p2 - - def __contains__(self, other): - if hasattr(other, "parsed"): - p2 = other.parsed - else: - p2, nm2 = self._parse_net(other) - return all(a1 <= a2 and b1 >= b2 for (a1, b1), (a2, b2) in zip(self.parsed, p2)) # noqa: E501 - - def __rcontains__(self, other): - return self in self.__class__(other) - - -class OID(Gen): - name = "OID" - - def __init__(self, oid): - self.oid = oid - self.cmpt = [] - fmt = [] - for i in oid.split("."): - if "-" in i: - fmt.append("%i") - self.cmpt.append(tuple(map(int, i.split("-")))) - else: - fmt.append(i) - self.fmt = ".".join(fmt) - - def __repr__(self): - return "OID(%r)" % self.oid - - def __iter__(self): - ii = [k[0] for k in self.cmpt] - while True: - yield self.fmt % tuple(ii) - i = 0 - while True: - if i >= len(ii): - return - if ii[i] < self.cmpt[i][1]: - ii[i] += 1 - break - else: - ii[i] = self.cmpt[i][0] - i += 1 - - def __iterlen__(self): - return reduce(operator.mul, (max(y - x, 0) + 1 for (x, y) in self.cmpt), 1) # noqa: E501 - - -###################################### -# Packet abstract and base classes # -###################################### - -class Packet_metaclass(type): - def __new__(cls, name, bases, dct): - if "fields_desc" in dct: # perform resolution of references to other packets # noqa: E501 - current_fld = dct["fields_desc"] - resolved_fld = [] - for f in current_fld: - if isinstance(f, Packet_metaclass): # reference to another fields_desc # noqa: E501 - for f2 in f.fields_desc: - resolved_fld.append(f2) - else: - resolved_fld.append(f) - else: # look for a fields_desc in parent classes - resolved_fld = None - for b in bases: - if hasattr(b, "fields_desc"): - resolved_fld = b.fields_desc - break - - if resolved_fld: # perform default value replacements - final_fld = [] - for f in resolved_fld: - if f.name in dct: - f = f.copy() - f.default = dct[f.name] - del(dct[f.name]) - final_fld.append(f) - - dct["fields_desc"] = final_fld - - dct.setdefault("__slots__", []) - for attr in ["name", "overload_fields"]: - try: - dct["_%s" % attr] = dct.pop(attr) - except KeyError: - pass - newcls = super(Packet_metaclass, cls).__new__(cls, name, bases, dct) - newcls.__all_slots__ = set( - attr - for cls in newcls.__mro__ if hasattr(cls, "__slots__") - for attr in cls.__slots__ - ) - - newcls.aliastypes = [newcls] + getattr(newcls, "aliastypes", []) - - if hasattr(newcls, "register_variant"): - newcls.register_variant() - for f in newcls.fields_desc: - if hasattr(f, "register_owner"): - f.register_owner(newcls) - if newcls.__name__[0] != "_": - from scapy import config - config.conf.layers.register(newcls) - return newcls - - def __getattr__(self, attr): - for k in self.fields_desc: - if k.name == attr: - return k - raise AttributeError(attr) - - def __call__(cls, *args, **kargs): - if "dispatch_hook" in cls.__dict__: - try: - cls = cls.dispatch_hook(*args, **kargs) - except Exception: - from scapy import config - if config.conf.debug_dissector: - raise - cls = config.conf.raw_layer - i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__) - i.__init__(*args, **kargs) - return i - - -class Field_metaclass(type): - def __new__(cls, name, bases, dct): - dct.setdefault("__slots__", []) - newcls = super(Field_metaclass, cls).__new__(cls, name, bases, dct) - return newcls - - -class NewDefaultValues(Packet_metaclass): - """NewDefaultValues is deprecated (not needed anymore) - - remove this: - __metaclass__ = NewDefaultValues - and it should still work. - """ - def __new__(cls, name, bases, dct): - from scapy.error import log_loading - import traceback - try: - for tb in traceback.extract_stack() + [("??", -1, None, "")]: - f, l, _, line = tb - if line.startswith("class"): - break - except Exception: - f, l = "??", -1 # noqa: E741 - raise - log_loading.warning("Deprecated (no more needed) use of NewDefaultValues (%s l. %i).", f, l) # noqa: E501 - - return super(NewDefaultValues, cls).__new__(cls, name, bases, dct) - - -class BasePacket(Gen): - __slots__ = [] - - -############################# -# Packet list base class # -############################# - -class BasePacketList(object): - __slots__ = [] - - -class _CanvasDumpExtended(object): - def psdump(self, filename=None, **kargs): - """ - psdump(filename=None, layer_shift=0, rebuild=1) - - Creates an EPS file describing a packet. If filename is not provided a - temporary file is created and gs is called. - - :param filename: the file's filename - """ - from scapy.config import conf - from scapy.utils import get_temp_file, ContextManagerSubprocess - canvas = self.canvas_dump(**kargs) - if filename is None: - fname = get_temp_file(autoext=kargs.get("suffix", ".eps")) - canvas.writeEPSfile(fname) - if WINDOWS and conf.prog.psreader is None: - os.startfile(fname) - else: - with ContextManagerSubprocess("psdump()", conf.prog.psreader): - subprocess.Popen([conf.prog.psreader, fname]) - else: - canvas.writeEPSfile(filename) - print() - - def pdfdump(self, filename=None, **kargs): - """ - pdfdump(filename=None, layer_shift=0, rebuild=1) - - Creates a PDF file describing a packet. If filename is not provided a - temporary file is created and xpdf is called. - - :param filename: the file's filename - """ - from scapy.config import conf - from scapy.utils import get_temp_file, ContextManagerSubprocess - canvas = self.canvas_dump(**kargs) - if filename is None: - fname = get_temp_file(autoext=kargs.get("suffix", ".pdf")) - canvas.writePDFfile(fname) - if WINDOWS and conf.prog.pdfreader is None: - os.startfile(fname) - else: - with ContextManagerSubprocess("pdfdump()", - conf.prog.pdfreader): - subprocess.Popen([conf.prog.pdfreader, fname]) - else: - canvas.writePDFfile(filename) - print() - - def svgdump(self, filename=None, **kargs): - """ - svgdump(filename=None, layer_shift=0, rebuild=1) - - Creates an SVG file describing a packet. If filename is not provided a - temporary file is created and gs is called. - - :param filename: the file's filename - """ - from scapy.config import conf - from scapy.utils import get_temp_file, ContextManagerSubprocess - canvas = self.canvas_dump(**kargs) - if filename is None: - fname = get_temp_file(autoext=kargs.get("suffix", ".svg")) - canvas.writeSVGfile(fname) - if WINDOWS and conf.prog.svgreader is None: - os.startfile(fname) - else: - with ContextManagerSubprocess("svgdump()", - conf.prog.svgreader): - subprocess.Popen([conf.prog.svgreader, fname]) - else: - canvas.writeSVGfile(filename) - print() diff --git a/scripts/external_libs/scapy-2.4.3/scapy/compat.py b/scripts/external_libs/scapy-2.4.3/scapy/compat.py deleted file mode 100644 index 8d06a67033..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/compat.py +++ /dev/null @@ -1,119 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Copyright (C) Gabriel Potter -# This program is published under a GPLv2 license - -""" -Python 2 and 3 link classes. -""" - -from __future__ import absolute_import -import base64 -import binascii -import gzip -import struct - -import scapy.modules.six as six - -########### -# Python3 # -########### - - -def lambda_tuple_converter(func): - """ - Converts a Python 2 function as - lambda (x,y): x + y - In the Python 3 format: - lambda x,y : x + y - """ - if func is not None and func.__code__.co_argcount == 1: - return lambda *args: func(args[0] if len(args) == 1 else args) - else: - return func - - -if six.PY2: - bytes_encode = plain_str = str - chb = lambda x: x if isinstance(x, str) else chr(x) - orb = ord - - def raw(x): - """Builds a packet and returns its bytes representation. - This function is and always be cross-version compatible""" - if hasattr(x, "__bytes__"): - return x.__bytes__() - return bytes(x) -else: - def raw(x): - """Builds a packet and returns its bytes representation. - This function is and always be cross-version compatible""" - return bytes(x) - - def bytes_encode(x): - """Ensure that the given object is bytes. - If the parameter is a packet, raw() should be preferred. - """ - if isinstance(x, str): - return x.encode() - return bytes(x) - - def plain_str(x): - """Convert basic byte objects to str""" - if isinstance(x, bytes): - return x.decode(errors="ignore") - return str(x) - - def chb(x): - """Same than chr() but encode as bytes.""" - return struct.pack("!B", x) - - def orb(x): - """Return ord(x) when not already an int.""" - if isinstance(x, int): - return x - return ord(x) - - -def bytes_hex(x): - """Hexify a str or a bytes object""" - return binascii.b2a_hex(bytes_encode(x)) - - -def hex_bytes(x): - """De-hexify a str or a byte object""" - return binascii.a2b_hex(bytes_encode(x)) - - -def base64_bytes(x): - """Turn base64 into bytes""" - if six.PY2: - return base64.decodestring(x) - return base64.decodebytes(bytes_encode(x)) - - -def bytes_base64(x): - """Turn bytes into base64""" - if six.PY2: - return base64.encodestring(x).replace('\n', '') - return base64.encodebytes(bytes_encode(x)).replace(b'\n', b'') - - -if six.PY2: - from StringIO import StringIO - - def gzip_decompress(x): - """Decompress using gzip""" - with gzip.GzipFile(fileobj=StringIO(x), mode='rb') as fdesc: - return fdesc.read() - - def gzip_compress(x): - """Compress using gzip""" - buf = StringIO() - with gzip.GzipFile(fileobj=buf, mode='wb') as fdesc: - fdesc.write(x) - return buf.getvalue() -else: - gzip_decompress = gzip.decompress - gzip_compress = gzip.compress diff --git a/scripts/external_libs/scapy-2.4.3/scapy/config.py b/scripts/external_libs/scapy-2.4.3/scapy/config.py deleted file mode 100644 index d5e5a12f06..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/config.py +++ /dev/null @@ -1,682 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Implementation of the configuration object. -""" - -from __future__ import absolute_import -from __future__ import print_function -import functools -import os -import re -import time -import socket -import sys - -from scapy import VERSION, base_classes -from scapy.consts import DARWIN, WINDOWS, LINUX, BSD, SOLARIS -from scapy.error import log_scapy, warning, ScapyInvalidPlatformException -from scapy.modules import six -from scapy.themes import NoTheme, apply_ipython_style - -############ -# Config # -############ - - -class ConfClass(object): - def configure(self, cnf): - self.__dict__ = cnf.__dict__.copy() - - def __repr__(self): - return str(self) - - def __str__(self): - s = "" - keys = self.__class__.__dict__.copy() - keys.update(self.__dict__) - keys = sorted(keys) - for i in keys: - if i[0] != "_": - r = repr(getattr(self, i)) - r = " ".join(r.split()) - wlen = 76 - max(len(i), 10) - if len(r) > wlen: - r = r[:wlen - 3] + "..." - s += "%-10s = %s\n" % (i, r) - return s[:-1] - - -class Interceptor(object): - def __init__(self, name=None, default=None, - hook=None, args=None, kargs=None): - self.name = name - self.intname = "_intercepted_%s" % name - self.default = default - self.hook = hook - self.args = args if args is not None else [] - self.kargs = kargs if kargs is not None else {} - - def __get__(self, obj, typ=None): - if not hasattr(obj, self.intname): - setattr(obj, self.intname, self.default) - return getattr(obj, self.intname) - - @staticmethod - def set_from_hook(obj, name, val): - int_name = "_intercepted_%s" % name - setattr(obj, int_name, val) - - def __set__(self, obj, val): - setattr(obj, self.intname, val) - self.hook(self.name, val, *self.args, **self.kargs) - - -def _readonly(name): - default = Conf.__dict__[name].default - Interceptor.set_from_hook(conf, name, default) - raise ValueError("Read-only value !") - - -ReadOnlyAttribute = functools.partial( - Interceptor, - hook=(lambda name, *args, **kwargs: _readonly(name)) -) -ReadOnlyAttribute.__doc__ = "Read-only class attribute" - - -class ProgPath(ConfClass): - universal_open = "open" if DARWIN else "xdg-open" - pdfreader = universal_open - psreader = universal_open - svgreader = universal_open - dot = "dot" - display = "display" - tcpdump = "tcpdump" - tcpreplay = "tcpreplay" - hexedit = "hexer" - tshark = "tshark" - wireshark = "wireshark" - ifconfig = "ifconfig" - - -class ConfigFieldList: - def __init__(self): - self.fields = set() - self.layers = set() - - @staticmethod - def _is_field(f): - return hasattr(f, "owners") - - def _recalc_layer_list(self): - self.layers = {owner for f in self.fields for owner in f.owners} - - def add(self, *flds): - self.fields |= {f for f in flds if self._is_field(f)} - self._recalc_layer_list() - - def remove(self, *flds): - self.fields -= set(flds) - self._recalc_layer_list() - - def __contains__(self, elt): - if isinstance(elt, base_classes.Packet_metaclass): - return elt in self.layers - return elt in self.fields - - def __repr__(self): - return "<%s [%s]>" % (self.__class__.__name__, " ".join(str(x) for x in self.fields)) # noqa: E501 - - -class Emphasize(ConfigFieldList): - pass - - -class Resolve(ConfigFieldList): - pass - - -class Num2Layer: - def __init__(self): - self.num2layer = {} - self.layer2num = {} - - def register(self, num, layer): - self.register_num2layer(num, layer) - self.register_layer2num(num, layer) - - def register_num2layer(self, num, layer): - self.num2layer[num] = layer - - def register_layer2num(self, num, layer): - self.layer2num[layer] = num - - def __getitem__(self, item): - if isinstance(item, base_classes.Packet_metaclass): - return self.layer2num[item] - return self.num2layer[item] - - def __contains__(self, item): - if isinstance(item, base_classes.Packet_metaclass): - return item in self.layer2num - return item in self.num2layer - - def get(self, item, default=None): - return self[item] if item in self else default - - def __repr__(self): - lst = [] - for num, layer in six.iteritems(self.num2layer): - if layer in self.layer2num and self.layer2num[layer] == num: - dir = "<->" - else: - dir = " ->" - lst.append((num, "%#6x %s %-20s (%s)" % (num, dir, layer.__name__, - layer._name))) - for layer, num in six.iteritems(self.layer2num): - if num not in self.num2layer or self.num2layer[num] != layer: - lst.append((num, "%#6x <- %-20s (%s)" % (num, layer.__name__, - layer._name))) - lst.sort() - return "\n".join(y for x, y in lst) - - -class LayersList(list): - - def __init__(self): - list.__init__(self) - self.ldict = {} - - def __repr__(self): - return "\n".join("%-20s: %s" % (l.__name__, l.name) for l in self) - - def register(self, layer): - self.append(layer) - if layer.__module__ not in self.ldict: - self.ldict[layer.__module__] = [] - self.ldict[layer.__module__].append(layer) - - def layers(self): - result = [] - # This import may feel useless, but it is required for the eval below - import scapy # noqa: F401 - for lay in self.ldict: - doc = eval(lay).__doc__ - result.append((lay, doc.strip().split("\n")[0] if doc else lay)) - return result - - -class CommandsList(list): - def __repr__(self): - s = [] - for l in sorted(self, key=lambda x: x.__name__): - doc = l.__doc__.split("\n")[0] if l.__doc__ else "--" - s.append("%-20s: %s" % (l.__name__, doc)) - return "\n".join(s) - - def register(self, cmd): - self.append(cmd) - return cmd # return cmd so that method can be used as a decorator - - -def lsc(): - """Displays Scapy's default commands""" - print(repr(conf.commands)) - - -class CacheInstance(dict, object): - __slots__ = ["timeout", "name", "_timetable", "__dict__"] - - def __init__(self, name="noname", timeout=None): - self.timeout = timeout - self.name = name - self._timetable = {} - - def flush(self): - self.__init__(name=self.name, timeout=self.timeout) - - def __getitem__(self, item): - if item in self.__slots__: - return object.__getattribute__(self, item) - val = dict.__getitem__(self, item) - if self.timeout is not None: - t = self._timetable[item] - if time.time() - t > self.timeout: - raise KeyError(item) - return val - - def get(self, item, default=None): - # overloading this method is needed to force the dict to go through - # the timetable check - try: - return self[item] - except KeyError: - return default - - def __setitem__(self, item, v): - if item in self.__slots__: - return object.__setattr__(self, item, v) - self._timetable[item] = time.time() - dict.__setitem__(self, item, v) - - def update(self, other): - for key, value in six.iteritems(other): - # We only update an element from `other` either if it does - # not exist in `self` or if the entry in `self` is older. - if key not in self or self._timetable[key] < other._timetable[key]: - dict.__setitem__(self, key, value) - self._timetable[key] = other._timetable[key] - - def iteritems(self): - if self.timeout is None: - return six.iteritems(self.__dict__) - t0 = time.time() - return ((k, v) for (k, v) in six.iteritems(self.__dict__) if t0 - self._timetable[k] < self.timeout) # noqa: E501 - - def iterkeys(self): - if self.timeout is None: - return six.iterkeys(self.__dict__) - t0 = time.time() - return (k for k in six.iterkeys(self.__dict__) if t0 - self._timetable[k] < self.timeout) # noqa: E501 - - def __iter__(self): - return six.iterkeys(self.__dict__) - - def itervalues(self): - if self.timeout is None: - return six.itervalues(self.__dict__) - t0 = time.time() - return (v for (k, v) in six.iteritems(self.__dict__) if t0 - self._timetable[k] < self.timeout) # noqa: E501 - - def items(self): - if self.timeout is None: - return dict.items(self) - t0 = time.time() - return [(k, v) for (k, v) in six.iteritems(self.__dict__) if t0 - self._timetable[k] < self.timeout] # noqa: E501 - - def keys(self): - if self.timeout is None: - return dict.keys(self) - t0 = time.time() - return [k for k in six.iterkeys(self.__dict__) if t0 - self._timetable[k] < self.timeout] # noqa: E501 - - def values(self): - if self.timeout is None: - return list(six.itervalues(self)) - t0 = time.time() - return [v for (k, v) in six.iteritems(self.__dict__) if t0 - self._timetable[k] < self.timeout] # noqa: E501 - - def __len__(self): - if self.timeout is None: - return dict.__len__(self) - return len(self.keys()) - - def summary(self): - return "%s: %i valid items. Timeout=%rs" % (self.name, len(self), self.timeout) # noqa: E501 - - def __repr__(self): - s = [] - if self: - mk = max(len(k) for k in six.iterkeys(self.__dict__)) - fmt = "%%-%is %%s" % (mk + 1) - for item in six.iteritems(self.__dict__): - s.append(fmt % item) - return "\n".join(s) - - -class NetCache: - def __init__(self): - self._caches_list = [] - - def add_cache(self, cache): - self._caches_list.append(cache) - setattr(self, cache.name, cache) - - def new_cache(self, name, timeout=None): - c = CacheInstance(name=name, timeout=timeout) - self.add_cache(c) - - def __delattr__(self, attr): - raise AttributeError("Cannot delete attributes") - - def update(self, other): - for co in other._caches_list: - if hasattr(self, co.name): - getattr(self, co.name).update(co) - else: - self.add_cache(co.copy()) - - def flush(self): - for c in self._caches_list: - c.flush() - - def __repr__(self): - return "\n".join(c.summary() for c in self._caches_list) - - -def _version_checker(module, minver): - """Checks that module has a higher version that minver. - - params: - - module: a module to test - - minver: a tuple of versions - """ - # We could use LooseVersion, but distutils imports imp which is deprecated - version_regexp = r'[a-z]?((?:\d|\.)+\d+)(?:\.dev[0-9]+)?' - version_tags = re.match(version_regexp, module.__version__) - if not version_tags: - return False - version_tags = version_tags.group(1).split(".") - version_tags = tuple(int(x) for x in version_tags) - return version_tags >= minver - - -def isCryptographyValid(): - """ - Check if the cryptography library is present, and if it is recent enough - for most usages in scapy (v1.7 or later). - """ - try: - import cryptography - except ImportError: - return False - return _version_checker(cryptography, (1, 7)) - - -def isCryptographyRecent(): - """ - Check if the cryptography library is recent (2.0 and later) - """ - try: - import cryptography - except ImportError: - return False - return _version_checker(cryptography, (2, 0)) - - -def isCryptographyAdvanced(): - """ - Check if the cryptography library is present, and if it supports X25519, - ChaCha20Poly1305 and such (v2.0 or later). - """ - try: - from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey # noqa: E501 - X25519PrivateKey.generate() - except Exception: - return False - else: - return True - - -def isPyPy(): - """Returns either scapy is running under PyPy or not""" - try: - import __pypy__ # noqa: F401 - return True - except ImportError: - return False - - -def _prompt_changer(attr, val): - """Change the current prompt theme""" - try: - sys.ps1 = conf.color_theme.prompt(conf.prompt) - except Exception: - pass - try: - apply_ipython_style(get_ipython()) - except NameError: - pass - - -def _set_conf_sockets(): - """Populate the conf.L2Socket and conf.L3Socket - according to the various use_* parameters - """ - from scapy.main import _load - if conf.use_bpf and not BSD: - Interceptor.set_from_hook(conf, "use_bpf", False) - raise ScapyInvalidPlatformException("BSD-like (OSX, *BSD...) only !") - if not conf.use_pcap and SOLARIS: - Interceptor.set_from_hook(conf, "use_pcap", True) - raise ScapyInvalidPlatformException( - "Scapy only supports libpcap on Solaris !" - ) - # we are already in an Interceptor hook, use Interceptor.set_from_hook - if conf.use_pcap or conf.use_dnet: - try: - from scapy.arch.pcapdnet import L2pcapListenSocket, L2pcapSocket, \ - L3pcapSocket - except (OSError, ImportError): - warning("No libpcap provider available ! pcap won't be used") - Interceptor.set_from_hook(conf, "use_pcap", False) - else: - conf.L3socket = L3pcapSocket - conf.L3socket6 = functools.partial(L3pcapSocket, filter="ip6") - conf.L2socket = L2pcapSocket - conf.L2listen = L2pcapListenSocket - # Update globals - _load("scapy.arch.pcapdnet") - return - if conf.use_bpf: - from scapy.arch.bpf.supersocket import L2bpfListenSocket, \ - L2bpfSocket, L3bpfSocket - conf.L3socket = L3bpfSocket - conf.L3socket6 = functools.partial(L3bpfSocket, filter="ip6") - conf.L2socket = L2bpfSocket - conf.L2listen = L2bpfListenSocket - # Update globals - _load("scapy.arch.bpf") - return - if LINUX: - from scapy.arch.linux import L3PacketSocket, L2Socket, L2ListenSocket - conf.L3socket = L3PacketSocket - conf.L3socket6 = functools.partial(L3PacketSocket, filter="ip6") - conf.L2socket = L2Socket - conf.L2listen = L2ListenSocket - # Update globals - _load("scapy.arch.linux") - return - if WINDOWS: - from scapy.arch.windows import _NotAvailableSocket - from scapy.arch.windows.native import L3WinSocket, L3WinSocket6 - conf.L3socket = L3WinSocket - conf.L3socket6 = L3WinSocket6 - conf.L2socket = _NotAvailableSocket - conf.L2listen = _NotAvailableSocket - # No need to update globals on Windows - return - from scapy.supersocket import L3RawSocket - from scapy.layers.inet6 import L3RawSocket6 - conf.L3socket = L3RawSocket - conf.L3socket6 = L3RawSocket6 - - -def _socket_changer(attr, val): - if not isinstance(val, bool): - raise TypeError("This argument should be a boolean") - dependencies = { # Things that will be turned off - "use_pcap": ["use_bpf"], - "use_bpf": ["use_pcap"], - } - restore = {k: getattr(conf, k) for k in dependencies} - del restore[attr] # This is handled directly by _set_conf_sockets - if val: # Only if True - for param in dependencies[attr]: - Interceptor.set_from_hook(conf, param, False) - try: - _set_conf_sockets() - except (ScapyInvalidPlatformException, ImportError) as e: - for key, value in restore.items(): - Interceptor.set_from_hook(conf, key, value) - if isinstance(e, ScapyInvalidPlatformException): - raise - - -def _loglevel_changer(attr, val): - """Handle a change of conf.logLevel""" - log_scapy.setLevel(val) - - -class Conf(ConfClass): - """This object contains the configuration of Scapy. -session : filename where the session will be saved -interactive_shell : can be "ipython", "python" or "auto". Default: Auto -stealth : if 1, prevents any unwanted packet to go out (ARP, DNS, ...) -checkIPID: if 0, doesn't check that IPID matches between IP sent and ICMP IP citation received # noqa: E501 - if 1, checks that they either are equal or byte swapped equals (bug in some IP stacks) # noqa: E501 - if 2, strictly checks that they are equals -checkIPsrc: if 1, checks IP src in IP and ICMP IP citation match (bug in some NAT stacks) # noqa: E501 -checkIPinIP: if True, checks that IP-in-IP layers match. If False, do not - check IP layers that encapsulates another IP layer -check_TCPerror_seqack: if 1, also check that TCP seq and ack match the ones in ICMP citation # noqa: E501 -iff : selects the default output interface for srp() and sendp(). default:"eth0") # noqa: E501 -verb : level of verbosity, from 0 (almost mute) to 3 (verbose) -promisc : default mode for listening socket (to get answers if you spoof on a lan) # noqa: E501 -sniff_promisc : default mode for sniff() -filter : bpf filter added to every sniffing socket to exclude traffic from analysis # noqa: E501 -histfile : history file -padding : includes padding in disassembled packets -except_filter : BPF filter for packets to ignore -debug_match : when 1, store received packet that are not matched into debug.recv # noqa: E501 -route : holds the Scapy routing table and provides methods to manipulate it -warning_threshold : how much time between warnings from the same place -ASN1_default_codec: Codec used by default for ASN1 objects -mib : holds MIB direct access dictionary -resolve : holds list of fields for which resolution should be done -noenum : holds list of enum fields for which conversion to string should NOT be done # noqa: E501 -AS_resolver: choose the AS resolver class to use -extensions_paths: path or list of paths where extensions are to be looked for -contribs : a dict which can be used by contrib layers to store local configuration # noqa: E501 -debug_tls:When 1, print some TLS session secrets when they are computed. -recv_poll_rate: how often to check for new packets. Defaults to 0.05s. -""" - version = ReadOnlyAttribute("version", VERSION) - session = "" - interactive = False - interactive_shell = "" - stealth = "not implemented" - iface = None - iface6 = None - layers = LayersList() - commands = CommandsList() - dot15d4_protocol = None # Used in dot15d4.py - logLevel = Interceptor("logLevel", log_scapy.level, _loglevel_changer) - checkIPID = False - checkIPsrc = True - checkIPaddr = True - checkIPinIP = True - check_TCPerror_seqack = False - verb = 2 - prompt = Interceptor("prompt", ">>> ", _prompt_changer) - promisc = True - sniff_promisc = 1 - raw_layer = None - raw_summary = False - default_l2 = None - l2types = Num2Layer() - l3types = Num2Layer() - L3socket = None - L3socket6 = None - L2socket = None - L2listen = None - BTsocket = None - USBsocket = None - min_pkt_size = 60 - bufsize = 2**16 - histfile = os.getenv('SCAPY_HISTFILE', - os.path.join(os.path.expanduser("~"), - ".scapy_history")) - padding = 1 - except_filter = "" - debug_match = False - debug_tls = False - wepkey = "" - cache_iflist = {} - route = None # Filed by route.py - route6 = None # Filed by route6.py - auto_fragment = True - debug_dissector = False - color_theme = Interceptor("color_theme", NoTheme(), _prompt_changer) - warning_threshold = 5 - prog = ProgPath() - resolve = Resolve() - noenum = Resolve() - emph = Emphasize() - use_pypy = ReadOnlyAttribute("use_pypy", isPyPy()) - use_pcap = Interceptor( - "use_pcap", - os.getenv("SCAPY_USE_PCAPDNET", "").lower().startswith("y"), - _socket_changer - ) - # XXX use_dnet is deprecated - use_dnet = os.getenv("SCAPY_USE_PCAPDNET", "").lower().startswith("y") - use_bpf = Interceptor("use_bpf", False, _socket_changer) - use_npcap = False - ipv6_enabled = socket.has_ipv6 - extensions_paths = "." - stats_classic_protocols = [] - stats_dot11_protocols = [] - temp_files = [] - netcache = NetCache() - geoip_city = None - # can, tls, http are not loaded by default - load_layers = ['bluetooth', 'bluetooth4LE', 'dhcp', 'dhcp6', 'dns', - 'dot11', 'dot15d4', 'eap', 'gprs', 'hsrp', 'inet', - 'inet6', 'ipsec', 'ir', 'isakmp', 'l2', 'l2tp', - 'llmnr', 'lltd', 'mgcp', 'mobileip', 'netbios', - 'netflow', 'ntp', 'ppi', 'ppp', 'pptp', 'radius', 'rip', - 'rtp', 'sctp', 'sixlowpan', 'skinny', 'smb', 'snmp', - 'tftp', 'vrrp', 'vxlan', 'x509', 'zigbee'] - contribs = dict() - crypto_valid = isCryptographyValid() - crypto_valid_recent = isCryptographyRecent() - crypto_valid_advanced = crypto_valid_recent and isCryptographyAdvanced() - fancy_prompt = True - auto_crop_tables = True - recv_poll_rate = 0.05 - - def __getattr__(self, attr): - # Those are loaded on runtime to avoid import loops - if attr == "manufdb": - from scapy.data import MANUFDB - return MANUFDB - if attr == "ethertypes": - from scapy.data import ETHER_TYPES - return ETHER_TYPES - if attr == "protocols": - from scapy.data import IP_PROTOS - return IP_PROTOS - if attr == "services_udp": - from scapy.data import UDP_SERVICES - return UDP_SERVICES - if attr == "services_tcp": - from scapy.data import TCP_SERVICES - return TCP_SERVICES - return object.__getattr__(self, attr) - - -if not Conf.ipv6_enabled: - log_scapy.warning("IPv6 support disabled in Python. Cannot load Scapy IPv6 layers.") # noqa: E501 - for m in ["inet6", "dhcp6"]: - if m in Conf.load_layers: - Conf.load_layers.remove(m) - -conf = Conf() - - -def crypto_validator(func): - """ - This a decorator to be used for any method relying on the cryptography library. # noqa: E501 - Its behaviour depends on the 'crypto_valid' attribute of the global 'conf'. - """ - def func_in(*args, **kwargs): - if not conf.crypto_valid: - raise ImportError("Cannot execute crypto-related method! " - "Please install python-cryptography v1.7 or later.") # noqa: E501 - return func(*args, **kwargs) - return func_in diff --git a/scripts/external_libs/scapy-2.4.3/scapy/consts.py b/scripts/external_libs/scapy-2.4.3/scapy/consts.py deleted file mode 100644 index 952d34ed05..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/consts.py +++ /dev/null @@ -1,35 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -import os -from sys import platform, maxsize -import platform as platform_lib - -LINUX = platform.startswith("linux") -OPENBSD = platform.startswith("openbsd") -FREEBSD = "freebsd" in platform -NETBSD = platform.startswith("netbsd") -DARWIN = platform.startswith("darwin") -SOLARIS = platform.startswith("sunos") -WINDOWS = platform.startswith("win32") -WINDOWS_XP = platform_lib.release() == "XP" -BSD = DARWIN or FREEBSD or OPENBSD or NETBSD -# See https://docs.python.org/3/library/platform.html#cross-platform -IS_64BITS = maxsize > 2**32 - -if WINDOWS: - try: - if float(platform_lib.release()) >= 8.1: - LOOPBACK_NAME = "Microsoft KM-TEST Loopback Adapter" - else: - LOOPBACK_NAME = "Microsoft Loopback Adapter" - except ValueError: - LOOPBACK_NAME = "Microsoft Loopback Adapter" - # Will be different on Windows - LOOPBACK_INTERFACE = None -else: - uname = os.uname() - LOOPBACK_NAME = "lo" if LINUX else "lo0" - LOOPBACK_INTERFACE = LOOPBACK_NAME diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/__init__.py deleted file mode 100644 index 496a2f92cc..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Package of contrib modules that have to be loaded explicitly. -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/altbeacon.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/altbeacon.py deleted file mode 100644 index 75ce3aeaf5..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/altbeacon.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- mode: python3; indent-tabs-mode: nil; tab-width: 4 -*- -# altbeacon.py - protocol handlers for AltBeacon -# -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Michael Farrell -# This program is published under a GPLv2 (or later) license -# -# scapy.contrib.description = AltBeacon BLE proximity beacon -# scapy.contrib.status = loads -""" -scapy.contrib.altbeacon - AltBeacon Bluetooth LE proximity beacons. - -The AltBeacon specification can be found at: https://github.com/AltBeacon/spec -""" - -from scapy.fields import ByteField, ShortField, SignedByteField, \ - StrFixedLenField -from scapy.layers.bluetooth import EIR_Hdr, EIR_Manufacturer_Specific_Data, \ - UUIDField, LowEnergyBeaconHelper -from scapy.packet import Packet - - -# When building beacon frames, one should use their own manufacturer ID. -# -# However, most software (including the AltBeacon SDK) requires explicitly -# registering particular manufacturer IDs to listen to, and the only ID used is -# that of Radius Networks (the developer of the specification). -# -# To maximise compatibility, Scapy's implementation of -# LowEnergyBeaconHelper.build_eir (for constructing frames) uses Radius -# Networks' manufacturer ID. -# -# Scapy's implementation of AltBeacon **does not** require a specific -# manufacturer ID to detect AltBeacons - it uses -# EIR_Manufacturer_Specific_Data.register_magic_payload. -RADIUS_NETWORKS_MFG = 0x0118 - - -class AltBeacon(Packet, LowEnergyBeaconHelper): - """ - AltBeacon broadcast frame type. - - https://github.com/AltBeacon/spec - """ - name = "AltBeacon" - magic = b"\xBE\xAC" - fields_desc = [ - StrFixedLenField("header", magic, len(magic)), - - # The spec says this is 20 bytes, with >=16 bytes being an - # organisational unit-specific identifier. However, the Android library - # treats this as UUID + uint16 + uint16. - UUIDField("id1", None), - - # Local identifier - ShortField("id2", None), - ShortField("id3", None), - - SignedByteField("tx_power", None), - ByteField("mfg_reserved", None), - ] - - @classmethod - def magic_check(cls, payload): - """ - Checks if the given payload is for us (starts with our magic string). - """ - return payload.startswith(cls.magic) - - def build_eir(self): - """Builds a list of EIR messages to wrap this frame.""" - - # Note: Company ID is not required by spec, but most tools only look - # for manufacturer-specific data with Radius Networks' manufacturer ID. - return LowEnergyBeaconHelper.base_eir + [ - EIR_Hdr() / EIR_Manufacturer_Specific_Data( - company_id=RADIUS_NETWORKS_MFG) / self - ] - - -EIR_Manufacturer_Specific_Data.register_magic_payload(AltBeacon) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/anqp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/anqp.py deleted file mode 100644 index 54c8e32f20..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/anqp.py +++ /dev/null @@ -1,89 +0,0 @@ -# TRex Change -from scapy.layers.dot11 import * -import struct - -gas_types = { - 10: 'GAS Initial Request', - 11: 'GAS Initial Response', - 12: 'GAS Comeback Request', - 13: 'GAS Comeback Response' -} - -class Dot11uGASAction(Packet): - name = "802.11 GAS Action Frame" - fields_desc = [ - ByteField("category", 4), # Public action frame - ByteEnumField('action', 10, gas_types), - ByteField("dialogToken", 0), - ] - -class Dot11uGASInitialRequest(Packet): - name = "802.11 GAS Initial Request ANQP Frame" - fields_desc = [ - ByteField("tagNumber", 0x6c), # ANQP - ByteField("tagLength", 2), # Tag length as from 802.11u - BitField("pameBI", 0, 1), - BitField("queryResponse", 0, 7), - ByteField("advProtocol", 0), # ANQP - LenField("queryLength", 0, fmt=' -## -# This program is published under a GPLv2 license - - -# scapy.contrib.description = ATA Over Internet -# scapy.contrib.status = loads - -from scapy.packet import Packet, bind_layers -from scapy.fields import FlagsField, XByteField, ByteField, XShortField, \ - ShortField, StrLenField, BitField, BitEnumField, ByteEnumField, \ - FieldLenField, PacketListField, FieldListField, MACField, PacketField, \ - ConditionalField, XIntField -from scapy.layers.l2 import Ether -from scapy.data import ETHER_ANY - - -class IssueATACommand(Packet): - name = "Issue ATA Command" - fields_desc = [FlagsField("flags", 0, 8, "zezdzzaw"), - XByteField("err_feature", 0), - ByteField("sector_count", 1), - XByteField("cmd_status", 0xec), - XByteField("lba0", 0), - XByteField("lba1", 0), - XByteField("lba2", 0), - XByteField("lba3", 0), - XByteField("lba4", 0), - XByteField("lba5", 0), - XShortField("reserved", 0), - StrLenField("data", "", - length_from=lambda x: x.sector_count * 512)] - - def extract_padding(self, s): - return "", s - - -class QueryConfigInformation(Packet): - name = "Query Config Information" - fields_desc = [ShortField("buffer_count", 0), - ShortField("firmware", 0), - ByteField("sector_count", 0), - BitField("aoe", 0, 4), - BitEnumField("ccmd", 0, 4, {0: "Read config string", - 1: "Test config string", - 2: "Test config string prefix", - 3: "Set config string", - 4: "Force set config string"}), - FieldLenField("config_length", None, length_of="config"), - StrLenField("config", None, - length_from=lambda x: x.config_length)] - - def extract_padding(self, s): - return "", s - - -class Directive(Packet): - name = "Directive" - fields_desc = [ByteField("reserved", 0), - ByteEnumField("dcmd", 0, - {0: "No directive", - 1: "Add mac address to mask list", - 2: "Delete mac address from mask list"}), - MACField("mac_addr", ETHER_ANY)] - - -class MacMaskList(Packet): - name = "Mac Mask List" - fields_desc = [ByteField("reserved", 0), - ByteEnumField("mcmd", 0, {0: "Read Mac Mask List", - 1: "Edit Mac Mask List"}), - ByteEnumField("merror", 0, {0: "", - 1: "Unspecified error", - 2: "Bad dcmd directive", - 3: "Mask List Full"}), - FieldLenField("dir_count", None, count_of="directives"), - PacketListField("directives", None, Directive, - count_from=lambda pkt: pkt.dir_count)] - - def extract_padding(self, s): - return "", s - - -class ReserveRelease(Packet): - name = "Reserve / Release" - fields_desc = [ByteEnumField("rcmd", 0, {0: "Read Reserve List", - 1: "Set Reserve List", - 2: "Force Set Reserve List"}), - FieldLenField("nb_mac", None, count_of="mac_addrs"), - FieldListField("mac_addrs", None, MACField("", ETHER_ANY), - count_from=lambda pkt: pkt.nb_mac)] - - def extract_padding(self, s): - return "", s - - -class AOE(Packet): - name = "ATA over Ethernet" - fields_desc = [BitField("version", 1, 4), - FlagsField("flags", 0, 4, ["Response", "Error", - "r1", "r2"]), - ByteEnumField("error", 0, {1: "Unrecognized command code", - 2: "Bad argument parameter", - 3: "Device unavailable", - 4: "Config string present", - 5: "Unsupported exception", - 6: "Target is reserved"}), - XShortField("major", 0xFFFF), - XByteField("minor", 0xFF), - ByteEnumField("cmd", 1, {0: "Issue ATA Command", - 1: "Query Config Information", - 2: "Mac Mask List", - 3: "Reserve / Release"}), - XIntField("tag", 0), - ConditionalField(PacketField("i_ata_cmd", IssueATACommand(), - IssueATACommand), - lambda x: x.cmd == 0), - ConditionalField(PacketField("q_conf_info", - QueryConfigInformation(), - QueryConfigInformation), - lambda x: x.cmd == 1), - ConditionalField(PacketField("mac_m_list", MacMaskList(), - MacMaskList), - lambda x: x.cmd == 2), - ConditionalField(PacketField("res_rel", ReserveRelease(), - ReserveRelease), - lambda x: x.cmd == 3)] - - def extract_padding(self, s): - return "", s - - -bind_layers(Ether, AOE, type=0x88A2) -bind_layers(AOE, IssueATACommand, cmd=0) -bind_layers(AOE, QueryConfigInformation, cmd=1) -bind_layers(AOE, MacMaskList, cmd=2) -bind_layers(AOE, ReserveRelease, cmd=3) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/__init__.py deleted file mode 100644 index d992d4cd52..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -""" -Package of contrib automotive modules that have to be loaded explicitly. -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/bmw/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/bmw/__init__.py deleted file mode 100644 index f06000ab15..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/bmw/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -""" -Package of contrib automotive bmw specific modules -that have to be loaded explicitly. -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/bmw/enet.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/bmw/enet.py deleted file mode 100644 index 078dd325b7..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/bmw/enet.py +++ /dev/null @@ -1,72 +0,0 @@ -#! /usr/bin/env python - -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.description = ENET - BMW diagnostic protocol over Ethernet -# scapy.contrib.status = loads - -import struct -import socket -from scapy.packet import Packet, bind_layers, bind_bottom_up -from scapy.fields import IntField, ShortEnumField, XByteField -from scapy.layers.inet import TCP -from scapy.supersocket import StreamSocket -from scapy.contrib.automotive.uds import UDS - - -""" -BMW specific diagnostic over IP protocol implementation ENET -""" - -# #########################ENET################################### - - -class ENET(Packet): - name = 'ENET' - fields_desc = [ - IntField('length', None), - ShortEnumField('type', 1, {0x01: "message", - 0x02: "echo"}), - XByteField('src', 0), - XByteField('dst', 0), - ] - - def hashret(self): - hdr_hash = struct.pack("B", self.src ^ self.dst) - pay_hash = self.payload.hashret() - return hdr_hash + pay_hash - - def answers(self, other): - if other.__class__ == self.__class__: - return self.payload.answers(other.payload) - return 0 - - def extract_padding(self, s): - return s[:self.length - 2], s[self.length - 2:] - - def post_build(self, pkt, pay): - """ - This will set the LenField 'length' to the correct value. - """ - if self.length is None: - pkt = struct.pack("!I", len(pay) + 2) + pkt[4:] - return pkt + pay - - -bind_bottom_up(TCP, ENET, sport=6801) -bind_bottom_up(TCP, ENET, dport=6801) -bind_layers(TCP, ENET, sport=6801, dport=6801) -bind_layers(ENET, UDS) - - -# ########################ENETSocket################################### - - -class ENETSocket(StreamSocket): - def __init__(self, ip='127.0.0.1', port=6801): - s = socket.socket() - s.connect((ip, port)) - StreamSocket.__init__(self, s, ENET) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/ccp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/ccp.py deleted file mode 100644 index e1763c197d..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/ccp.py +++ /dev/null @@ -1,590 +0,0 @@ -#! /usr/bin/env python - -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.description = CAN Calibration Protocol (CCP) -# scapy.contrib.status = loads - -import struct - -from scapy.packet import Packet, bind_layers, bind_bottom_up -from scapy.fields import XIntField, FlagsField, ByteEnumField, \ - ThreeBytesField, XBitField, ShortField, IntField, XShortField, \ - ByteField, XByteField, StrFixedLenField, LEShortField -from scapy.layers.can import CAN - - -class CCP(CAN): - name = 'CAN Calibration Protocol' - fields_desc = [ - FlagsField('flags', 0, 3, ['error', - 'remote_transmission_request', - 'extended']), - XBitField('identifier', 0, 29), - ByteField('length', 8), - ThreeBytesField('reserved', 0), - ] - - def extract_padding(self, p): - return p, None - - -class CRO(Packet): - commands = { - 0x01: "CONNECT", - 0x1B: "GET_CCP_VERSION", - 0x17: "EXCHANGE_ID", - 0x12: "GET_SEED", - 0x13: "UNLOCK", - 0x02: "SET_MTA", - 0x03: "DNLOAD", - 0x23: "DNLOAD_6", - 0x04: "UPLOAD", - 0x0F: "SHORT_UP", - 0x11: "SELECT_CAL_PAGE", - 0x14: "GET_DAQ_SIZE", - 0x15: "SET_DAQ_PTR", - 0x16: "WRITE_DAQ", - 0x06: "START_STOP", - 0x07: "DISCONNECT", - 0x0C: "SET_S_STATUS", - 0x0D: "GET_S_STATUS", - 0x0E: "BUILD_CHKSUM", - 0x10: "CLEAR_MEMORY", - 0x18: "PROGRAM", - 0x22: "PROGRAM_6", - 0x19: "MOVE", - 0x05: "TEST", - 0x09: "GET_ACTIVE_CAL_PAGE", - 0x08: "START_STOP_ALL", - 0x20: "DIAG_SERVICE", - 0x21: "ACTION_SERVICE" - } - name = 'Command Receive Object' - fields_desc = [ - ByteEnumField('cmd', 0x01, commands), - ByteField('ctr', 0) - ] - - def hashret(self): - return struct.pack('B', self.ctr) - - -# ##### CROs ###### - -class CONNECT(Packet): - fields_desc = [ - LEShortField('station_address', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 4, length=4), - ] - - -bind_layers(CRO, CONNECT, cmd=0x01) - - -class GET_CCP_VERSION(Packet): - fields_desc = [ - XByteField('main_protocol_version', 0), - XByteField('release_version', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 4, length=4) - ] - - -bind_layers(CRO, GET_CCP_VERSION, cmd=0x1B) - - -class EXCHANGE_ID(Packet): - fields_desc = [ - StrFixedLenField('ccp_master_device_id', b'\x00' * 6, length=6) - ] - - -bind_layers(CRO, EXCHANGE_ID, cmd=0x17) - - -class GET_SEED(Packet): - fields_desc = [ - XByteField('resource', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 5, length=5) - ] - - -bind_layers(CRO, GET_SEED, cmd=0x12) - - -class UNLOCK(Packet): - fields_desc = [ - StrFixedLenField('key', b'\x00' * 6, length=6) - ] - - -bind_layers(CRO, UNLOCK, cmd=0x13) - - -class SET_MTA(Packet): - fields_desc = [ - XByteField('mta_num', 0), - XByteField('address_extension', 0), - XIntField('address', 0), - ] - - -bind_layers(CRO, SET_MTA, cmd=0x02) - - -class DNLOAD(Packet): - fields_desc = [ - XByteField('size', 0), - StrFixedLenField('data', b'\x00' * 5, length=5) - ] - - -bind_layers(CRO, DNLOAD, cmd=0x03) - - -class DNLOAD_6(Packet): - fields_desc = [ - StrFixedLenField('data', b'\x00' * 6, length=6) - ] - - -bind_layers(CRO, DNLOAD_6, cmd=0x23) - - -class UPLOAD(Packet): - fields_desc = [ - XByteField('size', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 5, length=5) - ] - - -bind_layers(CRO, UPLOAD, cmd=0x04) - - -class SHORT_UP(Packet): - fields_desc = [ - XByteField('size', 0), - XByteField('address_extension', 0), - XIntField('address', 0), - ] - - -bind_layers(CRO, SHORT_UP, cmd=0x0F) - - -class SELECT_CAL_PAGE(Packet): - fields_desc = [ - StrFixedLenField('ccp_reserved', b'\xff' * 6, length=6) - ] - - -bind_layers(CRO, SELECT_CAL_PAGE, cmd=0x11) - - -class GET_DAQ_SIZE(Packet): - fields_desc = [ - XByteField('DAQ_num', 0), - XByteField('ccp_reserved', 0), - XIntField('DTO_identifier', 0), - ] - - -bind_layers(CRO, GET_DAQ_SIZE, cmd=0x14) - - -class SET_DAQ_PTR(Packet): - fields_desc = [ - XByteField('DAQ_num', 0), - XByteField('ODT_num', 0), - XByteField('ODT_element', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 3, length=3) - ] - - -bind_layers(CRO, SET_DAQ_PTR, cmd=0x15) - - -class WRITE_DAQ(Packet): - fields_desc = [ - XByteField('DAQ_size', 0), - XByteField('address_extension', 0), - XIntField('address', 0), - ] - - -bind_layers(CRO, WRITE_DAQ, cmd=0x16) - - -class START_STOP(Packet): - fields_desc = [ - XByteField('mode', 0), - XByteField('DAQ_num', 0), - XByteField('ODT_num', 0), - XByteField('event_channel', 0), - XShortField('transmission_rate', 0), - ] - - -bind_layers(CRO, START_STOP, cmd=0x06) - - -class DISCONNECT(Packet): - fields_desc = [ - ByteEnumField('type', 0, {0: "temporary", 1: "end_of_session"}), - StrFixedLenField('ccp_reserved0', b'\xff' * 1, length=1), - LEShortField('station_address', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 2, length=2) - ] - - -bind_layers(CRO, DISCONNECT, cmd=0x07) - - -class SET_S_STATUS(Packet): - name = "Set Session Status" - fields_desc = [ - FlagsField("session_status", 0, 8, ["CAL", "DAQ", "RESUME", "RES0", - "RES1", "RES2", "STORE", "RUN"]), - StrFixedLenField('ccp_reserved', b'\xff' * 5, length=5) - ] - - -bind_layers(CRO, SET_S_STATUS, cmd=0x0C) - - -class GET_S_STATUS(Packet): - fields_desc = [ - StrFixedLenField('ccp_reserved', b'\xff' * 6, length=6) - ] - - -bind_layers(CRO, GET_S_STATUS, cmd=0x0D) - - -class BUILD_CHKSUM(Packet): - fields_desc = [ - IntField('size', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 2, length=2) - ] - - -bind_layers(CRO, BUILD_CHKSUM, cmd=0x0E) - - -class CLEAR_MEMORY(Packet): - fields_desc = [ - IntField('size', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 2, length=2) - ] - - -bind_layers(CRO, CLEAR_MEMORY, cmd=0x10) - - -class PROGRAM(Packet): - fields_desc = [ - XByteField('size', 0), - StrFixedLenField('data', b'\x00' * 0, - length_from=lambda pkt: pkt.size), - StrFixedLenField('ccp_reserved', b'\xff' * 5, - length_from=lambda pkt: 5 - pkt.size) - ] - - -bind_layers(CRO, PROGRAM, cmd=0x18) - - -class PROGRAM_6(Packet): - fields_desc = [ - StrFixedLenField('data', b'\x00' * 6, length=6) - ] - - -bind_layers(CRO, PROGRAM_6, cmd=0x22) - - -class MOVE(Packet): - fields_desc = [ - IntField('size', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 2, length=2) - ] - - -bind_layers(CRO, MOVE, cmd=0x19) - - -class TEST(Packet): - fields_desc = [ - LEShortField('station_address', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 4, length=4) - ] - - -bind_layers(CRO, TEST, cmd=0x05) - - -class GET_ACTIVE_CAL_PAGE(Packet): - fields_desc = [ - StrFixedLenField('ccp_reserved', b'\xff' * 6, length=6) - ] - - -bind_layers(CRO, GET_ACTIVE_CAL_PAGE, cmd=0x09) - - -class START_STOP_ALL(Packet): - fields_desc = [ - ByteEnumField('type', 0, {0: "stop", 1: "start"}), - StrFixedLenField('ccp_reserved', b'\xff' * 5, length=5) - - ] - - -bind_layers(CRO, START_STOP_ALL, cmd=0x08) - - -class DIAG_SERVICE(Packet): - fields_desc = [ - ShortField('diag_service', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 4, length=4) - ] - - -bind_layers(CRO, DIAG_SERVICE, cmd=0x20) - - -class ACTION_SERVICE(Packet): - fields_desc = [ - ShortField('action_service', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 4, length=4) - ] - - -bind_layers(CRO, ACTION_SERVICE, cmd=0x21) - - -# ##### DTOs ###### - -class DEFAULT_DTO(Packet): - fields_desc = [ - StrFixedLenField('load', b'\xff' * 5, length=5), - ] - - -class GET_CCP_VERSION_DTO(Packet): - fields_desc = [ - XByteField('main_protocol_version', 0), - XByteField('release_version', 0), - StrFixedLenField('ccp_reserved', b'\x00' * 3, length=3) - ] - - -class EXCHANGE_ID_DTO(Packet): - fields_desc = [ - ByteField('slave_device_ID_length', 0), - ByteField('data_type_qualifier', 0), - ByteField('resource_availability_mask', 0), - ByteField('resource_protection_mask', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 1, length=1), - ] - - -class GET_SEED_DTO(Packet): - fields_desc = [ - XByteField('protection_status', 0), - StrFixedLenField('seed', b'\x00' * 4, length=4) - ] - - -class UNLOCK_DTO(Packet): - fields_desc = [ - ByteField('privilege_status', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 4, length=4), - ] - - -class DNLOAD_DTO(Packet): - fields_desc = [ - XByteField('MTA0_extension', 0), - XIntField('MTA0_address', 0) - ] - - -class DNLOAD_6_DTO(Packet): - fields_desc = [ - XByteField('MTA0_extension', 0), - XIntField('MTA0_address', 0) - ] - - -class UPLOAD_DTO(Packet): - fields_desc = [ - StrFixedLenField('data', b'\x00' * 5, length=5) - ] - - -class SHORT_UP_DTO(Packet): - fields_desc = [ - StrFixedLenField('data', b'\x00' * 5, length=5) - ] - - -class GET_DAQ_SIZE_DTO(Packet): - fields_desc = [ - XByteField('DAQ_list_size', 0), - XByteField('first_pid', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 3, length=3) - ] - - -class GET_S_STATUS_DTO(Packet): - fields_desc = [ - FlagsField("session_status", 0, 8, ["CAL", "DAQ", "RESUME", "RES0", - "RES1", "RES2", "STORE", "RUN"]), - ByteField('information_qualifier', 0), - StrFixedLenField('information', b'\x00' * 3, length=3) - ] - - -class BUILD_CHKSUM_DTO(Packet): - fields_desc = [ - ByteField('checksum_size', 0), - StrFixedLenField('checksum_data', b'\x00' * 4, - length_from=lambda pkt: pkt.checksum_size), - StrFixedLenField('ccp_reserved', b'\xff' * 0, - length_from=lambda pkt: 4 - pkt.checksum_size) - ] - - -class PROGRAM_DTO(Packet): - fields_desc = [ - ByteField('MTA0_extension', 0), - XIntField('MTA0_address', 0) - ] - - -class PROGRAM_6_DTO(Packet): - fields_desc = [ - ByteField('MTA0_extension', 0), - XIntField('MTA0_address', 0) - ] - - -class GET_ACTIVE_CAL_PAGE_DTO(Packet): - fields_desc = [ - XByteField('address_extension', 0), - XIntField('address', 0) - ] - - -class DIAG_SERVICE_DTO(Packet): - fields_desc = [ - ByteField('data_length', 0), - ByteField('data_type', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 3, length=3) - ] - - -class ACTION_SERVICE_DTO(Packet): - fields_desc = [ - ByteField('data_length', 0), - ByteField('data_type', 0), - StrFixedLenField('ccp_reserved', b'\xff' * 3, length=3) - ] - - -class DTO(Packet): - __slots__ = Packet.__slots__ + ["payload_cls"] - - return_codes = { - 0x00: "acknowledge / no error", - 0x01: "DAQ processor overload", - 0x10: "command processor busy", - 0x11: "DAQ processor busy", - 0x12: "internal timeout", - 0x18: "key request", - 0x19: "session status request", - 0x20: "cold start request", - 0x21: "cal. data init. request", - 0x22: "DAQ list init. request", - 0x23: "code update request", - 0x30: "unknown command", - 0x31: "command syntax", - 0x32: "parameter(s) out of range", - 0x33: "access denied", - 0x34: "overload", - 0x35: "access locked", - 0x36: "resource/function not available" - } - fields_desc = [ - XByteField("packet_id", 0xff), - ByteEnumField('return_code', 0x00, return_codes), - ByteField('ctr', 0) - ] - - def __init__(self, *args, **kwargs): - self.payload_cls = DEFAULT_DTO - if "payload_cls" in kwargs: - self.payload_cls = kwargs["payload_cls"] - del kwargs["payload_cls"] - Packet.__init__(self, *args, **kwargs) - - def guess_payload_class(self, payload): - return self.payload_cls - - @staticmethod - def get_dto_cls(cmd): - try: - return { - 0x03: DNLOAD_DTO, - 0x04: UPLOAD_DTO, - 0x09: GET_ACTIVE_CAL_PAGE_DTO, - 0x0D: GET_S_STATUS_DTO, - 0x0E: BUILD_CHKSUM_DTO, - 0x0F: SHORT_UP_DTO, - 0x12: GET_SEED_DTO, - 0x13: UNLOCK_DTO, - 0x14: GET_DAQ_SIZE_DTO, - 0x17: EXCHANGE_ID_DTO, - 0x18: PROGRAM_DTO, - 0x1B: GET_CCP_VERSION_DTO, - 0x20: DIAG_SERVICE_DTO, - 0x21: ACTION_SERVICE_DTO, - 0x22: PROGRAM_6_DTO, - 0x23: DNLOAD_6_DTO - }[cmd] - except KeyError: - return DEFAULT_DTO - - def answers(self, other): - """In CCP, the payload of a DTO packet is dependent on the cmd field - of a corresponding CRO packet. Two packets correspond, if there - ctr field is equal. If answers detect the corresponding CRO, it will - interpret the payload of a DTO with the correct class. In CCP, there is - no other way, to determine the class of a DTO payload. Since answers is - called on sr and sr1, this modification of the original answers - implementation will give a better user experience. """ - if not hasattr(other, "ctr"): - return 0 - if self.ctr != other.ctr: - return 0 - if not hasattr(other, "cmd"): - return 0 - - new_pl_cls = self.get_dto_cls(other.cmd) - if self.payload_cls != new_pl_cls and \ - self.payload_cls == DEFAULT_DTO: - data = bytes(self.load) - self.remove_payload() - self.add_payload(new_pl_cls(data)) - self.payload_cls = new_pl_cls - return 1 - - def hashret(self): - return struct.pack('B', self.ctr) - - -bind_bottom_up(CCP, DTO) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/gm/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/gm/__init__.py deleted file mode 100644 index 3e4219ec56..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/gm/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -""" -Package of contrib automotive gm specific modules -that have to be loaded explicitly. -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/gm/gmlan.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/gm/gmlan.py deleted file mode 100644 index 7801d9ba7b..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/gm/gmlan.py +++ /dev/null @@ -1,654 +0,0 @@ -#! /usr/bin/env python - -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Nils Weiss -# Copyright (C) Enrico Pozzobon -# This program is published under a GPLv2 license - -# scapy.contrib.description = General Motors Local Area Network (GMLAN) -# scapy.contrib.status = loads - -import struct -from scapy.fields import ObservableDict, XByteEnumField, ByteEnumField, \ - ConditionalField, XByteField, StrField, XShortEnumField, XShortField, \ - X3BytesField, XIntField, ShortField, PacketField, PacketListField, \ - FieldListField -from scapy.packet import Packet, bind_layers -from scapy.config import conf -from scapy.error import warning -from scapy.utils import PeriodicSenderThread - - -""" -GMLAN -""" - -conf.contribs['GMLAN'] = {'GMLAN_ECU_AddressingScheme': None} - - -class GMLAN(Packet): - @staticmethod - def determine_len(x): - if conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] is None: - warning("Define conf.GMLAN_ECU_AddressingScheme! " - "Assign either 2,3 or 4") - if conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] \ - not in [2, 3, 4]: - warning("Define conf.GMLAN_ECU_AddressingScheme! " - "Assign either 2,3 or 4") - return conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] == x - - services = ObservableDict( - {0x04: 'ClearDiagnosticInformation', - 0x10: 'InitiateDiagnosticOperation', - 0x12: 'ReadFailureRecordData', - 0x1a: 'ReadDataByIdentifier', - 0x20: 'ReturnToNormalOperation', - 0x22: 'ReadDataByParameterIdentifier', - 0x23: 'ReadMemoryByAddress', - 0x27: 'SecurityAccess', - 0x28: 'DisableNormalCommunication', - 0x2c: 'DynamicallyDefineMessage', - 0x2d: 'DefinePIDByAddress', - 0x34: 'RequestDownload', - 0x36: 'TransferData', - 0x3b: 'WriteDataByIdentifier', - 0x3e: 'TesterPresent', - 0x44: 'ClearDiagnosticInformationPositiveResponse', - 0x50: 'InitiateDiagnosticOperationPositiveResponse', - 0x52: 'ReadFailureRecordDataPositiveResponse', - 0x5a: 'ReadDataByIdentifierPositiveResponse', - 0x60: 'ReturnToNormalOperationPositiveResponse', - 0x62: 'ReadDataByParameterIdentifierPositiveResponse', - 0x63: 'ReadMemoryByAddressPositiveResponse', - 0x67: 'SecurityAccessPositiveResponse', - 0x68: 'DisableNormalCommunicationPositiveResponse', - 0x6c: 'DynamicallyDefineMessagePositiveResponse', - 0x6d: 'DefinePIDByAddressPositiveResponse', - 0x74: 'RequestDownloadPositiveResponse', - 0x76: 'TransferDataPositiveResponse', - 0x7b: 'WriteDataByIdentifierPositiveResponse', - 0x7e: 'TesterPresentPositiveResponse', - 0x7f: 'NegativeResponse', - 0xa2: 'ReportProgrammingState', - 0xa5: 'ProgrammingMode', - 0xa9: 'ReadDiagnosticInformation', - 0xaa: 'ReadDataByPacketIdentifier', - 0xae: 'DeviceControl', - 0xe2: 'ReportProgrammingStatePositiveResponse', - 0xe5: 'ProgrammingModePositiveResponse', - 0xe9: 'ReadDiagnosticInformationPositiveResponse', - 0xea: 'ReadDataByPacketIdentifierPositiveResponse', - 0xee: 'DeviceControlPositiveResponse'}) - name = 'General Motors Local Area Network' - fields_desc = [ - XByteEnumField('service', 0, services) - ] - - def answers(self, other): - """DEV: true if self is an answer from other""" - if other.__class__ == self.__class__: - return (other.service + 0x40) == self.service or \ - (self.service == 0x7f and - (self.requestServiceId == other.service)) - return 0 - - def hashret(self): - if self.service == 0x7f: - return struct.pack('B', self.requestServiceId) - return struct.pack('B', self.service & ~0x40) - - -# ########################IDO################################### -class GMLAN_IDO(Packet): - subfunctions = { - 0x02: 'disableAllDTCs', - 0x03: 'enableDTCsDuringDevCntrl', - 0x04: 'wakeUpLinks'} - name = 'InitiateDiagnosticOperation' - fields_desc = [ - ByteEnumField('subfunction', 0, subfunctions) - ] - - -bind_layers(GMLAN, GMLAN_IDO, service=0x10) - - -# ########################RFRD################################### -class GMLAN_DTC(Packet): - name = 'GMLAN DTC information' - fields_desc = [ - XByteField('failureRecordNumber', 0), - XByteField('DTCHighByte', 0), - XByteField('DTCLowByte', 0), - XByteField('DTCFailureType', 0) - ] - - def extract_padding(self, p): - return "", p - - -class GMLAN_RFRD(Packet): - subfunctions = { - 0x01: 'readFailureRecordIdentifiers', - 0x02: 'readFailureRecordParameters'} - name = 'ReadFailureRecordData' - fields_desc = [ - ByteEnumField('subfunction', 0, subfunctions), - ConditionalField(PacketField("dtc", b'', GMLAN_DTC), - lambda pkt: pkt.subfunction == 0x02) - ] - - -bind_layers(GMLAN, GMLAN_RFRD, service=0x12) - - -class GMLAN_RFRDPR(Packet): - name = 'ReadFailureRecordDataPositiveResponse' - fields_desc = [ - ByteEnumField('subfunction', 0, GMLAN_RFRD.subfunctions) - ] - - -bind_layers(GMLAN, GMLAN_RFRDPR, service=0x52) - - -class GMLAN_RFRDPR_RFRI(Packet): - failureRecordDataStructureIdentifiers = { - 0x00: "PID", - 0x01: "DPID" - } - name = 'ReadFailureRecordDataPositiveResponse_readFailureRecordIdentifiers' - fields_desc = [ - ByteEnumField('failureRecordDataStructureIdentifier', 0, - failureRecordDataStructureIdentifiers), - PacketListField("dtcs", [], GMLAN_DTC) - ] - - -bind_layers(GMLAN_RFRDPR, GMLAN_RFRDPR_RFRI, subfunction=0x01) - - -class GMLAN_RFRDPR_RFRP(Packet): - name = 'ReadFailureRecordDataPositiveResponse_readFailureRecordParameters' - fields_desc = [ - PacketField("dtc", b'', GMLAN_DTC) - ] - - -bind_layers(GMLAN_RFRDPR, GMLAN_RFRDPR_RFRP, subfunction=0x02) - - -# ########################RDBI################################### -class GMLAN_RDBI(Packet): - dataIdentifiers = ObservableDict({ - 0x90: "$90: VehicleIdentificationNumber (VIN)", - 0x92: "$92: SystemSupplierId (SYSSUPPID)", - 0x97: "$97: SystemNameOrEngineType (SNOET)", - 0x98: "$98: RepairShopCodeOrTesterSerialNumber (RSCOTSN)", - 0x99: "$99: ProgrammingDate (PD)", - 0x9a: "$9a: DiagnosticDataIdentifier (DDI)", - 0x9b: "$9b: XmlConfigurationCompatibilityIdentifier (XMLCCID)", - 0x9C: "$9C: XmlDataFilePartNumber (XMLDFPN)", - 0x9D: "$9D: XmlDataFileAlphaCode (XMLDFAC)", - 0x9F: "$9F: PreviousStoredRepairShopCodeOrTesterSerialNumbers " - "(PSRSCOTSN)", - 0xA0: "$A0: manufacturers_enable_counter (MEC)", - 0xA1: "$A1: ECUConfigurationOrCustomizationData (ECUCOCGD) 1", - 0xA2: "$A2: ECUConfigurationOrCustomizationData (ECUCOCGD) 2", - 0xA3: "$A3: ECUConfigurationOrCustomizationData (ECUCOCGD) 3", - 0xA4: "$A4: ECUConfigurationOrCustomizationData (ECUCOCGD) 4", - 0xA5: "$A5: ECUConfigurationOrCustomizationData (ECUCOCGD) 5", - 0xA6: "$A6: ECUConfigurationOrCustomizationData (ECUCOCGD) 6", - 0xA7: "$A7: ECUConfigurationOrCustomizationData (ECUCOCGD) 7", - 0xA8: "$A8: ECUConfigurationOrCustomizationData (ECUCOCGD) 8", - 0xB0: "$B0: ECUDiagnosticAddress (ECUADDR)", - 0xB1: "$B1: ECUFunctionalSystemsAndVirtualDevices (ECUFSAVD)", - 0xB2: "$B2: GM ManufacturingData (GMMD)", - 0xB3: "$B3: Data Universal Numbering System Identification (DUNS)", - 0xB4: "$B4: Manufacturing Traceability Characters (MTC)", - 0xB5: "$B5: GM BroadcastCode (GMBC)", - 0xB6: "$B6: GM Target Vehicle (GMTV)", - 0xB7: "$B7: GM Software Usage Description (GMSUD)", - 0xB8: "$B8: GM Bench Verification Information (GMBVI)", - 0xB9: "$B9: Subnet_Config_List_HighSpeed (SCLHS)", - 0xBA: "$BA: Subnet_Config_List_LowSpeed (SCLLS)", - 0xBB: "$BB: Subnet_Config_List_MidSpeed (SCLMS)", - 0xBC: "$BC: Subnet_Config_List_NonCan 1 (SCLNC 1)", - 0xBD: "$BD: Subnet_Config_List_NonCan 2 (SCLNC 2)", - 0xBE: "$BE: Subnet_Config_List_LIN (SCLLIN)", - 0xBF: "$BF: Subnet_Config_List_GMLANChassisExpansionBus (SCLGCEB)", - 0xC0: "$C0: BootSoftwarePartNumber (BSPN)", - 0xC1: "$C1: SoftwareModuleIdentifier (SWMI) 01", - 0xC2: "$C2: SoftwareModuleIdentifier (SWMI) 02", - 0xC3: "$C3: SoftwareModuleIdentifier (SWMI) 03", - 0xC4: "$C4: SoftwareModuleIdentifier (SWMI) 04", - 0xC5: "$C5: SoftwareModuleIdentifier (SWMI) 05", - 0xC6: "$C6: SoftwareModuleIdentifier (SWMI) 06", - 0xC7: "$C7: SoftwareModuleIdentifier (SWMI) 07", - 0xC8: "$C8: SoftwareModuleIdentifier (SWMI) 08", - 0xC9: "$C9: SoftwareModuleIdentifier (SWMI) 09", - 0xCA: "$CA: SoftwareModuleIdentifier (SWMI) 10", - 0xCB: "$CB: EndModelPartNumber", - 0xCC: "$CC: BaseModelPartNumber (BMPN)", - 0xD0: "$D0: BootSoftwarePartNumberAlphaCode", - 0xD1: "$D1: SoftwareModuleIdentifierAlphaCode (SWMIAC) 01", - 0xD2: "$D2: SoftwareModuleIdentifierAlphaCode (SWMIAC) 02", - 0xD3: "$D3: SoftwareModuleIdentifierAlphaCode (SWMIAC) 03", - 0xD4: "$D4: SoftwareModuleIdentifierAlphaCode (SWMIAC) 04", - 0xD5: "$D5: SoftwareModuleIdentifierAlphaCode (SWMIAC) 05", - 0xD6: "$D6: SoftwareModuleIdentifierAlphaCode (SWMIAC) 06", - 0xD7: "$D7: SoftwareModuleIdentifierAlphaCode (SWMIAC) 07", - 0xD8: "$D8: SoftwareModuleIdentifierAlphaCode (SWMIAC) 08", - 0xD9: "$D9: SoftwareModuleIdentifierAlphaCode (SWMIAC) 09", - 0xDA: "$DA: SoftwareModuleIdentifierAlphaCode (SWMIAC) 10", - 0xDB: "$DB: EndModelPartNumberAlphaCode", - 0xDC: "$DC: BaseModelPartNumberAlphaCode", - 0xDD: "$DD: SoftwareModuleIdentifierDataIdentifiers (SWMIDID)", - 0xDE: "$DE: GMLANIdentificationData (GMLANID)", - 0xDF: "$DF: ECUOdometerValue (ECUODO)", - 0xE0: "$E0: VehicleLevelDataRecord (VLDR) 0", - 0xE1: "$E1: VehicleLevelDataRecord (VLDR) 1", - 0xE2: "$E2: VehicleLevelDataRecord (VLDR) 2", - 0xE3: "$E3: VehicleLevelDataRecord (VLDR) 3", - 0xE4: "$E4: VehicleLevelDataRecord (VLDR) 4", - 0xE5: "$E5: VehicleLevelDataRecord (VLDR) 5", - 0xE6: "$E6: VehicleLevelDataRecord (VLDR) 6", - 0xE7: "$E7: VehicleLevelDataRecord (VLDR) 7", - 0xE8: "$E8: Subnet_Config_List_GMLANPowertrainExpansionBus (SCLGPEB)", - 0xE9: "$E9: Subnet_Config_List_GMLANFrontObjectExpansionBus " - "(SCLGFOEB)", - 0xEA: "$EA: Subnet_Config_List_GMLANRearObjectExpansionBus (SCLGROEB)", - 0xEB: "$EB: Subnet_Config_List_GMLANExpansionBus1 (SCLGEB1)", - 0xEC: "$EC: Subnet_Config_List_GMLANExpansionBus2 (SCLGEB2)", - 0xED: "$ED: Subnet_Config_List_GMLANExpansionBus3 (SCLGEB3)", - 0xEE: "$EE: Subnet_Config_List_GMLANExpansionBus4 (SCLGEB4)", - 0xEF: "$EF: Subnet_Config_List_GMLANExpansionBus5 (SCLGEB5)", - }) - - name = 'ReadDataByIdentifier' - fields_desc = [ - XByteEnumField('dataIdentifier', 0, dataIdentifiers) - ] - - -bind_layers(GMLAN, GMLAN_RDBI, service=0x1A) - - -class GMLAN_RDBIPR(Packet): - name = 'ReadDataByIdentifierPositiveResponse' - fields_desc = [ - XByteEnumField('dataIdentifier', 0, GMLAN_RDBI.dataIdentifiers), - ] - - -bind_layers(GMLAN, GMLAN_RDBIPR, service=0x5A) - - -# ########################RDBI################################### -class GMLAN_RDBPI(Packet): - dataIdentifiers = ObservableDict({ - 0x0005: "OBD_EngineCoolantTemperature", - 0x000C: "OBD_EngineRPM", - 0x001f: "OBD_TimeSinceEngineStart" - }) - name = 'ReadDataByParameterIdentifier' - fields_desc = [ - FieldListField("identifiers", [], - XShortEnumField('parameterIdentifier', 0, - dataIdentifiers)) - ] - - -bind_layers(GMLAN, GMLAN_RDBPI, service=0x22) - - -class GMLAN_RDBPIPR(Packet): - name = 'ReadDataByParameterIdentifierPositiveResponse' - fields_desc = [ - XShortEnumField('parameterIdentifier', 0, GMLAN_RDBPI.dataIdentifiers), - ] - - -bind_layers(GMLAN, GMLAN_RDBPIPR, service=0x62) - - -# ########################RDBPKTI################################### -class GMLAN_RDBPKTI(Packet): - name = 'ReadDataByPacketIdentifier' - subfunctions = { - 0x00: "stopSending", - 0x01: "sendOneResponse", - 0x02: "scheduleAtSlowRate", - 0x03: "scheduleAtMediumRate", - 0x04: "scheduleAtFastRate" - } - - fields_desc = [ - XByteEnumField('subfunction', 0, subfunctions), - ConditionalField(FieldListField('request_DPIDs', [], - XByteField("", 0)), - lambda pkt: pkt.subfunction > 0x0) - ] - - -bind_layers(GMLAN, GMLAN_RDBPKTI, service=0xAA) - - -# ########################RMBA################################### -class GMLAN_RMBA(Packet): - name = 'ReadMemoryByAddress' - fields_desc = [ - ConditionalField(XShortField('memoryAddress', 0), - lambda pkt: GMLAN.determine_len(2)), - ConditionalField(X3BytesField('memoryAddress', 0), - lambda pkt: GMLAN.determine_len(3)), - ConditionalField(XIntField('memoryAddress', 0), - lambda pkt: GMLAN.determine_len(4)), - XShortField('memorySize', 0), - ] - - -bind_layers(GMLAN, GMLAN_RMBA, service=0x23) - - -class GMLAN_RMBAPR(Packet): - name = 'ReadMemoryByAddressPositiveResponse' - fields_desc = [ - ConditionalField(XShortField('memoryAddress', 0), - lambda pkt: GMLAN.determine_len(2)), - ConditionalField(X3BytesField('memoryAddress', 0), - lambda pkt: GMLAN.determine_len(3)), - ConditionalField(XIntField('memoryAddress', 0), - lambda pkt: GMLAN.determine_len(4)), - StrField('dataRecord', None, fmt="B") - ] - - -bind_layers(GMLAN, GMLAN_RMBAPR, service=0x63) - - -# ########################SA################################### -class GMLAN_SA(Packet): - subfunctions = { - 0: 'ReservedByDocument', - 1: 'SPSrequestSeed', - 2: 'SPSsendKey', - 3: 'DevCtrlrequestSeed', - 4: 'DevCtrlsendKey', - 255: 'ReservedByDocument'} - for i in range(0x05, 0x0a + 1): - subfunctions[i] = 'ReservedByDocument' - for i in range(0x0b, 0xfa + 1): - subfunctions[i] = 'Reserved for vehicle manufacturer specific needs' - for i in range(0xfb, 0xfe + 1): - subfunctions[i] = 'Reserved for ECU or ' \ - 'system supplier manufacturing needs' - - name = 'SecurityAccess' - fields_desc = [ - ByteEnumField('subfunction', 0, subfunctions), - ConditionalField(XShortField('securityKey', B""), - lambda pkt: pkt.subfunction % 2 == 0) - ] - - -bind_layers(GMLAN, GMLAN_SA, service=0x27) - - -class GMLAN_SAPR(Packet): - name = 'SecurityAccessPositiveResponse' - fields_desc = [ - ByteEnumField('subfunction', 0, GMLAN_SA.subfunctions), - ConditionalField(XShortField('securitySeed', B""), - lambda pkt: pkt.subfunction % 2 == 1), - ] - - -bind_layers(GMLAN, GMLAN_SAPR, service=0x67) - - -# ########################DDM################################### -class GMLAN_DDM(Packet): - name = 'DynamicallyDefineMessage' - fields_desc = [ - XByteField('DPIDIdentifier', 0), - StrField('PIDData', b'\x00\x00') - ] - - -bind_layers(GMLAN, GMLAN_DDM, service=0x2C) - - -class GMLAN_DDMPR(Packet): - name = 'DynamicallyDefineMessagePositiveResponse' - fields_desc = [ - XByteField('DPIDIdentifier', 0) - ] - - -bind_layers(GMLAN, GMLAN_DDMPR, service=0x6C) - - -# ########################DPBA################################### -class GMLAN_DPBA(Packet): - name = 'DefinePIDByAddress' - fields_desc = [ - XShortField('parameterIdentifier', 0), - ConditionalField(XShortField('memoryAddress', 0), - lambda pkt: GMLAN.determine_len(2)), - ConditionalField(X3BytesField('memoryAddress', 0), - lambda pkt: GMLAN.determine_len(3)), - ConditionalField(XIntField('memoryAddress', 0), - lambda pkt: GMLAN.determine_len(4)), - XByteField('memorySize', 0), - ] - - -bind_layers(GMLAN, GMLAN_DPBA, service=0x2D) - - -class GMLAN_DPBAPR(Packet): - name = 'DefinePIDByAddressPositiveResponse' - fields_desc = [ - XShortField('parameterIdentifier', 0), - ] - - -bind_layers(GMLAN, GMLAN_DPBA, service=0x6D) - - -# ########################RD################################### -class GMLAN_RD(Packet): - name = 'RequestDownload' - fields_desc = [ - XByteField('dataFormatIdentifier', 0), - ConditionalField(XShortField('memorySize', 0), - lambda pkt: GMLAN.determine_len(2)), - ConditionalField(X3BytesField('memorySize', 0), - lambda pkt: GMLAN.determine_len(3)), - ConditionalField(XIntField('memorySize', 0), - lambda pkt: GMLAN.determine_len(4)), - ] - - -bind_layers(GMLAN, GMLAN_RD, service=0x34) - - -# ########################TD################################### -class GMLAN_TD(Packet): - subfunctions = { - 0x00: "download", - 0x80: "downloadAndExecuteOrExecute" - } - name = 'TransferData' - fields_desc = [ - ByteEnumField('subfunction', 0, subfunctions), - ConditionalField(XShortField('startingAddress', 0), - lambda pkt: GMLAN.determine_len(2)), - ConditionalField(X3BytesField('startingAddress', 0), - lambda pkt: GMLAN.determine_len(3)), - ConditionalField(XIntField('startingAddress', 0), - lambda pkt: GMLAN.determine_len(4)), - StrField("dataRecord", None) - ] - - -bind_layers(GMLAN, GMLAN_TD, service=0x36) - - -# ########################WDBI################################### -class GMLAN_WDBI(Packet): - name = 'WriteDataByIdentifier' - fields_desc = [ - XByteEnumField('dataIdentifier', 0, GMLAN_RDBI.dataIdentifiers), - StrField("dataRecord", b'\x00') - ] - - -bind_layers(GMLAN, GMLAN_WDBI, service=0x3B) - - -class GMLAN_WDBIPR(Packet): - name = 'WriteDataByIdentifierPositiveResponse' - fields_desc = [ - XByteEnumField('dataIdentifier', 0, GMLAN_RDBI.dataIdentifiers) - ] - - -bind_layers(GMLAN, GMLAN_WDBIPR, service=0x7B) - - -# ########################RPSPR################################### -class GMLAN_RPSPR(Packet): - programmedStates = { - 0x00: "fully programmed", - 0x01: "no op s/w or cal data", - 0x02: "op s/w present, cal data missing", - 0x03: "s/w present, default or no start cal present", - 0x50: "General Memory Fault", - 0x51: "RAM Memory Fault", - 0x52: "NVRAM Memory Fault", - 0x53: "Boot Memory Failure", - 0x54: "Flash Memory Failure", - 0x55: "EEPROM Memory Failure", - } - name = 'ReportProgrammedStatePositiveResponse' - fields_desc = [ - ByteEnumField('programmedState', 0, programmedStates), - ] - - -bind_layers(GMLAN, GMLAN_RPSPR, service=0xE2) - - -# ########################PM################################### -class GMLAN_PM(Packet): - subfunctions = { - 0x01: "requestProgrammingMode", - 0x02: "requestProgrammingMode_HighSpeed", - 0x03: "enableProgrammingMode" - } - name = 'ProgrammingMode' - fields_desc = [ - ByteEnumField('subfunction', 0, subfunctions), - ] - - -bind_layers(GMLAN, GMLAN_PM, service=0xA5) - - -# ########################RDI################################### -class GMLAN_RDI(Packet): - subfunctions = { - 0x80: 'readStatusOfDTCByDTCNumber', - 0x81: 'readStatusOfDTCByStatusMask', - 0x82: 'sendOnChangeDTCCount' - } - name = 'ReadDiagnosticInformation' - fields_desc = [ - ByteEnumField('subfunction', 0, subfunctions) - ] - - -bind_layers(GMLAN, GMLAN_RDI, service=0xA9) - - -class GMLAN_RDI_BN(Packet): - name = 'ReadStatusOfDTCByDTCNumber' - fields_desc = [ - XByteField('DTCHighByte', 0), - XByteField('DTCLowByte', 0), - XByteField('DTCFailureType', 0), - ] - - -bind_layers(GMLAN_RDI, GMLAN_RDI_BN, subfunction=0x80) - - -class GMLAN_RDI_BM(Packet): - name = 'ReadStatusOfDTCByStatusMask' - fields_desc = [ - XByteField('DTCStatusMask', 0), - ] - - -bind_layers(GMLAN_RDI, GMLAN_RDI_BM, subfunction=0x81) - - -class GMLAN_RDI_BC(Packet): - name = 'SendOnChangeDTCCount' - fields_desc = [ - XByteField('DTCStatusMask', 0), - ] - - -bind_layers(GMLAN_RDI, GMLAN_RDI_BC, subfunction=0x82) -# TODO:This function receive single frame responses... (Implement GMLAN Socket) - - -# ########################NRC################################### -class GMLAN_NR(Packet): - negativeResponseCodes = { - 0x11: 'ServiceNotSupported', - 0x12: 'SubFunctionNotSupported', - 0x22: 'ConditionsNotCorrectOrRequestSequenceError', - 0x31: 'RequestOutOfRange', - 0x35: 'InvalidKey', - 0x36: 'ExceedNumberOfAttempts', - 0x37: 'RequiredTimeDelayNotExpired', - 0x78: 'RequestCorrectlyReceived-ResponsePending', - 0x81: 'SchedulerFull', - 0x83: 'VoltageOutOfRange', - 0x85: 'GeneralProgrammingFailure', - 0x89: 'DeviceTypeError', - 0x99: 'ReadyForDownload-DTCStored', - 0xe3: 'DeviceControlLimitsExceeded', - } - name = 'NegativeResponse' - fields_desc = [ - XByteEnumField('requestServiceId', 0, GMLAN.services), - ByteEnumField('returnCode', 0, negativeResponseCodes), - ShortField('deviceControlLimitExceeded', 0) - ] - - -bind_layers(GMLAN, GMLAN_NR, service=0x7f) - - -# ################################################################## -# ######################## UTILS ################################### -# ################################################################## - - -class GMLAN_TesterPresentSender(PeriodicSenderThread): - def __init__(self, sock, pkt=GMLAN(service="TesterPresent"), interval=2): - """ Thread to send TesterPresent messages packets periodically - - Args: - sock: socket where packet is sent periodically - pkt: packet to send - interval: interval between two packets - """ - PeriodicSenderThread.__init__(self, sock, pkt, interval) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/__init__.py deleted file mode 100644 index 9d7ebf0032..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -""" -Package of contrib automotive obd specific modules -that have to be loaded explicitly. -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/iid/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/iid/__init__.py deleted file mode 100644 index 9d7ebf0032..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/iid/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -""" -Package of contrib automotive obd specific modules -that have to be loaded explicitly. -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/iid/iids.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/iid/iids.py deleted file mode 100644 index 9e0adf936a..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/iid/iids.py +++ /dev/null @@ -1,172 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -from scapy.fields import FieldLenField, FieldListField, StrFixedLenField, \ - ByteField, ShortField, FlagsField, XByteField, PacketListField -from scapy.contrib.automotive.obd.packet import OBD_Packet -from scapy.packet import Packet, bind_layers - - -# See https://en.wikipedia.org/wiki/OBD-II_PIDs#Service_09 -# for further information -# IID = Information IDentification - -class OBD_S09_PR_Record(Packet): - fields_desc = [ - XByteField("iid", 0), - ] - - -class OBD_S09_PR(Packet): - name = "Infotype IDs" - fields_desc = [ - PacketListField("data_records", [], OBD_S09_PR_Record) - ] - - -class OBD_IID00(OBD_Packet): - name = "IID_00_Service9SupportedInformationTypes" - fields_desc = [ - FlagsField('supported_iids', 0, 32, [ - 'IID20', - 'IID1F', - 'IID1E', - 'IID1D', - 'IID1C', - 'IID1B', - 'IID1A', - 'IID19', - 'IID18', - 'IID17', - 'IID16', - 'IID15', - 'IID14', - 'IID13', - 'IID12', - 'IID11', - 'IID10', - 'IID0F', - 'IID0E', - 'IID0D', - 'IID0C', - 'IID0B', - 'IID0A', - 'IID09', - 'IID08', - 'IID07', - 'IID06', - 'IID05', - 'IID04', - 'IID03', - 'IID02', - 'IID01' - ]) - ] - - -class _OBD_IID_MessageCount(OBD_Packet): - fields_desc = [ - ByteField('message_count', 0) - ] - - -class OBD_IID01(_OBD_IID_MessageCount): - name = "IID_01_VinMessageCount" - - -class OBD_IID03(_OBD_IID_MessageCount): - name = "IID_03_CalibrationIdMessageCount" - - -class OBD_IID05(_OBD_IID_MessageCount): - name = "IID_05_CalibrationVerificationNumbersMessageCount" - - -class OBD_IID07(_OBD_IID_MessageCount): - name = "IID_07_InUsePerformanceTrackingMessageCount" - - -class OBD_IID09(_OBD_IID_MessageCount): - name = "IID_09_EcuNameMessageCount" - - -class OBD_IID02(OBD_Packet): - name = "IID_02_VehicleIdentificationNumber" - fields_desc = [ - FieldLenField('count', None, count_of='vehicle_identification_numbers', - fmt='B'), - FieldListField('vehicle_identification_numbers', [], - StrFixedLenField('', b'', 17), - count_from=lambda pkt: pkt.count) - ] - - -class OBD_IID04(OBD_Packet): - name = "IID_04_CalibrationId" - fields_desc = [ - FieldLenField('count', None, count_of='calibration_identifications', - fmt='B'), - FieldListField('calibration_identifications', [], - StrFixedLenField('', b'', 16), - count_from=lambda pkt: pkt.count) - ] - - -class OBD_IID06(OBD_Packet): - name = "IID_06_CalibrationVerificationNumbers" - fields_desc = [ - FieldLenField('count', None, - count_of='calibration_verification_numbers', fmt='B'), - FieldListField('calibration_verification_numbers', [], - StrFixedLenField('', b'', 4), - count_from=lambda pkt: pkt.count) - ] - - -class OBD_IID08(OBD_Packet): - name = "IID_08_InUsePerformanceTracking" - fields_desc = [ - FieldLenField('count', None, count_of='data', fmt='B'), - FieldListField('data', [], - ShortField('', 0), - count_from=lambda pkt: pkt.count) - ] - - -class OBD_IID0A(OBD_Packet): - name = "IID_0A_EcuName" - fields_desc = [ - FieldLenField('count', None, count_of='ecu_names', fmt='B'), - FieldListField('ecu_names', [], - StrFixedLenField('', b'', 20), - count_from=lambda pkt: pkt.count) - ] - - -class OBD_IID0B(OBD_Packet): - name = "IID_0B_InUsePerformanceTrackingForCompressionIgnitionVehicles" - fields_desc = [ - FieldLenField('count', None, count_of='data', fmt='B'), - FieldListField('data', [], - ShortField('', 0), - count_from=lambda pkt: pkt.count) - ] - - -bind_layers(OBD_S09_PR_Record, OBD_IID00, iid=0x00) -bind_layers(OBD_S09_PR_Record, OBD_IID01, iid=0x01) -bind_layers(OBD_S09_PR_Record, OBD_IID02, iid=0x02) -bind_layers(OBD_S09_PR_Record, OBD_IID03, iid=0x03) -bind_layers(OBD_S09_PR_Record, OBD_IID04, iid=0x04) -bind_layers(OBD_S09_PR_Record, OBD_IID05, iid=0x05) -bind_layers(OBD_S09_PR_Record, OBD_IID06, iid=0x06) -bind_layers(OBD_S09_PR_Record, OBD_IID07, iid=0x07) -bind_layers(OBD_S09_PR_Record, OBD_IID08, iid=0x08) -bind_layers(OBD_S09_PR_Record, OBD_IID09, iid=0x09) -bind_layers(OBD_S09_PR_Record, OBD_IID0A, iid=0x0A) -bind_layers(OBD_S09_PR_Record, OBD_IID0B, iid=0x0B) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/mid/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/mid/__init__.py deleted file mode 100644 index 9d7ebf0032..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/mid/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -""" -Package of contrib automotive obd specific modules -that have to be loaded explicitly. -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/mid/mids.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/mid/mids.py deleted file mode 100644 index 6bc2b8ba93..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/mid/mids.py +++ /dev/null @@ -1,549 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -from scapy.fields import FlagsField, ScalingField, ByteEnumField, \ - MultipleTypeField, ShortField, ShortEnumField, PacketListField -from scapy.packet import Packet, bind_layers -from scapy.contrib.automotive.obd.packet import OBD_Packet - - -def _unit_and_scaling_fields(name): - return [ - (ScalingField(name, 0, fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x1), - (ScalingField(name, 0, scaling=0.1, fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x2), - (ScalingField(name, 0, scaling=0.01, fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x3), - (ScalingField(name, 0, scaling=0.001, fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x4), - (ScalingField(name, 0, scaling=0.0000305, fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x5), - (ScalingField(name, 0, scaling=0.000305, fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x6), - (ScalingField(name, 0, scaling=0.25, unit="rpm", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x7), - (ScalingField(name, 0, scaling=0.01, unit="km/h", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x8), - (ScalingField(name, 0, unit="km/h", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x9), - (ScalingField(name, 0, scaling=0.122, unit="mV", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0xA), - (ScalingField(name, 0, scaling=0.001, unit="V", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0xB), - (ScalingField(name, 0, scaling=0.01, unit="V", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0xC), - (ScalingField(name, 0, scaling=0.00390625, unit="mA", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0xD), - (ScalingField(name, 0, scaling=0.001, unit="A", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0xE), - (ScalingField(name, 0, scaling=0.01, unit="A", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0xF), - (ScalingField(name, 0, unit="ms", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x10), - (ScalingField(name, 0, scaling=100, unit="ms", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x11), - (ScalingField(name, 0, scaling=1, unit="s", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x12), - (ScalingField(name, 0, scaling=1, unit="mOhm", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x13), - (ScalingField(name, 0, scaling=1, unit="Ohm", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x14), - (ScalingField(name, 0, scaling=1, unit="kOhm", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x15), - (ScalingField(name, -40, scaling=0.1, unit="deg. C", - offset=-40, fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x16), - (ScalingField(name, 0, scaling=0.01, unit="kPa", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x17), - (ScalingField(name, 0, scaling=0.0117, unit="kPa", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x18), - (ScalingField(name, 0, scaling=0.079, unit="kPa", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x19), - (ScalingField(name, 0, scaling=1, unit="kPa", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x1A), - (ScalingField(name, 0, scaling=10, unit="kPa", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x1B), - (ScalingField(name, 0, scaling=0.01, unit="deg.", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x1C), - (ScalingField(name, 0, scaling=0.5, unit="deg.", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x1D), - (ScalingField(name, 0, scaling=0.0000305, fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x1E), - (ScalingField(name, 0, scaling=0.05, fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x1F), - (ScalingField(name, 0, scaling=0.0039062, fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x20), - (ScalingField(name, 0, scaling=1, unit="mHz", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x21), - (ScalingField(name, 0, scaling=1, unit="Hz", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x22), - (ScalingField(name, 0, scaling=1, unit="KHz", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x23), - (ScalingField(name, 0, scaling=1, unit="counts", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x24), - (ScalingField(name, 0, scaling=1, unit="km", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x25), - (ScalingField(name, 0, scaling=0.1, unit="mV/ms", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x26), - (ScalingField(name, 0, scaling=0.01, unit="g/s", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x27), - (ScalingField(name, 0, scaling=1, unit="g/s", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x28), - (ScalingField(name, 0, scaling=0.25, unit="Pa/s", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x29), - (ScalingField(name, 0, scaling=0.001, unit="kg/h", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x2A), - (ScalingField(name, 0, scaling=1, unit="switches", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x2B), - (ScalingField(name, 0, scaling=0.01, unit="g/cyl", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x2C), - (ScalingField(name, 0, scaling=0.01, unit="mg/stroke", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x2D), - (ShortEnumField(name, 0, {0: "false", 1: "true"}), - lambda pkt: pkt.unit_and_scaling_id == 0x2E), - (ScalingField(name, 0, scaling=0.01, unit="%", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x2F), - (ScalingField(name, 0, scaling=0.001526, unit="%", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x30), - (ScalingField(name, 0, scaling=0.001, unit="L", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x31), - (ScalingField(name, 0, scaling=0.0000305, unit="inch", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x32), - (ScalingField(name, 0, scaling=0.00024414, fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x33), - (ScalingField(name, 0, scaling=1, unit="min", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x34), - (ScalingField(name, 0, scaling=10, unit="ms", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x35), - (ScalingField(name, 0, scaling=0.01, unit="g", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x36), - (ScalingField(name, 0, scaling=0.1, unit="g", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x37), - (ScalingField(name, 0, scaling=1, unit="g", fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x38), - (ScalingField(name, 0, scaling=0.01, unit="%", offset=-327.68, - fmt='H'), - lambda pkt: pkt.unit_and_scaling_id == 0x39), - (ScalingField(name, 0, scaling=1, fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x81), - (ScalingField(name, 0, scaling=0.1, fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x82), - (ScalingField(name, 0, scaling=0.01, fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x83), - (ScalingField(name, 0, scaling=0.001, fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x84), - (ScalingField(name, 0, scaling=0.0000305, fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x85), - (ScalingField(name, 0, scaling=0.000305, fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x86), - (ScalingField(name, 0, scaling=0.122, unit="mV", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x8A), - (ScalingField(name, 0, scaling=0.001, unit="V", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x8B), - (ScalingField(name, 0, scaling=0.01, unit="V", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x8C), - (ScalingField(name, 0, scaling=0.00390625, unit="mA", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x8D), - (ScalingField(name, 0, scaling=0.001, unit="A", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x8E), - (ScalingField(name, 0, scaling=1, unit="ms", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x90), - (ScalingField(name, 0, scaling=0.1, unit="deg. C", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x96), - (ScalingField(name, 0, scaling=0.01, unit="deg.", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x9C), - (ScalingField(name, 0, scaling=0.5, unit="deg.", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0x9D), - (ScalingField(name, 0, scaling=1, unit="g/s", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0xA8), - (ScalingField(name, 0, scaling=0.25, unit="Pa/s", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0xA9), - (ScalingField(name, 0, scaling=0.01, unit="%", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0xAF), - (ScalingField(name, 0, scaling=0.003052, unit="%", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0xB0), - (ScalingField(name, 0, scaling=2, unit="mV/s", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0xB1), - (ScalingField(name, 0, scaling=0.001, unit="kPa", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0xFD), - (ScalingField(name, 0, scaling=0.25, unit="Pa", fmt='h'), - lambda pkt: pkt.unit_and_scaling_id == 0xFE) - ] - - -def _mid_flags(basemid): - return [ - 'MID%02X' % (basemid + 0x20), - 'MID%02X' % (basemid + 0x1F), - 'MID%02X' % (basemid + 0x1E), - 'MID%02X' % (basemid + 0x1D), - 'MID%02X' % (basemid + 0x1C), - 'MID%02X' % (basemid + 0x1B), - 'MID%02X' % (basemid + 0x1A), - 'MID%02X' % (basemid + 0x19), - 'MID%02X' % (basemid + 0x18), - 'MID%02X' % (basemid + 0x17), - 'MID%02X' % (basemid + 0x16), - 'MID%02X' % (basemid + 0x15), - 'MID%02X' % (basemid + 0x14), - 'MID%02X' % (basemid + 0x13), - 'MID%02X' % (basemid + 0x12), - 'MID%02X' % (basemid + 0x11), - 'MID%02X' % (basemid + 0x10), - 'MID%02X' % (basemid + 0x0F), - 'MID%02X' % (basemid + 0x0E), - 'MID%02X' % (basemid + 0x0D), - 'MID%02X' % (basemid + 0x0C), - 'MID%02X' % (basemid + 0x0B), - 'MID%02X' % (basemid + 0x0A), - 'MID%02X' % (basemid + 0x09), - 'MID%02X' % (basemid + 0x08), - 'MID%02X' % (basemid + 0x07), - 'MID%02X' % (basemid + 0x06), - 'MID%02X' % (basemid + 0x05), - 'MID%02X' % (basemid + 0x04), - 'MID%02X' % (basemid + 0x03), - 'MID%02X' % (basemid + 0x02), - 'MID%02X' % (basemid + 0x01) - ] - - -class OBD_MIDXX(OBD_Packet): - standardized_test_ids = { - 1: "TID_01_RichToLeanSensorThresholdVoltage", - 2: "TID_02_LeanToRichSensorThresholdVoltage", - 3: "TID_03_LowSensorVoltageForSwitchTimeCalculation", - 4: "TID_04_HighSensorVoltageForSwitchTimeCalculation", - 5: "TID_05_RichToLeanSensorSwitchTime", - 6: "TID_06_LeanToRichSensorSwitchTime", - 7: "TID_07_MinimumSensorVoltageForTestCycle", - 8: "TID_08_MaximumSensorVoltageForTestCycle", - 9: "TID_09_TimeBetweenSensorTransitions", - 10: "TID_0A_SensorPeriod"} - unit_and_scaling_ids = { - 0x01: "Raw Value", - 0x02: "Raw Value", - 0x03: "Raw Value", - 0x04: "Raw Value", - 0x05: "Raw Value", - 0x06: "Raw Value", - 0x07: "rotational frequency", - 0x08: "Speed", - 0x09: "Speed", - 0x0A: "Voltage", - 0x0B: "Voltage", - 0x0C: "Voltage", - 0x0D: "Current", - 0x0E: "Current", - 0x0F: "Current", - 0x10: "Time", - 0x11: "Time", - 0x12: "Time", - 0x13: "Resistance", - 0x14: "Resistance", - 0x15: "Resistance", - 0x16: "Temperature", - 0x17: "Pressure (Gauge)", - 0x18: "Pressure (Air pressure)", - 0x19: "Pressure (Fuel pressure)", - 0x1A: "Pressure (Gauge)", - 0x1B: "Pressure (Diesel pressure)", - 0x1C: "Angle", - 0x1D: "Angle", - 0x1E: "Equivalence ratio (lambda)", - 0x1F: "Air/Fuel ratio", - 0x20: "Ratio", - 0x21: "Frequency", - 0x22: "Frequency", - 0x23: "Frequency", - 0x24: "Counts", - 0x25: "Distance", - 0x26: "Voltage per time", - 0x27: "Mass per time", - 0x28: "Mass per time", - 0x29: "Pressure per time", - 0x2A: "Mass per time", - 0x2B: "Switches", - 0x2C: "Mass per cylinder", - 0x2D: "Mass per stroke", - 0x2E: "True/False", - 0x2F: "Percent", - 0x30: "Percent", - 0x31: "volume", - 0x32: "length", - 0x33: "Equivalence ratio (lambda)", - 0x34: "Time", - 0x35: "Time", - 0x36: "Weight", - 0x37: "Weight", - 0x38: "Weight", - 0x39: "Percent", - 0x81: "Raw Value", - 0x82: "Raw Value", - 0x83: "Raw Value", - 0x84: "Raw Value", - 0x85: "Raw Value", - 0x86: "Raw Value", - 0x8A: "Voltage", - 0x8B: "Voltage", - 0x8C: "Voltage", - 0x8D: "Current", - 0x8E: "Current", - 0x90: "Time", - 0x96: "Temperature", - 0x9C: "Angle", - 0x9D: "Angle", - 0xA8: "Mass per time", - 0xA9: "Pressure per time", - 0xAF: "Percent", - 0xB0: "Percent", - 0xB1: "Voltage per time", - 0xFD: "Pressure", - 0xFE: "Pressure" - } - - name = "OBD MID data record" - fields_desc = [ - ByteEnumField("standardized_test_id", 1, standardized_test_ids), - ByteEnumField("unit_and_scaling_id", 1, unit_and_scaling_ids), - MultipleTypeField(_unit_and_scaling_fields("test_value"), - ShortField("test_value", 0)), - MultipleTypeField(_unit_and_scaling_fields("min_limit"), - ShortField("min_limit", 0)), - MultipleTypeField(_unit_and_scaling_fields("max_limit"), - ShortField("max_limit", 0)), - ] - - -class OBD_MID00(OBD_Packet): - fields_desc = [ - FlagsField('supported_mids', 0, 32, _mid_flags(0x00)), - ] - - -class OBD_MID20(OBD_Packet): - fields_desc = [ - FlagsField('supported_mids', 0, 32, _mid_flags(0x20)), - ] - - -class OBD_MID40(OBD_Packet): - fields_desc = [ - FlagsField('supported_mids', 0, 32, _mid_flags(0x40)), - ] - - -class OBD_MID60(OBD_Packet): - fields_desc = [ - FlagsField('supported_mids', 0, 32, _mid_flags(0x60)), - ] - - -class OBD_MID80(OBD_Packet): - fields_desc = [ - FlagsField('supported_mids', 0, 32, _mid_flags(0x80)), - ] - - -class OBD_MIDA0(OBD_Packet): - fields_desc = [ - FlagsField('supported_mids', 0, 32, _mid_flags(0xA0)), - ] - - -class OBD_S06_PR_Record(Packet): - on_board_monitoring_ids = { - 0x00: "OBD Monitor IDs supported ($01 - $20)", - 0x01: "Oxygen Sensor Monitor Bank 1 - Sensor 1", - 0x02: "Oxygen Sensor Monitor Bank 1 - Sensor 2", - 0x03: "Oxygen Sensor Monitor Bank 1 - Sensor 3", - 0x04: "Oxygen Sensor Monitor Bank 1 - Sensor 4", - 0x05: "Oxygen Sensor Monitor Bank 2 - Sensor 1", - 0x06: "Oxygen Sensor Monitor Bank 2 - Sensor 2", - 0x07: "Oxygen Sensor Monitor Bank 2 - Sensor 3", - 0x08: "Oxygen Sensor Monitor Bank 2 - Sensor 4", - 0x09: "Oxygen Sensor Monitor Bank 3 - Sensor 1", - 0x0A: "Oxygen Sensor Monitor Bank 3 - Sensor 2", - 0x0B: "Oxygen Sensor Monitor Bank 3 - Sensor 3", - 0x0C: "Oxygen Sensor Monitor Bank 3 - Sensor 4", - 0x0D: "Oxygen Sensor Monitor Bank 4 - Sensor 1", - 0x0E: "Oxygen Sensor Monitor Bank 4 - Sensor 2", - 0x0F: "Oxygen Sensor Monitor Bank 4 - Sensor 3", - 0x10: "Oxygen Sensor Monitor Bank 4 - Sensor 4", - 0x20: "OBD Monitor IDs supported ($21 - $40)", - 0x21: "Catalyst Monitor Bank 1", - 0x22: "Catalyst Monitor Bank 2", - 0x23: "Catalyst Monitor Bank 3", - 0x24: "Catalyst Monitor Bank 4", - 0x32: "EGR Monitor Bank 2", - 0x33: "EGR Monitor Bank 3", - 0x34: "EGR Monitor Bank 4", - 0x35: "VVT Monitor Bank 1", - 0x36: "VVT Monitor Bank 2", - 0x37: "VVT Monitor Bank 3", - 0x38: "VVT Monitor Bank 4", - 0x39: "EVAP Monitor (Cap Off / 0.150\")", - 0x3A: "EVAP Monitor (0.090\")", - 0x3B: "EVAP Monitor (0.040\")", - 0x3C: "EVAP Monitor (0.020\")", - 0x3D: "Purge Flow Monitor", - 0x40: "OBD Monitor IDs supported ($41 - $60)", - 0x41: "Oxygen Sensor Heater Monitor Bank 1 - Sensor 1", - 0x42: "Oxygen Sensor Heater Monitor Bank 1 - Sensor 2", - 0x43: "Oxygen Sensor Heater Monitor Bank 1 - Sensor 3", - 0x44: "Oxygen Sensor Heater Monitor Bank 1 - Sensor 4", - 0x45: "Oxygen Sensor Heater Monitor Bank 2 - Sensor 1", - 0x46: "Oxygen Sensor Heater Monitor Bank 2 - Sensor 2", - 0x47: "Oxygen Sensor Heater Monitor Bank 2 - Sensor 3", - 0x48: "Oxygen Sensor Heater Monitor Bank 2 - Sensor 4", - 0x49: "Oxygen Sensor Heater Monitor Bank 3 - Sensor 1", - 0x4A: "Oxygen Sensor Heater Monitor Bank 3 - Sensor 2", - 0x4B: "Oxygen Sensor Heater Monitor Bank 3 - Sensor 3", - 0x4C: "Oxygen Sensor Heater Monitor Bank 3 - Sensor 4", - 0x4D: "Oxygen Sensor Heater Monitor Bank 4 - Sensor 1", - 0x4E: "Oxygen Sensor Heater Monitor Bank 4 - Sensor 2", - 0x4F: "Oxygen Sensor Heater Monitor Bank 4 - Sensor 3", - 0x50: "Oxygen Sensor Heater Monitor Bank 4 - Sensor 4", - 0x60: "OBD Monitor IDs supported ($61 - $80)", - 0x61: "Heated Catalyst Monitor Bank 1", - 0x62: "Heated Catalyst Monitor Bank 2", - 0x63: "Heated Catalyst Monitor Bank 3", - 0x64: "Heated Catalyst Monitor Bank 4", - 0x71: "Secondary Air Monitor 1", - 0x72: "Secondary Air Monitor 2", - 0x73: "Secondary Air Monitor 3", - 0x74: "Secondary Air Monitor 4", - 0x80: "OBD Monitor IDs supported ($81 - $A0)", - 0x81: "Fuel System Monitor Bank 1", - 0x82: "Fuel System Monitor Bank 2", - 0x83: "Fuel System Monitor Bank 3", - 0x84: "Fuel System Monitor Bank 4", - 0x85: "Boost Pressure Control Monitor Bank 1", - 0x86: "Boost Pressure Control Monitor Bank 2", - 0x90: "NOx Adsorber Monitor Bank 1", - 0x91: "NOx Adsorber Monitor Bank 2", - 0x98: "NOx Catalyst Monitor Bank 1", - 0x99: "NOx Catalyst Monitor Bank 2", - 0xA0: "OBD Monitor IDs supported ($A1 - $C0)", - 0xA1: "Misfire Monitor General Data", - 0xA2: "Misfire Cylinder 1 Data", - 0xA3: "Misfire Cylinder 2 Data", - 0xA4: "Misfire Cylinder 3 Data", - 0xA5: "Misfire Cylinder 4 Data", - 0xA6: "Misfire Cylinder 5 Data", - 0xA7: "Misfire Cylinder 6 Data", - 0xA8: "Misfire Cylinder 7 Data", - 0xA9: "Misfire Cylinder 8 Data", - 0xAA: "Misfire Cylinder 9 Data", - 0xAB: "Misfire Cylinder 10 Data", - 0xAC: "Misfire Cylinder 11 Data", - 0xAD: "Misfire Cylinder 12 Data", - 0xB0: "PM Filter Monitor Bank 1", - 0xB1: "PM Filter Monitor Bank 2" - } - name = "On-Board diagnostic monitoring ID" - fields_desc = [ - ByteEnumField("mid", 0, on_board_monitoring_ids), - ] - - -class OBD_S06_PR(Packet): - name = "On-Board monitoring IDs" - fields_desc = [ - PacketListField("data_records", [], OBD_S06_PR_Record) - ] - - -bind_layers(OBD_S06_PR_Record, OBD_MID00, mid=0x00) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x01) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x02) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x03) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x04) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x05) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x06) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x07) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x08) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x09) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x0A) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x0B) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x0C) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x0D) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x0E) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x0F) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x10) -bind_layers(OBD_S06_PR_Record, OBD_MID20, mid=0x20) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x21) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x22) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x23) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x24) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x32) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x33) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x34) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x35) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x36) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x37) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x38) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x39) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x3A) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x3B) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x3C) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x3D) -bind_layers(OBD_S06_PR_Record, OBD_MID40, mid=0x40) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x41) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x42) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x43) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x44) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x45) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x46) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x47) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x48) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x49) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x4A) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x4B) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x4C) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x4D) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x4E) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x4F) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x50) -bind_layers(OBD_S06_PR_Record, OBD_MID60, mid=0x60) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x61) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x62) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x63) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x64) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x71) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x72) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x73) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x74) -bind_layers(OBD_S06_PR_Record, OBD_MID80, mid=0x80) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x81) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x82) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x83) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x84) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x85) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x86) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x90) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x91) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x98) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0x99) -bind_layers(OBD_S06_PR_Record, OBD_MIDA0, mid=0xA0) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xA1) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xA2) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xA3) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xA4) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xA5) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xA6) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xA7) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xA8) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xA9) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xAA) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xAB) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xAC) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xAD) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xB0) -bind_layers(OBD_S06_PR_Record, OBD_MIDXX, mid=0xB1) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/obd.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/obd.py deleted file mode 100644 index 10e666fa10..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/obd.py +++ /dev/null @@ -1,88 +0,0 @@ -# flake8: noqa: F405 - -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.description = On Board Diagnostic Protocol (OBD-II) -# scapy.contrib.status = loads - -import struct - -from scapy.contrib.automotive.obd.iid.iids import * -from scapy.contrib.automotive.obd.mid.mids import * -from scapy.contrib.automotive.obd.pid.pids import * -from scapy.contrib.automotive.obd.tid.tids import * -from scapy.contrib.automotive.obd.services import * -from scapy.packet import Packet, bind_layers -from scapy.fields import XByteEnumField - - -class OBD(Packet): - services = { - 0x01: 'CurrentPowertrainDiagnosticDataRequest', - 0x02: 'PowertrainFreezeFrameDataRequest', - 0x03: 'EmissionRelatedDiagnosticTroubleCodesRequest', - 0x04: 'ClearResetDiagnosticTroubleCodesRequest', - 0x05: 'OxygenSensorMonitoringTestResultsRequest', - 0x06: 'OnBoardMonitoringTestResultsRequest', - 0x07: 'PendingEmissionRelatedDiagnosticTroubleCodesRequest', - 0x08: 'ControlOperationRequest', - 0x09: 'VehicleInformationRequest', - 0x0A: 'PermanentDiagnosticTroubleCodesRequest', - 0x41: 'CurrentPowertrainDiagnosticDataResponse', - 0x42: 'PowertrainFreezeFrameDataResponse', - 0x43: 'EmissionRelatedDiagnosticTroubleCodesResponse', - 0x44: 'ClearResetDiagnosticTroubleCodesResponse', - 0x45: 'OxygenSensorMonitoringTestResultsResponse', - 0x46: 'OnBoardMonitoringTestResultsResponse', - 0x47: 'PendingEmissionRelatedDiagnosticTroubleCodesResponse', - 0x48: 'ControlOperationResponse', - 0x49: 'VehicleInformationResponse', - 0x4A: 'PermanentDiagnosticTroubleCodesResponse', - 0x7f: 'NegativeResponse'} - - name = "On-board diagnostics" - - fields_desc = [ - XByteEnumField('service', 0, services) - ] - - def hashret(self): - if self.service == 0x7f: - return struct.pack('B', self.request_service_id & ~0x40) - return struct.pack('B', self.service & ~0x40) - - def answers(self, other): - """DEV: true if self is an answer from other""" - if other.__class__ == self.__class__: - return (other.service + 0x40) == self.service or \ - (self.service == 0x7f and - self.request_service_id == other.service) - return False - - -# Service Bindings - -bind_layers(OBD, OBD_S01, service=0x01) -bind_layers(OBD, OBD_S02, service=0x02) -bind_layers(OBD, OBD_S03, service=0x03) -bind_layers(OBD, OBD_S04, service=0x04) -bind_layers(OBD, OBD_S06, service=0x06) -bind_layers(OBD, OBD_S07, service=0x07) -bind_layers(OBD, OBD_S08, service=0x08) -bind_layers(OBD, OBD_S09, service=0x09) -bind_layers(OBD, OBD_S0A, service=0x0A) - -bind_layers(OBD, OBD_S01_PR, service=0x41) -bind_layers(OBD, OBD_S02_PR, service=0x42) -bind_layers(OBD, OBD_S03_PR, service=0x43) -bind_layers(OBD, OBD_S04_PR, service=0x44) -bind_layers(OBD, OBD_S06_PR, service=0x46) -bind_layers(OBD, OBD_S07_PR, service=0x47) -bind_layers(OBD, OBD_S08_PR, service=0x48) -bind_layers(OBD, OBD_S09_PR, service=0x49) -bind_layers(OBD, OBD_S0A_PR, service=0x4A) -bind_layers(OBD, OBD_NR, service=0x7F) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/packet.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/packet.py deleted file mode 100644 index be958298a0..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/packet.py +++ /dev/null @@ -1,14 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -from scapy.packet import Packet - - -class OBD_Packet(Packet): - def extract_padding(self, s): - return '', s diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/__init__.py deleted file mode 100644 index 9d7ebf0032..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -""" -Package of contrib automotive obd specific modules -that have to be loaded explicitly. -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids.py deleted file mode 100644 index 860ba16d5b..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids.py +++ /dev/null @@ -1,382 +0,0 @@ -# flake8: noqa: F405 - -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -from scapy.packet import Packet, bind_layers -from scapy.fields import PacketListField - -from scapy.contrib.automotive.obd.pid.pids_00_1F import * -from scapy.contrib.automotive.obd.pid.pids_20_3F import * -from scapy.contrib.automotive.obd.pid.pids_40_5F import * -from scapy.contrib.automotive.obd.pid.pids_60_7F import * -from scapy.contrib.automotive.obd.pid.pids_80_9F import * -from scapy.contrib.automotive.obd.pid.pids_A0_C0 import * - - -class OBD_S01_PR_Record(Packet): - fields_desc = [ - XByteField("pid", 0), - ] - - -class OBD_S01_PR(Packet): - name = "Parameter IDs" - fields_desc = [ - PacketListField("data_records", [], OBD_S01_PR_Record) - ] - - -class OBD_S02_PR_Record(Packet): - fields_desc = [ - XByteField("pid", 0), - XByteField("frame_no", 0), - ] - - -class OBD_S02_PR(Packet): - name = "Parameter IDs" - fields_desc = [ - PacketListField("data_records", [], OBD_S02_PR_Record) - ] - - -bind_layers(OBD_S01_PR_Record, OBD_PID00, pid=0x00) -bind_layers(OBD_S01_PR_Record, OBD_PID01, pid=0x01) -bind_layers(OBD_S01_PR_Record, OBD_PID02, pid=0x02) -bind_layers(OBD_S01_PR_Record, OBD_PID03, pid=0x03) -bind_layers(OBD_S01_PR_Record, OBD_PID04, pid=0x04) -bind_layers(OBD_S01_PR_Record, OBD_PID05, pid=0x05) -bind_layers(OBD_S01_PR_Record, OBD_PID06, pid=0x06) -bind_layers(OBD_S01_PR_Record, OBD_PID07, pid=0x07) -bind_layers(OBD_S01_PR_Record, OBD_PID08, pid=0x08) -bind_layers(OBD_S01_PR_Record, OBD_PID09, pid=0x09) -bind_layers(OBD_S01_PR_Record, OBD_PID0A, pid=0x0A) -bind_layers(OBD_S01_PR_Record, OBD_PID0B, pid=0x0B) -bind_layers(OBD_S01_PR_Record, OBD_PID0C, pid=0x0C) -bind_layers(OBD_S01_PR_Record, OBD_PID0D, pid=0x0D) -bind_layers(OBD_S01_PR_Record, OBD_PID0E, pid=0x0E) -bind_layers(OBD_S01_PR_Record, OBD_PID0F, pid=0x0F) -bind_layers(OBD_S01_PR_Record, OBD_PID10, pid=0x10) -bind_layers(OBD_S01_PR_Record, OBD_PID11, pid=0x11) -bind_layers(OBD_S01_PR_Record, OBD_PID12, pid=0x12) -bind_layers(OBD_S01_PR_Record, OBD_PID13, pid=0x13) -bind_layers(OBD_S01_PR_Record, OBD_PID14, pid=0x14) -bind_layers(OBD_S01_PR_Record, OBD_PID15, pid=0x15) -bind_layers(OBD_S01_PR_Record, OBD_PID16, pid=0x16) -bind_layers(OBD_S01_PR_Record, OBD_PID17, pid=0x17) -bind_layers(OBD_S01_PR_Record, OBD_PID18, pid=0x18) -bind_layers(OBD_S01_PR_Record, OBD_PID19, pid=0x19) -bind_layers(OBD_S01_PR_Record, OBD_PID1A, pid=0x1A) -bind_layers(OBD_S01_PR_Record, OBD_PID1B, pid=0x1B) -bind_layers(OBD_S01_PR_Record, OBD_PID1C, pid=0x1C) -bind_layers(OBD_S01_PR_Record, OBD_PID1D, pid=0x1D) -bind_layers(OBD_S01_PR_Record, OBD_PID1E, pid=0x1E) -bind_layers(OBD_S01_PR_Record, OBD_PID1F, pid=0x1F) -bind_layers(OBD_S01_PR_Record, OBD_PID20, pid=0x20) -bind_layers(OBD_S01_PR_Record, OBD_PID21, pid=0x21) -bind_layers(OBD_S01_PR_Record, OBD_PID22, pid=0x22) -bind_layers(OBD_S01_PR_Record, OBD_PID23, pid=0x23) -bind_layers(OBD_S01_PR_Record, OBD_PID24, pid=0x24) -bind_layers(OBD_S01_PR_Record, OBD_PID25, pid=0x25) -bind_layers(OBD_S01_PR_Record, OBD_PID26, pid=0x26) -bind_layers(OBD_S01_PR_Record, OBD_PID27, pid=0x27) -bind_layers(OBD_S01_PR_Record, OBD_PID28, pid=0x28) -bind_layers(OBD_S01_PR_Record, OBD_PID29, pid=0x29) -bind_layers(OBD_S01_PR_Record, OBD_PID2A, pid=0x2A) -bind_layers(OBD_S01_PR_Record, OBD_PID2B, pid=0x2B) -bind_layers(OBD_S01_PR_Record, OBD_PID2C, pid=0x2C) -bind_layers(OBD_S01_PR_Record, OBD_PID2D, pid=0x2D) -bind_layers(OBD_S01_PR_Record, OBD_PID2E, pid=0x2E) -bind_layers(OBD_S01_PR_Record, OBD_PID2F, pid=0x2F) -bind_layers(OBD_S01_PR_Record, OBD_PID30, pid=0x30) -bind_layers(OBD_S01_PR_Record, OBD_PID31, pid=0x31) -bind_layers(OBD_S01_PR_Record, OBD_PID32, pid=0x32) -bind_layers(OBD_S01_PR_Record, OBD_PID33, pid=0x33) -bind_layers(OBD_S01_PR_Record, OBD_PID34, pid=0x34) -bind_layers(OBD_S01_PR_Record, OBD_PID35, pid=0x35) -bind_layers(OBD_S01_PR_Record, OBD_PID36, pid=0x36) -bind_layers(OBD_S01_PR_Record, OBD_PID37, pid=0x37) -bind_layers(OBD_S01_PR_Record, OBD_PID38, pid=0x38) -bind_layers(OBD_S01_PR_Record, OBD_PID39, pid=0x39) -bind_layers(OBD_S01_PR_Record, OBD_PID3A, pid=0x3A) -bind_layers(OBD_S01_PR_Record, OBD_PID3B, pid=0x3B) -bind_layers(OBD_S01_PR_Record, OBD_PID3C, pid=0x3C) -bind_layers(OBD_S01_PR_Record, OBD_PID3D, pid=0x3D) -bind_layers(OBD_S01_PR_Record, OBD_PID3E, pid=0x3E) -bind_layers(OBD_S01_PR_Record, OBD_PID3F, pid=0x3F) -bind_layers(OBD_S01_PR_Record, OBD_PID40, pid=0x40) -bind_layers(OBD_S01_PR_Record, OBD_PID41, pid=0x41) -bind_layers(OBD_S01_PR_Record, OBD_PID42, pid=0x42) -bind_layers(OBD_S01_PR_Record, OBD_PID43, pid=0x43) -bind_layers(OBD_S01_PR_Record, OBD_PID44, pid=0x44) -bind_layers(OBD_S01_PR_Record, OBD_PID45, pid=0x45) -bind_layers(OBD_S01_PR_Record, OBD_PID46, pid=0x46) -bind_layers(OBD_S01_PR_Record, OBD_PID47, pid=0x47) -bind_layers(OBD_S01_PR_Record, OBD_PID48, pid=0x48) -bind_layers(OBD_S01_PR_Record, OBD_PID49, pid=0x49) -bind_layers(OBD_S01_PR_Record, OBD_PID4A, pid=0x4A) -bind_layers(OBD_S01_PR_Record, OBD_PID4B, pid=0x4B) -bind_layers(OBD_S01_PR_Record, OBD_PID4C, pid=0x4C) -bind_layers(OBD_S01_PR_Record, OBD_PID4D, pid=0x4D) -bind_layers(OBD_S01_PR_Record, OBD_PID4E, pid=0x4E) -bind_layers(OBD_S01_PR_Record, OBD_PID4F, pid=0x4F) -bind_layers(OBD_S01_PR_Record, OBD_PID50, pid=0x50) -bind_layers(OBD_S01_PR_Record, OBD_PID51, pid=0x51) -bind_layers(OBD_S01_PR_Record, OBD_PID52, pid=0x52) -bind_layers(OBD_S01_PR_Record, OBD_PID53, pid=0x53) -bind_layers(OBD_S01_PR_Record, OBD_PID54, pid=0x54) -bind_layers(OBD_S01_PR_Record, OBD_PID55, pid=0x55) -bind_layers(OBD_S01_PR_Record, OBD_PID56, pid=0x56) -bind_layers(OBD_S01_PR_Record, OBD_PID57, pid=0x57) -bind_layers(OBD_S01_PR_Record, OBD_PID58, pid=0x58) -bind_layers(OBD_S01_PR_Record, OBD_PID59, pid=0x59) -bind_layers(OBD_S01_PR_Record, OBD_PID5A, pid=0x5A) -bind_layers(OBD_S01_PR_Record, OBD_PID5B, pid=0x5B) -bind_layers(OBD_S01_PR_Record, OBD_PID5C, pid=0x5C) -bind_layers(OBD_S01_PR_Record, OBD_PID5D, pid=0x5D) -bind_layers(OBD_S01_PR_Record, OBD_PID5E, pid=0x5E) -bind_layers(OBD_S01_PR_Record, OBD_PID5F, pid=0x5F) -bind_layers(OBD_S01_PR_Record, OBD_PID60, pid=0x60) -bind_layers(OBD_S01_PR_Record, OBD_PID61, pid=0x61) -bind_layers(OBD_S01_PR_Record, OBD_PID62, pid=0x62) -bind_layers(OBD_S01_PR_Record, OBD_PID63, pid=0x63) -bind_layers(OBD_S01_PR_Record, OBD_PID64, pid=0x64) -bind_layers(OBD_S01_PR_Record, OBD_PID65, pid=0x65) -bind_layers(OBD_S01_PR_Record, OBD_PID66, pid=0x66) -bind_layers(OBD_S01_PR_Record, OBD_PID67, pid=0x67) -bind_layers(OBD_S01_PR_Record, OBD_PID68, pid=0x68) -bind_layers(OBD_S01_PR_Record, OBD_PID69, pid=0x69) -bind_layers(OBD_S01_PR_Record, OBD_PID6A, pid=0x6A) -bind_layers(OBD_S01_PR_Record, OBD_PID6B, pid=0x6B) -bind_layers(OBD_S01_PR_Record, OBD_PID6C, pid=0x6C) -bind_layers(OBD_S01_PR_Record, OBD_PID6D, pid=0x6D) -bind_layers(OBD_S01_PR_Record, OBD_PID6E, pid=0x6E) -bind_layers(OBD_S01_PR_Record, OBD_PID6F, pid=0x6F) -bind_layers(OBD_S01_PR_Record, OBD_PID70, pid=0x70) -bind_layers(OBD_S01_PR_Record, OBD_PID71, pid=0x71) -bind_layers(OBD_S01_PR_Record, OBD_PID72, pid=0x72) -bind_layers(OBD_S01_PR_Record, OBD_PID73, pid=0x73) -bind_layers(OBD_S01_PR_Record, OBD_PID74, pid=0x74) -bind_layers(OBD_S01_PR_Record, OBD_PID75, pid=0x75) -bind_layers(OBD_S01_PR_Record, OBD_PID76, pid=0x76) -bind_layers(OBD_S01_PR_Record, OBD_PID77, pid=0x77) -bind_layers(OBD_S01_PR_Record, OBD_PID78, pid=0x78) -bind_layers(OBD_S01_PR_Record, OBD_PID79, pid=0x79) -bind_layers(OBD_S01_PR_Record, OBD_PID7A, pid=0x7A) -bind_layers(OBD_S01_PR_Record, OBD_PID7B, pid=0x7B) -bind_layers(OBD_S01_PR_Record, OBD_PID7C, pid=0x7C) -bind_layers(OBD_S01_PR_Record, OBD_PID7D, pid=0x7D) -bind_layers(OBD_S01_PR_Record, OBD_PID7E, pid=0x7E) -bind_layers(OBD_S01_PR_Record, OBD_PID7F, pid=0x7F) -bind_layers(OBD_S01_PR_Record, OBD_PID80, pid=0x80) -bind_layers(OBD_S01_PR_Record, OBD_PID81, pid=0x81) -bind_layers(OBD_S01_PR_Record, OBD_PID82, pid=0x82) -bind_layers(OBD_S01_PR_Record, OBD_PID83, pid=0x83) -bind_layers(OBD_S01_PR_Record, OBD_PID84, pid=0x84) -bind_layers(OBD_S01_PR_Record, OBD_PID85, pid=0x85) -bind_layers(OBD_S01_PR_Record, OBD_PID86, pid=0x86) -bind_layers(OBD_S01_PR_Record, OBD_PID87, pid=0x87) -bind_layers(OBD_S01_PR_Record, OBD_PID88, pid=0x88) -bind_layers(OBD_S01_PR_Record, OBD_PID89, pid=0x89) -bind_layers(OBD_S01_PR_Record, OBD_PID8A, pid=0x8A) -bind_layers(OBD_S01_PR_Record, OBD_PID8B, pid=0x8B) -bind_layers(OBD_S01_PR_Record, OBD_PID8C, pid=0x8C) -bind_layers(OBD_S01_PR_Record, OBD_PID8D, pid=0x8D) -bind_layers(OBD_S01_PR_Record, OBD_PID8E, pid=0x8E) -bind_layers(OBD_S01_PR_Record, OBD_PID8F, pid=0x8F) -bind_layers(OBD_S01_PR_Record, OBD_PID90, pid=0x90) -bind_layers(OBD_S01_PR_Record, OBD_PID91, pid=0x91) -bind_layers(OBD_S01_PR_Record, OBD_PID92, pid=0x92) -bind_layers(OBD_S01_PR_Record, OBD_PID93, pid=0x93) -bind_layers(OBD_S01_PR_Record, OBD_PID94, pid=0x94) -bind_layers(OBD_S01_PR_Record, OBD_PID98, pid=0x98) -bind_layers(OBD_S01_PR_Record, OBD_PID99, pid=0x99) -bind_layers(OBD_S01_PR_Record, OBD_PID9A, pid=0x9A) -bind_layers(OBD_S01_PR_Record, OBD_PID9B, pid=0x9B) -bind_layers(OBD_S01_PR_Record, OBD_PID9C, pid=0x9C) -bind_layers(OBD_S01_PR_Record, OBD_PID9D, pid=0x9D) -bind_layers(OBD_S01_PR_Record, OBD_PID9E, pid=0x9E) -bind_layers(OBD_S01_PR_Record, OBD_PID9F, pid=0x9F) -bind_layers(OBD_S01_PR_Record, OBD_PIDA0, pid=0xA0) -bind_layers(OBD_S01_PR_Record, OBD_PIDA1, pid=0xA1) -bind_layers(OBD_S01_PR_Record, OBD_PIDA2, pid=0xA2) -bind_layers(OBD_S01_PR_Record, OBD_PIDA3, pid=0xA3) -bind_layers(OBD_S01_PR_Record, OBD_PIDA4, pid=0xA4) -bind_layers(OBD_S01_PR_Record, OBD_PIDA5, pid=0xA5) -bind_layers(OBD_S01_PR_Record, OBD_PIDA6, pid=0xA6) -bind_layers(OBD_S01_PR_Record, OBD_PIDC0, pid=0xC0) - - -# Service 2 - -bind_layers(OBD_S02_PR_Record, OBD_PID00, pid=0x00) -bind_layers(OBD_S02_PR_Record, OBD_PID01, pid=0x01) -bind_layers(OBD_S02_PR_Record, OBD_PID02, pid=0x02) -bind_layers(OBD_S02_PR_Record, OBD_PID03, pid=0x03) -bind_layers(OBD_S02_PR_Record, OBD_PID04, pid=0x04) -bind_layers(OBD_S02_PR_Record, OBD_PID05, pid=0x05) -bind_layers(OBD_S02_PR_Record, OBD_PID06, pid=0x06) -bind_layers(OBD_S02_PR_Record, OBD_PID07, pid=0x07) -bind_layers(OBD_S02_PR_Record, OBD_PID08, pid=0x08) -bind_layers(OBD_S02_PR_Record, OBD_PID09, pid=0x09) -bind_layers(OBD_S02_PR_Record, OBD_PID0A, pid=0x0A) -bind_layers(OBD_S02_PR_Record, OBD_PID0B, pid=0x0B) -bind_layers(OBD_S02_PR_Record, OBD_PID0C, pid=0x0C) -bind_layers(OBD_S02_PR_Record, OBD_PID0D, pid=0x0D) -bind_layers(OBD_S02_PR_Record, OBD_PID0E, pid=0x0E) -bind_layers(OBD_S02_PR_Record, OBD_PID0F, pid=0x0F) -bind_layers(OBD_S02_PR_Record, OBD_PID10, pid=0x10) -bind_layers(OBD_S02_PR_Record, OBD_PID11, pid=0x11) -bind_layers(OBD_S02_PR_Record, OBD_PID12, pid=0x12) -bind_layers(OBD_S02_PR_Record, OBD_PID13, pid=0x13) -bind_layers(OBD_S02_PR_Record, OBD_PID14, pid=0x14) -bind_layers(OBD_S02_PR_Record, OBD_PID15, pid=0x15) -bind_layers(OBD_S02_PR_Record, OBD_PID16, pid=0x16) -bind_layers(OBD_S02_PR_Record, OBD_PID17, pid=0x17) -bind_layers(OBD_S02_PR_Record, OBD_PID18, pid=0x18) -bind_layers(OBD_S02_PR_Record, OBD_PID19, pid=0x19) -bind_layers(OBD_S02_PR_Record, OBD_PID1A, pid=0x1A) -bind_layers(OBD_S02_PR_Record, OBD_PID1B, pid=0x1B) -bind_layers(OBD_S02_PR_Record, OBD_PID1C, pid=0x1C) -bind_layers(OBD_S02_PR_Record, OBD_PID1D, pid=0x1D) -bind_layers(OBD_S02_PR_Record, OBD_PID1E, pid=0x1E) -bind_layers(OBD_S02_PR_Record, OBD_PID1F, pid=0x1F) -bind_layers(OBD_S02_PR_Record, OBD_PID20, pid=0x20) -bind_layers(OBD_S02_PR_Record, OBD_PID21, pid=0x21) -bind_layers(OBD_S02_PR_Record, OBD_PID22, pid=0x22) -bind_layers(OBD_S02_PR_Record, OBD_PID23, pid=0x23) -bind_layers(OBD_S02_PR_Record, OBD_PID24, pid=0x24) -bind_layers(OBD_S02_PR_Record, OBD_PID25, pid=0x25) -bind_layers(OBD_S02_PR_Record, OBD_PID26, pid=0x26) -bind_layers(OBD_S02_PR_Record, OBD_PID27, pid=0x27) -bind_layers(OBD_S02_PR_Record, OBD_PID28, pid=0x28) -bind_layers(OBD_S02_PR_Record, OBD_PID29, pid=0x29) -bind_layers(OBD_S02_PR_Record, OBD_PID2A, pid=0x2A) -bind_layers(OBD_S02_PR_Record, OBD_PID2B, pid=0x2B) -bind_layers(OBD_S02_PR_Record, OBD_PID2C, pid=0x2C) -bind_layers(OBD_S02_PR_Record, OBD_PID2D, pid=0x2D) -bind_layers(OBD_S02_PR_Record, OBD_PID2E, pid=0x2E) -bind_layers(OBD_S02_PR_Record, OBD_PID2F, pid=0x2F) -bind_layers(OBD_S02_PR_Record, OBD_PID30, pid=0x30) -bind_layers(OBD_S02_PR_Record, OBD_PID31, pid=0x31) -bind_layers(OBD_S02_PR_Record, OBD_PID32, pid=0x32) -bind_layers(OBD_S02_PR_Record, OBD_PID33, pid=0x33) -bind_layers(OBD_S02_PR_Record, OBD_PID34, pid=0x34) -bind_layers(OBD_S02_PR_Record, OBD_PID35, pid=0x35) -bind_layers(OBD_S02_PR_Record, OBD_PID36, pid=0x36) -bind_layers(OBD_S02_PR_Record, OBD_PID37, pid=0x37) -bind_layers(OBD_S02_PR_Record, OBD_PID38, pid=0x38) -bind_layers(OBD_S02_PR_Record, OBD_PID39, pid=0x39) -bind_layers(OBD_S02_PR_Record, OBD_PID3A, pid=0x3A) -bind_layers(OBD_S02_PR_Record, OBD_PID3B, pid=0x3B) -bind_layers(OBD_S02_PR_Record, OBD_PID3C, pid=0x3C) -bind_layers(OBD_S02_PR_Record, OBD_PID3D, pid=0x3D) -bind_layers(OBD_S02_PR_Record, OBD_PID3E, pid=0x3E) -bind_layers(OBD_S02_PR_Record, OBD_PID3F, pid=0x3F) -bind_layers(OBD_S02_PR_Record, OBD_PID40, pid=0x40) -bind_layers(OBD_S02_PR_Record, OBD_PID41, pid=0x41) -bind_layers(OBD_S02_PR_Record, OBD_PID42, pid=0x42) -bind_layers(OBD_S02_PR_Record, OBD_PID43, pid=0x43) -bind_layers(OBD_S02_PR_Record, OBD_PID44, pid=0x44) -bind_layers(OBD_S02_PR_Record, OBD_PID45, pid=0x45) -bind_layers(OBD_S02_PR_Record, OBD_PID46, pid=0x46) -bind_layers(OBD_S02_PR_Record, OBD_PID47, pid=0x47) -bind_layers(OBD_S02_PR_Record, OBD_PID48, pid=0x48) -bind_layers(OBD_S02_PR_Record, OBD_PID49, pid=0x49) -bind_layers(OBD_S02_PR_Record, OBD_PID4A, pid=0x4A) -bind_layers(OBD_S02_PR_Record, OBD_PID4B, pid=0x4B) -bind_layers(OBD_S02_PR_Record, OBD_PID4C, pid=0x4C) -bind_layers(OBD_S02_PR_Record, OBD_PID4D, pid=0x4D) -bind_layers(OBD_S02_PR_Record, OBD_PID4E, pid=0x4E) -bind_layers(OBD_S02_PR_Record, OBD_PID4F, pid=0x4F) -bind_layers(OBD_S02_PR_Record, OBD_PID50, pid=0x50) -bind_layers(OBD_S02_PR_Record, OBD_PID51, pid=0x51) -bind_layers(OBD_S02_PR_Record, OBD_PID52, pid=0x52) -bind_layers(OBD_S02_PR_Record, OBD_PID53, pid=0x53) -bind_layers(OBD_S02_PR_Record, OBD_PID54, pid=0x54) -bind_layers(OBD_S02_PR_Record, OBD_PID55, pid=0x55) -bind_layers(OBD_S02_PR_Record, OBD_PID56, pid=0x56) -bind_layers(OBD_S02_PR_Record, OBD_PID57, pid=0x57) -bind_layers(OBD_S02_PR_Record, OBD_PID58, pid=0x58) -bind_layers(OBD_S02_PR_Record, OBD_PID59, pid=0x59) -bind_layers(OBD_S02_PR_Record, OBD_PID5A, pid=0x5A) -bind_layers(OBD_S02_PR_Record, OBD_PID5B, pid=0x5B) -bind_layers(OBD_S02_PR_Record, OBD_PID5C, pid=0x5C) -bind_layers(OBD_S02_PR_Record, OBD_PID5D, pid=0x5D) -bind_layers(OBD_S02_PR_Record, OBD_PID5E, pid=0x5E) -bind_layers(OBD_S02_PR_Record, OBD_PID5F, pid=0x5F) -bind_layers(OBD_S02_PR_Record, OBD_PID60, pid=0x60) -bind_layers(OBD_S02_PR_Record, OBD_PID61, pid=0x61) -bind_layers(OBD_S02_PR_Record, OBD_PID62, pid=0x62) -bind_layers(OBD_S02_PR_Record, OBD_PID63, pid=0x63) -bind_layers(OBD_S02_PR_Record, OBD_PID64, pid=0x64) -bind_layers(OBD_S02_PR_Record, OBD_PID65, pid=0x65) -bind_layers(OBD_S02_PR_Record, OBD_PID66, pid=0x66) -bind_layers(OBD_S02_PR_Record, OBD_PID67, pid=0x67) -bind_layers(OBD_S02_PR_Record, OBD_PID68, pid=0x68) -bind_layers(OBD_S02_PR_Record, OBD_PID69, pid=0x69) -bind_layers(OBD_S02_PR_Record, OBD_PID6A, pid=0x6A) -bind_layers(OBD_S02_PR_Record, OBD_PID6B, pid=0x6B) -bind_layers(OBD_S02_PR_Record, OBD_PID6C, pid=0x6C) -bind_layers(OBD_S02_PR_Record, OBD_PID6D, pid=0x6D) -bind_layers(OBD_S02_PR_Record, OBD_PID6E, pid=0x6E) -bind_layers(OBD_S02_PR_Record, OBD_PID6F, pid=0x6F) -bind_layers(OBD_S02_PR_Record, OBD_PID70, pid=0x70) -bind_layers(OBD_S02_PR_Record, OBD_PID71, pid=0x71) -bind_layers(OBD_S02_PR_Record, OBD_PID72, pid=0x72) -bind_layers(OBD_S02_PR_Record, OBD_PID73, pid=0x73) -bind_layers(OBD_S02_PR_Record, OBD_PID74, pid=0x74) -bind_layers(OBD_S02_PR_Record, OBD_PID75, pid=0x75) -bind_layers(OBD_S02_PR_Record, OBD_PID76, pid=0x76) -bind_layers(OBD_S02_PR_Record, OBD_PID77, pid=0x77) -bind_layers(OBD_S02_PR_Record, OBD_PID78, pid=0x78) -bind_layers(OBD_S02_PR_Record, OBD_PID79, pid=0x79) -bind_layers(OBD_S02_PR_Record, OBD_PID7A, pid=0x7A) -bind_layers(OBD_S02_PR_Record, OBD_PID7B, pid=0x7B) -bind_layers(OBD_S02_PR_Record, OBD_PID7C, pid=0x7C) -bind_layers(OBD_S02_PR_Record, OBD_PID7D, pid=0x7D) -bind_layers(OBD_S02_PR_Record, OBD_PID7E, pid=0x7E) -bind_layers(OBD_S02_PR_Record, OBD_PID7F, pid=0x7F) -bind_layers(OBD_S02_PR_Record, OBD_PID80, pid=0x80) -bind_layers(OBD_S02_PR_Record, OBD_PID81, pid=0x81) -bind_layers(OBD_S02_PR_Record, OBD_PID82, pid=0x82) -bind_layers(OBD_S02_PR_Record, OBD_PID83, pid=0x83) -bind_layers(OBD_S02_PR_Record, OBD_PID84, pid=0x84) -bind_layers(OBD_S02_PR_Record, OBD_PID85, pid=0x85) -bind_layers(OBD_S02_PR_Record, OBD_PID86, pid=0x86) -bind_layers(OBD_S02_PR_Record, OBD_PID87, pid=0x87) -bind_layers(OBD_S02_PR_Record, OBD_PID88, pid=0x88) -bind_layers(OBD_S02_PR_Record, OBD_PID89, pid=0x89) -bind_layers(OBD_S02_PR_Record, OBD_PID8A, pid=0x8A) -bind_layers(OBD_S02_PR_Record, OBD_PID8B, pid=0x8B) -bind_layers(OBD_S02_PR_Record, OBD_PID8C, pid=0x8C) -bind_layers(OBD_S02_PR_Record, OBD_PID8D, pid=0x8D) -bind_layers(OBD_S02_PR_Record, OBD_PID8E, pid=0x8E) -bind_layers(OBD_S02_PR_Record, OBD_PID8F, pid=0x8F) -bind_layers(OBD_S02_PR_Record, OBD_PID90, pid=0x90) -bind_layers(OBD_S02_PR_Record, OBD_PID91, pid=0x91) -bind_layers(OBD_S02_PR_Record, OBD_PID92, pid=0x92) -bind_layers(OBD_S02_PR_Record, OBD_PID93, pid=0x93) -bind_layers(OBD_S02_PR_Record, OBD_PID94, pid=0x94) -bind_layers(OBD_S02_PR_Record, OBD_PID98, pid=0x98) -bind_layers(OBD_S02_PR_Record, OBD_PID99, pid=0x99) -bind_layers(OBD_S02_PR_Record, OBD_PID9A, pid=0x9A) -bind_layers(OBD_S02_PR_Record, OBD_PID9B, pid=0x9B) -bind_layers(OBD_S02_PR_Record, OBD_PID9C, pid=0x9C) -bind_layers(OBD_S02_PR_Record, OBD_PID9D, pid=0x9D) -bind_layers(OBD_S02_PR_Record, OBD_PID9E, pid=0x9E) -bind_layers(OBD_S02_PR_Record, OBD_PID9F, pid=0x9F) -bind_layers(OBD_S02_PR_Record, OBD_PIDA0, pid=0xA0) -bind_layers(OBD_S02_PR_Record, OBD_PIDA1, pid=0xA1) -bind_layers(OBD_S02_PR_Record, OBD_PIDA2, pid=0xA2) -bind_layers(OBD_S02_PR_Record, OBD_PIDA3, pid=0xA3) -bind_layers(OBD_S02_PR_Record, OBD_PIDA4, pid=0xA4) -bind_layers(OBD_S02_PR_Record, OBD_PIDA5, pid=0xA5) -bind_layers(OBD_S02_PR_Record, OBD_PIDA6, pid=0xA6) -bind_layers(OBD_S02_PR_Record, OBD_PIDC0, pid=0xC0) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_00_1F.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_00_1F.py deleted file mode 100644 index 3b28c0868a..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_00_1F.py +++ /dev/null @@ -1,378 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -from scapy.fields import BitEnumField, BitField, ScalingField, \ - FlagsField, XByteEnumField, PacketField -from scapy.contrib.automotive.obd.packet import OBD_Packet -from scapy.contrib.automotive.obd.services import OBD_DTC - - -# See https://en.wikipedia.org/wiki/OBD-II_PIDs for further information -# PID = Parameter IDentification - -class OBD_PID00(OBD_Packet): - name = "PID_00_PIDsSupported" - - fields_desc = [ - FlagsField('supported_pids', b'', 32, [ - 'PID20', - 'PID1F', - 'PID1E', - 'PID1D', - 'PID1C', - 'PID1B', - 'PID1A', - 'PID19', - 'PID18', - 'PID17', - 'PID16', - 'PID15', - 'PID14', - 'PID13', - 'PID12', - 'PID11', - 'PID10', - 'PID0F', - 'PID0E', - 'PID0D', - 'PID0C', - 'PID0B', - 'PID0A', - 'PID09', - 'PID08', - 'PID07', - 'PID06', - 'PID05', - 'PID04', - 'PID03', - 'PID02', - 'PID01' - ]) - ] - - -class OBD_PID01(OBD_Packet): - name = "PID_01_MonitorStatusSinceDtcsCleared" - - onOff = { - 0: 'off', - 1: 'on' - } - - fields_desc = [ - BitEnumField('mil', 0, 1, onOff), - BitField('dtc_count', 0, 7), - - BitField('reserved1', 0, 1), - FlagsField('continuous_tests_ready', 0, 3, [ - 'misfire', - 'fuelSystem', - 'components' - ]), - - BitField('reserved2', 0, 1), - FlagsField('continuous_tests_supported', 0, 3, [ - 'misfire', - 'fuel_system', - 'components' - ]), - - FlagsField('once_per_trip_tests_supported', 0, 8, [ - 'egr', - 'oxygenSensorHeater', - 'oxygenSensor', - 'acSystemRefrigerant', - 'secondaryAirSystem', - 'evaporativeSystem', - 'heatedCatalyst', - 'catalyst' - ]), - - FlagsField('once_per_trip_tests_ready', 0, 8, [ - 'egr', - 'oxygenSensorHeater', - 'oxygenSensor', - 'acSystemRefrigerant', - 'secondaryAirSystem', - 'evaporativeSystem', - 'heatedCatalyst', - 'catalyst' - ]) - ] - - -class OBD_PID02(OBD_Packet): - name = "PID_02_FreezeDtc" - fields_desc = [ - PacketField('dtc', b'', OBD_DTC) - ] - - -class OBD_PID03(OBD_Packet): - name = "PID_03_FuelSystemStatus" - - loopStates = { - 0x00: 'OpenLoopInsufficientEngineTemperature', - 0x02: 'ClosedLoop', - 0x04: 'OpenLoopEngineLoadOrFuelCut', - 0x08: 'OpenLoopDueSystemFailure', - 0x10: 'ClosedLoopWithFault' - } - - fields_desc = [ - XByteEnumField('fuel_system1', 0, loopStates), - XByteEnumField('fuel_system2', 0, loopStates) - ] - - -class OBD_PID04(OBD_Packet): - name = "PID_04_CalculatedEngineLoad" - fields_desc = [ - ScalingField('data', 0, scaling=100 / 255., unit="%") - ] - - -class OBD_PID05(OBD_Packet): - name = "PID_05_EngineCoolantTemperature" - fields_desc = [ - ScalingField('data', 0, unit="deg. C", offset=-40.0) - ] - - -class OBD_PID06(OBD_Packet): - name = "PID_06_ShortTermFuelTrimBank1" - fields_desc = [ - ScalingField('data', 0, scaling=100 / 128., - unit="%", offset=-100.0) - ] - - -class OBD_PID07(OBD_Packet): - name = "PID_07_LongTermFuelTrimBank1" - fields_desc = [ - ScalingField('data', 0, scaling=100 / 128., - unit="%", offset=-100.0) - ] - - -class OBD_PID08(OBD_Packet): - name = "PID_08_ShortTermFuelTrimBank2" - fields_desc = [ - ScalingField('data', 0, scaling=100 / 128., - unit="%", offset=-100.0) - ] - - -class OBD_PID09(OBD_Packet): - name = "PID_09_LongTermFuelTrimBank2" - fields_desc = [ - ScalingField('data', 0, scaling=100 / 128., - unit="%", offset=-100.0) - ] - - -class OBD_PID0A(OBD_Packet): - name = "PID_0A_FuelPressure" - fields_desc = [ - ScalingField('data', 0, scaling=3, unit="kPa") - ] - - -class OBD_PID0B(OBD_Packet): - name = "PID_0B_IntakeManifoldAbsolutePressure" - fields_desc = [ - ScalingField('data', 0, unit="kPa") - ] - - -class OBD_PID0C(OBD_Packet): - name = "PID_0C_EngineRpm" - fields_desc = [ - ScalingField('data', 0, scaling=1 / 4., unit="min-1", fmt="H") - ] - - -class OBD_PID0D(OBD_Packet): - name = "PID_0D_VehicleSpeed" - fields_desc = [ - ScalingField('data', 0, unit="km/h") - ] - - -class OBD_PID0E(OBD_Packet): - name = "PID_0E_TimingAdvance" - fields_desc = [ - ScalingField('data', 0, scaling=1 / 2., unit="deg.", offset=-64.0) - ] - - -class OBD_PID0F(OBD_Packet): - name = "PID_0F_IntakeAirTemperature" - fields_desc = [ - ScalingField('data', 0, unit="deg. C", offset=-40.0) - ] - - -class OBD_PID10(OBD_Packet): - name = "PID_10_MafAirFlowRate" - fields_desc = [ - ScalingField('data', 0, scaling=1 / 100., unit="g/s") - ] - - -class OBD_PID11(OBD_Packet): - name = "PID_11_ThrottlePosition" - fields_desc = [ - ScalingField('data', 0, scaling=100 / 255., unit="%") - ] - - -class OBD_PID12(OBD_Packet): - name = "PID_12_CommandedSecondaryAirStatus" - - states = { - 0x00: 'upstream', - 0x02: 'downstreamCatalyticConverter', - 0x04: 'outsideAtmosphereOrOff', - 0x08: 'pumpCommanded' - } - - fields_desc = [ - XByteEnumField('data', 0, states) - ] - - -class OBD_PID13(OBD_Packet): - name = "PID_13_OxygenSensorsPresent" - fields_desc = [ - FlagsField('sensors_present', b'', 8, [ - 'Bank1Sensor1', - 'Bank1Sensor2', - 'Bank1Sensor3', - 'Bank1Sensor4', - 'Bank2Sensor1', - 'Bank2Sensor2', - 'Bank2Sensor3', - 'Bank2Sensor4' - ]) - ] - - -class _OBD_PID14_1B(OBD_Packet): - fields_desc = [ - ScalingField('outputVoltage', 0, scaling=0.005, unit="V"), - ScalingField('trim', 0, scaling=100 / 128., - unit="%", offset=-100) - ] - - -class OBD_PID14(_OBD_PID14_1B): - name = "PID_14_OxygenSensor1" - - -class OBD_PID15(_OBD_PID14_1B): - name = "PID_15_OxygenSensor2" - - -class OBD_PID16(_OBD_PID14_1B): - name = "PID_16_OxygenSensor3" - - -class OBD_PID17(_OBD_PID14_1B): - name = "PID_17_OxygenSensor4" - - -class OBD_PID18(_OBD_PID14_1B): - name = "PID_18_OxygenSensor5" - - -class OBD_PID19(_OBD_PID14_1B): - name = "PID_19_OxygenSensor6" - - -class OBD_PID1A(_OBD_PID14_1B): - name = "PID_1A_OxygenSensor7" - - -class OBD_PID1B(_OBD_PID14_1B): - name = "PID_1B_OxygenSensor8" - - -class OBD_PID1C(OBD_Packet): - name = "PID_1C_ObdStandardsThisVehicleConformsTo" - - obdStandards = { - 0x01: 'OBD-II as defined by the CARB', - 0x02: 'OBD as defined by the EPA', - 0x03: 'OBD and OBD-II', - 0x04: 'OBD-I', - 0x05: 'Not OBD compliant', - 0x06: 'EOBD (Europe)', - 0x07: 'EOBD and OBD-II', - 0x08: 'EOBD and OBD', - 0x09: 'EOBD, OBD and OBD II', - 0x0A: 'JOBD (Japan)', - 0x0B: 'JOBD and OBD II', - 0x0C: 'JOBD and EOBD', - 0x0D: 'JOBD, EOBD, and OBD II', - 0x0E: 'Reserved', - 0x0F: 'Reserved', - 0x10: 'Reserved', - 0x11: 'Engine Manufacturer Diagnostics (EMD)', - 0x12: 'Engine Manufacturer Diagnostics Enhanced (EMD+)', - 0x13: 'Heavy Duty On-Board Diagnostics (Child/Partial) (HD OBD-C)', - 0x14: 'Heavy Duty On-Board Diagnostics (HD OBD)', - 0x15: 'World Wide Harmonized OBD (WWH OBD)', - 0x16: 'Reserved', - 0x17: 'Heavy Duty Euro OBD Stage I without NOx control (HD EOBD-I)', - 0x18: 'Heavy Duty Euro OBD Stage I with NOx control (HD EOBD-I N)', - 0x19: 'Heavy Duty Euro OBD Stage II without NOx control (HD EOBD-II)', - 0x1A: 'Heavy Duty Euro OBD Stage II with NOx control (HD EOBD-II N)', - 0x1B: 'Reserved', - 0x1C: 'Brazil OBD Phase 1 (OBDBr-1)', - 0x1D: 'Brazil OBD Phase 2 (OBDBr-2)', - 0x1E: 'Korean OBD (KOBD)', - 0x1F: 'India OBD I (IOBD I)', - 0x20: 'India OBD II (IOBD II)', - 0x21: 'Heavy Duty Euro OBD Stage VI (HD EOBD-IV)', - } - - fields_desc = [ - XByteEnumField('data', 0, obdStandards) - ] - - -class OBD_PID1D(OBD_Packet): - name = "PID_1D_OxygenSensorsPresent" - fields_desc = [ - FlagsField('sensors_present', 0, 8, [ - 'Bank1Sensor1', - 'Bank1Sensor2', - 'Bank2Sensor1', - 'Bank2Sensor2', - 'Bank3Sensor1', - 'Bank3Sensor2', - 'Bank4Sensor1', - 'Bank4Sensor2' - ]) - ] - - -class OBD_PID1E(OBD_Packet): - name = "PID_1E_AuxiliaryInputStatus" - fields_desc = [ - BitField('reserved', 0, 7), - BitEnumField('pto_status', 0, 1, OBD_PID01.onOff) - ] - - -class OBD_PID1F(OBD_Packet): - name = "PID_1F_RunTimeSinceEngineStart" - fields_desc = [ - ScalingField('data', 0, unit="s", fmt="H") - ] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_20_3F.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_20_3F.py deleted file mode 100644 index f382df5f28..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_20_3F.py +++ /dev/null @@ -1,242 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -from scapy.fields import FlagsField, ScalingField -from scapy.contrib.automotive.obd.packet import OBD_Packet - - -# See https://en.wikipedia.org/wiki/OBD-II_PIDs for further information -# PID = Parameter IDentification - - -class OBD_PID20(OBD_Packet): - name = "PID_20_PIDsSupported" - fields_desc = [ - FlagsField('supported_pids', 0, 32, [ - 'PID40', - 'PID3F', - 'PID3E', - 'PID3D', - 'PID3C', - 'PID3B', - 'PID3A', - 'PID39', - 'PID38', - 'PID37', - 'PID36', - 'PID35', - 'PID34', - 'PID33', - 'PID32', - 'PID31', - 'PID30', - 'PID2F', - 'PID2E', - 'PID2D', - 'PID2C', - 'PID2B', - 'PID2A', - 'PID29', - 'PID28', - 'PID27', - 'PID26', - 'PID25', - 'PID24', - 'PID23', - 'PID22', - 'PID21' - ]) - ] - - -class OBD_PID21(OBD_Packet): - name = "PID_21_DistanceTraveledWithMalfunctionIndicatorLampOn" - fields_desc = [ - ScalingField('data', 0, unit="km", fmt="H") - ] - - -class OBD_PID22(OBD_Packet): - name = "PID_22_FuelRailPressure" - fields_desc = [ - ScalingField('data', 0, scaling=0.079, unit="kPa", fmt="H") - ] - - -class OBD_PID23(OBD_Packet): - name = "PID_23_FuelRailGaugePressure" - fields_desc = [ - ScalingField('data', 0, scaling=10, unit="kPa", fmt="H") - ] - - -class _OBD_PID24_2B(OBD_Packet): - fields_desc = [ - ScalingField('equivalence_ratio', 0, scaling=0.0000305, fmt="H"), - ScalingField('voltage', 0, scaling=0.000122, unit="V", fmt="H") - ] - - -class OBD_PID24(_OBD_PID24_2B): - name = "PID_24_OxygenSensor1" - - -class OBD_PID25(_OBD_PID24_2B): - name = "PID_25_OxygenSensor2" - - -class OBD_PID26(_OBD_PID24_2B): - name = "PID_26_OxygenSensor3" - - -class OBD_PID27(_OBD_PID24_2B): - name = "PID_27_OxygenSensor4" - - -class OBD_PID28(_OBD_PID24_2B): - name = "PID_28_OxygenSensor5" - - -class OBD_PID29(_OBD_PID24_2B): - name = "PID_29_OxygenSensor6" - - -class OBD_PID2A(_OBD_PID24_2B): - name = "PID_2A_OxygenSensor7" - - -class OBD_PID2B(_OBD_PID24_2B): - name = "PID_2B_OxygenSensor8" - - -class OBD_PID2C(OBD_Packet): - name = "PID_2C_CommandedEgr" - fields_desc = [ - ScalingField('data', 0, scaling=100 / 255., unit="%") - ] - - -class OBD_PID2D(OBD_Packet): - name = "PID_2D_EgrError" - fields_desc = [ - ScalingField('data', 0, scaling=100 / 128., - unit="%", offset=-100.0) - ] - - -class OBD_PID2E(OBD_Packet): - name = "PID_2E_CommandedEvaporativePurge" - fields_desc = [ - ScalingField('data', 0, scaling=100 / 255., unit="%") - ] - - -class OBD_PID2F(OBD_Packet): - name = "PID_2F_FuelTankLevelInput" - fields_desc = [ - ScalingField('data', 0, scaling=100 / 255., unit="%") - ] - - -class OBD_PID30(OBD_Packet): - name = "PID_30_WarmUpsSinceCodesCleared" - fields_desc = [ - ScalingField('data', 0) - ] - - -class OBD_PID31(OBD_Packet): - name = "PID_31_DistanceTraveledSinceCodesCleared" - fields_desc = [ - ScalingField('data', 0, unit="km", fmt="H") - ] - - -class OBD_PID32(OBD_Packet): - name = "PID_32_EvapSystemVaporPressure" - fields_desc = [ - ScalingField('data', 0, scaling=0.25, unit="Pa", fmt="h") - ] - - -class OBD_PID33(OBD_Packet): - name = "PID_33_AbsoluteBarometricPressure" - fields_desc = [ - ScalingField('data', 0, unit="kPa") - ] - - -class _OBD_PID34_3B(OBD_Packet): - fields_desc = [ - ScalingField('equivalence_ratio', 0, scaling=0.0000305, fmt="H"), - ScalingField('current', 0, scaling=0.00390625, unit="mA", fmt="H") - ] - - -class OBD_PID34(_OBD_PID34_3B): - name = "PID_34_OxygenSensor1" - - -class OBD_PID35(_OBD_PID34_3B): - name = "PID_35_OxygenSensor2" - - -class OBD_PID36(_OBD_PID34_3B): - name = "PID_36_OxygenSensor3" - - -class OBD_PID37(_OBD_PID34_3B): - name = "PID_37_OxygenSensor4" - - -class OBD_PID38(_OBD_PID34_3B): - name = "PID_38_OxygenSensor5" - - -class OBD_PID39(_OBD_PID34_3B): - name = "PID_39_OxygenSensor6" - - -class OBD_PID3A(_OBD_PID34_3B): - name = "PID_3A_OxygenSensor7" - - -class OBD_PID3B(_OBD_PID34_3B): - name = "PID_3B_OxygenSensor8" - - -class OBD_PID3C(OBD_Packet): - name = "PID_3C_CatalystTemperatureBank1Sensor1" - fields_desc = [ - ScalingField('data', 0, scaling=0.1, unit="deg. C", - offset=-40.0, fmt="H") - ] - - -class OBD_PID3D(OBD_Packet): - name = "PID_3D_CatalystTemperatureBank2Sensor1" - fields_desc = [ - ScalingField('data', 0, scaling=0.1, unit="deg. C", - offset=-40.0, fmt="H") - ] - - -class OBD_PID3E(OBD_Packet): - name = "PID_3E_CatalystTemperatureBank1Sensor2" - fields_desc = [ - ScalingField('data', 0, scaling=0.1, unit="deg. C", - offset=-40.0, fmt="H") - ] - - -class OBD_PID3F(OBD_Packet): - name = "PID_3F_CatalystTemperatureBank2Sensor2" - fields_desc = [ - ScalingField('data', 0, scaling=0.1, unit="deg. C", - offset=-40.0, fmt="H") - ] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_40_5F.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_40_5F.py deleted file mode 100644 index e23f9f2d5f..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_40_5F.py +++ /dev/null @@ -1,335 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -from scapy.fields import ByteEnumField, BitField, FlagsField, XByteField, \ - ScalingField, ThreeBytesField -from scapy.contrib.automotive.obd.packet import OBD_Packet - - -# See https://en.wikipedia.org/wiki/OBD-II_PIDs for further information -# PID = Parameter IDentification - - -class OBD_PID40(OBD_Packet): - name = "PID_40_PIDsSupported" - fields_desc = [ - FlagsField('supported_pids', 0, 32, [ - 'PID60', - 'PID5F', - 'PID5E', - 'PID5D', - 'PID5C', - 'PID5B', - 'PID5A', - 'PID59', - 'PID58', - 'PID57', - 'PID56', - 'PID55', - 'PID54', - 'PID53', - 'PID52', - 'PID51', - 'PID50', - 'PID4F', - 'PID4E', - 'PID4D', - 'PID4C', - 'PID4B', - 'PID4A', - 'PID49', - 'PID48', - 'PID47', - 'PID46', - 'PID45', - 'PID44', - 'PID43', - 'PID42', - 'PID41' - ]) - ] - - -class OBD_PID41(OBD_Packet): - name = "PID_41_MonitorStatusThisDriveCycle" - onOff = { - 0: 'off', - 1: 'on' - } - - fields_desc = [ - XByteField('reserved', 0), - - BitField('reserved1', 0, 1), - FlagsField('continuous_tests_ready', 0, 3, [ - 'misfire', - 'fuelSystem', - 'components' - ]), - - BitField('reserved2', 0, 1), - FlagsField('continuous_tests_supported', 0, 3, [ - 'misfire', - 'fuelSystem', - 'components' - ]), - - FlagsField('once_per_trip_tests_supported', 0, 8, [ - 'egr', - 'oxygenSensorHeater', - 'oxygenSensor', - 'acSystemRefrigerant', - 'secondaryAirSystem', - 'evaporativeSystem', - 'heatedCatalyst', - 'catalyst' - ]), - - FlagsField('once_per_trip_tests_ready', 0, 8, [ - 'egr', - 'oxygenSensorHeater', - 'oxygenSensor', - 'acSystemRefrigerant', - 'secondaryAirSystem', - 'evaporativeSystem', - 'heatedCatalyst', - 'catalyst' - ]) - ] - - -class OBD_PID42(OBD_Packet): - name = "PID_42_ControlModuleVoltage" - fields_desc = [ - ScalingField('data', 0, scaling=0.001, unit="V", fmt="H") - ] - - -class OBD_PID43(OBD_Packet): - name = "PID_43_AbsoluteLoadValue" - fields_desc = [ - ScalingField('data', 0, scaling=100 / 255., unit="%", fmt="H") - ] - - -class OBD_PID44(OBD_Packet): - name = "PID_44_FuelAirCommandedEquivalenceRatio" - fields_desc = [ - ScalingField('data', 0, scaling=0.0000305, fmt="H") - ] - - -class _OBD_PercentPacket(OBD_Packet): - fields_desc = [ - ScalingField('data', 0, scaling=100 / 255., unit="%") - ] - - -class OBD_PID45(_OBD_PercentPacket): - name = "PID_45_RelativeThrottlePosition" - - -class OBD_PID46(OBD_Packet): - name = "PID_46_AmbientAirTemperature" - fields_desc = [ - ScalingField('data', 0, unit="deg. C", offset=-40.0) - ] - - -class OBD_PID47(_OBD_PercentPacket): - name = "PID_47_AbsoluteThrottlePositionB" - - -class OBD_PID48(_OBD_PercentPacket): - name = "PID_48_AbsoluteThrottlePositionC" - - -class OBD_PID49(_OBD_PercentPacket): - name = "PID_49_AcceleratorPedalPositionD" - - -class OBD_PID4A(_OBD_PercentPacket): - name = "PID_4A_AcceleratorPedalPositionE" - - -class OBD_PID4B(_OBD_PercentPacket): - name = "PID_4B_AcceleratorPedalPositionF" - - -class OBD_PID4C(_OBD_PercentPacket): - name = "PID_4C_CommandedThrottleActuator" - - -class OBD_PID4D(OBD_Packet): - name = "PID_4D_TimeRunWithMilOn" - fields_desc = [ - ScalingField('data', 0, unit="min", fmt="H") - ] - - -class OBD_PID4E(OBD_Packet): - name = "PID_4E_TimeSinceTroubleCodesCleared" - fields_desc = [ - ScalingField('data', 0, unit="min", fmt="H") - ] - - -class OBD_PID4F(OBD_Packet): - name = "PID_4F_VariousMaxValues" - fields_desc = [ - ScalingField('equivalence_ratio', 0), - ScalingField('sensor_voltage', 0, unit="V"), - ScalingField('sensor_current', 0, unit="mA"), - ScalingField('intake_manifold_absolute_pressure', 0, - scaling=10, unit="kPa") - ] - - -class OBD_PID50(OBD_Packet): - name = "PID_50_MaximumValueForAirFlowRateFromMassAirFlowSensor" - fields_desc = [ - ScalingField('data', 0, scaling=10, unit="g/s"), - ThreeBytesField('reserved', 0) - ] - - -class OBD_PID51(OBD_Packet): - name = "PID_51_FuelType" - - fuelTypes = { - 0: 'Not available', - 1: 'Gasoline', - 2: 'Methanol', - 3: 'Ethanol', - 4: 'Diesel', - 5: 'LPG', - 6: 'CNG', - 7: 'Propane', - 8: 'Electric', - 9: 'Bifuel running Gasoline', - 10: 'Bifuel running Methanol', - 11: 'Bifuel running Ethanol', - 12: 'Bifuel running LPG', - 13: 'Bifuel running CNG', - 14: 'Bifuel running Propane', - 15: 'Bifuel running Electricity', - 16: 'Bifuel running electric and combustion engine', - 17: 'Hybrid gasoline', - 18: 'Hybrid Ethanol', - 19: 'Hybrid Diesel', - 20: 'Hybrid Electric', - 21: 'Hybrid running electric and combustion engine', - 22: 'Hybrid Regenerative', - 23: 'Bifuel running diesel'} - - fields_desc = [ - ByteEnumField('data', 0, fuelTypes) - ] - - -class OBD_PID52(_OBD_PercentPacket): - name = "PID_52_EthanolFuel" - - -class OBD_PID53(OBD_Packet): - name = "PID_53_AbsoluteEvapSystemVaporPressure" - fields_desc = [ - ScalingField('data', 0, scaling=1 / 200., unit="kPa", fmt="H") - ] - - -class OBD_PID54(OBD_Packet): - name = "PID_54_EvapSystemVaporPressure" - fields_desc = [ - ScalingField('data', 0, unit="Pa", fmt="h") - ] - - -class _OBD_SensorTrimPacket1(OBD_Packet): - fields_desc = [ - ScalingField('bank1', 0, scaling=100 / 128., - offset=-100, unit="%"), - ScalingField('bank3', 0, scaling=100 / 128., - offset=-100, unit="%") - ] - - -class _OBD_SensorTrimPacket2(OBD_Packet): - fields_desc = [ - ScalingField('bank2', 0, scaling=100 / 128., - offset=-100, unit="%"), - ScalingField('bank4', 0, scaling=100 / 128., - offset=-100, unit="%") - ] - - -class OBD_PID55(_OBD_SensorTrimPacket1): - name = "PID_55_ShortTermSecondaryOxygenSensorTrim" - - -class OBD_PID56(_OBD_SensorTrimPacket1): - name = "PID_56_LongTermSecondaryOxygenSensorTrim" - - -class OBD_PID57(_OBD_SensorTrimPacket2): - name = "PID_57_ShortTermSecondaryOxygenSensorTrim" - - -class OBD_PID58(_OBD_SensorTrimPacket2): - name = "PID_58_LongTermSecondaryOxygenSensorTrim" - - -class OBD_PID59(OBD_Packet): - name = "PID_59_FuelRailAbsolutePressure" - fields_desc = [ - ScalingField('data', 0, scaling=10, unit="kPa", fmt="H") - ] - - -class OBD_PID5A(_OBD_PercentPacket): - name = "PID_5A_RelativeAcceleratorPedalPosition" - - -class OBD_PID5B(_OBD_PercentPacket): - name = "PID_5B_HybridBatteryPackRemainingLife" - - -class OBD_PID5C(OBD_Packet): - name = "PID_5C_EngineOilTemperature" - fields_desc = [ - ScalingField('data', 0, unit="deg. C", offset=-40.0) - ] - - -class OBD_PID5D(OBD_Packet): - name = "PID_5D_FuelInjectionTiming" - fields_desc = [ - ScalingField('data', 0, scaling=1 / 128., offset=-210, - unit="deg.", fmt="H") - ] - - -class OBD_PID5E(OBD_Packet): - name = "PID_5E_EngineFuelRate" - fields_desc = [ - ScalingField('data', 0, scaling=0.05, unit="L/h", fmt="H") - ] - - -class OBD_PID5F(OBD_Packet): - name = "PID_5F_EmissionRequirementsToWhichVehicleIsDesigned" - - emissionRequirementTypes = { - 0xE: 'Heavy Duty Vehicles (EURO IV) B1', - 0xF: 'Heavy Duty Vehicles (EURO V) B2', - 0x10: 'Heavy Duty Vehicles (EURO EEV) C', - } - - fields_desc = [ - ByteEnumField('data', 0, emissionRequirementTypes) - ] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_60_7F.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_60_7F.py deleted file mode 100644 index b8e65a3cdf..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_60_7F.py +++ /dev/null @@ -1,501 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -from scapy.fields import BitField, FlagsField, ScalingField -from scapy.contrib.automotive.obd.packet import OBD_Packet - - -# See https://en.wikipedia.org/wiki/OBD-II_PIDs for further information -# PID = Parameter IDentification - - -class OBD_PID60(OBD_Packet): - name = "PID_60_PIDsSupported" - fields_desc = [ - FlagsField('supported_pids', 0, 32, [ - 'PID80', - 'PID7F', - 'PID7E', - 'PID7D', - 'PID7C', - 'PID7B', - 'PID7A', - 'PID79', - 'PID78', - 'PID77', - 'PID76', - 'PID75', - 'PID74', - 'PID73', - 'PID72', - 'PID71', - 'PID70', - 'PID6F', - 'PID6E', - 'PID6D', - 'PID6C', - 'PID6B', - 'PID6A', - 'PID69', - 'PID68', - 'PID67', - 'PID66', - 'PID65', - 'PID64', - 'PID63', - 'PID62', - 'PID61' - ]) - ] - - -class OBD_PID61(OBD_Packet): - name = "PID_61_DriverSDemandEnginePercentTorque" - fields_desc = [ - ScalingField('data', 0, unit="%", offset=-125.0) - ] - - -class OBD_PID62(OBD_Packet): - name = "PID_62_ActualEnginePercentTorque" - fields_desc = [ - ScalingField('data', 0, unit="%", offset=-125.0) - ] - - -class OBD_PID63(OBD_Packet): - name = "PID_63_EngineReferenceTorque" - fields_desc = [ - ScalingField('data', 0, unit="Nm", fmt="H") - ] - - -class OBD_PID64(OBD_Packet): - name = "PID_64_EnginePercentTorqueData" - fields_desc = [ - ScalingField('at_point1', 0, unit="%", offset=-125.0), - ScalingField('at_point2', 0, unit="%", offset=-125.0), - ScalingField('at_point3', 0, unit="%", offset=-125.0), - ScalingField('at_point4', 0, unit="%", offset=-125.0), - ScalingField('at_point5', 0, unit="%", offset=-125.0) - ] - - -class OBD_PID65(OBD_Packet): - name = "PID_65_AuxiliaryInputOutputSupported" - fields_desc = [ - BitField('reserved1', 0, 4), - BitField('glow_plug_lamp_status_supported', 0, 1), - BitField('manual_trans_neutral_drive_status_supported', 0, 1), - BitField('auto_trans_neutral_drive_status_supported', 0, 1), - BitField('power_take_off_status_supported', 0, 1), - - BitField('reserved2', 0, 4), - BitField('glow_plug_lamp_status', 0, 1), - BitField('manual_trans_neutral_drive_status', 0, 1), - BitField('auto_trans_neutral_drive_status', 0, 1), - BitField('power_take_off_status', 0, 1), - ] - - -class OBD_PID66(OBD_Packet): - name = "PID_66_MassAirFlowSensor" - fields_desc = [ - BitField('reserved', 0, 6), - BitField('sensor_b_supported', 0, 1), - BitField('sensor_a_supported', 0, 1), - ScalingField('sensor_a', 0, scaling=0.03125, unit="g/s", fmt="H"), - ScalingField('sensor_b', 0, scaling=0.03125, unit="g/s", fmt="H"), - ] - - -class OBD_PID67(OBD_Packet): - name = "PID_67_EngineCoolantTemperature" - fields_desc = [ - BitField('reserved', 0, 6), - BitField('sensor2_supported', 0, 1), - BitField('sensor1_supported', 0, 1), - ScalingField('sensor1', 0, unit="deg. C", offset=-40.0), - ScalingField('sensor2', 0, unit="deg. C", offset=-40.0) - ] - - -class OBD_PID68(OBD_Packet): - name = "PID_68_IntakeAirTemperatureSensor" - fields_desc = [ - BitField('reserved', 0, 2), - BitField('bank2_sensor3_supported', 0, 1), - BitField('bank2_sensor2_supported', 0, 1), - BitField('bank2_sensor1_supported', 0, 1), - BitField('bank1_sensor3_supported', 0, 1), - BitField('bank1_sensor2_supported', 0, 1), - BitField('bank1_sensor1_supported', 0, 1), - ScalingField('bank1_sensor1', 0, unit="deg. C", offset=-40), - ScalingField('bank1_sensor2', 0, unit="deg. C", offset=-40), - ScalingField('bank1_sensor3', 0, unit="deg. C", offset=-40), - ScalingField('bank2_sensor1', 0, unit="deg. C", offset=-40), - ScalingField('bank2_sensor2', 0, unit="deg. C", offset=-40), - ScalingField('bank2_sensor3', 0, unit="deg. C", offset=-40) - ] - - -class OBD_PID69(OBD_Packet): - name = "PID_69_CommandedEgrAndEgrError" - fields_desc = [ - BitField('reserved', 0, 2), - BitField('egr_b_error_supported', 0, 1), - BitField('actual_egr_b_duty_cycle_supported', 0, 1), - BitField('commanded_egr_b_duty_cycle_supported', 0, 1), - BitField('egr_a_error_supported', 0, 1), - BitField('actual_egr_a_duty_cycle_supported', 0, 1), - BitField('commanded_egr_a_duty_cycle_supported', 0, 1), - ScalingField('commanded_egr_a_duty_cycle', 0, scaling=100 / 255., - unit="%"), - ScalingField('actual_egr_a_duty_cycle', 0, scaling=100 / 255., - unit="%"), - ScalingField('egr_a_error', 0, scaling=100 / 128., unit="%", - offset=-100), - ScalingField('commanded_egr_b_duty_cycle', 0, scaling=100 / 255., - unit="%"), - ScalingField('actual_egr_b_duty_cycle', 0, scaling=100 / 255., - unit="%"), - ScalingField('egr_b_error', 0, scaling=100 / 128., unit="%", - offset=-100), - ] - - -class OBD_PID6A(OBD_Packet): - name = "PID_6A_CommandedDieselIntakeAirFlowControl" \ - "AndRelativeIntakeAirFlowPosition" - fields_desc = [ - BitField('reserved', 0, 4), - BitField('relative_intake_air_flow_b_position_supported', 0, 1), - BitField('commanded_intake_air_flow_b_control_supported', 0, 1), - BitField('relative_intake_air_flow_a_position_supported', 0, 1), - BitField('commanded_intake_air_flow_a_control_supported', 0, 1), - ScalingField('commanded_intake_air_flow_a_control', 0, - scaling=100 / 255., unit="%"), - ScalingField('relative_intake_air_flow_a_position', 0, - scaling=100 / 255., unit="%"), - ScalingField('commanded_intake_air_flow_b_control', 0, - scaling=100 / 255., unit="%"), - ScalingField('relative_intake_air_flow_b_position', 0, - scaling=100 / 255., unit="%"), - ] - - -class OBD_PID6B(OBD_Packet): - name = "PID_6B_ExhaustGasRecirculationTemperature" - fields_desc = [ - BitField('reserved', 0, 4), - BitField('bank2_sensor2_supported', 0, 1), - BitField('bank2_sensor1_supported', 0, 1), - BitField('bank1_sensor2_supported', 0, 1), - BitField('bank1_sensor1_supported', 0, 1), - ScalingField('bank1_sensor1', 0, unit="deg. C", offset=-40), - ScalingField('bank1_sensor2', 0, unit="deg. C", offset=-40), - ScalingField('bank2_sensor1', 0, unit="deg. C", offset=-40), - ScalingField('bank2_sensor2', 0, unit="deg. C", offset=-40), - ] - - -class OBD_PID6C(OBD_Packet): - name = "PID_6C_CommandedThrottleActuatorControlAndRelativeThrottlePosition" - fields_desc = [ - BitField('reserved', 0, 4), - BitField('relative_throttle_b_position_supported', 0, 1), - BitField('commanded_throttle_actuator_b_control_supported', 0, 1), - BitField('relative_throttle_a_position_supported', 0, 1), - BitField('commanded_throttle_actuator_a_control_supported', 0, 1), - ScalingField('commanded_throttle_actuator_a_control', 0, - scaling=100 / 255., unit="%"), - ScalingField('relative_throttle_a_position', 0, - scaling=100 / 255., unit="%"), - ScalingField('commanded_throttle_actuator_b_control', 0, - scaling=100 / 255., unit="%"), - ScalingField('relative_throttle_b_position', 0, - scaling=100 / 255., unit="%"), - ] - - -class OBD_PID6D(OBD_Packet): - name = "PID_6D_FuelPressureControlSystem" - fields_desc = [ - BitField('reserved', 0, 5), - BitField('fuel_temperature_supported', 0, 1), - BitField('fuel_rail_pressure_supported', 0, 1), - BitField('commanded_fuel_rail_pressure_supported', 0, 1), - ScalingField('commanded_fuel_rail_pressure', 0, scaling=10, unit="kPa", - fmt='H'), - ScalingField('fuel_rail_pressure', 0, scaling=10, unit="kPa", - fmt='H'), - ScalingField('fuel_rail_temperature', 0, unit="deg. C", offset=-40) - ] - - -class OBD_PID6E(OBD_Packet): - name = "PID_6E_InjectionPressureControlSystem" - fields_desc = [ - BitField('reserved', 0, 6), - BitField('injection_control_pressure_supported', 0, 1), - BitField('commanded_injection_control_pressure_supported', 0, 1), - ScalingField('commanded_injection_control_pressure', 0, scaling=10, - unit="kPa", fmt='H'), - ScalingField('injection_control_pressure', 0, scaling=10, - unit="kPa", fmt='H'), - ] - - -class OBD_PID6F(OBD_Packet): - name = "PID_6F_TurbochargerCompressorInletPressure" - fields_desc = [ - BitField('reserved', 0, 6), - BitField('sensor_b_supported', 0, 1), - BitField('sensor_a_supported', 0, 1), - ScalingField('sensor_a', 0, unit="kPa"), - ScalingField('sensor_b', 0, unit="kPa"), - ] - - -class OBD_PID70(OBD_Packet): - name = "PID_70_BoostPressureControl" - fields_desc = [ - BitField('reserved', 0, 4), - BitField('boost_pressure_sensor_b_supported', 0, 1), - BitField('commanded_boost_pressure_b_supported', 0, 1), - BitField('boost_pressure_sensor_a_supported', 0, 1), - BitField('commanded_boost_pressure_a_supported', 0, 1), - ScalingField('commanded_boost_pressure_a', 0, scaling=0.03125, - unit="kPa", fmt='H'), - ScalingField('boost_pressure_sensor_a', 0, scaling=0.03125, - unit="kPa", fmt='H'), - ScalingField('commanded_boost_pressure_b', 0, scaling=0.03125, - unit="kPa", fmt='H'), - ScalingField('boost_pressure_sensor_b', 0, scaling=0.03125, - unit="kPa", fmt='H'), - ] - - -class OBD_PID71(OBD_Packet): - name = "PID_71_VariableGeometryTurboControl" - fields_desc = [ - BitField('reserved', 0, 4), - BitField('vgt_b_position_supported', 0, 1), - BitField('commanded_vgt_b_position_supported', 0, 1), - BitField('vgt_a_position_supported', 0, 1), - BitField('commanded_vgt_a_position_supported', 0, 1), - ScalingField('commanded_variable_geometry_turbo_a_position', 0, - scaling=100 / 255., unit="%"), - ScalingField('variable_geometry_turbo_a_position', 0, - scaling=100 / 255., unit="%"), - ScalingField('commanded_variable_geometry_turbo_b_position', 0, - scaling=100 / 255., unit="%"), - ScalingField('variable_geometry_turbo_b_position', 0, - scaling=100 / 255., unit="%"), - ] - - -class OBD_PID72(OBD_Packet): - name = "PID_72_WastegateControl" - fields_desc = [ - BitField('reserved', 0, 4), - BitField('wastegate_b_position_supported', 0, 1), - BitField('commanded_wastegate_b_position_supported', 0, 1), - BitField('wastegate_a_position_supported', 0, 1), - BitField('commanded_wastegate_a_position_supported', 0, 1), - ScalingField('commanded_wastegate_a_position', 0, - scaling=100 / 255., unit="%"), - ScalingField('wastegate_a_position', 0, - scaling=100 / 255., unit="%"), - ScalingField('commanded_wastegate_b_position', 0, - scaling=100 / 255., unit="%"), - ScalingField('wastegate_b_position', 0, - scaling=100 / 255., unit="%"), - ] - - -class OBD_PID73(OBD_Packet): - name = "PID_73_ExhaustPressure" - fields_desc = [ - BitField('reserved', 0, 6), - BitField('sensor_bank2_supported', 0, 1), - BitField('sensor_bank1_supported', 0, 1), - ScalingField('sensor_bank1', 0, scaling=0.01, unit="kPa", fmt='H'), - ScalingField('sensor_bank2', 0, scaling=0.01, unit="kPa", fmt='H'), - ] - - -class OBD_PID74(OBD_Packet): - name = "PID_74_TurbochargerRpm" - fields_desc = [ - BitField('reserved', 0, 6), - BitField('b_supported', 0, 1), - BitField('a_supported', 0, 1), - ScalingField('a_rpm', 0, unit="min-1", fmt='H'), - ScalingField('b_rpm', 0, unit="min-1", fmt='H'), - ] - - -class OBD_PID75(OBD_Packet): - name = "PID_75_TurbochargerATemperature" - fields_desc = [ - BitField('reserved', 0, 4), - BitField('turbo_a_turbine_outlet_temperature_supported', 0, 1), - BitField('turbo_a_turbine_inlet_temperature_supported', 0, 1), - BitField('turbo_a_compressor_outlet_temperature_supported', 0, 1), - BitField('turbo_a_compressor_inlet_temperature_supported', 0, 1), - ScalingField('turbocharger_a_compressor_inlet_temperature', 0, - unit="deg. C", offset=-40), - ScalingField('turbocharger_a_compressor_outlet_temperature', 0, - unit="deg. C", offset=-40), - ScalingField('turbocharger_a_turbine_inlet_temperature', 0, - unit="deg. C", offset=-40, fmt='H', - scaling=0.1), - ScalingField('turbocharger_a_turbine_outlet_temperature', 0, - unit="deg. C", offset=-40, fmt='H', - scaling=0.1), - ] - - -class OBD_PID76(OBD_Packet): - name = "PID_76_TurbochargerBTemperature" - fields_desc = [ - BitField('reserved', 0, 4), - BitField('turbo_a_turbine_outlet_temperature_supported', 0, 1), - BitField('turbo_a_turbine_inlet_temperature_supported', 0, 1), - BitField('turbo_a_compressor_outlet_temperature_supported', 0, 1), - BitField('turbo_a_compressor_inlet_temperature_supported', 0, 1), - ScalingField('turbocharger_a_compressor_inlet_temperature', 0, - unit="deg. C", offset=-40), - ScalingField('turbocharger_a_compressor_outlet_temperature', 0, - unit="deg. C", offset=-40), - ScalingField('turbocharger_a_turbine_inlet_temperature', 0, - unit="deg. C", offset=-40, fmt='H', - scaling=0.1), - ScalingField('turbocharger_a_turbine_outlet_temperature', 0, - unit="deg. C", offset=-40, fmt='H', - scaling=0.1), - ] - - -class OBD_PID77(OBD_Packet): - name = "PID_77_ChargeAirCoolerTemperature" - fields_desc = [ - BitField('reserved', 0, 4), - BitField('bank2_sensor2_supported', 0, 1), - BitField('bank2_sensor1_supported', 0, 1), - BitField('bank1_sensor2_supported', 0, 1), - BitField('bank1_sensor1_supported', 0, 1), - ScalingField('bank1_sensor1', 0, unit="deg. C", offset=-40), - ScalingField('bank1_sensor2', 0, unit="deg. C", offset=-40), - ScalingField('bank2_sensor1', 0, unit="deg. C", offset=-40), - ScalingField('bank2_sensor2', 0, unit="deg. C", offset=-40), - ] - - -class _OBD_PID_ExhaustGasTemperatureBank(OBD_Packet): - fields_desc = [ - BitField('reserved', 0, 4), - BitField('sensor4_supported', 0, 1), - BitField('sensor3_supported', 0, 1), - BitField('sensor2_supported', 0, 1), - BitField('sensor1_supported', 0, 1), - ScalingField('sensor1', 0, unit="deg. C", offset=-40, - scaling=0.1, fmt='H'), - ScalingField('sensor2', 0, unit="deg. C", offset=-40, - scaling=0.1, fmt='H'), - ScalingField('sensor3', 0, unit="deg. C", offset=-40, - scaling=0.1, fmt='H'), - ScalingField('sensor4', 0, unit="deg. C", offset=-40, - scaling=0.1, fmt='H'), - ] - - -class OBD_PID78(_OBD_PID_ExhaustGasTemperatureBank): - name = "PID_78_ExhaustGasTemperatureBank1" - - -class OBD_PID79(_OBD_PID_ExhaustGasTemperatureBank): - name = "PID_79_ExhaustGasTemperatureBank2" - - -class _OBD_PID_DieselParticulateFilter(OBD_Packet): - fields_desc = [ - BitField('reserved', 0, 5), - BitField('outlet_pressure_supported', 0, 1), - BitField('inlet_pressure_supported', 0, 1), - BitField('delta_pressure_supported', 0, 1), - ScalingField('delta_pressure', 0, - unit='kPa', offset=-327.68, scaling=0.01, fmt='H'), - ScalingField('particulate_filter', 0, - unit='kPa', scaling=0.01, fmt='H'), - ScalingField('outlet_pressure', 0, - unit='kPa', scaling=0.01, fmt='H'), - ] - - -class OBD_PID7A(_OBD_PID_DieselParticulateFilter): - name = "PID_7A_DieselParticulateFilter1" - - -class OBD_PID7B(_OBD_PID_DieselParticulateFilter): - name = "PID_7B_DieselParticulateFilter2" - - -class OBD_PID7C(OBD_Packet): - name = "PID_7C_DieselParticulateFilterTemperature" - fields_desc = [ - BitField('reserved', 0, 4), - BitField('bank2_outlet_temperature_supported', 0, 1), - BitField('bank2_inlet_temperature_supported', 0, 1), - BitField('bank1_outlet_temperature_supported', 0, 1), - BitField('bank1_inlet_temperature_supported', 0, 1), - ScalingField('bank1_inlet_temperature_sensor', 0, - unit="deg. C", offset=-40, scaling=0.1, fmt='H'), - ScalingField('bank1_outlet_temperature_sensor', 0, - unit="deg. C", offset=-40, scaling=0.1, fmt='H'), - ScalingField('bank2_inlet_temperature_sensor', 0, - unit="deg. C", offset=-40, scaling=0.1, fmt='H'), - ScalingField('bank2_outlet_temperature_sensor', 0, - unit="deg. C", offset=-40, scaling=0.1, fmt='H'), - ] - - -class OBD_PID7D(OBD_Packet): - name = "PID_7D_NoxNteControlAreaStatus" - fields_desc = [ - BitField('reserved', 0, 4), - BitField('nte_deficiency_for_nox_active_area', 0, 1), - BitField('inside_manufacturer_specific_nox_nte_carve_out_area', 0, 1), - BitField('outside', 0, 1), - BitField('inside', 0, 1), - ] - - -class OBD_PID7E(OBD_Packet): - name = "PID_7E_PmNteControlAreaStatus" - fields_desc = [ - BitField('reserved', 0, 4), - BitField('nte_deficiency_for_pm_active_area', 0, 1), - BitField('inside_manufacturer_specific_pm_nte_carve_out_area', 0, 1), - BitField('outside', 0, 1), - BitField('inside', 0, 1), - ] - - -class OBD_PID7F(OBD_Packet): - name = "PID_7F_EngineRunTime" - fields_desc = [ - BitField('reserved', 0, 5), - BitField('total_with_pto_active_supported', 0, 1), - BitField('total_idle_supported', 0, 1), - BitField('total_supported', 0, 1), - ScalingField('total', 0, unit='sec', fmt='Q'), - ScalingField('total_idle', 0, unit='sec', fmt='Q'), - ScalingField('total_with_pto_active', 0, unit='sec', fmt='Q'), - ] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_80_9F.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_80_9F.py deleted file mode 100644 index 99647e430c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_80_9F.py +++ /dev/null @@ -1,287 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -from scapy.fields import StrFixedLenField, FlagsField, ScalingField, BitField -from scapy.contrib.automotive.obd.packet import OBD_Packet - - -# See https://en.wikipedia.org/wiki/OBD-II_PIDs for further information -# PID = Parameter IDentification - -class OBD_PID80(OBD_Packet): - name = "PID_80_PIDsSupported" - fields_desc = [ - FlagsField('supported_pids', 0, 32, [ - 'PIDA0', - 'PID9F', - 'PID9E', - 'PID9D', - 'PID9C', - 'PID9B', - 'PID9A', - 'PID99', - 'PID98', - 'PID97', - 'PID96', - 'PID95', - 'PID94', - 'PID93', - 'PID92', - 'PID91', - 'PID90', - 'PID8F', - 'PID8E', - 'PID8D', - 'PID8C', - 'PID8B', - 'PID8A', - 'PID89', - 'PID88', - 'PID87', - 'PID86', - 'PID85', - 'PID84', - 'PID83', - 'PID82', - 'PID81' - ]) - ] - - -class OBD_PID81(OBD_Packet): - name = "PID_81_EngineRunTimeForAuxiliaryEmissionsControlDevice" - fields_desc = [ - BitField('reserved', 0, 3), - BitField('total_run_time_with_ei_aecd5_supported', 0, 1), - BitField('total_run_time_with_ei_aecd4_supported', 0, 1), - BitField('total_run_time_with_ei_aecd3_supported', 0, 1), - BitField('total_run_time_with_ei_aecd2_supported', 0, 1), - BitField('total_run_time_with_ei_aecd1_supported', 0, 1), - ScalingField('total_run_time_with_ei_aecd1', 0, unit='sec', - fmt='Q'), - ScalingField('total_run_time_with_ei_aecd2', 0, unit='sec', - fmt='Q'), - ScalingField('total_run_time_with_ei_aecd3', 0, unit='sec', - fmt='Q'), - ScalingField('total_run_time_with_ei_aecd4', 0, unit='sec', - fmt='Q'), - ScalingField('total_run_time_with_ei_aecd5', 0, unit='sec', - fmt='Q'), - ] - - -class OBD_PID82(OBD_Packet): - name = "PID_82_EngineRunTimeForAuxiliaryEmissionsControlDevice" - fields_desc = [ - BitField('reserved', 0, 3), - BitField('total_run_time_with_ei_aecd10_supported', 0, 1), - BitField('total_run_time_with_ei_aecd9_supported', 0, 1), - BitField('total_run_time_with_ei_aecd8_supported', 0, 1), - BitField('total_run_time_with_ei_aecd7_supported', 0, 1), - BitField('total_run_time_with_ei_aecd6_supported', 0, 1), - ScalingField('total_run_time_with_ei_aecd6', 0, unit='sec', - fmt='Q'), - ScalingField('total_run_time_with_ei_aecd7', 0, unit='sec', - fmt='Q'), - ScalingField('total_run_time_with_ei_aecd8', 0, unit='sec', - fmt='Q'), - ScalingField('total_run_time_with_ei_aecd9', 0, unit='sec', - fmt='Q'), - ScalingField('total_run_time_with_ei_aecd10', 0, unit='sec', - fmt='Q'), - ] - - -class OBD_PID83(OBD_Packet): - name = "PID_83_NOxSensor" - fields_desc = [ - BitField('reserved', 0, 6), - BitField('nox_sensor_concentration_bank2_sensor1_supported', 0, 1), - BitField('nox_sensor_concentration_bank1_sensor1_supported', 0, 1), - ScalingField('nox_sensor_concentration_bank1_sensor1', 0, unit='ppm', - fmt='H'), - ScalingField('nox_sensor_concentration_bank2_sensor1', 0, unit='ppm', - fmt='H'), - ] - - -class OBD_PID84(OBD_Packet): - name = "PID_84_ManifoldSurfaceTemperature" - fields_desc = [ - StrFixedLenField('data', b'', 1) - ] - - -class OBD_PID85(OBD_Packet): - name = "PID_85_NoxReagentSystem" - fields_desc = [ - StrFixedLenField('data', b'', 10) - ] - - -class OBD_PID86(OBD_Packet): - name = "PID_86_ParticulateMatterSensor" - fields_desc = [ - StrFixedLenField('data', b'', 5) - ] - - -class OBD_PID87(OBD_Packet): - name = "PID_87_IntakeManifoldAbsolutePressure" - fields_desc = [ - StrFixedLenField('data', b'', 5) - ] - - -class OBD_PID88(OBD_Packet): - name = "PID_88_ScrInduceSystem" - fields_desc = [ - StrFixedLenField('data', b'', 13) - ] - - -class OBD_PID89(OBD_Packet): - # 11 - 15 - name = "PID_89_RunTimeForAecd" - fields_desc = [ - StrFixedLenField('data', b'', 41) - ] - - -class OBD_PID8A(OBD_Packet): - # 16 - 20 - name = "PID_8A_RunTimeForAecd" - fields_desc = [ - StrFixedLenField('data', b'', 41) - ] - - -class OBD_PID8B(OBD_Packet): - name = "PID_8B_DieselAftertreatment" - fields_desc = [ - StrFixedLenField('data', b'', 7) - ] - - -class OBD_PID8C(OBD_Packet): - name = "PID_8C_O2Sensor" - fields_desc = [ - StrFixedLenField('data', b'', 16) - ] - - -class OBD_PID8D(OBD_Packet): - name = "PID_8D_ThrottlePositionG" - fields_desc = [ - StrFixedLenField('data', b'', 1) - ] - - -class OBD_PID8E(OBD_Packet): - name = "PID_8E_EngineFrictionPercentTorque" - fields_desc = [ - StrFixedLenField('data', b'', 1) - ] - - -class OBD_PID8F(OBD_Packet): - name = "PID_8F_PmSensorBank1And2" - fields_desc = [ - StrFixedLenField('data', b'', 5) - ] - - -class OBD_PID90(OBD_Packet): - name = "PID_90_WwhObdVehicleObdSystemInformation" - fields_desc = [ - StrFixedLenField('data', b'', 3) - ] - - -class OBD_PID91(OBD_Packet): - name = "PID_91_WwhObdVehicleObdSystemInformation" - fields_desc = [ - StrFixedLenField('data', b'', 5) - ] - - -class OBD_PID92(OBD_Packet): - name = "PID_92_FuelSystemControl" - fields_desc = [ - StrFixedLenField('data', b'', 2) - ] - - -class OBD_PID93(OBD_Packet): - name = "PID_93_WwhObdVehicleObdCountersSupport" - fields_desc = [ - StrFixedLenField('data', b'', 3) - ] - - -class OBD_PID94(OBD_Packet): - name = "PID_94_NoxWarningAndInducementSystem" - fields_desc = [ - StrFixedLenField('data', b'', 12) - ] - - -class OBD_PID98(OBD_Packet): - name = "PID_98_ExhaustGasTemperatureSensor" - fields_desc = [ - StrFixedLenField('data', b'', 9) - ] - - -class OBD_PID99(OBD_Packet): - name = "PID_99_ExhaustGasTemperatureSensor" - fields_desc = [ - StrFixedLenField('data', b'', 9) - ] - - -class OBD_PID9A(OBD_Packet): - name = "PID_9A_HybridEvVehicleSystemDataBatteryVoltage" - fields_desc = [ - StrFixedLenField('data', b'', 6) - ] - - -class OBD_PID9B(OBD_Packet): - name = "PID_9B_DieselExhaustFluidSensorData" - fields_desc = [ - StrFixedLenField('data', b'', 4) - ] - - -class OBD_PID9C(OBD_Packet): - name = "PID_9C_O2SensorData" - fields_desc = [ - StrFixedLenField('data', b'', 17) - ] - - -class OBD_PID9D(OBD_Packet): - name = "PID_9D_EngineFuelRate" - fields_desc = [ - StrFixedLenField('data', b'', 4) - ] - - -class OBD_PID9E(OBD_Packet): - name = "PID_9E_EngineExhaustFlowRate" - fields_desc = [ - StrFixedLenField('data', b'', 2) - ] - - -class OBD_PID9F(OBD_Packet): - name = "PID_9F_FuelSystemPercentageUse" - fields_desc = [ - StrFixedLenField('data', b'', 9) - ] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_A0_C0.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_A0_C0.py deleted file mode 100644 index f4e075d268..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/pid/pids_A0_C0.py +++ /dev/null @@ -1,135 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -from scapy.fields import StrFixedLenField, FlagsField -from scapy.contrib.automotive.obd.packet import OBD_Packet - - -# See https://en.wikipedia.org/wiki/OBD-II_PIDs for further information -# PID = Parameter IDentification - -class OBD_PIDA0(OBD_Packet): - name = "PID_A0_PIDsSupported" - fields_desc = [ - FlagsField('supported_pids', 0, 32, [ - 'PIDC0', - 'PIDBF', - 'PIDBE', - 'PIDBD', - 'PIDBC', - 'PIDBB', - 'PIDBA', - 'PIDB9', - 'PIDB8', - 'PIDB7', - 'PIDB6', - 'PIDB5', - 'PIDB4', - 'PIDB3', - 'PIDB2', - 'PIDB1', - 'PIDB0', - 'PIDAF', - 'PIDAE', - 'PIDAD', - 'PIDAC', - 'PIDAB', - 'PIDAA', - 'PIDA9', - 'PIDA8', - 'PIDA7', - 'PIDA6', - 'PIDA5', - 'PIDA4', - 'PIDA3', - 'PIDA2', - 'PIDA1' - ]) - ] - - -class OBD_PIDA1(OBD_Packet): - name = "PID_A1_NoxSensorCorrectedData" - fields_desc = [ - StrFixedLenField('data', b'', 9) - ] - - -class OBD_PIDA2(OBD_Packet): - name = "PID_A2_CylinderFuelRate" - fields_desc = [ - StrFixedLenField('data', b'', 2) - ] - - -class OBD_PIDA3(OBD_Packet): - name = "PID_A3_EvapSystemVaporPressure" - fields_desc = [ - StrFixedLenField('data', b'', 9) - ] - - -class OBD_PIDA4(OBD_Packet): - name = "PID_A4_TransmissionActualGear" - fields_desc = [ - StrFixedLenField('data', b'', 4) - ] - - -class OBD_PIDA5(OBD_Packet): - name = "PID_A5_DieselExhaustFluidDosing" - fields_desc = [ - StrFixedLenField('data', b'', 4) - ] - - -class OBD_PIDA6(OBD_Packet): - name = "PID_A6_Odometer" - fields_desc = [ - StrFixedLenField('data', b'', 4) - ] - - -class OBD_PIDC0(OBD_Packet): - name = "PID_C0_PIDsSupported" - fields_desc = [ - FlagsField('supported_pids', 0, 32, [ - 'PIDE0', - 'PIDDF', - 'PIDDE', - 'PIDDD', - 'PIDDC', - 'PIDDB', - 'PIDDA', - 'PIDD9', - 'PIDD8', - 'PIDD7', - 'PIDD6', - 'PIDD5', - 'PIDD4', - 'PIDD3', - 'PIDD2', - 'PIDD1', - 'PIDD0', - 'PIDCF', - 'PIDCE', - 'PIDCD', - 'PIDCC', - 'PIDCB', - 'PIDCA', - 'PIDC9', - 'PIDC8', - 'PIDC7', - 'PIDC6', - 'PIDC5', - 'PIDC4', - 'PIDC3', - 'PIDC2', - 'PIDC1' - ]) - ] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/services.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/services.py deleted file mode 100644 index 7feb6f28c7..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/services.py +++ /dev/null @@ -1,135 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -from scapy.fields import ByteField, XByteField, BitEnumField, \ - PacketListField, XBitField, XByteEnumField, FieldListField, FieldLenField -from scapy.packet import Packet -from scapy.contrib.automotive.obd.packet import OBD_Packet - - -class OBD_DTC(OBD_Packet): - name = "DiagnosticTroubleCode" - - locations = { - 0b00: 'Powertrain', - 0b01: 'Chassis', - 0b10: 'Body', - 0b11: 'Network', - } - - fields_desc = [ - BitEnumField('location', 0, 2, locations), - XBitField('code1', 0, 2), - XBitField('code2', 0, 4), - XBitField('code3', 0, 4), - XBitField('code4', 0, 4), - ] - - -class OBD_NR(Packet): - name = "NegativeResponse" - - responses = { - 0x10: 'generalReject', - 0x11: 'serviceNotSupported', - 0x12: 'subFunctionNotSupported-InvalidFormat', - 0x21: 'busy-RepeatRequest', - 0x22: 'conditionsNotCorrectOrRequestSequenceError', - 0x78: 'requestCorrectlyReceived-ResponsePending' - } - - fields_desc = [ - XByteField('request_service_id', 0), - XByteEnumField('response_code', 0, responses) - ] - - -class OBD_S01(Packet): - name = "S1_CurrentData" - fields_desc = [ - FieldListField("pid", [], XByteField('', 0)) - ] - - -class OBD_S02_Record(OBD_Packet): - fields_desc = [ - XByteField('pid', 0), - ByteField('frame_no', 0) - ] - - -class OBD_S02(Packet): - name = "S2_FreezeFrameData" - fields_desc = [ - PacketListField("requests", [], OBD_S02_Record) - ] - - -class OBD_S03(Packet): - name = "S3_RequestDTCs" - - -class OBD_S03_PR(Packet): - name = "S3_ResponseDTCs" - fields_desc = [ - FieldLenField('count', None, count_of='dtcs', fmt='B'), - PacketListField('dtcs', [], OBD_DTC, count_from=lambda pkt: pkt.count) - ] - - -class OBD_S04(Packet): - name = "S4_ClearDTCs" - - -class OBD_S04_PR(Packet): - name = "S4_ClearDTCsPositiveResponse" - - -class OBD_S06(Packet): - name = "S6_OnBoardDiagnosticMonitoring" - fields_desc = [ - FieldListField("mid", [], XByteField('', 0)) - ] - - -class OBD_S07(Packet): - name = "S7_RequestPendingDTCs" - - -class OBD_S07_PR(Packet): - name = "S7_ResponsePendingDTCs" - fields_desc = [ - FieldLenField('count', None, count_of='dtcs', fmt='B'), - PacketListField('dtcs', [], OBD_DTC, count_from=lambda pkt: pkt.count) - ] - - -class OBD_S08(Packet): - name = "S8_RequestControlOfSystem" - fields_desc = [ - FieldListField("tid", [], XByteField('', 0)) - ] - - -class OBD_S09(Packet): - name = "S9_VehicleInformation" - fields_desc = [ - FieldListField("iid", [], XByteField('', 0)) - ] - - -class OBD_S0A(Packet): - name = "S0A_RequestPermanentDTCs" - - -class OBD_S0A_PR(Packet): - name = "S0A_ResponsePermanentDTCs" - fields_desc = [ - FieldLenField('count', None, count_of='dtcs', fmt='B'), - PacketListField('dtcs', [], OBD_DTC, count_from=lambda pkt: pkt.count) - ] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/tid/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/tid/__init__.py deleted file mode 100644 index 9d7ebf0032..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/tid/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -""" -Package of contrib automotive obd specific modules -that have to be loaded explicitly. -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/tid/tids.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/tid/tids.py deleted file mode 100644 index 50e9c85cd1..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/obd/tid/tids.py +++ /dev/null @@ -1,148 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Andreas Korb -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.status = skip - -from scapy.fields import FlagsField, ByteField, ScalingField, PacketListField -from scapy.packet import bind_layers, Packet -from scapy.contrib.automotive.obd.packet import OBD_Packet - - -class _OBD_TID_Voltage(OBD_Packet): - fields_desc = [ - ScalingField('data_a', 0, 0.005, "V"), - ScalingField('data_b', 0, 0.005, "V"), - ScalingField('data_c', 0, 0.005, "V"), - ScalingField('data_d', 0, 0.005, "V"), - ScalingField('data_e', 0, 0.005, "V"), - ] - - -class _OBD_TID_Time(OBD_Packet): - fields_desc = [ - ScalingField('data_a', 0, 0.004, "s"), - ScalingField('data_b', 0, 0.004, "s"), - ScalingField('data_c', 0, 0.004, "s"), - ScalingField('data_d', 0, 0.004, "s"), - ScalingField('data_e', 0, 0.004, "s"), - ] - - -class _OBD_TID_Period(OBD_Packet): - fields_desc = [ - ScalingField('data_a', 0, 0.04, "s"), - ScalingField('data_b', 0, 0.04, "s"), - ScalingField('data_c', 0, 0.04, "s"), - ScalingField('data_d', 0, 0.04, "s"), - ScalingField('data_e', 0, 0.04, "s"), - ] - - -class OBD_TID00(OBD_Packet): - name = "TID_00_Service8SupportedTestIdentifiers" - fields_desc = [ - FlagsField('supported_tids', 0, 32, [ - 'TID20', - 'TID1F', - 'TID1E', - 'TID1D', - 'TID1C', - 'TID1B', - 'TID1A', - 'TID19', - 'TID18', - 'TID17', - 'TID16', - 'TID15', - 'TID14', - 'TID13', - 'TID12', - 'TID11', - 'TID10', - 'TID0F', - 'TID0E', - 'TID0D', - 'TID0C', - 'TID0B', - 'TID0A', - 'TID09', - 'TID08', - 'TID07', - 'TID06', - 'TID05', - 'TID04', - 'TID03', - 'TID02', - 'TID01' - ]) - ] - - -class OBD_TID01(_OBD_TID_Voltage): - name = "TID_01_RichToLeanSensorThresholdVoltage" - - -class OBD_TID02(_OBD_TID_Voltage): - name = "TID_02_LeanToRichSensorThresholdVoltage" - - -class OBD_TID03(_OBD_TID_Voltage): - name = "TID_03_LowSensorVoltageForSwitchTimeCalculation" - - -class OBD_TID04(_OBD_TID_Voltage): - name = "TID_04_HighSensorVoltageForSwitchTimeCalculation" - - -class OBD_TID05(_OBD_TID_Time): - name = "TID_05_RichToLeanSensorSwitchTime" - - -class OBD_TID06(_OBD_TID_Time): - name = "TID_06_LeanToRichSensorSwitchTime" - - -class OBD_TID07(_OBD_TID_Voltage): - name = "TID_07_MinimumSensorVoltageForTestCycle" - - -class OBD_TID08(_OBD_TID_Voltage): - name = "TID_08_MaximumSensorVoltageForTestCycle" - - -class OBD_TID09(_OBD_TID_Period): - name = "TID_09_TimeBetweenSensorTransitions" - - -class OBD_TID0A(_OBD_TID_Period): - name = "TID_0A_SensorPeriod" - - -class OBD_S08_PR_Record(Packet): - name = "Control Operation ID" - fields_desc = [ - ByteField("tid", 0), - ] - - -class OBD_S08_PR(Packet): - name = "Control Operation IDs" - fields_desc = [ - PacketListField("data_records", [], OBD_S08_PR_Record) - ] - - -bind_layers(OBD_S08_PR_Record, OBD_TID00, tid=0x00) -bind_layers(OBD_S08_PR_Record, OBD_TID01, tid=0x01) -bind_layers(OBD_S08_PR_Record, OBD_TID02, tid=0x02) -bind_layers(OBD_S08_PR_Record, OBD_TID03, tid=0x03) -bind_layers(OBD_S08_PR_Record, OBD_TID04, tid=0x04) -bind_layers(OBD_S08_PR_Record, OBD_TID05, tid=0x05) -bind_layers(OBD_S08_PR_Record, OBD_TID06, tid=0x06) -bind_layers(OBD_S08_PR_Record, OBD_TID07, tid=0x07) -bind_layers(OBD_S08_PR_Record, OBD_TID08, tid=0x08) -bind_layers(OBD_S08_PR_Record, OBD_TID09, tid=0x09) -bind_layers(OBD_S08_PR_Record, OBD_TID0A, tid=0x0A) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/someip.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/someip.py deleted file mode 100644 index 42747e2bb8..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/someip.py +++ /dev/null @@ -1,225 +0,0 @@ -#! /usr/bin/env python - -# MIT License - -# Copyright (c) 2018 Jose Amores - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Sebastian Baar -# This program is published under a GPLv2 license - -# scapy.contrib.description = Scalable service-Oriented MiddlewarE/IP (SOME/IP) -# scapy.contrib.status = loads - -import struct - -from scapy.layers.inet import TCP, UDP -from scapy.compat import raw -from scapy.config import conf -from scapy.modules.six.moves import range -from scapy.packet import Packet, bind_layers -from scapy.fields import ShortField, BitEnumField, ConditionalField, \ - BitField, PacketField, IntField, ByteField, ByteEnumField - - -class _SOMEIP_MessageId(Packet): - """ MessageId subpacket.""" - name = "MessageId" - fields_desc = [ - ShortField("srv_id", 0), - BitEnumField("sub_id", 0, 1, {0: "METHOD_ID", 1: "EVENT_ID"}), - ConditionalField(BitField("method_id", 0, 15), - lambda pkt: pkt.sub_id == 0), - ConditionalField(BitField("event_id", 0, 15), - lambda pkt: pkt.sub_id == 1) - ] - - def extract_padding(self, s): - return "", s - - -class _SOMEIP_RequestId(Packet): - """ RequestId subpacket.""" - name = "RequestId" - fields_desc = [ - ShortField("client_id", 0), - ShortField("session_id", 0) - ] - - def extract_padding(self, s): - return "", s - - -class SOMEIP(Packet): - """ SOME/IP Packet.""" - - PROTOCOL_VERSION = 0x01 - INTERFACE_VERSION = 0x01 - LEN_OFFSET = 0x08 - LEN_OFFSET_TP = 0x0c - TYPE_REQUEST = 0x00 - TYPE_REQUEST_NO_RET = 0x01 - TYPE_NOTIFICATION = 0x02 - TYPE_REQUEST_ACK = 0x40 - TYPE_REQUEST_NORET_ACK = 0x41 - TYPE_NOTIFICATION_ACK = 0x42 - TYPE_RESPONSE = 0x80 - TYPE_ERROR = 0x81 - TYPE_RESPONSE_ACK = 0xc0 - TYPE_ERROR_ACK = 0xc1 - TYPE_TP_REQUEST = 0x20 - TYPE_TP_REQUEST_NO_RET = 0x21 - TYPE_TP_NOTIFICATION = 0x22 - TYPE_TP_RESPONSE = 0x23 - TYPE_TP_ERROR = 0x24 - RET_E_OK = 0x00 - RET_E_NOT_OK = 0x01 - RET_E_UNKNOWN_SERVICE = 0x02 - RET_E_UNKNOWN_METHOD = 0x03 - RET_E_NOT_READY = 0x04 - RET_E_NOT_REACHABLE = 0x05 - RET_E_TIMEOUT = 0x06 - RET_E_WRONG_PROTOCOL_V = 0x07 - RET_E_WRONG_INTERFACE_V = 0x08 - RET_E_MALFORMED_MSG = 0x09 - RET_E_WRONG_MESSAGE_TYPE = 0x0a - - _OVERALL_LEN_NOPAYLOAD = 16 - - name = "SOME/IP" - - fields_desc = [ - PacketField("msg_id", _SOMEIP_MessageId(), - _SOMEIP_MessageId), - IntField("len", None), - PacketField("req_id", _SOMEIP_RequestId(), - _SOMEIP_RequestId), - ByteField("proto_ver", PROTOCOL_VERSION), - ByteField("iface_ver", INTERFACE_VERSION), - ByteEnumField("msg_type", TYPE_REQUEST, { - TYPE_REQUEST: "REQUEST", - TYPE_REQUEST_NO_RET: "REQUEST_NO_RETURN", - TYPE_NOTIFICATION: "NOTIFICATION", - TYPE_REQUEST_ACK: "REQUEST_ACK", - TYPE_REQUEST_NORET_ACK: "REQUEST_NO_RETURN_ACK", - TYPE_NOTIFICATION_ACK: "NOTIFICATION_ACK", - TYPE_RESPONSE: "RESPONSE", - TYPE_ERROR: "ERROR", - TYPE_RESPONSE_ACK: "RESPONSE_ACK", - TYPE_ERROR_ACK: "ERROR_ACK", - TYPE_TP_REQUEST: "TP_REQUEST", - TYPE_TP_REQUEST_NO_RET: "TP_REQUEST_NO_RETURN", - TYPE_TP_NOTIFICATION: "TP_NOTIFICATION", - TYPE_TP_RESPONSE: "TP_RESPONSE", - TYPE_TP_ERROR: "TP_ERROR", - }), - ByteEnumField("retcode", 0, { - RET_E_OK: "E_OK", - RET_E_NOT_OK: "E_NOT_OK", - RET_E_UNKNOWN_SERVICE: "E_UNKNOWN_SERVICE", - RET_E_UNKNOWN_METHOD: "E_UNKNOWN_METHOD", - RET_E_NOT_READY: "E_NOT_READY", - RET_E_NOT_REACHABLE: "E_NOT_REACHABLE", - RET_E_TIMEOUT: "E_TIMEOUT", - RET_E_WRONG_PROTOCOL_V: "E_WRONG_PROTOCOL_VERSION", - RET_E_WRONG_INTERFACE_V: "E_WRONG_INTERFACE_VERSION", - RET_E_MALFORMED_MSG: "E_MALFORMED_MESSAGE", - RET_E_WRONG_MESSAGE_TYPE: "E_WRONG_MESSAGE_TYPE", - }), - ConditionalField(BitField("offset", 0, 28), - lambda pkt: SOMEIP._is_tp(pkt)), - ConditionalField(BitField("res", 0, 3), - lambda pkt: SOMEIP._is_tp(pkt)), - ConditionalField(BitField("more_seg", 0, 1), - lambda pkt: SOMEIP._is_tp(pkt)) - ] - - def post_build(self, pkt, pay): - length = self.len - if length is None: - if SOMEIP._is_tp(self): - length = SOMEIP.LEN_OFFSET_TP + len(pay) - else: - length = SOMEIP.LEN_OFFSET + len(pay) - - pkt = pkt[:4] + struct.pack("!I", length) + pkt[8:] - return pkt + pay - - def answers(self, other): - if other.__class__ == self.__class__: - if self.msg_type in [SOMEIP.TYPE_REQUEST_NO_RET, - SOMEIP.TYPE_REQUEST_NORET_ACK, - SOMEIP.TYPE_NOTIFICATION, - SOMEIP.TYPE_TP_REQUEST_NO_RET, - SOMEIP.TYPE_TP_NOTIFICATION]: - return 0 - return self.payload.answers(other.payload) - return 0 - - @staticmethod - def _is_tp(pkt): - """Returns true if pkt is using SOMEIP-TP, else returns false.""" - - tp = [SOMEIP.TYPE_TP_REQUEST, SOMEIP.TYPE_TP_REQUEST_NO_RET, - SOMEIP.TYPE_TP_NOTIFICATION, SOMEIP.TYPE_TP_RESPONSE, - SOMEIP.TYPE_TP_ERROR] - if isinstance(pkt, Packet): - return pkt.msg_type in tp - else: - return pkt[15] in tp - - def fragment(self, fragsize=1392): - """Fragment SOME/IP-TP""" - fnb = 0 - fl = self - lst = list() - while fl.underlayer is not None: - fnb += 1 - fl = fl.underlayer - - for p in fl: - s = raw(p[fnb].payload) - nb = (len(s) + fragsize) // fragsize - for i in range(nb): - q = p.copy() - del q[fnb].payload - q[fnb].len = SOMEIP.LEN_OFFSET_TP + \ - len(s[i * fragsize:(i + 1) * fragsize]) - q[fnb].more_seg = 1 - if i == nb - 1: - q[fnb].more_seg = 0 - q[fnb].offset += i * fragsize // 16 - r = conf.raw_layer(load=s[i * fragsize:(i + 1) * fragsize]) - r.overload_fields = p[fnb].payload.overload_fields.copy() - q.add_payload(r) - lst.append(q) - - return lst - - -def _bind_someip_layers(): - for i in range(15): - bind_layers(UDP, SOMEIP, sport=30490 + i) - bind_layers(TCP, SOMEIP, sport=30490 + i) - - -_bind_someip_layers() diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/someip_sd.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/someip_sd.py deleted file mode 100644 index 4ab49e30eb..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/someip_sd.py +++ /dev/null @@ -1,350 +0,0 @@ -#! /usr/bin/env python - -# MIT License - -# Copyright (c) 2018 Jose Amores - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Sebastian Baar -# This program is published under a GPLv2 license - -# scapy.contrib.description = SOME/IP Service Discovery -# scapy.contrib.status = loads - -import ctypes -import collections -import struct - -from scapy.packet import Packet, Raw -from scapy.fields import ByteField, BitField, ShortField, \ - X3BytesField, IntField, ByteEnumField, StrField, IPField, \ - FieldLenField, PacketListField -from scapy.contrib.automotive.someip import SOMEIP -from scapy.layers.inet6 import IP6Field -from scapy.compat import orb - - -class _SDPacketBase(Packet): - """ base class to be used among all SD Packet definitions.""" - # use this dictionary to set default values for desired fields (mostly on - # subclasses where not all fields are defined locally) - # - key : field_name, value : desired value - # - it will be used from 'init_fields' function, upon packet initialization - # - # example : _defaults = - # {'field_1_name':field_1_value,'field_2_name':field_2_value} - _defaults = {} - - def _set_defaults(self): - for key in self._defaults: - try: - self.get_field(key) - except KeyError: - pass - else: - self.setfieldval(key, self._defaults[key]) - - def init_fields(self): - super(_SDPacketBase, self).init_fields() - self._set_defaults() - - -# SD ENTRY -# - Service -# - EventGroup -class _SDEntry(_SDPacketBase): - TYPE_FMT = ">B" - TYPE_PAYLOAD_I = 0 - TYPE_SRV_FINDSERVICE = 0x00 - TYPE_SRV_OFFERSERVICE = 0x01 - TYPE_SRV = (TYPE_SRV_FINDSERVICE, TYPE_SRV_OFFERSERVICE) - TYPE_EVTGRP_SUBSCRIBE = 0x06 - TYPE_EVTGRP_SUBSCRIBE_ACK = 0x07 - TYPE_EVTGRP = (TYPE_EVTGRP_SUBSCRIBE, TYPE_EVTGRP_SUBSCRIBE_ACK) - OVERALL_LEN = 16 - - fields_desc = [ - ByteField("type", 0), - ByteField("index_1", 0), - ByteField("index_2", 0), - BitField("n_opt_1", 0, 4), - BitField("n_opt_2", 0, 4), - ShortField("srv_id", 0), - ShortField("inst_id", 0), - ByteField("major_ver", 0), - X3BytesField("ttl", 0) - ] - - def guess_payload_class(self, payload): - pl_type = orb(payload[_SDEntry.TYPE_PAYLOAD_I]) - - if (pl_type in _SDEntry.TYPE_SRV): - return (SDEntry_Service) - elif (pl_type in _SDEntry.TYPE_EVTGRP): - return (SDEntry_EventGroup) - - -class SDEntry_Service(_SDEntry): - _defaults = {"type": _SDEntry.TYPE_SRV_FINDSERVICE} - - name = "Service Entry" - fields_desc = [ - _SDEntry, - IntField("minor_ver", 0) - ] - - -class SDEntry_EventGroup(_SDEntry): - _defaults = {"type": _SDEntry.TYPE_EVTGRP_SUBSCRIBE} - - name = "Eventgroup Entry" - fields_desc = [ - _SDEntry, - BitField("res", 0, 12), - BitField("cnt", 0, 4), - ShortField("eventgroup_id", 0) - ] - - -# SD Option -# - Configuration -# - LoadBalancing -# - IPv4 EndPoint -# - IPv6 EndPoint - -# - IPv4 MultiCast -# - IPv6 MultiCast -# - IPv4 EndPoint -# - IPv6 EndPoint -class _SDOption(_SDPacketBase): - CFG_TYPE = 0x01 - CFG_OVERALL_LEN = 4 - LOADBALANCE_TYPE = 0x02 - LOADBALANCE_LEN = 0x05 - LOADBALANCE_OVERALL_LEN = 8 - IP4_ENDPOINT_TYPE = 0x04 - IP4_ENDPOINT_LEN = 0x0009 - IP4_MCAST_TYPE = 0x14 - IP4_MCAST_LEN = 0x0009 - IP4_SDENDPOINT_TYPE = 0x24 - IP4_SDENDPOINT_LEN = 0x0009 - IP4_OVERALL_LEN = 12 - IP6_ENDPOINT_TYPE = 0x06 - IP6_ENDPOINT_LEN = 0x0015 - IP6_MCAST_TYPE = 0x16 - IP6_MCAST_LEN = 0x0015 - IP6_SDENDPOINT_TYPE = 0x26 - IP6_SDENDPOINT_LEN = 0x0015 - IP6_OVERALL_LEN = 24 - - def guess_payload_class(self, payload): - pl_type = orb(payload[2]) - - return { - _SDOption.CFG_TYPE: SDOption_Config, - self.LOADBALANCE_TYPE: SDOption_LoadBalance, - self.IP4_ENDPOINT_TYPE: SDOption_IP4_EndPoint, - self.IP4_MCAST_TYPE: SDOption_IP4_Multicast, - self.IP4_SDENDPOINT_TYPE: SDOption_IP4_SD_EndPoint, - self.IP6_ENDPOINT_TYPE: SDOption_IP6_EndPoint, - self.IP6_MCAST_TYPE: SDOption_IP6_Multicast, - self.IP6_SDENDPOINT_TYPE: SDOption_IP6_SD_EndPoint - }.get(pl_type, Raw) - - -class _SDOption_Header(_SDOption): - fields_desc = [ - ShortField("len", None), - ByteField("type", 0), - ByteField("res_hdr", 0) - ] - - -class _SDOption_Tail(_SDOption): - fields_desc = [ - ByteField("res_tail", 0), - ByteEnumField("l4_proto", 0x06, {0x06: "TCP", 0x11: "UDP"}), - ShortField("port", 0) - ] - - -class _SDOption_IP4(_SDOption): - fields_desc = [ - _SDOption_Header, - IPField("addr", "0.0.0.0"), - _SDOption_Tail - ] - - -class _SDOption_IP6(_SDOption): - fields_desc = [ - _SDOption_Header, - IP6Field("addr", "2001:cdba:0000:0000:0000:0000:3257:9652"), - _SDOption_Tail - ] - - -class SDOption_Config(_SDOption): - LEN_OFFSET = 0x01 - - name = "Config Option" - _defaults = {'type': _SDOption.CFG_TYPE} - fields_desc = [ - _SDOption_Header, - StrField("cfg_str", "") - ] - - def post_build(self, pkt, pay): - length = self.len - if (length is None): - length = len(self.cfg_str) + self.LEN_OFFSET - pkt = struct.pack("!H", length) + pkt[2:] - return (pkt + pay) - - -class SDOption_LoadBalance(_SDOption): - name = "LoadBalance Option" - _defaults = {'type': _SDOption.LOADBALANCE_TYPE, - 'len': _SDOption.LOADBALANCE_LEN} - fields_desc = [ - _SDOption_Header, - ShortField("priority", 0), - ShortField("weight", 0) - ] - - -class SDOption_IP4_EndPoint(_SDOption_IP4): - name = "IP4 EndPoint Option" - _defaults = {'type': _SDOption.IP4_ENDPOINT_TYPE, - 'len': _SDOption.IP4_ENDPOINT_LEN} - - -class SDOption_IP4_Multicast(_SDOption_IP4): - name = "IP4 Multicast Option" - _defaults = {'type': _SDOption.IP4_MCAST_TYPE, - 'len': _SDOption.IP4_MCAST_LEN} - - -class SDOption_IP4_SD_EndPoint(_SDOption_IP4): - name = "IP4 SDEndPoint Option" - _defaults = {'type': _SDOption.IP4_SDENDPOINT_TYPE, - 'len': _SDOption.IP4_SDENDPOINT_LEN} - - -class SDOption_IP6_EndPoint(_SDOption_IP6): - name = "IP6 EndPoint Option" - _defaults = {'type': _SDOption.IP6_ENDPOINT_TYPE, - 'len': _SDOption.IP6_ENDPOINT_LEN} - - -class SDOption_IP6_Multicast(_SDOption_IP6): - name = "IP6 Multicast Option" - _defaults = {'type': _SDOption.IP6_MCAST_TYPE, - 'len': _SDOption.IP6_MCAST_LEN} - - -class SDOption_IP6_SD_EndPoint(_SDOption_IP6): - name = "IP6 SDEndPoint Option" - _defaults = {'type': _SDOption.IP6_SDENDPOINT_TYPE, - 'len': _SDOption.IP6_SDENDPOINT_LEN} - - -## -# SD PACKAGE DEFINITION -## -class SD(_SDPacketBase): - """ - SD Packet - - NOTE : when adding 'entries' or 'options', do not use list.append() - method but create a new list - e.g. : p = SD() - p.option_array = [SDOption_Config(),SDOption_IP6_EndPoint()] - """ - SOMEIP_MSGID_SRVID = 0xffff - SOMEIP_MSGID_SUBID = 0x1 - SOMEIP_MSGID_EVENTID = 0x100 - SOMEIP_PROTO_VER = 0x01 - SOMEIP_IFACE_VER = 0x01 - SOMEIP_MSG_TYPE = SOMEIP.TYPE_NOTIFICATION - - name = "SD" - _sdFlag = collections.namedtuple('Flag', 'mask offset') - FLAGSDEF = { - "REBOOT": _sdFlag(mask=0x80, offset=7), - "UNICAST": _sdFlag(mask=0x40, offset=6) - } - - name = "SD" - fields_desc = [ - ByteField("flags", 0), - X3BytesField("res", 0), - FieldLenField("len_entry_array", None, - length_of="entry_array", fmt="!I"), - PacketListField("entry_array", None, cls=_SDEntry, - length_from=lambda pkt: pkt.len_entry_array), - FieldLenField("len_option_array", None, - length_of="option_array", fmt="!I"), - PacketListField("option_array", None, cls=_SDOption, - length_from=lambda pkt: pkt.len_option_array) - ] - - def get_flag(self, name): - name = name.upper() - if (name in self.FLAGSDEF): - return ((self.flags & self.FLAGSDEF[name].mask) >> - self.FLAGSDEF[name].offset) - else: - return None - - def set_flag(self, name, value): - name = name.upper() - if (name in self.FLAGSDEF): - self.flags = (self.flags & - (ctypes.c_ubyte(~self.FLAGSDEF[name].mask).value)) \ - | ((value & 0x01) << self.FLAGSDEF[name].offset) - - def set_entryArray(self, entry_list): - if (isinstance(entry_list, list)): - self.entry_array = entry_list - else: - self.entry_array = [entry_list] - - def set_optionArray(self, option_list): - if (isinstance(option_list, list)): - self.option_array = option_list - else: - self.option_array = [option_list] - - def get_someip(self, stacked=False): - p = SOMEIP() - p.msg_id.srv_id = SD.SOMEIP_MSGID_SRVID - p.msg_id.sub_id = SD.SOMEIP_MSGID_SUBID - p.msg_id.event_id = SD.SOMEIP_MSGID_EVENTID - p.proto_ver = SD.SOMEIP_PROTO_VER - p.iface_ver = SD.SOMEIP_IFACE_VER - p.msg_type = SD.SOMEIP_MSG_TYPE - - if (stacked): - return (p / self) - else: - return (p) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/uds.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/uds.py deleted file mode 100644 index 763870909a..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/automotive/uds.py +++ /dev/null @@ -1,1008 +0,0 @@ -#! /usr/bin/env python - -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.description = Unified Diagnostic Service (UDS) -# scapy.contrib.status = loads - -import struct -from scapy.fields import ByteEnumField, StrField, ConditionalField, \ - BitEnumField, BitField, XByteField, FieldListField, \ - XShortField, X3BytesField, XIntField, ByteField, \ - ShortField, ObservableDict, XShortEnumField, XByteEnumField -from scapy.packet import Packet, bind_layers -from scapy.config import conf -from scapy.error import log_loading -from scapy.utils import PeriodicSenderThread - -""" -UDS -""" - -try: - if conf.contribs['UDS']['treat-response-pending-as-answer']: - pass -except KeyError: - log_loading.info("Specify \"conf.contribs['UDS'] = " - "{'treat-response-pending-as-answer': True}\" to treat " - "a negative response 'requestCorrectlyReceived-" - "ResponsePending' as answer of a request. \n" - "The default value is False.") - conf.contribs['UDS'] = {'treat-response-pending-as-answer': False} - - -class UDS(Packet): - services = ObservableDict( - {0x10: 'DiagnosticSessionControl', - 0x11: 'ECUReset', - 0x14: 'ClearDiagnosticInformation', - 0x19: 'ReadDTCInformation', - 0x22: 'ReadDataByIdentifier', - 0x23: 'ReadMemoryByAddress', - 0x24: 'ReadScalingDataByIdentifier', - 0x27: 'SecurityAccess', - 0x28: 'CommunicationControl', - 0x2A: 'ReadDataPeriodicIdentifier', - 0x2C: 'DynamicallyDefineDataIdentifier', - 0x2E: 'WriteDataByIdentifier', - 0x2F: 'InputOutputControlByIdentifier', - 0x31: 'RoutineControl', - 0x34: 'RequestDownload', - 0x35: 'RequestUpload', - 0x36: 'TransferData', - 0x37: 'RequestTransferExit', - 0x3D: 'WriteMemoryByAddress', - 0x3E: 'TesterPresent', - 0x50: 'DiagnosticSessionControlPositiveResponse', - 0x51: 'ECUResetPositiveResponse', - 0x54: 'ClearDiagnosticInformationPositiveResponse', - 0x59: 'ReadDTCInformationPositiveResponse', - 0x62: 'ReadDataByIdentifierPositiveResponse', - 0x63: 'ReadMemoryByAddressPositiveResponse', - 0x64: 'ReadScalingDataByIdentifierPositiveResponse', - 0x67: 'SecurityAccessPositiveResponse', - 0x68: 'CommunicationControlPositiveResponse', - 0x6A: 'ReadDataPeriodicIdentifierPositiveResponse', - 0x6C: 'DynamicallyDefineDataIdentifierPositiveResponse', - 0x6E: 'WriteDataByIdentifierPositiveResponse', - 0x6F: 'InputOutputControlByIdentifierPositiveResponse', - 0x71: 'RoutineControlPositiveResponse', - 0x74: 'RequestDownloadPositiveResponse', - 0x75: 'RequestUploadPositiveResponse', - 0x76: 'TransferDataPositiveResponse', - 0x77: 'RequestTransferExitPositiveResponse', - 0x7D: 'WriteMemoryByAddressPositiveResponse', - 0x7E: 'TesterPresentPositiveResponse', - 0x83: 'AccessTimingParameter', - 0x84: 'SecuredDataTransmission', - 0x85: 'ControlDTCSetting', - 0x86: 'ResponseOnEvent', - 0x87: 'LinkControl', - 0xC3: 'AccessTimingParameterPositiveResponse', - 0xC4: 'SecuredDataTransmissionPositiveResponse', - 0xC5: 'ControlDTCSettingPositiveResponse', - 0xC6: 'ResponseOnEventPositiveResponse', - 0xC7: 'LinkControlPositiveResponse', - 0x7f: 'NegativeResponse'}) - name = 'UDS' - fields_desc = [ - XByteEnumField('service', 0, services) - ] - - def answers(self, other): - """DEV: true if self is an answer from other""" - if other.__class__ == self.__class__: - return (other.service + 0x40) == self.service or \ - (self.service == 0x7f and - self.requestServiceId == other.service and - (self.negativeResponseCode != 0x78 or - conf.contribs['UDS']['treat-response-pending-as-answer'])) - return 0 - - def hashret(self): - if self.service == 0x7f: - return struct.pack('B', self.requestServiceId) - return struct.pack('B', self.service & ~0x40) - - -# ########################DSC################################### -class UDS_DSC(Packet): - diagnosticSessionTypes = { - 0x00: 'ISOSAEReserved', - 0x01: 'defaultSession', - 0x02: 'programmingSession', - 0x03: 'extendedDiagnosticSession', - 0x04: 'safetySystemDiagnosticSession', - 0x7F: 'ISOSAEReserved'} - name = 'DiagnosticSessionControl' - fields_desc = [ - ByteEnumField('diagnosticSessionType', 0, diagnosticSessionTypes) - ] - - -bind_layers(UDS, UDS_DSC, service=0x10) - - -class UDS_DSCPR(Packet): - name = 'DiagnosticSessionControlPositiveResponse' - fields_desc = [ - ByteEnumField('diagnosticSessionType', 0, - UDS_DSC.diagnosticSessionTypes), - StrField('sessionParameterRecord', B"") - ] - - -bind_layers(UDS, UDS_DSCPR, service=0x50) - - -# #########################ER################################### -class UDS_ER(Packet): - resetTypes = { - 0x00: 'ISOSAEReserved', - 0x01: 'hardReset', - 0x02: 'keyOffOnReset', - 0x03: 'softReset', - 0x04: 'enableRapidPowerShutDown', - 0x05: 'disableRapidPowerShutDown', - 0x7F: 'ISOSAEReserved'} - name = 'ECUReset' - fields_desc = [ - ByteEnumField('resetType', 0, resetTypes) - ] - - -bind_layers(UDS, UDS_ER, service=0x11) - - -class UDS_ERPR(Packet): - name = 'ECUResetPositiveResponse' - fields_desc = [ - ByteEnumField('resetType', 0, UDS_ER.resetTypes), - ConditionalField(ByteField('powerDownTime', 0), - lambda pkt: pkt.resetType == 0x04) - ] - - -bind_layers(UDS, UDS_ERPR, service=0x51) - - -# #########################SA################################### -class UDS_SA(Packet): - name = 'SecurityAccess' - fields_desc = [ - ByteField('securityAccessType', 0), - ConditionalField(StrField('securityAccessDataRecord', B""), - lambda pkt: pkt.securityAccessType % 2 == 1), - ConditionalField(StrField('securityKey', B""), - lambda pkt: pkt.securityAccessType % 2 == 0) - ] - - -bind_layers(UDS, UDS_SA, service=0x27) - - -class UDS_SAPR(Packet): - name = 'SecurityAccessPositiveResponse' - fields_desc = [ - ByteField('securityAccessType', 0), - ConditionalField(StrField('securitySeed', B""), - lambda pkt: pkt.securityAccessType % 2 == 1), - ] - - -bind_layers(UDS, UDS_SAPR, service=0x67) - - -# #########################CC################################### -class UDS_CC(Packet): - controlTypes = { - 0x00: 'enableRxAndTx', - 0x01: 'enableRxAndDisableTx', - 0x02: 'disableRxAndEnableTx', - 0x03: 'disableRxAndTx' - } - name = 'CommunicationControl' - fields_desc = [ - ByteEnumField('controlType', 0, controlTypes), - BitEnumField('communicationType0', 0, 2, - {0: 'ISOSAEReserved', - 1: 'normalCommunicationMessages', - 2: 'networkManagmentCommunicationMessages', - 3: 'networkManagmentCommunicationMessages and ' - 'normalCommunicationMessages'}), - BitField('communicationType1', 0, 2), - BitEnumField('communicationType2', 0, 4, - {0: 'Disable/Enable specified communication Type', - 1: 'Disable/Enable specific subnet', - 2: 'Disable/Enable specific subnet', - 3: 'Disable/Enable specific subnet', - 4: 'Disable/Enable specific subnet', - 5: 'Disable/Enable specific subnet', - 6: 'Disable/Enable specific subnet', - 7: 'Disable/Enable specific subnet', - 8: 'Disable/Enable specific subnet', - 9: 'Disable/Enable specific subnet', - 10: 'Disable/Enable specific subnet', - 11: 'Disable/Enable specific subnet', - 12: 'Disable/Enable specific subnet', - 13: 'Disable/Enable specific subnet', - 14: 'Disable/Enable specific subnet', - 15: 'Disable/Enable network'}) - ] - - -bind_layers(UDS, UDS_CC, service=0x28) - - -class UDS_CCPR(Packet): - name = 'CommunicationControlPositiveResponse' - fields_desc = [ - ByteEnumField('controlType', 0, UDS_CC.controlTypes) - ] - - -bind_layers(UDS, UDS_CCPR, service=0x68) - - -# #########################TP################################### -class UDS_TP(Packet): - name = 'TesterPresent' - fields_desc = [ - ByteField('subFunction', 0) - ] - - -bind_layers(UDS, UDS_TP, service=0x3E) - - -class UDS_TPPR(Packet): - name = 'TesterPresentPositiveResponse' - fields_desc = [ - ByteField('zeroSubFunction', 0) - ] - - -bind_layers(UDS, UDS_TPPR, service=0x7E) - - -# #########################ATP################################### -class UDS_ATP(Packet): - timingParameterAccessTypes = { - 0: 'ISOSAEReserved', - 1: 'readExtendedTimingParameterSet', - 2: 'setTimingParametersToDefaultValues', - 3: 'readCurrentlyActiveTimingParameters', - 4: 'setTimingParametersToGivenValues' - } - name = 'AccessTimingParameter' - fields_desc = [ - ByteEnumField('timingParameterAccessType', 0, - timingParameterAccessTypes), - ConditionalField(StrField('timingParameterRequestRecord', B""), - lambda pkt: pkt.timingParameterAccessType == 0x4) - ] - - -bind_layers(UDS, UDS_ATP, service=0x83) - - -class UDS_ATPPR(Packet): - name = 'AccessTimingParameterPositiveResponse' - fields_desc = [ - ByteEnumField('timingParameterAccessType', 0, - UDS_ATP.timingParameterAccessTypes), - ConditionalField(StrField('timingParameterResponseRecord', B""), - lambda pkt: pkt.timingParameterAccessType == 0x3) - ] - - -bind_layers(UDS, UDS_ATPPR, service=0xC3) - - -# #########################SDT################################### -class UDS_SDT(Packet): - name = 'SecuredDataTransmission' - fields_desc = [ - StrField('securityDataRequestRecord', B"") - ] - - -bind_layers(UDS, UDS_SDT, service=0x84) - - -class UDS_SDTPR(Packet): - name = 'SecuredDataTransmissionPositiveResponse' - fields_desc = [ - StrField('securityDataResponseRecord', B"") - ] - - -bind_layers(UDS, UDS_SDTPR, service=0xC4) - - -# #########################CDTCS################################### -class UDS_CDTCS(Packet): - DTCSettingTypes = { - 0: 'ISOSAEReserved', - 1: 'on', - 2: 'off' - } - name = 'ControlDTCSetting' - fields_desc = [ - ByteEnumField('DTCSettingType', 0, DTCSettingTypes), - StrField('DTCSettingControlOptionRecord', B"") - ] - - -bind_layers(UDS, UDS_CDTCS, service=0x85) - - -class UDS_CDTCSPR(Packet): - name = 'ControlDTCSettingPositiveResponse' - fields_desc = [ - ByteEnumField('DTCSettingType', 0, UDS_CDTCS.DTCSettingTypes) - ] - - -bind_layers(UDS, UDS_CDTCSPR, service=0xC5) - - -# #########################ROE################################### -# TODO: improve this protocol implementation -class UDS_ROE(Packet): - eventTypes = { - 0: 'doNotStoreEvent', - 1: 'storeEvent' - } - name = 'ResponseOnEvent' - fields_desc = [ - ByteEnumField('eventType', 0, eventTypes), - ByteField('eventWindowTime', 0), - StrField('eventTypeRecord', B"") - ] - - -bind_layers(UDS, UDS_ROE, service=0x86) - - -class UDS_ROEPR(Packet): - name = 'ResponseOnEventPositiveResponse' - fields_desc = [ - ByteEnumField('eventType', 0, UDS_ROE.eventTypes), - ByteField('numberOfIdentifiedEvents', 0), - ByteField('eventWindowTime', 0), - StrField('eventTypeRecord', B"") - ] - - -bind_layers(UDS, UDS_ROEPR, service=0xC6) - - -# #########################LC################################### -class UDS_LC(Packet): - linkControlTypes = { - 0: 'ISOSAEReserved', - 1: 'verifyBaudrateTransitionWithFixedBaudrate', - 2: 'verifyBaudrateTransitionWithSpecificBaudrate', - 3: 'transitionBaudrate' - } - name = 'LinkControl' - fields_desc = [ - ByteEnumField('linkControlType', 0, linkControlTypes), - ConditionalField(ByteField('baudrateIdentifier', 0), - lambda pkt: pkt.linkControlType == 0x1), - ConditionalField(ByteField('baudrateHighByte', 0), - lambda pkt: pkt.linkControlType == 0x2), - ConditionalField(ByteField('baudrateMiddleByte', 0), - lambda pkt: pkt.linkControlType == 0x2), - ConditionalField(ByteField('baudrateLowByte', 0), - lambda pkt: pkt.linkControlType == 0x2) - ] - - -bind_layers(UDS, UDS_LC, service=0x87) - - -class UDS_LCPR(Packet): - name = 'LinkControlPositiveResponse' - fields_desc = [ - ByteEnumField('linkControlType', 0, UDS_LC.linkControlTypes) - ] - - -bind_layers(UDS, UDS_LCPR, service=0xC7) - - -# #########################RDBI################################### -class UDS_RDBI(Packet): - dataIdentifiers = ObservableDict() - name = 'ReadDataByIdentifier' - fields_desc = [ - FieldListField("identifiers", [], - XShortEnumField('dataIdentifier', 0, - dataIdentifiers)) - ] - - -bind_layers(UDS, UDS_RDBI, service=0x22) - - -class UDS_RDBIPR(Packet): - name = 'ReadDataByIdentifierPositiveResponse' - fields_desc = [ - XShortEnumField('dataIdentifier', 0, - UDS_RDBI.dataIdentifiers), - ] - - -bind_layers(UDS, UDS_RDBIPR, service=0x62) - - -# #########################RMBA################################### -class UDS_RMBA(Packet): - name = 'ReadMemoryByAddress' - fields_desc = [ - BitField('memorySizeLen', 0, 4), - BitField('memoryAddressLen', 0, 4), - ConditionalField(XByteField('memoryAddress1', 0), - lambda pkt: pkt.memoryAddressLen == 1), - ConditionalField(XShortField('memoryAddress2', 0), - lambda pkt: pkt.memoryAddressLen == 2), - ConditionalField(X3BytesField('memoryAddress3', 0), - lambda pkt: pkt.memoryAddressLen == 3), - ConditionalField(XIntField('memoryAddress4', 0), - lambda pkt: pkt.memoryAddressLen == 4), - ConditionalField(XByteField('memorySize1', 0), - lambda pkt: pkt.memorySizeLen == 1), - ConditionalField(XShortField('memorySize2', 0), - lambda pkt: pkt.memorySizeLen == 2), - ConditionalField(X3BytesField('memorySize3', 0), - lambda pkt: pkt.memorySizeLen == 3), - ConditionalField(XIntField('memorySize4', 0), - lambda pkt: pkt.memorySizeLen == 4), - ] - - -bind_layers(UDS, UDS_RMBA, service=0x23) - - -class UDS_RMBAPR(Packet): - name = 'ReadMemoryByAddressPositiveResponse' - fields_desc = [ - StrField('dataRecord', None, fmt="B") - ] - - -bind_layers(UDS, UDS_RMBAPR, service=0x63) - - -# #########################RSDBI################################### -class UDS_RSDBI(Packet): - name = 'ReadScalingDataByIdentifier' - fields_desc = [ - XShortField('dataIdentifier', 0) - ] - - -bind_layers(UDS, UDS_RSDBI, service=0x24) - - -# TODO: Implement correct scaling here, instead of using just the dataRecord -class UDS_RSDBIPR(Packet): - name = 'ReadScalingDataByIdentifierPositiveResponse' - fields_desc = [ - XShortField('dataIdentifier', 0), - ByteField('scalingByte', 0), - StrField('dataRecord', None, fmt="B") - ] - - -bind_layers(UDS, UDS_RSDBIPR, service=0x64) - - -# #########################RDBPI################################### -class UDS_RDBPI(Packet): - transmissionModes = { - 0: 'ISOSAEReserved', - 1: 'sendAtSlowRate', - 2: 'sendAtMediumRate', - 3: 'sendAtFastRate', - 4: 'stopSending' - } - name = 'ReadDataByPeriodicIdentifier' - fields_desc = [ - ByteEnumField('transmissionMode', 0, transmissionModes), - ByteField('periodicDataIdentifier', 0), - StrField('furtherPeriodicDataIdentifier', 0, fmt="B") - ] - - -bind_layers(UDS, UDS_RDBPI, service=0x2A) - - -# TODO: Implement correct scaling here, instead of using just the dataRecord -class UDS_RDBPIPR(Packet): - name = 'ReadDataByPeriodicIdentifierPositiveResponse' - fields_desc = [ - ByteField('periodicDataIdentifier', 0), - StrField('dataRecord', None, fmt="B") - ] - - -bind_layers(UDS, UDS_RDBPIPR, service=0x6A) - - -# #########################DDDI################################### -# TODO: Implement correct interpretation here, -# instead of using just the dataRecord -class UDS_DDDI(Packet): - name = 'DynamicallyDefineDataIdentifier' - fields_desc = [ - ByteField('definitionMode', 0), - StrField('dataRecord', 0, fmt="B") - ] - - -bind_layers(UDS, UDS_DDDI, service=0x2C) - - -class UDS_DDDIPR(Packet): - name = 'DynamicallyDefineDataIdentifierPositiveResponse' - fields_desc = [ - ByteField('definitionMode', 0), - XShortField('dynamicallyDefinedDataIdentifier', 0) - ] - - -bind_layers(UDS, UDS_DDDIPR, service=0x6C) - - -# #########################WDBI################################### -class UDS_WDBI(Packet): - name = 'WriteDataByIdentifier' - fields_desc = [ - XShortEnumField('dataIdentifier', 0, - UDS_RDBI.dataIdentifiers) - ] - - -bind_layers(UDS, UDS_WDBI, service=0x2E) - - -class UDS_WDBIPR(Packet): - name = 'WriteDataByIdentifierPositiveResponse' - fields_desc = [ - XShortEnumField('dataIdentifier', 0, - UDS_RDBI.dataIdentifiers), - ] - - -bind_layers(UDS, UDS_WDBIPR, service=0x6E) - - -# #########################WMBA################################### -class UDS_WMBA(Packet): - name = 'WriteMemoryByAddress' - fields_desc = [ - BitField('memorySizeLen', 0, 4), - BitField('memoryAddressLen', 0, 4), - ConditionalField(XByteField('memoryAddress1', 0), - lambda pkt: pkt.memoryAddressLen == 1), - ConditionalField(XShortField('memoryAddress2', 0), - lambda pkt: pkt.memoryAddressLen == 2), - ConditionalField(X3BytesField('memoryAddress3', 0), - lambda pkt: pkt.memoryAddressLen == 3), - ConditionalField(XIntField('memoryAddress4', 0), - lambda pkt: pkt.memoryAddressLen == 4), - ConditionalField(XByteField('memorySize1', 0), - lambda pkt: pkt.memorySizeLen == 1), - ConditionalField(XShortField('memorySize2', 0), - lambda pkt: pkt.memorySizeLen == 2), - ConditionalField(X3BytesField('memorySize3', 0), - lambda pkt: pkt.memorySizeLen == 3), - ConditionalField(XIntField('memorySize4', 0), - lambda pkt: pkt.memorySizeLen == 4), - StrField('dataRecord', b'\x00', fmt="B"), - - ] - - -bind_layers(UDS, UDS_WMBA, service=0x3D) - - -class UDS_WMBAPR(Packet): - name = 'WriteMemoryByAddressPositiveResponse' - fields_desc = [ - BitField('memorySizeLen', 0, 4), - BitField('memoryAddressLen', 0, 4), - ConditionalField(XByteField('memoryAddress1', 0), - lambda pkt: pkt.memoryAddressLen == 1), - ConditionalField(XShortField('memoryAddress2', 0), - lambda pkt: pkt.memoryAddressLen == 2), - ConditionalField(X3BytesField('memoryAddress3', 0), - lambda pkt: pkt.memoryAddressLen == 3), - ConditionalField(XIntField('memoryAddress4', 0), - lambda pkt: pkt.memoryAddressLen == 4), - ConditionalField(XByteField('memorySize1', 0), - lambda pkt: pkt.memorySizeLen == 1), - ConditionalField(XShortField('memorySize2', 0), - lambda pkt: pkt.memorySizeLen == 2), - ConditionalField(X3BytesField('memorySize3', 0), - lambda pkt: pkt.memorySizeLen == 3), - ConditionalField(XIntField('memorySize4', 0), - lambda pkt: pkt.memorySizeLen == 4) - ] - - -bind_layers(UDS, UDS_WMBAPR, service=0x7D) - - -# #########################CDTCI################################### -class UDS_CDTCI(Packet): - name = 'ClearDiagnosticInformation' - fields_desc = [ - ByteField('groupOfDTCHighByte', 0), - ByteField('groupOfDTCMiddleByte', 0), - ByteField('groupOfDTCLowByte', 0), - ] - - -bind_layers(UDS, UDS_CDTCI, service=0x14) - - -# #########################RDTCI################################### -class UDS_RDTCI(Packet): - reportTypes = { - 0: 'ISOSAEReserved', - 1: 'reportNumberOfDTCByStatusMask', - 2: 'reportDTCByStatusMask', - 3: 'reportDTCSnapshotIdentification', - 4: 'reportDTCSnapshotRecordByDTCNumber', - 5: 'reportDTCSnapshotRecordByRecordNumber', - 6: 'reportDTCExtendedDataRecordByDTCNumber', - 7: 'reportNumberOfDTCBySeverityMaskRecord', - 8: 'reportDTCBySeverityMaskRecord', - 9: 'reportSeverityInformationOfDTC', - 10: 'reportSupportedDTC', - 11: 'reportFirstTestFailedDTC', - 12: 'reportFirstConfirmedDTC', - 13: 'reportMostRecentTestFailedDTC', - 14: 'reportMostRecentConfirmedDTC', - 15: 'reportMirrorMemoryDTCByStatusMask', - 16: 'reportMirrorMemoryDTCExtendedDataRecordByDTCNumber', - 17: 'reportNumberOfMirrorMemoryDTCByStatusMask', - 18: 'reportNumberOfEmissionsRelatedOBDDTCByStatusMask', - 19: 'reportEmissionsRelatedOBDDTCByStatusMask', - 20: 'reportDTCFaultDetectionCounter', - 21: 'reportDTCWithPermanentStatus' - } - name = 'ReadDTCInformation' - fields_desc = [ - ByteEnumField('reportType', 0, reportTypes), - ConditionalField(XByteField('DTCStatusMask', 0), - lambda pkt: pkt.reportType in [0x01, 0x02, 0x0f, - 0x11, 0x12, 0x13]), - ConditionalField(ByteField('DTCHighByte', 0), - lambda pkt: pkt.reportType in [0x3, 0x4, 0x6, - 0x10, 0x09]), - ConditionalField(ByteField('DTCMiddleByte', 0), - lambda pkt: pkt.reportType in [0x3, 0x4, 0x6, - 0x10, 0x09]), - ConditionalField(ByteField('DTCLowByte', 0), - lambda pkt: pkt.reportType in [0x3, 0x4, 0x6, - 0x10, 0x09]), - ConditionalField(ByteField('DTCSnapshotRecordNumber', 0), - lambda pkt: pkt.reportType in [0x3, 0x4, 0x5]), - ConditionalField(ByteField('DTCExtendedDataRecordNumber', 0), - lambda pkt: pkt.reportType in [0x6, 0x10]), - ConditionalField(ByteField('DTCSeverityMask', 0), - lambda pkt: pkt.reportType in [0x07, 0x08]), - ConditionalField(ByteField('DTCStatusMask', 0), - lambda pkt: pkt.reportType in [0x07, 0x08]), - ] - - -bind_layers(UDS, UDS_RDTCI, service=0x19) - - -class UDS_RDTCIPR(Packet): - name = 'ReadDTCInformationPositiveResponse' - fields_desc = [ - ByteEnumField('reportType', 0, UDS_RDTCI.reportTypes), - ConditionalField(XByteField('DTCStatusAvailabilityMask', 0), - lambda pkt: pkt.reportType in [0x01, 0x07, 0x11, - 0x12, 0x02, 0x0A, - 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x13, - 0x15]), - ConditionalField(ByteEnumField('DTCFormatIdentifier', 0, - {0: 'ISO15031-6DTCFormat', - 1: 'UDS-1DTCFormat', - 2: 'SAEJ1939-73DTCFormat', - 3: 'ISO11992-4DTCFormat'}), - lambda pkt: pkt.reportType in [0x01, 0x07, - 0x11, 0x12]), - ConditionalField(ShortField('DTCCount', 0), - lambda pkt: pkt.reportType in [0x01, 0x07, - 0x11, 0x12]), - ConditionalField(StrField('DTCAndStatusRecord', 0), - lambda pkt: pkt.reportType in [0x02, 0x0A, 0x0B, - 0x0C, 0x0D, 0x0E, - 0x0F, 0x13, 0x15]), - ConditionalField(StrField('dataRecord', 0), - lambda pkt: pkt.reportType in [0x03, 0x04, 0x05, - 0x06, 0x08, 0x09, - 0x10, 0x14]) - ] - - -bind_layers(UDS, UDS_RDTCIPR, service=0x59) - - -# #########################RC################################### -class UDS_RC(Packet): - routineControlTypes = { - 0: 'ISOSAEReserved', - 1: 'startRoutine', - 2: 'stopRoutine', - 3: 'requestRoutineResults' - } - name = 'RoutineControl' - fields_desc = [ - ByteEnumField('routineControlType', 0, routineControlTypes), - XShortField('routineIdentifier', 0), - StrField('routineControlOptionRecord', 0, fmt="B"), - ] - - -bind_layers(UDS, UDS_RC, service=0x31) - - -class UDS_RCPR(Packet): - name = 'RoutineControlPositiveResponse' - fields_desc = [ - ByteEnumField('routineControlType', 0, - UDS_RC.routineControlTypes), - XShortField('routineIdentifier', 0), - StrField('routineStatusRecord', 0, fmt="B"), - ] - - -bind_layers(UDS, UDS_RCPR, service=0x71) - - -# #########################RD################################### -class UDS_RD(Packet): - dataFormatIdentifiers = { - 0: 'noCompressionNoEncryption' - } - name = 'RequestDownload' - fields_desc = [ - ByteEnumField('dataFormatIdentifier', 0, dataFormatIdentifiers), - BitField('memorySizeLen', 0, 4), - BitField('memoryAddressLen', 0, 4), - ConditionalField(XByteField('memoryAddress1', 0), - lambda pkt: pkt.memoryAddressLen == 1), - ConditionalField(XShortField('memoryAddress2', 0), - lambda pkt: pkt.memoryAddressLen == 2), - ConditionalField(X3BytesField('memoryAddress3', 0), - lambda pkt: pkt.memoryAddressLen == 3), - ConditionalField(XIntField('memoryAddress4', 0), - lambda pkt: pkt.memoryAddressLen == 4), - ConditionalField(XByteField('memorySize1', 0), - lambda pkt: pkt.memorySizeLen == 1), - ConditionalField(XShortField('memorySize2', 0), - lambda pkt: pkt.memorySizeLen == 2), - ConditionalField(X3BytesField('memorySize3', 0), - lambda pkt: pkt.memorySizeLen == 3), - ConditionalField(XIntField('memorySize4', 0), - lambda pkt: pkt.memorySizeLen == 4) - ] - - -bind_layers(UDS, UDS_RD, service=0x34) - - -class UDS_RDPR(Packet): - name = 'RequestDownloadPositiveResponse' - fields_desc = [ - ByteEnumField('routineControlType', 0, - UDS_RC.routineControlTypes), - BitField('memorySizeLen', 0, 4), - BitField('memoryAddressLen', 0, 4), - StrField('maxNumberOfBlockLength', 0, fmt="B"), - ] - - -bind_layers(UDS, UDS_RDPR, service=0x74) - - -# #########################RU################################### -class UDS_RU(Packet): - name = 'RequestUpload' - fields_desc = [ - ByteEnumField('dataFormatIdentifier', 0, - UDS_RD.dataFormatIdentifiers), - BitField('memorySizeLen', 0, 4), - BitField('memoryAddressLen', 0, 4), - ConditionalField(XByteField('memoryAddress1', 0), - lambda pkt: pkt.memoryAddressLen == 1), - ConditionalField(XShortField('memoryAddress2', 0), - lambda pkt: pkt.memoryAddressLen == 2), - ConditionalField(X3BytesField('memoryAddress3', 0), - lambda pkt: pkt.memoryAddressLen == 3), - ConditionalField(XIntField('memoryAddress4', 0), - lambda pkt: pkt.memoryAddressLen == 4), - ConditionalField(XByteField('memorySize1', 0), - lambda pkt: pkt.memorySizeLen == 1), - ConditionalField(XShortField('memorySize2', 0), - lambda pkt: pkt.memorySizeLen == 2), - ConditionalField(X3BytesField('memorySize3', 0), - lambda pkt: pkt.memorySizeLen == 3), - ConditionalField(XIntField('memorySize4', 0), - lambda pkt: pkt.memorySizeLen == 4) - ] - - -bind_layers(UDS, UDS_RU, service=0x35) - - -class UDS_RUPR(Packet): - name = 'RequestUploadPositiveResponse' - fields_desc = [ - ByteEnumField('routineControlType', 0, - UDS_RC.routineControlTypes), - BitField('memorySizeLen', 0, 4), - BitField('memoryAddressLen', 0, 4), - StrField('maxNumberOfBlockLength', 0, fmt="B"), - ] - - -bind_layers(UDS, UDS_RUPR, service=0x75) - - -# #########################TD################################### -class UDS_TD(Packet): - name = 'TransferData' - fields_desc = [ - ByteField('blockSequenceCounter', 0), - StrField('transferRequestParameterRecord', 0, fmt="B") - ] - - -bind_layers(UDS, UDS_TD, service=0x36) - - -class UDS_TDPR(Packet): - name = 'TransferDataPositiveResponse' - fields_desc = [ - ByteField('blockSequenceCounter', 0), - StrField('transferResponseParameterRecord', 0, fmt="B") - ] - - -bind_layers(UDS, UDS_TDPR, service=0x76) - - -# #########################RTE################################### -class UDS_RTE(Packet): - name = 'RequestTransferExit' - fields_desc = [ - StrField('transferRequestParameterRecord', 0, fmt="B") - ] - - -bind_layers(UDS, UDS_RTE, service=0x37) - - -class UDS_RTEPR(Packet): - name = 'RequestTransferExitPositiveResponse' - fields_desc = [ - StrField('transferResponseParameterRecord', 0, fmt="B") - ] - - -bind_layers(UDS, UDS_RTEPR, service=0x77) - - -# #########################IOCBI################################### -class UDS_IOCBI(Packet): - name = 'InputOutputControlByIdentifier' - fields_desc = [ - XShortField('dataIdentifier', 0), - ByteField('controlOptionRecord', 0), - StrField('controlEnableMaskRecord', 0, fmt="B") - ] - - -bind_layers(UDS, UDS_IOCBI, service=0x2F) - - -class UDS_IOCBIPR(Packet): - name = 'InputOutputControlByIdentifierPositiveResponse' - fields_desc = [ - XShortField('dataIdentifier', 0), - StrField('controlStatusRecord', 0, fmt="B") - ] - - -bind_layers(UDS, UDS_IOCBIPR, service=0x6F) - - -# #########################NRC################################### -class UDS_NRC(Packet): - negativeResponseCodes = { - 0x00: 'positiveResponse', - 0x10: 'generalReject', - 0x11: 'serviceNotSupported', - 0x12: 'subFunctionNotSupported', - 0x13: 'incorrectMessageLengthOrInvalidFormat', - 0x14: 'responseTooLong', - 0x20: 'ISOSAEReserved', - 0x21: 'busyRepeatRequest', - 0x22: 'conditionsNotCorrect', - 0x23: 'ISOSAEReserved', - 0x24: 'requestSequenceError', - 0x25: 'noResponseFromSubnetComponent', - 0x26: 'failurePreventsExecutionOfRequestedAction', - 0x31: 'requestOutOfRange', - 0x33: 'securityAccessDenied', - 0x35: 'invalidKey', - 0x36: 'exceedNumberOfAttempts', - 0x37: 'requiredTimeDelayNotExpired', - 0x70: 'uploadDownloadNotAccepted', - 0x71: 'transferDataSuspended', - 0x72: 'generalProgrammingFailure', - 0x73: 'wrongBlockSequenceCounter', - 0x78: 'requestCorrectlyReceived-ResponsePending', - 0x7E: 'subFunctionNotSupportedInActiveSession', - 0x7F: 'serviceNotSupportedInActiveSession', - 0x80: 'ISOSAEReserved', - 0x81: 'rpmTooHigh', - 0x82: 'rpmTooLow', - 0x83: 'engineIsRunning', - 0x84: 'engineIsNotRunning', - 0x85: 'engineRunTimeTooLow', - 0x86: 'temperatureTooHigh', - 0x87: 'temperatureTooLow', - 0x88: 'vehicleSpeedTooHigh', - 0x89: 'vehicleSpeedTooLow', - 0x8a: 'throttle/PedalTooHigh', - 0x8b: 'throttle/PedalTooLow', - 0x8c: 'transmissionRangeNotInNeutral', - 0x8d: 'transmissionRangeNotInGear', - 0x8e: 'ISOSAEReserved', - 0x8f: 'brakeSwitch(es)NotClosed', - 0x90: 'shifterLeverNotInPark', - 0x91: 'torqueConverterClutchLocked', - 0x92: 'voltageTooHigh', - 0x93: 'voltageTooLow', - } - name = 'NegativeResponseCode' - fields_desc = [ - XByteEnumField('requestServiceId', 0, UDS.services), - ByteEnumField('negativeResponseCode', 0, negativeResponseCodes) - ] - - -bind_layers(UDS, UDS_NRC, service=0x7f) - - -# ################################################################## -# ######################## UTILS ################################### -# ################################################################## - - -class UDS_TesterPresentSender(PeriodicSenderThread): - def __init__(self, sock, pkt=UDS() / UDS_TP(), interval=2): - """ Thread to send TesterPresent messages packets periodically - - Args: - sock: socket where packet is sent periodically - pkt: packet to send - interval: interval between two packets - """ - PeriodicSenderThread.__init__(self, sock, pkt, interval) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/avs.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/avs.py deleted file mode 100644 index f8dbe64021..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/avs.py +++ /dev/null @@ -1,73 +0,0 @@ -#! /usr/bin/env python - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = AVS WLAN Monitor Header -# scapy.contrib.status = loads - -from scapy.packet import Packet, bind_layers -from scapy.fields import IntEnumField, IntField, LongField, SignedIntField -from scapy.layers.dot11 import Dot11 -from scapy.data import DLT_IEEE802_11_RADIO_AVS -from scapy.config import conf - -AVSWLANPhyType = {0: "Unknown", - 1: "FHSS 802.11 '97", - 2: "DSSS 802.11 '97", - 3: "IR Baseband", - 4: "DSSS 802.11b", - 5: "PBCC 802.11b", - 6: "OFDM 802.11g", - 7: "PBCC 802.11g", - 8: "OFDM 802.11a"} - -AVSWLANEncodingType = {0: "Unknown", - 1: "CCK", - 2: "PBCC", - 3: "OFDM"} - -AVSWLANSSIType = {0: "None", - 1: "Normalized RSSI", - 2: "dBm", - 3: "Raw RSSI"} - -AVSWLANPreambleType = {0: "Unknown", - 1: "Short", - 2: "Long"} - - -class AVSWLANHeader(Packet): - """ iwpriv eth1 set_prismhdr 1 """ - name = "AVS WLAN Monitor Header" - fields_desc = [IntField("version", 1), - IntField("len", 64), - LongField("mactime", 0), - LongField("hosttime", 0), - IntEnumField("phytype", 0, AVSWLANPhyType), - IntField("channel", 0), - IntField("datarate", 0), - IntField("antenna", 0), - IntField("priority", 0), - IntEnumField("ssi_type", 0, AVSWLANSSIType), - SignedIntField("ssi_signal", 0), - SignedIntField("ssi_noise", 0), - IntEnumField("preamble", 0, AVSWLANPreambleType), - IntEnumField("encoding", 0, AVSWLANEncodingType), - ] - - -conf.l2types.register(DLT_IEEE802_11_RADIO_AVS, AVSWLANHeader) - -bind_layers(AVSWLANHeader, Dot11) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/bgp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/bgp.py deleted file mode 100644 index b2bb75a3ff..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/bgp.py +++ /dev/null @@ -1,2535 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = BGP v0.1 -# scapy.contrib.status = loads - -""" -BGP (Border Gateway Protocol). -""" - -from __future__ import absolute_import -import struct -import re -import socket - -from scapy import pton_ntop -from scapy.packet import Packet, Packet_metaclass, bind_layers -from scapy.fields import (Field, BitField, BitEnumField, XBitField, ByteField, - ByteEnumField, ShortField, ShortEnumField, IntField, - IntEnumField, LongField, IEEEFloatField, StrField, - StrLenField, StrFixedLenField, FieldLenField, - FieldListField, PacketField, PacketListField, - IPField, FlagsField, ConditionalField, - MultiEnumField) -from scapy.layers.inet import TCP -from scapy.layers.inet6 import IP6Field -from scapy.utils import issubtype -from scapy.config import conf, ConfClass -from scapy.compat import orb, chb -from scapy.error import log_runtime -import scapy.modules.six as six - - -# -# Module configuration -# - - -class BGPConf(ConfClass): - """ - BGP module configuration. - """ - - # By default, set to True in order to behave like an OLD speaker (RFC 6793) - use_2_bytes_asn = True - - -bgp_module_conf = BGPConf() - - -# -# Constants -# - -# RFC 4271: "The maximum message size is 4096 octets. All implementations are -# required to support this maximum message size." -BGP_MAXIMUM_MESSAGE_SIZE = 4096 - -# RFC 4271: "Each message has a fixed-size header." Marker (16 bytes) + -# Length (2 bytes) + Type (1 byte) -_BGP_HEADER_SIZE = 19 - -# Marker included in every message (RFC 4271: "This 16-octet field is -# included for compatibility; it MUST be set to all ones") -_BGP_HEADER_MARKER = b"\xff" * 16 - -# extended-length flag (RFC 4271 4.3. UPDATE Message Format - -# Path Attributes) -_BGP_PA_EXTENDED_LENGTH = 0x10 - -# RFC 5492 (at least 2 bytes : code + length) -_BGP_CAPABILITY_MIN_SIZE = 2 - -# RFC 5492 (at least 3 bytes : type code + length) -_BGP_PATH_ATTRIBUTE_MIN_SIZE = 3 - - -# -# Fields and utilities -# - -def _bits_to_bytes_len(length_in_bits): - """ - Helper function that returns the numbers of bytes necessary to store the - given number of bits. - """ - - return (length_in_bits + 7) // 8 - - -class BGPFieldIPv4(Field): - """ - IPv4 Field (CIDR) - """ - - def mask2iplen(self, mask): - """Get the IP field mask length (in bytes).""" - return (mask + 7) // 8 - - def h2i(self, pkt, h): - """x.x.x.x/y to "internal" representation.""" - ip, mask = re.split("/", h) - return int(mask), ip - - def i2h(self, pkt, i): - """"Internal" representation to "human" representation - (x.x.x.x/y).""" - mask, ip = i - return ip + "/" + str(mask) - - def i2repr(self, pkt, i): - return self.i2h(pkt, i) - - def i2len(self, pkt, i): - mask, ip = i - return self.mask2iplen(mask) + 1 - - def i2m(self, pkt, i): - """"Internal" (IP as bytes, mask as int) to "machine" - representation.""" - mask, ip = i - ip = socket.inet_aton(ip) - return struct.pack(">B", mask) + ip[:self.mask2iplen(mask)] - - def addfield(self, pkt, s, val): - return s + self.i2m(pkt, val) - - def getfield(self, pkt, s): - length = self.mask2iplen(orb(s[0])) + 1 - return s[length:], self.m2i(pkt, s[:length]) - - def m2i(self, pkt, m): - mask = orb(m[0]) - mask2iplen_res = self.mask2iplen(mask) - ip = b"".join(m[i + 1:i + 2] if i < mask2iplen_res else b"\x00" for i in range(4)) # noqa: E501 - return (mask, socket.inet_ntoa(ip)) - - -class BGPFieldIPv6(Field): - """IPv6 Field (CIDR)""" - - def mask2iplen(self, mask): - """Get the IP field mask length (in bytes).""" - return (mask + 7) // 8 - - def h2i(self, pkt, h): - """x.x.x.x/y to internal representation.""" - ip, mask = re.split("/", h) - return int(mask), ip - - def i2h(self, pkt, i): - """"Internal" representation to "human" representation.""" - mask, ip = i - return ip + "/" + str(mask) - - def i2repr(self, pkt, i): - return self.i2h(pkt, i) - - def i2len(self, pkt, i): - mask, ip = i - return self.mask2iplen(mask) + 1 - - def i2m(self, pkt, i): - """"Internal" (IP as bytes, mask as int) to "machine" representation.""" # noqa: E501 - mask, ip = i - ip = pton_ntop.inet_pton(socket.AF_INET6, ip) - return struct.pack(">B", mask) + ip[:self.mask2iplen(mask)] - - def addfield(self, pkt, s, val): - return s + self.i2m(pkt, val) - - def getfield(self, pkt, s): - length = self.mask2iplen(orb(s[0])) + 1 - return s[length:], self.m2i(pkt, s[:length]) - - def m2i(self, pkt, m): - mask = orb(m[0]) - ip = b"".join(m[i + 1:i + 2] if i < self.mask2iplen(mask) else b"\x00" for i in range(16)) # noqa: E501 - return (mask, pton_ntop.inet_ntop(socket.AF_INET6, ip)) - - -def has_extended_length(flags): - """ - Used in BGPPathAttr to check if the extended-length flag is - set. - """ - - return flags & _BGP_PA_EXTENDED_LENGTH == _BGP_PA_EXTENDED_LENGTH - - -class BGPNLRI_IPv4(Packet): - """ - Packet handling IPv4 NLRI fields. - """ - - name = "IPv4 NLRI" - fields_desc = [BGPFieldIPv4("prefix", "0.0.0.0/0")] - - -class BGPNLRI_IPv6(Packet): - """ - Packet handling IPv6 NLRI fields. - """ - - name = "IPv6 NLRI" - fields_desc = [BGPFieldIPv6("prefix", "::/0")] - - -class BGPNLRIPacketListField(PacketListField): - """ - PacketListField handling NLRI fields. - """ - - def getfield(self, pkt, s): - lst = [] - length = None - ret = b"" - - if self.length_from is not None: - length = self.length_from(pkt) - - if length is not None: - remain, ret = s[:length], s[length:] - else: - index = s.find(_BGP_HEADER_MARKER) - if index != -1: - remain = s[:index] - ret = s[index:] - else: - remain = s - - while remain: - mask_length_in_bits = orb(remain[0]) - mask_length_in_bytes = (mask_length_in_bits + 7) // 8 - current = remain[:mask_length_in_bytes + 1] - remain = remain[mask_length_in_bytes + 1:] - packet = self.m2i(pkt, current) - lst.append(packet) - - return remain + ret, lst - - -class _BGPInvalidDataException(Exception): - """ - Raised when it is not possible to instantiate a BGP packet with the given - data. - """ - - def __init__(self, details): - Exception.__init__( - self, - "Impossible to build packet from the given data" + details - ) - - -def _get_cls(name, fallback_cls=conf.raw_layer): - """ - Returns class named "name" if it exists, fallback_cls otherwise. - """ - - return globals().get(name, fallback_cls) - - -# -# Common dictionaries -# - -_bgp_message_types = { - 0: "NONE", - 1: "OPEN", - 2: "UPDATE", - 3: "NOTIFICATION", - 4: "KEEPALIVE", - 5: "ROUTE-REFRESH" -} - - -# -# AFIs -# - -address_family_identifiers = { - 0: "Reserved", - 1: "IP (IP version 4)", - 2: "IP6 (IP version 6)", - 3: "NSAP", - 4: "HDLC (8-bit multidrop)", - 5: "BBN 1822", - 6: "802 (includes all 802 media plus Ethernet \"canonical format\")", - 7: "E.163", - 8: "E.164 (SMDS, Frame Relay, ATM)", - 9: "F.69 (Telex)", - 10: "X.121 (X.25, Frame Relay)", - 11: "IPX", - 12: "Appletalk", - 13: "Decnet IV", - 14: "Banyan Vines", - 15: "E.164 with NSAP format subaddress", # ANDY_MALIS - 16: "DNS (Domain Name System)", - 17: "Distinguished Name", # CHARLES_LYNN - 18: "AS Number", # CHARLES_LYNN - 19: "XTP over IP version 4", # MIKE_SAUL - 20: "XTP over IP version 6", # MIKE_SAUL - 21: "XTP native mode XTP", # MIKE_SAUL - 22: "Fibre Channel World-Wide Port Name", # MARK_BAKKE - 23: "Fibre Channel World-Wide Node Name", # MARK_BAKKE - 24: "GWID", # SUBRA_HEGDE - 25: "AFI for L2VPN information", # RFC 6074 - 26: "MPLS-TP Section Endpoint Identifier", # RFC 7212 - 27: "MPLS-TP LSP Endpoint Identifier", # RFC 7212 - 28: "MPLS-TP Pseudowire Endpoint Identifier", # RFC 7212 - 29: "MT IP: Multi-Topology IP version 4", # RFC 7307 - 30: "MT IPv6: Multi-Topology IP version 6", # RFC 7307 - 16384: "EIGRP Common Service Family", # DONNIE_SAVAGE - 16385: "EIGRP IPv4 Service Family", # DONNIE_SAVAGE - 16386: "EIGRP IPv6 Service Family", # DONNIE_SAVAGE - 16387: "LISP Canonical Address Format (LCAF)", # DAVID_MEYER - 16388: "BGP-LS", # RFC 7752 - 16389: "48-bit MAC", # RFC 7042 - 16390: "64-bit MAC", # RFC 7042 - 16391: "OUI", # draft-ietf-trill-ia-appsubtlv - 16392: "MAC/24", # draft-ietf-trill-ia-appsubtlv - 16393: "MAC/40", # draft-ietf-trill-ia-appsubtlv - 16394: "IPv6/64", # draft-ietf-trill-ia-appsubtlv - 16395: "RBridge Port ID", # draft-ietf-trill-ia-appsubtlv - 16396: "TRILL Nickname", # RFC 7455 - 65535: "Reserved" -} - - -subsequent_afis = { - 0: "Reserved", # RFC 4760 - 1: "Network Layer Reachability Information used for unicast forwarding", # RFC 4760 # noqa: E501 - 2: "Network Layer Reachability Information used for multicast forwarding", # RFC 4760 # noqa: E501 - 3: "Reserved", # RFC 4760 - 4: "Network Layer Reachability Information (NLRI) with MPLS Labels", # RFC 3107 # noqa: E501 - 5: "MCAST-VPN", # RFC 6514 - 6: "Network Layer Reachability Information used for Dynamic Placement of\ - Multi-Segment Pseudowires", # RFC 7267 - 7: "Encapsulation SAFI", # RFC 5512 - 8: "MCAST-VPLS", # RFC 7117 - 64: "Tunnel SAFI", # DRAFT-NALAWADE-KAPOOR-TUNNEL-SAFI-01 - 65: "Virtual Private LAN Service (VPLS)", # RFC 6074 - 66: "BGP MDT SAFI", # RFC 6037 - 67: "BGP 4over6 SAFI", # RFC 5747 - 68: "BGP 6over4 SAFI", # YONG_CUI - 69: "Layer-1 VPN auto-discovery information", # RFC 5195 - 70: "BGP EVPNs", # RFC 7432 - 71: "BGP-LS", # RFC 7752 - 72: "BGP-LS-VPN", # RFC 7752 - 128: "MPLS-labeled VPN address", # RFC 4364 - 129: "Multicast for BGP/MPLS IP Virtual Private Networks (VPNs)", # RFC 6514 # noqa: E501 - 132: "Route Target constraint", # RFC 4684 - 133: "IPv4 dissemination of flow specification rules", # RFC 5575 - 134: "VPNv4 dissemination of flow specification rules", # RFC 5575 - 140: "VPN auto-discovery", # draft-ietf-l3vpn-bgpvpn-auto - 255: "Reserved" # RFC 4760 -} - - -# Used by _bgp_dispatcher to instantiate the appropriate class -_bgp_cls_by_type = { - 1: "BGPOpen", - 2: "BGPUpdate", - 3: "BGPNotification", - 4: "BGPKeepAlive", - 5: "BGPRouteRefresh", -} - - -# -# Header -# - -class BGPHeader(Packet): - """ - The header of any BGP message. - References: RFC 4271 - """ - - name = "HEADER" - fields_desc = [ - XBitField( - "marker", - 0xffffffffffffffffffffffffffffffff, - 0x80 - ), - ShortField("len", None), - ByteEnumField("type", 4, _bgp_message_types) - ] - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - """ - Returns the right class for the given data. - """ - - return _bgp_dispatcher(_pkt) - - def post_build(self, p, pay): - if self.len is None: - length = len(p) - if pay: - length = length + len(pay) - p = p[:16] + struct.pack("!H", length) + p[18:] - return p + pay - - def guess_payload_class(self, payload): - return _get_cls(_bgp_cls_by_type.get(self.type, conf.raw_layer), conf.raw_layer) # noqa: E501 - - -def _bgp_dispatcher(payload): - """ - Returns the right class for a given BGP message. - """ - - cls = conf.raw_layer - - # By default, calling BGP() will build a BGPHeader. - if payload is None: - cls = _get_cls("BGPHeader", conf.raw_layer) - - else: - if len(payload) >= _BGP_HEADER_SIZE and\ - payload[:16] == _BGP_HEADER_MARKER: - - # Get BGP message type - message_type = orb(payload[18]) - if message_type == 4: - cls = _get_cls("BGPKeepAlive") - else: - cls = _get_cls("BGPHeader") - - return cls - - -class BGP(Packet): - """ - Every BGP message inherits from this class. - """ - - # - # BGP messages types - - OPEN_TYPE = 1 - UPDATE_TYPE = 2 - NOTIFICATION_TYPE = 3 - KEEPALIVE_TYPE = 4 - ROUTEREFRESH_TYPE = 5 - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - """ - Returns the right class for the given data. - """ - - return _bgp_dispatcher(_pkt) - - def guess_payload_class(self, p): - cls = None - if len(p) > 15 and p[:16] == _BGP_HEADER_MARKER: - cls = BGPHeader - return cls - - -# -# KEEPALIVE -# - -class BGPKeepAlive(BGP, BGPHeader): - - """ - KEEPALIVE message. - """ - - name = "KEEPALIVE" - - -# -# OPEN -# - -# -# Optional Parameters Codes -# - -optional_parameter_codes = { - 0: "Reserved", - 1: "Authentication (deprecated)", - 2: "Capabilities" -} - - -# -# Capabilities -# - -_capabilities = { - 0: "Reserved", # RFC 5492 - 1: "Multiprotocol Extensions for BGP-4", # RFC 2858 - 2: "Route Refresh Capability for BGP-4", # RFC 2918 - 3: "Outbound Route Filtering Capability", # RFC 5291 - 4: "Multiple routes to a destination capability", # RFC 3107 - 5: "Extended Next Hop Encoding", # RFC 5549 - 6: "BGP-Extended Message", # (TEMPORARY - registered 2015-09-30, expires 2016-09-30), # noqa: E501 - # draft-ietf-idr-bgp-extended-messages - 64: "Graceful Restart Capability", # RFC 4724 - 65: "Support for 4-octet AS number capability", # RFC 6793 - 66: "Deprecated (2003-03-06)", - 67: "Support for Dynamic Capability (capability specific)", # draft-ietf-idr-dynamic-cap # noqa: E501 - 68: "Multisession BGP Capability", # draft-ietf-idr-bgp-multisession - 69: "ADD-PATH Capability", # RFC-ietf-idr-add-paths-15 - 70: "Enhanced Route Refresh Capability", # RFC 7313 - 71: "Long-Lived Graceful Restart (LLGR) Capability", # draft-uttaro-idr-bgp-persistence # noqa: E501 - 73: "FQDN Capability", # draft-walton-bgp-hostname-capability - 128: "Route Refresh Capability for BGP-4 (Cisco)", # Cisco also uses 128 for RR capability # noqa: E501 - 130: "Outbound Route Filtering Capability (Cisco)", # Cisco also uses 130 for ORF capability # noqa: E501 -} - - -_capabilities_objects = { - 0x01: "BGPCapMultiprotocol", # RFC 2858 - 0x02: "BGPCapGeneric", # RFC 2918 - 0x03: "BGPCapORF", # RFC 5291 - 0x40: "BGPCapGracefulRestart", # RFC 4724 - 0x41: "BGPCapFourBytesASN", # RFC 4893 - 0x46: "BGPCapGeneric", # Enhanced Route Refresh Capability, RFC 7313 - 0x82: "BGPCapORF", # ORF / RFC 5291 (Cisco) -} - - -def _register_cls(registry, cls): - registry[cls.__name__] = cls - return cls - - -_capabilities_registry = {} - - -def _bgp_capability_dispatcher(payload): - """ - Returns the right class for a given BGP capability. - """ - - cls = _capabilities_registry["BGPCapGeneric"] - - # By default, calling BGPCapability() will build a "generic" capability. - if payload is None: - cls = _capabilities_registry["BGPCapGeneric"] - - else: - length = len(payload) - if length >= _BGP_CAPABILITY_MIN_SIZE: - code = orb(payload[0]) - cls = _get_cls(_capabilities_objects.get(code, "BGPCapGeneric")) - - return cls - - -class _BGPCap_metaclass(type): - def __new__(cls, clsname, bases, attrs): - newclass = super(_BGPCap_metaclass, cls).__new__( - cls, clsname, bases, attrs) - _register_cls(_capabilities_registry, newclass) - return newclass - - -class _BGPCapability_metaclass(Packet_metaclass, _BGPCap_metaclass): - pass - - -class BGPCapability(six.with_metaclass(_BGPCapability_metaclass, Packet)): - """ - Generic BGP capability. - """ - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - """ - Returns the right class for the given data. - """ - - return _bgp_capability_dispatcher(_pkt) - - def pre_dissect(self, s): - """ - Check that the payload is long enough (at least 2 bytes). - """ - length = len(s) - if length < _BGP_CAPABILITY_MIN_SIZE: - err = " ({}".format(length) + " is < _BGP_CAPABILITY_MIN_SIZE " - err += "({})).".format(_BGP_CAPABILITY_MIN_SIZE) - raise _BGPInvalidDataException(err) - return s - - # Every BGP capability object inherits from BGPCapability. - def haslayer(self, cls): - if cls == "BGPCapability": - if isinstance(self, BGPCapability): - return True - elif issubtype(cls, BGPCapability): - if isinstance(self, cls): - return True - return super(BGPCapability, self).haslayer(cls) - - def getlayer(self, cls, nb=1, _track=None, _subclass=True, **flt): - return super(BGPCapability, self).getlayer( - cls, nb=nb, _track=_track, _subclass=True, **flt - ) - - def post_build(self, p, pay): - length = 0 - if self.length is None: - # capability packet length - capability code (1 byte) - - # capability length (1 byte) - length = len(p) - 2 - p = p[:1] + chb(length) + p[2:] - return p + pay - - -class BGPCapGeneric(BGPCapability): - """ - This class provides an implementation of a generic capability. - """ - - name = "BGP Capability" - fields_desc = [ - ByteEnumField("code", 0, _capabilities), - FieldLenField("length", None, fmt="B", length_of="cap_data"), - StrLenField("cap_data", '', - length_from=lambda p: p.length, max_length=255), - ] - - -# -# Multiprotocol Extensions for BGP-4 -# - -class BGPCapMultiprotocol(BGPCapability): - """ - This class provides an implementation of the Multiprotocol - capability. - References: RFC 4760 - """ - - name = "Multiprotocol Extensions for BGP-4" - fields_desc = [ - ByteEnumField("code", 1, _capabilities), - ByteField("length", 4), - ShortEnumField("afi", 0, address_family_identifiers), - ByteField("reserved", 0), - ByteEnumField("safi", 0, subsequent_afis) - ] - - -# -# Outbound Route Filtering Capability for BGP-4 -# - -_orf_types = { - 0: "Reserved", # RFC 5291 - 64: "Address Prefix ORF", # RFC 5292 - 65: "CP-ORF", # RFC 7543 -} - - -send_receive_values = { - 1: "receive", - 2: "send", - 3: "receive + send" -} - - -class BGPCapORFBlock(Packet): - """ - The "ORFBlock" is made of entries. - """ - - class ORFTuple(Packet): - """ - Packet handling tuples. - """ - - # (ORF Type (1 octet) / Send/Receive (1 octet)) .... - name = "ORF Type" - fields_desc = [ - ByteEnumField("orf_type", 0, _orf_types), - ByteEnumField("send_receive", 0, send_receive_values) - ] - - name = "ORF Capability Entry" - fields_desc = [ - ShortEnumField("afi", 0, address_family_identifiers), - ByteField("reserved", 0), - ByteEnumField("safi", 0, subsequent_afis), - FieldLenField( - "orf_number", - None, - count_of="entries", - fmt="!B" - ), - PacketListField( - "entries", - [], - ORFTuple, - count_from=lambda p: p.orf_number - ) - ] - - def post_build(self, p, pay): - count = None - if self.orf_number is None: - count = len(self.entries) # orf_type (1 byte) + send_receive (1 byte) # noqa: E501 - p = p[:4] + struct.pack("!B", count) + p[5:] - return p + pay - - -class BGPCapORFBlockPacketListField(PacketListField): - """ - Handles lists of BGPCapORFBlocks. - """ - - def getfield(self, pkt, s): - lst = [] - length = None - - if self.length_from is not None: - length = self.length_from(pkt) - remain = s - if length is not None: - remain = s[:length] - - while remain: - # block length: afi (2 bytes) + reserved (1 byte) + safi (1 byte) + - # orf_number (1 byte) + entries (2 bytes * orf_number) - orf_number = orb(remain[4]) - entries_length = orf_number * 2 - current = remain[:5 + entries_length] - remain = remain[5 + entries_length:] - packet = self.m2i(pkt, current) - lst.append(packet) - - return remain, lst - - -class BGPCapORF(BGPCapability): - """ - This class provides an implementation of the Outbound Route Filtering - capability. - References: RFC 5291 - """ - - name = "Outbound Route Filtering Capability" - fields_desc = [ - ByteEnumField("code", 3, _capabilities), - ByteField("length", None), - BGPCapORFBlockPacketListField( - "orf", - [], - BGPCapORFBlock, - length_from=lambda p: p.length - ) - ] - - -# -# Graceful Restart capability -# - -gr_address_family_flags = { - 128: "Forwarding state preserved (0x80: F bit set)" -} - - -class BGPCapGracefulRestart(BGPCapability): - """ - This class provides an implementation of the Graceful Restart - capability. - References: RFC 4724 - """ - - class GRTuple(Packet): - - """Tuple """ - name = "" - fields_desc = [ShortEnumField("afi", 0, address_family_identifiers), - ByteEnumField("safi", 0, subsequent_afis), - ByteEnumField("flags", 0, gr_address_family_flags)] - - name = "Graceful Restart Capability" - fields_desc = [ByteEnumField("code", 64, _capabilities), - ByteField("length", None), - BitField("restart_flags", 0, 4), - BitField("restart_time", 0, 12), - PacketListField("entries", [], GRTuple)] - - -# -# Support for 4-octet AS number capability -# - -class BGPCapFourBytesASN(BGPCapability): - """ - This class provides an implementation of the 4-octet AS number - capability. - References: RFC 4893 - """ - - name = "Support for 4-octet AS number capability" - fields_desc = [ByteEnumField("code", 65, _capabilities), - ByteField("length", 4), - IntField("asn", 0)] - - -# -# Authentication Information optional parameter. -# - -class BGPAuthenticationInformation(Packet): - - """ - Provides an implementation of the Authentication Information optional - parameter, which is now obsolete. - References: RFC 1771, RFC 1654, RFC 4271 - """ - - name = "BGP Authentication Data" - fields_desc = [ByteField("authentication_code", 0), - StrField("authentication_data", None)] - - -# -# Optional Parameter. -# - - -class BGPOptParamPacketListField(PacketListField): - """ - PacketListField handling the optional parameters (OPEN message). - """ - - def getfield(self, pkt, s): - lst = [] - - length = 0 - if self.length_from is not None: - length = self.length_from(pkt) - remain = s - if length is not None: - remain, ret = s[:length], s[length:] - - while remain: - param_len = orb(remain[1]) # Get param length - current = remain[:2 + param_len] - remain = remain[2 + param_len:] - packet = self.m2i(pkt, current) - lst.append(packet) - - return remain + ret, lst - - -class BGPOptParam(Packet): - """ - Provides an implementation the OPEN message optional parameters. - References: RFC 4271 - """ - - name = "Optional parameter" - fields_desc = [ - ByteEnumField("param_type", 2, optional_parameter_codes), - ByteField("param_length", None), - ConditionalField( - PacketField( - "param_value", - None, - BGPCapability - ), - lambda p: p.param_type == 2 - ), - # It"s obsolete, but one can use it provided that - # param_type == 1. - ConditionalField( - PacketField( - "authentication_data", - None, - BGPAuthenticationInformation - ), - lambda p: p.param_type == 1 - ) - ] - - def post_build(self, p, pay): - length = None - packet = p - if self.param_length is None: - if self.param_value is None and self.authentication_data is None: - length = 0 - else: - length = len(p) - \ - 2 # parameter type (1 byte) - parameter length (1 byte) - packet = p[:1] + chb(length) - if (self.param_type == 2 and self.param_value is not None) or\ - (self.param_type == 1 and self.authentication_data is not None): # noqa: E501 - packet = packet + p[2:] - - return packet + pay - - -# -# OPEN -# - -class BGPOpen(BGP): - """ - OPEN messages are exchanged in order to open a new BGP session. - References: RFC 4271 - """ - - name = "OPEN" - fields_desc = [ - ByteField("version", 4), - ShortField("my_as", 0), - ShortField("hold_time", 0), - IPField("bgp_id", "0.0.0.0"), - FieldLenField( - "opt_param_len", - None, - length_of="opt_params", - fmt="!B" - ), - BGPOptParamPacketListField( - "opt_params", - [], - BGPOptParam, - length_from=lambda p: p.opt_param_len - ) - ] - - def post_build(self, p, pay): - if self.opt_param_len is None: - length = len(p) - 10 # 10 is regular length with no additional - # options - p = p[:9] + struct.pack("!B", length) + p[10:] - return p + pay - - -# -# UPDATE -# - -# -# Path attributes -# - -# -# Dictionaries - -path_attributes = { - 0: "Reserved", - 1: "ORIGIN", # RFC 4271 - 2: "AS_PATH", # RFC 4271 - 3: "NEXT_HOP", # RFC 4271 - 4: "MULTI_EXIT_DISC", # RFC 4271 - 5: "LOCAL_PREF", # RFC 4271 - 6: "ATOMIC_AGGREGATE", # RFC 4271 - 7: "AGGREGATOR", # RFC 4271 - 8: "COMMUNITY", # RFC 1997 - 9: "ORIGINATOR_ID", # RFC 4456 - 10: "CLUSTER_LIST", # RFC 4456 - 11: "DPA (deprecated)", # RFC 6938 - 12: "ADVERTISER (Historic) (deprecated)", # RFC 4223, RFC 6938 - 13: "RCID_PATH / CLUSTER_ID (Historic) (deprecated)", # RFC 4223, RFC 6938 - 14: "MP_REACH_NLRI", # RFC 4760 - 15: "MP_UNREACH_NLRI", # RFC 4760 - 16: "EXTENDED COMMUNITIES", # RFC 4360 - 17: "AS4_PATH", # RFC 6793 - 18: "AS4_AGGREGATOR", # RFC 6793 - 19: "SAFI Specific Attribute (SSA) (deprecated)", # draft-kapoor-nalawade-idr-bgp-ssa-00, # noqa: E501 - # draft-nalawade-idr-mdt-safi-00, draft-wijnands-mt-discovery-00 - 20: "Connector Attribute (deprecated)", # RFC 6037 - 21: "AS_PATHLIMIT (deprecated)", # draft-ietf-idr-as-pathlimit - 22: "PMSI_TUNNEL", # RFC 6514 - 23: "Tunnel Encapsulation Attribute", # RFC 5512 - 24: "Traffic Engineering", # RFC 5543 - 25: "IPv6 Address Specific Extended Community", # RFC 5701 - 26: "AIGP", # RFC 7311 - 27: "PE Distinguisher Labels", # RFC 6514 - 28: "BGP Entropy Label Capability Attribute (deprecated)", # RFC 6790, RFC 7447 # noqa: E501 - 29: "BGP-LS Attribute", # RFC 7752 - 40: "BGP Prefix-SID", # (TEMPORARY - registered 2015-09-30, expires 2016-09-30) # noqa: E501 - # draft-ietf-idr-bgp-prefix-sid - 128: "ATTR_SET", # RFC 6368 - 255: "Reserved for development" -} - -# http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xml -attributes_flags = { - 1: 0x40, # ORIGIN - 2: 0x40, # AS_PATH - 3: 0x40, # NEXT_HOP - 4: 0x80, # MULTI_EXIT_DISC - 5: 0x40, # LOCAL_PREF - 6: 0x40, # ATOMIC_AGGREGATE - 7: 0xc0, # AGGREGATOR - 8: 0xc0, # COMMUNITIES (RFC 1997) - 9: 0x80, # ORIGINATOR_ID (RFC 4456) - 10: 0x80, # CLUSTER_LIST (RFC 4456) - 11: 0xc0, # DPA (RFC 6938) - 12: 0x80, # ADVERTISER (RFC 1863, RFC 4223) - 13: 0x80, # RCID_PATH (RFC 1863, RFC 4223) - 14: 0x80, # MP_REACH_NLRI (RFC 4760) - 15: 0x80, # MP_UNREACH_NLRI (RFC 4760) - 16: 0xc0, # EXTENDED_COMMUNITIES (RFC 4360) - 17: 0xc0, # AS4_PATH (RFC 6793) - 18: 0xc0, # AS4_AGGREGATOR (RFC 6793) - 19: 0xc0, # SSA (draft-kapoor-nalawade-idr-bgp-ssa-00) - 20: 0xc0, # Connector (RFC 6037) - 21: 0xc0, # AS_PATHLIMIT (draft-ietf-idr-as-pathlimit) - 22: 0xc0, # PMSI_TUNNEL (RFC 6514) - 23: 0xc0, # Tunnel Encapsulation (RFC 5512) - 24: 0x80, # Traffic Engineering (RFC 5543) - 25: 0xc0, # IPv6 Address Specific Extended Community (RFC 5701) - 26: 0x80, # AIGP (RFC 7311) - 27: 0xc0, # PE Distinguisher Labels (RFC 6514) - 28: 0xc0, # BGP Entropy Label Capability Attribute - 29: 0x80, # BGP-LS Attribute - 40: 0xc0, # BGP Prefix-SID - 128: 0xc0 # ATTR_SET (RFC 6368) -} - - -class BGPPathAttrPacketListField(PacketListField): - """ - PacketListField handling the path attributes (UPDATE message). - """ - - def getfield(self, pkt, s): - lst = [] - length = 0 - - if self.length_from is not None: - length = self.length_from(pkt) - ret = "" - remain = s - if length is not None: - remain, ret = s[:length], s[length:] - - while remain: - # - # Get the path attribute flags - flags = orb(remain[0]) - - attr_len = 0 - if has_extended_length(flags): - attr_len = struct.unpack("!H", remain[2:4])[0] - current = remain[:4 + attr_len] - remain = remain[4 + attr_len:] - else: - attr_len = orb(remain[2]) - current = remain[:3 + attr_len] - remain = remain[3 + attr_len:] - - packet = self.m2i(pkt, current) - lst.append(packet) - - return remain + ret, lst - - -# -# ORIGIN -# - -class BGPPAOrigin(Packet): - - """ - Packet handling the ORIGIN attribute value. - References: RFC 4271 - """ - - name = "ORIGIN" - fields_desc = [ - ByteEnumField("origin", 0, {0: "IGP", 1: "EGP", 2: "INCOMPLETE"})] - - -# -# AS_PATH (2 bytes and 4 bytes) -# - -as_path_segment_types = { - # RFC 4271 - 1: "AS_SET", - 2: "AS_SEQUENCE", - - # RFC 5065 - 3: "AS_CONFED_SEQUENCE", - 4: "AS_CONFED_SET" -} - - -class ASPathSegmentPacketListField(PacketListField): - """ - PacketListField handling AS_PATH segments. - """ - - def getfield(self, pkt, s): - lst = [] - remain = s - - while remain: - # - # Get the segment length - segment_length = orb(remain[1]) - - if bgp_module_conf.use_2_bytes_asn: - current = remain[:2 + segment_length * 2] - remain = remain[2 + segment_length * 2:] - else: - current = remain[:2 + segment_length * 4] - remain = remain[2 + segment_length * 4:] - - packet = self.m2i(pkt, current) - lst.append(packet) - - return remain, lst - - -class BGPPAASPath(Packet): - """ - Packet handling the AS_PATH attribute value (2 bytes ASNs, for old - speakers). - References: RFC 4271, RFC 5065 - """ - - AS_TRANS = 23456 - - class ASPathSegment(Packet): - """ - Provides an implementation for AS_PATH segments with 2 bytes ASNs. - """ - - fields_desc = [ - ByteEnumField("segment_type", 2, as_path_segment_types), - ByteField("segment_length", None), - FieldListField("segment_value", [], ShortField("asn", 0)) - ] - - def post_build(self, p, pay): - segment_len = self.segment_length - if segment_len is None: - segment_len = len(self.segment_value) - p = p[:1] + chb(segment_len) + p[2:] - - return p + pay - - name = "AS_PATH (RFC 4271)" - fields_desc = [ - ASPathSegmentPacketListField("segments", [], ASPathSegment)] - - -class BGPPAAS4BytesPath(Packet): - """ - Packet handling the AS_PATH attribute value (4 bytes ASNs, for new - speakers -> ASNs are encoded as IntFields). - References: RFC 4893 - """ - - class ASPathSegment(Packet): - """ - Provides an implementation for AS_PATH segments with 4 bytes ASNs. - """ - - fields_desc = [ByteEnumField("segment_type", 2, as_path_segment_types), - ByteField("segment_length", None), - FieldListField("segment_value", [], IntField("asn", 0))] - - def post_build(self, p, pay): - segment_len = self.segment_length - if segment_len is None: - segment_len = len(self.segment_value) - p = p[:1] + chb(segment_len) + p[2:] - - return p + pay - - name = "AS_PATH (RFC 4893)" - fields_desc = [ - ASPathSegmentPacketListField("segments", [], ASPathSegment)] - - -# -# NEXT_HOP -# - -class BGPPANextHop(Packet): - """ - Packet handling the NEXT_HOP attribute value. - References: RFC 4271 - """ - - name = "NEXT_HOP" - fields_desc = [IPField("next_hop", "0.0.0.0")] - - -# -# MULTI_EXIT_DISC -# - -class BGPPAMultiExitDisc(Packet): - """ - Packet handling the MULTI_EXIT_DISC attribute value. - References: RFC 4271 - """ - - name = "MULTI_EXIT_DISC" - fields_desc = [IntField("med", 0)] - - -# -# LOCAL_PREF -# - -class BGPPALocalPref(Packet): - """ - Packet handling the LOCAL_PREF attribute value. - References: RFC 4271 - """ - - name = "LOCAL_PREF" - fields_desc = [IntField("local_pref", 0)] - - -# -# ATOMIC_AGGREGATE -# - -class BGPPAAtomicAggregate(Packet): - """ - Packet handling the ATOMIC_AGGREGATE attribute value. - References: RFC 4271 - """ - - name = "ATOMIC_AGGREGATE" - - -# -# AGGREGATOR -# - -class BGPPAAggregator(Packet): - """ - Packet handling the AGGREGATOR attribute value. - References: RFC 4271 - """ - - name = "AGGREGATOR" - fields_desc = [ShortField("aggregator_asn", 0), - IPField("speaker_address", "0.0.0.0")] - - -# -# COMMUNITIES -# - -# http://www.iana.org/assignments/bgp-well-known-communities/bgp-well-known-communities.xml -well_known_communities = { - 0xFFFFFF01: "NO_EXPORT", # RFC 1997 - 0xFFFFFF02: "NO_ADVERTISE", # RFC 1997 - 0xFFFFFF03: "NO_EXPORT_SUBCONFED", # RFC 1997 - 0xFFFFFF04: "NOPEER", # RFC 3765 - 0xFFFF0000: "planned-shut", # draft-francois-bgp-gshut - 0xFFFF0001: "ACCEPT-OWN", # RFC 7611 - 0xFFFF0002: "ROUTE_FILTER_TRANSLATED_v4", # draft-l3vpn-legacy-rtc - 0xFFFF0003: "ROUTE_FILTER_v4", # draft-l3vpn-legacy-rtc - 0xFFFF0004: "ROUTE_FILTER_TRANSLATED_v6", # draft-l3vpn-legacy-rtc - 0xFFFF0005: "ROUTE_FILTER_v6", # draft-l3vpn-legacy-rtc - 0xFFFF0006: "LLGR_STALE", # draft-uttaro-idr-bgp-persistence - 0xFFFF0007: "NO_LLGR", # draft-uttaro-idr-bgp-persistence - 0xFFFF0008: "accept-own-nexthop", # Ashutosh_Grewal -} - - -class BGPPACommunity(Packet): - """ - Packet handling the COMMUNITIES attribute value. - References: RFC 1997 - """ - - name = "COMMUNITIES" - fields_desc = [IntEnumField("community", 0, well_known_communities)] - - -# -# ORIGINATOR_ID -# - -class BGPPAOriginatorID(Packet): - """ - Packet handling the ORIGINATOR_ID attribute value. - References: RFC 4456 - """ - - name = "ORIGINATOR_ID" - fields_desc = [IPField("originator_id", "0.0.0.0")] - - -# -# CLUSTER_LIST -# - -class BGPPAClusterList(Packet): - """ - Packet handling the CLUSTER_LIST attribute value. - References: RFC 4456 - """ - - name = "CLUSTER_LIST" - fields_desc = [ - FieldListField("cluster_list", [], IntField("cluster_id", 0))] - - -# -# EXTENDED COMMUNITIES (RFC 4360) -# - -# BGP Transitive Extended Community Types -# http://www.iana.org/assignments/bgp-extended-communities/bgp-extended-communities.xhtml#transitive -_ext_comm_types = { - 0x00: "Transitive Two-Octet AS-Specific Extended Community", # RFC 7153 - 0x01: "Transitive IPv4-Address-Specific Extended Community", # RFC 7153 - 0x02: "Transitive Four-Octet AS-Specific Extended Community", # RFC 7153 - 0x03: "Transitive Opaque Extended Community", # RFC 7153 - 0x04: "QoS Marking", # Thomas_Martin_Knoll - 0x05: "CoS Capability", # Thomas_Martin_Knoll - 0x06: "EVPN", # RFC 7153 - 0x07: "Unassigned", - 0x08: "Flow spec redirect/mirror to IP next-hop", # draft-simpson-idr-flowspec-redirect # noqa: E501 - - # BGP Non-Transitive Extended Community Types - 0x40: "Non-Transitive Two-Octet AS-Specific Extended Community", # RFC 7153 # noqa: E501 - 0x41: "Non-Transitive IPv4-Address-Specific Extended Community", # RFC 7153 # noqa: E501 - 0x42: "Non-Transitive Four-Octet AS-Specific Extended Community", # RFC 7153 # noqa: E501 - 0x43: "Non-Transitive Opaque Extended Community", # RFC 7153 - 0x44: "QoS Marking", # Thomas_Martin_Knoll - - 0x80: "Generic Transitive Experimental Use Extended Community", # RFC 7153 - 0x81: "Generic Transitive Experimental Use Extended Community Part 2", # RFC 7674 # noqa: E501 - 0x82: "Generic Transitive Experimental Use Extended Community Part 3", # RFC 7674 # noqa: E501 -} - -# EVPN Extended Community Sub-Types -_ext_comm_evpn_subtypes = { - 0x00: "MAC Mobility", # RFC 7432 - 0x01: "ESI Label", # RFC 7432 - 0x02: "ES-Import Route Target", # RFC 7432 - 0x03: "EVPN Router\"s MAC Extended Community", - # draft-sajassi-l2vpn-evpn-inter-subnet-forwarding - 0x04: "Layer 2 Extended Community", # draft-ietf-bess-evpn-vpws - 0x05: "E-TREE Extended Community", # draft-ietf-bess-evpn-etree - 0x06: "DF Election Extended Community", # draft-ietf-bess-evpn-df-election - 0x07: "I-SID Extended Community", # draft-sajassi-bess-evpn-virtual-eth-segment # noqa: E501 -} - -# Transitive Two-Octet AS-Specific Extended Community Sub-Types -_ext_comm_trans_two_octets_as_specific_subtypes = { - 0x02: "Route Target", # RFC 4360 - 0x03: "Route Origin", # RFC 4360 - 0x04: "Unassigned", # RFC 4360 - 0x05: "OSPF Domain Identifier", # RFC 4577 - 0x08: "BGP Data Collection", # RFC 4384 - 0x09: "Source AS", # RFC 6514 - 0x0a: "L2VPN Identifier", # RFC 6074 - 0x0010: "Cisco VPN-Distinguisher", # Eric_Rosen -} - -# Non-Transitive Two-Octet AS-Specific Extended Community Sub-Types -_ext_comm_non_trans_two_octets_as_specific_subtypes = { - 0x04: "Link Bandwidth Extended Community", # draft-ietf-idr-link-bandwidth-00 # noqa: E501 - 0x80: "Virtual-Network Identifier Extended Community", - # draft-drao-bgp-l3vpn-virtual-network-overlays -} - -# Transitive Four-Octet AS-Specific Extended Community Sub-Types -_ext_comm_trans_four_octets_as_specific_subtypes = { - 0x02: "Route Target", # RFC 5668 - 0x03: "Route Origin", # RFC 5668 - 0x04: "Generic", # draft-ietf-idr-as4octet-extcomm-generic-subtype - 0x05: "OSPF Domain Identifier", # RFC 4577 - 0x08: "BGP Data Collection", # RFC 4384 - 0x09: "Source AS", # RFC 6514 - 0x10: "Cisco VPN Identifier", # Eric_Rosen -} - -# Non-Transitive Four-Octet AS-Specific Extended Community Sub-Types -_ext_comm_non_trans_four_octets_as_specific_subtypes = { - 0x04: "Generic", # draft-ietf-idr-as4octet-extcomm-generic-subtype -} - -# Transitive IPv4-Address-Specific Extended Community Sub-Types -_ext_comm_trans_ipv4_addr_specific_subtypes = { - 0x02: "Route Target", # RFC 4360 - 0x03: "Route Origin", # RFC 4360 - 0x05: "OSPF Domain Identifier", # RFC 4577 - 0x07: "OSPF Route ID", # RFC 4577 - 0x0a: "L2VPN Identifier", # RFC 6074 - 0x0b: "VRF Route Import", # RFC 6514 - 0x0c: "Flow-spec Redirect to IPv4", # draft-ietf-idr-flowspec-redirect - 0x10: "Cisco VPN-Distinguisher", # Eric_Rosen - 0x12: "Inter-Area P2MP Segmented Next-Hop", # RFC 7524 -} - -# Non-Transitive IPv4-Address-Specific Extended Community Sub-Types -_ext_comm_non_trans_ipv4_addr_specific_subtypes = {} - -# Transitive Opaque Extended Community Sub-Types -_ext_comm_trans_opaque_subtypes = { - 0x01: "Cost Community", # draft-ietf-idr-custom-decision - 0x03: "CP-ORF", # RFC 7543 - 0x04: "Extranet Source Extended Community", # RFC 7900 - 0x05: "Extranet Separation Extended Community", # RFC 7900 - 0x06: "OSPF Route Type", # RFC 4577 - 0x07: "Additional PMSI Tunnel Attribute Flags", # RFC 7902 - 0x0b: "Color Extended Community", # RFC 5512 - 0x0c: "Encapsulation Extended Community", # RFC 5512 - 0x0d: "Default Gateway", # Yakov_Rekhter - 0x0e: "Point-to-Point-to-Multipoint (PPMP) Label", # Rishabh_Parekh - 0x13: "Route-Target Record", # draft-ietf-bess-service-chaining - 0x14: "Consistent Hash Sort Order", # draft-ietf-bess-service-chaining -} - -# Non-Transitive Opaque Extended Community Sub-Types -_ext_comm_non_trans_opaque_subtypes = { - 0x00: "BGP Origin Validation State", # draft-ietf-sidr-origin-validation-signaling # noqa: E501 - 0x01: "Cost Community", # draft-ietf-idr-custom-decision -} - -# Generic Transitive Experimental Use Extended Community Sub-Types -_ext_comm_generic_transitive_exp_subtypes = { - 0x00: "OSPF Route Type (deprecated)", # RFC 4577 - 0x01: "OSPF Router ID (deprecated)", # RFC 4577 - 0x05: "OSPF Domain Identifier (deprecated)", # RFC 4577 - 0x06: "Flow spec traffic-rate", # RFC 5575 - 0x07: "Flow spec traffic-action", # RFC 5575 - 0x08: "Flow spec redirect AS-2byte format", # RFC 5575, RFC 7674 - 0x09: "Flow spec traffic-remarking", # RFC 5575 - 0x0a: "Layer2 Info Extended Community", # RFC 4761 - 0x0b: "E-Tree Info", # RFC 7796 -} - -# Generic Transitive Experimental Use Extended Community Part 2 Sub-Types -_ext_comm_generic_transitive_exp_part2_subtypes = { - 0x08: "Flow spec redirect IPv4 format", # RFC 7674 -} - -# Generic Transitive Experimental Use Extended Community Part 3 Sub-Types -_ext_comm_generic_transitive_exp_part3_subtypes = { - 0x08: "Flow spec redirect AS-4byte format", # RFC 7674 -} - -# Traffic Action Fields -_ext_comm_traffic_action_fields = { - 47: "Terminal Action", # RFC 5575 - 46: "Sample", # RFC 5575 -} - -# Transitive IPv6-Address-Specific Extended Community Types -_ext_comm_trans_ipv6_addr_specific_types = { - 0x0002: "Route Target", # RFC 5701 - 0x0003: "Route Origin", # RFC 5701 - 0x0004: "OSPFv3 Route Attributes (DEPRECATED)", # RFC 6565 - 0x000b: "VRF Route Import", # RFC 6515, RFC 6514 - 0x000c: "Flow-spec Redirect to IPv6", # draft-ietf-idr-flowspec-redirect-ip # noqa: E501 - 0x0010: "Cisco VPN-Distinguisher", # Eric_Rosen - 0x0011: "UUID-based Route Target", # Dhananjaya_Rao - 0x0012: "Inter-Area P2MP Segmented Next-Hop", # RFC 7524 -} - -# Non-Transitive IPv6-Address-Specific Extended Community Types -_ext_comm_non_trans_ipv6_addr_specific_types = {} - - -_ext_comm_subtypes_classes = { - 0x00: _ext_comm_trans_two_octets_as_specific_subtypes, - 0x01: _ext_comm_trans_ipv4_addr_specific_subtypes, - 0x02: _ext_comm_trans_four_octets_as_specific_subtypes, - 0x03: _ext_comm_trans_opaque_subtypes, - 0x06: _ext_comm_evpn_subtypes, - 0x40: _ext_comm_non_trans_two_octets_as_specific_subtypes, - 0x41: _ext_comm_non_trans_ipv4_addr_specific_subtypes, - 0x42: _ext_comm_non_trans_four_octets_as_specific_subtypes, - 0x43: _ext_comm_non_trans_opaque_subtypes, - 0x80: _ext_comm_generic_transitive_exp_subtypes, - 0x81: _ext_comm_generic_transitive_exp_part2_subtypes, - 0x82: _ext_comm_generic_transitive_exp_part3_subtypes, -} - - -# -# Extended Community "templates" -# - -class BGPPAExtCommTwoOctetASSpecific(Packet): - """ - Packet handling the Two-Octet AS Specific Extended Community attribute - value. - References: RFC 4360 - """ - - name = "Two-Octet AS Specific Extended Community" - fields_desc = [ - ShortField("global_administrator", 0), IntField("local_administrator", 0)] # noqa: E501 - - -class BGPPAExtCommFourOctetASSpecific(Packet): - """ - Packet handling the Four-Octet AS Specific Extended Community - attribute value. - References: RFC 5668 - """ - - name = "Four-Octet AS Specific Extended Community" - fields_desc = [ - IntField("global_administrator", 0), ShortField("local_administrator", 0)] # noqa: E501 - - -class BGPPAExtCommIPv4AddressSpecific(Packet): - """ - Packet handling the IPv4 Address Specific Extended Community attribute - value. - References: RFC 4360 - """ - - name = "IPv4 Address Specific Extended Community" - fields_desc = [ - IntField("global_administrator", 0), ShortField("local_administrator", 0)] # noqa: E501 - - -class BGPPAExtCommOpaque(Packet): - """ - Packet handling the Opaque Extended Community attribute value. - References: RFC 4360 - """ - - name = "Opaque Extended Community" - fields_desc = [StrFixedLenField("value", "", length=6)] - - -# -# FlowSpec related extended communities -# - -class BGPPAExtCommTrafficRate(Packet): - """ - Packet handling the (FlowSpec) "traffic-rate" extended community. - References: RFC 5575 - """ - - name = "FlowSpec traffic-rate extended community" - fields_desc = [ - ShortField("id", 0), - IEEEFloatField("rate", 0) - ] - - -class BGPPAExtCommTrafficAction(Packet): - """ - Packet handling the (FlowSpec) "traffic-action" extended community. - References: RFC 5575 - """ - - name = "FlowSpec traffic-action extended community" - fields_desc = [ - BitField("reserved", 0, 46), - BitField("sample", 0, 1), - BitField("terminal_action", 0, 1) - ] - - -class BGPPAExtCommRedirectAS2Byte(Packet): - """ - Packet handling the (FlowSpec) "redirect AS-2byte" extended community - (RFC 7674). - References: RFC 7674 - """ - - name = "FlowSpec redirect AS-2byte extended community" - fields_desc = [ - ShortField("asn", 0), - IntField("value", 0) - ] - - -class BGPPAExtCommRedirectIPv4(Packet): - """ - Packet handling the (FlowSpec) "redirect IPv4" extended community. - (RFC 7674). - References: RFC 7674 - """ - - name = "FlowSpec redirect IPv4 extended community" - fields_desc = [ - IntField("ip_addr", 0), - ShortField("value", 0) - ] - - -class BGPPAExtCommRedirectAS4Byte(Packet): - """ - Packet handling the (FlowSpec) "redirect AS-4byte" extended community. - (RFC 7674). - References: RFC 7674 - """ - - name = "FlowSpec redirect AS-4byte extended community" - fields_desc = [ - IntField("asn", 0), - ShortField("value", 0) - ] - - -class BGPPAExtCommTrafficMarking(Packet): - """ - Packet handling the (FlowSpec) "traffic-marking" extended community. - References: RFC 5575 - """ - - name = "FlowSpec traffic-marking extended community" - fields_desc = [ - BitEnumField("dscp", 48, 48, _ext_comm_traffic_action_fields) - ] - - -_ext_high_low_dict = { - BGPPAExtCommTwoOctetASSpecific: (0x00, 0x00), - BGPPAExtCommIPv4AddressSpecific: (0x01, 0x00), - BGPPAExtCommFourOctetASSpecific: (0x02, 0x00), - BGPPAExtCommOpaque: (0x03, 0x00), - BGPPAExtCommTrafficRate: (0x80, 0x06), - BGPPAExtCommTrafficAction: (0x80, 0x07), - BGPPAExtCommRedirectAS2Byte: (0x80, 0x08), - BGPPAExtCommTrafficMarking: (0x80, 0x09), - BGPPAExtCommRedirectIPv4: (0x81, 0x08), - BGPPAExtCommRedirectAS4Byte: (0x82, 0x08), -} - - -class _ExtCommValuePacketField(PacketField): - """ - PacketField handling Extended Communities "value parts". - """ - - __slots__ = ["type_from"] - - def __init__(self, name, default, cls, remain=0, type_from=(0, 0)): - PacketField.__init__(self, name, default, cls, remain) - self.type_from = type_from - - def m2i(self, pkt, m): - ret = None - type_high, type_low = self.type_from(pkt) - - if type_high == 0x00 or type_high == 0x40: - # Two-Octet AS Specific Extended Community - ret = BGPPAExtCommTwoOctetASSpecific(m) - - elif type_high == 0x01 or type_high == 0x41: - # IPv4 Address Specific - ret = BGPPAExtCommIPv4AddressSpecific(m) - - elif type_high == 0x02 or type_high == 0x42: - # Four-octet AS Specific Extended Community - ret = BGPPAExtCommFourOctetASSpecific(m) - - elif type_high == 0x03 or type_high == 0x43: - # Opaque - ret = BGPPAExtCommOpaque(m) - - elif type_high == 0x80: - # FlowSpec - if type_low == 0x06: - ret = BGPPAExtCommTrafficRate(m) - elif type_low == 0x07: - ret = BGPPAExtCommTrafficAction(m) - elif type_low == 0x08: - ret = BGPPAExtCommRedirectAS2Byte(m) - elif type_low == 0x09: - ret = BGPPAExtCommTrafficMarking(m) - - elif type_high == 0x81: - # FlowSpec - if type_low == 0x08: - ret = BGPPAExtCommRedirectIPv4(m) - - elif type_high == 0x82: - # FlowSpec - if type_low == 0x08: - ret = BGPPAExtCommRedirectAS4Byte(m) - - else: - ret = conf.raw_layer(m) - - return ret - - -class BGPPAIPv6AddressSpecificExtComm(Packet): - """ - Provides an implementation of the IPv6 Address Specific Extended - Community attribute. This attribute is not defined using the existing - BGP Extended Community attribute (see the RFC 5701 excerpt below). - References: RFC 5701 - """ - - name = "IPv6 Address Specific Extended Community" - fields_desc = [ - IP6Field("global_administrator", "::"), ShortField("local_administrator", 0)] # noqa: E501 - - -def _get_ext_comm_subtype(type_high): - """ - Returns a ByteEnumField with the right sub-types dict for a given community. # noqa: E501 - http://www.iana.org/assignments/bgp-extended-communities/bgp-extended-communities.xhtml - """ - - return _ext_comm_subtypes_classes.get(type_high, {}) - - -class _TypeLowField(ByteField): - """ - Field used to retrieve "dynamically" the right sub-type dict. - """ - - __slots__ = ["enum_from"] - - def __init__(self, name, default, enum_from=None): - ByteField.__init__(self, name=name, default=default) - self.enum_from = enum_from - - def i2repr(self, pkt, i): - enum = self.enum_from(pkt) - return enum.get(i, i) - - -class BGPPAExtCommunity(Packet): - """ - Provides an implementation of the Extended Communities attribute. - References: RFC 4360 - """ - - name = "EXTENDED_COMMUNITY" - fields_desc = [ - ByteEnumField("type_high", 0, _ext_comm_types), - _TypeLowField( - "type_low", - None, - enum_from=lambda x: _get_ext_comm_subtype(x.type_high) - ), - _ExtCommValuePacketField( - "value", - None, - Packet, - type_from=lambda x: (x.type_high, x.type_low) - ) - ] - - def post_build(self, p, pay): - if self.value is None: - p = p[:2] - if self.type_low is None and self.value is not None: - high, low = _ext_high_low_dict.get(self.value.__class__, (0x00, 0x00)) # noqa: E501 - p = chb(high) + chb(low) + p[2:] - return p + pay - - -class _ExtCommsPacketListField(PacketListField): - """ - PacketListField handling a list of extended communities. - """ - - def getfield(self, pkt, s): - lst = [] - length = len(s) - remain = s[:length] - - while remain: - current = remain[:8] - remain = remain[8:] - packet = self.m2i(pkt, current) - lst.append(packet) - - return remain, lst - - -class BGPPAExtComms(Packet): - """ - Packet handling the multiple extended communities. - """ - - name = "EXTENDED_COMMUNITIES" - fields_desc = [ - _ExtCommsPacketListField( - "extended_communities", - [], - BGPPAExtCommunity - ) - ] - - -class MPReachNLRIPacketListField(PacketListField): - """ - PacketListField handling the AFI specific part (except for the length of - Next Hop Network Address field, which is not AFI specific) of the - MP_REACH_NLRI attribute. - """ - - def getfield(self, pkt, s): - lst = [] - remain = s - - # IPv6 - if pkt.afi == 2: - if pkt.safi == 1: - # BGPNLRI_IPv6 - while remain: - mask = orb(remain[0]) - length_in_bytes = (mask + 7) // 8 - current = remain[:length_in_bytes + 1] - remain = remain[length_in_bytes + 1:] - prefix = BGPNLRI_IPv6(current) - lst.append(prefix) - - return remain, lst - - -class BGPPAMPReachNLRI(Packet): - """ - Packet handling the MP_REACH_NLRI attribute value, for non IPv6 - AFI. - References: RFC 4760 - """ - - name = "MP_REACH_NLRI" - fields_desc = [ - ShortEnumField("afi", 0, address_family_identifiers), - ByteEnumField("safi", 0, subsequent_afis), - ByteField("nh_addr_len", 0), - ConditionalField(IPField("nh_v4_addr", "0.0.0.0"), - lambda x: x.afi == 1 and x.nh_addr_len == 4), - ConditionalField(IP6Field("nh_v6_addr", "::"), - lambda x: x.afi == 2 and x.nh_addr_len == 16), - ConditionalField(IP6Field("nh_v6_global", "::"), - lambda x: x.afi == 2 and x.nh_addr_len == 32), - ConditionalField(IP6Field("nh_v6_link_local", "::"), - lambda x: x.afi == 2 and x.nh_addr_len == 32), - ByteField("reserved", 0), - MPReachNLRIPacketListField("nlri", [], Packet)] - - def post_build(self, p, pay): - if self.nlri is None: - p = p[:3] - - return p + pay - - -# -# MP_UNREACH_NLRI -# - -class BGPPAMPUnreachNLRI_IPv6(Packet): - """ - Packet handling the MP_UNREACH_NLRI attribute value, for IPv6 AFI. - """ - - name = "MP_UNREACH_NLRI (IPv6 NLRI)" - fields_desc = [BGPNLRIPacketListField( - "withdrawn_routes", [], BGPNLRI_IPv6)] - - -class MPUnreachNLRIPacketField(PacketField): - """ - PacketField handling the AFI specific part of the MP_UNREACH_NLRI - attribute. - """ - - def m2i(self, pkt, m): - ret = None - - if pkt.afi == 2: - ret = BGPPAMPUnreachNLRI_IPv6(m) - else: - ret = conf.raw_layer(m) - - return ret - - -class BGPPAMPUnreachNLRI(Packet): - """ - Packet handling the MP_UNREACH_NLRI attribute value, for non IPv6 - AFI. - References: RFC 4760 - """ - - name = "MP_UNREACH_NLRI" - fields_desc = [ShortEnumField("afi", 0, address_family_identifiers), - ByteEnumField("safi", 0, subsequent_afis), - MPUnreachNLRIPacketField("afi_safi_specific", None, Packet)] - - def post_build(self, p, pay): - if self.afi_safi_specific is None: - p = p[:3] - - return p + pay - - -# -# AS4_PATH -# - -class BGPPAAS4Path(Packet): - """ - Provides an implementation of the AS4_PATH attribute "value part". - References: RFC 4893 - """ - - name = "AS4_PATH" - fields_desc = [ - ByteEnumField( - "segment_type", - 2, - {1: "AS_SET", 2: "AS_SEQUENCE"} - ), - ByteField("segment_length", None), - FieldListField("segment_value", [], IntField("asn", 0)) - ] - - def post_build(self, p, pay): - if self.segment_length is None: - segment_len = len(self.segment_value) - p = p[:1] + chb(segment_len) + p[2:] - - return p + pay - - -# -# AS4_AGGREGATOR -# - -class BGPPAAS4Aggregator(Packet): - """ - Provides an implementation of the AS4_AGGREGATOR attribute - "value part". - References: RFC 4893 - """ - - name = "AS4_AGGREGATOR " - fields_desc = [IntField("aggregator_asn", 0), - IPField("speaker_address", "0.0.0.0")] - - -_path_attr_objects = { - 0x01: "BGPPAOrigin", - 0x02: "BGPPAASPath", # if bgp_module_conf.use_2_bytes_asn, BGPPAAS4BytesPath otherwise # noqa: E501 - 0x03: "BGPPANextHop", - 0x04: "BGPPAMultiExitDisc", - 0x05: "BGPPALocalPref", - 0x06: "BGPPAAtomicAggregate", - 0x07: "BGPPAAggregator", - 0x08: "BGPPACommunity", - 0x09: "BGPPAOriginatorID", - 0x0A: "BGPPAClusterList", - 0x0E: "BGPPAMPReachNLRI", - 0x0F: "BGPPAMPUnreachNLRI", - 0x10: "BGPPAExtComms", - 0x11: "BGPPAAS4Path", - 0x19: "BGPPAIPv6AddressSpecificExtComm" -} - - -class _PathAttrPacketField(PacketField): - """ - PacketField handling path attribute value parts. - """ - - def m2i(self, pkt, m): - ret = None - type_code = pkt.type_code - - # Reserved - if type_code == 0 or type_code == 255: - ret = conf.raw_layer(m) - # Unassigned - elif (type_code >= 30 and type_code <= 39) or\ - (type_code >= 41 and type_code <= 127) or\ - (type_code >= 129 and type_code <= 254): - ret = conf.raw_layer(m) - # Known path attributes - else: - if type_code == 0x02 and not bgp_module_conf.use_2_bytes_asn: - ret = BGPPAAS4BytesPath(m) - else: - ret = _get_cls( - _path_attr_objects.get(type_code, conf.raw_layer))(m) - - return ret - - -class BGPPathAttr(Packet): - """ - Provides an implementation of the path attributes. - References: RFC 4271 - """ - - name = "BGPPathAttr" - fields_desc = [ - FlagsField("type_flags", 0x80, 8, [ - "NA0", - "NA1", - "NA2", - "NA3", - "Extended-Length", - "Partial", - "Transitive", - "Optional" - ]), - ByteEnumField("type_code", 0, path_attributes), - ConditionalField( - ShortField("attr_ext_len", None), - lambda x: x.type_flags is not None and - has_extended_length(x.type_flags) - ), - ConditionalField( - ByteField("attr_len", None), - lambda x: x.type_flags is not None and not - has_extended_length(x.type_flags) - ), - _PathAttrPacketField("attribute", None, Packet) - ] - - def post_build(self, p, pay): - flags_value = None - length = None - packet = None - extended_length = False - - # Set default flags value ? - if self.type_flags is None: - # Set the standard value, if it is exists in attributes_flags. - if self.type_code in attributes_flags: - flags_value = attributes_flags.get(self.type_code) - - # Otherwise, set to optional, non-transitive. - else: - flags_value = 0x80 - - extended_length = has_extended_length(flags_value) - else: - extended_length = has_extended_length(self.type_flags) - - # Set the flags - if flags_value is None: - packet = p[:2] - else: - packet = struct.pack("!B", flags_value) + p[1] - - # Add the length - if self.attr_len is None: - if self.attribute is None: - length = 0 - else: - if extended_length: - length = len(p) - 4 # Flags + Type + Length (2 bytes) - else: - length = len(p) - 3 # Flags + Type + Length (1 byte) - - if length is None: - if extended_length: - packet = packet + p[2:4] - else: - packet = packet + p[2] - else: - if extended_length: - packet = packet + struct.pack("!H", length) - else: - packet = packet + struct.pack("!B", length) - - # Append the rest of the message - if extended_length: - if self.attribute is not None: - packet = packet + p[4:] - else: - if self.attribute is not None: - packet = packet + p[3:] - - return packet + pay - - -# -# UPDATE -# - -class BGPUpdate(BGP): - """ - UPDATE messages allow peers to exchange routes. - References: RFC 4271 - """ - - name = "UPDATE" - fields_desc = [ - FieldLenField( - "withdrawn_routes_len", - None, - length_of="withdrawn_routes", - fmt="!H" - ), - BGPNLRIPacketListField( - "withdrawn_routes", - [], - BGPNLRI_IPv4, - length_from=lambda p: p.withdrawn_routes_len - ), - FieldLenField( - "path_attr_len", - None, - length_of="path_attr", - fmt="!H" - ), - BGPPathAttrPacketListField( - "path_attr", - [], - BGPPathAttr, - length_from=lambda p: p.path_attr_len - ), - BGPNLRIPacketListField("nlri", [], BGPNLRI_IPv4) - ] - - def post_build(self, p, pay): - subpacklen = lambda p: len(p) - packet = "" - if self.withdrawn_routes_len is None: - wl = sum(map(subpacklen, self.withdrawn_routes)) - packet = p[:0] + struct.pack("!H", wl) + p[2:] - else: - wl = self.withdrawn_routes_len - if self.path_attr_len is None: - length = sum(map(subpacklen, self.path_attr)) - packet = p[:2 + wl] + struct.pack("!H", length) + p[4 + wl:] - - return packet + pay - - -# -# NOTIFICATION -# - -# -# RFC 4271, RFC 7313 -# http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml#bgp-parameters-3 -# -_error_codes = { - 0x01: "Message Header Error", - 0x02: "OPEN Message Error", - 0x03: "UPDATE Message Error", - 0x04: "Hold Timer Expired", - 0x05: "Finite State Machine Error", - 0x06: "Cease", - 0x07: "ROUTE-REFRESH Message Error", # RFC 7313 -} - -# -# http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml#bgp-parameters-4 -# -_error_subcodes = { - # Reserved - 0: {}, - - # Header (RFC 4271) - 1: - { - 0: "Unspecific", - 1: "Connection Not Synchronized", - 2: "Bad Message Length", - 3: "Bad Message Type" - }, - - # OPEN (RFC 4271, RFC 5492) - 2: - { - 0: "Reserved", - 1: "Unsupported Version Number", - 2: "Bad Peer AS", - 3: "Bad BGP Identifier", - 4: "Unsupported Optional Parameter", - 5: "Authentication Failure - Deprecated (RFC 4271)", - 6: "Unacceptable Hold Time", - 7: "Unsupported Capability" - }, - - # UPDATE (RFC 4271) - 3: - { - 0: "Reserved", - 1: "Malformed Attribute List", - 2: "Unrecognized Well-known Attribute", - 3: "Missing Well-known Attribute", - 4: "Attribute Flags Error", - 5: "Attribute Length Error", - 6: "Invalid ORIGIN Attribute", - 7: "AS Routing Loop - Deprecated (RFC 4271)", - 8: "Invalid NEXT_HOP Attribute", - 9: "Optional Attribute Error", - 10: "Invalid Network Field", - 11: "Malformed AS_PATH" - }, - - # Hold Timer Expired - 4: {}, - - # Finite State Machine Error (RFC 6608) - 5: - { - 0: "Unspecified Error", - 1: "Receive Unexpected Message in OpenSent State", - 2: "Receive Unexpected Message in OpenConfirm State", - 3: "Receive Unexpected Message in Established State" - }, - - # Cease (RFC 4486) - 6: - { - 0: "Unspecified Error", - 1: "Maximum Number of Prefixes Reached", - 2: "Administrative Shutdown", - 3: "Peer De-configured", - 4: "Administrative Reset", - 5: "Connection Rejected", - 6: "Other Configuration Change", - 7: "Connection Collision Resolution", - 8: "Out of Resources", - }, - - # ROUTE-REFRESH (RFC 7313) - 7: - { - 0: "Reserved", - 1: "Invalid Message Length" - }, -} - - -class BGPNotification(BGP): - """ - NOTIFICATION messages end a BGP session. - References: RFC 4271 - """ - - name = "NOTIFICATION" - fields_desc = [ - ByteEnumField("error_code", 0, _error_codes), - MultiEnumField( - "error_subcode", - 0, - _error_subcodes, - depends_on=lambda p: p.error_code, - fmt="B" - ), - StrField(name="data", default=None) - ] - - -# -# ROUTE_REFRESH -# - -_orf_when_to_refresh = { - 0x01: "IMMEDIATE", - 0x02: "DEFER" -} - - -_orf_actions = { - 0: "ADD", - 1: "REMOVE", - 2: "REMOVE-ALL" -} - - -_orf_match = { - 0: "PERMIT", - 1: "DENY" -} - - -_orf_entry_afi = 1 -_orf_entry_safi = 1 - - -def _update_orf_afi_safi(afi, safi): - """ - Helper function that sets the afi / safi values - of ORP entries. - """ - - global _orf_entry_afi - global _orf_entry_safi - - _orf_entry_afi = afi - _orf_entry_safi = safi - - -class BGPORFEntry(Packet): - """ - Provides an implementation of an ORF entry. - References: RFC 5291 - """ - - name = "ORF entry" - fields_desc = [ - BitEnumField("action", 0, 2, _orf_actions), - BitEnumField("match", 0, 1, _orf_match), - BitField("reserved", 0, 5), - StrField("value", "") - ] - - -class _ORFNLRIPacketField(PacketField): - """ - PacketField handling the ORF NLRI. - """ - - def m2i(self, pkt, m): - ret = None - - if _orf_entry_afi == 1: - # IPv4 - ret = BGPNLRI_IPv4(m) - - elif _orf_entry_afi == 2: - # IPv6 - ret = BGPNLRI_IPv6(m) - - else: - ret = conf.raw_layer(m) - - return ret - - -class BGPORFAddressPrefix(BGPORFEntry): - """ - Provides an implementation of the Address Prefix ORF (RFC 5292). - """ - - name = "Address Prefix ORF" - fields_desc = [ - BitEnumField("action", 0, 2, _orf_actions), - BitEnumField("match", 0, 1, _orf_match), - BitField("reserved", 0, 5), - IntField("sequence", 0), - ByteField("min_len", 0), - ByteField("max_len", 0), - _ORFNLRIPacketField("prefix", "", Packet), - ] - - -class BGPORFCoveringPrefix(Packet): - """ - Provides an implementation of the CP-ORF (RFC 7543). - """ - - name = "CP-ORF" - fields_desc = [ - BitEnumField("action", 0, 2, _orf_actions), - BitEnumField("match", 0, 1, _orf_match), - BitField("reserved", 0, 5), - IntField("sequence", 0), - ByteField("min_len", 0), - ByteField("max_len", 0), - LongField("rt", 0), - LongField("import_rt", 0), - ByteField("route_type", 0), - PacketField("host_addr", None, Packet) - ] - - -class BGPORFEntryPacketListField(PacketListField): - """ - PacketListField handling the ORF entries. - """ - - def m2i(self, pkt, m): - ret = None - - # Cisco also uses 128 - if pkt.orf_type == 64 or pkt.orf_type == 128: - ret = BGPORFAddressPrefix(m) - - elif pkt.orf_type == 65: - ret = BGPORFCoveringPrefix(m) - - else: - ret = conf.raw_layer(m) - - return ret - - def getfield(self, pkt, s): - lst = [] - length = 0 - ret = b"" - if self.length_from is not None: - length = self.length_from(pkt) - remain = s - if length is not None: - remain, ret = s[:length], s[length:] - - while remain: - orf_len = 0 - - # Get value length, depending on the ORF type - if pkt.orf_type == 64 or pkt.orf_type == 128: - # Address Prefix ORF - # Get the length, in bits, of the prefix - prefix_len = _bits_to_bytes_len( - orb(remain[6]) - ) - # flags (1 byte) + sequence (4 bytes) + min_len (1 byte) + - # max_len (1 byte) + mask_len (1 byte) + prefix_len - orf_len = 8 + prefix_len - - elif pkt.orf_type == 65: - # Covering Prefix ORF - - if _orf_entry_afi == 1: - # IPv4 - # sequence (4 bytes) + min_len (1 byte) + max_len (1 byte) + # noqa: E501 - # rt (8 bytes) + import_rt (8 bytes) + route_type (1 byte) - orf_len = 23 + 4 - - elif _orf_entry_afi == 2: - # IPv6 - # sequence (4 bytes) + min_len (1 byte) + max_len (1 byte) + # noqa: E501 - # rt (8 bytes) + import_rt (8 bytes) + route_type (1 byte) - orf_len = 23 + 16 - - elif _orf_entry_afi == 25: - # sequence (4 bytes) + min_len (1 byte) + max_len (1 byte) + # noqa: E501 - # rt (8 bytes) + import_rt (8 bytes) - route_type = orb(remain[22]) - - if route_type == 2: - # MAC / IP Advertisement Route - orf_len = 23 + 6 - - else: - orf_len = 23 - - current = remain[:orf_len] - remain = remain[orf_len:] - packet = self.m2i(pkt, current) - lst.append(packet) - - return remain + ret, lst - - -class BGPORF(Packet): - """ - Provides an implementation of ORFs carried in the RR message. - References: RFC 5291 - """ - - name = "ORF" - fields_desc = [ - ByteEnumField("when_to_refresh", 0, _orf_when_to_refresh), - ByteEnumField("orf_type", 0, _orf_types), - FieldLenField("orf_len", None, length_of="entries", fmt="!H"), - BGPORFEntryPacketListField( - "entries", - [], - Packet, - length_from=lambda p: p.orf_len, - ) - ] - - -# RFC 7313 -# http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml#route-refresh-subcodes -rr_message_subtypes = { - 0: "Route-Refresh", - 1: "BoRR", - 2: "EoRR", - 255: "Reserved" -} - - -class BGPRouteRefresh(BGP): - """ - Provides an implementation of the ROUTE-REFRESH message. - References: RFC 2918, RFC 7313 - """ - - name = "ROUTE-REFRESH" - fields_desc = [ - ShortEnumField("afi", 1, address_family_identifiers), - ByteEnumField("subtype", 0, rr_message_subtypes), - ByteEnumField("safi", 1, subsequent_afis), - PacketField( - 'orf_data', - "", BGPORF, - lambda p: _update_orf_afi_safi(p.afi, p.safi) - ) - ] - - -# -# Layer bindings -# - -bind_layers(TCP, BGP, dport=179) -bind_layers(TCP, BGP, sport=179) -bind_layers(BGPHeader, BGPOpen, {"type": 1}) -bind_layers(BGPHeader, BGPUpdate, {"type": 2}) -bind_layers(BGPHeader, BGPNotification, {"type": 3}) -bind_layers(BGPHeader, BGPKeepAlive, {"type": 4}) -bind_layers(BGPHeader, BGPRouteRefresh, {"type": 5}) - -# When loading the module, display the current module configuration. -log_runtime.warning( - "[bgp.py] use_2_bytes_asn: %s", bgp_module_conf.use_2_bytes_asn) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/bier.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/bier.py deleted file mode 100644 index 1a0260cede..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/bier.py +++ /dev/null @@ -1,69 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = Bit Index Explicit Replication (BIER) -# scapy.contrib.status = loads - -from scapy.packet import Packet, bind_layers -from scapy.fields import BitEnumField, BitField, BitFieldLenField, ByteField, \ - ShortField, StrLenField -from scapy.layers.inet import IP, UDP -from scapy.layers.inet6 import IPv6 - - -class BIERLength: - BIER_LEN_64 = 0 - BIER_LEN_128 = 1 - BIER_LEN_256 = 2 - BIER_LEN_512 = 3 - BIER_LEN_1024 = 4 - - -BIERnhcls = {1: "MPLS", - 2: "MPLS", - 4: "IPv4", - 5: "IPv6"} - - -class BIFT(Packet): - name = "BIFT" - fields_desc = [BitField("bsl", BIERLength.BIER_LEN_256, 4), - BitField("sd", 0, 8), - BitField("set", 0, 8), - BitField("cos", 0, 3), - BitField("s", 1, 1), - ByteField("ttl", 0)] - - -class BIER(Packet): - name = "BIER" - fields_desc = [BitField("id", 5, 4), - BitField("version", 0, 4), - BitFieldLenField("length", BIERLength.BIER_LEN_256, 4, - length_of=lambda x:(x.BitString >> 8)), - BitField("entropy", 0, 20), - BitField("OAM", 0, 2), - BitField("RSV", 0, 2), - BitField("DSCP", 0, 6), - BitEnumField("Proto", 2, 6, BIERnhcls), - ShortField("BFRID", 0), - StrLenField("BitString", - "", - length_from=lambda x:(8 << x.length))] - - -bind_layers(BIER, IP, Proto=4) -bind_layers(BIER, IPv6, Proto=5) -bind_layers(UDP, BIFT, dport=8138) -bind_layers(BIFT, BIER) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/bp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/bp.py deleted file mode 100644 index ef09463dbc..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/bp.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -""" - Copyright 2012, The MITRE Corporation - - NOTICE - This software/technical data was produced for the U.S. Government - under Prime Contract No. NASA-03001 and JPL Contract No. 1295026 - and is subject to FAR 52.227-14 (6/87) Rights in Data General, - and Article GP-51, Rights in Data General, respectively. - This software is publicly released under MITRE case #12-3054 -""" - -# scapy.contrib.description = Bundle Protocol (BP) -# scapy.contrib.status = loads - -from scapy.packet import Packet, bind_layers -from scapy.fields import ByteEnumField, ByteField, ConditionalField, \ - StrLenField -from scapy.contrib.sdnv import SDNV2FieldLenField, SDNV2LenField, SDNV2 -from scapy.contrib.ltp import LTP, ltp_bind_payload - - -class BP(Packet): - name = "BP" - fields_desc = [ByteField('version', 0x06), - SDNV2('ProcFlags', 0), - SDNV2LenField('BlockLen', None), - SDNV2('DSO', 0), - SDNV2('DSSO', 0), - SDNV2('SSO', 0), - SDNV2('SSSO', 0), - SDNV2('RTSO', 0), - SDNV2('RTSSO', 0), - SDNV2('CSO', 0), - SDNV2('CSSO', 0), - SDNV2('CT', 0), - SDNV2('CTSN', 0), - SDNV2('LT', 0), - SDNV2('DL', 0), - ConditionalField(SDNV2("FO", 0), lambda x: ( - x.ProcFlags & 0x01)), - ConditionalField(SDNV2("ADUL", 0), lambda x: ( - x.ProcFlags & 0x01)), - ] - - def mysummary(self): - tmp = "BP(%version%) flags(" - if (self.ProcFlags & 0x01): - tmp += ' FR' - if (self.ProcFlags & 0x02): - tmp += ' AR' - if (self.ProcFlags & 0x04): - tmp += ' DF' - if (self.ProcFlags & 0x08): - tmp += ' CT' - if (self.ProcFlags & 0x10): - tmp += ' S' - if (self.ProcFlags & 0x20): - tmp += ' ACKME' - RAWCOS = (self.ProcFlags & 0x0180) - COS = RAWCOS >> 7 - cos_tmp = '' - if COS == 0x00: - cos_tmp += 'B ' - if COS == 0x01: - cos_tmp += 'N ' - if COS == 0x02: - cos_tmp += 'E ' - if COS & 0xFE000: - cos_tmp += 'SRR: (' - if COS & 0x02000: - cos_tmp += 'Rec ' - if COS & 0x04000: - cos_tmp += 'CA ' - if COS & 0x08000: - cos_tmp += 'FWD ' - if COS & 0x10000: - cos_tmp += 'DLV ' - if COS & 0x20000: - cos_tmp += 'DEL ' - if COS & 0xFE000: - cos_tmp += ') ' - - if cos_tmp: - tmp += ' Pr: ' + cos_tmp - - tmp += " ) len(%BlockLen%) " - if self.DL == 0: - tmp += "CBHE: d[%DSO%,%DSSO%] s[%SSO%, %SSSO%] r[%RTSO%, %RTSSO%] c[%CSO%, %CSSO%] " # noqa: E501 - else: - tmp += "dl[%DL%] " - tmp += "ct[%CT%] ctsn[%CTSN%] lt[%LT%] " - if (self.ProcFlags & 0x01): - tmp += "fo[%FO%] " - tmp += "tl[%ADUL%]" - - return self.sprintf(tmp), [LTP] - - -class BPBLOCK(Packet): - fields_desc = [ByteEnumField('Type', 1, {1: "Bundle payload block"}), - SDNV2('ProcFlags', 0), - SDNV2FieldLenField('BlockLen', None, length_of="load"), - StrLenField("load", "", - length_from=lambda pkt: pkt.BlockLen, - max_length=65535) - ] - - def mysummary(self): - return self.sprintf("BPBLOCK(%Type%) Flags: %ProcFlags% Len: %BlockLen%") # noqa: E501 - - -ltp_bind_payload(BP, lambda pkt: pkt.DATA_ClientServiceID == 1) -bind_layers(BP, BPBLOCK) -bind_layers(BPBLOCK, BPBLOCK) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/cansocket.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/cansocket.py deleted file mode 100644 index 3acc9037a4..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/cansocket.py +++ /dev/null @@ -1,42 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.description = CANSocket Utils -# scapy.contrib.status = loads - -""" -CANSocket. -""" - -from scapy.error import log_loading -from scapy.consts import LINUX -from scapy.config import conf -import scapy.modules.six as six - -PYTHON_CAN = False - -try: - if conf.contribs['CANSocket']['use-python-can']: - from can import BusABC as can_BusABC # noqa: F401 - PYTHON_CAN = True -except ImportError: - log_loading.info("Can't import python-can.") -except KeyError: - log_loading.info("Specify 'conf.contribs['CANSocket'] = " - "{'use-python-can': True}' to enable python-can.") - - -if PYTHON_CAN: - from scapy.contrib.cansocket_python_can import (CANSocket, # noqa: F401 - srcan, CAN_FRAME_SIZE, CAN_INV_FILTER) # noqa: E501 -elif LINUX and six.PY3: - log_loading.info("Use native CANSocket. Specify " - "'conf.contribs['CANSocket'] = " - "{'use-python-can': True}' to enable python-can.") - from scapy.contrib.cansocket_native import (CANSocket, # noqa: F401 - srcan, CAN_FRAME_SIZE, CAN_INV_FILTER) # noqa: E501 -else: - log_loading.info("No CAN support available. Install python-can or " - "use Linux and python3.") diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/cansocket_native.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/cansocket_native.py deleted file mode 100644 index bbac4f941f..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/cansocket_native.py +++ /dev/null @@ -1,119 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.description = Native CANSocket -# scapy.contrib.status = loads - -""" -Native CANSocket. -""" - -import struct -import socket -import time -from scapy.config import conf -from scapy.supersocket import SuperSocket -from scapy.error import Scapy_Exception, warning -from scapy.layers.can import CAN -from scapy.packet import Padding -from scapy.arch.linux import get_last_packet_timestamp - -conf.contribs['NativeCANSocket'] = {'iface': "can0"} - -CAN_FRAME_SIZE = 16 -CAN_INV_FILTER = 0x20000000 - - -class CANSocket(SuperSocket): - desc = "read/write packets at a given CAN interface using PF_CAN sockets" - nonblocking_socket = True - - def __init__(self, iface=None, receive_own_messages=False, - can_filters=None, remove_padding=True, basecls=CAN): - self.basecls = basecls - self.remove_padding = remove_padding - self.iface = conf.contribs['NativeCANSocket']['iface'] if \ - iface is None else iface - self.ins = socket.socket(socket.PF_CAN, - socket.SOCK_RAW, - socket.CAN_RAW) - try: - self.ins.setsockopt(socket.SOL_CAN_RAW, - socket.CAN_RAW_RECV_OWN_MSGS, - struct.pack("i", receive_own_messages)) - except Exception as exception: - Scapy_Exception("Could not modify receive own messages (%s)", - exception) - - if can_filters is None: - can_filters = [{ - "can_id": 0, - "can_mask": 0 - }] - - can_filter_fmt = "={}I".format(2 * len(can_filters)) - filter_data = [] - for can_filter in can_filters: - filter_data.append(can_filter["can_id"]) - filter_data.append(can_filter["can_mask"]) - - self.ins.setsockopt(socket.SOL_CAN_RAW, - socket.CAN_RAW_FILTER, - struct.pack(can_filter_fmt, *filter_data)) - - self.ins.bind((self.iface,)) - self.outs = self.ins - - def recv(self, x=CAN_FRAME_SIZE): - try: - pkt, sa_ll = self.ins.recvfrom(x) - except BlockingIOError: # noqa: F821 - warning("Captured no data, socket in non-blocking mode.") - return None - except socket.timeout: - warning("Captured no data, socket read timed out.") - return None - except OSError: - # something bad happened (e.g. the interface went down) - warning("Captured no data.") - return None - - # need to change the byte order of the first four bytes, - # required by the underlying Linux SocketCAN frame format - pkt = struct.pack("I12s", pkt)) - len = pkt[4] - canpkt = self.basecls(pkt[:len + 8]) - canpkt.time = get_last_packet_timestamp(self.ins) - if self.remove_padding: - return canpkt - else: - return canpkt / Padding(pkt[len + 8:]) - - def send(self, x): - try: - if hasattr(x, "sent_time"): - x.sent_time = time.time() - - # need to change the byte order of the first four bytes, - # required by the underlying Linux SocketCAN frame format - bs = bytes(x) - bs = bs + b'\x00' * (CAN_FRAME_SIZE - len(bs)) - bs = struct.pack("I12s", bs)) - return SuperSocket.send(self, bs) - except socket.error as msg: - raise msg - - def close(self): - self.ins.close() - - -@conf.commands.register -def srcan(pkt, iface=None, receive_own_messages=False, - canfilter=None, basecls=CAN, *args, **kargs): - s = CANSocket(iface, receive_own_messages=receive_own_messages, - can_filters=canfilter, basecls=basecls) - a, b = s.sr(pkt, *args, **kargs) - s.close() - return a, b diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/cansocket_python_can.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/cansocket_python_can.py deleted file mode 100644 index d9e31b4cef..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/cansocket_python_can.py +++ /dev/null @@ -1,92 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -# scapy.contrib.description = Python-Can CANSocket -# scapy.contrib.status = loads - -""" -Python-CAN CANSocket Wrapper. -""" - -import time -import struct -from scapy.config import conf -from scapy.supersocket import SuperSocket -from scapy.error import warning -from scapy.layers.can import CAN -from can import BusABC as can_BusABC -from can import Message as can_Message -from can import CanError as can_Error - -CAN_FRAME_SIZE = 16 -CAN_INV_FILTER = 0x20000000 - - -class CANSocket(SuperSocket): - nonblocking_socket = True - desc = "read/write packets at a given CAN interface " \ - "using a python-can bus object" - - def __init__(self, iface=None, timeout=1.0, basecls=CAN): - - if issubclass(type(iface), can_BusABC): - self.basecls = basecls - self.iface = iface - self.ins = None - self.outs = None - self.timeout = timeout - else: - warning("Provide a python-can interface") - - def recv_raw(self, x=0xffff): - msg = self.iface.recv(timeout=self.timeout) - if msg is None: - return None, None, None - hdr = msg.is_extended_id << 31 | msg.is_remote_frame << 30 | \ - msg.is_error_frame << 29 | msg.arbitration_id - - if conf.contribs['CAN']['swap-bytes']: - hdr = struct.unpack("I", hdr))[0] - - dlc = msg.dlc << 24 - pkt_data = struct.pack("!II", hdr, dlc) + bytes(msg.data) - return self.basecls, pkt_data, msg.timestamp - - def send(self, x): - try: - msg = can_Message(is_remote_frame=x.flags == 0x2, - extended_id=x.flags == 0x4, - is_error_frame=x.flags == 0x1, - arbitration_id=x.identifier, - dlc=x.length, - data=bytes(x)[8:]) - if hasattr(x, "sent_time"): - x.sent_time = time.time() - return self.iface.send(msg) - except can_Error as ex: - raise ex - - @staticmethod - def select(sockets, remain=None): - """This function is called during sendrecv() routine to select - the available sockets. - """ - if remain is not None: - max_timeout = remain / len(sockets) - for s in sockets: - if s.timeout > max_timeout: - s.timeout = max_timeout - - # python-can sockets aren't selectable, so we return all of them - # sockets, None (means use the socket's recv() ) - return sockets, None - - -@conf.commands.register -def srcan(pkt, iface=None, basecls=CAN, *args, **kargs): - s = CANSocket(iface, basecls=basecls) - a, b = s.sr(pkt, *args, **kargs) - s.close() - return a, b diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/capwap.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/capwap.py deleted file mode 100755 index c5fb62b852..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/capwap.py +++ /dev/null @@ -1,1102 +0,0 @@ -import sys, os -from scapy.all import * -from scapy.layers.dot11 import * -import hashlib - -# TRex Change - -####################### -# Based on RFC 5415 -####################### - -############################### Global CAPWAP structure ############################## -# -# CAPWAP Control Packet (Discovery Request/Response): -# +-------------------------------------------+ -# | IP | UDP | CAPWAP | Control | Message | -# | Hdr | Hdr | Header | Header | Element(s) | -# +-------------------------------------------+ -# -# CAPWAP Control Packet (DTLS Security Required): -# +------------------------------------------------------------------+ -# | IP | UDP | CAPWAP | DTLS | CAPWAP | Control| Message | DTLS | -# | Hdr | Hdr | DTLS Hdr | Hdr | Header | Header | Element(s)| Trlr | -# +------------------------------------------------------------------+ -# \---------- authenticated -----------/ -# \------------- encrypted ------------/ -# -###################################################################################### - -################################# CAPWAP Header ###################################### -# -# 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 -# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -# |CAPWAP Preamble| HLEN | RID | WBID |T|F|L|W|M|K|Flags| -# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -# | Fragment ID | Frag Offset |Rsvd | -# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -# | (optional) Radio MAC Address | -# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -# | (optional) Wireless Specific Information | -# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -# | Payload .... | -# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -# -###################################################################################### - -def warn(msg): - warning('CAPWAP error: %s' % msg) - - -#################### Defines ################## - -capwap_header_types = {0: 'CAPWAP Header', 1: 'CAPWAP DTLS Header'} -capwap_wbid_types = {0: 'Reserved', 1: 'IEEE 802.11', 2: 'Reserved', 3: 'EPCGlobal'} -capwap_mac_radio_sizes = {6: 'EUI-48 MAC', 8: 'EUI-64 MAC'} -capwap_mac_types = {0: 'Local MAC', 1: 'Split MAC', 2: 'Both'} -capwap_wtp_descriptor_types = { - 0: 'Hardware Version', - 1: 'Active Software Version', - 2: 'Boot Version', - 3: 'Other Software Version' - } -capwap_board_data_types = { - 0: 'WTP Model Number', - 1: 'WTP Serial Number', - 2: 'Board ID', - 3: 'Board Revision', - 4: 'Base MAC Address' - } -capwap_discovery_types = { - 0: 'Unknown', - 1: 'Static Configuration', - 2: 'DHCP', - 3: 'DNS', - 4: 'AC Referral' - } -capwap_ecn_supports = {0: 'Limited', 1: 'Full and Limited'} -capwap_reserved_enabled_disabled = {0: 'Reserved', 1: 'Enabled', 2: 'Disabled'} -capwap_op_state_reserved_enabled_disabled = {0: 'Reserved', 2: 'Enabled', 1: 'Disabled'} -capwap_radio_mac_address_field = {0: 'Reserved', 1: 'Supported', 2: 'Not Supported'} -capwap_ac_information_types = {4: 'Hardware Version', 5: 'Software Version'} -capwap_ap_modes = { - 0: 'Local', - 1: 'Monitor', - 2: 'Remote', - 3: 'Rogue_detector', - 4: 'Sniffer', - 5: 'Bridge', - 6: 'Seconnect', - 7: 'Remote Bridge', - 8: 'Hybrid Remote', - 9: 'Sensor' -} -capwap_draft8_tunnel_modes = { - 1: 'Local Bridging', - 2: '802.3 Frame Tunnel Mode', - 4: 'Native Frame Tunnel Mode', - 7: 'All', - } -capwap_state_cause = { - 0: 'Normal', - 1: 'Radio Failure', - 2: 'Software Failure', - 3: 'Administratively Set', - } -capwap_reboot_statistics_last_failures = { - 0: 'Not Supported', - 1: 'AC Initiated', - 2: 'Link Failure', - 3: 'Software Failure', - 4: 'Hardware Failure', - 5: 'Other Failure', - 255: 'Unknown', - } -capwap_result_codes = { - 0: 'Success', - 1: 'Failure (AC List Message Element MUST Be Present)', - 2: 'Success (NAT Detected)', - 3: 'Join Failure (Unspecified)', - 4: 'Join Failure (Resource Depletion)', - 5: 'Join Failure (Unknown Source)', - 6: 'Join Failure (Incorrect Data)', - 7: 'Join Failure (Session ID Already in Use)', - 8: 'Join Failure (WTP Hardware Not Supported)', - 9: 'Join Failure (Binding Not Supported)', - 10: 'Reset Failure (Unable to Reset)', - 11: 'Reset Failure (Firmware Write Error)', - 12: 'Configuration Failure (Unable to Apply Requested Configuration - Service Provided Anyhow)', - 13: 'Configuration Failure (Unable to Apply Requested Configuration - Service Not Provided)', - 14: 'Image Data Error (Invalid Checksum)', - 15: 'Image Data Error (Invalid Data Length)', - 16: 'Image Data Error (Other Error)', - 17: 'Image Data Error (Image Already Present)', - 18: 'Message Unexpected (Invalid in Current State)', - 19: 'Message Unexpected (Unrecognized Request)', - 20: 'Failure - Missing Mandatory Message Element', - 21: 'Failure - Unrecognized Message Element', - 22: 'Data Transfer Error (No Information to Transfer)' - } - -capwap_message_elements_types = { - # CAPWAP Protocol Message Elements 1 - 1023 - 0: 'Unknown (0)', - 1: 'AC Descriptor', - 2: 'AC IPv4 List', - 3: 'AC IPv6 List', - 4: 'AC Name', - 5: 'AC Name with Priority', - 6: 'AC Timestamp', - 7: 'Add MAC ACL Entry', - 8: 'Add Station', - 9: '9 (Reserved)', - 10: 'CAPWAP Control IPV4 Address', - 11: 'CAPWAP Control IPV6 Address', - 30: 'CAPWAP Local IPV4 Address', - 50: 'CAPWAP Local IPV6 Address', - 12: 'CAPWAP Timers', - 51: 'CAPWAP Transport Protocol', - 13: 'Data Transfer Data', - 14: 'Data Transfer Mode', - 15: 'Decryption Error Report', - 16: 'Decryption Error Report Period', - 17: 'Delete MAC ACL Entry', - 18: 'Delete Station', - 19: '19 (Reserved)', - 20: 'Discovery Type', - 21: 'Duplicate IPv4 Address', - 22: 'Duplicate IPv6 Address', - 53: 'ECN Support', - 23: 'Idle Timeout', - 24: 'Image Data', - 25: 'Image Identifier', - 26: 'Image Information', - 27: 'Initiate Download', - 28: 'Location Data', - 29: 'Maximum Message Length', - 31: 'Radio Administrative State', - 32: 'Radio Operational State', - 33: 'Result Code', - 34: 'Returned Message Element', - 35: 'Session ID', - 36: 'Statistics Timer', - 37: 'Vendor Specific Payload', - 38: 'WTP Board Data', - 39: 'WTP Descriptor', - 40: 'WTP Fallback', - 41: 'WTP Frame Tunnel Mode', - 42: 'WTP IPv4 IP Address', # draft8 - 43: 'WTP IPv6 IP Address', # draft8 - 44: 'WTP MAC Type', - 45: 'WTP Name', - 46: '46 (Unused/Reserved)', - 47: 'WTP Radio Statistics', - 48: 'WTP Reboot Statistics', - 49: 'WTP Static IP Address Information', - 52: 'MTU Discovery Padding', - # IEEE 802.11 Message Elements 1024 - 2047 - 1024: 'IEEE 802.11 Add WLAN', - 1025: 'IEEE 802.11 Antenna', - 1026: 'IEEE 802.11 Assigned WTP BSSID', - 1027: 'IEEE 802.11 Delete WLAN', - 1028: 'IEEE 802.11 Direct Sequence Control', - 1029: 'IEEE 802.11 Information Element', - 1030: 'IEEE 802.11 MAC Operation', - 1031: 'IEEE 802.11 MIC Countermeasures', - 1032: 'IEEE 802.11 Multi-Domain Capability', - 1033: 'IEEE 802.11 OFDM Control', - 1034: 'IEEE 802.11 Rate Set', - 1035: 'IEEE 802.11 RSNA Error Report From Station', - 1036: 'IEEE 802.11 Station', - 1037: 'IEEE 802.11 Station QoS Profile', - 1038: 'IEEE 802.11 Station Session Key', - 1039: 'IEEE 802.11 Statistics', - 1040: 'IEEE 802.11 Supported Rates', - 1041: 'IEEE 802.11 Tx Power', - 1042: 'IEEE 802.11 Tx Power Level', - 1043: 'IEEE 802.11 Update Station QoS', - 1044: 'IEEE 802.11 Update WLAN', - 1045: 'IEEE 802.11 WTP Quality of Service', - 1046: 'IEEE 802.11 WTP Radio Configuration', - 1047: 'IEEE 802.11 WTP Radio Fail Alarm Indication', - 1048: 'IEEE 802.11 WTP Radio Information', - #Reserved for Future Use 2048 - 3071 - #EPCGlobal Message Elements 3072 - 4095 - #Reserved for Future Use 4096 - 65535 - } - -capwap_control_message_types = { - 0: 'Unknown', - 1: 'Discovery Request', - 2: 'Discovery Response', - 3: 'Join Request', - 4: 'Join Response', - 5: 'Configuration Status Request', - 6: 'Configuration Status Response', - 7: 'Configuration Update Request', - 8: 'Configuration Update Response', - 9: 'WTP Event Request', - 10: 'WTP Event Response', - 11: 'Change State Event Request', - 12: 'Change State Event Response', - 13: 'Echo Request', - 14: 'Echo Response', - 15: 'Image Data Request', - 16: 'Image Data Response', - 17: 'Reset Request', - 18: 'Reset Response', - 19: 'Primary Discovery Request', - 20: 'Primary Discovery Response', - 21: 'Data Transfer Request', - 22: 'Data Transfer Response', - 23: 'Clear Configuration Request', - 24: 'Clear Configuration Response', - 25: 'Station Configuration Request', - 26: 'Station Configuration Response', - } - -#################### Fields ################### - -class IEEE80211RateSetField(StrLenField): - def i2h(self, pkt, x): - return ', '.join(['%gMb/s' % (c * 0.5) for c in map(ord, sorted(x))]) - - -#################### Classes ################### - -# Dot11 over CAPWAP has FC bytes swapped -class Dot11_swapped(Dot11): - fields_desc = [ - FlagsField('FCfield', 0, 8, ['to-DS', 'from-DS', 'MF', 'retry', 'pw-mgt', 'MD', 'wep', 'order']), - BitField('subtype', 0, 4), - BitEnumField('type', 0, 2, ['Management', 'Control', 'Data', 'Reserved']), - BitField('proto', 0, 2), - ShortField('ID',0), - MACField('addr1', ETHER_ANY), - ConditionalField( - MACField("addr2", ETHER_ANY), - lambda pkt: (pkt.type != 1 or - pkt.subtype in [0x8, 0x9, 0xa, 0xb, 0xe, 0xf]), - ), - ConditionalField( - MACField("addr3", ETHER_ANY), - lambda pkt: pkt.type in [0, 2], - ), - ConditionalField(LEShortField("SC", 0), lambda pkt: pkt.type != 1), - ConditionalField( - MACField("addr4", ETHER_ANY), - lambda pkt: (pkt.type == 2 and - pkt.FCfield & 3 == 3), # from-DS+to-DS - ) - ] - - -# Dummy -class DTLS(Raw): - name = 'DTLS stub' - - -# extra data is payload -class Layer(Packet): - def extract_padding(self, s): - if type(s) is tuple: - raise Exception('Packet size is not whole number of bytes!') - return s, None - - -# extra data is inner-fields -class Container(Packet): - def extract_padding(self, s): - if type(s) is tuple: - raise Exception('Packet size is not whole number of bytes!') - return None, s - - -class CAPWAP_Radio_MAC(Container): - name = 'Radio MAC' - fields_desc = [ ByteEnumField('length', 6, capwap_mac_radio_sizes), - MACField('mac_address', '12:12:12:12:12:12'), - XByteField('padding', 0), - ] - - -class CAPWAP_Wireless_Specific_Information(Container): - name = 'Wireless Specific Information (General)' - fields_desc = [ ByteField('length', 6), - StrLenField('data', '', length_from = lambda pkt:pkt.length), - StrLenField('padding', '', length_from = lambda pkt: (3 - pkt.length) % 4) ] - - def post_dissect(self, s): - if self.length != len(self.data): - warn('%s: length is %s, size of data: %s' % (self.name, self.length, len(self.data))) - return s - - -class CAPWAP_Wireless_Specific_Information_IEEE802_11(Container): - name = 'Wireless Specific Information (IEEE 802.11)' - fields_desc = [ ByteField('length', 4), - ByteField('rssi', 0), - ByteField('snr', 0), - ShortField('data_rate', 0), # multiplier of 0.1 Mbps - X3BytesField('padding', 0), - ] - - -# CAPWAP ME sub-fields - -class CAPWAP_Encryption_Sub_Element(Container): - name = 'Encryption Sub-Element' - fields_desc = [ BitField('reserved', 0, 3), - BitEnumField('wbid', 0, 5, capwap_wbid_types), - BitField('encryption_capabilities', 0, 16) ] - - def post_dissect(self, s): - if self.reserved: - warn('%s: reserved field should be zero according to RFC' % self.name) - return s - - -class CAPWAP_Descriptor_Sub_Element(Container): - name = 'Descriptor Sub-Element' - fields_desc = [ IntField('descriptor_vendor_identifier', 0), - ShortEnumField('descriptor_type', 0, capwap_wtp_descriptor_types), - BitFieldLenField('descriptor_length', None, 16, length_of = 'descriptor_data'), - StrLenField('descriptor_data', '', length_from = lambda p: p.descriptor_length), - ] - - def post_dissect(self, s): - if self.descriptor_length > 1024: - warn('%s: descriptor_length field should not exceed 1024 (got %s) according to RFC' % (self.name, self.descriptor_length)) - if self.descriptor_length != len(self.descriptor_data): - warn('%s: descriptor_length value %s mismatches size of descriptor_data %s!' % (self.name, self.descriptor_length, len(self.descriptor_data))) - return s - - -class CAPWAP_AC_Information_Sub_Element(Container): - name = 'AC Information Sub-Element' - fields_desc = [ IntField('ac_information_vendor_identifier', 0), - ShortEnumField('ac_information_type', 0, capwap_ac_information_types), - ShortField('ac_information_length', 0), - StrLenField('ac_information_data', '', length_from = lambda p: p.ac_information_length), - ] - - def post_dissect(self, s): - if self.ac_information_length > 1024: - warn('%s: ac_information_length field should not exceed 1024 (got %s) according to RFC' % (self.name, self.ac_information_length)) - if self.ac_information_length != len(self.ac_information_data): - warn('%s: ac_information_length value %s mismatches size of ac_information_data %s!' % (self.name, self.ac_information_length, len(self.ac_information_data))) - return s - - -class CAPWAP_Board_Data_Sub_Element(Container): - name = 'Board Data Sub-Element' - fields_desc = [ ShortEnumField('board_data_type', 0, capwap_board_data_types), - BitFieldLenField('board_data_length', None, 16, length_of = 'board_data_value'), - StrLenField('board_data_value', '', length_from = lambda p: p.board_data_length), - ] - - def post_dissect(self, s): - if self.board_data_length > 1024: - warn('%s: board_data_length field should not exceed 1024 (got %s) according to RFC' % (self.name, self.board_data_length)) - if self.board_data_length != len(self.board_data_value): - warn('%s: board_data_length value %s mismatches size of board_data_value %s!' % (self.name, self.board_data_length, len(self.board_data_value))) - return s - - -class _CAPWAP_ME_HDR(Container): - fields_desc = [ ShortEnumField('type', None, capwap_message_elements_types), - ShortField('length', None) ] - - -class CAPWAP_ME(Container): - type = 'Unknown' - ignore_msg_types = [1022] - def __init__(self, *a, **k): - Container.__init__(self, *a, **k) - name_by_type = capwap_message_elements_types.get(self.type, 'Unknown') - if self.__class__ == CAPWAP_ME: - self.name = 'Message element - Not implemented (raw)' - if self.type not in self.ignore_msg_types: - if 'Reserved' in name_by_type: - warn('Usage of reserved Message element type %s (%s)' % (self.type, name_by_type)) - else: - warn('Not implemented Message element %s (%s).' % (self.type, name_by_type)) - elif self.type == 37: - if self.__class__ == CAPWAP_ME_Vendor_Specific_Payload: - self.name = 'Message element - Vendor Specific Payload (raw)' - else: - self.name = 'Message element - Vendor Specific Payload - %s' % capwap_vendor_specific_payload_names.get(self.element_id, 'raw') - else: - self.name = 'Message element - %s' % name_by_type - - fields_desc = [ _CAPWAP_ME_HDR, - StrLenField('raw', '', length_from = lambda pkt: pkt.length)] - - def post_dissect(self, s): - data_len = self._length - 4 - if self.length != data_len: - msg = 'Message element - %s: length is %s, size of data: %s' % ( - capwap_message_elements_types.get(self.type, 'Code %s' % self.type), - self.length, data_len) - #raise Exception(msg) - warn(msg) - return s - - def post_build(self, pkt, pay): - l = self.length - if l is None: - l = len(pkt) - 4 - elif l != len(pkt) - 4: - warn('Length in %s (%s) does not match size of data (%s)' % (self.name, l, len(pkt) - 4)) - return int2str(self.type, 2) + int2str(l, 2) + pkt[4:] + pay - - _registered_me_types = {} - _registered_vendor_specific_payloads = {} - @classmethod - def register_variant(cls): - assert hasattr(cls, 'type'), 'ME should have type' - cls._registered_me_types[cls.type.default] = cls - if cls.type.default == 37: - assert hasattr(cls, 'element_id'), 'ME Vendor Specific Payload should have element_id' - cls._registered_vendor_specific_payloads[cls.element_id.default] = cls - - @classmethod - def dispatch_hook(cls, pkt=None, *a, **k): - if pkt and len(pkt) >= 4: - me_type = str2int(pkt[:2]) - me_len = str2int(pkt[2:4]) - if me_type in cls._registered_me_types: - if me_type == 35 and me_len == 4: - return CAPWAP_ME_Session_ID_draft8 - if me_type == 37: - try: - element_id = str2int(pkt[8:10]) - return cls._registered_vendor_specific_payloads[element_id] - except Exception as e: - return CAPWAP_ME_Vendor_Specific_Payload - if me_type == 39 and len(pkt) > 6 and ord(pkt[6:7]) == 0: - return CAPWAP_ME_WTP_Descriptor_draft8 - return cls._registered_me_types[me_type] - elif me_type not in cls.ignore_msg_types: - warn('Got Message element type %s which is not supported' % me_type) - return cls - - -class CAPWAP_ME_AC_Descriptor(CAPWAP_ME): - type = 1 - fields_desc = [ _CAPWAP_ME_HDR, - ShortField('stations', 0), - ShortField('limit', 0), - ShortField('active_wtps', 0), - ShortField('max_wtps', 0), - BitField('reserved1', 0, 5), - FlagsField('authentication_credential_flags', 0, 3, ['Reserved', 'X.509 Certificate', 'Pre-shared secret']), - ByteEnumField('r_mac_field', 0, capwap_radio_mac_address_field), - BitField('reserved2', 0, 13), - FlagsField('dtls_policy_flags', 0, 3, ['Reserved', 'Clear Text Data Channel Supported', 'DTLS-Enabled Data Channel Supported']), - PacketListField('ac_information_sub_element', [], CAPWAP_AC_Information_Sub_Element, length_from = lambda p:p.length - 12), - ] - - def post_dissect(self, s): - CAPWAP_ME.post_dissect(self, s) - if self.length < 12: - warn('%s: length should be at least 12 (got %s) according to RFC' % (self.name, self.length)) - return s - - -class CAPWAP_ME_AC_IPv4_List(CAPWAP_ME): - type = 2 - fields_desc = [ _CAPWAP_ME_HDR, - FieldListField('ap_ip_address', [], IPField('', '0.0.0.0'), length_from = lambda pkt: pkt.length), - ] - - def post_dissect(self, s): - CAPWAP_ME.post_dissect(self, s) - if self.length > 1024: - warn('%s: length should be at most 1024 (got %s) according to RFC' % (self.name, self.length)) - if self.length % 4: - warn('%s: length should be whole multiplier of 4 (got %s)' % (self.name, self.length)) - return s - - -class CAPWAP_ME_AC_IPv6_List(CAPWAP_ME): - type = 3 - fields_desc = [ _CAPWAP_ME_HDR, - FieldListField('ap_ip_address', [], IP6Field('', '::1'), length_from = lambda pkt: pkt.length), - ] - - def post_dissect(self, s): - CAPWAP_ME.post_dissect(self, s) - if self.length > 1024: - warn('%s: length should be at most 1024 (got %s) according to RFC' % (self.name, self.length)) - if self.length % 16: - warn('%s: length should be whole multiplier of 16 (got %s)' % (self.name, self.length)) - return s - - -class CAPWAP_ME_AC_Name(CAPWAP_ME): - type = 4 - fields_desc = [ _CAPWAP_ME_HDR, - UTF8LenField('ac_name', '', length_from = lambda pkt: pkt.length), - ] - - def post_dissect(self, s): - CAPWAP_ME.post_dissect(self, s) - if self.length < 1: - warn('%s: length should be at least 1 (got %s) according to RFC' % (self.name, self.length)) - return s - - -class CAPWAP_ME_Add_Station(CAPWAP_ME): - type = 8 - fields_desc = [ _CAPWAP_ME_HDR, - ByteField('radio_id', 0), - ByteEnumField('mac_length', 6, capwap_mac_radio_sizes), - MACField('mac_address', '12:12:12:12:12:12'), - UTF8LenField('vlan_name', '', length_from = lambda pkt:pkt.length - 8), - ] - - def post_dissect(self, s): - CAPWAP_ME.post_dissect(self, s) - if self.length < 8: - warn('%s: length should be at least 8 (got %s) according to RFC' % (self.name, self.length)) - return s - - -class CAPWAP_ME_CAPWAP_Control_IPv4_Address(CAPWAP_ME): - type = 10 - fields_desc = [ _CAPWAP_ME_HDR, - IPField('ip_address', '0.0.0.0'), - ShortField('wtp_count', 0), - ] - - -class CAPWAP_ME_CAPWAP_Timers(CAPWAP_ME): - type = 12 - fields_desc = [ _CAPWAP_ME_HDR, - ByteField('discovery', 0), - ByteField('echo_request', 0), - ] - - -class CAPWAP_ME_Decryption_Error_Report_Period(CAPWAP_ME): - type = 16 - fields_desc = [ _CAPWAP_ME_HDR, - ByteField('radio_id', 0), - ShortField('report_interval', 0), - ] - - -class CAPWAP_ME_Delete_Station(CAPWAP_ME): - type = 18 - fields_desc = [ _CAPWAP_ME_HDR, - ByteField('radio_id', 0), - ByteEnumField('mac_length', 6, capwap_mac_radio_sizes), - MACField('mac_address', '12:12:12:12:12:12'), - ] - - def post_dissect(self, s): - CAPWAP_ME.post_dissect(self, s) - if self.length < 8: - warn('%s: length should be at least 8 (got %s) according to RFC' % (self.name, self.length)) - return s - - -class CAPWAP_ME_Discovery_Type(CAPWAP_ME): - type = 20 - fields_desc = [ _CAPWAP_ME_HDR, - ByteEnumField('discovery_type', 0, capwap_discovery_types), - ] - - -class CAPWAP_ME_Idle_Timeout(CAPWAP_ME): - type = 23 - fields_desc = [ _CAPWAP_ME_HDR, - IntField('timeout', 0), - ] - - -class CAPWAP_ME_Image_Identifier(CAPWAP_ME): - type = 25 - fields_desc = [ _CAPWAP_ME_HDR, - IntField('vendor_identifier', 0), - UTF8LenField('data', '', length_from = lambda pkt: pkt.length - 4) - ] - - -class CAPWAP_ME_Location_Data(CAPWAP_ME): - type = 28 - fields_desc = [ _CAPWAP_ME_HDR, - UTF8LenField('location', '', length_from = lambda pkt: pkt.length) - ] - - -class CAPWAP_ME_Maximum_Message_Length(CAPWAP_ME): - type = 29 - fields_desc = [ _CAPWAP_ME_HDR, - ShortField('maximum_message_length', 0) - ] - - -class CAPWAP_ME_Local_IPv4_Address(CAPWAP_ME): - type = 30 - fields_desc = [ _CAPWAP_ME_HDR, - IPField('ip_address', '0.0.0.0') - ] - - -class CAPWAP_ME_Radio_Administrative_State(CAPWAP_ME): - type = 31 - fields_desc = [ _CAPWAP_ME_HDR, - ByteField('radio_id', 0), - ByteEnumField('admin_state', 0, capwap_reserved_enabled_disabled), - ] - - -class CAPWAP_ME_Radio_Operational_State(CAPWAP_ME): - type = 32 - fields_desc = [ _CAPWAP_ME_HDR, - ByteField('radio_id', 0), - ByteEnumField('state', 0, capwap_op_state_reserved_enabled_disabled), - ByteEnumField('cause', 0, capwap_state_cause), - ] - - -class CAPWAP_ME_Result_Code(CAPWAP_ME): - type = 33 - fields_desc = [ _CAPWAP_ME_HDR, - BitEnumField('result_code', 0, 32, capwap_result_codes), - ] - - -# Cisco uses in some cases draft8 version of this header https://tools.ietf.org/html/draft-ietf-capwap-protocol-specification-08 -class CAPWAP_ME_Session_ID_draft8(CAPWAP_ME): - type = 35 - fields_desc = [ _CAPWAP_ME_HDR, - IntField('session_id', 0) ] - - #def post_dissect(self, s): - # CAPWAP_ME.post_dissect(self, s) - # if self.length != 4: - # warn('%s: length should be exactly 4 (got %s) according to RFC draft8' % (self.name, self.length)) - # return s - - -class CAPWAP_ME_Session_ID(CAPWAP_ME): - type = 35 - fields_desc = [ _CAPWAP_ME_HDR, - BitField('session_id', 0, 128) ] - - #def post_dissect(self, s): - # CAPWAP_ME.post_dissect(self, s) - # if self.length != 16: - # warn('%s: length should be exactly 16 (got %s) according to RFC' % (self.name, self.length)) - # return s - - -class CAPWAP_ME_Statistics_Timer(CAPWAP_ME): - type = 36 - fields_desc = [ _CAPWAP_ME_HDR, - ShortField('statistics_timer', 120) ] - - -def check_file(path): - if path and os.path.isfile(path): - return True - return False - - -def get_capwap_privkey_path(): - priv_key_file = os.getenv('CAPWAP_PRIVKEY') - if check_file(priv_key_file): - return priv_key_file - priv_key_file = os.path.join(os.getenv('HOME'), 'capwap_keys', 'privatekey.pem') - if check_file(priv_key_file): - return priv_key_file - raise Exception('Either put privatekey.pem into $HOME/capwap_keys/, or define full path to file via CAPWAP_PRIVKEY envvar.') - - -def get_capwap_internal(): - # Check if we have the decoded one already - current_dir = os.path.dirname(__file__) - encrypted_file = os.path.join(current_dir, 'capwap_internal.enc') - non_encrypted_file = os.path.join(current_dir, 'capwap_internal.py') - if os.path.isfile(non_encrypted_file): - with open(non_encrypted_file) as f: - return compile(f.read(), non_encrypted_file, 'exec') - else: - with open(encrypted_file, 'rb') as f: - file_cont = f.read() - decrypted_file = '/tmp/%s.py' % hashlib.sha256(file_cont).hexdigest() - if not os.path.isfile(decrypted_file): - priv_key_file = get_capwap_privkey_path() - ret = os.system('openssl smime -decrypt -in %s -binary -inform DEM -inkey %s -out %s' % (encrypted_file, priv_key_file, decrypted_file)) - if ret: - raise Exception('Decryption of capwap_internal failed with error code: %s' % ret) - with open(decrypted_file) as f: - file_cont = compile(f.read(), decrypted_file, 'exec') - return file_cont - -try: - exec(get_capwap_internal()) -except Exception as e: - import traceback - traceback.print_exc() - capwap_vendor_specific_payload_names = {} - warn('Could not load custom Vendor Specific Payloads, will use raw. %s' % e) - - -class CAPWAP_ME_Vendor_Specific_Payload(CAPWAP_ME): - type = 37 - fields_desc = [ _CAPWAP_ME_HDR, - IntField('vendor_identifier', 0), - ShortEnumField('element_id', 0, capwap_vendor_specific_payload_names), - StrLenField('data', '', length_from = lambda pkt: pkt.length - 6) ] - - def post_dissect(self, s): - if self.length < 7: - warn('%s: length should be at least 7 (got %s) according to RFC' % (self.name, self.length)) - return s - - -class CAPWAP_ME_WTP_Board_Data(CAPWAP_ME): - type = 38 - fields_desc = [ _CAPWAP_ME_HDR, - IntField('vendor_identifier', 0), - PacketListField('board_data_sub_element', [], CAPWAP_Board_Data_Sub_Element, length_from = lambda p:p.length - 4), - ] - - def post_dissect(self, s): - CAPWAP_ME.post_dissect(self, s) - if self.length < 14: - warn('%s: length should be at least 14 according to RFC' % self.name) - types_present = [False] * 2 - for d in self.board_data_sub_element: - if d.board_data_type < 2: - types_present[d.board_data_type] = True - for i in range(2): - if not types_present[i]: - warn('%s: %s must be present according to RFC' % (self.name, capwap_board_data_types[i])) - return s - - -# Cisco uses in some cases draft8 version of this header https://tools.ietf.org/html/draft-ietf-capwap-protocol-specification-08 -class CAPWAP_ME_WTP_Descriptor_draft8(CAPWAP_ME): - type = 39 - fields_desc = [ _CAPWAP_ME_HDR, - ByteField('max_radios', 1), - ByteField('radios_in_use', 1), - BitField('encryption_capabilities', 0, 16), - PacketListField('descriptor_sub_element', [], CAPWAP_Descriptor_Sub_Element, length_from = lambda p:p.length - 4), - ] - - def post_dissect(self, s): - CAPWAP_ME.post_dissect(self, s) - if self.length < 31: - warn('%s: length should be at least 33 according to RFC' % self.name) - versions_present = [False] * 3 - for d in self.descriptor_sub_element: - if d.descriptor_type < 3: - versions_present[d.descriptor_type] = True - for i in range(3): - if not versions_present[i]: - warn('%s: %s must be present according to RFC' % (self.name, capwap_wtp_descriptor_types[i])) - return s - - -class CAPWAP_ME_WTP_Descriptor(CAPWAP_ME): - type = 39 - fields_desc = [ _CAPWAP_ME_HDR, - ByteField('max_radios', 1), - ByteField('radios_in_use', 1), - BitFieldLenField('num_encrypt', None, 8, count_of = 'encryption_sub_element'), - PacketListField('encryption_sub_element', [], CAPWAP_Encryption_Sub_Element, count_from = lambda p:p.num_encrypt), - PacketListField('descriptor_sub_element', [], CAPWAP_Descriptor_Sub_Element, length_from = lambda p:p.length - 3 - sum(map(len, p.encryption_sub_element))), - ] - - def post_dissect(self, s): - CAPWAP_ME.post_dissect(self, s) - if not self.num_encrypt: - warn('%s: num_encrypt should be positive according to RFC' % self.name) - if self.length < 33: - warn('%s: length should be at least 33 according to RFC' % self.name) - versions_present = [False] * 3 - for d in self.descriptor_sub_element: - if d.descriptor_type < 3: - versions_present[d.descriptor_type] = True - for i in range(3): - if not versions_present[i]: - warn('%s: %s must be present according to RFC' % (self.name, capwap_wtp_descriptor_types[i])) - return s - - -class CAPWAP_ME_WTP_Fallback(CAPWAP_ME): - type = 40 - fields_desc = [ _CAPWAP_ME_HDR, - ByteEnumField('mode', 0, capwap_reserved_enabled_disabled) ] - - -class CAPWAP_ME_WTP_Frame_Tunnel_Mode_draft8(CAPWAP_ME): - type = 41 - fields_desc = [ _CAPWAP_ME_HDR, - ByteEnumField('tunnel_mode', 4, capwap_draft8_tunnel_modes) - ] - -# I have no idea how to distinguish which of them is used, will keep one what works for us -#class CAPWAP_ME_WTP_Frame_Tunnel_Mode(CAPWAP_ME): -# type = 41 -# fields_desc = [ _CAPWAP_ME_HDR, -# BitField('reserved', 0, 4), -# FlagsField('flags', 0, 4, 'RLEN') # actual order is NELR -# ] - - -class CAPWAP_ME_WTP_IPv4_IP_Address(CAPWAP_ME): - type = 42 - fields_desc = [ _CAPWAP_ME_HDR, - IPField('wtp_ipv4_ip_address', '0.0.0.0'), - ] - - -class CAPWAP_ME_WTP_IPv6_IP_Address(CAPWAP_ME): - type = 43 - fields_desc = [ _CAPWAP_ME_HDR, - IP6Field('wtp_ipv6_ip_address', '::1'), - ] - -class CAPWAP_ME_AP_Mode(CAPWAP_ME): - type = 1022 - fields_desc = [ _CAPWAP_ME_HDR, - ByteEnumField('ap_mode', 0, capwap_ap_modes) ] - -class CAPWAP_ME_WTP_MAC_Type(CAPWAP_ME): - type = 44 - fields_desc = [ _CAPWAP_ME_HDR, - ByteEnumField('mac_type', 0, capwap_mac_types) ] - - -class CAPWAP_ME_WTP_Name(CAPWAP_ME): - type = 45 - fields_desc = [ _CAPWAP_ME_HDR, - UTF8LenField('wtp_name', '', length_from = lambda pkt: pkt.length) - ] - - -class CAPWAP_ME_WTP_Reboot_Statistics(CAPWAP_ME): - type = 48 - fields_desc = [ _CAPWAP_ME_HDR, - ShortField('reboot_count', 0), - ShortField('ac_initiated_count', 0), - ShortField('link_failure_count', 0), - ShortField('sw_failure_count', 0), - ShortField('hw_failure_count', 0), - ShortField('other_failure_count', 0), - ShortField('unknown_failure_count', 0), - ByteEnumField('reboot_statistics_last_failure', 0, capwap_reboot_statistics_last_failures) - ] - - -class CAPWAP_ME_MTU_Discovery_Padding(CAPWAP_ME): - type = 52 - fields_desc = [ _CAPWAP_ME_HDR, - StrField('padding', '') - ] - - -class CAPWAP_ME_ECN_Support(CAPWAP_ME): - type = 53 - fields_desc = [ _CAPWAP_ME_HDR, - ByteEnumField('ecn_support', 0, capwap_ecn_supports) - ] - - -class CAPWAP_ME_Rate_Set(CAPWAP_ME): - type = 1034 - fields_desc = [ _CAPWAP_ME_HDR, - ByteField('radio_id', 0), - IEEE80211RateSetField('supported_rates', '', length_from = lambda pkt: pkt.length - 1), - ] - - -class CAPWAP_ME_WTP_Radio_Information(CAPWAP_ME): - type = 1048 - fields_desc = [ _CAPWAP_ME_HDR, - ByteField('radio_id', 0), - BitField('reserved', 0, 28), - FlagsField('flags', 0, 4, ['802.11b', '802.11a', '802.11g', '802.11n']) - ] - - -class CAPWAP_KeepAlive(Container): - name = 'Keep alive' - fields_desc = [ BitFieldLenField('message_elements_length', None, 16, length_of = 'message_elements', adjust = lambda pkt,x: x + 2), - PacketListField('message_elements', [], CAPWAP_ME, length_from = lambda p: p.message_elements_length - 2) ] - - #def post_dissect(self, s): - # ''' - # me_actual_len = sum(map(len, self.message_elements)) - # if self.message_elements_length > me_actual_len: - # warn('Message elements total length "%s" is less than size of data: "%s"' % (self.message_elements_length, me_actual_len)) - # ''' - # return s - - -class CAPWAP_Preamble(Container): - name = 'Preamble' - fields_desc = [ BitField('version', 0, 4), - BitEnumField('type', 0, 4, capwap_header_types), - ConditionalField(BitField('reserved', 0, 24), lambda pkt:pkt.type == 1) ] # padding in case of DTLS Header - - -class CAPWAP_Header(Container): - name = 'Header' - fields_desc = [ BitField('hlen', None, 5), # header len - BitField('rid', 0, 5), # radio id - BitEnumField('wbid', 0, 5, capwap_wbid_types), # wireless binding id - FlagsField('flags', 0, 6, 'KMWLFT'), # actual order is TFLWMK - BitField('reserved_flags', 0, 3), - BitField('fragment_id', 0, 16), - BitField('fragment_offset', 0, 13), - BitField('reserved_bits', 0, 3), - ConditionalField(PacketField('radio_mac', CAPWAP_Radio_MAC(), CAPWAP_Radio_MAC), lambda pkt:pkt.has_radio_mac()), - ConditionalField(PacketField('wireless_info', CAPWAP_Wireless_Specific_Information(), CAPWAP_Wireless_Specific_Information), lambda pkt:pkt.has_binding() and pkt.wbid != 1), - ConditionalField(PacketField('wireless_info_802', CAPWAP_Wireless_Specific_Information_IEEE802_11(), CAPWAP_Wireless_Specific_Information_IEEE802_11), lambda pkt:pkt.has_binding() and pkt.wbid == 1), - ] - - - def post_build(self, pkt, pay): - # fix hlen - if not self.hlen: - length = (len(pkt) + 1) >> 2 - pkt = int2str((length << 3) | (self.rid & 0b11100) >> 2) + pkt[1:] - return pkt + pay - - def is_fragment(self): - return bool(self.flags & 0b10000) - - def is_last_fragment(self): - return bool(self.flags & 0b1000) - - def has_binding(self): - return bool(self.flags & 0b100) - - def has_radio_mac(self): - return bool(self.flags & 0b10) - - -class CAPWAP_Control_Header(Layer): - name = 'Control Header' - fields_desc = [ ThreeBytesField('iana_enterprise_number', 0), - ByteEnumField('type', 0, capwap_control_message_types), - ByteField('sequence_number', 0), - BitFieldLenField('message_elements_length', None, 16, length_of = 'message_elements', adjust = lambda pkt,x: x + 3), - ByteField('flags', 0), - PacketListField('message_elements', [], CAPWAP_ME, length_from = lambda p: p.message_elements_length - 3), - ] - - def post_dissect(self, s): - me_actual_len = sum(map(len, self.message_elements)) + 3 - if self.message_elements_length != me_actual_len: - warn('%s message elements total length "%s" not equal actual data: "%s"' % (self.name, self.message_elements_length, me_actual_len)) - if self.iana_enterprise_number != 0: - warn('RFC 5415 requires IANA Enterprise Number = 0\n' - 'Provided number: %s' % self.iana_enterprise_number) - if self.flags != 0: - warn('RFC 5415 requires flags = 0\n' - 'Provided flags value: %s' % self.flags) - return '' - - def post_build(self, pkt, pay): - if self.type == 0: - warn('Control message type is 0!') - if self.iana_enterprise_number != 0: - warn('RFC 5415 requires IANA Enterprise Number = 0\n' - 'Provided number: %s' % self.iana_enterprise_number) - if self.flags != 0: - warn('RFC 5415 requires flags = 0\n' - 'Provided flags value: %s' % self.flags) - if len(pay): # ignore payload (raw etc.) - pay = 'removed raw (len %s)' % len(pay) - return Layer.post_build(self, pkt, pay) - - - -class CAPWAP_Control_Header_Fragment(Raw): - name = 'Control Header Fragment' - fields_desc = [ StrField('raw', '') ] - - -class CAPWAP_CTRL(Layer): - name = 'CAPWAP Control' - fields_desc = [ PacketField('preamble', CAPWAP_Preamble(), CAPWAP_Preamble), - ConditionalField(PacketField('header', CAPWAP_Header(), CAPWAP_Header), lambda pkt: pkt.is_plain()), - ConditionalField(PacketField('control_header', CAPWAP_Control_Header(), CAPWAP_Control_Header), lambda pkt: pkt.is_plain() and not pkt.is_fragment()), - ConditionalField(PacketField('control_header_fragment', CAPWAP_Control_Header_Fragment(), CAPWAP_Control_Header_Fragment), lambda pkt: pkt.is_fragment()), - ] - - def post_dissect(self, s): - if self.is_first_fragment(): - self.control_header_fragment.name = 'Control Header Fragment (%s)' % capwap_control_message_types.get(ord(self.control_header_fragment.raw[3:4]), 'Unknown') - return s - - #def post_build(self, pkt, pay): - # if self.header and self.header.fragment_offset == 0 and self.header.is_fragment(): - # ctrl_data = self.control_header_fragment.raw - # self.control_header_fragment.name = 'Control Header Fragment (%s)' % capwap_control_message_types.get(ord(ctrl_data[3:4]), 'Unknown') - # # self.header.hlen = len(self.preamble) + len(self.header) - # return pkt + pay - - def guess_payload_class(self, payload): - if self.preamble.type == 1: - return DTLS - return Layer.guess_payload_class(self, payload) - - def is_dtls(self): - return self.preamble.type == 1 - - def is_plain(self): - return self.preamble.type == 0 - - def is_fragment(self): - return self.is_plain() and self.header.is_fragment() - - def is_last_fragment(self): - return self.is_plain() and self.header.is_last_fragment() - - def is_first_fragment(self): - return self.is_fragment() and self.header.fragment_offset == 0 - - -class CAPWAP_DATA(Layer): - name = 'CAPWAP Data' - fields_desc = [ PacketField('preamble', CAPWAP_Preamble(), CAPWAP_Preamble), - ConditionalField(PacketField('header', CAPWAP_Header(), CAPWAP_Header), lambda pkt: pkt.preamble.type == 0), - ConditionalField(PacketField('keep_alive', CAPWAP_KeepAlive(), CAPWAP_KeepAlive), lambda pkt: pkt.header and bool(pkt.header.flags & 0b1)), - ] - - def is_keepalive(self): - return self.header.flags & 0b1 - - def guess_payload_class(self, payload): - if self.is_keepalive(): - return Raw - if self.header.flags & 0b100000: # type - #if self.is_keepalive(): - # warn('Flag of type should be zero in case of keepalive') - if self.header.wbid: - return Dot11_swapped - return Raw - return Dot3 - - - -bind_layers(UDP, CAPWAP_CTRL, sport = 5246) -bind_layers(UDP, CAPWAP_CTRL, dport = 5246) -bind_layers(CAPWAP_CTRL, DTLS, preamble = CAPWAP_Preamble(b'\1\0\0\0')) -bind_layers(UDP, CAPWAP_DATA, sport = 5247) -bind_layers(UDP, CAPWAP_DATA, dport = 5247) -bind_layers(CAPWAP_DATA, DTLS, preamble = CAPWAP_Preamble(b'\1\0\0\0')) - - - diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/capwap_internal.enc b/scripts/external_libs/scapy-2.4.3/scapy/contrib/capwap_internal.enc deleted file mode 100644 index 29628d6035..0000000000 Binary files a/scripts/external_libs/scapy-2.4.3/scapy/contrib/capwap_internal.enc and /dev/null differ diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/capwap_specific.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/capwap_specific.py deleted file mode 100644 index f5682a2d69..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/capwap_specific.py +++ /dev/null @@ -1,125 +0,0 @@ - -# TRex Change -class CAPWAP_PKTS_BUILDER: - - @staticmethod - def parse_message_elements(rx_pkt_buf, capwap_hlen, ap, ap_manager): - """Parses received capwap control packet and update state on given AP.""" - raise NotImplementedError - - @staticmethod - def discovery(ap): - """Returns a CAPWAP CONTROL packet containing the discovery packet of an AP to a controller, - not including sublayers. - - Args: - ap (AP): source of the packet - Returns: - capw_ctrl (bytes): capwap control bytes - """ - raise NotImplementedError - - @staticmethod - def join(ap): - """Returns a CAPWAP CONTROL packet containing the join packet of an AP to a controller, - not including sublayers. - - Args: - ap (AP): source of the packet - Returns: - capw_ctrl (bytes): capwap control bytes - """ - raise NotImplementedError - - @staticmethod - def conf_status_req(ap): - """Returns a CAPWAP CONTROL packet containing the "configuration status update" packet of an AP to a controller, - not including sublayers. - - Args: - ap (AP): source of the packet - Returns: - capw_ctrl (bytes): capwap control bytes - """ - raise NotImplementedError - - @staticmethod - def change_state(ap, radio_id=0): - """Returns a CAPWAP CONTROL packet containing the "change state event request" packet of an AP to a controller, - not including sublayers. - - Args: - ap (AP): source of the packet - radio_id (int): id of the concerned radio - Returns: - capw_ctrl (bytes): capwap control bytes - """ - raise NotImplementedError - - @staticmethod - def config_update(ap, capwap_seq): - """Returns a CAPWAP CONTROL packet containing the "configuration update response" packet of an AP to a controller, - not including sublayers. - - Args: - ap (AP): source of the packet - capwap_seq (int): sequence number of the requested response - Returns: - capw_ctrl (bytes): capwap control bytes - """ - raise NotImplementedError - - - @staticmethod - def echo(ap): - """Returns a CAPWAP CONTROL packet containing the "echo request" packet of an AP to a controller, - not including sublayers. - - Args: - ap (AP): source of the packet - Returns: - capw_ctrl (bytes): capwap control bytes - """ - raise NotImplementedError - - @staticmethod - def keep_alive(ap): - """Returns a CAPWAP DATA packet containing the "keep alive" packet of an AP to a controller, - not including sublayers. - - Args: - ap (AP): source of the packet - Returns: - capw_data (bytes): capwap data bytes - """ - raise NotImplementedError - - @staticmethod - def client_assoc(ap, vap, client_mac): - """Returns a CAPWAP DATA packet containing the "association request" - of a client attached to given AP, intended for the VAP. - - - Args: - ap (AP): source of the packet - vap (VAP): vap for the AP to associate, on a given frequency. - client_mac (str): mac address of the associating client - Returns: - capw_data (bytes): capwap data bytes, with payload Dot11 association request - """ - raise NotImplementedError - - @staticmethod - def client_disassoc(ap, vap, client_mac): - """Returns a CAPWAP DATA packet containing the "disassociation" packet - of a client attached to given AP, intended for the VAP. - - - Args: - ap (AP): source of the packet - vap (VAP): vap for the AP to associate, on a given frequency. - client_mac (str): mac address of the disassociating client - Returns: - capw_data (bytes): capwap data bytes, with payload Dot11 disassociation - """ - raise NotImplementedError diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/carp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/carp.py deleted file mode 100644 index 3aea2f3483..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/carp.py +++ /dev/null @@ -1,81 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = Common Address Redundancy Protocol (CARP) -# scapy.contrib.status = loads - -import struct -import hmac -import hashlib - -from scapy.packet import Packet, split_layers, bind_layers -from scapy.layers.inet import IP -from scapy.fields import BitField, ByteField, XShortField, XIntField -from scapy.layers.vrrp import IPPROTO_VRRP, VRRP, VRRPv3 -from scapy.utils import checksum, inet_aton -from scapy.error import warning - - -class CARP(Packet): - name = "CARP" - fields_desc = [BitField("version", 4, 4), - BitField("type", 4, 4), - ByteField("vhid", 1), - ByteField("advskew", 0), - ByteField("authlen", 0), - ByteField("demotion", 0), - ByteField("advbase", 0), - XShortField("chksum", None), - XIntField("counter1", 0), - XIntField("counter2", 0), - XIntField("hmac1", 0), - XIntField("hmac2", 0), - XIntField("hmac3", 0), - XIntField("hmac4", 0), - XIntField("hmac5", 0) - ] - - def post_build(self, pkt, pay): - if self.chksum is None: - pkt = pkt[:6] + struct.pack("!H", checksum(pkt)) + pkt[8:] - - return pkt - - def build_hmac_sha1(self, pw=b'\x00' * 20, ip4l=[], ip6l=[]): - h = hmac.new(pw, digestmod=hashlib.sha1) - # XXX: this is a dirty hack. it needs to pack version and type into a single 8bit field # noqa: E501 - h.update(b'\x21') - # XXX: mac addy if different from special link layer. comes before vhid - h.update(struct.pack('!B', self.vhid)) - - sl = [] - for i in ip4l: - # sort ips from smallest to largest - sl.append(inet_aton(i)) - sl.sort() - - for i in sl: - h.update(i) - - # XXX: do ip6l sorting - - return h.digest() - - -warning("CARP overwrites VRRP !") -# This cancel the bindings done in vrrp.py -split_layers(IP, VRRP, proto=IPPROTO_VRRP) -split_layers(IP, VRRPv3, proto=IPPROTO_VRRP) -# CARP bindings -bind_layers(IP, CARP, proto=112, dst='224.0.0.18') diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/cdp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/cdp.py deleted file mode 100644 index 9ad15c8a61..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/cdp.py +++ /dev/null @@ -1,384 +0,0 @@ -#! /usr/bin/env python - -# scapy.contrib.description = Cisco Discovery Protocol (CDP) -# scapy.contrib.status = loads - -############################################################################# -# # -# cdp.py --- Cisco Discovery Protocol (CDP) extension for Scapy # -# # -# Copyright (C) 2006 Nicolas Bareil # -# Arnaud Ebalard # -# EADS/CRC security team # -# # -# This file is part of Scapy # -# Scapy 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. # -# # -############################################################################# - -from __future__ import absolute_import -import struct - -from scapy.packet import Packet, bind_layers -from scapy.fields import ByteEnumField, ByteField, FieldLenField, FlagsField, \ - IP6Field, IPField, PacketListField, ShortField, StrLenField, \ - X3BytesField, XByteField, XShortEnumField, XShortField -from scapy.layers.inet import checksum -from scapy.layers.l2 import SNAP -from scapy.compat import orb, chb -from scapy.modules.six.moves import range -from scapy.config import conf - - -##################################################################### -# Helpers and constants -##################################################################### - -# CDP TLV classes keyed by type -_cdp_tlv_cls = {0x0001: "CDPMsgDeviceID", - 0x0002: "CDPMsgAddr", - 0x0003: "CDPMsgPortID", - 0x0004: "CDPMsgCapabilities", - 0x0005: "CDPMsgSoftwareVersion", - 0x0006: "CDPMsgPlatform", - 0x0007: "CDPMsgIPPrefix", - 0x0008: "CDPMsgProtoHello", - 0x0009: "CDPMsgVTPMgmtDomain", # CDPv2 - 0x000a: "CDPMsgNativeVLAN", # CDPv2 - 0x000b: "CDPMsgDuplex", # - # 0x000c: "CDPMsgGeneric", - # 0x000d: "CDPMsgGeneric", - 0x000e: "CDPMsgVoIPVLANReply", - 0x000f: "CDPMsgVoIPVLANQuery", - 0x0010: "CDPMsgPower", - 0x0011: "CDPMsgMTU", - 0x0012: "CDPMsgTrustBitmap", - 0x0013: "CDPMsgUntrustedPortCoS", - # 0x0014: "CDPMsgSystemName", - # 0x0015: "CDPMsgSystemOID", - 0x0016: "CDPMsgMgmtAddr", - # 0x0017: "CDPMsgLocation", - 0x0019: "CDPMsgUnknown19", - # 0x001a: "CDPPowerAvailable" - } - -_cdp_tlv_types = {0x0001: "Device ID", - 0x0002: "Addresses", - 0x0003: "Port ID", - 0x0004: "Capabilities", - 0x0005: "Software Version", - 0x0006: "Platform", - 0x0007: "IP Prefix", - 0x0008: "Protocol Hello", - 0x0009: "VTP Management Domain", # CDPv2 - 0x000a: "Native VLAN", # CDPv2 - 0x000b: "Duplex", # - 0x000c: "CDP Unknown command (send us a pcap file)", - 0x000d: "CDP Unknown command (send us a pcap file)", - 0x000e: "VoIP VLAN Reply", - 0x000f: "VoIP VLAN Query", - 0x0010: "Power", - 0x0011: "MTU", - 0x0012: "Trust Bitmap", - 0x0013: "Untrusted Port CoS", - 0x0014: "System Name", - 0x0015: "System OID", - 0x0016: "Management Address", - 0x0017: "Location", - 0x0018: "CDP Unknown command (send us a pcap file)", - 0x0019: "CDP Unknown command (send us a pcap file)", - 0x001a: "Power Available"} - - -def _CDPGuessPayloadClass(p, **kargs): - cls = conf.raw_layer - if len(p) >= 2: - t = struct.unpack("!H", p[:2])[0] - clsname = _cdp_tlv_cls.get(t, "CDPMsgGeneric") - cls = globals()[clsname] - - return cls(p, **kargs) - - -class CDPMsgGeneric(Packet): - name = "CDP Generic Message" - fields_desc = [XShortEnumField("type", None, _cdp_tlv_types), - FieldLenField("len", None, "val", "!H", - adjust=lambda pkt, x: x + 4), - StrLenField("val", "", length_from=lambda x:x.len - 4, - max_length=65531)] - - def guess_payload_class(self, p): - return conf.padding_layer # _CDPGuessPayloadClass - - -class CDPMsgDeviceID(CDPMsgGeneric): - name = "Device ID" - type = 0x0001 - - -_cdp_addr_record_ptype = {0x01: "NLPID", 0x02: "802.2"} -_cdp_addrrecord_proto_ip = b"\xcc" -_cdp_addrrecord_proto_ipv6 = b"\xaa\xaa\x03\x00\x00\x00\x86\xdd" - - -class CDPAddrRecord(Packet): - name = "CDP Address" - fields_desc = [ByteEnumField("ptype", 0x01, _cdp_addr_record_ptype), - FieldLenField("plen", None, "proto", "B"), - StrLenField("proto", None, length_from=lambda x:x.plen, - max_length=255), - FieldLenField("addrlen", None, length_of=lambda x:x.addr), - StrLenField("addr", None, length_from=lambda x:x.addrlen, - max_length=65535)] - - def guess_payload_class(self, p): - return conf.padding_layer - - -class CDPAddrRecordIPv4(CDPAddrRecord): - name = "CDP Address IPv4" - fields_desc = [ByteEnumField("ptype", 0x01, _cdp_addr_record_ptype), - FieldLenField("plen", 1, "proto", "B"), - StrLenField("proto", _cdp_addrrecord_proto_ip, - length_from=lambda x: x.plen, max_length=255), - ShortField("addrlen", 4), - IPField("addr", "0.0.0.0")] - - -class CDPAddrRecordIPv6(CDPAddrRecord): - name = "CDP Address IPv6" - fields_desc = [ByteEnumField("ptype", 0x02, _cdp_addr_record_ptype), - FieldLenField("plen", 8, "proto", "B"), - StrLenField("proto", _cdp_addrrecord_proto_ipv6, - length_from=lambda x:x.plen, max_length=255), - ShortField("addrlen", 16), - IP6Field("addr", "::1")] - - -def _CDPGuessAddrRecord(p, **kargs): - cls = conf.raw_layer - if len(p) >= 2: - plen = orb(p[1]) - proto = p[2:plen + 2] - - if proto == _cdp_addrrecord_proto_ip: - clsname = "CDPAddrRecordIPv4" - elif proto == _cdp_addrrecord_proto_ipv6: - clsname = "CDPAddrRecordIPv6" - else: - clsname = "CDPAddrRecord" - - cls = globals()[clsname] - - return cls(p, **kargs) - - -class CDPMsgAddr(CDPMsgGeneric): - name = "Addresses" - fields_desc = [XShortEnumField("type", 0x0002, _cdp_tlv_types), - ShortField("len", None), - FieldLenField("naddr", None, "addr", "!I"), - PacketListField("addr", [], _CDPGuessAddrRecord, count_from=lambda x:x.naddr)] # noqa: E501 - - def post_build(self, pkt, pay): - if self.len is None: - tmp_len = 8 + len(self.addr) * 9 - pkt = pkt[:2] + struct.pack("!H", tmp_len) + pkt[4:] - p = pkt + pay - return p - - -class CDPMsgPortID(CDPMsgGeneric): - name = "Port ID" - fields_desc = [XShortEnumField("type", 0x0003, _cdp_tlv_types), - FieldLenField("len", None, "iface", "!H", - adjust=lambda pkt, x: x + 4), - StrLenField("iface", "Port 1", length_from=lambda x:x.len - 4)] # noqa: E501 - - -_cdp_capabilities = ["Router", - "TransparentBridge", - "SourceRouteBridge", - "Switch", - "Host", - "IGMPCapable", - "Repeater"] + ["Bit%d" % x for x in range(25, 0, -1)] - - -class CDPMsgCapabilities(CDPMsgGeneric): - name = "Capabilities" - fields_desc = [XShortEnumField("type", 0x0004, _cdp_tlv_types), - ShortField("len", 8), - FlagsField("cap", 0, 32, _cdp_capabilities)] - - -class CDPMsgSoftwareVersion(CDPMsgGeneric): - name = "Software Version" - type = 0x0005 - - -class CDPMsgPlatform(CDPMsgGeneric): - name = "Platform" - type = 0x0006 - - -_cdp_duplex = {0x00: "Half", 0x01: "Full"} - -# ODR Routing - - -class CDPMsgIPPrefix(CDPMsgGeneric): - name = "IP Prefix" - type = 0x0007 - fields_desc = [XShortEnumField("type", 0x0007, _cdp_tlv_types), - ShortField("len", 8), - IPField("defaultgw", "192.168.0.1")] - - -class CDPMsgProtoHello(CDPMsgGeneric): - name = "Protocol Hello" - type = 0x0008 - fields_desc = [XShortEnumField("type", 0x0008, _cdp_tlv_types), - ShortField("len", 32), - X3BytesField("oui", 0x00000c), - XShortField("protocol_id", 0x0), - # TLV length (len) - 2 (type) - 2 (len) - 3 (OUI) - 2 - # (Protocol ID) - StrLenField("data", "", length_from=lambda p: p.len - 9)] - - -class CDPMsgVTPMgmtDomain(CDPMsgGeneric): - name = "VTP Management Domain" - type = 0x0009 - - -class CDPMsgNativeVLAN(CDPMsgGeneric): - name = "Native VLAN" - fields_desc = [XShortEnumField("type", 0x000a, _cdp_tlv_types), - ShortField("len", 6), - ShortField("vlan", 1)] - - -class CDPMsgDuplex(CDPMsgGeneric): - name = "Duplex" - fields_desc = [XShortEnumField("type", 0x000b, _cdp_tlv_types), - ShortField("len", 5), - ByteEnumField("duplex", 0x00, _cdp_duplex)] - - -class CDPMsgVoIPVLANReply(CDPMsgGeneric): - name = "VoIP VLAN Reply" - fields_desc = [XShortEnumField("type", 0x000e, _cdp_tlv_types), - ShortField("len", 7), - ByteField("status?", 1), - ShortField("vlan", 1)] - - -class CDPMsgVoIPVLANQuery(CDPMsgGeneric): - name = "VoIP VLAN Query" - type = 0x000f - fields_desc = [XShortEnumField("type", 0x000f, _cdp_tlv_types), - FieldLenField("len", None, "unknown2", fmt="!H", - adjust=lambda pkt, x: x + 7), - XByteField("unknown1", 0), - ShortField("vlan", 1), - # TLV length (len) - 2 (type) - 2 (len) - 1 (unknown1) - 2 (vlan) # noqa: E501 - StrLenField("unknown2", "", length_from=lambda p: p.len - 7, - max_length=65528)] - - -class _CDPPowerField(ShortField): - def i2repr(self, pkt, x): - if x is None: - x = 0 - return "%d mW" % x - - -class CDPMsgPower(CDPMsgGeneric): - name = "Power" - # Check if field length is fixed (2 bytes) - fields_desc = [XShortEnumField("type", 0x0010, _cdp_tlv_types), - ShortField("len", 6), - _CDPPowerField("power", 1337)] - - -class CDPMsgMTU(CDPMsgGeneric): - name = "MTU" - # Check if field length is fixed (2 bytes) - fields_desc = [XShortEnumField("type", 0x0011, _cdp_tlv_types), - ShortField("len", 6), - ShortField("mtu", 1500)] - - -class CDPMsgTrustBitmap(CDPMsgGeneric): - name = "Trust Bitmap" - fields_desc = [XShortEnumField("type", 0x0012, _cdp_tlv_types), - ShortField("len", 5), - XByteField("trust_bitmap", 0x0)] - - -class CDPMsgUntrustedPortCoS(CDPMsgGeneric): - name = "Untrusted Port CoS" - fields_desc = [XShortEnumField("type", 0x0013, _cdp_tlv_types), - ShortField("len", 5), - XByteField("untrusted_port_cos", 0x0)] - - -class CDPMsgMgmtAddr(CDPMsgAddr): - name = "Management Address" - type = 0x0016 - - -class CDPMsgUnknown19(CDPMsgGeneric): - name = "Unknown CDP Message" - type = 0x0019 - - -class CDPMsg(CDPMsgGeneric): - name = "CDP " - fields_desc = [XShortEnumField("type", None, _cdp_tlv_types), - FieldLenField("len", None, "val", fmt="!H", - adjust=lambda pkt, x: x + 4), - StrLenField("val", "", length_from=lambda x:x.len - 4, - max_length=65531)] - - -class _CDPChecksum: - def _check_len(self, pkt): - """Check for odd packet length and pad according to Cisco spec. - This padding is only used for checksum computation. The original - packet should not be altered.""" - if len(pkt) % 2: - last_chr = pkt[-1] - if last_chr <= b'\x80': - return pkt[:-1] + b'\x00' + last_chr - else: - return pkt[:-1] + b'\xff' + chb(orb(last_chr) - 1) - else: - return pkt - - def post_build(self, pkt, pay): - p = pkt + pay - if self.cksum is None: - cksum = checksum(self._check_len(p)) - p = p[:2] + struct.pack("!H", cksum) + p[4:] - return p - - -class CDPv2_HDR(_CDPChecksum, CDPMsgGeneric): - name = "Cisco Discovery Protocol version 2" - fields_desc = [ByteField("vers", 2), - ByteField("ttl", 180), - XShortField("cksum", None), - PacketListField("msg", [], _CDPGuessPayloadClass)] - - -bind_layers(SNAP, CDPv2_HDR, {"code": 0x2000, "OUI": 0xC}) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/chdlc.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/chdlc.py deleted file mode 100644 index e17201203a..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/chdlc.py +++ /dev/null @@ -1,60 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = Cisco HDLC and SLARP -# scapy.contrib.status = loads - -# This layer is based on information from http://www.nethelp.no/net/cisco-hdlc.txt # noqa: E501 - -from scapy.data import DLT_C_HDLC -from scapy.packet import Packet, bind_layers -from scapy.fields import ByteEnumField, ByteField, ConditionalField, \ - IntEnumField, IntField, IPField, XShortField -from scapy.layers.l2 import Dot3, STP -from scapy.layers.inet import IP -from scapy.layers.inet6 import IPv6 -from scapy.config import conf - - -class CHDLC(Packet): - name = "Cisco HDLC" - fields_desc = [ByteEnumField("address", 0x0f, {0x0f: "unicast", 0x8f: "multicast"}), # noqa: E501 - ByteField("control", 0), - XShortField("proto", 0x0800)] - - -class SLARP(Packet): - name = "SLARP" - fields_desc = [IntEnumField("type", 2, {0: "request", 1: "reply", 2: "line keepalive"}), # noqa: E501 - ConditionalField(IPField("address", "192.168.0.1"), - lambda pkt: pkt.type == 0 or pkt.type == 1), # noqa: E501 - ConditionalField(IPField("mask", "255.255.255.0"), - lambda pkt: pkt.type == 0 or pkt.type == 1), # noqa: E501 - ConditionalField(XShortField("unused", 0), - lambda pkt: pkt.type == 0 or pkt.type == 1), # noqa: E501 - ConditionalField(IntField("mysequence", 0), - lambda pkt: pkt.type == 2), - ConditionalField(IntField("yoursequence", 0), - lambda pkt: pkt.type == 2), - ConditionalField(XShortField("reliability", 0xffff), - lambda pkt: pkt.type == 2)] - - -bind_layers(CHDLC, Dot3, proto=0x6558) -bind_layers(CHDLC, IP, proto=0x800) -bind_layers(CHDLC, IPv6, proto=0x86dd) -bind_layers(CHDLC, SLARP, proto=0x8035) -bind_layers(CHDLC, STP, proto=0x4242) - -conf.l2types.register(DLT_C_HDLC, CHDLC) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/coap.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/coap.py deleted file mode 100644 index fcbc5ec853..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/coap.py +++ /dev/null @@ -1,255 +0,0 @@ -#! /usr/bin/env python - -# This file is part of Scapy. -# See http://www.secdev.org/projects/scapy for more information. -# -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . -# -# Copyright (C) 2016 Anmol Sarma - -# scapy.contrib.description = Constrained Application Protocol (CoAP) -# scapy.contrib.status = loads - -""" -RFC 7252 - Constrained Application Protocol (CoAP) layer for Scapy -""" - -import struct - -from scapy.fields import BitEnumField, BitField, BitFieldLenField, \ - ByteEnumField, ShortField, StrField, StrLenField -from scapy.layers.inet import UDP -from scapy.packet import Packet, bind_layers -from scapy.error import warning -from scapy.compat import raw - -coap_codes = { - 0: "Empty", - # Request codes - 1: "GET", - 2: "POST", - 3: "PUT", - 4: "DELETE", - # Response codes - 65: "2.01 Created", - 66: "2.02 Deleted", - 67: "2.03 Valid", - 68: "2.04 Changed", - 69: "2.05 Content", - 128: "4.00 Bad Request", - 129: "4.01 Unauthorized", - 130: "4.02 Bad Option", - 131: "4.03 Forbidden", - 132: "4.04 Not Found", - 133: "4.05 Method Not Allowed", - 134: "4.06 Not Acceptable", - 140: "4.12 Precondition Failed", - 141: "4.13 Request Entity Too Large", - 143: "4.15 Unsupported Content-Format", - 160: "5.00 Internal Server Error", - 161: "5.01 Not Implemented", - 162: "5.02 Bad Gateway", - 163: "5.03 Service Unavailable", - 164: "5.04 Gateway Timeout", - 165: "Proxying Not Supported"} - -coap_options = ({ - 1: "If-Match", - 3: "Uri-Host", - 4: "ETag", - 5: "If-None-Match", - 7: "Uri-Port", - 8: "Location-Path", - 11: "Uri-Path", - 12: "Content-Format", - 14: "Max-Age", - 15: "Uri-Query", - 17: "Accept", - 20: "Location-Query", - 35: "Proxy-Uri", - 39: "Proxy-Scheme", - 60: "Size1" -}, - { - "If-Match": 1, - "Uri-Host": 3, - "ETag": 4, - "If-None-Match": 5, - "Uri-Port": 7, - "Location-Path": 8, - "Uri-Path": 11, - "Content-Format": 12, - "Max-Age": 14, - "Uri-Query": 15, - "Accept": 17, - "Location-Query": 20, - "Proxy-Uri": 35, - "Proxy-Scheme": 39, - "Size1": 60 -}) - - -def _get_ext_field_size(val): - if val >= 15: - warning("Invalid Option Delta or Length") - if val == 14: - return 2 - if val == 13: - return 1 - return 0 - - -def _get_delta_ext_size(pkt): - return _get_ext_field_size(pkt.delta) - - -def _get_len_ext_size(pkt): - return _get_ext_field_size(pkt.len) - - -def _get_abs_val(val, ext_val): - if val >= 15: - warning("Invalid Option Length or Delta %d" % val) - if val == 14: - return 269 + struct.unpack('H', ext_val)[0] - if val == 13: - return 13 + struct.unpack('B', ext_val)[0] - return val - - -def _get_opt_val_size(pkt): - return _get_abs_val(pkt.len, pkt.len_ext) - - -class _CoAPOpt(Packet): - fields_desc = [BitField("delta", 0, 4), - BitField("len", 0, 4), - StrLenField("delta_ext", None, length_from=_get_delta_ext_size), # noqa: E501 - StrLenField("len_ext", None, length_from=_get_len_ext_size), - StrLenField("opt_val", None, length_from=_get_opt_val_size)] - - @staticmethod - def _populate_extended(val): - if val >= 269: - return struct.pack('H', val - 269), 14 - if val >= 13: - return struct.pack('B', val - 13), 13 - return None, val - - def do_build(self): - self.delta_ext, self.delta = self._populate_extended(self.delta) - self.len_ext, self.len = self._populate_extended(len(self.opt_val)) - - return Packet.do_build(self) - - def guess_payload_class(self, payload): - if payload[:1] != b"\xff": - return _CoAPOpt - else: - return Packet.guess_payload_class(self, payload) - - -class _CoAPOptsField(StrField): - islist = 1 - - def i2h(self, pkt, x): - return [(coap_options[0][o[0]], o[1]) if o[0] in coap_options[0] else o for o in x] # noqa: E501 - - # consume only the coap layer from the wire string - def getfield(self, pkt, s): - opts = self.m2i(pkt, s) - used = 0 - for o in opts: - used += o[0] - return s[used:], [(o[1], o[2]) for o in opts] - - def m2i(self, pkt, x): - opts = [] - o = _CoAPOpt(x) - cur_delta = 0 - while isinstance(o, _CoAPOpt): - cur_delta += _get_abs_val(o.delta, o.delta_ext) - # size of this option in bytes - u = 1 + len(o.opt_val) + len(o.delta_ext) + len(o.len_ext) - opts.append((u, cur_delta, o.opt_val)) - o = o.payload - return opts - - def i2m(self, pkt, x): - if not x: - return b"" - opt_lst = [] - for o in x: - if isinstance(o[0], str): - opt_lst.append((coap_options[1][o[0]], o[1])) - else: - opt_lst.append(o) - opt_lst.sort(key=lambda o: o[0]) - - opts = _CoAPOpt(delta=opt_lst[0][0], opt_val=opt_lst[0][1]) - high_opt = opt_lst[0][0] - for o in opt_lst[1:]: - opts = opts / _CoAPOpt(delta=o[0] - high_opt, opt_val=o[1]) - high_opt = o[0] - - return raw(opts) - - -class _CoAPPaymark(StrField): - - def i2h(self, pkt, x): - return x - - def getfield(self, pkt, s): - (u, m) = self.m2i(pkt, s) - return s[u:], m - - def m2i(self, pkt, x): - if len(x) > 0 and x[:1] == b"\xff": - return 1, b'\xff' - return 0, b'' - - def i2m(self, pkt, x): - return x - - -class CoAP(Packet): - __slots__ = ["content_format"] - name = "CoAP" - - fields_desc = [BitField("ver", 1, 2), - BitEnumField("type", 0, 2, {0: "CON", 1: "NON", 2: "ACK", 3: "RST"}), # noqa: E501 - BitFieldLenField("tkl", None, 4, length_of='token'), - ByteEnumField("code", 0, coap_codes), - ShortField("msg_id", 0), - StrLenField("token", "", length_from=lambda pkt: pkt.tkl), - _CoAPOptsField("options", []), - _CoAPPaymark("paymark", b"") - ] - - def getfieldval(self, attr): - v = getattr(self, attr) - if v: - return v - return Packet.getfieldval(self, attr) - - def post_dissect(self, pay): - for k in self.options: - if k[0] == "Content-Format": - self.content_format = k[1] - return pay - - -bind_layers(UDP, CoAP, sport=5683) -bind_layers(UDP, CoAP, dport=5683) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/dce_rpc.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/dce_rpc.py deleted file mode 100644 index 5254c809bc..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/dce_rpc.py +++ /dev/null @@ -1,161 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# Copyright (C) 2016 Gauthier Sebaux - -# scapy.contrib.description = DCE/RPC -# scapy.contrib.status = loads - -""" -A basic dissector for DCE/RPC. -Isn't reliable for all packets and for building -""" - -# TODO: namespace locally used fields -from scapy.packet import Packet, Raw, bind_layers -from scapy.fields import BitEnumField, ByteEnumField, ByteField, \ - FlagsField, IntField, LenField, ShortField, UUIDField, XByteField, \ - XShortField - - -# Fields -class EndiannessField(object): - """Field which change the endianness of a sub-field""" - __slots__ = ["fld", "endianess_from"] - - def __init__(self, fld, endianess_from): - self.fld = fld - self.endianess_from = endianess_from - - def set_endianess(self, pkt): - """Add the endianness to the format""" - end = self.endianess_from(pkt) - if isinstance(end, str) and end: - if isinstance(self.fld, UUIDField): - self.fld.uuid_fmt = (UUIDField.FORMAT_LE if end == '<' - else UUIDField.FORMAT_BE) - else: - # fld.fmt should always start with a order specifier, cf field - # init - self.fld.fmt = end[0] + self.fld.fmt[1:] - - def getfield(self, pkt, buf): - """retrieve the field with endianness""" - self.set_endianess(pkt) - return self.fld.getfield(pkt, buf) - - def addfield(self, pkt, buf, val): - """add the field with endianness to the buffer""" - self.set_endianess(pkt) - return self.fld.addfield(pkt, buf, val) - - def __getattr__(self, attr): - return getattr(self.fld, attr) - - -# DCE/RPC Packet -DCE_RPC_TYPE = ["request", "ping", "response", "fault", "working", "no_call", - "reject", "acknowledge", "connectionless_cancel", "frag_ack", - "cancel_ack"] -DCE_RPC_FLAGS1 = ["reserved_0", "last_frag", "frag", "no_frag_ack", "maybe", - "idempotent", "broadcast", "reserved_7"] -DCE_RPC_FLAGS2 = ["reserved_0", "cancel_pending", "reserved_2", "reserved_3", - "reserved_4", "reserved_5", "reserved_6", "reserved_7"] - - -def dce_rpc_endianess(pkt): - """Determine the right endianness sign for a given DCE/RPC packet""" - if pkt.endianness == 0: # big endian - return ">" - elif pkt.endianness == 1: # little endian - return "<" - else: - return "!" - - -class DceRpc(Packet): - """DCE/RPC packet""" - name = "DCE/RPC" - fields_desc = [ - ByteField("version", 4), - ByteEnumField("type", 0, DCE_RPC_TYPE), - FlagsField("flags1", 0, 8, DCE_RPC_FLAGS1), - FlagsField("flags2", 0, 8, DCE_RPC_FLAGS2), - BitEnumField("endianness", 0, 4, ["big", "little"]), - BitEnumField("encoding", 0, 4, ["ASCII", "EBCDIC"]), - ByteEnumField("float", 0, ["IEEE", "VAX", "CRAY", "IBM"]), - ByteField("DataRepr_reserved", 0), - XByteField("serial_high", 0), - EndiannessField(UUIDField("object_uuid", None), - endianess_from=dce_rpc_endianess), - EndiannessField(UUIDField("interface_uuid", None), - endianess_from=dce_rpc_endianess), - EndiannessField(UUIDField("activity", None), - endianess_from=dce_rpc_endianess), - EndiannessField(IntField("boot_time", 0), - endianess_from=dce_rpc_endianess), - EndiannessField(IntField("interface_version", 1), - endianess_from=dce_rpc_endianess), - EndiannessField(IntField("sequence_num", 0), - endianess_from=dce_rpc_endianess), - EndiannessField(ShortField("opnum", 0), - endianess_from=dce_rpc_endianess), - EndiannessField(XShortField("interface_hint", 0xffff), - endianess_from=dce_rpc_endianess), - EndiannessField(XShortField("activity_hint", 0xffff), - endianess_from=dce_rpc_endianess), - EndiannessField(LenField("frag_len", None, fmt="H"), - endianess_from=dce_rpc_endianess), - EndiannessField(ShortField("frag_num", 0), - endianess_from=dce_rpc_endianess), - ByteEnumField("auth", 0, ["none"]), # TODO other auth ? - XByteField("serial_low", 0), - ] - - -# Heuristically way to find the payload class -# -# To add a possible payload to a DCE/RPC packet, one must first create the -# packet class, then instead of binding layers using bind_layers, he must -# call DceRpcPayload.register_possible_payload() with the payload class as -# parameter. -# -# To be able to decide if the payload class is capable of handling the rest of -# the dissection, the classmethod can_handle() should be implemented in the -# payload class. This method is given the rest of the string to dissect as -# first argument, and the DceRpc packet instance as second argument. Based on -# this information, the method must return True if the class is capable of -# handling the dissection, False otherwise -class DceRpcPayload(Packet): - """Dummy class which use the dispatch_hook to find the payload class""" - _payload_class = [] - - @classmethod - def dispatch_hook(cls, _pkt, _underlayer=None, *args, **kargs): - """dispatch_hook to choose among different registered payloads""" - for klass in cls._payload_class: - if hasattr(klass, "can_handle") and \ - klass.can_handle(_pkt, _underlayer): - return klass - print("DCE/RPC payload class not found or undefined (using Raw)") - return Raw - - @classmethod - def register_possible_payload(cls, pay): - """Method to call from possible DCE/RPC endpoint to register it as - possible payload""" - cls._payload_class.append(pay) - - -bind_layers(DceRpc, DceRpcPayload) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/diameter.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/diameter.py deleted file mode 100644 index ff72cc538b..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/diameter.py +++ /dev/null @@ -1,4835 +0,0 @@ -########################################################################## -# -# Diameter protocol implementation for Scapy -# Original Author: patrick battistello -# -# This implements the base Diameter protocol RFC6733 and the additional standards: # noqa: E501 -# RFC7155, RFC4004, RFC4006, RFC4072, RFC4740, RFC5778, RFC5447, RFC6942, RFC5777 # noqa: E501 -# ETS29229 V12.3.0 (2014-09), ETS29272 V13.1.0 (2015-03), ETS29329 V12.5.0 (2014-12), # noqa: E501 -# ETS29212 V13.1.0 (2015-03), ETS32299 V13.0.0 (2015-03), ETS29210 V6.7.0 (2006-12), # noqa: E501 -# ETS29214 V13.1.0 (2015-03), ETS29273 V12.7.0 (2015-03), ETS29173 V12.3.0 (2015-03), # noqa: E501 -# ETS29172 V12.5.0 (2015-03), ETS29215 V13.1.0 (2015-03), ETS29209 V6.8.0 (2011-09), # noqa: E501 -# ETS29061 V13.0.0 (2015-03), ETS29219 V13.0.0 (2014-12) -# -# IMPORTANT note: -# -# - Some Diameter fields (Unsigned64, Float32, ...) have not been tested yet due to lack # noqa: E501 -# of network captures containing AVPs of that types contributions are welcomed. # noqa: E501 -# -########################################################################## - -# scapy.contrib.description = Diameter -# scapy.contrib.status = loads - -import socket -import struct -from time import ctime - -from scapy.packet import Packet, bind_layers -from scapy.fields import ConditionalField, EnumField, Field, FieldLenField, \ - FlagsField, IEEEDoubleField, IEEEFloatField, IntEnumField, IntField, \ - LongField, PacketListField, SignedIntField, StrLenField, X3BytesField, \ - XByteField, XIntField -from scapy.layers.inet import TCP -from scapy.layers.sctp import SCTPChunkData -import scapy.modules.six as six -from scapy.modules.six.moves import range -from scapy.compat import chb, orb, raw, bytes_hex, plain_str -from scapy.error import warning -from scapy.utils import inet_ntoa, inet_aton -from scapy.pton_ntop import inet_pton, inet_ntop - -##################################################################### -##################################################################### -# -# Definition of additional fields -# -##################################################################### -##################################################################### - - -class I3BytesEnumField (X3BytesField, EnumField): - """ 3 bytes enum field """ - - def __init__(self, name, default, enum): - EnumField.__init__(self, name, default, enum, "!I") - - -class I3FieldLenField(X3BytesField, FieldLenField): - __slots__ = ["length_of", "count_of", "adjust"] - - def __init__( - self, - name, - default, - length_of=None, - count_of=None, - adjust=lambda pkt, - x: x): - X3BytesField.__init__(self, name, default) - self.length_of = length_of - self.count_of = count_of - self.adjust = adjust - - def i2m(self, pkt, x): - return FieldLenField.i2m(self, pkt, x) - -########################################################### -# Fields for Diameter commands -########################################################### - - -class DRFlags (FlagsField): - def i2repr(self, pkt, x): - if x is None: - return "None" - res = hex(int(x)) - r = '' - cmdt = (x & 128) and ' Request' or ' Answer' - if x & 15: # Check if reserved bits are used - nb = 8 - offset = 0 - else: # Strip the first 4 bits - nb = 4 - offset = 4 - x >>= 4 - for i in range(nb): - r += (x & 1) and str(self.names[offset + i][0]) or '-' - x >>= 1 - invert = r[::-1] - return res + cmdt + ' (' + invert[:nb] + ')' - - -class DRCode (I3BytesEnumField): - def __init__(self, name, default, enum): - """enum is a dict of tuples, so conversion is required before calling the actual init method. # noqa: E501 - Note: the conversion is done only once.""" - enumDict = {} - for k, v in enum.items(): - enumDict[k] = v[0] - I3BytesEnumField.__init__(self, name, default, enumDict) - - def i2repr(self, pkt, x): - cmd = self.i2repr_one(pkt, x) - sx = str(x) - if cmd == sx: - cmd = 'Unknown' - return sx + " (" + cmd + ")" - -########################################################### -# Fields for Diameter AVPs -########################################################### - - -class AVPFlags (FlagsField): - def i2repr(self, pkt, x): - if x is None: - return "None" - res = hex(int(x)) - r = '' - if x & 31: # Check if reserved bits are used - nb = 8 - offset = 0 - else: # Strip the first 5 bits - nb = 3 - offset = 5 - x >>= 5 - for i in range(nb): - r += (x & 1) and str(self.names[offset + i][0]) or '-' - x >>= 1 - invert = r[::-1] - return res + ' (' + invert[:nb] + ')' - - -class AVPVendor (IntField): - def i2repr(self, pkt, x): - vendor = vendorList.get(x, "Unkown_Vendor") - return "%s (%s)" % (vendor, str(x)) - - -# Note the dictionary below is minimal (taken from scapy/layers/dhcp6.py -# + added 3GPP and ETSI -vendorList = { - 9: "ciscoSystems", - 35: "Nortel Networks", - 43: "3Com", - 311: "Microsoft", - 323: "Tekelec", - 2636: "Juniper Networks, Inc.", - 4526: "Netgear", - 5771: "Cisco Systems, Inc.", - 5842: "Cisco Systems", - 8164: "Starent Networks", - 10415: "3GPP", - 13019: "ETSI", - 16885: "Nortel Networks"} - -# The Application IDs for the Diameter command field -AppIDsEnum = { - 0: "Diameter_Common_Messages", - 1: "NASREQ_Application", - 2: "Mobile_IPv4_Application", - 3: "Diameter_Base_Accounting", - 4: "Diameter_Credit_Control_Application", - 5: "EAP_Application", - 6: "Diameter_Session_Initiation_Protocol_(SIP)_Application", - 7: "Diameter_Mobile_IPv6_IKE___(MIP6I)", - 8: "Diameter_Mobile_IPv6_Auth__(MIP6A)", - 111: "ALU_Sy", - 555: "Sun_Ping_Application", - 16777216: "3GPP_Cx", - 16777217: "3GPP_Sh", - 16777222: "3GPP_Gq", - 16777223: "3GPP_Gmb", - 16777224: "3GPP_Gx", - 16777227: "Ericsson_MSI", - 16777228: "Ericsson_Zx", - 16777229: "3GPP_RX", - 16777231: "Diameter_e2e4_Application", - 16777232: "Ericsson_Charging-CIP", - 16777236: "3GPP_Rx", - 16777238: "3GPP_Gx", - 16777250: "3GPP_STa", - 16777251: "3GPP_S6a/S6d", - 16777252: "3GPP_S13/S13'", - 16777255: "3GPP_SLg", - 16777264: "3GPP_SWm", - 16777265: "3GPP_SWx", - 16777266: "3GPP_Gxx", - 16777267: "3GPP_S9", - 16777269: "Ericsson_HSI", - 16777272: "3GPP_S6b", - 16777291: "3GPP_SLh", - 16777292: "3GPP_SGmb", - 16777302: "3GPP_Sy", - 16777304: "Ericsson_Sy", - 16777315: "Ericsson_Diameter_Signalling_Controller_Application_(DSC)", - 4294967295: "Relay", -} - - -########################################################### -# Definition of fields contained in section 4.2 of RFC6733 -# for AVPs payloads -########################################################### - -class OctetString (StrLenField): - def i2repr(self, pkt, x): - try: - return plain_str(x) - except BaseException: - return bytes_hex(x) - - -class Integer32 (SignedIntField): - pass - - -class Integer64 (Field): - def __init__(self, name, default): - Field.__init__(self, name, default, "q") - - -class Unsigned32 (IntField): - pass - - -class Unsigned64 (LongField): - pass - - -class Float32 (IEEEFloatField): - pass - - -class Float64 (IEEEDoubleField): - pass - - -########################################################### -# Definition of additional fields contained in section 4.3 -# of RFC6733 for AVPs payloads -########################################################### - -class Address (StrLenField): - def i2repr(self, pkt, x): - if x.startswith(b'\x00\x01'): # IPv4 address - return inet_ntoa(x[2:]) - elif x.startswith(b'\x00\x02'): # IPv6 address - return inet_ntop(socket.AF_INET6, x[2:]) - else: # Address format not yet decoded - print('Warning: Address format not yet decoded.') - return bytes_hex(x) - - def any2i(self, pkt, x): - if x and isinstance(x, str): - try: # Try IPv4 conversion - s = inet_aton(x) - return b'\x00\x01' + s - except BaseException: - try: # Try IPv6 conversion - s = inet_pton(socket.AF_INET6, x) - return b'\x00\x02' + s - except BaseException: - print('Warning: Address format not supported yet.') - return b'' - - -class Time (IntField): - def i2repr(self, pkt, x): - return ctime(x) - - -class Enumerated (IntEnumField): - def i2repr(self, pkt, x): - if x in self.i2s: - return self.i2s[x] + " (%d)" % x - else: - return repr(x) + " (Unknown)" - - -class IPFilterRule (StrLenField): - pass - - -class Grouped (StrLenField): - """This class is just for declarative purpose because it is used in the AVP definitions dict.""" # noqa: E501 - pass - - -#################################################################### -# Definition of additional fields contained in other standards -#################################################################### - -class QoSFilterRule (StrLenField): # Defined in 4.1.1 of RFC7155 - pass - - -class ISDN (StrLenField): - def i2repr(self, pkt, x): - out = b'' - for char in x: - c = orb(char) - out += chb(48 + (c & 15)) # convert second digit first - v = (c & 240) >> 4 - if v != 15: - out += chb(48 + v) - return out - - def any2i(self, pkt, x): - out = b'' - if x: - fd = True # waiting for first digit - for c in x: - digit = orb(c) - 48 - if fd: - val = digit - else: - val = val + 16 * digit - out += chb(val) - fd = not fd - if not fd: # Fill with 'f' if odd number of characters - out += chb(240 + val) - return out - - -##################################################################### -##################################################################### -# -# AVPs classes and definitions -# -##################################################################### -##################################################################### - -AVP_Code_length = 4 -AVP_Flag_length = 1 -DIAMETER_BYTES_ALIGNMENT = 4 -AVP_Flags_List = ["x", "x", "x", "x", "x", "P", "M", "V"] - - -def GuessAvpType(p, **kargs): - if len(p) > AVP_Code_length + AVP_Flag_length: - # Set AVP code and vendor - avpCode = struct.unpack("!I", p[:AVP_Code_length])[0] - vnd = bool(struct.unpack( - "!B", p[AVP_Code_length:AVP_Code_length + AVP_Flag_length])[0] & 128) # noqa: E501 - vndCode = vnd and struct.unpack("!I", p[8:12])[0] or 0 - # Check if vendor and code defined and fetch the corresponding AVP - # definition - if vndCode in AvpDefDict: - AvpVndDict = AvpDefDict[vndCode] - if avpCode in AvpVndDict: - # Unpack only the first 4 tuple items at this point - avpName, AVPClass, flags = AvpVndDict[avpCode][:3] - result = AVPClass(p, **kargs) - result.name = 'AVP ' + avpName - return result - # Packet too short or AVP vendor or AVP code not found ... - return AVP_Unknown(p, **kargs) - - -class AVP_Generic (Packet): - """ Parent class for the 5 following AVP intermediate classes below""" - - def extract_padding(self, s): - nbBytes = self.avpLen % DIAMETER_BYTES_ALIGNMENT - if nbBytes: - nbBytes = DIAMETER_BYTES_ALIGNMENT - nbBytes - return s[:nbBytes], s[nbBytes:] - - def post_build(self, p, pay): - nbBytes = (-len(p)) % 4 - while nbBytes: - p += struct.pack("B", 0) - nbBytes -= 1 - return p + pay - - def show2(self): - self.__class__(raw(self), name=self.name).show() - - -def AVP(avpId, **fields): - """ Craft an AVP based on its id and optional parameter fields""" - val = None - classType = AVP_Unknown - if isinstance(avpId, str): - try: - for vnd in AvpDefDict: - for code in AvpDefDict[vnd]: - val = AvpDefDict[vnd][code] - if val[0][:len( - avpId)] == avpId: # A prefix of the full name is considered valid # noqa: E501 - raise - found = False - except BaseException: - found = True - else: - if isinstance(avpId, list): - code = avpId[0] - vnd = avpId[1] - else: # Assume this is an int - code = avpId - vnd = 0 - try: - val = AvpDefDict[vnd][code] - found = True - except BaseException: - found = False - if not found: - warning('The AVP identifier %s has not been found.' % str(avpId)) - if isinstance(avpId, str): # The string input is not valid - return None - # At this point code, vnd are provisionned val may be set (if found is True) # noqa: E501 - # Set/override AVP code - fields['avpCode'] = code - # Set vendor if not already defined and relevant - if 'avpVnd' not in fields and vnd: - fields['avpVnd'] = vnd - # Set flags if not already defined and possible ... - if 'avpFlags' not in fields: - if val: - fields['avpFlags'] = val[2] - else: - fields['avpFlags'] = vnd and 128 or 0 - # Finally, set the name and class if possible - if val: - classType = val[1] - _ret = classType(**fields) - if val: - _ret.name = 'AVP ' + val[0] - return _ret - - -# AVP intermediate classes: -############################ - -class AVP_FL_NV (AVP_Generic): - """ Defines the AVP of Fixed Length with No Vendor field.""" - fields_desc = [ - IntField("avpCode", None), - AVPFlags("avpFlags", None, 8, AVP_Flags_List), - X3BytesField("avpLen", None) - ] - - -class AVP_FL_V (AVP_Generic): - """ Defines the AVP of Fixed Length with Vendor field.""" - fields_desc = [ - IntField("avpCode", None), - AVPFlags("avpFlags", None, 8, AVP_Flags_List), - X3BytesField("avpLen", None), - AVPVendor("avpVnd", 0) - ] - - -class AVP_VL_NV (AVP_Generic): - """ Defines the AVP of Variable Length with No Vendor field.""" - fields_desc = [ - IntField("avpCode", None), - AVPFlags("avpFlags", None, 8, AVP_Flags_List), - I3FieldLenField("avpLen", None, length_of="val", - adjust=lambda pkt, x:x + 8) - ] - - -class AVP_VL_V (AVP_Generic): - """ Defines the AVP of Variable Length with Vendor field.""" - fields_desc = [ - IntField("avpCode", None), - AVPFlags("avpFlags", None, 8, AVP_Flags_List), - I3FieldLenField("avpLen", None, length_of="val", - adjust=lambda pkt, x:x + 12), - AVPVendor("avpVnd", 0) - ] - - -class AVP_Unknown (AVP_Generic): - """ The default structure for AVPs which could not be decoded (optional vendor field, variable length). """ # noqa: E501 - name = 'AVP Unknown' - fields_desc = [ - IntField("avpCode", None), - AVPFlags("avpFlags", None, 8, AVP_Flags_List), - I3FieldLenField("avpLen", None, length_of="val", - adjust=lambda pkt, x:x + 8 + ((pkt.avpFlags & 0x80) >> 5)), # noqa: E501 - ConditionalField(AVPVendor("avpVnd", 0), lambda pkt:pkt.avpFlags & 0x80), # noqa: E501 - StrLenField("val", None, - length_from=lambda pkt:pkt.avpLen - 8 - ((pkt.avpFlags & 0x80) >> 5)) # noqa: E501 - ] - - -# AVP 'low level' classes: -############################ - -class AVPV_StrLenField (AVP_VL_V): - fields_desc = [ - AVP_VL_V, - StrLenField("val", None, length_from=lambda pkt:pkt.avpLen - 12) - ] - - -class AVPNV_StrLenField (AVP_VL_NV): - fields_desc = [ - AVP_VL_NV, - StrLenField("val", None, length_from=lambda pkt:pkt.avpLen - 8) - ] - - -class AVPV_OctetString (AVP_VL_V): - fields_desc = [ - AVP_VL_V, - OctetString("val", None, length_from=lambda pkt:pkt.avpLen - 12) - ] - - -class AVPNV_OctetString (AVP_VL_NV): - fields_desc = [ - AVP_VL_NV, - OctetString("val", None, length_from=lambda pkt:pkt.avpLen - 8) - ] - - -class AVPV_Grouped (AVP_VL_V): - fields_desc = [ - AVP_VL_V, - PacketListField('val', [], GuessAvpType, - length_from=lambda pkt:pkt.avpLen - 12) - ] - - -class AVPNV_Grouped (AVP_VL_NV): - fields_desc = [ - AVP_VL_NV, - PacketListField('val', [], GuessAvpType, - length_from=lambda pkt:pkt.avpLen - 8)] - - -class AVPV_Unsigned32 (AVP_FL_V): - avpLen = 16 - fields_desc = [AVP_FL_V, Unsigned32('val', None)] - - -class AVPNV_Unsigned32 (AVP_FL_NV): - avpLen = 12 - fields_desc = [AVP_FL_NV, Unsigned32('val', None)] - - -class AVPV_Integer32 (AVP_FL_V): - avpLen = 16 - fields_desc = [AVP_FL_V, Integer32('val', None)] - - -class AVPNV_Integer32 (AVP_FL_NV): - avpLen = 12 - fields_desc = [AVP_FL_NV, Integer32('val', None)] - - -class AVPV_Unsigned64 (AVP_FL_V): - avpLen = 20 - fields_desc = [AVP_FL_V, Unsigned64('val', None)] - - -class AVPNV_Unsigned64 (AVP_FL_NV): - avpLen = 16 - fields_desc = [AVP_FL_NV, Unsigned64('val', None)] - - -class AVPV_Integer64 (AVP_FL_V): - avpLen = 20 - fields_desc = [AVP_FL_V, Integer64('val', None)] - - -class AVPNV_Integer64 (AVP_FL_NV): - avpLen = 16 - fields_desc = [AVP_FL_NV, Integer64('val', None)] - - -class AVPV_Time (AVP_FL_V): - avpLen = 16 - fields_desc = [AVP_FL_V, Time("val", None)] - - -class AVPNV_Time (AVP_FL_NV): - avpLen = 12 - fields_desc = [AVP_FL_NV, Time("val", None)] - - -class AVPV_Address (AVP_VL_V): - fields_desc = [ - AVP_VL_V, - Address("val", None, length_from=lambda pkt:pkt.avpLen - 12) - ] - - -class AVPNV_Address (AVP_VL_NV): - fields_desc = [ - AVP_VL_NV, - Address("val", None, length_from=lambda pkt:pkt.avpLen - 8) - ] - - -class AVPV_IPFilterRule (AVP_VL_V): - fields_desc = [ - AVP_VL_V, - IPFilterRule("val", None, length_from=lambda pkt:pkt.avpLen - 12) - ] - - -class AVPNV_IPFilterRule (AVP_VL_NV): - fields_desc = [ - AVP_VL_NV, - IPFilterRule("val", None, length_from=lambda pkt:pkt.avpLen - 8) - ] - - -class AVPV_QoSFilterRule (AVP_VL_V): - fields_desc = [ - AVP_VL_V, - QoSFilterRule("val", None, length_from=lambda pkt:pkt.avpLen - 12) - ] - - -class AVPNV_QoSFilterRule (AVP_VL_NV): - fields_desc = [ - AVP_VL_NV, - QoSFilterRule("val", None, length_from=lambda pkt:pkt.avpLen - 8) - ] - - -############################################### -# Actual AVPs based on previous parent classes -############################################### - -# AVP special classes (which required interpretation/adaptation from standard) -############################################################################## - -class AVP_0_258 (AVP_FL_NV): - name = 'AVP Auth-Application-Id' - avpLen = 12 - fields_desc = [AVP_FL_NV, Enumerated('val', None, AppIDsEnum)] - - -class AVP_0_266 (AVP_FL_NV): - name = 'AVP Vendor-Id' - avpLen = 12 - fields_desc = [AVP_FL_NV, Enumerated('val', None, vendorList)] - - -class AVP_0_268 (AVP_FL_NV): - name = 'AVP Result-Code' - avpLen = 12 - fields_desc = [AVP_FL_NV, - Enumerated('val', - None, - {1001: "DIAMETER_MULTI_ROUND_AUTH", - 2001: "DIAMETER_SUCCESS", - 2002: "DIAMETER_LIMITED_SUCCESS", - 2003: "DIAMETER_FIRST_REGISTRATION", - 2004: "DIAMETER_SUBSEQUENT_REGISTRATION", - 2005: "DIAMETER_UNREGISTERED_SERVICE", - 2006: "DIAMETER_SUCCESS_SERVER_NAME_NOT_STORED", - 2007: "DIAMETER_SERVER_SELECTION", - 2008: "DIAMETER_SUCCESS_AUTH_SENT_SERVER_NOT_STORED", # noqa: E501 - 2009: "DIAMETER_SUCCESS_RELOCATE_HA", - 3001: "DIAMETER_COMMAND_UNSUPPORTED", - 3002: "DIAMETER_UNABLE_TO_DELIVER", - 3003: "DIAMETER_REALM_NOT_SERVED", - 3004: "DIAMETER_TOO_BUSY", - 3005: "DIAMETER_LOOP_DETECTED", - 3006: "DIAMETER_REDIRECT_INDICATION", - 3007: "DIAMETER_APPLICATION_UNSUPPORTED", - 3008: "DIAMETER_INVALID_HDR_BITS", - 3009: "DIAMETER_INVALID_AVP_BITS", - 3010: "DIAMETER_UNKNOWN_PEER", - 4001: "DIAMETER_AUTHENTICATION_REJECTED", - 4002: "DIAMETER_OUT_OF_SPACE", - 4003: "DIAMETER_ELECTION_LOST", - 4005: "DIAMETER_ERROR_MIP_REPLY_FAILURE", - 4006: "DIAMETER_ERROR_HA_NOT_AVAILABLE", - 4007: "DIAMETER_ERROR_BAD_KEY", - 4008: "DIAMETER_ERROR_MIP_FILTER_NOT_SUPPORTED", - 4010: "DIAMETER_END_USER_SERVICE_DENIED", - 4011: "DIAMETER_CREDIT_CONTROL_NOT_APPLICABLE", - 4012: "DIAMETER_CREDIT_LIMIT_REACHED", - 4013: "DIAMETER_USER_NAME_REQUIRED", - 4241: "DIAMETER_END_USER_SERVICE_DENIED", - 5001: "DIAMETER_AVP_UNSUPPORTED", - 5002: "DIAMETER_UNKNOWN_SESSION_ID", - 5003: "DIAMETER_AUTHORIZATION_REJECTED", - 5004: "DIAMETER_INVALID_AVP_VALUE", - 5005: "DIAMETER_MISSING_AVP", - 5006: "DIAMETER_RESOURCES_EXCEEDED", - 5007: "DIAMETER_CONTRADICTING_AVPS", - 5008: "DIAMETER_AVP_NOT_ALLOWED", - 5009: "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES", - 5010: "DIAMETER_NO_COMMON_APPLICATION", - 5011: "DIAMETER_UNSUPPORTED_VERSION", - 5012: "DIAMETER_UNABLE_TO_COMPLY", - 5013: "DIAMETER_INVALID_BIT_IN_HEADER", - 5014: "DIAMETER_INVALID_AVP_LENGTH", - 5015: "DIAMETER_INVALID_MESSAGE_LENGTH", - 5016: "DIAMETER_INVALID_AVP_BIT_COMBO", - 5017: "DIAMETER_NO_COMMON_SECURITY", - 5018: "DIAMETER_RADIUS_AVP_UNTRANSLATABLE", - 5024: "DIAMETER_ERROR_NO_FOREIGN_HA_SERVICE", - 5025: "DIAMETER_ERROR_END_TO_END_MIP_KEY_ENCRYPTION", # noqa: E501 - 5030: "DIAMETER_USER_UNKNOWN", - 5031: "DIAMETER_RATING_FAILED", - 5032: "DIAMETER_ERROR_USER_UNKNOWN", - 5033: "DIAMETER_ERROR_IDENTITIES_DONT_MATCH", - 5034: "DIAMETER_ERROR_IDENTITY_NOT_REGISTERED", - 5035: "DIAMETER_ERROR_ROAMING_NOT_ALLOWED", - 5036: "DIAMETER_ERROR_IDENTITY_ALREADY_REGISTERED", # noqa: E501 - 5037: "DIAMETER_ERROR_AUTH_SCHEME_NOT_SUPPORTED", # noqa: E501 - 5038: "DIAMETER_ERROR_IN_ASSIGNMENT_TYPE", - 5039: "DIAMETER_ERROR_TOO_MUCH_DATA", - 5040: "DIAMETER_ERROR_NOT SUPPORTED_USER_DATA", - 5041: "DIAMETER_ERROR_MIP6_AUTH_MODE", - 5241: "DIAMETER_END_USER_NOT_FOUND", - })] - - -class AVP_0_298 (AVP_FL_NV): - name = 'AVP Experimental-Result-Code' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated( - 'val', - None, - { - 2001: "DIAMETER_FIRST_REGISTRATION", - 2002: "DIAMETER_SUBSEQUENT_REGISTRATION", - 2003: "DIAMETER_UNREGISTERED_SERVICE", - 2004: "DIAMETER_SUCCESS_SERVER_NAME_NOT_STORED", - 2021: "DIAMETER_PDP_CONTEXT_DELETION_INDICATION", - 4100: "DIAMETER_USER_DATA_NOT_AVAILABLE", - 4101: "DIAMETER_PRIOR_UPDATE_IN_PROGRESS", - 4121: "DIAMETER_ERROR_OUT_OF_RESOURCES", - 4141: "DIAMETER_PCC_BEARER_EVENT", - 4181: "DIAMETER_AUTHENTICATION_DATA_UNAVAILABLE", - 4201: "DIAMETER_ERROR_ABSENT_USER", - 4221: "DIAMETER_ERROR_UNREACHABLE_USER", - 4222: "DIAMETER_ERROR_SUSPENDED_USER", - 4223: "DIAMETER_ERROR_DETACHED_USER", - 4224: "DIAMETER_ERROR_POSITIONING_DENIED", - 4225: "DIAMETER_ERROR_POSITIONING_FAILED", - 4226: "DIAMETER_ERROR_UNKNOWN_UNREACHABLE LCS_CLIENT", - 5001: "DIAMETER_ERROR_USER_UNKNOWN", - 5002: "DIAMETER_ERROR_IDENTITIES_DONT_MATCH", - 5003: "DIAMETER_ERROR_IDENTITY_NOT_REGISTERED", - 5004: "DIAMETER_ERROR_ROAMING_NOT_ALLOWED", - 5005: "DIAMETER_ERROR_IDENTITY_ALREADY_REGISTERED", - 5006: "DIAMETER_ERROR_AUTH_SCHEME_NOT_SUPPORTED", - 5007: "DIAMETER_ERROR_IN_ASSIGNMENT_TYPE", - 5008: "DIAMETER_ERROR_TOO_MUCH_DATA", - 5009: "DIAMETER_ERROR_NOT_SUPPORTED_USER_DATA", - 5010: "DIAMETER_MISSING_USER_ID", - 5011: "DIAMETER_ERROR_FEATURE_UNSUPPORTED", - 5041: "DIAMETER_ERROR_USER_NO_WLAN_SUBSCRIPTION", - 5042: "DIAMETER_ERROR_W-APN_UNUSED_BY_USER", - 5043: "DIAMETER_ERROR_W-DIAMETER_ERROR_NO_ACCESS_INDEPENDENT_SUBSCRIPTION", # noqa: E501 - 5044: "DIAMETER_ERROR_USER_NO_W-APN_SUBSCRIPTION", - 5045: "DIAMETER_ERROR_UNSUITABLE_NETWORK", - 5061: "INVALID_SERVICE_INFORMATION", - 5062: "FILTER_RESTRICTIONS", - 5063: "REQUESTED_SERVICE_NOT_AUTHORIZED", - 5064: "DUPLICATED_AF_SESSION", - 5065: "IP-CAN_SESSION_NOT_AVAILABLE", - 5066: "UNAUTHORIZED_NON_EMERGENCY_SESSION", - 5100: "DIAMETER_ERROR_USER_DATA_NOT_RECOGNIZED", - 5101: "DIAMETER_ERROR_OPERATION_NOT_ALLOWED", - 5102: "DIAMETER_ERROR_USER_DATA_CANNOT_BE_READ", - 5103: "DIAMETER_ERROR_USER_DATA_CANNOT_BE_MODIFIED", - 5104: "DIAMETER_ERROR_USER_DATA_CANNOT_BE_NOTIFIED", - 5105: "DIAMETER_ERROR_TRANSPARENT_DATA_OUT_OF_SYNC", - 5106: "DIAMETER_ERROR_SUBS_DATA_ABSENT", - 5107: "DIAMETER_ERROR_NO_SUBSCRIPTION_TO_DATA", - 5108: "DIAMETER_ERROR_DSAI_NOT_AVAILABLE", - 5120: "DIAMETER_ERROR_START_INDICATION", - 5121: "DIAMETER_ERROR_STOP_INDICATION", - 5122: "DIAMETER_ERROR_UNKNOWN_MBMS_BEARER_SERVICE", - 5123: "DIAMETER_ERROR_SERVICE_AREA", - 5140: "DIAMETER_ERROR_INITIAL_PARAMETERS", - 5141: "DIAMETER_ERROR_TRIGGER_EVENT", - 5142: "DIAMETER_BEARER_EVENT", - 5143: "DIAMETER_ERROR_BEARER_NOT_AUTHORIZED", - 5144: "DIAMETER_ERROR_TRAFFIC_MAPPING_INFO_REJECTED", - 5145: "DIAMETER_QOS_RULE_EVENT", - 5146: "DIAMETER_ERROR_TRAFFIC_MAPPING_INFO_REJECTED", - 5147: "DIAMETER_ERROR_CONFLICTING_REQUEST", - 5401: "DIAMETER_ERROR_IMPI_UNKNOWN", - 5402: "DIAMETER_ERROR_NOT_AUTHORIZED", - 5403: "DIAMETER_ERROR_TRANSACTION_IDENTIFIER_INVALID", - 5420: "DIAMETER_ERROR_UNKNOWN_EPS_SUBSCRIPTION", - 5421: "DIAMETER_ERROR_RAT_NOT_ALLOWED", - 5422: "DIAMETER_ERROR_EQUIPMENT_UNKNOWN", - 5423: "DIAMETER_ERROR_UNKNOWN_SERVING_NODE", - 5450: "DIAMETER_ERROR_USER_NO_NON_3GPP_SUBSCRIPTION", - 5451: "DIAMETER_ERROR_USER_NO_APN_SUBSCRIPTION", - 5452: "DIAMETER_ERROR_RAT_TYPE_NOT_ALLOWED", - 5470: "DIAMETER_ERROR_SUBSESSION", - 5490: "DIAMETER_ERROR_UNAUTHORIZED_REQUESTING_NETWORK", - 5510: "DIAMETER_ERROR_UNAUTHORIZED_REQUESTING_ENTITY", - 5511: "DIAMETER_ERROR_UNAUTHORIZED_SERVICE", - 5530: "DIAMETER_ERROR_INVALID_SME_ADDRESS", - 5531: "DIAMETER_ERROR_SC_CONGESTION", - 5532: "DIAMETER_ERROR_SM_PROTOCOL", - })] - - -class AVP_10415_630 (AVP_FL_V): - name = 'AVP Feature-List' - avpLen = 16 - fields_desc = [AVP_FL_V, - FlagsField('val', None, 32, - ['SiFC', - 'AliasInd', - 'IMSRestorationInd', - 'b3', - 'b4', - 'b5', - 'b6', - 'b7', - 'b8', - 'b9', - 'b10', - 'b11', - 'b12', - 'b13', - 'b14', - 'b15', - 'b16', - 'b17', - 'b18', - 'b19', - 'b20', - 'b21', - 'b22', - 'b23', - 'b24', - 'b25', - 'b26', - 'b27', - 'b28', - 'b29', - 'b30', - 'b31'])] - - -class AVP_10415_701 (AVP_VL_V): - name = 'AVP MSISDN' - fields_desc = [AVP_VL_V, ISDN('val', None, - length_from=lambda pkt:pkt.avpLen - 12)] - - -class AVP_10415_1643 (AVP_VL_V): - name = 'AVP A_MSISDN' - fields_desc = [AVP_VL_V, ISDN('val', None, - length_from=lambda pkt:pkt.avpLen - 12)] - - -# AVP enumerated classes (which could not be defined in AvpDefDict dict below) -############################################################################## - -class AVP_0_6 (AVP_FL_NV): - name = 'Service-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated('val', None, - { - 0: "Unknown", - 1: "Login", - 2: "Framed", - 3: "Callback-Login", - 4: "Callback-Framed", - 5: "Outbound", - 6: "Administrative", - 7: "NAS-Prompt", - 8: "Authenticate-Only", - 9: "Callback-NAS-Prompt", - 10: "Call Check", - 11: "Callback Administrative", - 12: "Voice", - 13: "Fax", - 14: "Modem Relay", - 15: "IAPP-Register", - 16: "IAPP-AP-Check", - 17: "Authorize Only", - 18: "Framed-Management", - })] - - -class AVP_0_7 (AVP_FL_NV): - name = 'Framed-Protocol' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated('val', None, - { - 1: "PPP", - 2: "SLIP", - 3: "ARAP", - 4: "Gandalf", - 5: "Xylogics", - 6: "X.75", - 7: "GPRS PDP Context", - 255: "Ascend-ARA", - 256: "MPP", - 257: "EURAW", - 258: "EUUI", - 259: "X25", - 260: "COMB", - 261: "FR", - })] - - -class AVP_0_10 (AVP_FL_NV): - name = 'Framed-Routing' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated('val', None, - { - 0: "None", - 1: "Send routing packets", - 2: "Listen for routing packets", - 3: "Send and Listen ", - })] - - -class AVP_0_13 (AVP_FL_NV): - name = 'Framed-Compression' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated('val', None, - {0: "None", 2: "IPX header compression", 3: "Stac-LZS compression", }) # noqa: E501 - ] - - -class AVP_0_15 (AVP_FL_NV): - name = 'Login-Service' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated('val', None, - { - 0: "Telnet", - 1: "Rlogin", - 2: "TCP-Clear", - 3: "PortMaster", - 4: "LAT", - 5: "X25-PAD", - 6: "X25-T3POS", - 7: "Unassigned", - })] - - -class AVP_0_45 (AVP_FL_NV): - name = 'Acct-Authentic' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated('val', None, - {0: "None", 1: "RADIUS", 2: "Local", 3: "Remote", 4: "Diameter", })] # noqa: E501 - - -class AVP_0_61 (AVP_FL_NV): - name = 'NAS-Port-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated('val', None, - { - 0: "Async", - 1: "Sync", - 2: "ISDN-Sync", - 3: "ISDN-Async-v120", - 4: "ISDN-Async-v110", - 5: "Virtual", - 6: "PIAFS", - 7: "HDLC-Clear-Channel", - 8: "X25", - 9: "X75", - 10: "G.3 Fax", - 11: "SDSL - Symmetric DSL", - 14: "IDSL - ISDN Digital Subscriber Line", - 15: "Ethernet", - 16: "xDSL - Digital Subscriber Line of unknown type", - 17: "Cable", - 18: "Wireless - Other", - 19: "Wireless - IEEE 802.11", - 20: "Token-Ring", - 21: "FDDI", - 22: "Wireless - CDMA2000", - 23: "Wireless - UMTS", - 24: "Wireless - 1X-EV", - 25: "IAPP", - 26: "FTTP - Fiber to the Premises", - 27: "Wireless - IEEE 802.16", - 28: "Wireless - IEEE 802.20", - 29: "Wireless - IEEE 802.22", - 30: "PPPoA - PPP over ATM", - 31: "PPPoEoA - PPP over Ethernet over ATM", - 32: "PPPoEoE - PPP over Ethernet over Ethernet", - 33: "PPPoEoVLAN - PPP over Ethernet over VLAN", - 34: "PPPoEoQinQ - PPP over Ethernet over IEEE 802.1QinQ", # noqa: E501 - 35: "xPON - Passive Optical Network", - 36: "Wireless - XGP", - })] - - -class AVP_0_64 (AVP_FL_NV): - name = 'Tunnel-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated('val', None, - { - 1: "PPTP", - 2: "L2F", - 3: "L2TP", - 4: "ATMP", - 5: "VTP", - 6: "AH", - 7: "IP-IP-Encap", - 8: "MIN-IP-IP", - 9: "ESP", - 10: "GRE", - 11: "DVS", - 12: "IP-in-IP Tunneling", - 13: "VLAN", - })] - - -class AVP_0_65 (AVP_FL_NV): - name = 'Tunnel-Medium-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated('val', None, - { - 1: "IPv4", - 2: "IPv6", - 3: "NSAP", - 4: "HDLC", - 5: "BBN", - 6: "IEEE-802", - 7: "E-163", - 8: "E-164", - 9: "F-69", - 10: "X-121", - 11: "IPX", - 12: "Appletalk-802", - 13: "Decnet4", - 14: "Vines", - 15: "E-164-NSAP", - })] - - -class AVP_0_72 (AVP_FL_NV): - name = 'ARAP-Zone-Access' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated('val', None, - { - 1: "Only allow access to default zone", - 2: "Use zone filter inclusively", - 3: "Use zone filter exclusively", - })] - - -class AVP_0_76 (AVP_FL_NV): - name = 'Prompt' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated('val', None, {0: "No Echo", 1: "Echo", }) - ] - - -class AVP_0_261 (AVP_FL_NV): - name = 'Redirect-Host-Usage' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated('val', None, - { - 0: "Don't Care", - 1: "All Session", - 2: "All Realm", - 3: "Realm and Application", - 4: "All Application", - 5: "All Host", - 6: "ALL_USER", - })] - - -class AVP_0_271 (AVP_FL_NV): - name = 'Session-Server-Failover' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated('val', None, - {0: "REFUSE_SERVICE", 1: "TRY_AGAIN", 2: "ALLOW_SERVICE", 3: "TRY_AGAIN_ALLOW_SERVICE", })] # noqa: E501 - - -class AVP_0_273 (AVP_FL_NV): - name = 'Disconnect-Cause' - avpLen = 12 - fields_desc = [AVP_FL_NV, Enumerated('val', None, {0: "REBOOTING", 1: "BUSY", 2: "DO_NOT_WANT_TO_TALK_TO_YOU", })] # noqa: E501 - - -class AVP_0_274 (AVP_FL_NV): - name = 'Auth-Request-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, { - 1: "AUTHENTICATE_ONLY", 2: "AUTHORIZE_ONLY", 3: "AUTHORIZE_AUTHENTICATE", })] # noqa: E501 - - -class AVP_0_277 (AVP_FL_NV): - name = 'Auth-Session-State' - avpLen = 12 - fields_desc = [AVP_FL_NV, Enumerated('val', None, {0: "STATE_MAINTAINED", 1: "NO_STATE_MAINTAINED", })] # noqa: E501 - - -class AVP_0_285 (AVP_FL_NV): - name = 'Re-Auth-Request-Type' - avpLen = 12 - fields_desc = [AVP_FL_NV, Enumerated('val', None, {0: "AUTHORIZE_ONLY", 1: "AUTHORIZE_AUTHENTICATE", })] # noqa: E501 - - -class AVP_0_295 (AVP_FL_NV): - name = 'Termination-Cause' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated( - 'val', - None, - { - 1: "DIAMETER_LOGOUT", - 2: "DIAMETER_SERVICE_NOT_PROVIDED", - 3: "DIAMETER_BAD_ANSWER", - 4: "DIAMETER_ADMINISTRATIVE", - 5: "DIAMETER_LINK_BROKEN", - 6: "DIAMETER_AUTH_EXPIRED", - 7: "DIAMETER_USER_MOVED", - 8: "DIAMETER_SESSION_TIMEOUT", - })] - - -class AVP_0_345 (AVP_FL_NV): - name = 'MIP-Algorithm-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, {2: "HMAC-SHA-1", })] - - -class AVP_0_346 (AVP_FL_NV): - name = 'MIP-Replay-Mode' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, {1: "None", 2: "Timestamps", 3: "Nonces", })] # noqa: E501 - - -class AVP_0_375 (AVP_FL_NV): - name = 'SIP-Server-Assignment-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated( - 'val', - None, - { - 0: "NO_ASSIGNMENT", - 1: "REGISTRATION", - 2: "RE_REGISTRATION", - 3: "UNREGISTERED_USER", - 4: "TIMEOUT_DEREGISTRATION", - 5: "USER_DEREGISTRATION", - 6: "TIMEOUT_DEREGISTRATION_STORE_SERVER_NAME", - 7: "USER_DEREGISTRATION_STORE_SERVER_NAME", - 8: "ADMINISTRATIVE_DEREGISTRATION", - 9: "AUTHENTICATION_FAILURE", - 10: "AUTHENTICATION_TIMEOUT", - 11: "DEREGISTRATION_TOO_MUCH_DATA", - })] - - -class AVP_0_377 (AVP_FL_NV): - name = 'SIP-Authentication-Scheme' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, {0: "DIGEST", })] - - -class AVP_0_384 (AVP_FL_NV): - name = 'SIP-Reason-Code' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated( - 'val', - None, - { - 0: "PERMANENT_TERMINATION", - 1: "NEW_SIP_SERVER_ASSIGNED", - 2: "SIP_SERVER_CHANGE", - 3: "REMOVE_SIP_SERVER", - })] - - -class AVP_0_387 (AVP_FL_NV): - name = 'SIP-User-Authorization-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, { - 0: "REGISTRATION", 1: "DEREGISTRATION", 2: "REGISTRATION_AND_CAPABILITIES", })] # noqa: E501 - - -class AVP_0_392 (AVP_FL_NV): - name = 'SIP-User-Data-Already-Available' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, { - 0: "USER_DATA_NOT_AVAILABLE", 1: "USER_DATA_ALREADY_AVAILABLE", })] - - -class AVP_0_403 (AVP_FL_NV): - name = 'CHAP-Algorithm' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, {5: "CHAP with MD5", })] - - -class AVP_0_406 (AVP_FL_NV): - name = 'Accounting-Auth-Method' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, { - 1: "PAP", 2: "CHAP", 3: "MS-CHAP-1", 4: "MS-CHAP-2", 5: "EAP", 6: "Undefined", 7: "None", })] # noqa: E501 - - -class AVP_0_416 (AVP_FL_NV): - name = 'CC-Request-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, { - 1: "INITIAL_REQUEST", 2: "UPDATE_REQUEST", 3: "TERMINATION_REQUEST", 4: "EVENT_REQUEST", })] # noqa: E501 - - -class AVP_0_418 (AVP_FL_NV): - name = 'CC-Session-Failover' - avpLen = 12 - fields_desc = [AVP_FL_NV, Enumerated('val', None, {0: "FAILOVER_NOT_SUPPORTED", 1: "FAILOVER_SUPPORTED", })] # noqa: E501 - - -class AVP_0_422 (AVP_FL_NV): - name = 'Check-Balance-Result' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, {0: "ENOUGH_CREDIT", 1: "NO_CREDIT", })] # noqa: E501 - - -class AVP_0_426 (AVP_FL_NV): - name = 'Credit-Control' - avpLen = 12 - fields_desc = [AVP_FL_NV, Enumerated('val', None, {0: "CREDIT_AUTHORIZATION", 1: "RE_AUTHORIZATION", })] # noqa: E501 - - -class AVP_0_427 (AVP_FL_NV): - name = 'Credit-Control-Failure-Handling' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, { - 0: "TERMINATE", 1: "CONTINUE", 2: "RETRY_AND_TERMINATE", })] - - -class AVP_0_428 (AVP_FL_NV): - name = 'Direct-Debiting-Failure-Handling' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, {0: "TERMINATE_OR_BUFFER", 1: "CONTINUE", })] # noqa: E501 - - -class AVP_0_433 (AVP_FL_NV): - name = 'Redirect-Address-Type' - avpLen = 12 - fields_desc = [AVP_FL_NV, Enumerated('val', None, {0: "IPV4_ADDRESS", 1: "IPV6_ADDRESS", 2: "URL", 3: "SIP_URI", })] # noqa: E501 - - -class AVP_0_436 (AVP_FL_NV): - name = 'Requested-Action' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, { - 0: "DIRECT_DEBITING", 1: "REFUND_ACCOUNT", 2: "CHECK_BALANCE", 3: "PRICE_ENQUIRY", })] # noqa: E501 - - -class AVP_0_449 (AVP_FL_NV): - name = 'Final-Unit-Action' - avpLen = 12 - fields_desc = [AVP_FL_NV, Enumerated('val', None, {0: "TERMINATE", 1: "REDIRECT", 2: "RESTRICT_ACCESS", })] # noqa: E501 - - -class AVP_0_450 (AVP_FL_NV): - name = 'Subscription-Id-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated( - 'val', - None, - { - 0: "END_USER_E164", - 1: "END_USER_IMSI", - 2: "END_USER_SIP_URI", - 3: "END_USER_NAI", - 4: "END_USER_PRIVATE", - })] - - -class AVP_0_452 (AVP_FL_NV): - name = 'Tariff-Change-Usage' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, { - 0: "UNIT_BEFORE_TARIFF_CHANGE", 1: "UNIT_AFTER_TARIFF_CHANGE", 2: "UNIT_INDETERMINATE", })] # noqa: E501 - - -class AVP_0_454 (AVP_FL_NV): - name = 'CC-Unit-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated( - 'val', - None, - { - 0: "TIME", - 1: "MONEY", - 2: "TOTAL-OCTETS", - 3: "INPUT-OCTETS", - 4: "OUTPUT-OCTETS", - 5: "SERVICE-SPECIFIC-UNITS", - })] - - -class AVP_0_455 (AVP_FL_NV): - name = 'Multiple-Services-Indicator' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, { - 0: "MULTIPLE_SERVICES_NOT_SUPPORTED", 1: "MULTIPLE_SERVICES_SUPPORTED", })] # noqa: E501 - - -class AVP_0_459 (AVP_FL_NV): - name = 'User-Equipment-Info-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, { - 0: "IMEISV", 1: "MAC", 2: "EUI64", 3: "MODIFIED_EUI64", })] - - -class AVP_0_480 (AVP_FL_NV): - name = 'Accounting-Record-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, { - 1: "Event Record", 2: "Start Record", 3: "Interim Record", 4: "Stop Record", })] # noqa: E501 - - -class AVP_0_483 (AVP_FL_NV): - name = 'Accounting-Realtime-Required' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, { - 0: "Reserved", 1: "DELIVER_AND_GRANT", 2: "GRANT_AND_STORE", 3: "GRANT_AND_LOSE", })] # noqa: E501 - - -class AVP_0_494 (AVP_FL_NV): - name = 'MIP6-Auth-Mode' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, {0: "Reserved", 1: "IP6_AUTH_MN_AAA", })] # noqa: E501 - - -class AVP_0_513 (AVP_FL_NV): - name = 'Protocol' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, { - 1: "ICMP", 2: "IGMP", 4: "IPv4", 6: "TCP", 17: "UDP", 132: "SCTP", })] # noqa: E501 - - -class AVP_0_514 (AVP_FL_NV): - name = 'Direction' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, {0: "IN", 1: "OUT", 2: "BOTH", })] - - -class AVP_0_517 (AVP_FL_NV): - name = 'Negated' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, {0: "False", 1: "True", })] - - -class AVP_0_534 (AVP_FL_NV): - name = 'Use-Assigned-Address' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, {0: "False", 1: "True", })] - - -class AVP_0_535 (AVP_FL_NV): - name = 'Diffserv-Code-Point' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated( - 'val', - None, - { - 0: "CS0", - 8: "CS1", - 10: "AF11", - 12: "AF12", - 14: "AF13", - 16: "CS2", - 18: "AF21", - 20: "AF22", - 22: "AF23", - 24: "CS3", - 26: "AF31", - 28: "AF32", - 30: "AF33", - 32: "CS4", - 34: "AF41", - 36: "AF42", - 38: "AF43", - 40: "CS5", - 46: "EF_PHB", - 48: "CS6", - 56: "CS7", - })] - - -class AVP_0_536 (AVP_FL_NV): - name = 'Fragmentation-Flag' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, {0: "Don't Fragment", 1: "More Fragments", })] # noqa: E501 - - -class AVP_0_538 (AVP_FL_NV): - name = 'IP-Option-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated( - 'val', - None, - { - 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 AVP_0_541 (AVP_FL_NV): - name = 'TCP-Option-Type' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated( - 'val', - None, - { - 0: "EOL", - 1: "NOP", - 2: "MSS", - 3: "WScale", - 4: "SAckOK", - 5: "SAck", - 8: "Timestamp", - 14: "AltChkSum", - 15: "AltChkSumOpt", - 25: "Mood", - })] - - -class AVP_0_546 (AVP_FL_NV): - name = 'ICMP-Type-Number' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated( - 'val', - None, - { - 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", - })] - - -class AVP_0_547 (AVP_FL_NV): - name = 'ICMP-Code' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, {0: "TBD", })] - - -class AVP_0_570 (AVP_FL_NV): - name = 'Timezone-Flag' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, Enumerated('val', None, {0: "UTC", 1: "LOCAL", 2: "OFFSET", })] # noqa: E501 - - -class AVP_0_575 (AVP_FL_NV): - name = 'QoS-Semantics' - avpLen = 12 - fields_desc = [ - AVP_FL_NV, - Enumerated( - 'val', - None, - { - 0: "QoS_Desired", - 1: "QoS_Available", - 2: "QoS_Delivered", - 3: "Minimum_QoS", - 4: "QoS_Authorized", - })] - - -class AVP_10415_500 (AVP_FL_V): - name = 'Abort-Cause' - avpLen = 16 - fields_desc = [AVP_FL_V, - Enumerated('val', - None, - {0: "BEARER_RELEASED", - 1: "INSUFFICIENT_SERVER_RESOURCES", - 2: "INSUFFICIENT_BEARER_RESOURCES", - })] - - -class AVP_10415_511 (AVP_FL_V): - name = 'Flow-Status' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "ENABLED-UPLINK", 1: "ENABLED-DOWNLINK", 2: "ENABLED", 3: "DISABLED", 4: "REMOVED", })] # noqa: E501 - - -class AVP_10415_512 (AVP_FL_V): - name = 'Flow-Usage' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "NO_INFORMATION", 1: "RTCP", 2: "AF_SIGNALLING", })] # noqa: E501 - - -class AVP_10415_513 (AVP_FL_V): - name = 'Specific-Action' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 1: "CHARGING_CORRELATION_EXCHANGE", - 2: "INDICATION_OF_LOSS_OF_BEARER", - 3: "INDICATION_OF_RECOVERY_OF_BEARER", - 4: "INDICATION_OF_RELEASE_OF_BEARER", - 6: "IP-CAN_CHANGE", - 7: "INDICATION_OF_OUT_OF_CREDIT", - 8: "INDICATION_OF_SUCCESSFUL_RESOURCES_ALLOCATION", - 9: "INDICATION_OF_FAILED_RESOURCES_ALLOCATION", - 10: "INDICATION_OF_LIMITED_PCC_DEPLOYMENT", - 11: "USAGE_REPORT", - 12: "ACCESS_NETWORK_INFO_REPORT", - })] - - -class AVP_10415_520 (AVP_FL_V): - name = 'Media-Type' - avpLen = 16 - fields_desc = [AVP_FL_V, - Enumerated('val', - None, - {0: "AUDIO", - 1: "VIDEO", - 2: "DATA", - 3: "APPLICATION", - 4: "CONTROL", - 5: "TEXT", - 6: "MESSAGE", - 4294967295: "OTHER", - })] - - -class AVP_10415_523 (AVP_FL_V): - name = 'SIP-Forking-Indication' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "SINGLE_DIALOGUE", 1: "SEVERAL_DIALOGUES", })] - - -class AVP_10415_527 (AVP_FL_V): - name = 'Service-Info-Status' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "FINAL_SERVICE_INFORMATION", 1: "PRELIMINARY_SERVICE_INFORMATION", })] # noqa: E501 - - -class AVP_10415_529 (AVP_FL_V): - name = 'AF-Signalling-Protocol' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "NO_INFORMATION", 1: "SIP", })] - - -class AVP_10415_533 (AVP_FL_V): - name = 'Rx-Request-Type' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "INITIAL_REQUEST", 1: "UPDATE_REQUEST", })] # noqa: E501 - - -class AVP_10415_536 (AVP_FL_V): - name = 'Required-Access-Info' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "USER_LOCATION", 1: "MS_TIME_ZONE", })] # noqa: E501 - - -class AVP_10415_614 (AVP_FL_V): - name = 'Server-Assignment-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "NO_ASSIGNMENT", - 1: "REGISTRATION", - 2: "RE_REGISTRATION", - 3: "UNREGISTERED_USER", - 4: "TIMEOUT_DEREGISTRATION", - 5: "USER_DEREGISTRATION", - 6: "TIMEOUT_DEREGISTRATION_STORE_SERVER_NAME", - 7: "USER_DEREGISTRATION_STORE_SERVER_NAME", - 8: "ADMINISTRATIVE_DEREGISTRATION", - 9: "AUTHENTICATION_FAILURE", - 10: "AUTHENTICATION_TIMEOUT", - 11: "DEREGISTRATION_TOO_MUCH_DATA", - 12: "AAA_USER_DATA_REQUEST", - 13: "PGW_UPDATE", - })] - - -class AVP_10415_616 (AVP_FL_V): - name = 'Reason-Code' - avpLen = 16 - fields_desc = [AVP_FL_V, - Enumerated('val', - None, - {0: "PERMANENT_TERMINATION", - 1: "NEW_SERVER_ASSIGNED", - 2: "SERVER_CHANGE", - 3: "REMOVE_S-CSCF", - })] - - -class AVP_10415_623 (AVP_FL_V): - name = 'User-Authorization-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "REGISTRATION", 1: "DE_REGISTRATION", 2: "REGISTRATION_AND_CAPABILITIES", })] # noqa: E501 - - -class AVP_10415_624 (AVP_FL_V): - name = 'User-Data-Already-Available' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "USER_DATA_NOT_AVAILABLE", 1: "USER_DATA_ALREADY_AVAILABLE", })] - - -class AVP_10415_633 (AVP_FL_V): - name = 'Originating-Request' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "ORIGINATING", })] - - -class AVP_10415_638 (AVP_FL_V): - name = 'Loose-Route-Indication' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "LOOSE_ROUTE_NOT_REQUIRED", 1: "LOOSE_ROUTE_REQUIRED", })] # noqa: E501 - - -class AVP_10415_648 (AVP_FL_V): - name = 'Multiple-Registration-Indication' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "NOT_MULTIPLE_REGISTRATION", 1: "MULTIPLE_REGISTRATION", })] - - -class AVP_10415_650 (AVP_FL_V): - name = 'Session-Priority' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "PRIORITY-0", 1: "PRIORITY-1", 2: "PRIORITY-2", 3: "PRIORITY-3", 4: "PRIORITY-4", })] # noqa: E501 - - -class AVP_10415_652 (AVP_FL_V): - name = 'Priviledged-Sender-Indication' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "NOT_PRIVILEDGED_SENDER", 1: "PRIVILEDGED_SENDER", })] - - -class AVP_10415_703 (AVP_FL_V): - name = 'Data-Reference' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "RepositoryData", - 1: "Undefined", - 2: "Undefined", - 3: "Undefined", - 4: "Undefined", - 5: "Undefined", - 6: "Undefined", - 7: "Undefined", - 8: "Undefined", - 9: "Undefined", - 10: "IMSPublicIdentity", - 11: "IMSUserState", - 12: "S-CSCFName", - 13: "InitialFilterCriteria", - 14: "LocationInformation", - 15: "UserState", - 16: "ChargingInformation", - 17: "MSISDN", - 18: "PSIActivation", - 19: "DSAI", - 20: "Reserved", - 21: "ServiceLevelTraceInfo", - 22: "IPAddressSecureBindingInformation", - 23: "ServicePriorityLevel", - 24: "SMSRegistrationInfo", - 25: "UEReachabilityForIP", - 26: "TADSinformation", - 27: "STN-SR", - 28: "UE-SRVCC-Capability", - 29: "ExtendedPriority", - 30: "CSRN", - 31: "ReferenceLocationInformation", - })] - - -class AVP_10415_705 (AVP_FL_V): - name = 'Subs-Req-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Subscribe", 1: "Unsubscribe", })] # noqa: E501 - - -class AVP_10415_706 (AVP_FL_V): - name = 'Requested-Domain' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "CS-Domain", 1: "PS-Domain", })] - - -class AVP_10415_707 (AVP_FL_V): - name = 'Current-Location' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "DoNotNeedInitiateActiveLocationRetrieval", 1: "InitiateActiveLocationRetrieval", })] # noqa: E501 - - -class AVP_10415_708 (AVP_FL_V): - name = 'Identity-Set' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "ALL_IDENTITIES", - 1: "REGISTERED_IDENTITIES", - 2: "IMPLICIT_IDENTITIES", - 3: "ALIAS_IDENTITIES", - })] - - -class AVP_10415_710 (AVP_FL_V): - name = 'Send-Data-Indication' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "USER_DATA_NOT_REQUESTED", 1: "USER_DATA_REQUESTED", })] # noqa: E501 - - -class AVP_10415_712 (AVP_FL_V): - name = 'One-Time-Notification' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "ONE_TIME_NOTIFICATION_REQUESTED", })] # noqa: E501 - - -class AVP_10415_714 (AVP_FL_V): - name = 'Serving-Node-Indication' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "ONLY_SERVING_NODES_REQUIRED", })] # noqa: E501 - - -class AVP_10415_717 (AVP_FL_V): - name = 'Pre-paging-Supported' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "PREPAGING_NOT_SUPPORTED", 1: "PREPAGING_SUPPORTED", })] # noqa: E501 - - -class AVP_10415_718 (AVP_FL_V): - name = 'Local-Time-Zone-Indication' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "ONLY_LOCAL_TIME_ZONE_REQUESTED", 1: "LOCAL_TIME_ZONE_WITH_LOCATION_INFO_REQUESTED", })] # noqa: E501 - - -class AVP_10415_829 (AVP_FL_V): - name = 'Role-Of-Node' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "HPLMN", 1: "VPLMN", 2: "FORWARDING_ROLE", })] # noqa: E501 - - -class AVP_10415_862 (AVP_FL_V): - name = 'Node-Functionality' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "S-CSCF", - 1: "P-CSCF", - 2: "I-CSCF", - 5: "BGCF", - 6: "AS", - 7: "IBCF", - 8: "S-GW", - 9: "P-GW", - 10: "HSGW", - 11: "E-CSCF ", - 12: "MME ", - 13: "TRF", - 14: "TF", - 15: "ATCF", - 16: "Proxy Function", - 17: "ePDG", - })] - - -class AVP_10415_864 (AVP_FL_V): - name = 'Originator' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "Calling Party", 1: "Called Party", })] # noqa: E501 - - -class AVP_10415_867 (AVP_FL_V): - name = 'PS-Append-Free-Format-Data' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "'Append' ", 1: "'Overwrite' ", })] # noqa: E501 - - -class AVP_10415_870 (AVP_FL_V): - name = 'Trigger-Type' - avpLen = 16 - fields_desc = [AVP_FL_V, - Enumerated('val', - None, - {1: "CHANGE_IN_SGSN_IP_ADDRESS ", - 2: "CHANGE_IN_QOS", - 3: "CHANGE_IN_LOCATION", - 4: "CHANGE_IN_RAT", - 5: "CHANGE_IN_UE_TIMEZONE", - 10: "CHANGEINQOS_TRAFFIC_CLASS", - 11: "CHANGEINQOS_RELIABILITY_CLASS", - 12: "CHANGEINQOS_DELAY_CLASS", - 13: "CHANGEINQOS_PEAK_THROUGHPUT", - 14: "CHANGEINQOS_PRECEDENCE_CLASS", - 15: "CHANGEINQOS_MEAN_THROUGHPUT", - 16: "CHANGEINQOS_MAXIMUM_BIT_RATE_FOR_UPLINK", - 17: "CHANGEINQOS_MAXIMUM_BIT_RATE_FOR_DOWNLINK", - 18: "CHANGEINQOS_RESIDUAL_BER", - 19: "CHANGEINQOS_SDU_ERROR_RATIO", - 20: "CHANGEINQOS_TRANSFER_DELAY", - 21: "CHANGEINQOS_TRAFFIC_HANDLING_PRIORITY", - 22: "CHANGEINQOS_GUARANTEED_BIT_RATE_FOR_UPLINK", # noqa: E501 - 23: "CHANGEINQOS_GUARANTEED_BIT_RATE_FOR_DOWNLINK", # noqa: E501 - 24: "CHANGEINQOS_APN_AGGREGATE_MAXIMUM_BIT_RATE", # noqa: E501 - 30: "CHANGEINLOCATION_MCC", - 31: "CHANGEINLOCATION_MNC", - 32: "CHANGEINLOCATION_RAC", - 33: "CHANGEINLOCATION_LAC", - 34: "CHANGEINLOCATION_CellId", - 35: "CHANGEINLOCATION_TAC", - 36: "CHANGEINLOCATION_ECGI", - 40: "CHANGE_IN_MEDIA_COMPOSITION", - 50: "CHANGE_IN_PARTICIPANTS_NMB", - 51: "CHANGE_IN_ THRSHLD_OF_PARTICIPANTS_NMB", - 52: "CHANGE_IN_USER_PARTICIPATING_TYPE", - 60: "CHANGE_IN_SERVICE_CONDITION", - 61: "CHANGE_IN_SERVING_NODE", - 70: "CHANGE_IN_USER_CSG_INFORMATION", - 71: "CHANGE_IN_HYBRID_SUBSCRIBED_USER_CSG_INFORMATION", # noqa: E501 - 72: "CHANGE_IN_HYBRID_UNSUBSCRIBED_USER_CSG_INFORMATION", # noqa: E501 - 73: "CHANGE_OF_UE_PRESENCE_IN_PRESENCE_REPORTING_AREA", # noqa: E501 - })] - - -class AVP_10415_872 (AVP_FL_V): - name = 'Reporting-Reason' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "THRESHOLD", - 1: "QHT", - 2: "FINAL", - 3: "QUOTA_EXHAUSTED", - 4: "VALIDITY_TIME", - 5: "OTHER_QUOTA_TYPE", - 6: "RATING_CONDITION_CHANGE", - 7: "FORCED_REAUTHORISATION", - 8: "POOL_EXHAUSTED", - })] - - -class AVP_10415_882 (AVP_FL_V): - name = 'Media-Initiator-Flag' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "called party", 1: "calling party", 2: "unknown", })] # noqa: E501 - - -class AVP_10415_883 (AVP_FL_V): - name = 'PoC-Server-Role' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "Participating PoC Server", 1: "Controlling PoC Server", })] # noqa: E501 - - -class AVP_10415_884 (AVP_FL_V): - name = 'PoC-Session-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "1 to 1 PoC session", - 1: "Chat PoC group session", - 2: "Pre-arranged PoC group session", - 3: "Ad-hoc PoC group session", - })] - - -class AVP_10415_899 (AVP_FL_V): - name = 'Address-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "e-mail address", - 1: "MSISDN", - 2: "IPv4 Address", - 3: "IPv6 Address", - 4: "Numeric Shortcode", - 5: "Alphanumeric Shortcode", - 6: "Other", - 7: "IMSI", - })] - - -class AVP_10415_902 (AVP_FL_V): - name = 'MBMS-StartStop-Indication' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "START", 1: "STOP", 2: "UPDATE", })] # noqa: E501 - - -class AVP_10415_906 (AVP_FL_V): - name = 'MBMS-Service-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "MULTICAST", 1: "BROADCAST", })] - - -class AVP_10415_907 (AVP_FL_V): - name = 'MBMS-2G-3G-Indicator' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "2G", 1: "3G", 2: "2G-AND-3G", })] # noqa: E501 - - -class AVP_10415_921 (AVP_FL_V): - name = 'CN-IP-Multicast-Distribution' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "NO-IP-MULTICAST", 1: "IP-MULTICAST", })] # noqa: E501 - - -class AVP_10415_922 (AVP_FL_V): - name = 'MBMS-HC-Indicator' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "uncompressed-header", 1: "compressed-header", })] # noqa: E501 - - -class AVP_10415_1000 (AVP_FL_V): - name = 'Bearer-Usage' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "GENERAL", 1: "IMS SIGNALLING", 2: "DEDICATED", })] # noqa: E501 - - -class AVP_10415_1006 (AVP_FL_V): - name = 'Event-Trigger' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "SGSN_CHANGE", - 1: "QOS_CHANGE", - 2: "RAT_CHANGE", - 3: "TFT_CHANGE", - 4: "PLMN_CHANGE", - 5: "LOSS_OF_BEARER", - 6: "RECOVERY_OF_BEARER", - 7: "IP-CAN_CHANGE", - 8: "GW-PCEF-MALFUNCTION", - 9: "RESOURCES_LIMITATION", - 10: "MAX_NR_BEARERS_REACHED", - 11: "QOS_CHANGE_EXCEEDING_AUTHORIZATION", - 12: "RAI_CHANGE", - 13: "USER_LOCATION_CHANGE", - 14: "NO_EVENT_TRIGGERS", - 15: "OUT_OF_CREDIT", - 16: "REALLOCATION_OF_CREDIT", - 17: "REVALIDATION_TIMEOUT", - 18: "UE_IP_ADDRESS_ALLOCATE", - 19: "UE_IP_ADDRESS_RELEASE", - 20: "DEFAULT_EPS_BEARER_QOS_CHANGE", - 21: "AN_GW_CHANGE", - 22: "SUCCESSFUL_RESOURCE_ALLOCATION", - 23: "RESOURCE_MODIFICATION_REQUEST", - 24: "PGW_TRACE_CONTROL", - 25: "UE_TIME_ZONE_CHANGE", - 26: "TAI_CHANGE", - 27: "ECGI_CHANGE", - 28: "CHARGING_CORRELATION_EXCHANGE", - 29: "APN-AMBR_MODIFICATION_FAILURE", - 30: "USER_CSG_INFORMATION_CHANGE", - 33: "USAGE_REPORT", - 34: "DEFAULT-EPS-BEARER-QOS_MODIFICATION_FAILURE", - 35: "USER_CSG_HYBRID_SUBSCRIBED_INFORMATION_CHANGE", - 36: "USER_CSG_ HYBRID_UNSUBSCRIBED_INFORMATION_CHANGE", - 37: "ROUTING_RULE_CHANGE", - 38: "MAX_MBR_APN_AMBR_CHANGE", - 39: "APPLICATION_START", - 40: "APPLICATION_STOP", - 41: "ADC_REVALIDATION_TIMEOUT", - 42: "CS_TO_PS_HANDOVER", - 43: "UE_LOCAL_IP_ADDRESS_CHANGE", - 45: "ACCESS_NETWORK_INFO_REPORT", - 100: "TIME_CHANGE", - 1000: "TFT DELETED", - 1001: "LOSS OF BEARER", - 1002: "RECOVERY OF BEARER", - 1003: "POLICY ENFORCEMENT FAILED", - })] - - -class AVP_10415_1007 (AVP_FL_V): - name = 'Metering-Method' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "DURATION", 1: "VOLUME", 2: "DURATION_VOLUME", })] # noqa: E501 - - -class AVP_10415_1008 (AVP_FL_V): - name = 'Offline' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "DISABLE_OFFLINE", 1: "ENABLE_OFFLINE", })] # noqa: E501 - - -class AVP_10415_1009 (AVP_FL_V): - name = 'Online' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "DISABLE_ONLINE", 1: "ENABLE_ONLINE", })] # noqa: E501 - - -class AVP_10415_1011 (AVP_FL_V): - name = 'Reporting-Level' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "SERVICE_IDENTIFIER_LEVEL", 1: "RATING_GROUP_LEVEL", 2: "SPONSORED_CONNECTIVITY_LEVEL", })] # noqa: E501 - - -class AVP_10415_1015 (AVP_FL_V): - name = 'PDP-Session-Operation' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "PDP-SESSION-TERMINATION", })] - - -class AVP_10415_1019 (AVP_FL_V): - name = 'PCC-Rule-Status' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "ACTIVE", 1: "INACTIVE", 2: "TEMPORARY_INACTIVE", })] # noqa: E501 - - -class AVP_10415_1021 (AVP_FL_V): - name = 'Bearer-Operation' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "TERMINATION", 1: "ESTABLISHMENT", 2: "MODIFICATION", })] # noqa: E501 - - -class AVP_10415_1023 (AVP_FL_V): - name = 'Bearer-Control-Mode' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "UE_ONLY", 1: "RESERVED", 2: "UE_NW", })] # noqa: E501 - - -class AVP_10415_1024 (AVP_FL_V): - name = 'Network-Request-Support' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "NETWORK_REQUEST NOT SUPPORTED", 1: "NETWORK_REQUEST SUPPORTED", })] # noqa: E501 - - -class AVP_10415_1027 (AVP_FL_V): - name = 'IP-CAN-Type' - avpLen = 16 - fields_desc = [AVP_FL_V, - Enumerated('val', - None, - {0: "3GPP-GPRS", - 1: "DOCSIS", - 2: "xDSL", - 3: "WiMAX", - 4: "3GPP2", - 5: "3GPP-EPS", - 6: "Non-3GPP-EPS", - })] - - -class AVP_10415_1028 (AVP_FL_V): - name = 'QoS-Class-Identifier' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 1: "QCI_1", - 2: "QCI_2", - 3: "QCI_3", - 4: "QCI_4", - 5: "QCI_5", - 6: "QCI_6", - 7: "QCI_7", - 8: "QCI_8", - 9: "QCI_9", - })] - - -class AVP_10415_1032 (AVP_FL_V): - name = 'RAT-Type' - avpLen = 16 - fields_desc = [AVP_FL_V, - Enumerated('val', - None, - {0: "WLAN", - 1: "VIRTUAL", - 1000: "UTRAN", - 1001: "GERAN", - 1002: "GAN", - 1003: "HSPA_EVOLUTION", - 1004: "EUTRAN", - 2000: "CDMA2000_1X", - 2001: "HRPD", - 2002: "UMB", - 2003: "EHRPD", - })] - - -class AVP_10415_1045 (AVP_FL_V): - name = 'Session-Release-Cause' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "UNSPECIFIED_REASON", 1: "UE_SUBSCRIPTION_REASON", 2: "INSUFFICIENT_SERVER_RESOURCES", })] # noqa: E501 - - -class AVP_10415_1047 (AVP_FL_V): - name = 'Pre-emption-Capability' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "PRE-EMPTION_CAPABILITY_ENABLED", 1: "PRE-EMPTION_CAPABILITY_DISABLED", })] # noqa: E501 - - -class AVP_10415_1048 (AVP_FL_V): - name = 'Pre-emption-Vulnerability' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "PRE-EMPTION_VULNERABILITY_ENABLED", 1: "PRE-EMPTION_VULNERABILITY_DISABLED", })] # noqa: E501 - - -class AVP_10415_1062 (AVP_FL_V): - name = 'Packet-Filter-Operation' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "DELETION", 1: "ADDITION", 2: "MODIFICATION", })] - - -class AVP_10415_1063 (AVP_FL_V): - name = 'Resource-Allocation-Notification' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "ENABLE_NOTIFICATION", })] - - -class AVP_10415_1068 (AVP_FL_V): - name = 'Usage-Monitoring-Level' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "SESSION_LEVEL", 1: "PCC_RULE_LEVEL", 2: "ADC_RULE_LEVEL", })] # noqa: E501 - - -class AVP_10415_1069 (AVP_FL_V): - name = 'Usage-Monitoring-Report' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "USAGE_MONITORING_REPORT_REQUIRED", })] # noqa: E501 - - -class AVP_10415_1070 (AVP_FL_V): - name = 'Usage-Monitoring-Support' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "USAGE_MONITORING_DISABLED", })] - - -class AVP_10415_1071 (AVP_FL_V): - name = 'CSG-Information-Reporting' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "CHANGE_CSG_CELL", - 1: "CHANGE_CSG_SUBSCRIBED_HYBRID_CELL", - 2: "CHANGE_CSG_UNSUBSCRIBED_HYBRID_CELL", - })] - - -class AVP_10415_1072 (AVP_FL_V): - name = 'Packet-Filter-Usage' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {1: "SEND_TO_UE", })] - - -class AVP_10415_1073 (AVP_FL_V): - name = 'Charging-Correlation-Indicator' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "CHARGING_IDENTIFIER_REQUIRED", })] # noqa: E501 - - -class AVP_10415_1080 (AVP_FL_V): - name = 'Flow-Direction' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "UNSPECIFIED", 1: "DOWNLINK", 2: "UPLINK", 3: "BIDIRECTIONAL", })] # noqa: E501 - - -class AVP_10415_1086 (AVP_FL_V): - name = 'Redirect-Support' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "REDIRECTION_DISABLED", 1: "REDIRECTION_ENABLED", })] # noqa: E501 - - -class AVP_10415_1099 (AVP_FL_V): - name = 'PS-to-CS-Session-Continuity' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "VIDEO_PS2CS_CONT_CANDIDATE", })] - - -class AVP_10415_1204 (AVP_FL_V): - name = 'Type-Number' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "TBC", })] - - -class AVP_10415_1208 (AVP_FL_V): - name = 'Addressee-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "TO ", 1: "CC ", 2: "BCC", })] - - -class AVP_10415_1209 (AVP_FL_V): - name = 'Priority' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "Low", 1: "Normal", 2: "High", })] - - -class AVP_10415_1211 (AVP_FL_V): - name = 'Message-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 1: "m-send-req", - 2: "m-send-conf", - 3: "m-notification-ind ", - 4: "m-notifyresp-ind ", - 5: "m-retrieve-conf ", - 6: "m-acknowledge-ind ", - 7: "m-delivery-ind ", - 8: "m-read-rec-ind ", - 9: "m-read-orig-ind", - 10: "m-forward-req ", - 11: "m-forward-conf ", - 12: "m-mbox-store-conf", - 13: "m-mbox-view-conf ", - 14: "m-mbox-upload-conf ", - 15: "m-mbox-delete-conf ", - })] - - -class AVP_10415_1214 (AVP_FL_V): - name = 'Class-Identifier' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "Personal", 1: "Advertisement", 2: "Informational", 3: "Auto", })] # noqa: E501 - - -class AVP_10415_1216 (AVP_FL_V): - name = 'Delivery-Report-Requested' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "No", 1: "Yes", })] - - -class AVP_10415_1217 (AVP_FL_V): - name = 'Adaptations' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Yes", 1: "No", })] - - -class AVP_10415_1220 (AVP_FL_V): - name = 'Content-Class' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "text ", - 1: "image-basic ", - 2: "image-rich ", - 3: "video-basic", - 4: "video-rich ", - 5: "megapixel ", - 6: "content-basic ", - 7: "content-rich ", - })] - - -class AVP_10415_1221 (AVP_FL_V): - name = 'DRM-Content' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "No", 1: "Yes", })] - - -class AVP_10415_1222 (AVP_FL_V): - name = 'Read-Reply-Report-Requested' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "No", 1: "Yes", })] - - -class AVP_10415_1224 (AVP_FL_V): - name = 'File-Repair-Supported' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "Forwarding not pending", 1: "Forwarding pending", 2: "NOT_SUPPORTED", })] # noqa: E501 - - -class AVP_10415_1225 (AVP_FL_V): - name = 'MBMS-User-Service-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {1: "DOWNLOAD", 2: "STREAMING", })] - - -class AVP_10415_1247 (AVP_FL_V): - name = 'PDP-Context-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Primary", 1: "Secondary", })] - - -class AVP_10415_1248 (AVP_FL_V): - name = 'MMBox-Storage-Requested' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "No", 1: "Yes", })] - - -class AVP_10415_1254 (AVP_FL_V): - name = 'PoC-User-Role-info-Units' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 1: "Moderator", 2: "Dispatcher", 3: "Session-Owner", 4: "Session-Participant", })] # noqa: E501 - - -class AVP_10415_1259 (AVP_FL_V): - name = 'Participant-Access-Priority' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 1: "Pre-emptive priority: ", - 2: "High priority: Lower than Pre-emptive priority", - 3: "Normal priority: Normal level. Lower than High priority", - 4: "Low priority: Lowest level priority", - })] - - -class AVP_10415_1261 (AVP_FL_V): - name = 'PoC-Change-Condition' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "ServiceChange", - 1: "VolumeLimit", - 2: "TimeLimit", - 3: "NumberofTalkBurstLimit", - 4: "NumberofActiveParticipants", - })] - - -class AVP_10415_1268 (AVP_FL_V): - name = 'Envelope-Reporting' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "DO_NOT_REPORT_ENVELOPES", - 1: "REPORT_ENVELOPES", - 2: "REPORT_ENVELOPES_WITH_VOLUME", - 3: "REPORT_ENVELOPES_WITH_EVENTS", - 4: "REPORT_ENVELOPES_WITH_VOLUME_AND_EVENTS", - })] - - -class AVP_10415_1271 (AVP_FL_V): - name = 'Time-Quota-Type' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "DISCRETE_TIME_PERIOD", 1: "CONTINUOUS_TIME_PERIOD", })] # noqa: E501 - - -class AVP_10415_1277 (AVP_FL_V): - name = 'PoC-Session-Initiation-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Pre-established", 1: "On-demand", })] # noqa: E501 - - -class AVP_10415_1279 (AVP_FL_V): - name = 'User-Participating-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "Normal", 1: "NW PoC Box", 2: "UE PoC Box", })] - - -class AVP_10415_1417 (AVP_FL_V): - name = 'Network-Access-Mode' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "PACKET_AND_CIRCUIT", 1: "Reserved", 2: "ONLY_PACKET", })] # noqa: E501 - - -class AVP_10415_1420 (AVP_FL_V): - name = 'Cancellation-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "MME_UPDATE_PROCEDURE", - 1: "SGSN_UPDATE_PROCEDURE", - 2: "SUBSCRIPTION_WITHDRAWAL", - 3: "UPDATE_PROCEDURE_IWF", - 4: "INITIAL_ATTACH_PROCEDURE", - })] - - -class AVP_10415_1424 (AVP_FL_V): - name = 'Subscriber-Status' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "SERVICE_GRANTED", 1: "OPERATOR_DETERMINED_BARRING", })] # noqa: E501 - - -class AVP_10415_1428 (AVP_FL_V): - name = 'All-APN-Configurations-Included-Indicator' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "ALL_APN_CONFIGURATIONS_INCLUDED", })] # noqa: E501 - - -class AVP_10415_1432 (AVP_FL_V): - name = 'VPLMN-Dynamic-Address-Allowed' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "NOTALLOWED", 1: "ALLOWED", })] - - -class AVP_10415_1434 (AVP_FL_V): - name = 'Alert-Reason' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "UE_PRESENT", 1: "UE_MEMORY_AVAILABLE", })] # noqa: E501 - - -class AVP_10415_1438 (AVP_FL_V): - name = 'PDN-GW-Allocation-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "STATIC", 1: "DYNAMIC", })] - - -class AVP_10415_1445 (AVP_FL_V): - name = 'Equipment-Status' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "WHITELISTED", 1: "BLACKLISTED", 2: "GREYLISTED", })] # noqa: E501 - - -class AVP_10415_1456 (AVP_FL_V): - name = 'PDN-Type' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "IPv4", 1: "IPv6", 2: "IPv4v6", 3: "IPv4_OR_IPv6", })] # noqa: E501 - - -class AVP_10415_1457 (AVP_FL_V): - name = 'Roaming-Restricted-Due-To-Unsupported-Feature' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Roaming-Restricted-Due-To-Unsupported-Feature", })] # noqa: E501 - - -class AVP_10415_1462 (AVP_FL_V): - name = 'Trace-Depth' - avpLen = 16 - fields_desc = [AVP_FL_V, - Enumerated('val', - None, - {0: "Minimum", - 1: "Medium", - 2: "Maximum", - 3: "MinimumWithoutVendorSpecificExtension", - 4: "MediumWithoutVendorSpecificExtension", - 5: "MaximumWithoutVendorSpecificExtension", - })] - - -class AVP_10415_1468 (AVP_FL_V): - name = 'Complete-Data-List-Included-Indicator' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "ALL_PDP_CONTEXTS_INCLUDED", })] - - -class AVP_10415_1478 (AVP_FL_V): - name = 'Notification-To-UE-User' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "NOTIFY_LOCATION_ALLOWED", - 1: "NOTIFYANDVERIFY_LOCATION_ALLOWED_IF_NO_RESPONSE", - 2: "NOTIFYANDVERIFY_LOCATION_NOT_ALLOWED_IF_NO_RESPONSE", - 3: "LOCATION_NOT_ALLOWED", - })] - - -class AVP_10415_1481 (AVP_FL_V): - name = 'GMLC-Restriction' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "GMLC_LIST", 1: "HOME_COUNTRY", })] # noqa: E501 - - -class AVP_10415_1482 (AVP_FL_V): - name = 'PLMN-Client' - avpLen = 16 - fields_desc = [AVP_FL_V, - Enumerated('val', - None, - {0: "BROADCAST_SERVICE", - 1: "O_AND_M_HPLMN", - 2: "O_AND_M_VPLMN", - 3: "ANONYMOUS_LOCATION", - 4: "TARGET_UE_SUBSCRIBED_SERVICE", - })] - - -class AVP_10415_1491 (AVP_FL_V): - name = 'ICS-Indicator' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "FALSE", 1: "TRUE", })] - - -class AVP_10415_1492 (AVP_FL_V): - name = 'IMS-Voice-Over-PS-Sessions-Supported' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "NOT_SUPPORTED", 1: "SUPPORTED", })] # noqa: E501 - - -class AVP_10415_1493 (AVP_FL_V): - name = 'Homogeneous-Support-of-IMS-Voice-Over-PS-Sessions' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "NOT_SUPPORTED", 1: "SUPPORTED", })] # noqa: E501 - - -class AVP_10415_1499 (AVP_FL_V): - name = 'User-State' - avpLen = 16 - fields_desc = [AVP_FL_V, - Enumerated('val', - None, - {0: "DETACHED", - 1: "ATTACHED_NOT_REACHABLE_FOR_PAGING", - 2: "ATTACHED_REACHABLE_FOR_PAGING", - 3: "CONNECTED_NOT_REACHABLE_FOR_PAGING", - 4: "CONNECTED_REACHABLE_FOR_PAGING", - 5: "NETWORK_DETERMINED_NOT_REACHABLE", - })] - - -class AVP_10415_1501 (AVP_FL_V): - name = 'Non-3GPP-IP-Access' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "NON_3GPP_SUBSCRIPTION_ALLOWED", 1: "NON_3GPP_SUBSCRIPTION_BARRED", })] # noqa: E501 - - -class AVP_10415_1502 (AVP_FL_V): - name = 'Non-3GPP-IP-Access-APN' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "NON_3GPP_APNS_ENABLE", 1: "NON_3GPP_APNS_DISABLE", })] # noqa: E501 - - -class AVP_10415_1503 (AVP_FL_V): - name = 'AN-Trusted' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "TRUSTED", 1: "UNTRUSTED", })] - - -class AVP_10415_1515 (AVP_FL_V): - name = 'Trust-Relationship-Update' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "TBC", })] - - -class AVP_10415_1519 (AVP_FL_V): - name = 'Transport-Access-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "BBF", })] - - -class AVP_10415_1610 (AVP_FL_V): - name = 'Current-Location-Retrieved' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "ACTIVE-LOCATION-RETRIEVAL", })] - - -class AVP_10415_1613 (AVP_FL_V): - name = 'SIPTO-Permission' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "SIPTO_ALLOWED", 1: "SIPTO_NOTALLOWED", })] # noqa: E501 - - -class AVP_10415_1614 (AVP_FL_V): - name = 'Error-Diagnostic' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "GPRS_DATA_SUBSCRIBED", - 1: "NO_GPRS_DATA_SUBSCRIBED", - 2: "ODB-ALL-APN", - 3: "ODB-HPLMN-APN", - 4: "ODB-VPLMN-APN", - })] - - -class AVP_10415_1615 (AVP_FL_V): - name = 'UE-SRVCC-Capability' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "UE-SRVCC-NOT-SUPPORTED", 1: "UE-SRVCC-SUPPORTED", })] # noqa: E501 - - -class AVP_10415_1617 (AVP_FL_V): - name = 'VPLMN-LIPA-Allowed' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "LIPA-NOTALLOWED", 1: "LIPA-ALLOWED", })] # noqa: E501 - - -class AVP_10415_1618 (AVP_FL_V): - name = 'LIPA-Permission' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "LIPA-PROHIBITED", 1: "LIPA-ONLY", 2: "LIPA-CONDITIONAL", })] # noqa: E501 - - -class AVP_10415_1623 (AVP_FL_V): - name = 'Job-Type' - avpLen = 16 - fields_desc = [AVP_FL_V, - Enumerated('val', - None, - {0: "Immediate-MDT-only", - 1: "Logged-MDT-only", - 2: "Trace-only", - 3: "Immediate-MDT-and-Trace", - 4: "RLF-reports-only", - })] - - -class AVP_10415_1627 (AVP_FL_V): - name = 'Report-Interval' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "UMTS_250_ms", - 1: "UMTS_500_ms", - 2: "UMTS_1000_ms", - 3: "UMTS_2000_ms", - 4: "UMTS_3000_ms", - 5: "UMTS_4000_ms", - 6: "UMTS_6000_ms", - 7: "UMTS_8000_ms", - 8: "UMTS_12000_ms", - 9: "UMTS_16000_ms", - 10: "UMTS_20000_ms", - 11: "UMTS_24000_ms", - 12: "UMTS_28000_ms", - 13: "UMTS_32000_ms", - 14: "UMTS_64000_ms", - 15: "LTE_120_ms", - 16: "LTE_240_ms", - 17: "LTE_480_ms", - 18: "LTE_640_ms", - 19: "LTE_1024_ms", - 20: "LTE_2048_ms", - 21: "LTE_5120_ms", - 22: "LTE_10240_ms", - 23: "LTE_60000_ms", - 24: "LTE_360000_ms", - 25: "LTE_720000_ms", - 26: "LTE_1800000_ms", - 27: "LTE_3600000_ms", - })] - - -class AVP_10415_1628 (AVP_FL_V): - name = 'Report-Amount' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "1", 1: "2", 2: "4", 3: "8", 4: "16", 5: "32", 6: "64", 7: "infinity", })] # noqa: E501 - - -class AVP_10415_1631 (AVP_FL_V): - name = 'Logging-Interval' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "1.28", - 1: "2.56", - 2: "5.12", - 3: "10.24", - 4: "20.48", - 5: "30.72", - 6: "40.96", - 7: "61.44", - })] - - -class AVP_10415_1632 (AVP_FL_V): - name = 'Logging-Duration' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "600_sec", 1: "1200_sec", 2: "2400_sec", 3: "3600_sec", 4: "5400_sec", 5: "7200_sec", })] # noqa: E501 - - -class AVP_10415_1633 (AVP_FL_V): - name = 'Relay-Node-Indicator' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "NOT_RELAY_NODE", 1: "RELAY_NODE", })] # noqa: E501 - - -class AVP_10415_1634 (AVP_FL_V): - name = 'MDT-User-Consent' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "CONSENT_NOT_GIVEN", 1: "CONSENT_GIVEN", })] # noqa: E501 - - -class AVP_10415_1636 (AVP_FL_V): - name = 'Subscribed-VSRVCC' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "VSRVCC_SUBSCRIBED", })] - - -class AVP_10415_1648 (AVP_FL_V): - name = 'SMS-Register-Request' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "SMS_REGISTRATION_REQUIRED", 1: "SMS_REGISTRATION_NOT_PREFERRED", 2: "NO_PREFERENCE", })] # noqa: E501 - - -class AVP_10415_1650 (AVP_FL_V): - name = 'Daylight-Saving-Time' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "NO_ADJUSTMENT", 1: "PLUS_ONE_HOUR_ADJUSTMENT", 2: "PLUS_TWO_HOURS_ADJUSTMENT", })] # noqa: E501 - - -class AVP_10415_2006 (AVP_FL_V): - name = 'Interface-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "Unknown", - 1: "MOBILE_ORIGINATING", - 2: "MOBILE_TERMINATING", - 3: "APPLICATION_ORIGINATING", - 4: "APPLICATION_TERMINATION", - })] - - -class AVP_10415_2007 (AVP_FL_V): - name = 'SM-Message-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "SUBMISSION", })] - - -class AVP_10415_2011 (AVP_FL_V): - name = 'Reply-Path-Requested' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "No Reply Path Set", 1: "Reply path Set", })] # noqa: E501 - - -class AVP_10415_2016 (AVP_FL_V): - name = 'SMS-Node' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "SMS Router", 1: "IP-SM-GW", 2: "SMS Router and IP-SM-GW", 3: "SMS-SC", })] # noqa: E501 - - -class AVP_10415_2025 (AVP_FL_V): - name = 'PoC-Event-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "Normal;", - 1: "Instant Ppersonal Aalert event;", - 2: "PoC Group Advertisement event;", - 3: "Early Ssession Setting-up event;", - 4: "PoC Talk Burst", - })] - - -class AVP_10415_2029 (AVP_FL_V): - name = 'SM-Service-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "VAS4SMS Short Message content processing", - 1: "VAS4SMS Short Message forwarding", - 2: "VAS4SMS Short Message Forwarding multiple subscriptions ", - 3: "VAS4SMS Short Message filtering ", - 4: "VAS4SMS Short Message receipt", - 5: "VAS4SMS Short Message Network Storage ", - 6: "VAS4SMS Short Message to multiple destinations", - 7: "VAS4SMS Short Message Virtual Private Network (VPN)", - 8: "VAS4SMS Short Message Auto Reply", - 9: "VAS4SMS Short Message Personal Signature", - 10: "VAS4SMS Short Message Deferred Delivery ", - })] - - -class AVP_10415_2033 (AVP_FL_V): - name = 'Subscriber-Role' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Originating", 1: "Terminating", })] # noqa: E501 - - -class AVP_10415_2036 (AVP_FL_V): - name = 'SDP-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "SDP Offer", 1: "SDP Answer", })] - - -class AVP_10415_2047 (AVP_FL_V): - name = 'Serving-Node-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "SGSN", 1: "PMIPSGW", 2: "GTPSGW", 3: "ePDG", 4: "hSGW", 5: "MME", 6: "TWAN", })] # noqa: E501 - - -class AVP_10415_2049 (AVP_FL_V): - name = 'Participant-Action-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "CREATE_CONF", 1: "JOIN_CONF", 2: "INVITE_INTO_CONF", 3: "QUIT_CONF", })] # noqa: E501 - - -class AVP_10415_2051 (AVP_FL_V): - name = 'Dynamic-Address-Flag' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Static", 1: "Dynamic", })] - - -class AVP_10415_2065 (AVP_FL_V): - name = 'SGW-Change' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "ACR_Start_NOT_due_to_SGW_Change", })] # noqa: E501 - - -class AVP_10415_2066 (AVP_FL_V): - name = 'Charging-Characteristics-Selection-Mode' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "Serving-Node-Supplied", - 1: "Subscription-specific", - 2: "APN-specific", - 3: "Home-Default", - 4: "Roaming-Default", - 5: "Visiting-Default", - })] - - -class AVP_10415_2068 (AVP_FL_V): - name = 'Dynamic-Address-Flag-Extension' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Static", 1: "Dynamic", })] - - -class AVP_10415_2118 (AVP_FL_V): - name = 'Charge-Reason-Code' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "UNKNOWN", - 1: "USAGE", - 2: "COMMUNICATION-ATTEMPT-CHARGE", - 3: "SETUP-CHARGE", - 4: "ADD-ON-CHARGE", - })] - - -class AVP_10415_2203 (AVP_FL_V): - name = 'Subsession-Operation' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "TERMINATION", 1: "ESTABLISHMENT", 2: "MODIFICATION", })] # noqa: E501 - - -class AVP_10415_2204 (AVP_FL_V): - name = 'Multiple-BBERF-Action' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "ESTABLISHMENT", 1: "TERMINATION", })] # noqa: E501 - - -class AVP_10415_2206 (AVP_FL_V): - name = 'DRA-Deployment' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "DRA_Deployed", })] - - -class AVP_10415_2208 (AVP_FL_V): - name = 'DRA-Binding' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "DRA_BINDING_DELETION", })] - - -class AVP_10415_2303 (AVP_FL_V): - name = 'Online-Charging-Flag' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "ECF address not provided", 1: "ECF address provided", })] # noqa: E501 - - -class AVP_10415_2308 (AVP_FL_V): - name = 'IMSI-Unauthenticated-Flag' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Authenticated", 1: "Unauthenticated", })] # noqa: E501 - - -class AVP_10415_2310 (AVP_FL_V): - name = 'AoC-Format' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "MONETARY", 1: "NON_MONETARY", 2: "CAI", })] # noqa: E501 - - -class AVP_10415_2312 (AVP_FL_V): - name = 'AoC-Service-Obligatory-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "NON_BINDING", 1: "BINDING", })] - - -class AVP_10415_2313 (AVP_FL_V): - name = 'AoC-Service-Type' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "NONE", 1: "AOC-S", 2: "AOC-D", 3: "AOC-E", })] # noqa: E501 - - -class AVP_10415_2317 (AVP_FL_V): - name = 'CSG-Access-Mode' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Closed mode", 1: "Hybrid Mode", })] # noqa: E501 - - -class AVP_10415_2318 (AVP_FL_V): - name = 'CSG-Membership-Indication' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Not CSG member", 1: "CSG Member ", })] # noqa: E501 - - -class AVP_10415_2322 (AVP_FL_V): - name = 'IMS-Emergency-Indicator' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Non Emergency", 1: "Emergency", })] # noqa: E501 - - -class AVP_10415_2323 (AVP_FL_V): - name = 'MBMS-Charged-Party' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Content Provider", 1: "Subscriber", })] # noqa: E501 - - -class AVP_10415_2500 (AVP_FL_V): - name = 'SLg-Location-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "CURRENT_LOCATION", - 1: "CURRENT_OR_LAST_KNOWN_LOCATION", - 2: "INITIAL_LOCATION", - 3: "ACTIVATE_DEFERRED_LOCATION", - 4: "CANCEL_DEFERRED_LOCATION", - 5: "NOTIFICATION_VERIFICATION_ONLY", - })] - - -class AVP_10415_2507 (AVP_FL_V): - name = 'Vertical-Requested' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "VERTICAL_COORDINATE_IS_NOT REQUESTED", 1: "VERTICAL_COORDINATE_IS_REQUESTED", })] # noqa: E501 - - -class AVP_10415_2508 (AVP_FL_V): - name = 'Velocity-Requested' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "VELOCITY_IS_NOT_REQUESTED", 1: "BEST VELOCITY_IS_REQUESTED", })] # noqa: E501 - - -class AVP_10415_2509 (AVP_FL_V): - name = 'Response-Time' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "LOW_DELAY", 1: "DELAY_TOLERANT", })] # noqa: E501 - - -class AVP_10415_2512 (AVP_FL_V): - name = 'LCS-Privacy-Check' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "ALLOWED_WITHOUT_NOTIFICATION", - 1: "ALLOWED_WITH_NOTIFICATION", - 2: "ALLOWED_IF_NO_RESPONSE", - 3: "RESTRICTED_IF_NO_RESPONSE", - 4: "NOT_ALLOWED", - })] - - -class AVP_10415_2513 (AVP_FL_V): - name = 'Accuracy-Fulfilment-Indicator' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "REQUESTED_ACCURACY_FULFILLED", 1: "REQUESTED_ACCURACY_NOT_FULFILLED", })] # noqa: E501 - - -class AVP_10415_2518 (AVP_FL_V): - name = 'Location-Event' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "EMERGENCY_CALL_ORIGINATION", - 1: "EMERGENCY_CALL_RELEASE", - 2: "MO_LR", - 3: "EMERGENCY_CALL_HANDOVER", - })] - - -class AVP_10415_2519 (AVP_FL_V): - name = 'Pseudonym-Indicator' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "PSEUDONYM_NOT_REQUESTED", 1: "PSEUDONYM_REQUESTED", })] # noqa: E501 - - -class AVP_10415_2523 (AVP_FL_V): - name = 'LCS-QoS-Class' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "ASSURED", 1: "BEST EFFORT", })] - - -class AVP_10415_2538 (AVP_FL_V): - name = 'Occurrence-Info' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "ONE_TIME_EVENT", 1: "MULTIPLE_TIME_EVENT", })] # noqa: E501 - - -class AVP_10415_2550 (AVP_FL_V): - name = 'Periodic-Location-Support-Indicator' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "NOT_SUPPORTED", 1: "SUPPORTED", })] # noqa: E501 - - -class AVP_10415_2551 (AVP_FL_V): - name = 'Prioritized-List-Indicator' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "NOT_PRIORITIZED", 1: "PRIORITIZED", })] # noqa: E501 - - -class AVP_10415_2602 (AVP_FL_V): - name = 'Low-Priority-Indicator' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "NO", })] - - -class AVP_10415_2604 (AVP_FL_V): - name = 'Local-GW-Inserted-Indication' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "Local GW Not Inserted", 1: "Local GW Inserted", })] - - -class AVP_10415_2605 (AVP_FL_V): - name = 'Transcoder-Inserted-Indication' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "Transcoder Not Inserted", 1: "Transcoder Inserted", })] - - -class AVP_10415_2702 (AVP_FL_V): - name = 'AS-Code' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "4xx;", 1: "5xx;", 2: "Timeout", })] - - -class AVP_10415_2704 (AVP_FL_V): - name = 'NNI-Type' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "non-roaming", 1: "roaming without loopback", 2: "roaming with loopback", })] # noqa: E501 - - -class AVP_10415_2706 (AVP_FL_V): - name = 'Relationship-Mode' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "trusted", 1: "non-trusted", })] - - -class AVP_10415_2707 (AVP_FL_V): - name = 'Session-Direction' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "inbound", })] - - -class AVP_10415_2710 (AVP_FL_V): - name = 'Access-Transfer-Type' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "PS to CS Transfer", 1: "CS to PS Transfer", })] # noqa: E501 - - -class AVP_10415_2717 (AVP_FL_V): - name = 'TAD-Identifier' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "CS", 1: "PS", })] - - -class AVP_10415_2809 (AVP_FL_V): - name = 'Mute-Notification' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "MUTE_REQUIRED", })] - - -class AVP_10415_2811 (AVP_FL_V): - name = 'AN-GW-Status' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "AN_GW_FAILED", })] - - -class AVP_10415_2904 (AVP_FL_V): - name = 'SL-Request-Type' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "INITIAL_REQUEST", 1: "INTERMEDIATE_REQUEST", })] # noqa: E501 - - -class AVP_10415_3407 (AVP_FL_V): - name = 'SM-Device-Trigger-Indicator' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Not DeviceTrigger ", 1: "Device Trigger", })] # noqa: E501 - - -class AVP_10415_3415 (AVP_FL_V): - name = 'Forwarding-Pending' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "Forwarding not pending", 1: "Forwarding pending", })] # noqa: E501 - - -class AVP_10415_3421 (AVP_FL_V): - name = 'CN-Operator-Selection-Entity' - avpLen = 16 - fields_desc = [ - AVP_FL_V, - Enumerated( - 'val', - None, - { - 0: "The Serving Network has been selected by the UE", - 1: "The Serving Network has been selected by the network", - })] - - -class AVP_10415_3428 (AVP_FL_V): - name = 'Coverage-Status' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Out of coverage", 1: "In coverage", })] # noqa: E501 - - -class AVP_10415_3438 (AVP_FL_V): - name = 'Role-Of-ProSe-Function' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "HPLMN", 1: "VPLMN", })] - - -class AVP_10415_3442 (AVP_FL_V): - name = 'ProSe-Direct-Discovery-Model' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Model A", 1: "Model B", })] - - -class AVP_10415_3443 (AVP_FL_V): - name = 'ProSe-Event-Type' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "Announcing", 1: "Monitoring", 2: "Match Report", })] # noqa: E501 - - -class AVP_10415_3445 (AVP_FL_V): - name = 'ProSe-Functionality' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "Direct discovery", 1: "EPC-level discovery", })] # noqa: E501 - - -class AVP_10415_3448 (AVP_FL_V): - name = 'ProSe-Range-Class' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "Reserved", 1: "50 m", 2: "100 m", 3: "200 m", 4: "500 m", 5: "1000 m", })] # noqa: E501 - - -class AVP_10415_3449 (AVP_FL_V): - name = 'ProSe-Reason-For-Cancellation' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, { - 0: "Proximity Alert sent", 1: "Time expired with no renewal", })] - - -class AVP_10415_3451 (AVP_FL_V): - name = 'ProSe-Role-Of-UE' - avpLen = 16 - fields_desc = [AVP_FL_V, Enumerated('val', None, {0: "Announcing UE", 1: "Monitoring UE", 2: "Requestor UE", })] # noqa: E501 - - -class AVP_10415_3454 (AVP_FL_V): - name = 'Proximity-Alert-Indication' - avpLen = 16 - fields_desc = [ - AVP_FL_V, Enumerated('val', None, {0: "Alert", 1: "No Alert", })] - - -# Remaining AVPs (which do not need to be declared as classes) -############################################################## - -# In AvpDefDict dictionary, the first level key is the 'AVP vendor' and the second level key is the 'AVP code' # noqa: E501 -# Each tuple then defines the AVP name, the Scapy class and the default flags -AvpDefDict = { - 0: { - 1: ('User-Name', AVPNV_StrLenField, 64), - 2: ('User-Password', AVPNV_OctetString, 64), - 5: ('NAS-Port', AVPNV_Unsigned32, 64), - 6: ('Service-Type', AVP_0_6, 64), - 7: ('Framed-Protocol', AVP_0_7, 64), - 9: ('Framed-IP-Netmask', AVPNV_OctetString, 64), - 10: ('Framed-Routing', AVP_0_10, 64), - 11: ('Filter-Id', AVPNV_StrLenField, 64), - 12: ('Framed-MTU', AVPNV_Unsigned32, 64), - 13: ('Framed-Compression', AVP_0_13, 64), - 15: ('Login-Service', AVP_0_15, 64), - 16: ('Login-TCP-Port', AVPNV_Unsigned32, 64), - 18: ('Reply-Message', AVPNV_StrLenField, 64), - 19: ('Callback-Number', AVPNV_StrLenField, 64), - 20: ('Callback-Id', AVPNV_StrLenField, 64), - 22: ('Framed-Route', AVPNV_StrLenField, 64), - 23: ('Framed-IPX-Network', AVPNV_Unsigned32, 64), - 25: ('Class', AVPNV_OctetString, 64), - 27: ('Session-Timeout', AVPNV_Unsigned32, 64), - 28: ('Idle-Timeout', AVPNV_Unsigned32, 64), - 30: ('Called-Station-Id', AVPNV_StrLenField, 64), - 31: ('Calling-Station-Id', AVPNV_StrLenField, 64), - 33: ('Proxy-State', AVPNV_OctetString, 64), - 34: ('Login-LAT-Service', AVPNV_OctetString, 64), - 35: ('Login-LAT-Node', AVPNV_OctetString, 64), - 36: ('Login-LAT-Group', AVPNV_OctetString, 64), - 37: ('Framed-Appletalk-Link', AVPNV_Unsigned32, 64), - 38: ('Framed-Appletalk-Network', AVPNV_Unsigned32, 64), - 39: ('Framed-Appletalk-Zone', AVPNV_OctetString, 64), - 41: ('Acct-Delay-Time', AVPNV_Unsigned32, 64), - 44: ('Acct-Session-Id', AVPNV_OctetString, 64), - 45: ('Acct-Authentic', AVP_0_45, 64), - 46: ('Acct-Session-Time', AVPNV_Unsigned32, 64), - 50: ('Acct-Multi-Session-Id', AVPNV_StrLenField, 64), - 51: ('Acct-Link-Count', AVPNV_Unsigned32, 64), - 55: ('Event-Timestamp', AVPNV_Time, 64), - 60: ('CHAP-Challenge', AVPNV_OctetString, 64), - 61: ('NAS-Port-Type', AVP_0_61, 64), - 62: ('Port-Limit', AVPNV_Unsigned32, 64), - 63: ('Login-LAT-Port', AVPNV_OctetString, 64), - 64: ('Tunnel-Type', AVP_0_64, 64), - 65: ('Tunnel-Medium-Type', AVP_0_65, 64), - 66: ('Tunnel-Client-Endpoint', AVPNV_StrLenField, 64), - 67: ('Tunnel-Server-Endpoint', AVPNV_StrLenField, 64), - 68: ('Acct-Tunnel-Connection', AVPNV_OctetString, 64), - 69: ('Tunnel-Password', AVPNV_OctetString, 64), - 70: ('ARAP-Password', AVPNV_OctetString, 64), - 71: ('ARAP-Features', AVPNV_OctetString, 64), - 72: ('ARAP-Zone-Access', AVP_0_72, 64), - 73: ('ARAP-Security', AVPNV_Unsigned32, 64), - 74: ('ARAP-Security-Data', AVPNV_OctetString, 64), - 75: ('Password-Retry', AVPNV_Unsigned32, 64), - 76: ('Prompt', AVP_0_76, 64), - 77: ('Connect-Info', AVPNV_StrLenField, 64), - 78: ('Configuration-Token', AVPNV_OctetString, 64), - 81: ('Tunnel-Private-Group-Id', AVPNV_OctetString, 64), - 82: ('Tunnel-Assignment-Id', AVPNV_OctetString, 64), - 83: ('Tunnel-Preference', AVPNV_Unsigned32, 64), - 84: ('ARAP-Challenge-Response', AVPNV_OctetString, 64), - 85: ('Acct-Interim-Interval', AVPNV_Unsigned32, 64), - 86: ('Acct-Tunnel-Packets-Lost', AVPNV_Unsigned32, 64), - 87: ('NAS-Port-Id', AVPNV_StrLenField, 64), - 88: ('Framed-Pool', AVPNV_OctetString, 64), - 89: ('Chargeable-User-Identity', AVPNV_OctetString, 64), - 90: ('Tunnel-Client-Auth-Id', AVPNV_StrLenField, 64), - 91: ('Tunnel-Server-Auth-Id', AVPNV_StrLenField, 64), - 94: ('Originating-Line-Info', AVPNV_OctetString, 64), - 96: ('Framed-Interface-Id', AVPNV_Unsigned64, 64), - 97: ('Framed-IPv6-Prefix', AVPNV_OctetString, 64), - 99: ('Framed-IPv6-Route', AVPNV_StrLenField, 64), - 100: ('Framed-IPv6-Pool', AVPNV_OctetString, 64), - 102: ('EAP-Key-Name', AVPNV_OctetString, 64), - 104: ('Digest-Realm', AVPNV_StrLenField, 64), - 110: ('Digest-Qop', AVPNV_StrLenField, 64), - 111: ('Digest-Algorithm', AVPNV_StrLenField, 64), - 121: ('Digest-HA1', AVPNV_OctetString, 64), - 124: ('MIP6-Feature-Vector', AVPNV_Unsigned64, 64), - 125: ('MIP6-Home-Link-Prefix', AVPNV_OctetString, 64), - 257: ('Host-IP-Address', AVPNV_Address, 64), - 258: ('Auth-Application-Id', AVP_0_258, 64), - 259: ('Acct-Application-Id', AVPNV_Unsigned32, 64), - 260: ('Vendor-Specific-Application-Id', AVPNV_Grouped, 64), - 261: ('Redirect-Host-Usage', AVP_0_261, 64), - 262: ('Redirect-Max-Cache-Time', AVPNV_Unsigned32, 64), - 263: ('Session-Id', AVPNV_StrLenField, 64), - 264: ('Origin-Host', AVPNV_StrLenField, 64), - 265: ('Supported-Vendor-Id', AVPNV_Unsigned32, 64), - 266: ('Vendor-Id', AVP_0_266, 64), - 267: ('Firmware-Revision', AVPNV_Unsigned32, 0), - 268: ('Result-Code', AVP_0_268, 64), - 269: ('Product-Name', AVPNV_StrLenField, 0), - 270: ('Session-Binding', AVPNV_Unsigned32, 64), - 271: ('Session-Server-Failover', AVP_0_271, 64), - 272: ('Multi-Round-Time-Out', AVPNV_Unsigned32, 64), - 273: ('Disconnect-Cause', AVP_0_273, 64), - 274: ('Auth-Request-Type', AVP_0_274, 64), - 276: ('Auth-Grace-Period', AVPNV_Unsigned32, 64), - 277: ('Auth-Session-State', AVP_0_277, 64), - 278: ('Origin-State-Id', AVPNV_Unsigned32, 64), - 279: ('Failed-AVP', AVPNV_Grouped, 64), - 280: ('Proxy-Host', AVPNV_StrLenField, 64), - 281: ('Error-Message', AVPNV_StrLenField, 0), - 282: ('Route-Record', AVPNV_StrLenField, 64), - 283: ('Destination-Realm', AVPNV_StrLenField, 64), - 284: ('Proxy-Info', AVPNV_Grouped, 64), - 285: ('Re-Auth-Request-Type', AVP_0_285, 64), - 287: ('Accounting-Sub-Session-Id', AVPNV_Unsigned64, 64), - 291: ('Authorization-Lifetime', AVPNV_Unsigned32, 64), - 292: ('Redirect-Host', AVPNV_StrLenField, 64), - 293: ('Destination-Host', AVPNV_StrLenField, 64), - 294: ('Error-Reporting-Host', AVPNV_StrLenField, 0), - 295: ('Termination-Cause', AVP_0_295, 64), - 296: ('Origin-Realm', AVPNV_StrLenField, 64), - 297: ('Experimental-Result', AVPNV_Grouped, 64), - 298: ('Experimental-Result-Code', AVP_0_298, 64), - 299: ('Inband-Security-Id', AVPNV_Unsigned32, 64), - 318: ('MIP-FA-to-HA-SPI', AVPNV_Unsigned32, 64), - 319: ('MIP-FA-to-MN-SPI', AVPNV_Unsigned32, 64), - 320: ('MIP-Reg-Request', AVPNV_OctetString, 64), - 321: ('MIP-Reg-Reply', AVPNV_OctetString, 64), - 322: ('MIP-MN-AAA-Auth', AVPNV_Grouped, 64), - 323: ('MIP-HA-to-FA-SPI', AVPNV_Unsigned32, 64), - 325: ('MIP-MN-to-FA-MSA', AVPNV_Grouped, 64), - 326: ('MIP-FA-to-MN-MSA', AVPNV_Grouped, 64), - 328: ('MIP-FA-to-HA-MSA', AVPNV_Grouped, 64), - 329: ('MIP-HA-to-FA-MSA', AVPNV_Grouped, 64), - 331: ('MIP-MN-to-HA-MSA', AVPNV_Grouped, 64), - 332: ('MIP-HA-to-MN-MSA', AVPNV_Grouped, 64), - 333: ('MIP-Mobile-Node-Address', AVPNV_Address, 64), - 334: ('MIP-Home-Agent-Address', AVPNV_Address, 64), - 335: ('MIP-Nonce', AVPNV_OctetString, 64), - 336: ('MIP-Candidate-Home-Agent-Host', AVPNV_StrLenField, 64), - 337: ('MIP-Feature-Vector', AVPNV_Unsigned32, 64), - 338: ('MIP-Auth-Input-Data-Length', AVPNV_Unsigned32, 64), - 339: ('MIP-Authenticator-Length', AVPNV_Unsigned32, 64), - 340: ('MIP-Authenticator-Offset', AVPNV_Unsigned32, 64), - 341: ('MIP-MN-AAA-SPI', AVPNV_Unsigned32, 64), - 342: ('MIP-Filter-Rule', AVPNV_IPFilterRule, 64), - 343: ('MIP-Session-Key', AVPNV_OctetString, 64), - 344: ('MIP-FA-Challenge', AVPNV_OctetString, 64), - 345: ('MIP-Algorithm-Type', AVP_0_345, 64), - 346: ('MIP-Replay-Mode', AVP_0_346, 64), - 347: ('MIP-Originating-Foreign-AAA', AVPNV_Grouped, 64), - 348: ('MIP-Home-Agent-Host', AVPNV_StrLenField, 64), - 363: ('Accounting-Input-Octets', AVPNV_Unsigned64, 64), - 364: ('Accounting-Output-Octets', AVPNV_Unsigned64, 64), - 365: ('Accounting-Input-Packets', AVPNV_Unsigned64, 64), - 366: ('Accounting-Output-Packets', AVPNV_Unsigned64, 64), - 367: ('MIP-MSA-Lifetime', AVPNV_Unsigned32, 64), - 368: ('SIP-Accounting-Information', AVPNV_Grouped, 64), - 369: ('SIP-Accounting-Server-URI', AVPNV_StrLenField, 64), - 370: ('SIP-Credit-Control-Server-URI', AVPNV_StrLenField, 64), - 371: ('SIP-Server-URI', AVPNV_StrLenField, 64), - 372: ('SIP-Server-Capabilities', AVPNV_Grouped, 64), - 373: ('SIP-Mandatory-Capability', AVPNV_Unsigned32, 64), - 374: ('SIP-Optional-Capability', AVPNV_Unsigned32, 64), - 375: ('SIP-Server-Assignment-Type', AVP_0_375, 64), - 376: ('SIP-Auth-Data-Item', AVPNV_Grouped, 64), - 377: ('SIP-Authentication-Scheme', AVP_0_377, 64), - 378: ('SIP-Item-Number', AVPNV_Unsigned32, 64), - 379: ('SIP-Authenticate', AVPNV_Grouped, 64), - 380: ('SIP-Authorization', AVPNV_Grouped, 64), - 381: ('SIP-Authentication-Info', AVPNV_Grouped, 64), - 382: ('SIP-Number-Auth-Items', AVPNV_Unsigned32, 64), - 383: ('SIP-Deregistration-Reason', AVPNV_Grouped, 64), - 384: ('SIP-Reason-Code', AVP_0_384, 64), - 385: ('SIP-Reason-Info', AVPNV_StrLenField, 64), - 386: ('SIP-Visited-Network-Id', AVPNV_StrLenField, 64), - 387: ('SIP-User-Authorization-Type', AVP_0_387, 64), - 388: ('SIP-Supported-User-Data-Type', AVPNV_StrLenField, 64), - 389: ('SIP-User-Data', AVPNV_Grouped, 64), - 390: ('SIP-User-Data-Type', AVPNV_StrLenField, 64), - 391: ('SIP-User-Data-Contents', AVPNV_OctetString, 64), - 392: ('SIP-User-Data-Already-Available', AVP_0_392, 64), - 393: ('SIP-Method', AVPNV_StrLenField, 64), - 400: ('NAS-Filter-Rule', AVPNV_IPFilterRule, 64), - 401: ('Tunneling', AVPNV_Grouped, 64), - 402: ('CHAP-Auth', AVPNV_Grouped, 64), - 403: ('CHAP-Algorithm', AVP_0_403, 64), - 404: ('CHAP-Ident', AVPNV_OctetString, 64), - 405: ('CHAP-Response', AVPNV_OctetString, 64), - 406: ('Accounting-Auth-Method', AVP_0_406, 64), - 407: ('QoS-Filter-Rule', AVPNV_QoSFilterRule, 64), - 411: ('CC-Correlation-Id', AVPNV_OctetString, 0), - 412: ('CC-Input-Octets', AVPNV_Unsigned64, 64), - 413: ('CC-Money', AVPNV_Grouped, 64), - 414: ('CC-Output-Octets', AVPNV_Unsigned64, 64), - 415: ('CC-Request-Number', AVPNV_Unsigned32, 64), - 416: ('CC-Request-Type', AVP_0_416, 64), - 417: ('CC-Service-Specific-Units', AVPNV_Unsigned64, 64), - 418: ('CC-Session-Failover', AVP_0_418, 64), - 419: ('CC-Sub-Session-Id', AVPNV_Unsigned64, 64), - 420: ('CC-Time', AVPNV_Unsigned32, 64), - 421: ('CC-Total-Octets', AVPNV_Unsigned64, 64), - 422: ('Check-Balance-Result', AVP_0_422, 64), - 423: ('Cost-Information', AVPNV_Grouped, 64), - 424: ('Cost-Unit', AVPNV_StrLenField, 64), - 425: ('Currency-Code', AVPNV_Unsigned32, 64), - 426: ('Credit-Control', AVP_0_426, 64), - 427: ('Credit-Control-Failure-Handling', AVP_0_427, 64), - 428: ('Direct-Debiting-Failure-Handling', AVP_0_428, 64), - 429: ('Exponent', AVPNV_Integer32, 64), - 430: ('Final-Unit-Indication', AVPNV_Grouped, 64), - 431: ('Granted-Service-Unit', AVPNV_Grouped, 64), - 432: ('Rating-Group', AVPNV_Unsigned32, 64), - 433: ('Redirect-Address-Type', AVP_0_433, 64), - 434: ('Redirect-Server', AVPNV_Grouped, 64), - 435: ('Redirect-Server-Address', AVPNV_StrLenField, 64), - 436: ('Requested-Action', AVP_0_436, 64), - 437: ('Requested-Service-Unit', AVPNV_Grouped, 64), - 438: ('Restriction-Filter-Rule', AVPNV_IPFilterRule, 64), - 439: ('Service-Identifier', AVPNV_Unsigned32, 64), - 440: ('Service-Parameter-Info', AVPNV_Grouped, 0), - 441: ('Service-Parameter-Type', AVPNV_Unsigned32, 0), - 442: ('Service-Parameter-Value', AVPNV_OctetString, 0), - 443: ('Subscription-Id', AVPNV_Grouped, 64), - 444: ('Subscription-Id-Data', AVPNV_StrLenField, 64), - 445: ('Unit-Value', AVPNV_Grouped, 64), - 446: ('Used-Service-Unit', AVPNV_Grouped, 64), - 447: ('Value-Digits', AVPNV_Integer64, 64), - 448: ('Validity-Time', AVPNV_Unsigned32, 64), - 449: ('Final-Unit-Action', AVP_0_449, 64), - 450: ('Subscription-Id-Type', AVP_0_450, 64), - 451: ('Tariff-Time-Change', AVPNV_Time, 64), - 452: ('Tariff-Change-Usage', AVP_0_452, 64), - 453: ('G-S-U-Pool-Identifier', AVPNV_Unsigned32, 64), - 454: ('CC-Unit-Type', AVP_0_454, 64), - 455: ('Multiple-Services-Indicator', AVP_0_455, 64), - 456: ('Multiple-Services-Credit-Control', AVPNV_Grouped, 64), - 457: ('G-S-U-Pool-Reference', AVPNV_Grouped, 64), - 458: ('User-Equipment-Info', AVPNV_Grouped, 0), - 459: ('User-Equipment-Info-Type', AVP_0_459, 0), - 460: ('User-Equipment-Info-Value', AVPNV_OctetString, 0), - 461: ('Service-Context-Id', AVPNV_StrLenField, 64), - 462: ('EAP-Payload', AVPNV_OctetString, 64), - 463: ('EAP-Reissued-Payload', AVPNV_OctetString, 64), - 464: ('EAP-Master-Session-Key', AVPNV_OctetString, 64), - 465: ('Accounting-EAP-Auth-Method', AVPNV_Unsigned64, 64), - 480: ('Accounting-Record-Type', AVP_0_480, 64), - 483: ('Accounting-Realtime-Required', AVP_0_483, 64), - 485: ('Accounting-Record-Number', AVPNV_Unsigned32, 64), - 486: ('MIP6-Agent-Info', AVPNV_Grouped, 64), - 487: ('MIP-Careof-Address', AVPNV_Address, 64), - 488: ('MIP-Authenticator', AVPNV_OctetString, 64), - 489: ('MIP-MAC-Mobility-Data', AVPNV_OctetString, 64), - 490: ('MIP-Timestamp', AVPNV_OctetString, 64), - 491: ('MIP-MN-HA-SPI', AVPNV_Unsigned32, 64), - 492: ('MIP-MN-HA-MSA', AVPNV_Grouped, 64), - 493: ('Service-Selection', AVPNV_StrLenField, 64), - 494: ('MIP6-Auth-Mode', AVP_0_494, 64), - 506: ('Mobile-Node-Identifier', AVPNV_StrLenField, 64), - 508: ('QoS-Resources', AVPNV_Grouped, 64), - 509: ('Filter-Rule', AVPNV_Grouped, 64), - 510: ('Filter-Rule-Precedence', AVPNV_Unsigned32, 64), - 511: ('Classifier', AVPNV_Grouped, 64), - 512: ('Classifier-ID', AVPNV_OctetString, 64), - 513: ('Protocol', AVP_0_513, 64), - 514: ('Direction', AVP_0_514, 64), - 515: ('From-Spec', AVPNV_Grouped, 64), - 516: ('To-Spec', AVPNV_Grouped, 64), - 517: ('Negated', AVP_0_517, 64), - 518: ('IP-Address', AVPNV_Address, 64), - 519: ('IP-Address-Range', AVPNV_Grouped, 64), - 520: ('IP-Address-Start', AVPNV_Address, 64), - 521: ('IP-Address-End', AVPNV_Address, 64), - 522: ('IP-Address-Mask', AVPNV_Grouped, 64), - 523: ('IP-Mask-Bit-Mask-Width', AVPNV_Unsigned32, 64), - 524: ('MAC-Address', AVPNV_OctetString, 64), - 525: ('MAC-Address-Mask', AVPNV_Grouped, 64), - 526: ('MAC-Address-Mask-Pattern', AVPNV_OctetString, 64), - 527: ('EUI64-Address', AVPNV_OctetString, 64), - 528: ('EUI64-Address-Mask', AVPNV_Grouped, 64), - 529: ('EUI64-Address-Mask-Pattern', AVPNV_OctetString, 64), - 530: ('Port', AVPNV_Integer32, 64), - 531: ('Port-Range', AVPNV_Grouped, 64), - 532: ('Port-Start', AVPNV_Integer32, 64), - 533: ('Port-End', AVPNV_Integer32, 64), - 534: ('Use-Assigned-Address', AVP_0_534, 64), - 535: ('Diffserv-Code-Point', AVP_0_535, 64), - 536: ('Fragmentation-Flag', AVP_0_536, 64), - 537: ('IP-Option', AVPNV_Grouped, 64), - 538: ('IP-Option-Type', AVP_0_538, 64), - 539: ('IP-Option-Value', AVPNV_OctetString, 64), - 540: ('TCP-Option', AVPNV_Grouped, 64), - 541: ('TCP-Option-Type', AVP_0_541, 64), - 542: ('TCP-Option-Value', AVPNV_OctetString, 64), - 543: ('TCP-Flags', AVPNV_Grouped, 64), - 544: ('TCP-Flag-Type', AVPNV_Unsigned32, 64), - 545: ('ICMP-Type', AVPNV_Grouped, 64), - 546: ('ICMP-Type-Number', AVP_0_546, 64), - 547: ('ICMP-Code', AVP_0_547, 64), - 548: ('ETH-Option', AVPNV_Grouped, 64), - 549: ('ETH-Proto-Type', AVPNV_Grouped, 64), - 550: ('ETH-Ether-Type', AVPNV_OctetString, 64), - 551: ('ETH-SAP', AVPNV_OctetString, 64), - 552: ('VLAN-ID-Range', AVPNV_Grouped, 64), - 553: ('S-VID-Start', AVPNV_Unsigned32, 64), - 554: ('S-VID-End', AVPNV_Unsigned32, 64), - 555: ('C-VID-Start', AVPNV_Unsigned32, 64), - 556: ('C-VID-End', AVPNV_Unsigned32, 64), - 557: ('User-Priority-Range', AVPNV_Grouped, 64), - 558: ('Low-User-Priority', AVPNV_Unsigned32, 64), - 559: ('High-User-Priority', AVPNV_Unsigned32, 64), - 560: ('Time-Of-Day-Condition', AVPNV_Grouped, 64), - 561: ('Time-Of-Day-Start', AVPNV_Unsigned32, 64), - 562: ('Time-Of-Day-End', AVPNV_Unsigned32, 64), - 563: ('Day-Of-Week-Mask', AVPNV_Unsigned32, 64), - 564: ('Day-Of-Month-Mask', AVPNV_Unsigned32, 64), - 565: ('Month-Of-Year-Mask', AVPNV_Unsigned32, 64), - 566: ('Absolute-Start-Time', AVPNV_Time, 64), - 567: ('Absolute-Start-Fractional-Seconds', AVPNV_Unsigned32, 64), - 568: ('Absolute-End-Time', AVPNV_Time, 64), - 569: ('Absolute-End-Fractional-Seconds', AVPNV_Unsigned32, 64), - 570: ('Timezone-Flag', AVP_0_570, 64), - 571: ('Timezone-Offset', AVPNV_Integer32, 64), - 572: ('Treatment-Action', AVPNV_Grouped, 64), - 573: ('QoS-Profile-Id', AVPNV_Unsigned32, 64), - 574: ('QoS-Profile-Template', AVPNV_Grouped, 64), - 575: ('QoS-Semantics', AVP_0_575, 64), - 576: ('QoS-Parameters', AVPNV_Grouped, 64), - 577: ('Excess-Treatment', AVPNV_Grouped, 64), - 578: ('QoS-Capability', AVPNV_Grouped, 64), - 618: ('ERP-RK-Request', AVPNV_Grouped, 64), - 619: ('ERP-Realm', AVPNV_StrLenField, 64), - }, - 10415: { - 13: ('3GPP-Charging-Characteristics', AVPV_StrLenField, 192), - 318: ('3GPP-AAA-Server-Name', AVPV_StrLenField, 192), - 500: ('Abort-Cause', AVP_10415_500, 192), - 501: ('Access-Network-Charging-Address', AVPV_Address, 192), - 502: ('Access-Network-Charging-Identifier', AVPV_Grouped, 192), - 503: ('Access-Network-Charging-Identifier-Value', AVPV_OctetString, 192), # noqa: E501 - 504: ('AF-Application-Identifier', AVPV_OctetString, 192), - 505: ('AF-Charging-Identifier', AVPV_OctetString, 192), - 506: ('Authorization-Token', AVPV_OctetString, 192), - 507: ('Flow-Description', AVPV_IPFilterRule, 192), - 508: ('Flow-Grouping', AVPV_Grouped, 192), - 509: ('Flow-Number', AVPV_Unsigned32, 192), - 510: ('Flows', AVPV_Grouped, 192), - 511: ('Flow-Status', AVP_10415_511, 192), - 512: ('Flow-Usage', AVP_10415_512, 192), - 513: ('Specific-Action', AVP_10415_513, 192), - 515: ('Max-Requested-Bandwidth-DL', AVPV_Unsigned32, 192), - 516: ('Max-Requested-Bandwidth-UL', AVPV_Unsigned32, 192), - 517: ('Media-Component-Description', AVPV_Grouped, 192), - 518: ('Media-Component-Number', AVPV_Unsigned32, 192), - 519: ('Media-Sub-Component', AVPV_Grouped, 192), - 520: ('Media-Type', AVP_10415_520, 192), - 521: ('RR-Bandwidth', AVPV_Unsigned32, 192), - 522: ('RS-Bandwidth', AVPV_Unsigned32, 192), - 523: ('SIP-Forking-Indication', AVP_10415_523, 192), - 525: ('Service-URN', AVPV_OctetString, 192), - 526: ('Acceptable-Service-Info', AVPV_Grouped, 192), - 527: ('Service-Info-Status', AVP_10415_527, 192), - 528: ('MPS-Identifier', AVPV_OctetString, 128), - 529: ('AF-Signalling-Protocol', AVP_10415_529, 128), - 531: ('Sponsor-Identity', AVPV_StrLenField, 128), - 532: ('Application-Service-Provider-Identity', AVPV_StrLenField, 128), - 533: ('Rx-Request-Type', AVP_10415_533, 128), - 534: ('Min-Requested-Bandwidth-DL', AVPV_Unsigned32, 128), - 535: ('Min-Requested-Bandwidth-UL', AVPV_Unsigned32, 128), - 536: ('Required-Access-Info', AVP_10415_536, 128), - 537: ('IP-Domain-Id', AVPV_OctetString, 128), - 538: ('GCS-Identifier', AVPV_OctetString, 128), - 539: ('Sharing-Key-DL', AVPV_Unsigned32, 128), - 540: ('Sharing-Key-UL', AVPV_Unsigned32, 128), - 541: ('Retry-Interval', AVPV_Unsigned32, 128), - 600: ('Visited-Network-Identifier', AVPV_OctetString, 192), - 601: ('Public-Identity', AVPV_StrLenField, 192), - 602: ('Server-Name', AVPV_StrLenField, 192), - 603: ('Server-Capabilities', AVPV_Grouped, 192), - 604: ('Mandatory-Capability', AVPV_Unsigned32, 192), - 605: ('Optional-Capability', AVPV_Unsigned32, 192), - 606: ('User-Data', AVPV_OctetString, 192), - 607: ('SIP-Number-Auth-Items', AVPV_Unsigned32, 192), - 608: ('SIP-Authentication-Scheme', AVPV_StrLenField, 192), - 609: ('SIP-Authenticate', AVPV_OctetString, 192), - 610: ('SIP-Authorization', AVPV_OctetString, 192), - 611: ('SIP-Authentication-Context', AVPV_OctetString, 192), - 612: ('SIP-Auth-Data-Item', AVPV_Grouped, 192), - 613: ('SIP-Item-Number', AVPV_Unsigned32, 192), - 614: ('Server-Assignment-Type', AVP_10415_614, 192), - 615: ('Deregistration-Reason', AVPV_Grouped, 192), - 616: ('Reason-Code', AVP_10415_616, 192), - 617: ('Reason-Info', AVPV_StrLenField, 192), - 618: ('Charging-Information', AVPV_Grouped, 192), - 619: ('Primary-Event-Charging-Function-Name', AVPV_StrLenField, 192), - 620: ('Secondary-Event-Charging-Function-Name', AVPV_StrLenField, 192), - 621: ('Primary-Charging-Collection-Function-Name', AVPV_StrLenField, 192), # noqa: E501 - 622: ('Secondary-Charging-Collection-Function-Name', AVPV_StrLenField, 192), # noqa: E501 - 623: ('User-Authorization-Type', AVP_10415_623, 192), - 624: ('User-Data-Already-Available', AVP_10415_624, 192), - 625: ('Confidentiality-Key', AVPV_OctetString, 192), - 626: ('Integrity-Key', AVPV_OctetString, 192), - 628: ('Supported-Features', AVPV_Grouped, 128), - 629: ('Feature-List-ID', AVPV_Unsigned32, 128), - 630: ('Feature-List', AVP_10415_630, 128), - 631: ('Supported-Applications', AVPV_Grouped, 128), - 632: ('Associated-Identities', AVPV_Grouped, 128), - 633: ('Originating-Request', AVP_10415_633, 192), - 634: ('Wildcarded-Public-Identity', AVPV_StrLenField, 128), - 635: ('SIP-Digest-Authenticate', AVPV_Grouped, 128), - 636: ('Wildcarded-IMPU', AVPV_StrLenField, 128), - 637: ('UAR-Flags', AVPV_Unsigned32, 128), - 638: ('Loose-Route-Indication', AVP_10415_638, 128), - 639: ('SCSCF-Restoration-Info', AVPV_Grouped, 128), - 640: ('Path', AVPV_OctetString, 128), - 641: ('Contact', AVPV_OctetString, 128), - 642: ('Subscription-Info', AVPV_Grouped, 128), - 643: ('Call-ID-SIP-Header', AVPV_OctetString, 128), - 644: ('From-SIP-Header', AVPV_OctetString, 128), - 645: ('To-SIP-Header', AVPV_OctetString, 128), - 646: ('Record-Route', AVPV_OctetString, 128), - 647: ('Associated-Registered-Identities', AVPV_Grouped, 128), - 648: ('Multiple-Registration-Indication', AVP_10415_648, 128), - 649: ('Restoration-Info', AVPV_Grouped, 128), - 650: ('Session-Priority', AVP_10415_650, 128), - 651: ('Identity-with-Emergency-Registration', AVPV_Grouped, 128), - 652: ('Priviledged-Sender-Indication', AVP_10415_652, 128), - 653: ('LIA-Flags', AVPV_Unsigned32, 128), - 654: ('Initial-CSeq-Sequence-Number', AVPV_Unsigned32, 128), - 655: ('SAR-Flags', AVPV_Unsigned32, 128), - 700: ('User-Identity', AVPV_Grouped, 192), - 701: ('MSISDN', AVP_10415_701, 192), - 702: ('User-Data', AVPV_OctetString, 192), - 703: ('Data-Reference', AVP_10415_703, 192), - 704: ('Service-Indication', AVPV_OctetString, 192), - 705: ('Subs-Req-Type', AVP_10415_705, 192), - 706: ('Requested-Domain', AVP_10415_706, 192), - 707: ('Current-Location', AVP_10415_707, 192), - 708: ('Identity-Set', AVP_10415_708, 128), - 709: ('Expiry-Time', AVPV_Time, 128), - 710: ('Send-Data-Indication', AVP_10415_710, 128), - 711: ('DSAI-Tag', AVPV_OctetString, 192), - 712: ('One-Time-Notification', AVP_10415_712, 128), - 713: ('Requested-Nodes', AVPV_Unsigned32, 128), - 714: ('Serving-Node-Indication', AVP_10415_714, 128), - 715: ('Repository-Data-ID', AVPV_Grouped, 128), - 716: ('Sequence-Number', AVPV_Unsigned32, 128), - 717: ('Pre-paging-Supported', AVP_10415_717, 128), - 718: ('Local-Time-Zone-Indication', AVP_10415_718, 128), - 719: ('UDR-Flags', AVPV_Unsigned32, 128), - 720: ('Call-Reference-Info', AVPV_Grouped, 128), - 721: ('Call-Reference-Number', AVPV_OctetString, 128), - 722: ('AS-Number', AVPV_OctetString, 128), - 823: ('Event-Type', AVPV_Grouped, 192), - 824: ('SIP-Method', AVPV_StrLenField, 192), - 825: ('Event', AVPV_StrLenField, 192), - 826: ('Content-Type', AVPV_StrLenField, 192), - 827: ('Content-Length', AVPV_Unsigned32, 192), - 828: ('Content-Disposition', AVPV_StrLenField, 192), - 829: ('Role-Of-Node', AVP_10415_829, 192), - 830: ('Session-Id', AVPV_StrLenField, 192), - 831: ('Calling-Party-Address', AVPV_StrLenField, 192), - 832: ('Called-Party-Address', AVPV_StrLenField, 192), - 833: ('Time-Stamps', AVPV_Grouped, 192), - 834: ('SIP-Request-Timestamp', AVPV_Time, 192), - 835: ('SIP-Response-Timestamp', AVPV_Time, 192), - 836: ('Application-Server', AVPV_StrLenField, 192), - 837: ('Application-provided-called-party-address', AVPV_StrLenField, 192), # noqa: E501 - 838: ('Inter-Operator-Identifier', AVPV_Grouped, 192), - 839: ('Originating-IOI', AVPV_StrLenField, 192), - 840: ('Terminating-IOI', AVPV_StrLenField, 192), - 841: ('IMS-Charging-Identifier', AVPV_StrLenField, 192), - 842: ('SDP-Session-Description', AVPV_StrLenField, 192), - 843: ('SDP-Media-Component', AVPV_Grouped, 192), - 844: ('SDP-Media-Name', AVPV_StrLenField, 192), - 845: ('SDP-Media-Description', AVPV_StrLenField, 192), - 846: ('CG-Address', AVPV_Address, 192), - 847: ('GGSN-Address', AVPV_Address, 192), - 848: ('Served-Party-IP-Address', AVPV_Address, 192), - 849: ('Authorised-QoS', AVPV_StrLenField, 192), - 850: ('Application-Server-Information', AVPV_Grouped, 192), - 851: ('Trunk-Group-Id', AVPV_Grouped, 192), - 852: ('Incoming-Trunk-Group-Id', AVPV_StrLenField, 192), - 853: ('Outgoing-Trunk-Group-Id', AVPV_StrLenField, 192), - 854: ('Bearer-Service', AVPV_OctetString, 192), - 855: ('Service-Id', AVPV_StrLenField, 192), - 856: ('Associated-URI', AVPV_StrLenField, 192), - 857: ('Charged-Party', AVPV_StrLenField, 192), - 858: ('PoC-Controlling-Address', AVPV_StrLenField, 192), - 859: ('PoC-Group-Name', AVPV_StrLenField, 192), - 861: ('Cause-Code', AVPV_Integer32, 192), - 862: ('Node-Functionality', AVP_10415_862, 192), - 864: ('Originator', AVP_10415_864, 192), - 865: ('PS-Furnish-Charging-Information', AVPV_Grouped, 192), - 866: ('PS-Free-Format-Data', AVPV_OctetString, 192), - 867: ('PS-Append-Free-Format-Data', AVP_10415_867, 192), - 868: ('Time-Quota-Threshold', AVPV_Unsigned32, 192), - 869: ('Volume-Quota-Threshold', AVPV_Unsigned32, 192), - 870: ('Trigger-Type', AVP_10415_870, 192), - 871: ('Quota-Holding-Time', AVPV_Unsigned32, 192), - 872: ('Reporting-Reason', AVP_10415_872, 192), - 873: ('Service-Information', AVPV_Grouped, 192), - 874: ('PS-Information', AVPV_Grouped, 192), - 876: ('IMS-Information', AVPV_Grouped, 192), - 877: ('MMS-Information', AVPV_Grouped, 192), - 878: ('LCS-Information', AVPV_Grouped, 192), - 879: ('PoC-Information', AVPV_Grouped, 192), - 880: ('MBMS-Information', AVPV_Grouped, 192), - 881: ('Quota-Consumption-Time', AVPV_Unsigned32, 192), - 882: ('Media-Initiator-Flag', AVP_10415_882, 192), - 883: ('PoC-Server-Role', AVP_10415_883, 192), - 884: ('PoC-Session-Type', AVP_10415_884, 192), - 885: ('Number-Of-Participants', AVPV_Unsigned32, 192), - 887: ('Participants-Involved', AVPV_StrLenField, 192), - 888: ('Expires', AVPV_Unsigned32, 192), - 889: ('Message-Body', AVPV_Grouped, 192), - 897: ('Address-Data', AVPV_StrLenField, 192), - 898: ('Address-Domain', AVPV_Grouped, 192), - 899: ('Address-Type', AVP_10415_899, 192), - 900: ('TMGI', AVPV_OctetString, 192), - 901: ('Required-MBMS-Bearer-Capabilities', AVPV_StrLenField, 192), - 902: ('MBMS-StartStop-Indication', AVP_10415_902, 192), - 903: ('MBMS-Service-Area', AVPV_OctetString, 192), - 904: ('MBMS-Session-Duration', AVPV_OctetString, 192), - 905: ('Alternative-APN', AVPV_StrLenField, 192), - 906: ('MBMS-Service-Type', AVP_10415_906, 192), - 907: ('MBMS-2G-3G-Indicator', AVP_10415_907, 192), - 909: ('RAI', AVPV_StrLenField, 192), - 910: ('Additional-MBMS-Trace-Info', AVPV_OctetString, 192), - 911: ('MBMS-Time-To-Data-Transfer', AVPV_OctetString, 192), - 920: ('MBMS-Flow-Identifier', AVPV_OctetString, 192), - 921: ('CN-IP-Multicast-Distribution', AVP_10415_921, 192), - 922: ('MBMS-HC-Indicator', AVP_10415_922, 192), - 1000: ('Bearer-Usage', AVP_10415_1000, 192), - 1001: ('Charging-Rule-Install', AVPV_Grouped, 192), - 1002: ('Charging-Rule-Remove', AVPV_Grouped, 192), - 1003: ('Charging-Rule-Definition', AVPV_Grouped, 192), - 1004: ('Charging-Rule-Base-Name', AVPV_StrLenField, 192), - 1005: ('Charging-Rule-Name', AVPV_OctetString, 192), - 1006: ('Event-Trigger', AVP_10415_1006, 192), - 1007: ('Metering-Method', AVP_10415_1007, 192), - 1008: ('Offline', AVP_10415_1008, 192), - 1009: ('Online', AVP_10415_1009, 192), - 1010: ('Precedence', AVPV_Unsigned32, 192), - 1011: ('Reporting-Level', AVP_10415_1011, 192), - 1012: ('TFT-Filter', AVPV_IPFilterRule, 192), - 1013: ('TFT-Packet-Filter-Information', AVPV_Grouped, 192), - 1014: ('ToS-Traffic-Class', AVPV_OctetString, 192), - 1015: ('PDP-Session-Operation', AVP_10415_1015, 192), - 1018: ('Charging-Rule-Report', AVPV_Grouped, 192), - 1019: ('PCC-Rule-Status', AVP_10415_1019, 192), - 1020: ('Bearer-Identifier', AVPV_OctetString, 192), - 1021: ('Bearer-Operation', AVP_10415_1021, 192), - 1022: ('Access-Network-Charging-Identifier-Gx', AVPV_Grouped, 192), - 1023: ('Bearer-Control-Mode', AVP_10415_1023, 192), - 1024: ('Network-Request-Support', AVP_10415_1024, 192), - 1025: ('Guaranteed-Bitrate-DL', AVPV_Unsigned32, 192), - 1026: ('Guaranteed-Bitrate-UL', AVPV_Unsigned32, 192), - 1027: ('IP-CAN-Type', AVP_10415_1027, 192), - 1028: ('QoS-Class-Identifier', AVP_10415_1028, 192), - 1032: ('RAT-Type', AVP_10415_1032, 128), - 1033: ('Event-Report-Indication', AVPV_Grouped, 128), - 1034: ('Allocation-Retention-Priority', AVPV_Grouped, 128), - 1035: ('CoA-IP-Address', AVPV_Address, 128), - 1036: ('Tunnel-Header-Filter', AVPV_IPFilterRule, 128), - 1037: ('Tunnel-Header-Length', AVPV_Unsigned32, 128), - 1038: ('Tunnel-Information', AVPV_Grouped, 128), - 1039: ('CoA-Information', AVPV_Grouped, 128), - 1040: ('APN-Aggregate-Max-Bitrate-DL', AVPV_Unsigned32, 128), - 1041: ('APN-Aggregate-Max-Bitrate-UL', AVPV_Unsigned32, 128), - 1042: ('Revalidation-Time', AVPV_Time, 192), - 1043: ('Rule-Activation-Time', AVPV_Time, 192), - 1044: ('Rule-Deactivation-Time', AVPV_Time, 192), - 1045: ('Session-Release-Cause', AVP_10415_1045, 192), - 1046: ('Priority-Level', AVPV_Unsigned32, 128), - 1047: ('Pre-emption-Capability', AVP_10415_1047, 128), - 1048: ('Pre-emption-Vulnerability', AVP_10415_1048, 128), - 1049: ('Default-EPS-Bearer-QoS', AVPV_Grouped, 128), - 1050: ('AN-GW-Address', AVPV_Address, 128), - 1056: ('Security-Parameter-Index', AVPV_OctetString, 128), - 1057: ('Flow-Label', AVPV_OctetString, 128), - 1058: ('Flow-Information', AVPV_Grouped, 128), - 1059: ('Packet-Filter-Content', AVPV_IPFilterRule, 128), - 1060: ('Packet-Filter-Identifier', AVPV_OctetString, 128), - 1061: ('Packet-Filter-Information', AVPV_Grouped, 128), - 1062: ('Packet-Filter-Operation', AVP_10415_1062, 128), - 1063: ('Resource-Allocation-Notification', AVP_10415_1063, 128), - 1065: ('PDN-Connection-ID', AVPV_OctetString, 128), - 1066: ('Monitoring-Key', AVPV_OctetString, 128), - 1067: ('Usage-Monitoring-Information', AVPV_Grouped, 128), - 1068: ('Usage-Monitoring-Level', AVP_10415_1068, 128), - 1069: ('Usage-Monitoring-Report', AVP_10415_1069, 128), - 1070: ('Usage-Monitoring-Support', AVP_10415_1070, 128), - 1071: ('CSG-Information-Reporting', AVP_10415_1071, 128), - 1072: ('Packet-Filter-Usage', AVP_10415_1072, 128), - 1073: ('Charging-Correlation-Indicator', AVP_10415_1073, 128), - 1075: ('Routing-Rule-Remove', AVPV_Grouped, 128), - 1076: ('Routing-Rule-Definition', AVPV_Grouped, 128), - 1077: ('Routing-Rule-Identifier', AVPV_OctetString, 128), - 1078: ('Routing-Filter', AVPV_Grouped, 128), - 1079: ('Routing-IP-Address', AVPV_Address, 128), - 1080: ('Flow-Direction', AVP_10415_1080, 128), - 1082: ('Credit-Management-Status', AVPV_Unsigned32, 128), - 1085: ('Redirect-Information', AVPV_Grouped, 128), - 1086: ('Redirect-Support', AVP_10415_1086, 128), - 1087: ('TDF-Information', AVPV_Grouped, 128), - 1088: ('TDF-Application-Identifier', AVPV_OctetString, 128), - 1089: ('TDF-Destination-Host', AVPV_StrLenField, 128), - 1090: ('TDF-Destination-Realm', AVPV_StrLenField, 128), - 1091: ('TDF-IP-Address', AVPV_Address, 128), - 1098: ('Application-Detection-Information', AVPV_Grouped, 128), - 1099: ('PS-to-CS-Session-Continuity', AVP_10415_1099, 128), - 1200: ('Domain-Name', AVPV_StrLenField, 192), - 1203: ('MM-Content-Type', AVPV_Grouped, 192), - 1204: ('Type-Number', AVP_10415_1204, 192), - 1205: ('Additional-Type-Information', AVPV_StrLenField, 192), - 1206: ('Content-Size', AVPV_Unsigned32, 192), - 1207: ('Additional-Content-Information', AVPV_Grouped, 192), - 1208: ('Addressee-Type', AVP_10415_1208, 192), - 1209: ('Priority', AVP_10415_1209, 192), - 1211: ('Message-Type', AVP_10415_1211, 192), - 1212: ('Message-Size', AVPV_Unsigned32, 192), - 1213: ('Message-Class', AVPV_Grouped, 192), - 1214: ('Class-Identifier', AVP_10415_1214, 192), - 1215: ('Token-Text', AVPV_StrLenField, 192), - 1216: ('Delivery-Report-Requested', AVP_10415_1216, 192), - 1217: ('Adaptations', AVP_10415_1217, 192), - 1218: ('Applic-ID', AVPV_StrLenField, 192), - 1219: ('Aux-Applic-Info', AVPV_StrLenField, 192), - 1220: ('Content-Class', AVP_10415_1220, 192), - 1221: ('DRM-Content', AVP_10415_1221, 192), - 1222: ('Read-Reply-Report-Requested', AVP_10415_1222, 192), - 1223: ('Reply-Applic-ID', AVPV_StrLenField, 192), - 1224: ('File-Repair-Supported', AVP_10415_1224, 192), - 1225: ('MBMS-User-Service-Type', AVP_10415_1225, 192), - 1226: ('Unit-Quota-Threshold', AVPV_Unsigned32, 192), - 1227: ('PDP-Address', AVPV_Address, 192), - 1228: ('SGSN-Address', AVPV_Address, 192), - 1229: ('PoC-Session-Id', AVPV_StrLenField, 192), - 1230: ('Deferred-Location-Event-Type', AVPV_StrLenField, 192), - 1231: ('LCS-APN', AVPV_StrLenField, 192), - 1245: ('Positioning-Data', AVPV_StrLenField, 192), - 1247: ('PDP-Context-Type', AVP_10415_1247, 192), - 1248: ('MMBox-Storage-Requested', AVP_10415_1248, 192), - 1250: ('Called-Asserted-Identity', AVPV_StrLenField, 192), - 1251: ('Requested-Party-Address', AVPV_StrLenField, 192), - 1252: ('PoC-User-Role', AVPV_Grouped, 192), - 1253: ('PoC-User-Role-IDs', AVPV_StrLenField, 192), - 1254: ('PoC-User-Role-info-Units', AVP_10415_1254, 192), - 1255: ('Talk-Burst-Exchange', AVPV_Grouped, 192), - 1258: ('Event-Charging-TimeStamp', AVPV_Time, 192), - 1259: ('Participant-Access-Priority', AVP_10415_1259, 192), - 1260: ('Participant-Group', AVPV_Grouped, 192), - 1261: ('PoC-Change-Condition', AVP_10415_1261, 192), - 1262: ('PoC-Change-Time', AVPV_Time, 192), - 1263: ('Access-Network-Information', AVPV_OctetString, 192), - 1264: ('Trigger', AVPV_Grouped, 192), - 1265: ('Base-Time-Interval', AVPV_Unsigned32, 192), - 1266: ('Envelope', AVPV_Grouped, 192), - 1267: ('Envelope-End-Time', AVPV_Time, 192), - 1268: ('Envelope-Reporting', AVP_10415_1268, 192), - 1269: ('Envelope-Start-Time', AVPV_Time, 192), - 1270: ('Time-Quota-Mechanism', AVPV_Grouped, 192), - 1271: ('Time-Quota-Type', AVP_10415_1271, 192), - 1272: ('Early-Media-Description', AVPV_Grouped, 192), - 1273: ('SDP-TimeStamps', AVPV_Grouped, 192), - 1274: ('SDP-Offer-Timestamp', AVPV_Time, 192), - 1275: ('SDP-Answer-Timestamp', AVPV_Time, 192), - 1276: ('AF-Correlation-Information', AVPV_Grouped, 192), - 1277: ('PoC-Session-Initiation-Type', AVP_10415_1277, 192), - 1278: ('Offline-Charging', AVPV_Grouped, 192), - 1279: ('User-Participating-Type', AVP_10415_1279, 192), - 1281: ('IMS-Communication-Service-Identifier', AVPV_StrLenField, 192), - 1282: ('Number-Of-Received-Talk-Bursts', AVPV_Unsigned32, 192), - 1283: ('Number-Of-Talk-Bursts', AVPV_Unsigned32, 192), - 1284: ('Received-Talk-Burst-Time', AVPV_Unsigned32, 192), - 1285: ('Received-Talk-Burst-Volume', AVPV_Unsigned32, 192), - 1286: ('Talk-Burst-Time', AVPV_Unsigned32, 192), - 1287: ('Talk-Burst-Volume', AVPV_Unsigned32, 192), - 1288: ('Media-Initiator-Party', AVPV_StrLenField, 192), - 1400: ('Subscription-Data', AVPV_Grouped, 192), - 1401: ('Terminal-Information', AVPV_Grouped, 192), - 1402: ('IMEI', AVPV_StrLenField, 192), - 1403: ('Software-Version', AVPV_StrLenField, 192), - 1404: ('QoS-Subscribed', AVPV_OctetString, 192), - 1405: ('ULR-Flags', AVPV_Unsigned32, 192), - 1406: ('ULA-Flags', AVPV_Unsigned32, 192), - 1407: ('Visited-PLMN-Id', AVPV_OctetString, 192), - 1408: ('Requested-EUTRAN-Authentication-Info', AVPV_Grouped, 192), - 1409: ('GERAN-Authentication-Info', AVPV_Grouped, 192), - 1410: ('Number-Of-Requested-Vectors', AVPV_Unsigned32, 192), - 1411: ('Re-Synchronization-Info', AVPV_OctetString, 192), - 1412: ('Immediate-Response-Preferred', AVPV_Unsigned32, 192), - 1413: ('Authentication-Info', AVPV_Grouped, 192), - 1414: ('E-UTRAN-Vector', AVPV_Grouped, 192), - 1415: ('UTRAN-Vector', AVPV_Grouped, 192), - 1416: ('GERAN-Vector', AVPV_Grouped, 192), - 1417: ('Network-Access-Mode', AVP_10415_1417, 192), - 1418: ('HPLMN-ODB', AVPV_Unsigned32, 192), - 1419: ('Item-Number', AVPV_Unsigned32, 192), - 1420: ('Cancellation-Type', AVP_10415_1420, 192), - 1421: ('DSR-Flags', AVPV_Unsigned32, 192), - 1422: ('DSA-Flags', AVPV_Unsigned32, 192), - 1423: ('Context-Identifier', AVPV_Unsigned32, 192), - 1424: ('Subscriber-Status', AVP_10415_1424, 192), - 1425: ('Operator-Determined-Barring', AVPV_Unsigned32, 192), - 1426: ('Access-Restriction-Data', AVPV_Unsigned32, 192), - 1427: ('APN-OI-Replacement', AVPV_StrLenField, 192), - 1428: ('All-APN-Configurations-Included-Indicator', AVP_10415_1428, 192), # noqa: E501 - 1429: ('APN-Configuration-Profile', AVPV_Grouped, 192), - 1430: ('APN-Configuration', AVPV_Grouped, 192), - 1431: ('EPS-Subscribed-QoS-Profile', AVPV_Grouped, 192), - 1432: ('VPLMN-Dynamic-Address-Allowed', AVP_10415_1432, 192), - 1433: ('STN-SR', AVPV_OctetString, 192), - 1434: ('Alert-Reason', AVP_10415_1434, 192), - 1435: ('AMBR', AVPV_Grouped, 192), - 1437: ('CSG-Id', AVPV_Unsigned32, 192), - 1438: ('PDN-GW-Allocation-Type', AVP_10415_1438, 192), - 1439: ('Expiration-Date', AVPV_Time, 192), - 1440: ('RAT-Frequency-Selection-Priority-ID', AVPV_Unsigned32, 192), - 1441: ('IDA-Flags', AVPV_Unsigned32, 192), - 1442: ('PUA-Flags', AVPV_Unsigned32, 192), - 1443: ('NOR-Flags', AVPV_Unsigned32, 192), - 1444: ('User-Id', AVPV_StrLenField, 128), - 1445: ('Equipment-Status', AVP_10415_1445, 192), - 1446: ('Regional-Subscription-Zone-Code', AVPV_OctetString, 192), - 1447: ('RAND', AVPV_OctetString, 192), - 1448: ('XRES', AVPV_OctetString, 192), - 1449: ('AUTN', AVPV_OctetString, 192), - 1450: ('KASME', AVPV_OctetString, 192), - 1452: ('Trace-Collection-Entity', AVPV_Address, 192), - 1453: ('Kc', AVPV_OctetString, 192), - 1454: ('SRES', AVPV_OctetString, 192), - 1456: ('PDN-Type', AVP_10415_1456, 192), - 1457: ('Roaming-Restricted-Due-To-Unsupported-Feature', AVP_10415_1457, 192), # noqa: E501 - 1458: ('Trace-Data', AVPV_Grouped, 192), - 1459: ('Trace-Reference', AVPV_OctetString, 192), - 1462: ('Trace-Depth', AVP_10415_1462, 192), - 1463: ('Trace-NE-Type-List', AVPV_OctetString, 192), - 1464: ('Trace-Interface-List', AVPV_OctetString, 192), - 1465: ('Trace-Event-List', AVPV_OctetString, 192), - 1466: ('OMC-Id', AVPV_OctetString, 192), - 1467: ('GPRS-Subscription-Data', AVPV_Grouped, 192), - 1468: ('Complete-Data-List-Included-Indicator', AVP_10415_1468, 192), - 1469: ('PDP-Context', AVPV_Grouped, 192), - 1470: ('PDP-Type', AVPV_OctetString, 192), - 1471: ('3GPP2-MEID', AVPV_OctetString, 192), - 1472: ('Specific-APN-Info', AVPV_Grouped, 192), - 1473: ('LCS-Info', AVPV_Grouped, 192), - 1474: ('GMLC-Number', AVPV_OctetString, 192), - 1475: ('LCS-PrivacyException', AVPV_Grouped, 192), - 1476: ('SS-Code', AVPV_OctetString, 192), - 1477: ('SS-Status', AVPV_OctetString, 192), - 1478: ('Notification-To-UE-User', AVP_10415_1478, 192), - 1479: ('External-Client', AVPV_Grouped, 192), - 1480: ('Client-Identity', AVPV_OctetString, 192), - 1481: ('GMLC-Restriction', AVP_10415_1481, 192), - 1482: ('PLMN-Client', AVP_10415_1482, 192), - 1483: ('Service-Type', AVPV_Grouped, 192), - 1484: ('ServiceTypeIdentity', AVPV_Unsigned32, 192), - 1485: ('MO-LR', AVPV_Grouped, 192), - 1486: ('Teleservice-List', AVPV_Grouped, 192), - 1487: ('TS-Code', AVPV_OctetString, 192), - 1488: ('Call-Barring-Info', AVPV_Grouped, 192), - 1489: ('SGSN-Number', AVPV_OctetString, 192), - 1490: ('IDR-Flags', AVPV_Unsigned32, 192), - 1491: ('ICS-Indicator', AVP_10415_1491, 128), - 1492: ('IMS-Voice-Over-PS-Sessions-Supported', AVP_10415_1492, 128), - 1493: ('Homogeneous-Support-of-IMS-Voice-Over-PS-Sessions', AVP_10415_1493, 128), # noqa: E501 - 1494: ('Last-UE-Activity-Time', AVPV_Time, 128), - 1495: ('EPS-User-State', AVPV_Grouped, 128), - 1496: ('EPS-Location-Information', AVPV_Grouped, 128), - 1497: ('MME-User-State', AVPV_Grouped, 128), - 1498: ('SGSN-User-State', AVPV_Grouped, 128), - 1499: ('User-State', AVP_10415_1499, 128), - 1500: ('Non-3GPP-User-Data', AVPV_Grouped, 192), - 1501: ('Non-3GPP-IP-Access', AVP_10415_1501, 192), - 1502: ('Non-3GPP-IP-Access-APN', AVP_10415_1502, 192), - 1503: ('AN-Trusted', AVP_10415_1503, 192), - 1504: ('ANID', AVPV_StrLenField, 192), - 1505: ('Trace-Info', AVPV_Grouped, 128), - 1506: ('MIP-FA-RK', AVPV_OctetString, 192), - 1507: ('MIP-FA-RK-SPI', AVPV_Unsigned32, 192), - 1508: ('PPR-Flags', AVPV_Unsigned32, 128), - 1509: ('WLAN-Identifier', AVPV_Grouped, 128), - 1510: ('TWAN-Access-Info', AVPV_Grouped, 128), - 1511: ('Access-Authorization-Flags', AVPV_Unsigned32, 128), - 1512: ('TWAN-Default-APN-Context-Id', AVPV_Unsigned32, 128), - 1515: ('Trust-Relationship-Update', AVP_10415_1515, 128), - 1516: ('Full-Network-Name', AVPV_OctetString, 128), - 1517: ('Short-Network-Name', AVPV_OctetString, 128), - 1518: ('AAA-Failure-Indication', AVPV_Unsigned32, 128), - 1519: ('Transport-Access-Type', AVP_10415_1519, 128), - 1520: ('DER-Flags', AVPV_Unsigned32, 128), - 1521: ('DEA-Flags', AVPV_Unsigned32, 128), - 1522: ('RAR-Flags', AVPV_Unsigned32, 128), - 1523: ('DER-S6b-Flags', AVPV_Unsigned32, 128), - 1524: ('SSID', AVPV_StrLenField, 128), - 1525: ('HESSID', AVPV_StrLenField, 128), - 1526: ('Access-Network-Info', AVPV_Grouped, 128), - 1527: ('TWAN-Connection-Mode', AVPV_Unsigned32, 128), - 1528: ('TWAN-Connectivity-Parameters', AVPV_Grouped, 128), - 1529: ('Connectivity-Flags', AVPV_Unsigned32, 128), - 1530: ('TWAN-PCO', AVPV_OctetString, 128), - 1531: ('TWAG-CP-Address', AVPV_Address, 128), - 1532: ('TWAG-UP-Address', AVPV_StrLenField, 128), - 1533: ('TWAN-S2a-Failure-Cause', AVPV_Unsigned32, 128), - 1534: ('SM-Back-Off-Timer', AVPV_Unsigned32, 128), - 1535: ('WLCP-Key', AVPV_OctetString, 128), - 1600: ('Information', AVPV_Grouped, 128), - 1601: ('SGSN-Location-Information', AVPV_Grouped, 128), - 1602: ('E-UTRAN-Cell-Global-Identity', AVPV_OctetString, 128), - 1603: ('Tracking-Area-Identity', AVPV_OctetString, 128), - 1604: ('Cell-Global-Identity', AVPV_OctetString, 128), - 1605: ('Routing-Area-Identity', AVPV_OctetString, 128), - 1606: ('Location-Area-Identity', AVPV_OctetString, 128), - 1607: ('Service-Area-Identity', AVPV_OctetString, 128), - 1608: ('Geographical-Information', AVPV_OctetString, 128), - 1609: ('Geodetic-Information', AVPV_OctetString, 128), - 1610: ('Current-Location-Retrieved', AVP_10415_1610, 128), - 1611: ('Age-Of-Location-Information', AVPV_Unsigned32, 128), - 1612: ('Active-APN', AVPV_Grouped, 128), - 1613: ('SIPTO-Permission', AVP_10415_1613, 128), - 1614: ('Error-Diagnostic', AVP_10415_1614, 128), - 1615: ('UE-SRVCC-Capability', AVP_10415_1615, 128), - 1616: ('MPS-Priority', AVPV_Unsigned32, 128), - 1617: ('VPLMN-LIPA-Allowed', AVP_10415_1617, 128), - 1618: ('LIPA-Permission', AVP_10415_1618, 128), - 1619: ('Subscribed-Periodic-RAU-TAU-Timer', AVPV_Unsigned32, 128), - 1621: ('Ext-PDP-Address', AVPV_Address, 128), - 1622: ('MDT-Configuration', AVPV_Grouped, 128), - 1623: ('Job-Type', AVP_10415_1623, 128), - 1624: ('Area-Scope', AVPV_Grouped, 128), - 1625: ('List-Of-Measurements', AVPV_Unsigned32, 128), - 1626: ('Reporting-Trigger', AVPV_Unsigned32, 128), - 1627: ('Report-Interval', AVP_10415_1627, 128), - 1628: ('Report-Amount', AVP_10415_1628, 128), - 1629: ('Event-Threshold-RSRP', AVPV_Unsigned32, 128), - 1631: ('Logging-Interval', AVP_10415_1631, 128), - 1632: ('Logging-Duration', AVP_10415_1632, 128), - 1633: ('Relay-Node-Indicator', AVP_10415_1633, 128), - 1634: ('MDT-User-Consent', AVP_10415_1634, 128), - 1635: ('PUR-Flags', AVPV_Unsigned32, 128), - 1636: ('Subscribed-VSRVCC', AVP_10415_1636, 128), - 1638: ('CLR-Flags', AVPV_Unsigned32, 128), - 1639: ('UVR-Flags', AVPV_Unsigned32, 192), - 1640: ('UVA-Flags', AVPV_Unsigned32, 192), - 1641: ('VPLMN-CSG-Subscription-Data', AVPV_Grouped, 192), - 1642: ('Time-Zone', AVPV_StrLenField, 128), - 1643: ('A-MSISDN', AVP_10415_1643, 128), - 1645: ('MME-Number-for-MT-SMS', AVPV_OctetString, 128), - 1648: ('SMS-Register-Request', AVP_10415_1648, 128), - 1649: ('Local-Time-Zone', AVPV_Grouped, 128), - 1650: ('Daylight-Saving-Time', AVP_10415_1650, 128), - 1654: ('Subscription-Data-Flags', AVPV_Unsigned32, 128), - 1659: ('Positioning-Method', AVPV_OctetString, 128), - 1660: ('Measurement-Quantity', AVPV_OctetString, 128), - 1661: ('Event-Threshold-Event-1F', AVPV_Integer32, 128), - 1662: ('Event-Threshold-Event-1I', AVPV_Integer32, 128), - 1663: ('Restoration-Priority', AVPV_Unsigned32, 128), - 1664: ('SGs-MME-Identity', AVPV_StrLenField, 128), - 1665: ('SIPTO-Local-Network-Permission', AVPV_Unsigned32, 128), - 1666: ('Coupled-Node-Diameter-ID', AVPV_StrLenField, 128), - 1667: ('WLAN-offloadability', AVPV_Grouped, 128), - 1668: ('WLAN-offloadability-EUTRAN', AVPV_Unsigned32, 128), - 1669: ('WLAN-offloadability-UTRAN', AVPV_Unsigned32, 128), - 1670: ('Reset-ID', AVPV_OctetString, 128), - 1671: ('MDT-Allowed-PLMN-Id', AVPV_OctetString, 128), - 2000: ('SMS-Information', AVPV_Grouped, 192), - 2001: ('Data-Coding-Scheme', AVPV_Integer32, 192), - 2002: ('Destination-Interface', AVPV_Grouped, 192), - 2003: ('Interface-Id', AVPV_StrLenField, 192), - 2004: ('Interface-Port', AVPV_StrLenField, 192), - 2005: ('Interface-Text', AVPV_StrLenField, 192), - 2006: ('Interface-Type', AVP_10415_2006, 192), - 2007: ('SM-Message-Type', AVP_10415_2007, 192), - 2008: ('Originator-SCCP-Address', AVPV_Address, 192), - 2009: ('Originator-Interface', AVPV_Grouped, 192), - 2010: ('Recipient-SCCP-Address', AVPV_Address, 192), - 2011: ('Reply-Path-Requested', AVP_10415_2011, 192), - 2012: ('SM-Discharge-Time', AVPV_Time, 192), - 2013: ('SM-Protocol-ID', AVPV_OctetString, 192), - 2015: ('SM-User-Data-Header', AVPV_OctetString, 192), - 2016: ('SMS-Node', AVP_10415_2016, 192), - 2018: ('Client-Address', AVPV_Address, 192), - 2019: ('Number-Of-Messages-Sent', AVPV_Unsigned32, 192), - 2021: ('Remaining-Balance', AVPV_Grouped, 192), - 2022: ('Refund-Information', AVPV_OctetString, 192), - 2023: ('Carrier-Select-Routing-Information', AVPV_StrLenField, 192), - 2024: ('Number-Portability-Routing-Information', AVPV_StrLenField, 192), # noqa: E501 - 2025: ('PoC-Event-Type', AVP_10415_2025, 192), - 2026: ('Recipient-Info', AVPV_Grouped, 192), - 2027: ('Originator-Received-Address', AVPV_Grouped, 192), - 2028: ('Recipient-Received-Address', AVPV_Grouped, 192), - 2029: ('SM-Service-Type', AVP_10415_2029, 192), - 2030: ('MMTel-Information', AVPV_Grouped, 192), - 2031: ('MMTel-SService-Type', AVPV_Unsigned32, 192), - 2032: ('Service-Mode', AVPV_Unsigned32, 192), - 2033: ('Subscriber-Role', AVP_10415_2033, 192), - 2034: ('Number-Of-Diversions', AVPV_Unsigned32, 192), - 2035: ('Associated-Party-Address', AVPV_StrLenField, 192), - 2036: ('SDP-Type', AVP_10415_2036, 192), - 2037: ('Change-Condition', AVPV_Integer32, 192), - 2038: ('Change-Time', AVPV_Time, 192), - 2039: ('Diagnostics', AVPV_Integer32, 192), - 2040: ('Service-Data-Container', AVPV_Grouped, 192), - 2041: ('Start-Time', AVPV_Time, 192), - 2042: ('Stop-Time', AVPV_Time, 192), - 2043: ('Time-First-Usage', AVPV_Time, 192), - 2044: ('Time-Last-Usage', AVPV_Time, 192), - 2045: ('Time-Usage', AVPV_Unsigned32, 192), - 2046: ('Traffic-Data-Volumes', AVPV_Grouped, 192), - 2047: ('Serving-Node-Type', AVP_10415_2047, 192), - 2048: ('Supplementary-Service', AVPV_Grouped, 192), - 2049: ('Participant-Action-Type', AVP_10415_2049, 192), - 2050: ('PDN-Connection-Charging-ID', AVPV_Unsigned32, 192), - 2051: ('Dynamic-Address-Flag', AVP_10415_2051, 192), - 2052: ('Accumulated-Cost', AVPV_Grouped, 192), - 2053: ('AoC-Cost-Information', AVPV_Grouped, 192), - 2056: ('Current-Tariff', AVPV_Grouped, 192), - 2058: ('Rate-Element', AVPV_Grouped, 192), - 2059: ('Scale-Factor', AVPV_Grouped, 192), - 2060: ('Tariff-Information', AVPV_Grouped, 192), - 2061: ('Unit-Cost', AVPV_Grouped, 192), - 2062: ('Incremental-Cost', AVPV_Grouped, 192), - 2063: ('Local-Sequence-Number', AVPV_Unsigned32, 192), - 2064: ('Node-Id', AVPV_StrLenField, 192), - 2065: ('SGW-Change', AVP_10415_2065, 192), - 2066: ('Charging-Characteristics-Selection-Mode', AVP_10415_2066, 192), - 2067: ('SGW-Address', AVPV_Address, 192), - 2068: ('Dynamic-Address-Flag-Extension', AVP_10415_2068, 192), - 2118: ('Charge-Reason-Code', AVP_10415_2118, 192), - 2200: ('Subsession-Decision-Info', AVPV_Grouped, 192), - 2201: ('Subsession-Enforcement-Info', AVPV_Grouped, 192), - 2202: ('Subsession-Id', AVPV_Unsigned32, 192), - 2203: ('Subsession-Operation', AVP_10415_2203, 192), - 2204: ('Multiple-BBERF-Action', AVP_10415_2204, 192), - 2206: ('DRA-Deployment', AVP_10415_2206, 128), - 2208: ('DRA-Binding', AVP_10415_2208, 128), - 2301: ('SIP-Request-Timestamp-Fraction', AVPV_Unsigned32, 192), - 2302: ('SIP-Response-Timestamp-Fraction', AVPV_Unsigned32, 192), - 2303: ('Online-Charging-Flag', AVP_10415_2303, 192), - 2304: ('CUG-Information', AVPV_OctetString, 192), - 2305: ('Real-Time-Tariff-Information', AVPV_Grouped, 192), - 2306: ('Tariff-XML', AVPV_StrLenField, 192), - 2307: ('MBMS-GW-Address', AVPV_Address, 192), - 2308: ('IMSI-Unauthenticated-Flag', AVP_10415_2308, 192), - 2309: ('Account-Expiration', AVPV_Time, 192), - 2310: ('AoC-Format', AVP_10415_2310, 192), - 2311: ('AoC-Service', AVPV_Grouped, 192), - 2312: ('AoC-Service-Obligatory-Type', AVP_10415_2312, 192), - 2313: ('AoC-Service-Type', AVP_10415_2313, 192), - 2314: ('AoC-Subscription-Information', AVPV_Grouped, 192), - 2315: ('Preferred-AoC-Currency', AVPV_Unsigned32, 192), - 2317: ('CSG-Access-Mode', AVP_10415_2317, 192), - 2318: ('CSG-Membership-Indication', AVP_10415_2318, 192), - 2319: ('User-CSG-Information', AVPV_Grouped, 192), - 2320: ('Outgoing-Session-Id', AVPV_StrLenField, 192), - 2321: ('Initial-IMS-Charging-Identifier', AVPV_StrLenField, 192), - 2322: ('IMS-Emergency-Indicator', AVP_10415_2322, 192), - 2323: ('MBMS-Charged-Party', AVP_10415_2323, 192), - 2400: ('LMSI', AVPV_OctetString, 192), - 2401: ('Serving-Node', AVPV_Grouped, 192), - 2402: ('MME-Name', AVPV_StrLenField, 192), - 2403: ('MSC-Number', AVPV_OctetString, 192), - 2404: ('LCS-Capabilities-Sets', AVPV_Unsigned32, 192), - 2405: ('GMLC-Address', AVPV_Address, 192), - 2406: ('Additional-Serving-Node', AVPV_Grouped, 192), - 2407: ('PPR-Address', AVPV_Address, 192), - 2408: ('MME-Realm', AVPV_StrLenField, 128), - 2409: ('SGSN-Name', AVPV_StrLenField, 128), - 2410: ('SGSN-Realm', AVPV_StrLenField, 128), - 2411: ('RIA-Flags', AVPV_Unsigned32, 128), - 2500: ('SLg-Location-Type', AVP_10415_2500, 192), - 2501: ('LCS-EPS-Client-Name', AVPV_Grouped, 192), - 2502: ('LCS-Requestor-Name', AVPV_Grouped, 192), - 2503: ('LCS-Priority', AVPV_Unsigned32, 192), - 2504: ('LCS-QoS', AVPV_Grouped, 192), - 2505: ('Horizontal-Accuracy', AVPV_Unsigned32, 192), - 2506: ('Vertical-Accuracy', AVPV_Unsigned32, 192), - 2507: ('Vertical-Requested', AVP_10415_2507, 192), - 2508: ('Velocity-Requested', AVP_10415_2508, 192), - 2509: ('Response-Time', AVP_10415_2509, 192), - 2510: ('Supported-GAD-Shapes', AVPV_Unsigned32, 192), - 2511: ('LCS-Codeword', AVPV_StrLenField, 192), - 2512: ('LCS-Privacy-Check', AVP_10415_2512, 192), - 2513: ('Accuracy-Fulfilment-Indicator', AVP_10415_2513, 192), - 2514: ('Age-Of-Location-Estimate', AVPV_Unsigned32, 192), - 2515: ('Velocity-Estimate', AVPV_OctetString, 192), - 2516: ('EUTRAN-Positioning-Data', AVPV_OctetString, 192), - 2517: ('ECGI', AVPV_OctetString, 192), - 2518: ('Location-Event', AVP_10415_2518, 192), - 2519: ('Pseudonym-Indicator', AVP_10415_2519, 192), - 2520: ('LCS-Service-Type-ID', AVPV_Unsigned32, 192), - 2523: ('LCS-QoS-Class', AVP_10415_2523, 192), - 2524: ('GERAN-Positioning-Info', AVPV_Grouped, 128), - 2525: ('GERAN-Positioning-Data', AVPV_OctetString, 128), - 2526: ('GERAN-GANSS-Positioning-Data', AVPV_OctetString, 128), - 2527: ('UTRAN-Positioning-Info', AVPV_Grouped, 128), - 2528: ('UTRAN-Positioning-Data', AVPV_OctetString, 128), - 2529: ('UTRAN-GANSS-Positioning-Data', AVPV_OctetString, 128), - 2530: ('LRR-Flags', AVPV_Unsigned32, 128), - 2531: ('LCS-Reference-Number', AVPV_OctetString, 128), - 2532: ('Deferred-Location-Type', AVPV_Unsigned32, 128), - 2533: ('Area-Event-Info', AVPV_Grouped, 128), - 2534: ('Area-Definition', AVPV_Grouped, 128), - 2535: ('Area', AVPV_Grouped, 128), - 2536: ('Area-Type', AVPV_Unsigned32, 128), - 2537: ('Area-Identification', AVPV_Grouped, 128), - 2538: ('Occurrence-Info', AVP_10415_2538, 128), - 2539: ('Interval-Time', AVPV_Unsigned32, 128), - 2540: ('Periodic-LDR-Information', AVPV_Grouped, 128), - 2541: ('Reporting-Amount', AVPV_Unsigned32, 128), - 2542: ('Reporting-Interval', AVPV_Unsigned32, 128), - 2543: ('Reporting-PLMN-List', AVPV_Grouped, 128), - 2544: ('PLMN-ID-List', AVPV_Grouped, 128), - 2545: ('PLR-Flags', AVPV_Unsigned32, 128), - 2546: ('PLA-Flags', AVPV_Unsigned32, 128), - 2547: ('Deferred-MT-LR-Data', AVPV_Grouped, 128), - 2548: ('Termination-Cause', AVPV_Unsigned32, 128), - 2549: ('LRA-Flags', AVPV_Unsigned32, 128), - 2550: ('Periodic-Location-Support-Indicator', AVP_10415_2550, 128), - 2551: ('Prioritized-List-Indicator', AVP_10415_2551, 128), - 2552: ('ESMLC-Cell-Info', AVPV_Grouped, 128), - 2553: ('Cell-Portion-ID', AVPV_Unsigned32, 128), - 2554: ('1xRTT-RCID', AVPV_OctetString, 128), - 2601: ('IMS-Application-Reference-Identifier', AVPV_StrLenField, 192), - 2602: ('Low-Priority-Indicator', AVP_10415_2602, 192), - 2604: ('Local-GW-Inserted-Indication', AVP_10415_2604, 192), - 2605: ('Transcoder-Inserted-Indication', AVP_10415_2605, 192), - 2606: ('PDP-Address-Prefix-Length', AVPV_Unsigned32, 192), - 2701: ('Transit-IOI-List', AVPV_StrLenField, 192), - 2702: ('AS-Code', AVP_10415_2702, 192), - 2704: ('NNI-Type', AVP_10415_2704, 192), - 2705: ('Neighbour-Node-Address', AVPV_Address, 192), - 2706: ('Relationship-Mode', AVP_10415_2706, 192), - 2707: ('Session-Direction', AVP_10415_2707, 192), - 2708: ('From-Address', AVPV_StrLenField, 192), - 2709: ('Access-Transfer-Information', AVPV_Grouped, 192), - 2710: ('Access-Transfer-Type', AVP_10415_2710, 192), - 2711: ('Related-IMS-Charging-Identifier', AVPV_StrLenField, 192), - 2712: ('Related-IMS-Charging-Identifier-Node', AVPV_Address, 192), - 2713: ('IMS-Visited-Network-Identifier', AVPV_StrLenField, 192), - 2714: ('TWAN-User-Location-Info', AVPV_Grouped, 192), - 2716: ('BSSID', AVPV_StrLenField, 192), - 2717: ('TAD-Identifier', AVP_10415_2717, 192), - 2802: ('TDF-Application-Instance-Identifier', AVPV_OctetString, 128), - 2804: ('HeNB-Local-IP-Address', AVPV_Address, 128), - 2805: ('UE-Local-IP-Address', AVPV_Address, 128), - 2806: ('UDP-Source-Port', AVPV_Unsigned32, 128), - 2809: ('Mute-Notification', AVP_10415_2809, 128), - 2810: ('Monitoring-Time', AVPV_Time, 128), - 2811: ('AN-GW-Status', AVP_10415_2811, 128), - 2812: ('User-Location-Info-Time', AVPV_Time, 128), - 2816: ('Default-QoS-Information', AVPV_Grouped, 128), - 2817: ('Default-QoS-Name', AVPV_StrLenField, 128), - 2818: ('Conditional-APN-Aggregate-Max-Bitrate', AVPV_Grouped, 128), - 2819: ('RAN-NAS-Release-Cause', AVPV_OctetString, 128), - 2820: ('Presence-Reporting-Area-Elements-List', AVPV_OctetString, 128), - 2821: ('Presence-Reporting-Area-Identifier', AVPV_OctetString, 128), - 2822: ('Presence-Reporting-Area-Information', AVPV_Grouped, 128), - 2823: ('Presence-Reporting-Area-Status', AVPV_Unsigned32, 128), - 2824: ('NetLoc-Access-Support', AVPV_Unsigned32, 128), - 2825: ('Fixed-User-Location-Info', AVPV_Grouped, 128), - 2826: ('PCSCF-Restoration-Indication', AVPV_Unsigned32, 128), - 2827: ('IP-CAN-Session-Charging-Scope', AVPV_Unsigned32, 128), - 2828: ('Monitoring-Flags', AVPV_Unsigned32, 128), - 2901: ('Policy-Counter-Identifier', AVPV_StrLenField, 192), - 2902: ('Policy-Counter-Status', AVPV_StrLenField, 192), - 2903: ('Policy-Counter-Status-Report', AVPV_Grouped, 192), - 2904: ('SL-Request-Type', AVP_10415_2904, 192), - 2905: ('Pending-Policy-Counter-Information', AVPV_Grouped, 192), - 2906: ('Pending-Policy-Counter-Change-Time', AVPV_Time, 192), - 3401: ('Reason-Header', AVPV_StrLenField, 192), - 3402: ('Instance-Id', AVPV_StrLenField, 192), - 3403: ('Route-Header-Received', AVPV_StrLenField, 192), - 3404: ('Route-Header-Transmitted', AVPV_StrLenField, 192), - 3405: ('SM-Device-Trigger-Information', AVPV_Grouped, 192), - 3406: ('MTC-IWF-Address', AVPV_Address, 192), - 3407: ('SM-Device-Trigger-Indicator', AVP_10415_3407, 192), - 3408: ('SM-Sequence-Number', AVPV_Unsigned32, 192), - 3409: ('SMS-Result', AVPV_Unsigned32, 192), - 3410: ('VCS-Information', AVPV_Grouped, 192), - 3411: ('Basic-Service-Code', AVPV_Grouped, 192), - 3412: ('Bearer-Capability', AVPV_OctetString, 192), - 3413: ('Teleservice', AVPV_OctetString, 192), - 3414: ('ISUP-Location-Number', AVPV_OctetString, 192), - 3415: ('Forwarding-Pending', AVP_10415_3415, 192), - 3416: ('ISUP-Cause', AVPV_Grouped, 192), - 3417: ('MSC-Address', AVPV_OctetString, 192), - 3418: ('Network-Call-Reference-Number', AVPV_OctetString, 192), - 3419: ('Start-of-Charging', AVPV_Time, 192), - 3420: ('VLR-Number', AVPV_OctetString, 192), - 3421: ('CN-Operator-Selection-Entity', AVP_10415_3421, 192), - 3422: ('ISUP-Cause-Diagnostics', AVPV_OctetString, 192), - 3423: ('ISUP-Cause-Location', AVPV_Unsigned32, 192), - 3424: ('ISUP-Cause-Value', AVPV_Unsigned32, 192), - 3425: ('ePDG-Address', AVPV_Address, 192), - 3428: ('Coverage-Status', AVP_10415_3428, 192), - 3429: ('Layer-2-Group-ID', AVPV_StrLenField, 192), - 3430: ('Monitored-PLMN-Identifier', AVPV_StrLenField, 192), - 3431: ('Monitoring-UE-HPLMN-Identifier', AVPV_StrLenField, 192), - 3432: ('Monitoring-UE-Identifier', AVPV_StrLenField, 192), - 3433: ('Monitoring-UE-VPLMN-Identifier', AVPV_StrLenField, 192), - 3434: ('PC3-Control-Protocol-Cause', AVPV_Integer32, 192), - 3435: ('PC3-EPC-Control-Protocol-Cause', AVPV_Integer32, 192), - 3436: ('Requested-PLMN-Identifier', AVPV_StrLenField, 192), - 3437: ('Requestor-PLMN-Identifier', AVPV_StrLenField, 192), - 3438: ('Role-Of-ProSe-Function', AVP_10415_3438, 192), - 3439: ('Usage-Information-Report-Sequence-Number', AVPV_Integer32, 192), # noqa: E501 - 3440: ('ProSe-3rd-Party-Application-ID', AVPV_StrLenField, 192), - 3441: ('ProSe-Direct-Communication-Data-Container', AVPV_Grouped, 192), - 3442: ('ProSe-Direct-Discovery-Model', AVP_10415_3442, 192), - 3443: ('ProSe-Event-Type', AVP_10415_3443, 192), - 3444: ('ProSe-Function-IP-Address', AVPV_Address, 192), - 3445: ('ProSe-Functionality', AVP_10415_3445, 192), - 3446: ('ProSe-Group-IP-Multicast-Address', AVPV_Address, 192), - 3447: ('ProSe-Information', AVPV_Grouped, 192), - 3448: ('ProSe-Range-Class', AVP_10415_3448, 192), - 3449: ('ProSe-Reason-For-Cancellation', AVP_10415_3449, 192), - 3450: ('ProSe-Request-Timestamp', AVPV_Time, 192), - 3451: ('ProSe-Role-Of-UE', AVP_10415_3451, 192), - 3452: ('ProSe-Source-IP-Address', AVPV_Address, 192), - 3453: ('ProSe-UE-ID', AVPV_StrLenField, 192), - 3454: ('Proximity-Alert-Indication', AVP_10415_3454, 192), - 3455: ('Proximity-Alert-Timestamp', AVPV_Time, 192), - 3456: ('Proximity-Cancellation-Timestamp', AVPV_Time, 192), - 3457: ('ProSe-Function-PLMN-Identifier', AVPV_StrLenField, 192), - }, -} - - -##################################################################### -##################################################################### -# -# Diameter commands classes and definitions -# -##################################################################### -##################################################################### - -# Version + message length + flags + code + Application-ID + Hop-by-Hop ID -# + End-to-End ID -DR_Header_Length = 20 -DR_Flags_List = ["x", "x", "x", "x", "T", "E", "P", "R"] - -# The Diameter commands definition fields meaning: -# 2nd: the 2 letters prefix for both requests and answers -# 3rd: dictionary of Request/Answer command flags for each supported application ID. Each dictionary key is one of the # noqa: E501 -# supported application ID and each value is a tuple defining the request -# flag and then the answer flag -DR_cmd_def = { - 257: ('Capabilities-Exchange', 'CE', {0: (128, 0)}), - 258: ('Re-Auth', 'RA', {0: (192, 64), 1: (192, 64), 16777250: (192, 64), 16777272: (192, 64), 16777264: (192, 64)}), # noqa: E501 - 260: ('AA-Mobile-Node', 'AM', {2: (192, 64)}), - 262: ('Home-Agent-MIP', 'HA', {2: (192, 64)}), - 265: ('AA', 'AA', {16777272: (192, 64), 1: (192, 64), 16777250: (192, 64), 16777264: (192, 64)}), # noqa: E501 - 268: ('Diameter-EAP', 'DE', {16777272: (192, 64), 16777264: (192, 64), 16777250: (192, 64), 5: (192, 64), 7: (192, 64)}), # noqa: E501 - 271: ('Accounting', 'AC', {0: (192, 64), 1: (192, 64)}), - 272: ('Credit-Control', 'CC', {4: (192, 64)}), - 274: ('Abort-Session', 'AS', {0: (192, 64), 1: (192, 64), 16777250: (192, 64), 16777272: (192, 64), 16777264: (192, 64)}), # noqa: E501 - 275: ('Session-Termination', 'ST', {0: (192, 64), 1: (192, 64), 16777250: (192, 64), 16777264: (192, 64), 16777272: (192, 64)}), # noqa: E501 - 280: ('Device-Watchdog', 'DW', {0: (128, 0)}), - 282: ('Disconnect-Peer', 'DP', {0: (128, 0)}), - 283: ('User-Authorization', 'UA', {6: (192, 64)}), - 284: ('Server-Assignment', 'SA', {6: (192, 64)}), - 285: ('Location-Info', 'LI', {6: (192, 64)}), - 286: ('Multimedia-Auth', 'MA', {6: (192, 64)}), - 287: ('Registration-Termination', 'RT', {6: (192, 64)}), - 288: ('Push-Profile', 'PP', {6: (192, 64)}), - 300: ('User-Authorization', 'UA', {16777216: (192, 64)}), - 301: ('Server-Assignment', 'SA', {16777216: (192, 64), 16777265: (192, 64)}), # noqa: E501 - 302: ('Location-Info', 'LI', {16777216: (192, 64)}), - 303: ('Multimedia-Auth', 'MA', {16777216: (192, 64), 16777265: (192, 64)}), - 304: ('Registration-Termination', 'RT', {16777216: (192, 64), 16777265: (192, 64)}), # noqa: E501 - 305: ('Push-Profile', 'PP', {16777216: (192, 64), 16777265: (128, 64)}), - 306: ('User-Data', 'UD', {16777217: (192, 64)}), - 307: ('Profile-Update', 'PU', {16777217: (192, 64)}), - 308: ('Subscribe-Notifications', 'SN', {16777217: (192, 64)}), - 309: ('Push-Notification', 'PN', {16777217: (192, 64)}), - 316: ('Update-Location', 'UL', {16777251: (192, 64)}), - 317: ('Cancel-Location', 'CL', {16777251: (192, 64)}), - 318: ('Authentication-Information', 'AI', {16777251: (192, 64)}), - 319: ('Insert-Subscriber-Data', 'ID', {16777251: (192, 64)}), - 320: ('Delete-Subscriber-Data', 'DS', {16777251: (192, 64)}), - 321: ('Purge-UE', 'PU', {16777251: (192, 64)}), - 322: ('Reset', 'RS', {16777251: (192, 64)}), - 323: ('Notify', 'NO', {16777251: (192, 64)}), - 324: ('ME-Identity-Check', 'EC', {16777252: (192, 64)}), - 325: ('MIP6', 'MI', {8: (192, 64)}), - 8388620: ('Provide-Location', 'PL', {16777255: (192, 64)}), - 8388621: ('Location-Report', 'LR', {16777255: (192, 64)}), - 8388622: ('LCS-Routing-Info', 'RI', {16777291: (192, 64)}), - 8388635: ('Spending-Limit', 'SL', {16777255: (192, 64)}), - 8388636: ('Spending-Status-Notification', 'SN', {16777255: (192, 64)}), - 8388638: ('Update-VCSG-Location', 'UV', {16777308: (192, 64)}), - 8388642: ('Cancel-VCSG-Location', 'CV', {16777308: (192, 64)}), -} - -# Generic class + commands builder -####################################### - - -class DiamG (Packet): - """ Generic class defining all the Diameter fields""" - name = "Diameter" - fields_desc = [ - # Protocol version field, 1 byte, default value = 1 - XByteField("version", 1), - I3FieldLenField( - "drLen", - None, - length_of="avpList", - adjust=lambda p, - x:x + - DR_Header_Length), - DRFlags("drFlags", None, 8, DR_Flags_List), - # Command Code, 3 bytes, no default - DRCode("drCode", None, DR_cmd_def), - # Application ID, 4 bytes, no default - IntEnumField("drAppId", None, AppIDsEnum), - # Hop-by-Hop Identifier, 4 bytes - XIntField("drHbHId", 0), - # End-to-end Identifier, 4 bytes - XIntField("drEtEId", 0), - PacketListField( - "avpList", - [], - GuessAvpType, - length_from=lambda pkt:pkt.drLen - - DR_Header_Length), - ] - - -def getCmdParams(cmd, request, **fields): - """Update or fill the fields parameters depending on command code. Both cmd and drAppId can be provided # noqa: E501 - in string or int format.""" - drCode = None - params = None - drAppId = None - # Fetch the parameters if cmd is found in dict - if isinstance(cmd, int): - drCode = cmd # Enable to craft commands with non standard code - if cmd in DR_cmd_def: - params = DR_cmd_def[drCode] - else: - params = ('Unknown', 'UK', {0: (128, 0)}) - warning( - 'No Diameter command with code %d found in DR_cmd_def dictionary' % # noqa: E501 - cmd) - else: # Assume command is a string - if len(cmd) > 3: # Assume full command name given - fpos = 0 - else: # Assume abbreviated name is given and take only the first two letters # noqa: E501 - cmd = cmd[:2] - fpos = 1 - for k, f in DR_cmd_def.items(): - if f[fpos][:len( - cmd)] == cmd: # Accept only a prefix of the full name - drCode = k - params = f - break - if not drCode: - warning( - 'Diameter command with name %s not found in DR_cmd_def dictionary.' % # noqa: E501 - cmd) - return (fields, 'Unknown') - # The drCode is set/overridden in any case - fields['drCode'] = drCode - # Processing of drAppId - if 'drAppId' in fields: - val = fields['drAppId'] - if isinstance(val, str): # Translate into application Id code - found = False - for k, v in six.iteritems(AppIDsEnum): - if v.find(val) != -1: - drAppId = k - fields['drAppId'] = drAppId - found = True - break - if not found: - del(fields['drAppId']) - warning( - 'Application ID with name %s not found in AppIDsEnum dictionary.' % # noqa: E501 - val) - return (fields, 'Unknown') - else: # Assume type is int - drAppId = val - else: # Application Id shall be taken from the params found based on cmd - drAppId = next(iter(params[2])) # The first record is taken - fields['drAppId'] = drAppId - # Set the command name - name = request and params[0] + '-Request' or params[0] + '-Answer' - # Processing of flags (only if not provided manually) - if 'drFlags' not in fields: - if drAppId in params[2]: - flags = params[2][drAppId] - fields['drFlags'] = request and flags[0] or flags[1] - return (fields, name) - - -def DiamReq(cmd, **fields): - """Craft Diameter request commands""" - upfields, name = getCmdParams(cmd, True, **fields) - p = DiamG(**upfields) - p.name = name - return p - - -def DiamAns(cmd, **fields): - """Craft Diameter answer commands""" - upfields, name = getCmdParams(cmd, False, **fields) - p = DiamG(**upfields) - p.name = name - return p - -# Binding -####################################### - - -bind_layers(TCP, DiamG, dport=3868) -bind_layers(TCP, DiamG, sport=3868) -bind_layers(SCTPChunkData, DiamG, dport=3868) -bind_layers(SCTPChunkData, DiamG, sport=3868) -bind_layers(SCTPChunkData, DiamG, proto_id=46) -bind_layers(SCTPChunkData, DiamG, proto_id=47) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/dtp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/dtp.py deleted file mode 100644 index 67d101cd06..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/dtp.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env python - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = Dynamic Trunking Protocol (DTP) -# scapy.contrib.status = loads - -""" - DTP Scapy Extension - ~~~~~~~~~~~~~~~~~~~ - - :version: 2008-12-22 - :author: Jochen Bartl - - :Thanks: - - - TLV code derived from the CDP implementation of scapy. (Thanks to Nicolas Bareil and Arnaud Ebalard) # noqa: E501 -""" - -from __future__ import absolute_import -from __future__ import print_function -import struct - -from scapy.packet import Packet, bind_layers -from scapy.fields import ByteField, FieldLenField, MACField, PacketListField, \ - ShortField, StrLenField, XShortField -from scapy.layers.l2 import SNAP, Dot3, LLC -from scapy.sendrecv import sendp -from scapy.config import conf -from scapy.volatile import RandMAC - - -class DtpGenericTlv(Packet): - name = "DTP Generic TLV" - fields_desc = [XShortField("type", 0x0001), - FieldLenField("length", None, length_of=lambda pkt:pkt.value + 4), # noqa: E501 - StrLenField("value", "", length_from=lambda pkt:pkt.length - 4) # noqa: E501 - ] - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 2: - t = struct.unpack("!H", _pkt[:2])[0] - cls = _DTP_TLV_CLS.get(t, "DtpGenericTlv") - return cls - - def guess_payload_class(self, p): - return conf.padding_layer - - -class DTPDomain(DtpGenericTlv): - name = "DTP Domain" - fields_desc = [ShortField("type", 1), - FieldLenField("length", None, "domain", adjust=lambda pkt, x:x + 4), # noqa: E501 - StrLenField("domain", b"\x00", length_from=lambda pkt:pkt.length - 4) # noqa: E501 - ] - - -class DTPStatus(DtpGenericTlv): - name = "DTP Status" - fields_desc = [ShortField("type", 2), - FieldLenField("length", None, "status", adjust=lambda pkt, x:x + 4), # noqa: E501 - StrLenField("status", b"\x03", length_from=lambda pkt:pkt.length - 4) # noqa: E501 - ] - - -class DTPType(DtpGenericTlv): - name = "DTP Type" - fields_desc = [ShortField("type", 3), - FieldLenField("length", None, "dtptype", adjust=lambda pkt, x:x + 4), # noqa: E501 - StrLenField("dtptype", b"\xa5", length_from=lambda pkt:pkt.length - 4) # noqa: E501 - ] - - -class DTPNeighbor(DtpGenericTlv): - name = "DTP Neighbor" - fields_desc = [ShortField("type", 4), - # FieldLenField("length", None, "neighbor", adjust=lambda pkt,x:x + 4), # noqa: E501 - ShortField("len", 10), - MACField("neighbor", None) - ] - - -_DTP_TLV_CLS = { - 0x0001: DTPDomain, - 0x0002: DTPStatus, - 0x0003: DTPType, - 0x0004: DTPNeighbor -} - - -class DTP(Packet): - name = "DTP" - fields_desc = [ByteField("ver", 1), - PacketListField("tlvlist", [], DtpGenericTlv)] - - -bind_layers(SNAP, DTP, code=0x2004, OUI=0xc) - - -def negotiate_trunk(iface=conf.iface, mymac=str(RandMAC())): - print("Trying to negotiate a trunk on interface %s" % iface) - p = Dot3(src=mymac, dst="01:00:0c:cc:cc:cc") / LLC() - p /= SNAP() - p /= DTP(tlvlist=[DTPDomain(), DTPStatus(), DTPType(), DTPNeighbor(neighbor=mymac)]) # noqa: E501 - sendp(p) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/eddystone.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/eddystone.py deleted file mode 100644 index 62406697e2..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/eddystone.py +++ /dev/null @@ -1,245 +0,0 @@ -# -*- mode: python3; indent-tabs-mode: nil; tab-width: 4 -*- -# eddystone.py - protocol handlers for Eddystone beacons -# -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Michael Farrell -# This program is published under a GPLv2 (or later) license -# -# scapy.contrib.description = Eddystone BLE proximity beacon -# scapy.contrib.status = loads -""" -scapy.contrib.eddystone - Google Eddystone Bluetooth LE proximity beacons. - -The Eddystone specification can be found at: -https://github.com/google/eddystone/blob/master/protocol-specification.md - -These beacons are used as building blocks for other systems: - -* Google's Physical Web -* RuuviTag -* Waze Beacons - -""" - -from scapy.compat import orb -from scapy.fields import IntField, SignedByteField, StrField, BitField, \ - StrFixedLenField, ShortField, FixedPointField, ByteEnumField -from scapy.layers.bluetooth import EIR_Hdr, EIR_ServiceData16BitUUID, \ - EIR_CompleteList16BitServiceUUIDs, LowEnergyBeaconHelper -from scapy.modules import six -from scapy.packet import bind_layers, Packet - -EDDYSTONE_UUID = 0xfeaa - -EDDYSTONE_URL_SCHEMES = { - 0: b"http://www.", - 1: b"https://www.", - 2: b"http://", - 3: b"https://", -} - -EDDYSTONE_URL_TABLE = { - 0: b".com/", - 1: b".org/", - 2: b".edu/", - 3: b".net/", - 4: b".info/", - 5: b".biz/", - 6: b".gov/", - 7: b".com", - 8: b".org", - 9: b".edu", - 10: b".net", - 11: b".info", - 12: b".biz", - 13: b".gov", -} - - -class EddystoneURLField(StrField): - # https://github.com/google/eddystone/tree/master/eddystone-url#eddystone-url-http-url-encoding - def i2m(self, pkt, x): - if x is None: - return b"" - - o = bytearray() - p = 0 - while p < len(x): - c = orb(x[p]) - if c == 46: # "." - for k, v in EDDYSTONE_URL_TABLE.items(): - if x.startswith(v, p): - o.append(k) - p += len(v) - 1 - break - else: - o.append(c) - else: - o.append(c) - p += 1 - - # Make the output immutable. - return bytes(o) - - def m2i(self, pkt, x): - if not x: - return None - - o = bytearray() - for c in x: - i = orb(c) - r = EDDYSTONE_URL_TABLE.get(i) - if r is None: - o.append(i) - else: - o.extend(r) - return bytes(o) - - def any2i(self, pkt, x): - if isinstance(x, six.text_type): - x = x.encode("ascii") - return x - - -class Eddystone_Frame(Packet, LowEnergyBeaconHelper): - """ - The base Eddystone frame on which all Eddystone messages are built. - - https://github.com/google/eddystone/blob/master/protocol-specification.md - """ - name = "Eddystone Frame" - fields_desc = [ - BitField("type", None, 4), - BitField("reserved", 0, 4), - ] - - def build_eir(self): - """Builds a list of EIR messages to wrap this frame.""" - - return LowEnergyBeaconHelper.base_eir + [ - EIR_Hdr() / EIR_CompleteList16BitServiceUUIDs(svc_uuids=[ - EDDYSTONE_UUID]), - EIR_Hdr() / EIR_ServiceData16BitUUID() / self - ] - - -class Eddystone_UID(Packet): - """ - An Eddystone type for transmitting a unique identifier. - - https://github.com/google/eddystone/tree/master/eddystone-uid - """ - name = "Eddystone UID" - fields_desc = [ - SignedByteField("tx_power", 0), - StrFixedLenField("namespace", None, 10), - StrFixedLenField("instance", None, 6), - StrFixedLenField("reserved", None, 2), - ] - - -class Eddystone_URL(Packet): - """ - An Eddystone type for transmitting a URL (to a web page). - - https://github.com/google/eddystone/tree/master/eddystone-url - """ - name = "Eddystone URL" - fields_desc = [ - SignedByteField("tx_power", 0), - ByteEnumField("url_scheme", 0, EDDYSTONE_URL_SCHEMES), - EddystoneURLField("url", None), - ] - - def to_url(self): - return EDDYSTONE_URL_SCHEMES[self.url_scheme] + self.url - - @staticmethod - def from_url(url): - """Creates an Eddystone_Frame with a Eddystone_URL for a given URL.""" - url = url.encode('ascii') - scheme = None - for k, v in EDDYSTONE_URL_SCHEMES.items(): - if url.startswith(v): - scheme = k - url = url[len(v):] - break - else: - raise Exception("URLs must start with EDDYSTONE_URL_SCHEMES") - - return Eddystone_Frame() / Eddystone_URL( - url_scheme=scheme, - url=url) - - -class Eddystone_TLM(Packet): - """ - An Eddystone type for transmitting beacon telemetry information. - - https://github.com/google/eddystone/tree/master/eddystone-tlm - """ - name = "Eddystone TLM" - fields_desc = [ - ByteEnumField("version", None, { - 0: "unencrypted", - 1: "encrypted", - }), - ] - - -class Eddystone_TLM_Unencrypted(Packet): - """ - A subtype of Eddystone-TLM for transmitting telemetry in unencrypted form. - - https://github.com/google/eddystone/blob/master/eddystone-tlm/tlm-plain.md - """ - name = "Eddystone TLM (Unencrypted)" - fields_desc = [ - ShortField("batt_mv", 0), - FixedPointField("temperature", -128, 16, 8), - IntField("adv_cnt", None), - IntField("sec_cnt", None), - ] - - -class Eddystone_TLM_Encrypted(Packet): - """ - A subtype of Eddystone-TLM for transmitting telemetry in encrypted form. - - This implementation does not support decrypting this data. - - https://github.com/google/eddystone/blob/master/eddystone-tlm/tlm-encrypted.md - """ - name = "Eddystone TLM (Encrypted)" - fields_desc = [ - StrFixedLenField("etlm", None, 12), - StrFixedLenField("salt", None, 2), - StrFixedLenField("mic", None, 2), - ] - - -class Eddystone_EID(Packet): - """ - An Eddystone type for transmitting encrypted, ephemeral identifiers. - - This implementation does not support decrypting this data. - - https://github.com/google/eddystone/tree/master/eddystone-eid - """ - name = "Eddystone EID" - fields_desc = [ - SignedByteField("tx_power", 0), - StrFixedLenField("eid", None, 8), - ] - - -bind_layers(Eddystone_TLM, Eddystone_TLM_Unencrypted, version=0) -bind_layers(Eddystone_TLM, Eddystone_TLM_Encrypted, version=1) - -bind_layers(Eddystone_Frame, Eddystone_UID, type=0) -bind_layers(Eddystone_Frame, Eddystone_URL, type=1) -bind_layers(Eddystone_Frame, Eddystone_TLM, type=2) -bind_layers(Eddystone_Frame, Eddystone_EID, type=3) - -bind_layers(EIR_ServiceData16BitUUID, Eddystone_Frame, svc_uuid=EDDYSTONE_UUID) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/eigrp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/eigrp.py deleted file mode 100644 index 74559f4531..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/eigrp.py +++ /dev/null @@ -1,531 +0,0 @@ -#!/usr/bin/env python - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# flake8: noqa: E501 - -# scapy.contrib.description = Enhanced Interior Gateway Routing Protocol (EIGRP) -# scapy.contrib.status = loads - -""" - EIGRP Scapy Extension - ~~~~~~~~~~~~~~~~~~~~~ - - :version: 2009-08-13 - :copyright: 2009 by Jochen Bartl - :e-mail: lobo@c3a.de / jochen.bartl@gmail.com - :license: GPL v2 - - :TODO - - - Replace TLV code with a more generic solution - * http://trac.secdev.org/scapy/ticket/90 - - Write function for calculating authentication data - - :Known bugs: - - - - - :Thanks: - - - TLV code derived from the CDP implementation of scapy. (Thanks to Nicolas Bareil and Arnaud Ebalard) - http://trac.secdev.org/scapy/ticket/18 - - IOS / EIGRP Version Representation FIX by Dirk Loss -""" -from __future__ import absolute_import -import socket -import struct - -from scapy.packet import Packet -from scapy.fields import StrField, IPField, XShortField, FieldLenField, \ - StrLenField, IntField, ByteEnumField, ByteField, ConditionalField, \ - FlagsField, IP6Field, PacketField, PacketListField, ShortEnumField, \ - ShortField, StrFixedLenField, ThreeBytesField -from scapy.layers.inet import IP, checksum, bind_layers -from scapy.layers.inet6 import IPv6 -from scapy.compat import chb, raw -from scapy.config import conf -from scapy.utils import inet_aton, inet_ntoa -from scapy.pton_ntop import inet_ntop, inet_pton -from scapy.error import warning, Scapy_Exception -from scapy.volatile import RandShort, RandString - - -class EigrpIPField(StrField, IPField): - """ - This is a special field type for handling ip addresses of destination networks in internal and - external route updates. - - EIGRP removes zeros from the host portion of the ip address if the netmask is 8, 16 or 24 bits. - """ - - __slots__ = ["length_from"] - - def __init__(self, name, default, length=None, length_from=None): - StrField.__init__(self, name, default) - self.length_from = length_from - if length is not None: - self.length_from = lambda pkt, length=length: length - - def h2i(self, pkt, x): - return IPField.h2i(self, pkt, x) - - def i2m(self, pkt, x): - x = inet_aton(x) - tmp_len = self.length_from(pkt) - - if tmp_len <= 8: - return x[:1] - elif tmp_len <= 16: - return x[:2] - elif tmp_len <= 24: - return x[:3] - else: - return x - - def m2i(self, pkt, x): - tmp_len = self.length_from(pkt) - - if tmp_len <= 8: - x += b"\x00\x00\x00" - elif tmp_len <= 16: - x += b"\x00\x00" - elif tmp_len <= 24: - x += b"\x00" - - return inet_ntoa(x) - - def prefixlen_to_bytelen(self, tmp_len): - if tmp_len <= 8: - tmp_len = 1 - elif tmp_len <= 16: - tmp_len = 2 - elif tmp_len <= 24: - tmp_len = 3 - else: - tmp_len = 4 - - return tmp_len - - def i2len(self, pkt, x): - tmp_len = self.length_from(pkt) - tmp_len = self.prefixlen_to_bytelen(tmp_len) - return tmp_len - - def getfield(self, pkt, s): - tmp_len = self.length_from(pkt) - tmp_len = self.prefixlen_to_bytelen(tmp_len) - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - - def randval(self): - return IPField.randval(self) - - -class EigrpIP6Field(StrField, IP6Field): - """ - This is a special field type for handling ip addresses of destination networks in internal and - external route updates. - - """ - - __slots__ = ["length_from"] - - def __init__(self, name, default, length=None, length_from=None): - StrField.__init__(self, name, default) - self.length_from = length_from - if length is not None: - self.length_from = lambda pkt, length=length: length - - def any2i(self, pkt, x): - return IP6Field.any2i(self, pkt, x) - - def i2repr(self, pkt, x): - return IP6Field.i2repr(self, pkt, x) - - def h2i(self, pkt, x): - return IP6Field.h2i(self, pkt, x) - - def i2m(self, pkt, x): - x = inet_pton(socket.AF_INET6, x) - tmp_len = self.length_from(pkt) - tmp_len = self.prefixlen_to_bytelen(tmp_len) - - return x[:tmp_len] - - def m2i(self, pkt, x): - tmp_len = self.length_from(pkt) - - prefixlen = self.prefixlen_to_bytelen(tmp_len) - if tmp_len > 128: - warning("EigrpIP6Field: Prefix length is > 128. Dissection of this packet will fail") # noqa: E501 - else: - pad = b"\x00" * (16 - prefixlen) - x += pad - - return inet_ntop(socket.AF_INET6, x) - - def prefixlen_to_bytelen(self, plen): - plen = plen // 8 - - if plen < 16: - plen += 1 - - return plen - - def i2len(self, pkt, x): - tmp_len = self.length_from(pkt) - tmp_len = self.prefixlen_to_bytelen(tmp_len) - return tmp_len - - def getfield(self, pkt, s): - tmp_len = self.length_from(pkt) - tmp_len = self.prefixlen_to_bytelen(tmp_len) - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - - def randval(self): - return IP6Field.randval(self) - - -class EIGRPGeneric(Packet): - name = "EIGRP Generic TLV" - fields_desc = [XShortField("type", 0x0000), - FieldLenField("len", None, "value", "!H", adjust=lambda pkt, x: x + 4), # noqa: E501 - StrLenField("value", b"\x00", length_from=lambda pkt: pkt.len - 4)] # noqa: E501 - - def guess_payload_class(self, p): - return conf.padding_layer - - -class EIGRPParam(EIGRPGeneric): - name = "EIGRP Parameters" - fields_desc = [XShortField("type", 0x0001), - ShortField("len", 12), - # Bandwidth - ByteField("k1", 1), - # Load - ByteField("k2", 0), - # Delay - ByteField("k3", 1), - # Reliability - ByteField("k4", 0), - # MTU - ByteField("k5", 0), - ByteField("reserved", 0), - ShortField("holdtime", 15) - ] - - -class EIGRPAuthData(EIGRPGeneric): - name = "EIGRP Authentication Data" - fields_desc = [XShortField("type", 0x0002), - FieldLenField("len", None, "authdata", "!H", adjust=lambda pkt, x: x + 24), # noqa: E501 - ShortEnumField("authtype", 2, {2: "MD5"}), - ShortField("keysize", None), - IntField("keyid", 1), - StrFixedLenField("nullpad", b"\x00" * 12, 12), - StrLenField("authdata", RandString(16), length_from=lambda pkt: pkt.keysize) # noqa: E501 - ] - - def post_build(self, p, pay): - p += pay - - if self.keysize is None: - keysize = len(self.authdata) - p = p[:6] + chb((keysize >> 8) & 0xff) + chb(keysize & 0xff) + p[8:] # noqa: E501 - - return p - - -class EIGRPSeq(EIGRPGeneric): - name = "EIGRP Sequence" - fields_desc = [XShortField("type", 0x0003), - ShortField("len", None), - ByteField("addrlen", 4), - ConditionalField(IPField("ipaddr", "192.168.0.1"), - lambda pkt:pkt.addrlen == 4), - ConditionalField(IP6Field("ip6addr", "2001::"), - lambda pkt:pkt.addrlen == 16) - ] - - def post_build(self, p, pay): - p += pay - - if self.len is None: - tmp_len = len(p) - tmp_p = p[:2] + chb((tmp_len >> 8) & 0xff) - p = tmp_p + chb(tmp_len & 0xff) + p[4:] - - return p - - -class ShortVersionField(ShortField): - def i2repr(self, pkt, x): - try: - minor = x & 0xff - major = (x >> 8) & 0xff - except TypeError: - return "unknown" - else: - # We print a leading 'v' so that these values don't look like floats # noqa: E501 - return "v%s.%s" % (major, minor) - - def h2i(self, pkt, x): - """The field accepts string values like v12.1, v1.1 or integer values. - String values have to start with a "v" folled by a floating point number. - Valid numbers are between 0 and 255. - """ - - if isinstance(x, str) and x.startswith("v") and len(x) <= 8: - major = int(x.split(".")[0][1:]) - minor = int(x.split(".")[1]) - - return (major << 8) | minor - - elif isinstance(x, int) and 0 <= x <= 65535: - return x - else: - if not hasattr(self, "default"): - return x - if self.default is not None: - warning("set value to default. Format of %r is invalid" % x) - return self.default - else: - raise Scapy_Exception("Format of value is invalid") - - def randval(self): - return RandShort() - - -class EIGRPSwVer(EIGRPGeneric): - name = "EIGRP Software Version" - fields_desc = [XShortField("type", 0x0004), - ShortField("len", 8), - ShortVersionField("ios", "v12.0"), - ShortVersionField("eigrp", "v1.2") - ] - - -class EIGRPNms(EIGRPGeneric): - name = "EIGRP Next Multicast Sequence" - fields_desc = [XShortField("type", 0x0005), - ShortField("len", 8), - IntField("nms", 2) - ] - - -# Don't get confused by the term "receive-only". This flag is always set, when you configure # noqa: E501 -# one of the stub options. It's also the only flag set, when you configure "eigrp stub receive-only". # noqa: E501 -_EIGRP_STUB_FLAGS = ["connected", "static", "summary", "receive-only", "redistributed", "leak-map"] # noqa: E501 - - -class EIGRPStub(EIGRPGeneric): - name = "EIGRP Stub Router" - fields_desc = [XShortField("type", 0x0006), - ShortField("len", 6), - FlagsField("flags", 0x000d, 16, _EIGRP_STUB_FLAGS)] - -# Delay 0xffffffff == Destination Unreachable - - -class EIGRPIntRoute(EIGRPGeneric): - name = "EIGRP Internal Route" - fields_desc = [XShortField("type", 0x0102), - FieldLenField("len", None, "dst", "!H", adjust=lambda pkt, x: x + 25), # noqa: E501 - IPField("nexthop", "192.168.0.0"), - IntField("delay", 128000), - IntField("bandwidth", 256), - ThreeBytesField("mtu", 1500), - ByteField("hopcount", 0), - ByteField("reliability", 255), - ByteField("load", 0), - XShortField("reserved", 0), - ByteField("prefixlen", 24), - EigrpIPField("dst", "192.168.1.0", length_from=lambda pkt: pkt.prefixlen), # noqa: E501 - ] - - -_EIGRP_EXTERNAL_PROTOCOL_ID = { - 0x01: "IGRP", - 0x02: "EIGRP", - 0x03: "Static Route", - 0x04: "RIP", - 0x05: "Hello", - 0x06: "OSPF", - 0x07: "IS-IS", - 0x08: "EGP", - 0x09: "BGP", - 0x0A: "IDRP", - 0x0B: "Connected Link" -} - -_EIGRP_EXTROUTE_FLAGS = ["external", "candidate-default"] - - -class EIGRPExtRoute(EIGRPGeneric): - name = "EIGRP External Route" - fields_desc = [XShortField("type", 0x0103), - FieldLenField("len", None, "dst", "!H", adjust=lambda pkt, x: x + 45), # noqa: E501 - IPField("nexthop", "192.168.0.0"), - IPField("originrouter", "192.168.0.1"), - IntField("originasn", 0), - IntField("tag", 0), - IntField("externalmetric", 0), - ShortField("reserved", 0), - ByteEnumField("extprotocolid", 3, _EIGRP_EXTERNAL_PROTOCOL_ID), # noqa: E501 - FlagsField("flags", 0, 8, _EIGRP_EXTROUTE_FLAGS), - IntField("delay", 0), - IntField("bandwidth", 256), - ThreeBytesField("mtu", 1500), - ByteField("hopcount", 0), - ByteField("reliability", 255), - ByteField("load", 0), - XShortField("reserved2", 0), - ByteField("prefixlen", 24), - EigrpIPField("dst", "192.168.1.0", length_from=lambda pkt: pkt.prefixlen) # noqa: E501 - ] - - -class EIGRPv6IntRoute(EIGRPGeneric): - name = "EIGRP for IPv6 Internal Route" - fields_desc = [XShortField("type", 0x0402), - FieldLenField("len", None, "dst", "!H", adjust=lambda pkt, x: x + 37), # noqa: E501 - IP6Field("nexthop", "::"), - IntField("delay", 128000), - IntField("bandwidth", 256000), - ThreeBytesField("mtu", 1500), - ByteField("hopcount", 1), - ByteField("reliability", 255), - ByteField("load", 0), - XShortField("reserved", 0), - ByteField("prefixlen", 16), - EigrpIP6Field("dst", "2001::", length_from=lambda pkt: pkt.prefixlen) # noqa: E501 - ] - - -class EIGRPv6ExtRoute(EIGRPGeneric): - name = "EIGRP for IPv6 External Route" - fields_desc = [XShortField("type", 0x0403), - FieldLenField("len", None, "dst", "!H", adjust=lambda pkt, x: x + 57), # noqa: E501 - IP6Field("nexthop", "::"), - IPField("originrouter", "192.168.0.1"), - IntField("originasn", 0), - IntField("tag", 0), - IntField("externalmetric", 0), - ShortField("reserved", 0), - ByteEnumField("extprotocolid", 3, _EIGRP_EXTERNAL_PROTOCOL_ID), # noqa: E501 - FlagsField("flags", 0, 8, _EIGRP_EXTROUTE_FLAGS), - IntField("delay", 0), - IntField("bandwidth", 256000), - ThreeBytesField("mtu", 1500), - ByteField("hopcount", 1), - ByteField("reliability", 0), - ByteField("load", 1), - XShortField("reserved2", 0), - ByteField("prefixlen", 8), - EigrpIP6Field("dst", "::", length_from=lambda pkt: pkt.prefixlen) # noqa: E501 - ] - - -_eigrp_tlv_cls = { - 0x0001: "EIGRPParam", - 0x0002: "EIGRPAuthData", - 0x0003: "EIGRPSeq", - 0x0004: "EIGRPSwVer", - 0x0005: "EIGRPNms", - 0x0006: "EIGRPStub", - 0x0102: "EIGRPIntRoute", - 0x0103: "EIGRPExtRoute", - 0x0402: "EIGRPv6IntRoute", - 0x0403: "EIGRPv6ExtRoute" -} - - -class RepeatedTlvListField(PacketListField): - def __init__(self, name, default, cls): - PacketField.__init__(self, name, default, cls) - - def getfield(self, pkt, s): - lst = [] - remain = s - 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 remain, lst - - def addfield(self, pkt, s, val): - return s + b"".join(raw(v) for v in val) - - -def _EIGRPGuessPayloadClass(p, **kargs): - cls = conf.raw_layer - if len(p) >= 2: - t = struct.unpack("!H", p[:2])[0] - clsname = _eigrp_tlv_cls.get(t, "EIGRPGeneric") - cls = globals()[clsname] - return cls(p, **kargs) - - -_EIGRP_OPCODES = {1: "Update", - 2: "Request", - 3: "Query", - 4: "Replay", - 5: "Hello", - 6: "IPX SAP", - 10: "SIA Query", - 11: "SIA Reply"} - -# The Conditional Receive bit is used for reliable multicast communication. -# Update-Flag: Not sure if Cisco calls it that way, but it's set when neighbors -# are exchanging routing information -_EIGRP_FLAGS = ["init", "cond-recv", "unknown", "update"] - - -class EIGRP(Packet): - name = "EIGRP" - fields_desc = [ByteField("ver", 2), - ByteEnumField("opcode", 5, _EIGRP_OPCODES), - XShortField("chksum", None), - FlagsField("flags", 0, 32, _EIGRP_FLAGS), - IntField("seq", 0), - IntField("ack", 0), - IntField("asn", 100), - RepeatedTlvListField("tlvlist", [], _EIGRPGuessPayloadClass) - ] - - def post_build(self, p, pay): - p += pay - if self.chksum is None: - c = checksum(p) - p = p[:2] + chb((c >> 8) & 0xff) + chb(c & 0xff) + p[4:] - return p - - def mysummary(self): - summarystr = "EIGRP (AS=%EIGRP.asn% Opcode=%EIGRP.opcode%" - if self.opcode == 5 and self.ack != 0: - summarystr += " (ACK)" - if self.flags != 0: - summarystr += " Flags=%EIGRP.flags%" - - return self.sprintf(summarystr + ")") - - -bind_layers(IP, EIGRP, proto=88) -bind_layers(IPv6, EIGRP, nh=88) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/enipTCP.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/enipTCP.py deleted file mode 100644 index bfd19fa25a..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/enipTCP.py +++ /dev/null @@ -1,228 +0,0 @@ -# coding: utf8 - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = EtherNet/IP -# scapy.contrib.status = loads - -# Copyright (C) 2019 Jose Diogo Monteiro -# Based on https://github.com/scy-phy/scapy-cip-enip -# Routines for EtherNet/IP (Industrial Protocol) dissection -# EtherNet/IP Home: www.odva.org - -import struct -from scapy.packet import Packet, bind_layers -from scapy.layers.inet import TCP -from scapy.fields import LEShortField, LEShortEnumField, LEIntEnumField, \ - LEIntField, LELongField, FieldLenField, PacketListField, ByteField, \ - PacketField, MultipleTypeField, StrLenField, StrFixedLenField, \ - XLEIntField, XLEStrLenField - -_commandIdList = { - 0x0004: "ListServices", # Request Struct Don't Have Command Spec Data - 0x0063: "ListIdentity", # Request Struct Don't Have Command Spec Data - 0x0064: "ListInterfaces", # Request Struct Don't Have Command Spec Data - 0x0065: "RegisterSession", # Request Structure = Reply Structure - 0x0066: "UnregisterSession", # Don't Have Command Specific Data - 0x006f: "SendRRData", # Request Structure = Reply Structure - 0x0070: "SendUnitData", # There is no reply - 0x0072: "IndicateStatus", - 0x0073: "Cancel" -} - -_statusList = { - 0: "success", - 1: "invalid_cmd", - 2: "no_resources", - 3: "incorrect_data", - 100: "invalid_session", - 101: "invalid_length", - 105: "unsupported_prot_rev" -} - -_itemID = { - 0x0000: "Null Address Item", - 0x00a1: "Connection-based Address Item", - 0x00b1: "Connected Transport packet Data Item", - 0x00b2: "Unconnected message Data Item", - 0x8000: "Sockaddr Info, originator-to-target Data Item", - 0x8001: "Sockaddr Info, target-to-originator Data Item" -} - - -class ItemData(Packet): - """Common Packet Format""" - name = "Item Data" - fields_desc = [ - LEShortEnumField("typeId", 0, _itemID), - LEShortField("length", 0), - XLEStrLenField("data", "", length_from=lambda pkt: pkt.length), - ] - - def extract_padding(self, s): - return '', s - - -class EncapsulatedPacket(Packet): - """Encapsulated Packet""" - name = "Encapsulated Packet" - fields_desc = [LEShortField("itemCount", 2), PacketListField( - "item", None, ItemData, count_from=lambda pkt: pkt.itemCount), ] - - -class BaseSendPacket(Packet): - """ Abstract Class""" - fields_desc = [ - LEIntField("interfaceHandle", 0), - LEShortField("timeout", 0), - PacketField("encapsulatedPacket", None, EncapsulatedPacket), - ] - - -class CommandSpecificData(Packet): - """Command Specific Data Field Default""" - pass - - -class ENIPSendUnitData(BaseSendPacket): - """Send Unit Data Command Field""" - name = "ENIPSendUnitData" - - -class ENIPSendRRData(BaseSendPacket): - """Send RR Data Command Field""" - name = "ENIPSendRRData" - - -class ENIPListInterfacesReplyItems(Packet): - """List Interfaces Items Field""" - name = "ENIPListInterfacesReplyItems" - fields_desc = [ - LEIntField("itemTypeCode", 0), - FieldLenField("itemLength", 0, length_of="itemData"), - StrLenField("itemData", "", length_from=lambda pkt: pkt.itemLength), - ] - - -class ENIPListInterfacesReply(Packet): - """List Interfaces Command Field""" - name = "ENIPListInterfacesReply" - fields_desc = [ - FieldLenField("itemCount", 0, count_of="identityItems"), - PacketField("identityItems", 0, ENIPListInterfacesReplyItems), - ] - - -class ENIPListIdentityReplyItems(Packet): - """List Identity Items Field""" - name = "ENIPListIdentityReplyItems" - fields_desc = [ - LEIntField("itemTypeCode", 0), - FieldLenField("itemLength", 0, length_of="itemData"), - StrLenField("itemData", "", length_from=lambda pkt: pkt.item_length), - ] - - -class ENIPListIdentityReply(Packet): - """List Identity Command Field""" - name = "ENIPListIdentityReply" - fields_desc = [ - FieldLenField("itemCount", 0, count_of="identityItems"), - PacketField("identityItems", None, ENIPListIdentityReplyItems), - ] - - -class ENIPListServicesReplyItems(Packet): - """List Services Items Field""" - name = "ENIPListServicesReplyItems" - fields_desc = [ - LEIntField("itemTypeCode", 0), - LEIntField("itemLength", 0), - ByteField("version", 1), - ByteField("flag", 0), - StrFixedLenField("serviceName", None, 16 * 4), - ] - - -class ENIPListServicesReply(Packet): - """List Services Command Field""" - name = "ENIPListServicesReply" - fields_desc = [ - FieldLenField("itemCount", 0, count_of="identityItems"), - PacketField("targetItems", None, ENIPListServicesReplyItems), - ] - - -class ENIPRegisterSession(CommandSpecificData): - """Register Session Command Field""" - name = "ENIPRegisterSession" - fields_desc = [ - LEShortField("protocolVersion", 1), - LEShortField("options", 0) - ] - - -class ENIPTCP(Packet): - """Ethernet/IP packet over TCP""" - name = "ENIPTCP" - fields_desc = [ - LEShortEnumField("commandId", None, _commandIdList), - LEShortField("length", 0), - XLEIntField("session", 0), - LEIntEnumField("status", None, _statusList), - LELongField("senderContext", 0), - LEIntField("options", 0), - MultipleTypeField( - [ - # List Services Reply - (PacketField("commandSpecificData", ENIPListServicesReply, - ENIPListServicesReply), - lambda pkt: pkt.commandId == 0x4), - # List Identity Reply - (PacketField("commandSpecificData", ENIPListIdentityReply, - ENIPListIdentityReply), - lambda pkt: pkt.commandId == 0x63), - # List Interfaces Reply - (PacketField("commandSpecificData", ENIPListInterfacesReply, - ENIPListInterfacesReply), - lambda pkt: pkt.commandId == 0x64), - # Register Session - (PacketField("commandSpecificData", ENIPRegisterSession, - ENIPRegisterSession), - lambda pkt: pkt.commandId == 0x65), - # Send RR Data - (PacketField("commandSpecificData", ENIPSendRRData, - ENIPSendRRData), - lambda pkt: pkt.commandId == 0x6f), - # Send Unit Data - (PacketField("commandSpecificData", ENIPSendUnitData, - ENIPSendUnitData), - lambda pkt: pkt.commandId == 0x70), - ], - PacketField( - "commandSpecificData", - None, - CommandSpecificData) # By default - ), - ] - - def post_build(self, pkt, pay): - if self.length is None and pay: - pkt = pkt[:2] + struct.pack(" error - raise LEBitFieldSequenceException('Missing further LEBitField ' - 'based fields after field ' - '{} '.format(self.name)) - - def addfield(self, pkt, s, val): - """ - - :param pkt: packet instance the raw string s and field belongs to - :param s: raw string representing the frame - :param val: value - :return: final raw string, tuple (s, bitsdone, data) if in between bit field # noqa: E501 - - as we don't know the final size of the full bitfield we need to accumulate the data. # noqa: E501 - if we reach a field that ends at a octet boundary, we build the whole string # noqa: E501 - - """ - if type(s) is tuple and len(s) == 4: - s, bitsdone, data, _ = s - self._check_field_type(pkt, -1) - else: - # this is the first bit field in the set - bitsdone = 0 - data = [] - - bitsdone += self.size - data.append((self.size, self.i2m(pkt, val))) - - if bitsdone % 8: - # somewhere in between bit 0 .. 7 - next field should add more bits... # noqa: E501 - self._check_field_type(pkt, 1) - return s, bitsdone, data, type(LEBitField) - else: - data.reverse() - octet = 0 - remaining_len = 8 - octets = bytearray() - for size, val in data: - - while True: - if size < remaining_len: - remaining_len = remaining_len - size - octet |= val << remaining_len - break - - elif size > remaining_len: - # take the leading bits and add them to octet - size -= remaining_len - octet |= val >> size - octets = struct.pack('!B', octet) + octets - - octet = 0 - remaining_len = 8 - # delete all consumed bits - # TODO: do we need to add a check for bitfields > 64 bits to catch overruns here? # noqa: E501 - val &= ((2 ** size) - 1) - continue - else: - # size == remaining len - octet |= val - octets = struct.pack('!B', octet) + octets - octet = 0 - remaining_len = 8 - break - - return s + octets - - def getfield(self, pkt, s): - - """ - extract data from raw str - - collect all instances belonging to the bit field set. - if we reach a field that ends at a octet boundary, dissect the whole bit field at once # noqa: E501 - - :param pkt: packet instance the field belongs to - :param s: raw string representing the frame -or- tuple containing raw str, number of bits and array of fields # noqa: E501 - :return: tuple containing raw str, number of bits and array of fields -or- remaining raw str and value of this # noqa: E501 - """ - - if type(s) is tuple and len(s) == 3: - s, bits_in_set, fields = s - else: - bits_in_set = 0 - fields = [] - - bits_in_set += self.size - - fields.append(self) - - if bits_in_set % 8: - # we are in between the bitfield - return (s, bits_in_set, fields), None - - else: - cur_val = 0 - cur_val_bit_idx = 0 - this_val = 0 - - field_idx = 0 - field = fields[field_idx] - field_required_bits = field.size - idx = 0 - - s = bytearray(s) - bf_total_byte_length = bits_in_set // 8 - - for octet in s[0:bf_total_byte_length]: - idx += 1 - - octet_bits_left = 8 - - while octet_bits_left: - - if field_required_bits == octet_bits_left: - # whole field fits into remaining bits - # as this also signals byte-alignment this should exit the inner and outer loop # noqa: E501 - cur_val |= octet << cur_val_bit_idx - pkt.fields[field.name] = cur_val - - ''' - TODO: check if do_dessect() needs a non-None check for assignment to raw_packet_cache_fields # noqa: E501 - - setfieldval() is evil as it sets raw_packet_cache_fields to None - but this attribute # noqa: E501 - is accessed in do_dissect() without checking for None... exception is caught and the # noqa: E501 - user ends up with a layer decoded as raw... - - pkt.setfieldval(field.name, int(bit_str[:field.size], 2)) # noqa: E501 - ''' - - octet_bits_left = 0 - - this_val = cur_val - - elif field_required_bits < octet_bits_left: - # pick required bits - cur_val |= (octet & ((2 ** field_required_bits) - 1)) << cur_val_bit_idx # noqa: E501 - pkt.fields[field.name] = cur_val - - # remove consumed bits - octet >>= field_required_bits - octet_bits_left -= field_required_bits - - # and move to the next field - field_idx += 1 - field = fields[field_idx] - field_required_bits = field.size - cur_val_bit_idx = 0 - cur_val = 0 - - elif field_required_bits > octet_bits_left: - # take remaining bits - cur_val |= octet << cur_val_bit_idx - - cur_val_bit_idx += octet_bits_left - field_required_bits -= octet_bits_left - octet_bits_left = 0 - - return s[bf_total_byte_length:], this_val - - -class LEBitFieldLenField(LEBitField): - __slots__ = ["length_of", "count_of", "adjust"] - - def __init__(self, name, default, size, length_of=None, count_of=None, adjust=lambda pkt, x: x): # noqa: E501 - LEBitField.__init__(self, name, default, size) - self.length_of = length_of - self.count_of = count_of - self.adjust = adjust - - def i2m(self, pkt, x): - return (FieldLenField.i2m.__func__ if six.PY2 else FieldLenField.i2m)(self, pkt, x) # noqa: E501 - - -class LEBitEnumField(LEBitField, _EnumField): - __slots__ = EnumField.__slots__ - - def __init__(self, name, default, size, enum): - _EnumField.__init__(self, name, default, enum) - self.rev = size < 0 - self.size = abs(size) - - -################################################ -# DLPDU structure definitions (read/write PDUs) -################################################ - -ETHERCAT_TYPE_12_CIRCULATING_FRAME = { - 0x00: 'FRAME-NOT-CIRCULATING', - 0x01: 'FRAME-CIRCULATED-ONCE' -} - -ETHERCAT_TYPE_12_NEXT_FRAME = { - 0x00: 'LAST-TYPE12-PDU', - 0x01: 'TYPE12-PDU-FOLLOWS' -} - - -class EtherCatType12DLPDU(Packet): - """ - Type12 message base class - """ - def post_build(self, pkt, pay): - """ - - set next attr automatically if not set explicitly by user - - :param pkt: raw string containing the current layer - :param pay: raw string containing the payload - :return: + payload - """ - - data_len = len(self.data) - if data_len > 2047: - raise ValueError('payload size {} exceeds maximum length {} ' - 'of data size.'.format(data_len, 2047)) - - if self.next is not None: - has_next = True if self.next else False - else: - if pay: - has_next = True - else: - has_next = False - - if has_next: - next_flag = bytearray([pkt[7] | 0b10000000]) - else: - next_flag = bytearray([pkt[7] & 0b01111111]) - - return pkt[:7] + next_flag + pkt[8:] + pay - - def guess_payload_class(self, payload): - - try: - dlpdu_type = payload[0] - return EtherCat.ETHERCAT_TYPE12_DLPDU_TYPES[dlpdu_type] - - except KeyError: - log_runtime.error( - '{}.guess_payload_class() - unknown or invalid ' - 'DLPDU type'.format(self.__class__.__name__)) - return Packet.guess_payload_class(self, payload) - - # structure templates lacking leading cmd-attribute - PHYSICAL_ADDRESSING_DESC = [ - ByteField('idx', 0), - LEShortField('adp', 0), - LEShortField('ado', 0), - LEBitFieldLenField('len', None, 11, count_of='data'), - LEBitField('_reserved', 0, 3), - LEBitEnumField('c', 0, 1, ETHERCAT_TYPE_12_CIRCULATING_FRAME), - LEBitEnumField('next', None, 1, ETHERCAT_TYPE_12_NEXT_FRAME), - LEShortField('irq', 0), - FieldListField('data', [], ByteField('', 0x00), - count_from=lambda pkt: pkt.len), - LEShortField('wkc', 0) - ] - - BROADCAST_ADDRESSING_DESC = PHYSICAL_ADDRESSING_DESC - - LOGICAL_ADDRESSING_DESC = [ - ByteField('idx', 0), - LEIntField('adr', 0), - LEBitFieldLenField('len', None, 11, count_of='data'), - LEBitField('_reserved', 0, 3), - LEBitEnumField('c', 0, 1, ETHERCAT_TYPE_12_CIRCULATING_FRAME), - LEBitEnumField('next', None, 1, ETHERCAT_TYPE_12_NEXT_FRAME), - LEShortField('irq', 0), - FieldListField('data', [], ByteField('', 0x00), - count_from=lambda pkt: pkt.len), - LEShortField('wkc', 0) - ] - - -################ -# read messages -################ - -class EtherCatAPRD(EtherCatType12DLPDU): - """ - APRD - Auto Increment Physical Read - (IEC 61158-5-12, sec. 5.4.1.2 tab. 14 / p. 32) - """ - - fields_desc = [ByteField('_cmd', 0x01)] + \ - EtherCatType12DLPDU.PHYSICAL_ADDRESSING_DESC - - -class EtherCatFPRD(EtherCatType12DLPDU): - """ - FPRD - Configured address physical read - (IEC 61158-5-12, sec. 5.4.1.3 tab. 15 / p. 33) - """ - - fields_desc = [ByteField('_cmd', 0x04)] + \ - EtherCatType12DLPDU.PHYSICAL_ADDRESSING_DESC - - -class EtherCatBRD(EtherCatType12DLPDU): - """ - BRD - Broadcast read - (IEC 61158-5-12, sec. 5.4.1.4 tab. 16 / p. 34) - """ - - fields_desc = [ByteField('_cmd', 0x07)] + \ - EtherCatType12DLPDU.BROADCAST_ADDRESSING_DESC - - -class EtherCatLRD(EtherCatType12DLPDU): - """ - LRD - Logical read - (IEC 61158-5-12, sec. 5.4.1.5 tab. 17 / p. 36) - """ - - fields_desc = [ByteField('_cmd', 0x0a)] + \ - EtherCatType12DLPDU.LOGICAL_ADDRESSING_DESC - - -################# -# write messages -################# - - -class EtherCatAPWR(EtherCatType12DLPDU): - """ - APWR - Auto Increment Physical Write - (IEC 61158-5-12, sec. 5.4.2.2 tab. 18 / p. 37) - """ - - fields_desc = [ByteField('_cmd', 0x02)] + \ - EtherCatType12DLPDU.PHYSICAL_ADDRESSING_DESC - - -class EtherCatFPWR(EtherCatType12DLPDU): - """ - FPWR - Configured address physical write - (IEC 61158-5-12, sec. 5.4.2.3 tab. 19 / p. 38) - """ - - fields_desc = [ByteField('_cmd', 0x05)] + \ - EtherCatType12DLPDU.PHYSICAL_ADDRESSING_DESC - - -class EtherCatBWR(EtherCatType12DLPDU): - """ - BWR - Broadcast read (IEC 61158-5-12, sec. 5.4.2.4 tab. 20 / p. 39) - """ - - fields_desc = [ByteField('_cmd', 0x08)] + \ - EtherCatType12DLPDU.BROADCAST_ADDRESSING_DESC - - -class EtherCatLWR(EtherCatType12DLPDU): - """ - LWR - Logical write - (IEC 61158-5-12, sec. 5.4.2.5 tab. 21 / p. 40) - """ - - fields_desc = [ByteField('_cmd', 0x0b)] + \ - EtherCatType12DLPDU.LOGICAL_ADDRESSING_DESC - - -###################### -# read/write messages -###################### - - -class EtherCatAPRW(EtherCatType12DLPDU): - """ - APRW - Auto Increment Physical Read Write - (IEC 61158-5-12, sec. 5.4.3.1 tab. 22 / p. 41) - """ - - fields_desc = [ByteField('_cmd', 0x03)] + \ - EtherCatType12DLPDU.PHYSICAL_ADDRESSING_DESC - - -class EtherCatFPRW(EtherCatType12DLPDU): - """ - FPRW - Configured address physical read write - (IEC 61158-5-12, sec. 5.4.3.2 tab. 23 / p. 43) - """ - - fields_desc = [ByteField('_cmd', 0x06)] + \ - EtherCatType12DLPDU.PHYSICAL_ADDRESSING_DESC - - -class EtherCatBRW(EtherCatType12DLPDU): - """ - BRW - Broadcast read write - (IEC 61158-5-12, sec. 5.4.3.3 tab. 24 / p. 39) - """ - - fields_desc = [ByteField('_cmd', 0x09)] + \ - EtherCatType12DLPDU.BROADCAST_ADDRESSING_DESC - - -class EtherCatLRW(EtherCatType12DLPDU): - """ - LRW - Logical read write - (IEC 61158-5-12, sec. 5.4.3.4 tab. 25 / p. 45) - """ - - fields_desc = [ByteField('_cmd', 0x0c)] + \ - EtherCatType12DLPDU.LOGICAL_ADDRESSING_DESC - - -class EtherCatARMW(EtherCatType12DLPDU): - """ - ARMW - Auto increment physical read multiple write - (IEC 61158-5-12, sec. 5.4.3.5 tab. 26 / p. 46) - """ - - fields_desc = [ByteField('_cmd', 0x0d)] + \ - EtherCatType12DLPDU.PHYSICAL_ADDRESSING_DESC - - -class EtherCatFRMW(EtherCatType12DLPDU): - """ - FRMW - Configured address physical read multiple write - (IEC 61158-5-12, sec. 5.4.3.6 tab. 27 / p. 47) - """ - - fields_desc = [ByteField('_cmd', 0x0e)] + \ - EtherCatType12DLPDU.PHYSICAL_ADDRESSING_DESC - - -class EtherCat(Packet): - """ - Common EtherCat header layer - """ - ETHER_HEADER_LEN = 14 - ETHER_FSC_LEN = 4 - ETHER_FRAME_MIN_LEN = 64 - ETHERCAT_HEADER_LEN = 2 - - FRAME_TYPES = { - 0x01: 'TYPE-12-PDU', - 0x04: 'NETWORK-VARIABLES', - 0x05: 'MAILBOX' - } - - fields_desc = [ - LEBitField('length', 0, 11), - LEBitField('_reserved', 0, 1), - LEBitField('type', 0, 4), - ] - - ETHERCAT_TYPE12_DLPDU_TYPES = { - 0x01: EtherCatAPRD, - 0x04: EtherCatFPRD, - 0x07: EtherCatBRD, - 0x0a: EtherCatLRD, - 0x02: EtherCatAPWR, - 0x05: EtherCatFPWR, - 0x08: EtherCatBWR, - 0x0b: EtherCatLWR, - 0x03: EtherCatAPRW, - 0x06: EtherCatFPRW, - 0x09: EtherCatBRW, - 0x0c: EtherCatLRW, - 0x0d: EtherCatARMW, - 0x0e: EtherCatFRMW - } - - def post_build(self, pkt, pay): - """ - need to set the length of the whole PDU manually - to avoid any bit fiddling use a dummy class to build the layer content - - also add padding if frame is < 64 bytes - - Note: padding only handles Ether/n*Dot1Q/EtherCat - (no special mumbo jumbo) - - :param pkt: raw string containing the current layer - :param pay: raw string containing the payload - :return: + payload - """ - - class _EtherCatLengthCalc(Packet): - """ - dummy class used to generate str representation easily - """ - fields_desc = [ - LEBitField('length', None, 11), - LEBitField('_reserved', 0, 1), - LEBitField('type', 0, 4), - ] - - payload_len = len(pay) - - # length field is 11 bit - if payload_len > 2047: - raise ValueError('payload size {} exceeds maximum length {} ' - 'of EtherCat message.'.format(payload_len, 2047)) - - self.length = payload_len - - vlan_headers_total_size = 0 - upper_layer = self.underlayer - - # add size occupied by VLAN tags - while upper_layer and isinstance(upper_layer, Dot1Q): - vlan_headers_total_size += 4 - upper_layer = upper_layer.underlayer - - if not isinstance(upper_layer, Ether): - raise Exception('missing Ether layer') - - pad_len = EtherCat.ETHER_FRAME_MIN_LEN - (EtherCat.ETHER_HEADER_LEN + - vlan_headers_total_size + - EtherCat.ETHERCAT_HEADER_LEN + # noqa: E501 - payload_len + - EtherCat.ETHER_FSC_LEN) - - if pad_len > 0: - pad = Padding() - pad.load = b'\x00' * pad_len - - return raw(_EtherCatLengthCalc(length=self.length, - type=self.type)) + pay + raw(pad) - return raw(_EtherCatLengthCalc(length=self.length, - type=self.type)) + pay - - def guess_payload_class(self, payload): - try: - dlpdu_type = payload[0] - return EtherCat.ETHERCAT_TYPE12_DLPDU_TYPES[dlpdu_type] - except KeyError: - log_runtime.error( - '{}.guess_payload_class() - unknown or invalid ' - 'DLPDU type'.format(self.__class__.__name__)) - return Packet.guess_payload_class(self, payload) - - -bind_layers(Ether, EtherCat, type=0x88a4) -bind_layers(Dot1Q, EtherCat, type=0x88a4) - -# bindings for DLPDUs - -bind_layers(EtherCat, EtherCatAPRD, type=0x01) -bind_layers(EtherCat, EtherCatFPRD, type=0x01) -bind_layers(EtherCat, EtherCatBRD, type=0x01) -bind_layers(EtherCat, EtherCatLRD, type=0x01) -bind_layers(EtherCat, EtherCatAPWR, type=0x01) -bind_layers(EtherCat, EtherCatFPWR, type=0x01) -bind_layers(EtherCat, EtherCatBWR, type=0x01) -bind_layers(EtherCat, EtherCatLWR, type=0x01) -bind_layers(EtherCat, EtherCatAPRW, type=0x01) -bind_layers(EtherCat, EtherCatFPRW, type=0x01) -bind_layers(EtherCat, EtherCatBRW, type=0x01) -bind_layers(EtherCat, EtherCatLRW, type=0x01) -bind_layers(EtherCat, EtherCatARMW, type=0x01) -bind_layers(EtherCat, EtherCatFRMW, type=0x01) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/etherip.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/etherip.py deleted file mode 100644 index 5f4a816157..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/etherip.py +++ /dev/null @@ -1,31 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = EtherIP -# scapy.contrib.status = loads - -from scapy.fields import BitField -from scapy.packet import Packet, bind_layers -from scapy.layers.inet import IP -from scapy.layers.l2 import Ether - - -class EtherIP(Packet): - name = "EtherIP / RFC 3378" - fields_desc = [BitField("version", 3, 4), - BitField("reserved", 0, 12)] - - -bind_layers(IP, EtherIP, frag=0, proto=0x61) -bind_layers(EtherIP, Ether) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/geneve.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/geneve.py deleted file mode 100644 index 57cd6d5d89..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/geneve.py +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright (C) 2018 Hao Zheng - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# flake8: noqa: E501 - -# scapy.contrib.description = Generic Network Virtualization Encapsulation (GENEVE) -# scapy.contrib.status = loads - -""" -Geneve: Generic Network Virtualization Encapsulation - -draft-ietf-nvo3-geneve-06 -""" - -from scapy.fields import BitField, XByteField, XShortEnumField, X3BytesField, \ - XStrField -from scapy.packet import Packet, bind_layers -from scapy.layers.inet import IP, UDP -from scapy.layers.inet6 import IPv6 -from scapy.layers.l2 import Ether, ETHER_TYPES -from scapy.compat import chb, orb -from scapy.error import warning - - -class GENEVEOptionsField(XStrField): - islist = 1 - - def getfield(self, pkt, s): - opln = pkt.optionlen * 4 - if opln < 0: - warning("bad optionlen (%i). Assuming optionlen=0" % pkt.optionlen) - opln = 0 - return s[opln:], self.m2i(pkt, s[:opln]) - - -class GENEVE(Packet): - name = "GENEVE" - fields_desc = [BitField("version", 0, 2), - BitField("optionlen", None, 6), - BitField("oam", 0, 1), - BitField("critical", 0, 1), - BitField("reserved", 0, 6), - XShortEnumField("proto", 0x0000, ETHER_TYPES), - X3BytesField("vni", 0), - XByteField("reserved2", 0x00), - GENEVEOptionsField("options", "")] - - def post_build(self, p, pay): - p += pay - optionlen = self.optionlen - if optionlen is None: - optionlen = (len(self.options) + 3) // 4 - p = chb(optionlen & 0x2f | orb(p[0]) & 0xc0) + p[1:] - return p - - def answers(self, other): - if isinstance(other, GENEVE): - if ((self.proto == other.proto) and (self.vni == other.vni)): - return self.payload.answers(other.payload) - else: - return self.payload.answers(other) - return 0 - - def mysummary(self): - return self.sprintf("GENEVE (vni=%GENEVE.vni%," - "optionlen=%GENEVE.optionlen%," - "proto=%GENEVE.proto%)") - - -bind_layers(UDP, GENEVE, dport=6081) -bind_layers(GENEVE, Ether, proto=0x6558) -bind_layers(GENEVE, IP, proto=0x0800) -bind_layers(GENEVE, IPv6, proto=0x86dd) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/gsm_um.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/gsm_um.py deleted file mode 100644 index 7b1354a4e2..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/gsm_um.py +++ /dev/null @@ -1,13119 +0,0 @@ -#!/usr/bin/env python - -# scapy.contrib.description = PPI -# scapy.contrib.status = loads - -""" - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - 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. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -""" - - #################################################################### - # This file holds the GSM UM interface implementation for Scapy # - # author: Laurent Weber # - # # - # Some examples on how to use this script: # - # http://0xbadcab1e.lu/scapy_gsm_um-howto.txt # - # # - # tested on: scapy-version: 2.2.0 (dev) # - #################################################################### - -import logging -from types import IntType -from types import NoneType -from types import StringType -#from time import sleep -import socket -logging.getLogger("scapy").setLevel(1) -from scapy.all import * - -# This method is intended to send gsm air packets. It uses a unix domain -# socket. It opens a socket, sends the parameter to the socket and -# closes the socket. -# typeSock determines the type of the socket, can be: -# 0 for UDP Socket -# 1 for Unix Domain Socket -# 2 for TCP - - -def sendum(x, typeSock=0): - try: - if type(x) is not str: - x = str(x) - if typeSock is 0: - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - host = '127.0.0.1' - port = 28670 # default for openBTS - s.connect((host, port)) - elif typeSock is 1: - s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - s.connect("/tmp/osmoL") - elif typeSock is 2: - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - host = '127.0.0.1' - port = 43797 - s.connect((host, port)) - s.send(x) - s.close() - except: - print("[Error]: There was a problem when trying to transmit data.\ - Please make sure you started the socket server.") - -# Known Bugs/Problems: -# If a message uses multiple times the same IE you cannot set the values -# of this IE's if you use the preconfigured packets. You need to build -# the IE's by hand and than assemble them as entire messages. - -# The ErrorLength class is a custom exception that gets raised when a -# packet doesn't have the correct size. - - -class ErrorLength(Exception): - def __str__(self): - error = "ERROR: Please make sure you build entire, 8 bit fields." - return repr(error) -### -# This method computes the length of the actual IE. -# It computes how many "None" fields have to be removed (if any). -# The method returns an integer containing the number of bytes that have to be -# cut off the packet. -# parameter length contains the max length of the IE can be found in -# 0408 -# The parameter fields contains the value of the fields (not the default but -# the real, actual value. -# The parameter fields2 contains fields_desc. -# Location contains the location of the length field in the IE. Everything -# after the the length field has to be counted (04.07 11.2.1.1.2) - - -def adapt(min_length, max_length, fields, fields2, location=2): - # find out how much bytes there are between min_length and the location of - # the length field - location = min_length - location - i = len(fields) - 1 - rm = mysum = 0 - while i >= 0: - if fields[i] is None: - rm += 1 - try: - mysum += fields2[i].size - except AttributeError: # ByteFields don't have .size - mysum += 8 - else: - break - i -= 1 - if mysum % 8 is 0: - length = mysum / 8 # Number of bytes we have to delete - dyn_length = (max_length - min_length - length) - if dyn_length < 0: - dyn_length = 0 - if length is max_length: # Fix for packets that have all values set - length -= min_length # to None - return [length, dyn_length + location] - else: - raise ErrorLength() - - -def examples(example=None): - if example == None: - print("""This command presents some example to introduce scapy -gsm-um to new users. -The following parameters can be used: - examples("imsiDetach") - examples("call") - examples("dissect")""") - elif example == "imsiDetach": - print(""" ->>> a=imsiDetachIndication() -... a.typeOfId=1; a.odd=1; a.idDigit1=0xF; -... a.idDigit2_1=2; a.idDigit2=7; a.idDigit3_1=0; -... a.idDigit3=7; a.idDigit4_1=7; a.idDigit4=2; -... a.idDigit5_1=0; a.idDigit5=0; a.idDigit6_1=0; -... a.idDigit6=1; a.idDigit7_1=2; a.idDigit7=7; -... a.idDigit8_1=7; a.idDigit8=5; a.idDigit9_1=1; a.idDigit9=4; ->>> hexdump(a) -0000 05 01 00 08 F0 27 07 72 00 01 27 75 14 .....'.r..'u. ->>> sendum(a) -""") - elif example == "call": - print(""" -If you use an USRP and the testcall function this sets up a phonecall: ->>> sendum(setupMobileOriginated()) ->>> sendum(connectAcknowledge()) -""") - - -# Section 10.2/3 -class TpPd(Packet): - """Skip indicator and transaction identifier and Protocol Discriminator""" - name = "Skip Indicator And Transaction Identifier and Protocol \ -Discriminator" - fields_desc = [ - BitField("ti", 0x0, 4), - BitField("pd", 0x3, 4) - ] - - -class MessageType(Packet): - """Message Type Section 10.4""" - name = "Message Type" - fields_desc = [ - XByteField("mesType", 0x3C) - ] - - -## -# Message for Radio Resources management (RR) Section 9.1 -### - -# Network to MS -def additionalAssignment(MobileAllocation_presence=0, - StartingTime_presence=0): - """ADDITIONAL ASSIGNMENT Section 9.1.1""" - # Mandatory - a = TpPd(pd=0x6) - b = MessageType(mesType=0x3B) # 00111011 - c = ChannelDescription() - packet = a / b / c - # Not Mandatory - if MobileAllocation_presence is 1: - d = MobileAllocationHdr(ieiMA=0x72, eightBitMA=0x0) - packet = packet / d - if StartingTime_presence is 1: - e = StartingTimeHdr(ieiST=0x7C, eightBitST=0x0) - packet = packet / e - return packet - - -# Network to MS -def assignmentCommand(FrequencyList_presence=0, - CellChannelDescription_presence=0, - CellChannelDescription_presence1=0, - MultislotAllocation_presence=0, - ChannelMode_presence=0, ChannelMode_presence1=0, - ChannelMode_presence2=0, ChannelMode_presence3=0, - ChannelMode_presence4=0, ChannelMode_presence5=0, - ChannelMode_presence6=0, ChannelMode_presence7=0, - ChannelDescription=0, ChannelMode2_presence=0, - MobileAllocation_presence=0, StartingTime_presence=0, - FrequencyList_presence1=0, - ChannelDescription2_presence=0, - ChannelDescription_presence=0, - FrequencyChannelSequence_presence=0, - MobileAllocation_presence1=0, - CipherModeSetting_presence=0, - VgcsTargetModeIdentication_presence=0, - MultiRateConfiguration_presence=0): - """ASSIGNMENT COMMAND Section 9.1.2""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x2e) # 101110 - c = ChannelDescription2() - d = PowerCommand() - packet = a / b / c / d - if FrequencyList_presence is 1: - e = FrequencyListHdr(ieiFL=0x05, eightBitFL=0x0) - packet = packet / e - if CellChannelDescription_presence is 1: - f = CellChannelDescriptionHdr(ieiCCD=0x62, eightBitCCD=0x0) - packet = packet / f - if MultislotAllocation_presence is 1: - g = MultislotAllocationHdr(ieiMSA=0x10, eightBitMSA=0x0) - packet = packet / g - if ChannelMode_presence is 1: - h = ChannelModeHdr(ieiCM=0x63, eightBitCM=0x0) - packet = packet / h - if ChannelMode_presence1 is 1: - i = ChannelModeHdr(ieiCM=0x11, eightBitCM=0x0) - packet = packet / i - if ChannelMode_presence2 is 1: - j = ChannelModeHdr(ieiCM=0x13, eightBitCM=0x0) - packet = packet / j - if ChannelMode_presence3 is 1: - k = ChannelModeHdr(ieiCM=0x14, eightBitCM=0x0) - packet = packet / k - if ChannelMode_presence4 is 1: - l = ChannelModeHdr(ieiCM=0x15, eightBitCM=0x0) - packet = packet / l - if ChannelMode_presence5 is 1: - m = ChannelModeHdr(ieiCM=0x16, eightBitCM=0x0) - packet = packet / m - if ChannelMode_presence6 is 1: - n = ChannelModeHdr(ieiCM=0x17, eightBitCM=0x0) - packet = packet / n - if ChannelMode_presence7 is 1: - o = ChannelModeHdr(ieiCM=0x18, eightBitCM=0x0) - packet = packet / o - if ChannelDescription_presence is 1: - p = ChannelDescriptionHdr(ieiCD=0x64, eightBitCD=0x0) - packet = packet / p - if ChannelMode2_presence is 1: - q = ChannelMode2Hdr(ieiCM2=0x66, eightBitCM2=0x0) - packet = packet / q - if MobileAllocation_presence is 1: - r = MobileAllocationHdr(ieiMA=0x72, eightBitMA=0x0) - packet = packet / r - if StartingTime_presence is 1: - s = StartingTimeHdr(ieiST=0x7C, eightBitST=0x0) - packet = packet / s - if FrequencyList_presence1 is 1: - t = FrequencyListHdr(ieiFL=0x19, eightBitFL=0x0) - packet = packet / t - if ChannelDescription2_presence is 1: - u = ChannelDescription2Hdr(ieiCD2=0x1C, eightBitCD2=0x0) - packet = packet / u - if ChannelDescription_presence is 1: - v = ChannelDescriptionHdr(ieiCD=0x1D, eightBitCD=0x0) - packet = packet / v - if FrequencyChannelSequence_presence is 1: - w = FrequencyChannelSequenceHdr(ieiFCS=0x1E, eightBitFCS=0x0) - packet = packet / w - if MobileAllocation_presence1 is 1: - x = MobileAllocationHdr(ieiMA=0x21, eightBitMA=0x0) - packet = packet / x - if CipherModeSetting_presence is 1: - y = CipherModeSettingHdr(ieiCMS=0x9, eightBitCMS=0x0) - packet = packet / y - if VgcsTargetModeIdentication_presence is 1: - z = VgcsTargetModeIdenticationHdr(ieiVTMI=0x01, eightBitVTMI=0x0) - packet = packet / z - if MultiRateConfiguration_presence is 1: - aa = MultiRateConfigurationHdr(ieiMRC=0x03, eightBitMRC=0x0) - packet = packet / aa - return packet - - -# MS to Network -def assignmentComplete(): - """ASSIGNMENT COMPLETE Section 9.1.3""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x29) # 00101001 - c = RrCause() - packet = a / b / c - return packet - - -# MS to Network -def assignmentFailure(): - """ASSIGNMENT FAILURE Section 9.1.4""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x2F) # 00101111 - c = RrCause() - packet = a / b / c - return packet - - -# Network to MS -def channelModeModify(VgcsTargetModeIdentication_presence=0, - MultiRateConfiguration_presence=0): - """CHANNEL MODE MODIFY Section 9.1.5""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x8) # 0001000 - c = ChannelDescription2() - d = ChannelMode() - packet = a / b / c / d - if VgcsTargetModeIdentication is 1: - e = VgcsTargetModeIdenticationHdr(ieiVTMI=0x01, eightBitVTMI=0x0) - packet = packet / e - if MultiRateConfiguration is 1: - f = MultiRateConfigurationHdr(ieiMRC=0x03, eightBitMRC=0x0) - packet = packet / f - return packet - - -def channelModeModifyAcknowledge(): - """CHANNEL MODE MODIFY ACKNOWLEDGE Section 9.1.6""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x17) # 00010111 - c = ChannelDescription2() - d = ChannelMode() - packet = a / b / c / d - return packet - - -# Network to MS -def channelRelease(BaRange_presence=0, GroupChannelDescription_presence=0, - GroupCipherKeyNumber_presence=0, GprsResumption_presence=0, - BaListPref_presence=0): - """CHANNEL RELEASE Section 9.1.7""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0xD) # 00001101 - c = RrCause() - packet = a / b / c - if BaRange_presence is 1: - d = BaRangeHdr(ieiBR=0x73, eightBitBR=0x0) - packet = packet / d - if GroupChannelDescription_presence is 1: - e = GroupChannelDescriptionHdr(ieiGCD=0x74, eightBitGCD=0x0) - packet = packet / e - if GroupCipherKeyNumber_presence is 1: - f = GroupCipherKeyNumber(ieiGCKN=0x8) - packet = packet / f - if GprsResumption_presence is 1: - g = GprsResumptionHdr(ieiGR=0xC, eightBitGR=0x0) - packet = packet / g - if BaListPref_presence is 1: - h = BaListPrefHdr(ieiBLP=0x75, eightBitBLP=0x0) - packet = packet / h - return packet - - -class ChannelRequest(Packet): - """Channel request Section 9.1.8""" - name = "Channel Request" - fields_desc = [ - ByteField("estCause", 0x0) - ] - - -def channelRequest(): - return ChannelRequest() - - -# Network to MS -def cipheringModeCommand(): - """CIPHERING MODE COMMAND Section 9.1.9""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x35) # 00110101 - c = RrCause() - #d=cipherModeSetting() - #e=cipherResponse() - # FIX - d = CipherModeSettingAndcipherResponse() - packet = a / b / c / d - return packet - - -def cipheringModeComplete(MobileId_presence=0): - """CIPHERING MODE COMPLETE Section 9.1.10""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x32) # 00110010 - packet = a / b - if MobileId_presence is 1: - c = MobileIdHdr(ieiMI=0x17, eightBitMI=0x0) - packet = packet / c - return packet - - -# Network to MS -def classmarkChange(MobileStationClassmark3_presence=0): - """CLASSMARK CHANGE Section 9.1.11""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x16) # 00010110 - c = MobileStationClassmark2() - packet = a / b / c - if MobileStationClassmark3_presence is 1: - e = MobileStationClassmark3(ieiMSC3=0x20) - packet = packet / e - return packet - - -# Network to MS -def classmarkEnquiry(): - """CLASSMARK ENQUIRY Section 9.1.12""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x13) # 00010011 - packet = a / b - return packet -# 9.1.12a Spare - - -# Network to MS -def configurationChangeCommand(ChannelMode_presence=0, - ChannelMode_presence1=0, - ChannelMode_presence2=0, - ChannelMode_presence3=0, - ChannelMode_presence4=0, - ChannelMode_presence5=0, - ChannelMode_presence6=0, - ChannelMode_presence7=0): - """CONFIGURATION CHANGE COMMAND Section 9.1.12b""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x30) # 00110000 - c = MultislotAllocation() - packet = a / b / c - if ChannelMode_presence is 1: - d = ChannelModeHdr(ieiCM=0x63, eightBitCM=0x0) - packet = packet / d - if ChannelMode_presence1 is 1: - e = ChannelModeHdr(ieiCM=0x11, eightBitCM=0x0) - packet = packet / e - if ChannelMode_presence2 is 1: - f = ChannelModeHdr(ieiCM=0x13, eightBitCM=0x0) - packet = packet / f - if ChannelMode_presence3 is 1: - g = ChannelModeHdr(ieiCM=0x14, eightBitCM=0x0) - packet = packet / g - if ChannelMode_presence4 is 1: - h = ChannelModeHdr(ieiCM=0x15, eightBitCM=0x0) - packet = packet / h - if ChannelMode_presence5 is 1: - i = ChannelModeHdr(ieiCM=0x16, eightBitCM=0x0) - packet = packet / i - if ChannelMode_presence6 is 1: - j = ChannelModeHdr(ieiCM=0x17, eightBitCM=0x0) - packet = packet / j - if ChannelMode_presence7 is 1: - k = ChannelModeHdr(ieiCM=0x18, eightBitCM=0x0) - packet = packet / k - return packet - - -def configurationChangeAcknowledge(): - """CONFIGURATION CHANGE ACKNOWLEDGE Section 9.1.12c""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x31) # 00110001 - c = MobileId() - packet = a / b / c - return packet - - -def configurationChangeReject(): - """CONFIGURATION CHANGE REJECT Section 9.1.12d""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x33) # 00110011 - c = RrCause() - packet = a / b / c - return packet - - -# Network to MS -def frequencyRedefinition(CellChannelDescription_presence=0): - """Frequency redefinition Section 9.1.13""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x14) # 00010100 - c = ChannelDescription() - d = MobileAllocation() - e = StartingTime() - packet = a / b / c / d / e - if CellChannelDescription_presence is 1: - f = CellChannelDescriptionHdr(ieiCCD=0x62, eightBitCCD=0x0) - packet = packet / f - return packet - - -# Network to MS -def pdchAssignmentCommand(ChannelDescription_presence=0, - CellChannelDescription_presence=0, - MobileAllocation_presence=0, - StartingTime_presence=0, FrequencyList_presence=0, - ChannelDescription_presence1=0, - FrequencyChannelSequence_presence=0, - MobileAllocation_presence1=0, - PacketChannelDescription_presence=0, - DedicatedModeOrTBF_presence=0): - """PDCH ASSIGNMENT COMMAND Section 9.1.13a""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x23) # 00100011 - c = ChannelDescription() - packet = a / b / c - if ChannelDescription_presence is 1: - d = ChannelDescriptionHdr(ieiCD=0x62, eightBitCD=0x0) - packet = packet / d - if CellChannelDescription_presence is 1: - e = CellChannelDescriptionHdr(ieiCCD=0x05, eightBitCCD=0x0) - packet = packet / e - if MobileAllocation_presence is 1: - f = MobileAllocationHdr(ieiMA=0x72, eightBitMA=0x0) - packet = packet / f - if StartingTime_presence is 1: - g = StartingTimeHdr(ieiST=0x7C, eightBitST=0x0) - packet = packet / g - if FrequencyList_presence is 1: - h = FrequencyListHdr(ieiFL=0x19, eightBitFL=0x0) - packet = packet / h - if ChannelDescription_presence1 is 1: - i = ChannelDescriptionHdr(ieiCD=0x1C, eightBitCD=0x0) - packet = packet / i - if FrequencyChannelSequence_presence is 1: - j = FrequencyChannelSequenceHdr(ieiFCS=0x1E, eightBitFCS=0x0) - packet = packet / j - if MobileAllocation_presence1 is 1: - k = MobileAllocationHdr(ieiMA=0x21, eightBitMA=0x0) - packet = packet / k - if PacketChannelDescription_presence is 1: - l = PacketChannelDescription(ieiPCD=0x22) - packet = packet / l - if DedicatedModeOrTBF_presence is 1: - m = DedicatedModeOrTBFHdr(ieiDMOT=0x23, eightBitDMOT=0x0) - packet = packet / m - return packet - - -def gprsSuspensionRequest(): - """GPRS SUSPENSION REQUEST Section 9.1.13b""" - a = TpPd(pd=0x6) - b = MessageType() - c = Tlli() - d = RoutingAreaIdentification() - e = SuspensionCause() - packet = a / b / c / d / e - return packet - - -class HandoverAccess(Packet): - name = "Handover Access" # Section 9.1.14" - fields_desc = [ - ByteField("handover", None), - ] - - -# Network to MS -def handoverCommand(SynchronizationIndication_presence=0, - FrequencyShortList_presence=0, FrequencyList_presence=0, - CellChannelDescription_presence=0, - MultislotAllocation_presence=0, - ChannelMode_presence=0, ChannelMode_presence1=0, - ChannelMode_presence2=0, - ChannelMode_presence3=0, ChannelMode_presence4=0, - ChannelMode_presence5=0, - ChannelMode_presence6=0, ChannelMode_presence7=0, - ChannelDescription_presence1=0, ChannelMode2_presence=0, - FrequencyChannelSequence_presence=0, - MobileAllocation_presence=0, - StartingTime_presence=0, TimeDifference_presence=0, - TimingAdvance_presence=0, - FrequencyShortList_presence1=0, - FrequencyList_presence1=0, - ChannelDescription2_presence=0, - ChannelDescription_presence2=0, - FrequencyChannelSequence_presence1=0, - MobileAllocation_presence1=0, - CipherModeSetting_presence=0, - VgcsTargetModeIdentication_presence=0, - MultiRateConfiguration_presence=0): - """HANDOVER COMMAND Section 9.1.15""" - name = "Handover Command" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x2b) # 00101011 - c = CellDescription() - d = ChannelDescription2() - e = HandoverReference() - f = PowerCommandAndAccessType() - packet = a / b / c / d / e / f - if SynchronizationIndication_presence is 1: - g = SynchronizationIndicationHdr(ieiSI=0xD, eightBitSI=0x0) - packet = packet / g - if FrequencyShortList_presence is 1: - h = FrequencyShortListHdr(ieiFSL=0x02) - packet = packet / h - if FrequencyList_presence is 1: - i = FrequencyListHdr(ieiFL=0x05, eightBitFL=0x0) - packet = packet / i - if CellChannelDescription_presence is 1: - j = CellChannelDescriptionHdr(ieiCCD=0x62, eightBitCCD=0x0) - packet = packet / j - if MultislotAllocation_presence is 1: - k = MultislotAllocationHdr(ieiMSA=0x10, eightBitMSA=0x0) - packet = packet / k - if ChannelMode_presence is 1: - l = ChannelModeHdr(ieiCM=0x63, eightBitCM=0x0) - packet = packet / l - if ChannelMode_presence1 is 1: - m = ChannelModeHdr(ieiCM=0x11, eightBitCM=0x0) - packet = packet / m - if ChannelMode_presence2 is 1: - n = ChannelModeHdr(ieiCM=0x13, eightBitCM=0x0) - packet = packet / n - if ChannelMode_presence3 is 1: - o = ChannelModeHdr(ieiCM=0x14, eightBitCM=0x0) - packet = packet / o - if ChannelMode_presence4 is 1: - p = ChannelModeHdr(ieiCM=0x15, eightBitCM=0x0) - packet = packet / p - if ChannelMode_presence5 is 1: - q = ChannelModeHdr(ieiCM=0x16, eightBitCM=0x0) - packet = packet / q - if ChannelMode_presence6 is 1: - r = ChannelModeHdr(ieiCM=0x17, eightBitCM=0x0) - packet = packet / r - if ChannelMode_presence7 is 1: - s = ChannelModeHdr(ieiCM=0x18, eightBitCM=0x0) - packet = packet / s - if ChannelDescription_presence1 is 1: - s1 = ChannelDescriptionHdr(ieiCD=0x64, eightBitCD=0x0) - packet = packet / s1 - if ChannelMode2_presence is 1: - t = ChannelMode2Hdr(ieiCM2=0x66, eightBitCM2=0x0) - packet = packet / t - if FrequencyChannelSequence_presence is 1: - u = FrequencyChannelSequenceHdr(ieiFCS=0x69, eightBitFCS=0x0) - packet = packet / u - if MobileAllocation_presence is 1: - v = MobileAllocationHdr(ieiMA=0x72, eightBitMA=0x0) - packet = packet / v - if StartingTime_presence is 1: - w = StartingTimeHdr(ieiST=0x7C, eightBitST=0x0) - packet = packet / w - if TimeDifference_presence is 1: - x = TimeDifferenceHdr(ieiTD=0x7B, eightBitTD=0x0) - packet = packet / x - if TimingAdvance_presence is 1: - y = TimingAdvanceHdr(ieiTA=0x7D, eightBitTA=0x0) - packet = packet / y - if FrequencyShortList_presence1 is 1: - z = FrequencyShortListHdr(ieiFSL=0x12) - packet = packet / z - if FrequencyList_presence1 is 1: - aa = FrequencyListHdr(ieiFL=0x19, eightBitFL=0x0) - packet = packet / aa - if ChannelDescription2_presence is 1: - ab = ChannelDescription2Hdr(ieiCD2=0x1C, eightBitCD2=0x0) - packet = packet / ab - if ChannelDescription_presence2 is 1: - ac = ChannelDescriptionHdr(ieiCD=0x1D, eightBitCD=0x0) - packet = packet / ac - if FrequencyChannelSequence_presence1 is 1: - ad = FrequencyChannelSequenceHdr(ieiFCS=0x1E, eightBitFCS=0x0) - packet = packet / ad - if MobileAllocation_presence1 is 1: - ae = MobileAllocationHdr(ieiMA=0x21, eightBitMA=0x0) - packet = packet / ae - if CipherModeSetting_presence is 1: - af = CipherModeSettingHdr(ieiCMS=0x9, eightBitCMS=0x0) - packet = packet / af - if VgcsTargetModeIdentication_presence is 1: - ag = VgcsTargetModeIdenticationHdr(ieiVTMI=0x01, eightBitVTMI=0x0) - packet = packet / ag - if MultiRateConfiguration_presence is 1: - ah = MultiRateConfigurationHdr(ieiMRC=0x03, eightBitMRC=0x0) - packet = packet / ah - return packet - - -def handoverComplete(MobileTimeDifference_presence=0): - """HANDOVER COMPLETE Section 9.1.16""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x2c) # 00101100 - c = RrCause() - packet = a / b / c - if MobileTimeDifference_presence is 1: - d = MobileTimeDifferenceHdr(ieiMTD=0x77, eightBitMTD=0x0) - packet = packet / d - return packet - - -def handoverFailure(): - """HANDOVER FAILURE Section 9.1.17""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x28) # 00101000 - c = RrCause() - packet = a / b / c - return packet - - -#The L2 pseudo length of this message is the sum of lengths of all -#information elements present in the message except -#the IA Rest Octets and L2 Pseudo Length information elements. -# Network to MS -def immediateAssignment(ChannelDescription_presence=0, - PacketChannelDescription_presence=0, - StartingTime_presence=0): - """IMMEDIATE ASSIGNMENT Section 9.1.18""" - a = L2PseudoLength() - b = TpPd(pd=0x6) - c = MessageType(mesType=0x3F) # 00111111 - d = PageModeAndDedicatedModeOrTBF() - packet = a / b / c / d - if ChannelDescription_presence is 1: - f = ChannelDescription() - packet = packet / f - if PacketChannelDescription_presence is 1: - g = PacketChannelDescription() - packet = packet / g - h = RequestReference() - i = TimingAdvance() - j = MobileAllocation() - packet = packet / h / i / j - if StartingTime_presence is 1: - k = StartingTimeHdr(ieiST=0x7C, eightBitST=0x0) - packet = packet / k - l = IaRestOctets() - packet = packet / l - return packet - - -#The L2 pseudo length of this message is the sum of lengths of all -#information elements present in the message except -#the IAX Rest Octets and L2 Pseudo Length information elements. - -# Network to MS -def immediateAssignmentExtended(StartingTime_presence=0): - """IMMEDIATE ASSIGNMENT EXTENDED Section 9.1.19""" - a = L2PseudoLength() - b = TpPd(pd=0x6) - c = MessageType(mesType=0x39) # 00111001 - d = PageModeAndSpareHalfOctets() - f = ChannelDescription() - g = RequestReference() - h = TimingAdvance() - i = MobileAllocation() - packet = a / b / c / d / f / g / h / i - if StartingTime_presence is 1: - j = StartingTimeHdr(ieiST=0x7C, eightBitST=0x0) - packet = packet / j - k = IaxRestOctets() - packet = packet / k - return packet - - -# This message has L2 pseudo length 19 -# Network to MS -def immediateAssignmentReject(): - """IMMEDIATE ASSIGNMENT REJECT Section 9.1.20""" - a = L2PseudoLength(l2pLength=0x13) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x3a) # 00111010 - d = PageModeAndSpareHalfOctets() - f = RequestReference() - g = WaitIndication() - h = RequestReference() - i = WaitIndication() - j = RequestReference() - k = WaitIndication() - l = RequestReference() - m = WaitIndication() - n = IraRestOctets() - packet = a / b / c / d / f / g / h / i / j / k / l / m / n - return packet - - -def measurementReport(): - """MEASUREMENT REPORT Section 9.1.21""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x15) # 00010101 - c = MeasurementResults() - packet = a / b / c - return packet - - -# len max 20 -class NotificationFacch(): - """NOTIFICATION/FACCH Section 9.1.21a""" - name = "Notification/facch" - fields_desc = [ - BitField("rr", 0x0, 1), - BitField("msgTyoe", 0x0, 5), - BitField("layer2Header", 0x0, 2), - BitField("frChanDes", 0x0, 24) - ] - - -# The L2 pseudo length of this message has a value one -# Network to MS -def notificationNch(): - """NOTIFICATION/NCH Section 9.1.21b""" - a = L2PseudoLength(l2pLength=0x01) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x20) # 00100000 - d = NtNRestOctets() - packet = a / b / c / d - return packet - - -def notificationResponse(): - """NOTIFICATION RESPONSE Section 9.1.21d""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x26) # 00100110 - c = MobileStationClassmark2() - d = MobileId() - e = DescriptiveGroupOrBroadcastCallReference() - packet = a / b / c / d / e - return packet - - -# Network to MS -def rrCellChangeOrder(): - """RR-CELL CHANGE ORDER Section 9.1.21e""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x8) # 00001000 - c = CellDescription() - d = NcModeAndSpareHalfOctets() - packet = a / b / c / d - return packet - - -# Network to MS -def pagingRequestType1(MobileId_presence=0): - """PAGING REQUEST TYPE 1 Section 9.1.22""" - #The L2 pseudo length of this message is the sum of lengths of all - #information elements present in the message except - #the P1 Rest Octets and L2 Pseudo Length information elements. - a = L2PseudoLength() - b = TpPd(pd=0x6) - c = MessageType(mesType=0x21) # 00100001 - d = PageModeAndChannelNeeded() - f = MobileId() - packet = a / b / c / d / f - if MobileId_presence is 1: - g = MobileIdHdr(ieiMI=0x17, eightBitMI=0x0) - packet = packet / g - h = P1RestOctets() - packet = packet / h - return packet - - -# The L2 pseudo length of this message is the sum of lengths of all -# information elements present in the message except -# Network to MS -def pagingRequestType2(MobileId_presence=0): - """PAGING REQUEST TYPE 2 Section 9.1.23""" - a = L2PseudoLength() - b = TpPd(pd=0x6) - c = MessageType(mesType=0x22) # 00100010 - d = PageModeAndChannelNeeded() - f = MobileId() - g = MobileId() - packet = a / b / c / d / f / g - if MobileId_presence is 1: - h = MobileIdHdr(ieiMI=0x17, eightBitMI=0x0) - packet = packet / h - i = P2RestOctets() - packet = packet / i - return packet - - -# Network to MS -def pagingRequestType3(): - """PAGING REQUEST TYPE 3 Section 9.1.24""" -# This message has a L2 Pseudo Length of 19 - a = L2PseudoLength(l2pLength=0x13) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x24) # 00100100 - d = PageModeAndChannelNeeded() - e = TmsiPTmsi() - f = TmsiPTmsi() - g = TmsiPTmsi() - h = TmsiPTmsi() - i = P3RestOctets() - packet = a / b / c / d / e / f / g / h / i - return packet - - -def pagingResponse(): - """PAGING RESPONSE Section 9.1.25""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x27) # 00100111 - c = CiphKeySeqNrAndSpareHalfOctets() - d = MobileStationClassmark2() - e = MobileId() - packet = a / b / c / d / e - return packet - - -# Network to MS -def partialRelease(): - """PARTIAL RELEASE Section 9.1.26""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0xa) # 00001010 - c = ChannelDescription() - packet = a / b / c - return packet - - -def partialReleaseComplete(): - """PARTIAL RELEASE COMPLETE Section 9.1.27""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0xf) # 00001111 - packet = a / b - return packet - - -# Network to MS -def physicalInformation(): - """PHYSICAL INFORMATION Section 9.1.28""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x2d) # 00101101 - c = TimingAdvance() - packet = a / b / c - return packet - - -def rrInitialisationRequest(): - """RR Initialisation Request Section 9.1.28.a""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x3c) # 00111100 - c = CiphKeySeqNrAndMacModeAndChannelCodingRequest() - e = MobileStationClassmark2() - f = Tlli() - g = ChannelRequestDescription() - h = GprsMeasurementResults() - packet = a / b / c / e / f / g / h - return packet - - -def rrStatus(): - """RR STATUS Section 9.1.29""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x12) # 00010010 - c = RrCause() - packet = a / b / c - return packet - - -# It does not -# follow the basic format. Its length is _25_ bits. The -# order of bit transmission is defined in GSM 04.04. -# Network to MS -class SynchronizationChannelInformation(): - """SYNCHRONIZATION CHANNEL INFORMATION Section 9.1.30""" - name = "Synchronization Channel Information" - fields_desc = [ - BitField("bsic", 0x0, 5), - BitField("t1Hi", 0x0, 3), - ByteField("t1Mi", 0x0), - BitField("t1Lo", 0x0, 1), - BitField("t2", 0x0, 5), - BitField("t3Hi", 0x0, 2), - BitField("t3Lo", 0x0, 1) - ] - - -# This message has a L2 Pseudo Length of 21. -# Network to MS -def systemInformationType1(): - """SYSTEM INFORMATION TYPE 1 Section 9.1.31""" - a = L2PseudoLength(l2pLength=0x15) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x19) # 00011001 - d = CellChannelDescription() - e = RachControlParameters() - f = Si1RestOctets() - packet = a / b / c / d / e / f - return packet - - -# This message has a L2 Pseudo Length of 22. -# Network to MS -def systemInformationType2(): - """SYSTEM INFORMATION TYPE 2 Section 9.1.32""" - a = L2PseudoLength(l2pLength=0x16) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x1a) # 00011010 - d = NeighbourCellsDescription() - e = NccPermitted() - f = RachControlParameters() - packet = a / b / c / d / e / f - return packet - - -# This message has a L2 pseudo length of 21 -# Network to MS -def systemInformationType2bis(): - """SYSTEM INFORMATION TYPE 2bis Section 9.1.33""" - a = L2PseudoLength(l2pLength=0x15) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x2) # 00000010 - d = NeighbourCellsDescription() - e = RachControlParameters() - f = Si2bisRestOctets() - packet = a / b / c / d / e / f - return packet - - -# This message has a L2 pseudo length of 18 -# Network to MS -def systemInformationType2ter(): - """SYSTEM INFORMATION TYPE 2ter Section 9.1.34""" - a = L2PseudoLength(l2pLength=0x12) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x3) # 00000011 - d = NeighbourCellsDescription2() - e = Si2terRestOctets() - packet = a / b / c / d / e - return packet - - -# This message has a L2 Pseudo Length of 18 -# Network to MS -def systemInformationType3(): - """SYSTEM INFORMATION TYPE 3 Section 9.1.35""" - a = L2PseudoLength(l2pLength=0x12) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x1b) # 00011011 - d = CellIdentity() - e = LocalAreaId() - f = ControlChannelDescription() - g = CellOptionsBCCH() - h = CellSelectionParameters() - i = RachControlParameters() - j = Si3RestOctets() - packet = a / b / c / d / e / f / g / h / i / j - return packet - - -#The L2 pseudo length of this message is the -#sum of lengths of all information elements present in the message except -#the SI 4 Rest Octets and L2 Pseudo Length -# Network to MS -def systemInformationType4(ChannelDescription_presence=0, - MobileAllocation_presence=0): - """SYSTEM INFORMATION TYPE 4 Section 9.1.36""" - a = L2PseudoLength() - b = TpPd(pd=0x6) - c = MessageType(mesType=0x1C) # 000111100 - d = LocalAreaId() - e = CellSelectionParameters() - f = RachControlParameters() - packet = a / b / c / d / e / f - if ChannelDescription_presence is 1: - g = ChannelDescriptionHdr(ieiCD=0x64, eightBitCD=0x0) - packet = packet / g - if MobileAllocation_presence is 1: - h = MobileAllocationHdr(ieiMA=0x72, eightBitMA=0x0) - packet = packet / h - i = Si4RestOctets() - packet = packet / i - return packet - - -#This message has a L2 Pseudo Length of 18 -# Network to MS -def systemInformationType5(): - """SYSTEM INFORMATION TYPE 5 Section 9.1.37""" - a = L2PseudoLength(l2pLength=0x12) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x35) # 000110101 - d = NeighbourCellsDescription() - packet = a / b / c / d - return packet - - -#This message has a L2 Pseudo Length of 18 -# Network to MS -def systemInformationType5bis(): - """SYSTEM INFORMATION TYPE 5bis Section 9.1.38""" - a = L2PseudoLength(l2pLength=0x12) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x5) # 00000101 - d = NeighbourCellsDescription() - packet = a / b / c / d - return packet - - -# This message has a L2 Pseudo Length of 18 -# Network to MS -def systemInformationType5ter(): - """SYSTEM INFORMATION TYPE 5ter Section 9.1.39""" - a = L2PseudoLength(l2pLength=0x12) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x6) # 00000110 - d = NeighbourCellsDescription2() - packet = a / b / c / d - return packet - - -#This message has a L2 Pseudo Length of 11 -# Network to MS -def systemInformationType6(): - """SYSTEM INFORMATION TYPE 6 Section 9.1.40""" - a = L2PseudoLength(l2pLength=0x0b) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x1e) # 00011011 - d = CellIdentity() - e = LocalAreaId() - f = CellOptionsBCCH() - g = NccPermitted() - h = Si6RestOctets() - packet = a / b / c / d / e / f / g - return packet - - -# The L2 pseudo length of this message has the value 1 -# Network to MS -def systemInformationType7(): - """SYSTEM INFORMATION TYPE 7 Section 9.1.41""" - a = L2PseudoLength(l2pLength=0x01) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x37) # 000110111 - d = Si7RestOctets() - packet = a / b / c / d - return packet - - -# The L2 pseudo length of this message has the value 1 -# Network to MS -def systemInformationType8(): - """SYSTEM INFORMATION TYPE 8 Section 9.1.42""" - a = L2PseudoLength(l2pLength=0x01) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x18) # 00011000 - d = Si8RestOctets() - packet = a / b / c / d - return packet - - -# The L2 pseudo length of this message has the value 1 -# Network to MS -def systemInformationType9(): - """SYSTEM INFORMATION TYPE 9 Section 9.1.43""" - a = L2PseudoLength(l2pLength=0x01) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x4) # 00000100 - d = Si9RestOctets() - packet = a / b / c / d - return packet - - -# The L2 pseudo length of this message has the value 0 -# Network to MS -def systemInformationType13(): - """SYSTEM INFORMATION TYPE 13 Section 9.1.43a""" - a = L2PseudoLength(l2pLength=0x00) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x0) # 00000000 - d = Si13RestOctets() - packet = a / b / c / d - return packet -# -# 9.1.43b / c spare -# - - -# The L2 pseudo length of this message has the value 1 -# Network to MS -def systemInformationType16(): - """SYSTEM INFORMATION TYPE 16 Section 9.1.43d""" - a = L2PseudoLength(l2pLength=0x01) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x3d) # 00111101 - d = Si16RestOctets() - packet = a / b / c / d - return packet - - -# The L2 pseudo length of this message has the value 1 -# Network to MS -def systemInformationType17(): - """SYSTEM INFORMATION TYPE 17 Section 9.1.43e""" - a = L2PseudoLength(l2pLength=0x01) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x3e) # 00111110 - d = Si17RestOctets() - packet = a / b / c / d - return packet - - -def talkerIndication(): - """TALKER INDICATION Section 9.1.44""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x11) # 00010001 - c = MobileStationClassmark2() - d = MobileId() - packet = a / b / c / d - return packet - - -class UplinkAccess(): - """UPLINK ACCESS Section 9.1.45""" - name = "Uplink Access" - fields_desc = [ - ByteField("establishment", 0x0) - ] - - -# Network to MS -def uplinkBusy(): - """UPLINK BUSY Section 9.1.46""" - name = "Uplink Busy" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x2a) # 00101010 - packet = a / b - return packet - - -# Network to MS -class UplinkFree(): - """UPLINK FREE Section 9.1.47""" - name = "Uplink Free" - fields_desc = [ - BitField("pd", 0x0, 1), - BitField("msgType", 0x0, 5), - BitField("layer2Header", 0x0, 2), - BitField("uplinkAccess", 0x0, 1), - BitField("lOrH", 0x0, 1), # 0 for L, 1 for H - BitField("upIdCode", 0x0, 6), - ] - - -def uplinkRelease(): - """UPLINK RELEASE Section 9.1.48""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0xe) # 00001110 - c = RrCause() - packet = a / b / c - return packet - - -# Network to MS -def vgcsUplinkGrant(): - """VGCS UPLINK GRANT Section 9.1.49""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x9) # 00001001 - c = RrCause() - d = RequestReference() - e = TimingAdvance() - packet = a / b / c / d / e - return packet - - -# Network to MS -def systemInformationType10(): - """SYSTEM INFORMATION TYPE 10 Section 9.1.50""" - name = "SyStem Information Type 10" - fields_desc = [ - BitField("pd", 0x0, 1), - BitField("msgType", 0x0, 5), - BitField("layer2Header", 0x0, 2), - BitField("si10", 0x0, 160) - ] - - -# Network to MS -# The L2 pseudo length of this message has the value 18 -def extendedMeasurementOrder(): - """EXTENDED MEASUREMENT ORDER Section 9.1.51""" - a = L2PseudoLength(l2pLength=0x12) - b = TpPd(pd=0x6) - c = MessageType(mesType=0x37) # 00110111 - d = ExtendedMeasurementFrequencyList() - packet = a / b / c / d - return packet - - -def extendedMeasurementReport(): - """EXTENDED MEASUREMENT REPORT Section 9.1.52""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x36) # 00110110 - c = ExtendedMeasurementResults() - packet = a / b / c - return packet - - -def applicationInformation(): - """APPLICATION INFORMATION Section 9.1.53""" - a = TpPd(pd=0x6) - b = MessageType(mesType=0x38) # 00111000 - c = ApduIDAndApduFlags() - e = ApduData() - packet = a / b / c / e - return packet -# -# 9.2 Messages for mobility management -# - - -# Network to MS -def authenticationReject(): - """AUTHENTICATION REJECT Section 9.2.1""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x11) # 00010001 - packet = a / b - return packet - - -# Network to MS -def authenticationRequest(): - """AUTHENTICATION REQUEST Section 9.2.2""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x12) # 00010010 - c = CiphKeySeqNrAndSpareHalfOctets() - d = AuthenticationParameterRAND() - packet = a / b / c / d - return packet - - -def authenticationResponse(): - """AUTHENTICATION RESPONSE Section 9.2.3""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x14) # 00010100 - c = AuthenticationParameterSRES() - packet = a / b / c - return packet - - -def cmReestablishmentRequest(LocalAreaId_presence=0): - """CM RE-ESTABLISHMENT REQUEST Section 9.2.4""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x28) # 00101000 - c = CiphKeySeqNrAndSpareHalfOctets() - e = MobileStationClassmark2() - f = MobileId() - if LocalAreaId_presence is 1: - g = LocalAreaId(iei=0x13, eightbit=0x0) - packet = packet / g - packet = a / b / c / e / f - return packet - - -# Network to MS -def cmServiceAccept(): - """CM SERVICE ACCEPT Section 9.2.5""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x21) # 00100001 - packet = a / b - return packet - - -# Network to MS -def cmServicePrompt(): - """CM SERVICE PROMPT Section 9.2.5a""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x25) # 00100101 - c = PdAndSapi() - packet = a / b / c - return packet - - -# Network to MS -def cmServiceReject(): - """CM SERVICE REJECT Section 9.2.6""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x22) # 00100010 - c = RejectCause() - packet = a / b / c - return packet - - -def cmServiceAbort(): - """CM SERVICE ABORT Section 9.2.7""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x23) # 00100011 - packet = a / b - return packet - - -# Network to MS -def abort(): - """ABORT Section 9.2.8""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x29) # 00101001 - c = RejectCause() - packet = a / b / c - return packet - - -def cmServiceRequest(PriorityLevel_presence=0): - """CM SERVICE REQUEST Section 9.2.9""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x24) # 00100100 - c = CmServiceTypeAndCiphKeySeqNr() - e = MobileStationClassmark2() - f = MobileId() - packet = a / b / c / e / f - if PriorityLevel_presence is 1: - g = PriorityLevelHdr(ieiPL=0x8, eightBitPL=0x0) - packet = packet / g - return packet - - -# Network to MS -def identityRequest(): - """IDENTITY REQUEST Section 9.2.10""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x8) # 00001000 - c = IdentityTypeAndSpareHalfOctets() - packet = a / b / c - return packet - - -def identityResponse(): - """IDENTITY RESPONSE Section 9.2.11""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x9) # 00001001 - c = MobileId() - packet = a / b / c - return packet - - -def imsiDetachIndication(): - """IMSI DETACH INDICATION Section 9.2.12""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x1) # 00000001 - c = MobileStationClassmark1() - d = MobileId() - packet = a / b / c / d - return packet - - -# Network to MS -def locationUpdatingAccept(MobileId_presence=0, - FollowOnProceed_presence=0, - CtsPermission_presence=0): - """LOCATION UPDATING ACCEPT Section 9.2.13""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x02) # 00000010 - c = LocalAreaId() - packet = a / b / c - if MobileId_presence is 1: - d = MobileIdHdr(ieiMI=0x17, eightBitMI=0x0) - packet = packet / d - if FollowOnProceed_presence is 1: - e = FollowOnProceed(ieiFOP=0xA1) - packet = packet / e - if CtsPermission_presence is 1: - f = CtsPermissionHdr(ieiCP=0xA2, eightBitCP=0x0) - packet = packet / f - return packet - - -# Network to MS -def locationUpdatingReject(): - """LOCATION UPDATING REJECT Section 9.2.14""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x4) # 0x00000100 - c = RejectCause() - packet = a / b / c - return packet - - -def locationUpdatingRequest(): - """LOCATION UPDATING REQUEST Section 9.2.15""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x8) # 00001000 - c = LocationUpdatingTypeAndCiphKeySeqNr() - e = LocalAreaId() - f = MobileStationClassmark1() - g = MobileId() - packet = a / b / c / e / f / g - return packet - - -# Network to MS -def mmInformation(NetworkName_presence=0, NetworkName_presence1=0, - TimeZone_presence=0, TimeZoneAndTime_presence=0, - LsaIdentifier_presence=0): - """MM INFORMATION Section 9.2.15a""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x32) # 00110010 - packet = a / b - if NetworkName_presence is 1: - c = NetworkNameHdr(ieiNN=0x43, eightBitNN=0x0) - packet = packet / c - if NetworkName_presence1 is 1: - d = NetworkNameHdr(ieiNN=0x45, eightBitNN=0x0) - packet = packet / d - if TimeZone_presence is 1: - e = TimeZoneHdr(ieiTZ=0x46, eightBitTZ=0x0) - packet = packet / e - if TimeZoneAndTime_presence is 1: - f = TimeZoneAndTimeHdr(ieiTZAT=0x47, eightBitTZAT=0x0) - packet = packet / f - if LsaIdentifier_presence is 1: - g = LsaIdentifierHdr(ieiLI=0x48, eightBitLI=0x0) - packet = packet / g - return packet - - -def mmStatus(): - """MM STATUS Section 9.2.16""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x31) # 00110001 - c = RejectCause() - packet = a / b / c - return packet - - -# Network to MS -def tmsiReallocationCommand(): - """TMSI REALLOCATION COMMAND Section 9.2.17""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x1a) # 00011010 - c = LocalAreaId() - d = MobileId() - packet = a / b / c / d - return packet - - -def tmsiReallocationComplete(): - """TMSI REALLOCATION COMPLETE Section 9.2.18""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x1b) # 00011011 - packet = a / b - return packet - - -def mmNull(): - """MM NULL Section 9.2.19""" - a = TpPd(pd=0x5) - b = MessageType(mesType=0x30) # 00110000 - packet = a / b - return packet - -# -# 9.3 Messages for circuit-switched call control -# - - -# Network to MS -def alertingNetToMs(Facility_presence=0, ProgressIndicator_presence=0, - UserUser_presence=0): - """ALERTING Section 9.3.1.1""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x1) # 00000001 - packet = a / b - if Facility_presence is 1: - c = FacilityHdr(ieiF=0x1C) - packet = packet / c - if ProgressIndicator_presence is 1: - d = ProgressIndicatorHdr(ieiPI=0x1E) - packet = packet / d - if UserUser_presence is 1: - e = UserUserHdr(ieiUU=0x7E) - packet = packet / e - return packet - - -def alertingMsToNet(Facility_presence=0, UserUser_presence=0, - SsVersionIndicator_presence=0): - """ALERTING Section 9.3.1.2""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x1) # 00000001 - packet = a / b - if Facility_presence is 1: - c = FacilityHdr(ieiF=0x1C, eightBitF=0x0) - packet = packet / c - if UserUser_presence is 1: - d = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0) - packet = packet / d - if SsVersionIndicator_presence is 1: - e = SsVersionIndicatorHdr(ieiSVI=0x7F, eightBitSVI=0x0) - packet = packet / e - return packet - - -def callConfirmed(RepeatIndicator_presence=0, - BearerCapability_presence=0, BearerCapability_presence1=0, - Cause_presence=0, CallControlCapabilities_presence=0): - """CALL CONFIRMED Section 9.3.2""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x8) # 00001000 - packet = a / b - if RepeatIndicator_presence is 1: - c = RepeatIndicatorHdr(ieiRI=0xD, eightBitRI=0x0) - packet = packet / c - if BearerCapability_presence is 1: - d = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0) - packet = packet / d - if BearerCapability_presence1 is 1: - e = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0) - packet = packet / e - if Cause_presence is 1: - f = CauseHdr(ieiC=0x08, eightBitC=0x0) - packet = packet / f - if CallControlCapabilities_presence is 1: - g = CallControlCapabilitiesHdr(ieiCCC=0x15, eightBitCCC=0x0) - packet = packet / g - return packet - - -# Network to MS -def callProceeding(RepeatIndicator_presence=0, - BearerCapability_presence=0, - BearerCapability_presence1=0, - Facility_presence=0, ProgressIndicator_presence=0, - PriorityLevel_presence=0): - """CALL PROCEEDING Section 9.3.3""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x2) # 00000010 - packet = a / b - if RepeatIndicator_presence is 1: - c = RepeatIndicatorHdr(ieiRI=0xD, eightBitRI=0x0) - packet = packet / c - if BearerCapability_presence is 1: - d = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0) - packet = packet / d - if BearerCapability_presence1 is 1: - e = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0) - packet = packet / e - if Facility_presence is 1: - f = FacilityHdr(ieiF=0x1C, eightBitF=0x0) - packet = packet / f - if ProgressIndicator_presence is 1: - g = ProgressIndicatorHdr(ieiPI=0x1E, eightBitPI=0x0) - packet = packet / g - if PriorityLevel_presence is 1: - h = PriorityLevelHdr(ieiPL=0x80, eightBitPL=0x0) - packet = packet / h - return packet - - -# Network to MS -def congestionControl(Cause_presence=0): - """CONGESTION CONTROL Section 9.3.4""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x39) # 00111001 - c = CongestionLevelAndSpareHalfOctets() - packet = a / b / c - if Cause_presence is 1: - e = CauseHdr(ieiC=0x08, eightBitC=0x0) - packet = packet / e - return packet - - -# Network to MS -def connectNetToMs(Facility_presence=0, ProgressIndicator_presence=0, - ConnectedNumber_presence=0, ConnectedSubaddress_presence=0, - UserUser_presence=0): - """CONNECT Section 9.3.5.1""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x7) # 00000111 - packet = a / b - if Facility_presence is 1: - c = FacilityHdr(ieiF=0x1C, eightBitF=0x0) - packet = packet / c - if ProgressIndicator_presence is 1: - d = ProgressIndicatorHdr(ieiPI=0x1E, eightBitPI=0x0) - packet = packet / d - if ConnectedNumber_presence is 1: - e = ConnectedNumberHdr(ieiCN=0x4C, eightBitCN=0x0) - packet = packet / e - if ConnectedSubaddress_presence is 1: - f = ConnectedSubaddressHdr(ieiCS=0x4D, eightBitCS=0x0) - packet = packet / f - if UserUser_presence is 1: - g = UserUserHdr(ieiUU=0x7F, eightBitUU=0x0) - packet = packet / g - return packet - - -def connectMsToNet(Facility_presence=0, ConnectedSubaddress_presence=0, - UserUser_presence=0, SsVersionIndicator_presence=0): - """CONNECT Section 9.3.5.2""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x7) # 00000111 - packet = a / b - if Facility_presence is 1: - c = FacilityHdr(ieiF=0x1C, eightBitF=0x0) - packet = packet / c - if ConnectedSubaddress_presence is 1: - d = ConnectedSubaddressHdr(ieiCS=0x4D, eightBitCS=0x0) - packet = packet / d - if UserUser_presence is 1: - e = UserUserHdr(ieiUU=0x7F, eightBitUU=0x0) - packet = packet / e - if SsVersionIndicator_presence is 1: - f = SsVersionIndicatorHdr(ieiSVI=0x7F, eightBitSVI=0x0) - packet = packet / f - return packet - - -def connectAcknowledge(): - """CONNECT ACKNOWLEDGE Section 9.3.6""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0xf) # 00001111 - packet = a / b - return packet - - -# Network to MS -def disconnectNetToMs(Facility_presence=0, ProgressIndicator_presence=0, - UserUser_presence=0, AllowedActions_presence=0): - """DISCONNECT Section 9.3.7.1""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x25) # 00100101 - c = Cause() - packet = a / b / c - if Facility_presence is 1: - d = FacilityHdr(ieiF=0x1C, eightBitF=0x0) - packet = packet / d - if ProgressIndicator_presence is 1: - e = ProgressIndicatorHdr(ieiPI=0x1E, eightBitPI=0x0) - packet = packet / e - if UserUser_presence is 1: - f = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0) - packet = packet / f - if AllowedActions_presence is 1: - g = AllowedActionsHdr(ieiAA=0x7B, eightBitAA=0x0) - packet = packet / g - return packet - - -def disconnectMsToNet(Facility_presence=0, UserUser_presence=0, - SsVersionIndicator_presence=0): - """Disconnect Section 9.3.7.2""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x25) # 00100101 - c = Cause() - packet = a / b / c - if Facility_presence is 1: - d = FacilityHdr(ieiF=0x1C, eightBitF=0x0) - packet = packet / d - if UserUser_presence is 1: - e = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0) - packet = packet / e - if SsVersionIndicator_presence is 1: - f = SsVersionIndicatorHdr(ieiSVI=0x7F, eightBitSVI=0x0) - packet = packet / f - return packet - - -def emergencySetup(BearerCapability_presence=0): - """EMERGENCY SETUP Section 9.3.8""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0xe) # 00001110 - packet = a / b - if BearerCapability_presence is 1: - c = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0) - packet = packet / c - return packet - - -# Network to MS -def facilityNetToMs(): - """FACILITY Section 9.3.9.1""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x3a) # 00111010 - c = Facility() - packet = a / b / c - return packet - - -def facilityMsToNet(SsVersionIndicator_presence=0): - """FACILITY Section 9.3.9.2""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x3a) # 00111010 - c = Facility() - packet = a / b / c - if SsVersionIndicator_presence is 1: - d = SsVersionIndicatorHdr(ieiSVI=0x7F, eightBitSVI=0x0) - packet = packet / d - return packet - - -def hold(): - """HOLD Section 9.3.10""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x18) # 00011000 - packet = a / b - return packet - - -# Network to MS -def holdAcknowledge(): - """HOLD ACKNOWLEDGE Section 9.3.11""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x19) # 00011001 - packet = a / b - return packet - - -# Network to MS -def holdReject(): - """HOLD REJECT Section 9.3.12""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x1a) # 00011010 - c = Cause() - packet = a / b / c - return packet - - -def modify(LowLayerCompatibility_presence=0, - HighLayerCompatibility_presence=0, - ReverseCallSetupDirection_presence=0): - """MODIFY Section 9.3.13""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x17) # 00010111 - c = BearerCapability() - packet = a / b / c - if LowLayerCompatibility_presence is 1: - d = LowLayerCompatibilityHdr(ieiLLC=0x7C, eightBitLLC=0x0) - packet = packet / d - if HighLayerCompatibility_presence is 1: - e = HighLayerCompatibilityHdr(ieiHLC=0x7D, eightBitHLC=0x0) - packet = packet / e - if ReverseCallSetupDirection_presence is 1: - f = ReverseCallSetupDirectionHdr(ieiRCSD=0xA3) - packet = packet / f - return packet - - -def modifyComplete(LowLayerCompatibility_presence=0, - HighLayerCompatibility_presence=0, - ReverseCallSetupDirection_presence=0): - """MODIFY COMPLETE Section 9.3.14""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x1f) # 00011111 - c = BearerCapability() - packet = a / b / c - if LowLayerCompatibility_presence is 1: - d = LowLayerCompatibilityHdr(ieiLLC=0x7C, eightBitLLC=0x0) - packet = packet / d - if HighLayerCompatibility_presence is 1: - e = HighLayerCompatibilityHdr(ieiHLC=0x7D, eightBitHLC=0x0) - packet = packet / e - if ReverseCallSetupDirection_presence is 1: - f = ReverseCallSetupDirection(ieiRCSD=0xA3) - packet = packet / f - return packet - - -def modifyReject(LowLayerCompatibility_presence=0, - HighLayerCompatibility_presence=0): - """MODIFY REJECT Section 9.3.15""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x13) # 00010011 - c = BearerCapability() - d = Cause() - packet = a / b / c / d - if LowLayerCompatibility_presence is 1: - e = LowLayerCompatibilityHdr(ieiLLC=0x7C, eightBitLLC=0x0) - packet = packet / e - if HighLayerCompatibility_presence is 1: - f = HighLayerCompatibilityHdr(ieiHLC=0x7D, eightBitHLC=0x0) - packet = packet / f - return packet - - -def notify(): - """NOTIFY Section 9.3.16""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x3e) # 00111110 - c = NotificationIndicator() - packet = a / b / c - return packet - - -# Network to MS -def progress(UserUser_presence=0): - """PROGRESS Section 9.3.17""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x3) # 00000011 - c = ProgressIndicator() - packet = a / b / c - if UserUser_presence is 1: - d = UserUserHdr() - packet = packet / d - return packet - - -# Network to MS -def ccEstablishment(): - """CC-ESTABLISHMENT Section 9.3.17a""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x4) # 00000100 - c = SetupContainer() - packet = a / b / c - return packet - - -def ccEstablishmentConfirmed(RepeatIndicator_presence=0, - BearerCapability_presence=0, - BearerCapability_presence1=0, - Cause_presence=0): - """CC-ESTABLISHMENT CONFIRMED Section 9.3.17b""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x6) # 00000110 - packet = a / b - if RepeatIndicator_presence is 1: - c = RepeatIndicatorHdr(ieiRI=0xD, eightBitRI=0x0) - packet = packet / c - if BearerCapability_presence is 1: - d = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0) - packet = packet / d - if BearerCapability_presence1 is 1: - e = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0) - packet = packet / e - if Cause_presence is 1: - f = CauseHdr(ieiC=0x08, eightBitC=0x0) - packet = packet / f - return packet - - -# Network to MS -def releaseNetToMs(): - """RELEASE Section 9.3.18.1""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x2d) # 00101101 - c = CauseHdr(ieiC=0x08, eightBitC=0x0) - d = CauseHdr(ieiC=0x08, eightBitC=0x0) - e = FacilityHdr(ieiF=0x1C, eightBitF=0x0) - f = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0) - packet = a / b / c / d / e / f - return packet - - -def releaseMsToNet(Cause_presence=0, Cause_presence1=0, - Facility_presence=0, UserUser_presence=0, - SsVersionIndicator_presence=0): - """RELEASE Section 9.3.18.2""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x2d) # 00101101 - packet = a / b - if Cause_presence is 1: - c = CauseHdr(ieiC=0x08, eightBitC=0x0) - packet = packet / c - if Cause_presence1 is 1: - d = CauseHdr(ieiC=0x08, eightBitC=0x0) - packet = packet / d - if Facility_presence is 1: - e = FacilityHdr(ieiF=0x1C, eightBitF=0x0) - packet = packet / e - if UserUser_presence is 1: - f = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0) - packet = packet / f - if SsVersionIndicator_presence is 1: - g = SsVersionIndicatorHdr(ieiSVI=0x7F, eightBitSVI=0x0) - packet = packet / g - return packet - - -# Network to MS -def recall(): - """RECALL Section 9.3.18a""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0xb) # 00001011 - c = RecallType() - d = Facility() - packet = a / b / c / d - return packet - - -# Network to MS -def releaseCompleteNetToMs(Cause_presence=0, Facility_presence=0, - UserUser_presence=0): - """RELEASE COMPLETE Section 9.3.19.1""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x2a) # 00101010 - packet = a / b - if Cause_presence is 1: - c = CauseHdr(ieiC=0x08, eightBitC=0x0) - packet = packet / c - if Facility_presence is 1: - d = FacilityHdr(ieiF=0x1C, eightBitF=0x0) - packet = packet / d - if UserUser_presence is 1: - e = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0) - packet = packet / e - return packet - - -def releaseCompleteMsToNet(Cause_presence=0, Facility_presence=0, - UserUser_presence=0, SsVersionIndicator_presence=0): - """RELEASE COMPLETE Section 9.3.19.2""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x2a) # 00101010 - packet = a / b - if Cause_presence is 1: - c = CauseHdr(ieiC=0x08, eightBitC=0x0) - packet = packet / c - if Facility_presence is 1: - d = FacilityHdr(ieiF=0x1C, eightBitF=0x0) - packet = packet / d - if UserUser_presence is 1: - e = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0) - packet = packet / e - if SsVersionIndicator_presence is 1: - f = SsVersionIndicatorHdr(ieiSVI=0x7F, eightBitSVI=0x0) - packet = packet / f - return packet - - -def retrieve(): - """RETRIEVE Section 9.3.20""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x1c) # 00011100 - packet = a / b - return packet - - -# Network to MS -def retrieveAcknowledge(): - """RETRIEVE ACKNOWLEDGE Section 9.3.21""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x1d) # 00011101 - packet = a / b - return packet - - -# Network to MS -def retrieveReject(): - """RETRIEVE REJECT Section 9.3.22""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x1e) # 00011110 - c = Cause() - packet = a / b / c - return packet - - -# Network to MS -def setupMobileTerminated(RepeatIndicator_presence=0, - BearerCapability_presence=0, - BearerCapability_presence1=0, - Facility_presence=0, ProgressIndicator_presence=0, - Signal_presence=0, - CallingPartyBcdNumber_presence=0, - CallingPartySubaddress_presence=0, - CalledPartyBcdNumber_presence=0, - CalledPartySubaddress_presence=0, -# RecallType_presence=0, - RedirectingPartyBcdNumber_presence=0, - RedirectingPartySubaddress_presence=0, - RepeatIndicator_presence1=0, - LowLayerCompatibility_presence=0, - LowLayerCompatibility_presence1=0, - RepeatIndicator_presence2=0, - HighLayerCompatibility_presence=0, - HighLayerCompatibility_presence1=0, - UserUser_presence=0, PriorityLevel_presence=0, - AlertingPattern_presence=0): - """SETUP Section 9.3.23.1""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x5) # 00000101 - packet = a / b - if RepeatIndicator_presence is 1: - c = RepeatIndicatorHdr(ieiRI=0xD, eightBitRI=0x0) - packet = packet / c - if BearerCapability_presence is 1: - d = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0) - packet = packet / d - if BearerCapability_presence1 is 1: - e = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0) - packet = packet / e - if Facility_presence is 1: - f = FacilityHdr(ieiF=0x1C, eightBitF=0x0) - packet = packet / f - if ProgressIndicator_presence is 1: - g = ProgressIndicatorHdr(ieiPI=0x1E, eightBitPI=0x0) - packet = packet / g - if Signal_presence is 1: - h = SignalHdr(ieiS=0x34, eightBitS=0x0) - packet = packet / h - if CallingPartyBcdNumber_presence is 1: - i = CallingPartyBcdNumberHdr(ieiCPBN=0x5C, eightBitCPBN=0x0) - packet = packet / i - if CallingPartySubaddress_presence is 1: - j = CallingPartySubaddressHdr(ieiCPS=0x5D, eightBitCPS=0x0) - packet = packet / j - if CalledPartyBcdNumber_presence is 1: - k = CalledPartyBcdNumberHdr(ieiCPBN=0x5E, eightBitCPBN=0x0) - packet = packet / k - if CalledPartySubaddress_presence is 1: - l = CalledPartySubaddressHdr(ieiCPS=0x6D, eightBitCPS=0x0) - packet = packet / l - if RedirectingPartyBcdNumber_presence is 1: - n = RedirectingPartyBcdNumberHdr(ieiRPBN=0x74, eightBitRPBN=0x0) - packet = packet / n - if RedirectingPartySubaddress_presence is 1: - m = RedirectingPartySubaddress_presence(ieiRPBN=0x75, eightBitRPBN=0x0) - packet = packet / m - if RepeatIndicator_presence1 is 1: - o = RepeatIndicatorHdr(ieiRI=0xD0, eightBitRI=0x0) - packet = packet / o - if LowLayerCompatibility_presence is 1: - p = LowLayerCompatibilityHdr(ieiLLC=0x7C, eightBitLLC=0x0) - packet = packet / p - if LowLayerCompatibility_presence1 is 1: - q = LowLayerCompatibilityHdr(ieiLLC=0x7C, eightBitLLC=0x0) - packet = packet / q - if RepeatIndicator_presence2 is 1: - r = RepeatIndicatorHdr(ieiRI=0xD, eightBitRI=0x0) - packet = packet / r - if HighLayerCompatibility_presence is 1: - s = HighLayerCompatibilityHdr(ieiHLC=0x7D, eightBitHLC=0x0) - packet = packet / s - if HighLayerCompatibility_presence1 is 1: - t = HighLayerCompatibilityHdr(ieiHLC=0x7D, eightBitHLC=0x0) - packet = packet / t - if UserUser_presence is 1: - u = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0) - packet = packet / u - if PriorityLevel_presence is 1: - v = PriorityLevelHdr(ieiPL=0x8, eightBitPL=0x0) - packet = packet / v - if AlertingPattern_presence is 1: - w = AlertingPatternHdr(ieiAP=0x19, eightBitAP=0x0) - packet = packet / w - return packet - - -def setupMobileOriginated(RepeatIndicator_presence=0, - BearerCapability_presence=0, - BearerCapability_presence1=0, - Facility_presence=0, - CallingPartySubaddress_presence=0, - CalledPartyBcdNumber_presence=0, - CalledPartySubaddress_presence=0, - RepeatIndicator_presence1=0, - LowLayerCompatibility_presence=0, - LowLayerCompatibility_presence1=0, - RepeatIndicator_presence2=0, - HighLayerCompatibility_presence=0, - HighLayerCompatibility_presence1=0, - UserUser_presence=0, SsVersionIndicator_presence=0, - ClirSuppression_presence=0, - ClirInvocation_presence=0, - CallControlCapabilities_presence=0, - Facility_presence1=0, - Facility_presence2=0): - """SETUP Section 9.3.23.2""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x5) # 00000101 - packet = a / b - if RepeatIndicator_presence is 1: - c = RepeatIndicatorHdr(ieiRI=0xD, eightBitRI=0x0) - packet = packet / c - if BearerCapability_presence is 1: - d = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0) - packet = packet / d - if BearerCapability_presence1 is 1: - e = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0) - packet = packet / e - if Facility_presence is 1: - f = FacilityHdr(ieiF=0x1C, eightBitF=0x0) - packet = packet / f - if CallingPartySubaddress_presence is 1: - g = CallingPartySubaddressHdr(ieiCPS=0x5D, eightBitCPS=0x0) - packet = packet / g - if CalledPartyBcdNumber_presence is 1: - h = CalledPartyBcdNumberHdr(ieiCPBN=0x5E, eightBitCPBN=0x0) - packet = packet / h - if CalledPartySubaddress_presence is 1: - i = CalledPartySubaddressHdr(ieiCPS=0x6D, eightBitCPS=0x0) - packet = packet / i - if RepeatIndicator_presence1 is 1: - j = RepeatIndicatorHdr(ieiRI=0xD0, eightBitRI=0x0) - packet = packet / j - if LowLayerCompatibility_presence is 1: - k = LowLayerCompatibilityHdr(ieiLLC=0x7C, eightBitLLC=0x0) - packet = packet / k - if LowLayerCompatibility_presence1 is 1: - l = LowLayerCompatibilityHdr(ieiLLC=0x7C, eightBitLLC=0x0) - packet = packet / l - if RepeatIndicator_presence2 is 1: - m = RepeatIndicatorHdr(ieiRI=0xD, eightBitRI=0x0) - packet = packet / m - if HighLayerCompatibility_presence is 1: - n = HighLayerCompatibilityHdr(ieiHLC=0x7D, eightBitHLC=0x0) - packet = packet / n - if HighLayerCompatibility_presence1 is 1: - o = HighLayerCompatibilityHdr(ieiHLC=0x7D, eightBitHLC=0x0) - packet = packet / o - if UserUser_presence is 1: - p = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0) - packet = packet / p - if SsVersionIndicator_presence is 1: - q = SsVersionIndicatorHdr(ieiSVI=0x7F, eightBitSVI=0x0) - packet = packet / q - if ClirSuppression_presence is 1: - r = ClirSuppressionHdr(ieiCS=0xA1, eightBitCS=0x0) - packet = packet / r - if ClirInvocation_presence is 1: - s = ClirInvocationHdr(ieiCI=0xA2, eightBitCI=0x0) - packet = packet / s - if CallControlCapabilities_presence is 1: - t = CallControlCapabilitiesHdr(ieiCCC=0x15, eightBitCCC=0x0) - packet = packet / t - if Facility_presence1 is 1: - u = FacilityHdr(ieiF=0x1D, eightBitF=0x0) - packet = packet / u - if Facility_presence2 is 1: - v = FacilityHdr(ieiF=0x1B, eightBitF=0x0) - packet = packet / v - return packet - - -def startCc(CallControlCapabilities_presence=0): - """START CC Section 9.3.23a""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x9) # 00001001 - packet = a / b - if CallControlCapabilities_presence is 1: - c = CallControlCapabilitiesHdr(ieiCCC=0x15, eightBitCCC=0x0) - packet = paclet / c - return packet - - -def startDtmf(): - """START DTMF Section 9.3.24""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x35) # 00110101 - c = KeypadFacilityHdr(ieiKF=0x2C, eightBitKF=0x0) - packet = a / b / c - return packet - - -# Network to MS -def startDtmfAcknowledge(): - """START DTMF ACKNOWLEDGE Section 9.3.25""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x32) # 00110010 - c = KeypadFacilityHdr(ieiKF=0x2C, eightBitKF=0x0) - packet = a / b / c - return packet - - -# Network to MS -def startDtmfReject(): - """ START DTMF REJECT Section 9.3.26""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x37) # 00110111 - c = Cause() - packet = a / b / c - return packet - - -def status(AuxiliaryStates_presence=0): - """STATUS Section 9.3.27""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x3d) # 00111101 - c = Cause() - d = CallState() - packet = a / b / c / d - if AuxiliaryStates_presence is 1: - e = AuxiliaryStatesHdr(ieiAS=0x24, eightBitAS=0x0) - packet = packet / e - return packet - - -def statusEnquiry(): - """STATUS ENQUIRY Section 9.3.28""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x34) # 00110100 - packet = a / b - return packet - - -def stopDtmf(): - """STOP DTMF Section 9.3.29""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x31) # 00110001 - packet = a / b - return packet - - -# Network to MS -def stopDtmfAcknowledge(): - """STOP DTMF ACKNOWLEDGE Section 9.3.30""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x32) # 00110010 - packet = a / b - return packet - - -def userInformation(MoreData_presence=0): - """USER INFORMATION Section 9.3.31""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x20) # 000100000 - c = UserUser() - packet = a / b / c - if MoreData_presence is 1: - d = MoreDataHdr(ieiMD=0xA0, eightBitMD=0x0) - packet = packet / d - return packet - -# -# 9.4 GPRS Mobility Management Messages -# - - -def attachRequest(PTmsiSignature_presence=0, GprsTimer_presence=0, - TmsiStatus_presence=0): - """ATTACH REQUEST Section 9.4.1""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x1) # 0000001 - c = MsNetworkCapability() - d = AttachTypeAndCiphKeySeqNr() - f = DrxParameter() - g = MobileId() - h = RoutingAreaIdentification() - i = MsRadioAccessCapability() - packet = a / b / c / d / f / g / h / i - if PTmsiSignature_presence is 1: - j = PTmsiSignature(ieiPTS=0x19) - packet = packet / j - if GprsTimer_presence is 1: - k = GprsTimer(ieiGT=0x17) - packet = packet / k - if TmsiStatus_presence is 1: - l = TmsiStatus(ieiTS=0x9) - packet = packet / l - return packet - - -def attachAccept(PTmsiSignature_presence=0, GprsTimer_presence=0, - MobileId_presence=0, MobileId_presence1=0, - GmmCause_presence=0): - """ATTACH ACCEPT Section 9.4.2""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x2) # 00000010 - c = AttachResult() - d = ForceToStandby() - e = GprsTimer() - f = RadioPriorityAndSpareHalfOctets() - h = RoutingAreaIdentification() - packet = a / b / c / d / e / f / h - if PTmsiSignature_presence is 1: - i = PTmsiSignature(ieiPTS=0x19) - packet = packet / i - if GprsTimer_presence is 1: - j = GprsTimer(ieiGT=0x17) - packet = packet / j - if MobileId_presence is 1: - k = MobileIdHdr(ieiMI=0x18, eightBitMI=0x0) - packet = packet / k - if MobileId_presence1 is 1: - l = MobileIdHdr(ieiMI=0x23, eightBitMI=0x0) - packet = packet / l - if GmmCause_presence is 1: - m = GmmCause(ieiGC=0x25) - packet = packet / m - return packet - - -def attachComplete(): - """ATTACH COMPLETE Section 9.4.3""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x3) # 00000011 - packet = a / b - return packet - - -def attachReject(): - """ATTACH REJECT Section 9.4.4""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x1) # 00000001 - c = GmmCause() - packet = a / b / c - return packet - - -def detachRequest(GmmCause_presence=0): - """DETACH REQUEST Section 9.4.5""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x5) # 00000101 - c = DetachTypeAndForceToStandby() - packet = a / b / c - if GmmCause_presence is 1: - e = GmmCause(ieiGC=0x25) - packet = packet / e - return packet - - -def detachRequestMsOriginating(): - """DETACH REQUEST Section 9.4.5.2""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x5) # 00000101 - c = DetachTypeAndSpareHalfOctets() - packet = a / b / c - return packet - - -def detachAcceptMsTerminated(): - """DETACH ACCEPT Section 9.4.6.1""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x6) # 00000110 - packet = a / b - return packet - - -def detachAcceptMsOriginating(): - """DETACH ACCEPT Section 9.4.6.2""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x6) # 00000110 - c = ForceToStandbyAndSpareHalfOctets() - packet = a / b / c - return packet - - -def ptmsiReallocationCommand(PTmsiSignature_presence=0): - """P-TMSI REALLOCATION COMMAND Section 9.4.7""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x10) # 00010000 - c = MobileId() - d = RoutingAreaIdentification() - e = ForceToStandbyAndSpareHalfOctets() - packet = a / b / c / d / e - if PTmsiSignature_presence is 1: - g = PTmsiSignature(ieiPTS=0x19) - packet = packet / g - return packet - - -def ptmsiReallocationComplete(): - """P-TMSI REALLOCATION COMPLETE Section 9.4.8""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x11) # 00010001 - packet = a / b - return packet - - -def authenticationAndCipheringRequest( - AuthenticationParameterRAND_presence=0, - CiphKeySeqNr_presence=0): - """AUTHENTICATION AND CIPHERING REQUEST Section 9.4.9""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x12) # 00010010 - d = CipheringAlgorithmAndImeisvRequest() - e = ForceToStandbyAndAcReferenceNumber() - packet = a / b / d / e - if AuthenticationParameterRAND_presence is 1: - g = AuthenticationParameterRAND(ieiAPR=0x21) - packet = packet / g - if CiphKeySeqNr_presence is 1: - h = CiphKeySeqNrHdr(ieiCKSN=0x08, eightBitCKSN=0x0) - packet = packet / h - return packet - - -def authenticationAndCipheringResponse( - AuthenticationParameterSRES_presence=0, - MobileId_presence=0): - """AUTHENTICATION AND CIPHERING RESPONSE Section 9.4.10""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x13) # 00010011 - c = AcReferenceNumberAndSpareHalfOctets() - packet = a / b / c - if AuthenticationParameterSRES_presence is 1: - e = AuthenticationParameterSRES(ieiAPS=0x22) - packet = packet / e - if MobileId_presence is 1: - f = MobileIdHdr(ieiMI=0x23, eightBitMI=0x0) - packet = packet / f - return packet - - -def authenticationAndCipheringReject(): - """AUTHENTICATION AND CIPHERING REJECT Section 9.4.11""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x14) # 00010100 - packet = a / b - return packet - - -def identityRequest(): - """IDENTITY REQUEST Section 9.4.12""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x15) # 00010101 - c = IdentityType2AndforceToStandby() - packet = a / b / c - return packet - - -def identityResponse(): - """IDENTITY RESPONSE Section 9.4.13""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x16) # 00010110 - c = MobileId() - packet = a / b / c - return packet - - -def routingAreaUpdateRequest(PTmsiSignature_presence=0, - GprsTimer_presence=0, - DrxParameter_presence=0, - TmsiStatus_presence=0): - """ROUTING AREA UPDATE REQUEST Section 9.4.14""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x8) # 00001000 - c = UpdateTypeAndCiphKeySeqNr() - e = RoutingAreaIdentification() - f = MsNetworkCapability() - packet = a / b / c / e / f - if PTmsiSignature_presence is 1: - g = PTmsiSignature(ieiPTS=0x19) - packet = packet / g - if GprsTimer_presence is 1: - h = GprsTimer(ieiGT=0x17) - packet = packet / h - if DrxParameter_presence is 1: - i = DrxParameter(ieiDP=0x27) - packet = packet / i - if TmsiStatus_presence is 1: - j = TmsiStatus(ieiTS=0x9) - packet = packet / j - return packet - - -def routingAreaUpdateAccept(PTmsiSignature_presence=0, - MobileId_presence=0, MobileId_presence1=0, - ReceiveNpduNumbersList_presence=0, - GprsTimer_presence=0, GmmCause_presence=0): - """ROUTING AREA UPDATE ACCEPT Section 9.4.15""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x9) # 00001001 - c = ForceToStandbyAndUpdateResult() - e = GprsTimer() - f = RoutingAreaIdentification() - packet = a / b / c / e / f - if PTmsiSignature_presence is 1: - g = PTmsiSignature(ieiPTS=0x19) - packet = packet / g - if MobileId_presence is 1: - h = MobileIdHdr(ieiMI=0x18, eightBitMI=0x0) - packet = packet / h - if MobileId_presence1 is 1: - i = MobileIdHdr(ieiMI=0x23, eightBitMI=0x0) - packet = packet / i - if ReceiveNpduNumbersList_presence is 1: - j = ReceiveNpduNumbersList(ieiRNNL=0x26) - packet = packet / j - if GprsTimer_presence is 1: - k = GprsTimer(ieiGT=0x17) - packet = packet / k - if GmmCause_presence is 1: - l = GmmCause(ieiGC=0x25) - packet = packet / l - return packet - - -def routingAreaUpdateComplete(ReceiveNpduNumbersList_presence=0): - """ROUTING AREA UPDATE COMPLETE Section 9.4.16""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0xa) # 00001010 - packet = a / b - if ReceiveNpduNumbersList_presence is 1: - c = ReceiveNpduNumbersList(ieiRNNL=0x26) - packet = packet / c - return packet - - -def routingAreaUpdateReject(): - """ROUTING AREA UPDATE REJECT Section 9.4.17""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0xb) # 00001011 - c = GmmCause() - d = ForceToStandbyAndSpareHalfOctets() - packet = a / b / c / d - return packet - - -def gmmStatus(): - """GMM STATUS Section 9.4.18""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x20) # 00100000 - c = GmmCause() - packet = a / b / c - return packet - - -def gmmInformation(NetworkName_presence=0, NetworkName_presence1=0, - TimeZone_presence=0, TimeZoneAndTime_presence=0, - LsaIdentifier_presence=0): - """GMM INFORMATION Section 9.4.19""" - a = TpPd(pd=0x3) - b = MessageType(mesType=0x21) # 00100001 - packet = a / b - if NetworkName_presence is 1: - c = NetworkNameHdr(ieiNN=0x43, eightBitNN=0x0) - packet = packet / c - if NetworkName_presence1 is 1: - d = NetworkNameHdr(ieiNN=0x45, eightBitNN=0x0) - packet = packet / d - if TimeZone_presence is 1: - e = TimeZoneHdr(ieiTZ=0x46, eightBitTZ=0x0) - packet = packet / e - if TimeZoneAndTime_presence is 1: - f = TimeZoneAndTimeHdr(ieiTZAT=0x47, eightBitTZAT=0x0) - packet = packet / f - if LsaIdentifier_presence is 1: - g = LsaIdentifierHdr(ieiLI=0x48, eightBitLI=0x0) - packet = packet / g - return packet - -# -# 9.5 GPRS Session Management Messages -# - - -def activatePdpContextRequest(AccessPointName_presence=0, - ProtocolConfigurationOptions_presence=0): - """ACTIVATE PDP CONTEXT REQUEST Section 9.5.1""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x41) # 01000001 - c = NetworkServiceAccessPointIdentifier() - d = LlcServiceAccessPointIdentifier() - e = QualityOfService() - f = PacketDataProtocolAddress() - packet = a / b / c / d / e / f - if AccessPointName_presence is 1: - g = AccessPointName(ieiAPN=0x28) - packet = packet / g - if ProtocolConfigurationOptions_presence is 1: - h = ProtocolConfigurationOptions(ieiPCO=0x27) - packet = packet / h - return packet - - -def activatePdpContextAccept(PacketDataProtocolAddress_presence=0, - ProtocolConfigurationOptions_presence=0): - """ACTIVATE PDP CONTEXT ACCEPT Section 9.5.2""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x42) # 01000010 - c = LlcServiceAccessPointIdentifier() - d = QualityOfService() - e = RadioPriorityAndSpareHalfOctets() - packet = a / b / c / d / e - if PacketDataProtocolAddress_presence is 1: - f = PacketDataProtocolAddress(ieiPDPA=0x2B) - packet = packet / f - if ProtocolConfigurationOptions_presence is 1: - g = ProtocolConfigurationOptions(ieiPCO=0x27) - packet = packet / g - return packet - - -def activatePdpContextReject(ProtocolConfigurationOptions_presence=0): - """ACTIVATE PDP CONTEXT REJECT Section 9.5.3""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x43) # 01000011 - c = SmCause() - packet = a / b / c - if ProtocolConfigurationOptions_presence is 1: - d = ProtocolConfigurationOptions(ieiPCO=0x27) - packet = packet / d - return packet - - -def requestPdpContextActivation(AccessPointName_presence=0): - """REQUEST PDP CONTEXT ACTIVATION Section 9.5.4""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x44) # 01000100 - c = PacketDataProtocolAddress() - packet = a / b / c - if AccessPointName_presence is 1: - d = AccessPointName(ieiAPN=0x28) - packet = packet / d - return packet - - -def requestPdpContextActivationReject(): - """REQUEST PDP CONTEXT ACTIVATION REJECT Section 9.5.5""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x45) # 01000101 - c = SmCause() - packet = a / b / c - return packet - - -def modifyPdpContextRequest(): - """MODIFY PDP CONTEXT REQUEST Section 9.5.6""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x48) # 01001000 - c = RadioPriorityAndSpareHalfOctets() - d = LlcServiceAccessPointIdentifier() - e = QualityOfService() - packet = a / b / c / d / e - return packet - - -def modifyPdpContextAccept(): - """MODIFY PDP CONTEXT ACCEPT Section 9.5.7""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x45) # 01000101 - packet = a / b - return packet - - -def deactivatePdpContextRequest(): - """DEACTIVATE PDP CONTEXT REQUEST Section 9.5.8""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x46) # 01000110 - c = SmCause() - packet = a / b / c - return packet - - -def deactivatePdpContextAccept(): - """DEACTIVATE PDP CONTEXT ACCEPT Section 9.5.9""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x47) # 01000111 - packet = a / b - return packet - - -def activateAaPdpContextRequest(AccessPointName_presence=0, - ProtocolConfigurationOptions_presence=0, - GprsTimer_presence=0): - """ACTIVATE AA PDP CONTEXT REQUEST Section 9.5.10""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x50) # 01010000 - c = NetworkServiceAccessPointIdentifier() - d = LlcServiceAccessPointIdentifier() - e = QualityOfService() - f = PacketDataProtocolAddress() - packet = a / b / c / d / e / f - if AccessPointName_presence is 1: - g = AccessPointName(ieiAPN=0x28) - packet = packet / g - if ProtocolConfigurationOptions_presence is 1: - h = ProtocolConfigurationOptions(ieiPCO=0x27) - packet = packet / h - if GprsTimer_presence is 1: - i = GprsTimer(ieiGT=0x29) - packet = packet / i - return packet - - -def activateAaPdpContextAccept(ProtocolConfigurationOptions_presence=0, - GprsTimer_presence=0): - """ACTIVATE AA PDP CONTEXT ACCEPT Section 9.5.11""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x51) # 01010001 - c = LlcServiceAccessPointIdentifier() - d = QualityOfService() - e = MobileId() - f = PacketDataProtocolAddress() - g = RadioPriorityAndSpareHalfOctets() - packet = a / b / c / d / e / f / g - if ProtocolConfigurationOptions_presence is 1: - i = ProtocolConfigurationOptions(ieiPCO=0x27) - packet = packet / i - if GprsTimer_presence is 1: - j = GprsTimer(ieiGT=0x29) - packet = packet / j - return packet - - -def activateAaPdpContextReject(ProtocolConfigurationOptions_presence=0): - """ACTIVATE AA PDP CONTEXT REJECT Section 9.5.12""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x52) # 01010010 - c = SmCause() - packet = a / b / c - if ProtocolConfigurationOptions_presence is 1: - d = ProtocolConfigurationOptions(ieiPCO=0x27) - packet = packet / d - return packet - - -def deactivateAaPdpContextRequest(): - """DEACTIVATE AA PDP CONTEXT REQUEST Section 9.5.13""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x53) # 01010011 - c = AaDeactivationCauseAndSpareHalfOctets() - packet = a / b / c - return packet - - -def deactivateAaPdpContextAccept(): - """DEACTIVATE AA PDP CONTEXT ACCEPT Section 9.5.14""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x54) # 01010100 - packet = a / b - return packet - - -def smStatus(): - """SM STATUS Section 9.5.15""" - a = TpPd(pd=0x8) - b = MessageType(mesType=0x55) # 01010101 - c = SmCause() - packet = a / b / c - return packet - - -# ============================================# -# Information Elements contents (Section 10) # -# =========================================== # - -#### -# This section contains the elements we need to build the messages -#### - -# -# Common information elements: -# -class CellIdentityHdr(Packet): - """ Cell identity Section 10.5.1.1 """ - name = "Cell Identity" - fields_desc = [ - BitField("eightBitCI", None, 1), - XBitField("ieiCI", None, 7), - ByteField("ciValue1", 0x0), - ByteField("ciValue2", 0x0) - ] - - -class CiphKeySeqNrHdr(Packet): - """ Ciphering Key Sequence Number Section 10.5.1.2 """ - name = "Cipher Key Sequence Number" - fields_desc = [ - XBitField("ieiCKSN", None, 4), - BitField("spare", 0x0, 1), - BitField("keySeq", 0x0, 3) - ] - - -# Fix 1/2 len problem -class CiphKeySeqNrAndSpareHalfOctets(Packet): - name = "Cipher Key Sequence Number and Spare Half Octets" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("keySeq", 0x0, 3), - BitField("spareHalfOctets", 0x0, 4) - ] - - -# Fix 1/2 len problem -class CiphKeySeqNrAndMacModeAndChannelCodingRequest(Packet): - name = "Cipher Key Sequence Number and Mac Mode And Channel Coding Request" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("keySeq", 0x0, 3), - BitField("macMode", 0x0, 2), - BitField("cs", 0x0, 2) - ] - - -class LocalAreaIdHdr(Packet): - """ Local Area Identification Section 10.5.1.3 """ - name = "Location Area Identification" - fields_desc = [ - BitField("eightBitLAI", None, 1), - XBitField("ieiLAI", None, 7), - BitField("mccDigit2", 0x0, 4), - BitField("mccDigit1", 0x0, 4), - BitField("mncDigit3", 0x0, 4), - BitField("mccDigit3", 0x0, 4), - BitField("mncDigit2", 0x0, 4), - BitField("mncDigit1", 0x0, 4), - ByteField("lac1", 0x0), - ByteField("lac2", 0x0) - ] -# -# The Mobile Identity is a type 4 information element with a minimum -# length of 3 octet and 11 octets length maximal. -# - - -# len 3 - 11 -class MobileIdHdr(Packet): - """ Mobile Identity Section 10.5.1.4 """ - name = "Mobile Identity" - fields_desc = [ - BitField("eightBitMI", 0x0, 1), - XBitField("ieiMI", 0x0, 7), - - XByteField("lengthMI", None), - - BitField("idDigit1", 0x0, 4), - BitField("oddEven", 0x0, 1), - BitField("typeOfId", 0x0, 3), - - BitField("idDigit2_1", None, 4), # optional - BitField("idDigit2", None, 4), - - BitField("idDigit3_1", None, 4), - BitField("idDigit3", None, 4), - - BitField("idDigit4_1", None, 4), - BitField("idDigit4", None, 4), - - BitField("idDigit5_1", None, 4), - BitField("idDigit5", None, 4), - - BitField("idDigit6_1", None, 4), - BitField("idDigit6", None, 4), - BitField("idDigit7_1", None, 4), - BitField("idDigit7", None, 4), - BitField("idDigit8_1", None, 4), - BitField("idDigit8", None, 4), - BitField("idDigit9_1", None, 4), - BitField("idDigit9", None, 4), - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i, None)) # this list holds the values of -# the variables, the INTERESSTING value! - res = adapt(3, 11, a, self.fields_desc) - if self.lengthMI is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - print(repr(p)) - return p + pay - - -class MobileStationClassmark1Hdr(Packet): - """ Mobile Station Classmark 1 Section 10.5.1.5 """ - name = "Mobile Station Classmark 1" - fields_desc = [ - BitField("eightBitiMSC1", None, 1), - XBitField("ieiMSC1", None, 7), - BitField("spare", 0x0, 1), - BitField("revisionLvl", 0x0, 2), - BitField("esInd", 0x0, 1), - BitField("a51", 0x0, 1), - BitField("rfPowerCap", 0x0, 3) - ] - - -class MobileStationClassmark2Hdr(Packet): - """ Mobile Station Classmark 2 Section 10.5.1.6 """ - name = "Mobile Station Classmark 2" - fields_desc = [ - BitField("eightBitMSC2", None, 1), - XBitField("ieiMSC2", None, 7), - XByteField("lengthMSC2", 0x3), - BitField("spare", 0x0, 1), - BitField("revisionLvl", 0x0, 2), - BitField("esInd", 0x0, 1), - BitField("a51", 0x0, 1), - BitField("rfPowerCap", 0x0, 3), - BitField("spare1", 0x0, 1), - BitField("psCap", 0x0, 1), - BitField("ssScreenInd", 0x0, 2), - BitField("smCaPabi", 0x0, 1), - BitField("vbs", 0x0, 1), - BitField("vgcs", 0x0, 1), - BitField("fc", 0x0, 1), - BitField("cm3", 0x0, 1), - BitField("spare2", 0x0, 1), - BitField("lcsvaCap", 0x0, 1), - BitField("spare3", 0x0, 1), - BitField("soLsa", 0x0, 1), - BitField("cmsp", 0x0, 1), - BitField("a53", 0x0, 1), - BitField("a52", 0x0, 1) - ] - - -# len max 14 -class MobileStationClassmark3(Packet): - """ Mobile Station Classmark 3 Section 10.5.1.7 """ - name = "Mobile Station Classmark 3" - fields_desc = [ - # FIXME - ByteField("ieiMSC3", 0x0), - ByteField("byte2", 0x0), - ByteField("byte3", 0x0), - ByteField("byte4", 0x0), - ByteField("byte5", 0x0), - ByteField("byte6", 0x0), - ByteField("byte7", 0x0), - ByteField("byte8", 0x0), - ByteField("byte9", 0x0), - ByteField("byte10", 0x0), - ByteField("byte11", 0x0), - ByteField("byte12", 0x0), - ByteField("byte13", 0x0), - ByteField("byte14", 0x0) - ] - - -class SpareHalfOctets(Packet): - """ Spare Half Octet Section 10.5.1.8 """ - name = "Spare Half Octet" - fields_desc = [ - BitField("filler", None, 4), - BitField("spareHalfOctets", 0x0, 4) - ] - - -class DescriptiveGroupOrBroadcastCallReferenceHdr(Packet): - """ Descriptive group or broadcast call reference Section 10.5.1.9 """ - name = "Descriptive Group or Broadcast Call Reference" - fields_desc = [ - BitField("eightBitDGOBCR", None, 1), - XBitField("ieiDGOBCR", None, 7), - BitField("binCallRef", 0x0, 27), - BitField("sf", 0x0, 1), - BitField("fa", 0x0, 1), - BitField("callPrio", 0x0, 3), - BitField("cipherInfo", 0x0, 4), - BitField("spare1", 0x0, 1), - BitField("spare2", 0x0, 1), - BitField("spare3", 0x0, 1), - BitField("spare4", 0x0, 1) - ] - - -class GroupCipherKeyNumber(Packet): - """ Group Cipher Key Number reference Section 10.5.1.10 """ - name = "Group Cipher Key Number" - fields_desc = [ - XBitField("ieiGCKN", None, 4), - BitField("groupCipher", 0x0, 4) - ] - - -class PdAndSapiHdr(Packet): - """ PD and SAPI $(CCBS)$ Section 10.5.1.10a """ - name = "PD and SAPI $(CCBS)$" - fields_desc = [ - BitField("eightBitPAS", None, 1), - XBitField("ieiPAS", None, 7), - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("sapi", 0x0, 2), - BitField("pd", 0x0, 4) - ] - - -class PriorityLevelHdr(Packet): - """ Priority Level Section 10.5.1.11 """ - name = "Priority Level" - fields_desc = [ - XBitField("ieiPL", None, 4), - BitField("spare", 0x0, 1), - BitField("callPrio", 0x0, 3) - ] - -# -# Radio Resource management information elements -# - - -# len 6 to max for L3 message (251) -class BaRangeHdr(Packet): - """ BA Range Section 10.5.2.1a """ - name = "BA Range" - fields_desc = [ - BitField("eightBitBR", None, 1), - XBitField("ieiBR", None, 7), - - XByteField("lengthBR", None), -#error: byte format requires -128 <= number <= 127 - ByteField("nrOfRanges", 0x0), -# # rX = range X -# # L o = Lower H i = higher -# # H p = high Part Lp = low Part - ByteField("r1LoHp", 0x0), - - BitField("r1LoLp", 0x0, 3), - BitField("r1HiHp", 0x0, 5), - - BitField("r1HiLp", 0x0, 4), - BitField("r2LoHp", 0x0, 4), - # optional - BitField("r2LoLp", None, 5), - BitField("r2HiHp", None, 3), - - ByteField("r2HiLp", None), - ByteField("r3LoHp", None), - - BitField("r3LoLp", None, 5), - BitField("r3HiHp", None, 3), - - ByteField("r3HiLp", None), - ByteField("r4LoHp", None), - - BitField("r4LoLp", None, 5), - BitField("r4HiHp", None, 3), - ByteField("r4HiLp", None), - ByteField("r5LoHp", None), - - BitField("r5LoLp", None, 5), - BitField("r5HiHp", None, 3), - ByteField("r5HiLp", None), - ByteField("r6LoHp", None), - - BitField("r6LoLp", None, 5), - BitField("r6HiHp", None, 3), - ByteField("r6HiLp", None), - ByteField("r7LoHp", None), - - BitField("r7LoLp", None, 5), - BitField("r7HiHp", None, 3), - ByteField("r7HiLp", None), - ByteField("r8LoHp", None), - - BitField("r8LoLp", None, 5), - BitField("r8HiHp", None, 3), - ByteField("r8HiLp", None), - ByteField("r9LoHp", None), - - BitField("r9LoLp", None, 5), - BitField("r9HiHp", None, 3), - ByteField("r9HiLp", None), - ByteField("r10LoHp", None), - - BitField("r10LoLp", None, 5), - BitField("r10HiHp", None, 3), - ByteField("r10HiLp", None), - ByteField("r11LoHp", None), - - BitField("r11LoLp", None, 5), - BitField("r11HiHp", None, 3), - ByteField("r11HiLp", None), - ByteField("r12LoHp", None), - - BitField("r12LoLp", None, 5), - BitField("r12HiHp", None, 3), - ByteField("r12HiLp", None), - ByteField("r13LoHp", None), - - BitField("r13LoLp", None, 5), - BitField("r13HiHp", None, 3), - ByteField("r13HiLp", None), - ByteField("r14LoHp", None), - - BitField("r14LoLp", None, 5), - BitField("r14HiHp", None, 3), - ByteField("r14HiLp", None), - ByteField("r15LoHp", None), - - BitField("r15LoLp", None, 5), - BitField("r15HiHp", None, 3), - ByteField("r15HiLp", None), - ByteField("r16LoHp", None), - - BitField("r16LoLp", None, 5), - BitField("r16HiHp", None, 3), - ByteField("r16HiLp", None), - ByteField("r17LoHp", None), - - BitField("r17LoLp", None, 5), - BitField("r17HiHp", None, 3), - ByteField("r17HiLp", None), - ByteField("r18LoHp", None), - - BitField("r18LoLp", None, 5), - BitField("r18HiHp", None, 3), - ByteField("r18HiLp", None), - ByteField("r19LoHp", None), - - BitField("r19LoLp", None, 5), - BitField("r19HiHp", None, 3), - ByteField("r19HiLp", None), - ByteField("r20LoHp", None), - - BitField("r20LoLp", None, 5), - BitField("r20HiHp", None, 3), - ByteField("r20HiLp", None), - ByteField("r21LoHp", None), - - BitField("r21LoLp", None, 5), - BitField("r21HiHp", None, 3), - ByteField("r21HiLp", None), - ByteField("r22LoHp", None), - - BitField("r22LoLp", None, 5), - BitField("r22HiHp", None, 3), - ByteField("r22HiLp", None), - ByteField("r23LoHp", None), - - BitField("r23LoLp", None, 5), - BitField("r23HiHp", None, 3), - ByteField("r23HiLp", None), - ByteField("r24LoHp", None), - - BitField("r24LoLp", None, 5), - BitField("r24HiHp", None, 3), - ByteField("r24HiLp", None), - ByteField("r25LoHp", None), - - BitField("r25LoLp", None, 5), - BitField("r25HiHp", None, 3), - ByteField("r25HiLp", None), - ByteField("r26LoHp", None), - - BitField("r26LoLp", None, 5), - BitField("r26HiHp", None, 3), - ByteField("r26HiLp", None), - ByteField("r27LoHp", None), - - BitField("r27LoLp", None, 5), - BitField("r27HiHp", None, 3), - ByteField("r27HiLp", None), - ByteField("r28LoHp", None), - - BitField("r28LoLp", None, 5), - BitField("r28HiHp", None, 3), - ByteField("r28HiLp", None), - ByteField("r29LoHp", None), - - BitField("r29LoLp", None, 5), - BitField("r29HiHp", None, 3), - ByteField("r29HiLp", None), - ByteField("r30LoHp", None), - - BitField("r30LoLp", None, 5), - BitField("r30HiHp", None, 3), - ByteField("r30HiLp", None), - ByteField("r31LoHp", None), - - BitField("r31LoLp", None, 5), - BitField("r31HiHp", None, 3), - ByteField("r31HiLp", None), - ByteField("r32LoHp", None), - - BitField("r32LoLp", None, 5), - BitField("r32HiHp", None, 3), - ByteField("r32HiLp", None), - ByteField("r33LoHp", None), - - BitField("r33LoLp", None, 5), - BitField("r33HiHp", None, 3), - ByteField("r33HiLp", None), - ByteField("r34LoHp", None), - - BitField("r34LoLp", None, 5), - BitField("r34HiHp", None, 3), - ByteField("r34HiLp", None), - ByteField("r35LoHp", None), - - BitField("r35LoLp", None, 5), - BitField("r35HiHp", None, 3), - ByteField("r35HiLp", None), - ByteField("r36LoHp", None), - - BitField("r36LoLp", None, 5), - BitField("r36HiHp", None, 3), - ByteField("r36HiLp", None), - ByteField("r37LoHp", None), - - BitField("r37LoLp", None, 5), - BitField("r37HiHp", None, 3), - ByteField("r37HiLp", None), - ByteField("r38LoHp", None), - - BitField("r38LoLp", None, 5), - BitField("r38HiHp", None, 3), - ByteField("r38HiLp", None), - ByteField("r39LoHp", None), - - BitField("r39LoLp", None, 5), - BitField("r39HiHp", None, 3), - ByteField("r39HiLp", None), - ByteField("r40LoHp", None), - - BitField("r40LoLp", None, 5), - BitField("r40HiHp", None, 3), - ByteField("r40HiLp", None), - ByteField("r41LoHp", None), - - BitField("r41LoLp", None, 5), - BitField("r41HiHp", None, 3), - ByteField("r41HiLp", None), - ByteField("r42LoHp", None), - - BitField("r42LoLp", None, 5), - BitField("r42HiHp", None, 3), - ByteField("r42HiLp", None), - ByteField("r43LoHp", None), - - BitField("r43LoLp", None, 5), - BitField("r43HiHp", None, 3), - ByteField("r43HiLp", None), - ByteField("r44LoHp", None), - - BitField("r44LoLp", None, 5), - BitField("r44HiHp", None, 3), - ByteField("r44HiLp", None), - ByteField("r45LoHp", None), - - BitField("r45LoLp", None, 5), - BitField("r45HiHp", None, 3), - ByteField("r45HiLp", None), - ByteField("r46LoHp", None), - - BitField("r46LoLp", None, 5), - BitField("r46HiHp", None, 3), - ByteField("r46HiLp", None), - ByteField("r47LoHp", None), - - BitField("r47LoLp", None, 5), - BitField("r47HiHp", None, 3), - ByteField("r47HiLp", None), - ByteField("r48LoHp", None), - - BitField("r48LoLp", None, 5), - BitField("r48HiHp", None, 3), - ByteField("r48HiLp", None), - ByteField("r49LoHp", None), - - BitField("r49LoLp", None, 5), - BitField("r49HiHp", None, 3), - ByteField("r49HiLp", None), - ByteField("r50LoHp", None), - - BitField("r50LoLp", None, 5), - BitField("r50HiHp", None, 3), - ByteField("r50HiLp", None), - ByteField("r51LoHp", None), - - BitField("r51LoLp", None, 5), - BitField("r51HiHp", None, 3), - ByteField("r51HiLp", None), - ByteField("r52LoHp", None), - - BitField("r52LoLp", None, 5), - BitField("r52HiHp", None, 3), - ByteField("r52HiLp", None), - ByteField("r53LoHp", None), - - BitField("r53LoLp", None, 5), - BitField("r53HiHp", None, 3), - ByteField("r53HiLp", None), - ByteField("r54LoHp", None), - - BitField("r54LoLp", None, 5), - BitField("r54HiHp", None, 3), - ByteField("r54HiLp", None), - ByteField("r55LoHp", None), - - BitField("r55LoLp", None, 5), - BitField("r55HiHp", None, 3), - ByteField("r55HiLp", None), - ByteField("r56LoHp", None), - - BitField("r56LoLp", None, 5), - BitField("r56HiHp", None, 3), - ByteField("r56HiLp", None), - ByteField("r57LoHp", None), - - BitField("r57LoLp", None, 5), - BitField("r57HiHp", None, 3), - ByteField("r57HiLp", None), - ByteField("r58LoHp", None), - - BitField("r58LoLp", None, 5), - BitField("r58HiHp", None, 3), - ByteField("r58HiLp", None), - ByteField("r59LoHp", None), - - BitField("r59LoLp", None, 5), - BitField("r59HiHp", None, 3), - ByteField("r59HiLp", None), - ByteField("r60LoHp", None), - - BitField("r60LoLp", None, 5), - BitField("r60HiHp", None, 3), - ByteField("r60HiLp", None), - ByteField("r61LoHp", None), - - BitField("r61LoLp", None, 5), - BitField("r61HiHp", None, 3), - ByteField("r61HiLp", None), - ByteField("r62LoHp", None), - - BitField("r62LoLp", None, 5), - BitField("r62HiHp", None, 3), - ByteField("r62HiLp", None), - ByteField("r63LoHp", None), - - BitField("r63LoLp", None, 5), - BitField("r63HiHp", None, 3), - ByteField("r63HiLp", None), - ByteField("r64LoHp", None), - - BitField("r64LoLp", None, 5), - BitField("r64HiHp", None, 3), - ByteField("r64HiLp", None), - ByteField("r65LoHp", None), - - BitField("r65LoLp", None, 5), - BitField("r65HiHp", None, 3), - ByteField("r65HiLp", None), - ByteField("r66LoHp", None), - - BitField("r66LoLp", None, 5), - BitField("r66HiHp", None, 3), - ByteField("r66HiLp", None), - ByteField("r67LoHp", None), - - BitField("r67LoLp", None, 5), - BitField("r67HiHp", None, 3), - ByteField("r67HiLp", None), - ByteField("r68LoHp", None), - - BitField("r68LoLp", None, 5), - BitField("r68HiHp", None, 3), - ByteField("r68HiLp", None), - ByteField("r69LoHp", None), - - BitField("r69LoLp", None, 5), - BitField("r69HiHp", None, 3), - ByteField("r69HiLp", None), - ByteField("r70LoHp", None), - - BitField("r70LoLp", None, 5), - BitField("r70HiHp", None, 3), - ByteField("r70HiLp", None), - ByteField("r71LoHp", None), - - BitField("r71LoLp", None, 5), - BitField("r71HiHp", None, 3), - ByteField("r71HiLp", None), - ByteField("r72LoHp", None), - - BitField("r72LoLp", None, 5), - BitField("r72HiHp", None, 3), - ByteField("r72HiLp", None), - ByteField("r73LoHp", None), - - BitField("r73LoLp", None, 5), - BitField("r73HiHp", None, 3), - ByteField("r73HiLp", None), - ByteField("r74LoHp", None), - - BitField("r74LoLp", None, 5), - BitField("r74HiHp", None, 3), - ByteField("r74HiLp", None), - ByteField("r75LoHp", None), - - BitField("r75LoLp", None, 5), - BitField("r75HiHp", None, 3), - ByteField("r75HiLp", None), - ByteField("r76LoHp", None), - - BitField("r76LoLp", None, 5), - BitField("r76HiHp", None, 3), - ByteField("r76HiLp", None), - ByteField("r77LoHp", None), - - BitField("r77LoLp", None, 5), - BitField("r77HiHp", None, 3), - ByteField("r77HiLp", None), - ByteField("r78LoHp", None), - - BitField("r78LoLp", None, 5), - BitField("r78HiHp", None, 3), - ByteField("r78HiLp", None), - ByteField("r79LoHp", None), - - BitField("r79LoLp", None, 5), - BitField("r79HiHp", None, 3), - ByteField("r79HiLp", None), - ByteField("r80LoHp", None), - - BitField("r80LoLp", None, 5), - BitField("r80HiHp", None, 3), - ByteField("r80HiLp", None), - ByteField("r81LoHp", None), - - BitField("r81LoLp", None, 5), - BitField("r81HiHp", None, 3), - ByteField("r81HiLp", None), - ByteField("r82LoHp", None), - - BitField("r82LoLp", None, 5), - BitField("r82HiHp", None, 3), - ByteField("r82HiLp", None), - ByteField("r83LoHp", None), - - BitField("r83LoLp", None, 5), - BitField("r83HiHp", None, 3), - ByteField("r83HiLp", None), - ByteField("r84LoHp", None), - - BitField("r84LoLp", None, 5), - BitField("r84HiHp", None, 3), - ByteField("r84HiLp", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - print("i is %s" % (i,)) - aList.append(self.fields_desc[i].name) - print("aList %s" % (len(aList))) - print("self.fields_desc %s" % (len(self.fields_desc))) - for i in aList: - a.append(getattr(self, i)) - res = adapt(6, 251, a, self.fields_desc) - if self.lengthBR is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# len 3 to max for L3 message (251) -class BaListPrefHdr(Packet): - """ BA List Pref Section 10.5.2.1c """ - name = "BA List Pref" - fields_desc = [ - # FIXME dynamic - BitField("eightBitBLP", None, 1), - XBitField("ieiBLP", None, 7), - - XByteField("lengthBLP", None), - - BitField("fixBit", 0x0, 1), - BitField("rangeLower", 0x0, 10), - BitField("fixBit2", 0x0, 1), - BitField("rangeUpper", 0x0, 10), - BitField("baFreq", 0x0, 10), - BitField("sparePad", 0x0, 8) - ] - - -# len 17 || Have a look at the specs for the field format -# Bit map 0 format -# Range 1024 format -# Range 512 format -# Range 256 format -# Range 128 format -# Variable bit map format -class CellChannelDescriptionHdr(Packet): - """ Cell Channel Description Section 10.5.2.1b """ - name = "Cell Channel Description " - fields_desc = [ - BitField("eightBitCCD", None, 1), - XBitField("ieiCCD", None, 7), - BitField("bit128", 0x0, 1), - BitField("bit127", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("spare2", 0x0, 1), - BitField("bit124", 0x0, 1), - BitField("bit123", 0x0, 1), - BitField("bit122", 0x0, 1), - BitField("bit121", 0x0, 1), - ByteField("bit120", 0x0), - ByteField("bit112", 0x0), - ByteField("bit104", 0x0), - ByteField("bit96", 0x0), - ByteField("bit88", 0x0), - ByteField("bit80", 0x0), - ByteField("bit72", 0x0), - ByteField("bit64", 0x0), - ByteField("bit56", 0x0), - ByteField("bit48", 0x0), - ByteField("bit40", 0x0), - ByteField("bit32", 0x0), - ByteField("bit24", 0x0), - ByteField("bit16", 0x0), - ByteField("bit8", 0x0) - ] - - -class CellDescriptionHdr(Packet): - """ Cell Description Section 10.5.2.2 """ - name = "Cell Description" - fields_desc = [ - BitField("eightBitCD", None, 1), - XBitField("ieiCD", None, 7), - BitField("bcchHigh", 0x0, 2), - BitField("ncc", 0x0, 3), - BitField("bcc", 0x0, 3), - ByteField("bcchLow", 0x0) - ] - - -class CellOptionsBCCHHdr(Packet): - """ Cell Options (BCCH) Section 10.5.2.3 """ - name = "Cell Options (BCCH)" - fields_desc = [ - BitField("eightBitCOB", None, 1), - XBitField("ieiCOB", None, 7), - BitField("spare", 0x0, 1), - BitField("pwrc", 0x0, 1), - BitField("dtx", 0x0, 2), - BitField("rLinkTout", 0x0, 4) - ] - - -class CellOptionsSACCHHdr(Packet): - """ Cell Options (SACCH) Section 10.5.2.3a """ - name = "Cell Options (SACCH)" - fields_desc = [ - BitField("eightBitCOS", None, 1), - XBitField("ieiCOS", None, 7), - BitField("dtx", 0x0, 1), - BitField("pwrc", 0x0, 1), - BitField("dtx", 0x0, 1), - BitField("rLinkTout", 0x0, 4) - ] - - -class CellSelectionParametersHdr(Packet): - """ Cell Selection Parameters Section 10.5.2.4 """ - name = "Cell Selection Parameters" - fields_desc = [ - BitField("eightBitCSP", None, 1), - XBitField("ieiCSP", None, 7), - BitField("cellReselect", 0x0, 3), - BitField("msTxPwrMax", 0x0, 5), - BitField("acs", None, 1), - BitField("neci", None, 1), - BitField("rxlenAccMin", None, 6) - ] - - -class MacModeAndChannelCodingRequestHdr(Packet): - """ MAC Mode and Channel Coding Requested Section 10.5.2.4a """ - name = "MAC Mode and Channel Coding Requested" - fields_desc = [ - XBitField("ieiMMACCR", None, 4), - BitField("macMode", 0x0, 2), - BitField("cs", 0x0, 2) - ] - - -class ChannelDescriptionHdr(Packet): - """ Channel Description Section 10.5.2.5 """ - name = "Channel Description" - fields_desc = [ - BitField("eightBitCD", None, 1), - XBitField("ieiCD", None, 7), - - BitField("channelTyp", 0x0, 5), - BitField("tn", 0x0, 3), - - BitField("tsc", 0x0, 3), - BitField("h", 0x1, 1), - # if h=1 maybe we find a better solution here... - BitField("maioHi", 0x0, 4), - - BitField("maioLo", 0x0, 2), - BitField("hsn", 0x0, 6) - #BitField("spare", 0x0, 2), - #BitField("arfcnHigh", 0x0, 2), - #ByteField("arfcnLow", 0x0) - ] - - -class ChannelDescription2Hdr(Packet): - """ Channel Description 2 Section 10.5.2.5a """ - name = "Channel Description 2" - fields_desc = [ - BitField("eightBitCD2", None, 1), - XBitField("ieiCD2", None, 7), - BitField("channelTyp", 0x0, 5), - BitField("tn", 0x0, 3), - BitField("tsc", 0x0, 3), - BitField("h", 0x0, 1), - # if h=1 - # BitField("maioHi", 0x0, 4), - # BitField("maioLo", 0x0, 2), - # BitField("hsn", 0x0, 6) - BitField("spare", 0x0, 2), - BitField("arfcnHigh", 0x0, 2), - ByteField("arfcnLow", 0x0) - ] - - -class ChannelModeHdr(Packet): - """ Channel Mode Section 10.5.2.6 """ - name = "Channel Mode" - fields_desc = [ - BitField("eightBitCM", None, 1), - XBitField("ieiCM", None, 7), - ByteField("mode", 0x0) - ] - - -class ChannelMode2Hdr(Packet): - """ Channel Mode 2 Section 10.5.2.7 """ - name = "Channel Mode 2" - fields_desc = [ - BitField("eightBitCM2", None, 1), - XBitField("ieiCM2", None, 7), - ByteField("mode", 0x0) - ] - - -class ChannelNeededHdr(Packet): - """ Channel Needed Section 10.5.2.8 """ - name = "Channel Needed" - fields_desc = [ - XBitField("ieiCN", None, 4), - BitField("channel2", 0x0, 2), - BitField("channel1", 0x0, 2), - ] - - -class ChannelRequestDescriptionHdr(Packet): - """Channel Request Description Section 10.5.2.8a """ - name = "Channel Request Description" - fields_desc = [ - BitField("eightBitCRD", None, 1), - XBitField("ieiCRD", None, 7), - BitField("mt", 0x0, 1), - ConditionalField(BitField("spare", 0x0, 39), - lambda pkt: pkt.mt == 0), - ConditionalField(BitField("spare", 0x0, 3), - lambda pkt: pkt.mt == 1), - ConditionalField(BitField("priority", 0x0, 2), - lambda pkt: pkt.mt == 1), - ConditionalField(BitField("rlcMode", 0x0, 1), - lambda pkt: pkt.mt == 1), - ConditionalField(BitField("llcFrame", 0x1, 1), - lambda pkt: pkt.mt == 1), - ConditionalField(ByteField("reqBandMsb", 0x0), - lambda pkt: pkt.mt == 1), - ConditionalField(ByteField("reqBandLsb", 0x0), - lambda pkt: pkt.mt == 1), - ConditionalField(ByteField("rlcMsb", 0x0), - lambda pkt: pkt.mt == 1), - ConditionalField(ByteField("rlcLsb", 0x0), - lambda pkt: pkt.mt == 1) - ] - - -class CipherModeSettingHdr(Packet): - """Cipher Mode Setting Section 10.5.2.9 """ - name = "Cipher Mode Setting" - fields_desc = [ - XBitField("ieiCMS", None, 4), - BitField("algoId", 0x0, 3), - BitField("sc", 0x0, 1), - ] - - -class CipherResponseHdr(Packet): - """Cipher Response Section 10.5.2.10 """ - name = "Cipher Response" - fields_desc = [ - XBitField("ieiCR", None, 4), - BitField("spare", 0x0, 3), - BitField("cr", 0x0, 1), - ] - - -# This packet fixes the problem with the 1/2 Byte length. Concatenation -# of cipherModeSetting and cipherResponse -class CipherModeSettingAndcipherResponse(Packet): - name = "Cipher Mode Setting And Cipher Response" - fields_desc = [ - BitField("algoId", 0x0, 3), - BitField("sc", 0x0, 1), - BitField("spare", 0x0, 3), - BitField("cr", 0x0, 1) - ] - - -class ControlChannelDescriptionHdr(Packet): - """Control Channel Description Section 10.5.2.11 """ - name = "Control Channel Description" - fields_desc = [ - BitField("eightBitCCD", None, 1), - XBitField("ieiCCD", None, 7), - - BitField("spare", 0x0, 1), - BitField("att", 0x0, 1), - BitField("bsAgBlksRes", 0x0, 3), - BitField("ccchConf", 0x0, 3), - - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("spare2", 0x0, 1), - BitField("spare3", 0x0, 1), - BitField("spare4", 0x0, 1), - BitField("bsPaMfrms", 0x0, 3), - - ByteField("t3212", 0x0) - ] - - -class FrequencyChannelSequenceHdr(Packet): - """Frequency Channel Sequence Section 10.5.2.12""" - name = "Frequency Channel Sequence" - fields_desc = [ - BitField("eightBitFCS", None, 1), - XBitField("ieiFCS", None, 7), - BitField("spare", 0x0, 1), - BitField("lowestArfcn", 0x0, 7), - BitField("skipArfcn01", 0x0, 4), - BitField("skipArfcn02", 0x0, 4), - BitField("skipArfcn03", 0x0, 4), - BitField("skipArfcn04", 0x0, 4), - BitField("skipArfcn05", 0x0, 4), - BitField("skipArfcn06", 0x0, 4), - BitField("skipArfcn07", 0x0, 4), - BitField("skipArfcn08", 0x0, 4), - BitField("skipArfcn09", 0x0, 4), - BitField("skipArfcn10", 0x0, 4), - BitField("skipArfcn11", 0x0, 4), - BitField("skipArfcn12", 0x0, 4), - BitField("skipArfcn13", 0x0, 4), - BitField("skipArfcn14", 0x0, 4), - BitField("skipArfcn15", 0x0, 4), - BitField("skipArfcn16", 0x0, 4) - ] - - -class FrequencyListHdr(Packet): - """Frequency List Section 10.5.2.13""" - name = "Frequency List" - # Problem: - # There are several formats for the Frequency List information - # element, distinguished by the "format indicator" subfield. - # Some formats are frequency bit maps, the others use a special encoding - # scheme. - fields_desc = [ - BitField("eightBitFL", None, 1), - XBitField("ieiFL", None, 7), - XByteField("lengthFL", None), - - BitField("formatID", 0x0, 2), - BitField("spare", 0x0, 2), - BitField("arfcn124", 0x0, 1), - BitField("arfcn123", 0x0, 1), - BitField("arfcn122", 0x0, 1), - BitField("arfcn121", 0x0, 1), - - ByteField("arfcn120", 0x0), - ByteField("arfcn112", 0x0), - ByteField("arfcn104", 0x0), - ByteField("arfcn96", 0x0), - ByteField("arfcn88", 0x0), - ByteField("arfcn80", 0x0), - ByteField("arfcn72", 0x0), - ByteField("arfcn64", 0x0), - ByteField("arfcn56", 0x0), - ByteField("arfcn48", 0x0), - ByteField("arfcn40", 0x0), - ByteField("arfcn32", 0x0), - ByteField("arfcn24", 0x0), - ByteField("arfcn16", 0x0), - ByteField("arfcn8", 0x0) - ] - - -class FrequencyShortListHdr(Packet): - """Frequency Short List Section 10.5.2.14""" - name = "Frequency Short List" -# len is 10 -#This element is encoded exactly as the Frequency List information element, -#except that it has a fixed length instead of a -#variable length and does not contain a length indicator and that it -#shall not be encoded in bitmap 0 format. - fields_desc = [ - ByteField("ieiFSL", 0x0), - ByteField("byte2", 0x0), - ByteField("byte3", 0x0), - ByteField("byte4", 0x0), - ByteField("byte5", 0x0), - ByteField("byte6", 0x0), - ByteField("byte7", 0x0), - ByteField("byte8", 0x0), - ByteField("byte9", 0x0), - ByteField("byte10", 0x0) - ] - - -class FrequencyShortListHdr2(Packet): - """Frequency Short List2 Section 10.5.2.14a""" - name = "Frequency Short List 2" - fields_desc = [ - ByteField("byte1", 0x0), - ByteField("byte2", 0x0), - ByteField("byte3", 0x0), - ByteField("byte4", 0x0), - ByteField("byte5", 0x0), - ByteField("byte6", 0x0), - ByteField("byte7", 0x0), - ByteField("byte8", 0x0) - ] - - -# len 4 to 13 -class GroupChannelDescriptionHdr(Packet): - """Group Channel Description Section 10.5.2.14b""" - name = "Group Channel Description" - fields_desc = [ - BitField("eightBitGCD", None, 1), - XBitField("ieiGCD", None, 7), - - XByteField("lengthGCD", None), - - BitField("channelType", 0x0, 5), - BitField("tn", 0x0, 3), - - BitField("tsc", 0x0, 3), - BitField("h", 0x0, 1), - # if h == 0 the packet looks the following way: - ConditionalField(BitField("spare", 0x0, 2), - lambda pkt: pkt. h == 0x0), - ConditionalField(BitField("arfcnHi", 0x0, 2), - lambda pkt: pkt. h == 0x0), - ConditionalField(ByteField("arfcnLo", None), - lambda pkt: pkt. h == 0x0), - # if h == 1 the packet looks the following way: - ConditionalField(BitField("maioHi", 0x0, 4), - lambda pkt: pkt. h == 0x1), - ConditionalField(BitField("maioLo", None, 2), - lambda pkt: pkt. h == 0x1), - ConditionalField(BitField("hsn", None, 6), - lambda pkt: pkt. h == 0x1), - # finished with conditional fields - ByteField("maC6", None), - ByteField("maC7", None), - ByteField("maC8", None), - ByteField("maC9", None), - ByteField("maC10", None), - ByteField("maC11", None), - ByteField("maC12", None), - ByteField("maC13", None), - ByteField("maC14", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(4, 13, a, self.fields_desc) - if self.lengthGCD is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class GprsResumptionHdr(Packet): - """GPRS Resumption Section 10.5.2.14c""" - name = "GPRS Resumption" - fields_desc = [ - XBitField("ieiGR", None, 4), - BitField("spare", 0x0, 3), - BitField("ack", 0x0, 1) - ] - - -class HandoverReferenceHdr(Packet): - """Handover Reference Section 10.5.2.15""" - name = "Handover Reference" - fields_desc = [ - BitField("eightBitHR", None, 1), - XBitField("ieiHR", None, 7), - ByteField("handoverRef", 0x0) - ] - - -# len 1-12 -class IaRestOctets(Packet): - """IA Rest Octets Section 10.5.2.16""" - name = "IA Rest Octets" - fields_desc = [ - ByteField("ieiIRO", 0x0), - # FIXME brainfuck packet - XByteField("lengthIRO", None), - ByteField("byte2", None), - ByteField("byte3", None), - ByteField("byte4", None), - ByteField("byte5", None), - ByteField("byte6", None), - ByteField("byte7", None), - ByteField("byte8", None), - ByteField("byte9", None), - ByteField("byte10", None), - ByteField("byte11", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(1, 12, a, self.fields_desc) - if self.lengthIRO is None: - if res[1] < 0: # FIXME better fix - res[1] = 0 - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class IraRestOctetsHdr(Packet): - """IAR Rest Octets Section 10.5.2.17""" - name = "IAR Rest Octets" - fields_desc = [ - BitField("eightBitIRO", None, 1), - XBitField("ieiIRO", None, 7), - BitField("spare01", 0x0, 1), - BitField("spare02", 0x0, 1), - BitField("spare03", 0x1, 1), - BitField("spare04", 0x0, 1), - BitField("spare05", 0x1, 1), - BitField("spare06", 0x0, 1), - BitField("spare07", 0x1, 1), - BitField("spare08", 0x1, 1), - BitField("spare09", 0x0, 1), - BitField("spare10", 0x0, 1), - BitField("spare11", 0x1, 1), - BitField("spare12", 0x0, 1), - BitField("spare13", 0x1, 1), - BitField("spare14", 0x0, 1), - BitField("spare15", 0x1, 1), - BitField("spare16", 0x1, 1), - BitField("spare17", 0x0, 1), - BitField("spare18", 0x0, 1), - BitField("spare19", 0x1, 1), - BitField("spare20", 0x0, 1), - BitField("spare21", 0x1, 1), - BitField("spare22", 0x0, 1), - BitField("spare23", 0x1, 1), - BitField("spare24", 0x1, 1) - ] - - -# len is 1 to 5 what do we do with the variable size? no lenght -# field?! WTF -class IaxRestOctetsHdr(Packet): - """IAX Rest Octets Section 10.5.2.18""" - name = "IAX Rest Octets" - fields_desc = [ - BitField("eightBitIRO", None, 1), - XBitField("ieiIRO", None, 7), - BitField("spare01", 0x0, 1), - BitField("spare02", 0x0, 1), - BitField("spare03", 0x1, 1), - BitField("spare04", 0x0, 1), - BitField("spare05", 0x1, 1), - BitField("spare06", 0x0, 1), - BitField("spare07", 0x1, 1), - BitField("spare08", 0x1, 1), - ByteField("spareB1", None), - ByteField("spareB2", None), - ByteField("spareB3", None) - ] - - -class L2PseudoLengthHdr(Packet): - """L2 Pseudo Length Section 10.5.2.19""" - name = "L2 Pseudo Length" - fields_desc = [ - BitField("eightBitPL", None, 1), - XBitField("ieiPL", None, 7), - BitField("l2pLength", None, 6), - BitField("bit2", 0x0, 1), - BitField("bit1", 0x1, 1) - ] - - -class MeasurementResultsHdr(Packet): - """Measurement Results Section 10.5.2.20""" - name = "Measurement Results" - fields_desc = [ - BitField("eightBitMR", None, 1), - XBitField("ieiMR", None, 7), - BitField("baUsed", 0x0, 1), - BitField("dtxUsed", 0x0, 1), - BitField("rxLevFull", 0x0, 6), - BitField("spare", 0x0, 1), - BitField("measValid", 0x0, 1), - BitField("rxLevSub", 0x0, 6), - BitField("spare0", 0x0, 1), - BitField("rxqualFull", 0x0, 3), - BitField("rxqualSub", 0x0, 3), - BitField("noNcellHi", 0x0, 1), - BitField("noNcellLo", 0x0, 2), - BitField("rxlevC1", 0x0, 6), - BitField("bcchC1", 0x0, 5), - BitField("bsicC1Hi", 0x0, 3), - BitField("bsicC1Lo", 0x0, 3), - BitField("rxlevC2", 0x0, 5), - BitField("rxlevC2Lo", 0x0, 1), - BitField("bcchC2", 0x0, 5), - BitField("bsicC1Hi", 0x0, 2), - BitField("bscicC2Lo", 0x0, 4), - BitField("bscicC2Hi", 0x0, 4), - - BitField("rxlevC3Lo", 0x0, 2), - BitField("bcchC3", 0x0, 5), - BitField("rxlevC3Hi", 0x0, 1), - - BitField("bsicC3Lo", 0x0, 5), - BitField("bsicC3Hi", 0x0, 3), - - BitField("rxlevC4Lo", 0x0, 3), - BitField("bcchC4", 0x0, 5), - - BitField("bsicC4", 0x0, 6), - BitField("rxlevC5Hi", 0x0, 2), - - BitField("rxlevC5Lo", 0x0, 4), - BitField("bcchC5Hi", 0x0, 4), - - BitField("bcchC5Lo", 0x0, 1), - BitField("bsicC5", 0x0, 6), - BitField("rxlevC6", 0x0, 1), - - BitField("rxlevC6Lo", 0x0, 5), - BitField("bcchC6Hi", 0x0, 3), - - BitField("bcchC6Lo", 0x0, 3), - BitField("bsicC6", 0x0, 5) - ] - - -class GprsMeasurementResultsHdr(Packet): - """GPRS Measurement Results Section 10.5.2.20a""" - name = "GPRS Measurement Results" - fields_desc = [ - BitField("eightBitGMR", None, 1), - XBitField("ieiGMR", None, 7), - BitField("cValue", 0x0, 6), - BitField("rxqualHi", 0x0, 2), - BitField("rxqL", 0x0, 1), - BitField("spare", 0x0, 1), - BitField("signVar", 0x0, 6) - ] - - -# len 3 to 10 -class MobileAllocationHdr(Packet): - """Mobile Allocation Section 10.5.2.21""" - name = "Mobile Allocation" - fields_desc = [ - BitField("eightBitMA", None, 1), - XBitField("ieiMA", None, 7), - XByteField("lengthMA", None), - ByteField("maC64", 0x12), - ByteField("maC56", None), # optional fields start here - ByteField("maC48", None), - ByteField("maC40", None), - ByteField("maC32", None), - ByteField("maC24", None), - ByteField("maC16", None), - ByteField("maC8", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(3, 10, a, self.fields_desc) - if self.lengthMA is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class MobileTimeDifferenceHdr(Packet): - """Mobile Time Difference Section 10.5.2.21a""" - name = "Mobile Time Difference" - fields_desc = [ - BitField("eightBitMTD", None, 1), - XBitField("ieiMTD", None, 7), - XByteField("lengthMTD", 0x5), - ByteField("valueHi", 0x0), - ByteField("valueCnt", 0x0), - BitField("valueLow", 0x0, 5), - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("spare2", 0x0, 1) - ] - - -# min 4 octets max 8 -class MultiRateConfigurationHdr(Packet): - """ MultiRate configuration Section 10.5.2.21aa""" - name = "MultiRate Configuration" - fields_desc = [ - BitField("eightBitMRC", None, 1), - XBitField("ieiMRC", None, 7), - - XByteField("lengthMRC", None), - - BitField("mrVersion", 0x0, 3), - BitField("spare", 0x0, 1), - BitField("icmi", 0x0, 1), - BitField("spare", 0x0, 1), - BitField("startMode", 0x0, 2), - - ByteField("amrCodec", 0x0), - - BitField("spare", None, 2), - BitField("threshold1", None, 6), - - BitField("hysteresis1", None, 4), - BitField("threshold2", None, 4), - - BitField("threshold2cnt", None, 2), - BitField("hysteresis2", None, 4), - BitField("threshold3", None, 2), - - BitField("threshold3cnt", None, 4), - BitField("hysteresis3", None, 4) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(4, 8, a, self.fields_desc) - if self.lengthMRC is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# len 3 to 12 -class MultislotAllocationHdr(Packet): - """Multislot Allocation Section 10.5.2.21b""" - name = "Multislot Allocation" - fields_desc = [ - BitField("eightBitMSA", None, 1), - XBitField("ieiMSA", None, 7), - XByteField("lengthMSA", None), - BitField("ext0", 0x1, 1), - BitField("da", 0x0, 7), - ConditionalField(BitField("ext1", 0x1, 1), # optional - lambda pkt: pkt.ext0 == 0), - ConditionalField(BitField("ua", 0x0, 7), - lambda pkt: pkt.ext0 == 0), - ByteField("chan1", None), - ByteField("chan2", None), - ByteField("chan3", None), - ByteField("chan4", None), - ByteField("chan5", None), - ByteField("chan6", None), - ByteField("chan7", None), - ByteField("chan8", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(3, 12, a, self.fields_desc) - if res[0] is not 0: - p = p[:-res[0]] - if self.lengthMSA is None: - p = p[:1] + struct.pack(">B", len(p)-2) + p[2:] - return p + pay - - -class NcModeHdr(Packet): - """NC mode Section 10.5.2.21c""" - name = "NC Mode" - fields_desc = [ - XBitField("ieiNM", None, 4), - BitField("spare", 0x0, 2), - BitField("ncMode", 0x0, 2) - ] - - -# Fix for len problem -# concatenation NC Mode And Spare Half Octets -class NcModeAndSpareHalfOctets(Packet): - name = "NC Mode And Spare Half Octets" - fields_desc = [ - BitField("spare", 0x0, 2), - BitField("ncMode", 0x0, 2), - BitField("spareHalfOctets", 0x0, 4) - ] - - -class NeighbourCellsDescriptionHdr(Packet): - """Neighbour Cells Description Section 10.5.2.22""" - name = "Neighbour Cells Description" - fields_desc = [ - BitField("eightBitNCD", None, 1), - XBitField("ieiNCD", None, 7), - BitField("bit128", 0x0, 1), - BitField("bit127", 0x0, 1), - BitField("extInd", 0x0, 1), - BitField("baInd", 0x0, 1), - BitField("bit124", 0x0, 1), - BitField("bit123", 0x0, 1), - BitField("bit122", 0x0, 1), - BitField("bit121", 0x0, 1), - BitField("120bits", 0x0, 120) - ] - - -class NeighbourCellsDescription2Hdr(Packet): - """Neighbour Cells Description 2 Section 10.5.2.22a""" - name = "Neighbour Cells Description 2" - fields_desc = [ - BitField("eightBitNCD2", None, 1), - XBitField("ieiNCD2", None, 7), - BitField("bit128", 0x0, 1), - BitField("multiband", 0x0, 2), - BitField("baInd", 0x0, 1), - BitField("bit124", 0x0, 1), - BitField("bit123", 0x0, 1), - BitField("bit122", 0x0, 1), - BitField("bit121", 0x0, 1), - BitField("120bits", 0x0, 120) - ] - - -class NtNRestOctets(Packet): - """NT/N Rest Octets Section 10.5.2.22c""" - name = "NT/N Rest Octets" - fields_desc = [ - BitField("nln", 0x0, 2), - BitField("ncnInfo", 0x0, 4), - BitField("spare", 0x0, 2) - ] - - -# -# The following packet has no length info! -# -# len 1-18 -class P1RestOctets(Packet): - """P1 Rest Octets Section 10.5.2.23""" - name = "P1 Rest Octets" - fields_desc = [ - BitField("nln", 0x0, 2), - BitField("nlnStatus", 0x0, 1), - BitField("prio1", 0x0, 3), - BitField("prio2", 0x0, 3), - # optional - BitField("pageIndication1", 0x0, 1), - BitField("pageIndication2", 0x0, 1), - BitField("spare", 0x0, 5), - ByteField("spareB1", None), - ByteField("spareB2", None), - ByteField("spareB3", None), - ByteField("spareB4", None), - ByteField("spareB5", None), - ByteField("spareB6", None), - ByteField("spareB7", None), - ByteField("spareB8", None), - ByteField("spareB9", None), - ByteField("spareB10", None), - ByteField("spareB11", None), - ByteField("spareB12", None), - ByteField("spareB13", None), - ByteField("spareB14", None), - ByteField("spareB15", None), - ByteField("spareB16", None), - ] - - -# len 2-12 -class P2RestOctets(Packet): - """P2 Rest Octets Section 10.5.2.24""" - name = "P2 Rest Octets" - fields_desc = [ - BitField("cn3", 0x0, 2), - BitField("nln", 0x0, 2), - BitField("nlnStatus", 0x0, 1), - BitField("prio1", 0x0, 3), - - BitField("prio2", 0x0, 3), - BitField("prio3", 0x0, 3), - BitField("pageIndication3", 0x0, 1), - BitField("spare", 0x0, 1), - - # optinal (No length field!) - ByteField("spareB1", None), - ByteField("spareB2", None), - ByteField("spareB3", None), - ByteField("spareB4", None), - - ByteField("spareB5", None), - ByteField("spareB6", None), - ByteField("spareB7", None), - ByteField("spareB8", None), - - ByteField("spareB9", None), - ByteField("spareB10", None) - ] - - -# len 4 -class P3RestOctets(Packet): - """P3 Rest Octets Section 10.5.2.25""" - name = "P3 Rest Octets" - fields_desc = [ - BitField("cn3", 0x0, 2), - BitField("cn4", 0x0, 2), - BitField("nln", 0x0, 2), - BitField("nlnStatus", 0x0, 1), - BitField("prio1", 0x0, 3), - BitField("prio2", 0x0, 3), - BitField("prio3", 0x0, 3), - BitField("prio4", 0x0, 3), - BitField("spare", 0x0, 5) - ] - - -# len 4 -# strange packet, lots of valid formats - -# ideas for the dynamic packets: -# 1] for user interaction: Create an interactive "builder" based on a -# Q/A process (not very scapy like) -# 2] for usage in scripts, create an alternative packet for every -# possible packet layout -# - - -class PacketChannelDescription(Packet): - """Packet Channel Description Section 10.5.2.25a""" - name = "Packet Channel Description" - fields_desc = [ - ByteField("ieiPCD", None), - BitField("chanType", 0x0, 5), # This packet has multiple - # possible layouts. I moddeled the first one - BitField("tn", 0x0, 3), # maybe build an - #"interactive" builder. Like - # a Q/A then propose a - # packet? - BitField("tsc", 0x0, 3), - BitField("chooser1", 0x0, 1), - BitField("chooser2", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("arfcn", 0x0, 10), - ] - - -class DedicatedModeOrTBFHdr(Packet): - """Dedicated mode or TBF Section 10.5.2.25b""" - name = "Dedicated Mode or TBF" - fields_desc = [ - XBitField("ieiDMOT", None, 4), - BitField("spare", 0x0, 1), - BitField("tma", 0x0, 1), - BitField("downlink", 0x0, 1), - BitField("td", 0x0, 1) - ] - - -# FIXME add implementation -class RrPacketUplinkAssignment(Packet): - """RR Packet Uplink Assignment Section 10.5.2.25c""" - name = "RR Packet Uplink Assignment" - fields_desc = [ - # Fill me - ] - - -class PageModeHdr(Packet): - """Page Mode Section 10.5.2.26""" - name = "Page Mode" - fields_desc = [ - XBitField("ieiPM", None, 4), - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("pm", 0x0, 2) - ] - - -# Fix for 1/2 len problem -# concatenation: pageMode and dedicatedModeOrTBF -class PageModeAndDedicatedModeOrTBF(Packet): - name = "Page Mode and Dedicated Mode Or TBF" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("pm", 0x0, 2), - BitField("spare", 0x0, 1), - BitField("tma", 0x0, 1), - BitField("downlink", 0x0, 1), - BitField("td", 0x0, 1) - ] - - -# Fix for 1/2 len problem -# concatenation: pageMode and spareHalfOctets -class PageModeAndSpareHalfOctets(Packet): - name = "Page Mode and Spare Half Octets" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("pm", 0x0, 2), - BitField("spareHalfOctets", 0x0, 4) - ] - - -# Fix for 1/2 len problem -# concatenation: pageMode and Channel Needed -class PageModeAndChannelNeeded(Packet): - name = "Page Mode and Channel Needed" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("pm", 0x0, 2), - BitField("channel2", 0x0, 2), - BitField("channel1", 0x0, 2) - ] - - -class NccPermittedHdr(Packet): - """NCC Permitted Section 10.5.2.27""" - name = "NCC Permited" - fields_desc = [ - BitField("eightBitNP", None, 1), - XBitField("ieiNP", None, 7), - ByteField("nccPerm", 0x0) - ] - - -class PowerCommandHdr(Packet): - """Power Command Section 10.5.2.28""" - name = "Power Command" - fields_desc = [ - BitField("eightBitPC", None, 1), - XBitField("ieiPC", None, 7), - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("spare2", 0x0, 1), - BitField("powerLvl", 0x0, 5) - ] - - -class PowerCommandAndAccessTypeHdr(Packet): - """Power Command and access type Section 10.5.2.28a""" - name = "Power Command and Access Type" - fields_desc = [ - BitField("eightBitPCAAT", None, 1), - XBitField("ieiPCAAT", None, 7), - BitField("atc", 0x0, 1), - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("powerLvl", 0x0, 5) - ] - - -class RachControlParametersHdr(Packet): - """RACH Control Parameters Section 10.5.2.29""" - name = "RACH Control Parameters" - fields_desc = [ - BitField("eightBitRCP", None, 1), - XBitField("ieiRCP", None, 7), - BitField("maxRetrans", 0x0, 2), - BitField("txInteger", 0x0, 4), - BitField("cellBarrAccess", 0x0, 1), - BitField("re", 0x0, 1), - BitField("ACC15", 0x0, 1), - BitField("ACC14", 0x0, 1), - BitField("ACC13", 0x0, 1), - BitField("ACC12", 0x0, 1), - BitField("ACC11", 0x0, 1), - BitField("ACC10", 0x0, 1), - BitField("ACC09", 0x0, 1), - BitField("ACC08", 0x0, 1), - BitField("ACC07", 0x0, 1), - BitField("ACC06", 0x0, 1), - BitField("ACC05", 0x0, 1), - BitField("ACC04", 0x0, 1), - BitField("ACC03", 0x0, 1), - BitField("ACC02", 0x0, 1), - BitField("ACC01", 0x0, 1), - BitField("ACC00", 0x0, 1), - ] - - -class RequestReferenceHdr(Packet): - """Request Reference Section 10.5.2.30""" - name = "Request Reference" - fields_desc = [ - BitField("eightBitRR", None, 1), - XBitField("ieiRR", None, 7), - ByteField("ra", 0x0), - BitField("t1", 0x0, 5), - BitField("t3Hi", 0x0, 3), - BitField("t3Lo", 0x0, 3), - BitField("t2", 0x0, 5) - ] - - -class RrCauseHdr(Packet): - """RR Cause Section 10.5.2.31""" - name = "RR Cause" - fields_desc = [ - BitField("eightBitRC", None, 1), - XBitField("ieiRC", None, 7), - ByteField("rrCause", 0x0) - ] - - -class Si1RestOctets(Packet): - """SI 1 Rest Octets Section 10.5.2.32""" - name = "SI 1 Rest Octets" - fields_desc = [ - ByteField("nchPos", 0x0) - ] - - -class Si2bisRestOctets(Packet): - """SI 2bis Rest Octets Section 10.5.2.33""" - name = "SI 2bis Rest Octets" - fields_desc = [ - ByteField("spare", 0x0) - ] - - -class Si2terRestOctets(Packet): - """SI 2ter Rest Octets Section 10.5.2.33a""" - name = "SI 2ter Rest Octets" - fields_desc = [ - ByteField("spare1", 0x0), - ByteField("spare2", 0x0), - ByteField("spare3", 0x0), - ByteField("spare4", 0x0) - ] - - -# len 5 -class Si3RestOctets(Packet): - """SI 3 Rest Octets Section 10.5.2.34""" - name = "SI 3 Rest Octets" - fields_desc = [ - ByteField("byte1", 0x0), - ByteField("byte2", 0x0), - ByteField("byte3", 0x0), - ByteField("byte4", 0x0), - ByteField("byte5", 0x0) - ] - - -# len 1 to 11 -class Si4RestOctets(Packet): - """SI 4 Rest Octets Section 10.5.2.35""" - name = "SI 4 Rest Octets" - fields_desc = [ - XByteField("lengthSI4", None), - ByteField("byte2", None), - ByteField("byte3", None), - ByteField("byte4", None), - ByteField("byte5", None), - ByteField("byte6", None), - ByteField("byte7", None), - ByteField("byte8", None), - ByteField("byte9", None), - ByteField("byte10", None), - ByteField("byte11", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(1, 11, a, self.fields_desc, 1) - if self.lengthSI4 is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - if len(p) is 1: # length of this packet can be 0, but packet is - p = '' # but the IE is manadatory 0_o - return p + pay - - -class Si6RestOctets(Packet): - """SI 6 Rest Octets Section 10.5.2.35a""" - name = "SI 4 Rest Octets" - fields_desc = [ - # FIXME - ] - - -# len 21 -class Si7RestOctets(Packet): - """SI 7 Rest Octets Section 10.5.2.36""" - name = "SI 7 Rest Octets" - fields_desc = [ - # FIXME - XByteField("lengthSI7", 0x15), - ByteField("byte2", 0x0), - ByteField("byte3", 0x0), - ByteField("byte4", 0x0), - ByteField("byte5", 0x0), - ByteField("byte6", 0x0), - ByteField("byte7", 0x0), - ByteField("byte8", 0x0), - ByteField("byte9", 0x0), - ByteField("byte10", 0x0), - ByteField("byte11", 0x0), - ByteField("byte12", 0x0), - ByteField("byte13", 0x0), - ByteField("byte14", 0x0), - ByteField("byte15", 0x0), - ByteField("byte16", 0x0), - ByteField("byte17", 0x0), - ByteField("byte18", 0x0), - ByteField("byte19", 0x0), - ByteField("byte20", 0x0), - ByteField("byte21", 0x0) - ] - - -# len 21 -class Si8RestOctets(Packet): - """SI 8 Rest Octets Section 10.5.2.37""" - name = "SI 8 Rest Octets" - fields_desc = [ - # FIXME - XByteField("lengthSI8", 0x15), - ByteField("byte2", 0x0), - ByteField("byte3", 0x0), - ByteField("byte4", 0x0), - ByteField("byte5", 0x0), - ByteField("byte6", 0x0), - ByteField("byte7", 0x0), - ByteField("byte8", 0x0), - ByteField("byte9", 0x0), - ByteField("byte10", 0x0), - ByteField("byte11", 0x0), - ByteField("byte12", 0x0), - ByteField("byte13", 0x0), - ByteField("byte14", 0x0), - ByteField("byte15", 0x0), - ByteField("byte16", 0x0), - ByteField("byte17", 0x0), - ByteField("byte18", 0x0), - ByteField("byte19", 0x0), - ByteField("byte20", 0x0), - ByteField("byte21", 0x0) - ] - - -#len 17 -class Si9RestOctets(Packet): - """SI 9 Rest Octets Section 10.5.2.37a""" - name = "SI 9 Rest Octets" - fields_desc = [ - # FIXME - XByteField("lengthSI9", 0x11), - ByteField("byte2", 0x0), - ByteField("byte3", 0x0), - ByteField("byte4", 0x0), - ByteField("byte5", 0x0), - ByteField("byte6", 0x0), - ByteField("byte7", 0x0), - ByteField("byte8", 0x0), - ByteField("byte9", 0x0), - ByteField("byte10", 0x0), - ByteField("byte11", 0x0), - ByteField("byte12", 0x0), - ByteField("byte13", 0x0), - ByteField("byte14", 0x0), - ByteField("byte15", 0x0), - ByteField("byte16", 0x0), - ByteField("byte17", 0x0) - ] - - -# len 21 -class Si13RestOctets(Packet): - """SI 13 Rest Octets Section 10.5.2.37b""" - name = "SI 13 Rest Octets" - fields_desc = [ - # FIXME - XByteField("lengthSI3", 0x15), - ByteField("byte2", 0x0), - ByteField("byte3", 0x0), - ByteField("byte4", 0x0), - ByteField("byte5", 0x0), - ByteField("byte6", 0x0), - ByteField("byte7", 0x0), - ByteField("byte8", 0x0), - ByteField("byte9", 0x0), - ByteField("byte10", 0x0), - ByteField("byte11", 0x0), - ByteField("byte12", 0x0), - ByteField("byte13", 0x0), - ByteField("byte14", 0x0), - ByteField("byte15", 0x0), - ByteField("byte16", 0x0), - ByteField("byte17", 0x0), - ByteField("byte18", 0x0), - ByteField("byte19", 0x0), - ByteField("byte20", 0x0), - ByteField("byte21", 0x0) - ] - - -# 10.5.2.37c [spare] -# 10.5.2.37d [spare] - - -# len 21 -class Si16RestOctets(Packet): - """SI 16 Rest Octets Section 10.5.2.37e""" - name = "SI 16 Rest Octets" - fields_desc = [ - # FIXME - XByteField("lengthSI16", 0x15), - ByteField("byte2", 0x0), - ByteField("byte3", 0x0), - ByteField("byte4", 0x0), - ByteField("byte5", 0x0), - ByteField("byte6", 0x0), - ByteField("byte7", 0x0), - ByteField("byte8", 0x0), - ByteField("byte9", 0x0), - ByteField("byte10", 0x0), - ByteField("byte11", 0x0), - ByteField("byte12", 0x0), - ByteField("byte13", 0x0), - ByteField("byte14", 0x0), - ByteField("byte15", 0x0), - ByteField("byte16", 0x0), - ByteField("byte17", 0x0), - ByteField("byte18", 0x0), - ByteField("byte19", 0x0), - ByteField("byte20", 0x0), - ByteField("byte21", 0x0) - ] - - -# len 21 -class Si17RestOctets(Packet): - """SI 17 Rest Octets Section 10.5.2.37f""" - name = "SI 17 Rest Octets" - fields_desc = [ - # FIXME - XByteField("lengthSI17", 0x15), - ByteField("byte2", 0x0), - ByteField("byte3", 0x0), - ByteField("byte4", 0x0), - ByteField("byte5", 0x0), - ByteField("byte6", 0x0), - ByteField("byte7", 0x0), - ByteField("byte8", 0x0), - ByteField("byte9", 0x0), - ByteField("byte10", 0x0), - ByteField("byte11", 0x0), - ByteField("byte12", 0x0), - ByteField("byte13", 0x0), - ByteField("byte14", 0x0), - ByteField("byte15", 0x0), - ByteField("byte16", 0x0), - ByteField("byte17", 0x0), - ByteField("byte18", 0x0), - ByteField("byte19", 0x0), - ByteField("byte20", 0x0), - ByteField("byte21", 0x0) - ] - - -class StartingTimeHdr(Packet): - """Starting Time Section 10.5.2.38""" - name = "Starting Time" - fields_desc = [ - BitField("eightBitST", None, 1), - XBitField("ieiST", None, 7), - ByteField("ra", 0x0), - BitField("t1", 0x0, 5), - BitField("t3Hi", 0x0, 3), - BitField("t3Lo", 0x0, 3), - BitField("t2", 0x0, 5) - ] - - -class SynchronizationIndicationHdr(Packet): - """Synchronization Indication Section 10.5.2.39""" - name = "Synchronization Indication" - fields_desc = [ - XBitField("ieiSI", None, 4), - BitField("nci", 0x0, 1), - BitField("rot", 0x0, 1), - BitField("si", 0x0, 2) - ] - - -class TimingAdvanceHdr(Packet): - """Timing Advance Section 10.5.2.40""" - name = "Timing Advance" - fields_desc = [ - BitField("eightBitTA", None, 1), - XBitField("ieiTA", None, 7), - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("timingVal", 0x0, 6) - ] - - -class TimeDifferenceHdr(Packet): - """ Time Difference Section 10.5.2.41""" - name = "Time Difference" - fields_desc = [ - BitField("eightBitTD", None, 1), - XBitField("ieiTD", None, 7), - XByteField("lengthTD", 0x3), - ByteField("timeValue", 0x0) - ] - - -class TlliHdr(Packet): - """ TLLI Section Section 10.5.2.41a""" - name = "TLLI" - fields_desc = [ - BitField("eightBitT", None, 1), - XBitField("ieiT", None, 7), - ByteField("value", 0x0), - ByteField("value1", 0x0), - ByteField("value2", 0x0), - ByteField("value3", 0x0) - ] - - -class TmsiPTmsiHdr(Packet): - """ TMSI/P-TMSI Section 10.5.2.42""" - name = "TMSI/P-TMSI" - fields_desc = [ - BitField("eightBitTPT", None, 1), - XBitField("ieiTPT", None, 7), - ByteField("value", 0x0), - ByteField("value1", 0x0), - ByteField("value2", 0x0), - ByteField("value3", 0x0) - ] - - -class VgcsTargetModeIdenticationHdr(Packet): - """ VGCS target Mode Indication 10.5.2.42a""" - name = "VGCS Target Mode Indication" - fields_desc = [ - BitField("eightBitVTMI", None, 1), - XBitField("ieiVTMI", None, 7), - XByteField("lengthVTMI", 0x2), - BitField("targerMode", 0x0, 2), - BitField("cipherKeyNb", 0x0, 4), - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1) - ] - - -class WaitIndicationHdr(Packet): - """ Wait Indication Section 10.5.2.43""" - name = "Wait Indication" - fields_desc = [ # asciiart of specs strange - BitField("eightBitWI", None, 1), - XBitField("ieiWI", None, 7), - ByteField("timeoutVal", 0x0) - ] - - -# len 17 -class ExtendedMeasurementResultsHdr(Packet): - """EXTENDED MEASUREMENT RESULTS Section 10.5.2.45""" - name = "Extended Measurement Results" - fields_desc = [ - BitField("eightBitEMR", None, 1), - XBitField("ieiEMR", None, 7), - - BitField("scUsed", None, 1), - BitField("dtxUsed", None, 1), - BitField("rxLevC0", None, 6), - - BitField("rxLevC1", None, 6), - BitField("rxLevC2Hi", None, 2), - - BitField("rxLevC2Lo", None, 4), - BitField("rxLevC3Hi", None, 4), - - BitField("rxLevC3Lo", None, 3), - BitField("rxLevC4", None, 5), - - BitField("rxLevC5", None, 6), - BitField("rxLevC6Hi", None, 2), - - BitField("rxLevC6Lo", None, 4), - BitField("rxLevC7Hi", None, 4), - - BitField("rxLevC7Lo", None, 2), - BitField("rxLevC8", None, 6), - - BitField("rxLevC9", None, 6), - BitField("rxLevC10Hi", None, 2), - - BitField("rxLevC10Lo", None, 4), - BitField("rxLevC11Hi", None, 4), - - BitField("rxLevC13Lo", None, 2), - BitField("rxLevC12", None, 6), - - BitField("rxLevC13", None, 6), - BitField("rxLevC14Hi", None, 2), - - BitField("rxLevC14Lo", None, 4), - BitField("rxLevC15Hi", None, 4), - - BitField("rxLevC15Lo", None, 2), - BitField("rxLevC16", None, 6), - - - BitField("rxLevC17", None, 6), - BitField("rxLevC18Hi", None, 2), - - BitField("rxLevC18Lo", None, 4), - BitField("rxLevC19Hi", None, 4), - - BitField("rxLevC19Lo", None, 2), - BitField("rxLevC20", None, 6) - ] - - -# len 17 -class ExtendedMeasurementFrequencyListHdr(Packet): - """Extended Measurement Frequency List Section 10.5.2.46""" - name = "Extended Measurement Frequency List" - fields_desc = [ - BitField("eightBitEMFL", None, 1), - XBitField("ieiEMFL", None, 7), - - BitField("bit128", 0x0, 1), - BitField("bit127", 0x0, 1), - BitField("spare", 0x0, 1), - BitField("seqCode", 0x0, 1), - BitField("bit124", 0x0, 1), - BitField("bit123", 0x0, 1), - BitField("bit122", 0x0, 1), - BitField("bit121", 0x0, 1), - - BitField("bitsRest", 0x0, 128) - ] - - -class SuspensionCauseHdr(Packet): - """Suspension Cause Section 10.5.2.47""" - name = "Suspension Cause" - fields_desc = [ - BitField("eightBitSC", None, 1), - XBitField("ieiSC", None, 7), - ByteField("suspVal", 0x0) - ] - - -class ApduIDHdr(Packet): - """APDU Flags Section 10.5.2.48""" - name = "Apdu Id" - fields_desc = [ - XBitField("ieiAI", None, 4), - BitField("id", None, 4) - ] - - -class ApduFlagsHdr(Packet): - """APDU Flags Section 10.5.2.49""" - name = "Apdu Flags" - fields_desc = [ - XBitField("iei", None, 4), - BitField("spare", 0x0, 1), - BitField("cr", 0x0, 1), - BitField("firstSeg", 0x0, 1), - BitField("lastSeg", 0x0, 1) - ] - - -# Fix 1/2 len problem -class ApduIDAndApduFlags(Packet): - name = "Apu Id and Apdu Flags" - fields_desc = [ - BitField("id", None, 4), - BitField("spare", 0x0, 1), - BitField("cr", 0x0, 1), - BitField("firstSeg", 0x0, 1), - BitField("lastSeg", 0x0, 1) - ] - - -# len 2 to max L3 (251) (done) -class ApduDataHdr(Packet): - """APDU Data Section 10.5.2.50""" - name = "Apdu Data" - fields_desc = [ - BitField("eightBitAD", None, 1), - XBitField("ieiAD", None, 7), - XByteField("lengthAD", None), - #optional - ByteField("apuInfo1", None), - ByteField("apuInfo2", None), - ByteField("apuInfo3", None), - ByteField("apuInfo4", None), - ByteField("apuInfo5", None), - ByteField("apuInfo6", None), - ByteField("apuInfo7", None), - ByteField("apuInfo8", None), - ByteField("apuInfo9", None), - ByteField("apuInfo10", None), - ByteField("apuInfo11", None), - ByteField("apuInfo12", None), - ByteField("apuInfo13", None), - ByteField("apuInfo14", None), - ByteField("apuInfo15", None), - ByteField("apuInfo16", None), - ByteField("apuInfo17", None), - ByteField("apuInfo18", None), - ByteField("apuInfo19", None), - ByteField("apuInfo20", None), - ByteField("apuInfo21", None), - ByteField("apuInfo22", None), - ByteField("apuInfo23", None), - ByteField("apuInfo24", None), - ByteField("apuInfo25", None), - ByteField("apuInfo26", None), - ByteField("apuInfo27", None), - ByteField("apuInfo28", None), - ByteField("apuInfo29", None), - ByteField("apuInfo30", None), - ByteField("apuInfo31", None), - ByteField("apuInfo32", None), - ByteField("apuInfo33", None), - ByteField("apuInfo34", None), - ByteField("apuInfo35", None), - ByteField("apuInfo36", None), - ByteField("apuInfo37", None), - ByteField("apuInfo38", None), - ByteField("apuInfo39", None), - ByteField("apuInfo40", None), - ByteField("apuInfo41", None), - ByteField("apuInfo42", None), - ByteField("apuInfo43", None), - ByteField("apuInfo44", None), - ByteField("apuInfo45", None), - ByteField("apuInfo46", None), - ByteField("apuInfo47", None), - ByteField("apuInfo48", None), - ByteField("apuInfo49", None), - ByteField("apuInfo50", None), - ByteField("apuInfo51", None), - ByteField("apuInfo52", None), - ByteField("apuInfo53", None), - ByteField("apuInfo54", None), - ByteField("apuInfo55", None), - ByteField("apuInfo56", None), - ByteField("apuInfo57", None), - ByteField("apuInfo58", None), - ByteField("apuInfo59", None), - ByteField("apuInfo60", None), - ByteField("apuInfo61", None), - ByteField("apuInfo62", None), - ByteField("apuInfo63", None), - ByteField("apuInfo64", None), - ByteField("apuInfo65", None), - ByteField("apuInfo66", None), - ByteField("apuInfo67", None), - ByteField("apuInfo68", None), - ByteField("apuInfo69", None), - ByteField("apuInfo70", None), - ByteField("apuInfo71", None), - ByteField("apuInfo72", None), - ByteField("apuInfo73", None), - ByteField("apuInfo74", None), - ByteField("apuInfo75", None), - ByteField("apuInfo76", None), - ByteField("apuInfo77", None), - ByteField("apuInfo78", None), - ByteField("apuInfo79", None), - ByteField("apuInfo80", None), - ByteField("apuInfo81", None), - ByteField("apuInfo82", None), - ByteField("apuInfo83", None), - ByteField("apuInfo84", None), - ByteField("apuInfo85", None), - ByteField("apuInfo86", None), - ByteField("apuInfo87", None), - ByteField("apuInfo88", None), - ByteField("apuInfo89", None), - ByteField("apuInfo90", None), - ByteField("apuInfo91", None), - ByteField("apuInfo92", None), - ByteField("apuInfo93", None), - ByteField("apuInfo94", None), - ByteField("apuInfo95", None), - ByteField("apuInfo96", None), - ByteField("apuInfo97", None), - ByteField("apuInfo98", None), - ByteField("apuInfo99", None), - ByteField("apuInfo100", None), - ByteField("apuInfo101", None), - ByteField("apuInfo102", None), - ByteField("apuInfo103", None), - ByteField("apuInfo104", None), - ByteField("apuInfo105", None), - ByteField("apuInfo106", None), - ByteField("apuInfo107", None), - ByteField("apuInfo108", None), - ByteField("apuInfo109", None), - ByteField("apuInfo110", None), - ByteField("apuInfo111", None), - ByteField("apuInfo112", None), - ByteField("apuInfo113", None), - ByteField("apuInfo114", None), - ByteField("apuInfo115", None), - ByteField("apuInfo116", None), - ByteField("apuInfo117", None), - ByteField("apuInfo118", None), - ByteField("apuInfo119", None), - ByteField("apuInfo120", None), - ByteField("apuInfo121", None), - ByteField("apuInfo122", None), - ByteField("apuInfo123", None), - ByteField("apuInfo124", None), - ByteField("apuInfo125", None), - ByteField("apuInfo126", None), - ByteField("apuInfo127", None), - ByteField("apuInfo128", None), - ByteField("apuInfo129", None), - ByteField("apuInfo130", None), - ByteField("apuInfo131", None), - ByteField("apuInfo132", None), - ByteField("apuInfo133", None), - ByteField("apuInfo134", None), - ByteField("apuInfo135", None), - ByteField("apuInfo136", None), - ByteField("apuInfo137", None), - ByteField("apuInfo138", None), - ByteField("apuInfo139", None), - ByteField("apuInfo140", None), - ByteField("apuInfo141", None), - ByteField("apuInfo142", None), - ByteField("apuInfo143", None), - ByteField("apuInfo144", None), - ByteField("apuInfo145", None), - ByteField("apuInfo146", None), - ByteField("apuInfo147", None), - ByteField("apuInfo148", None), - ByteField("apuInfo149", None), - ByteField("apuInfo150", None), - ByteField("apuInfo151", None), - ByteField("apuInfo152", None), - ByteField("apuInfo153", None), - ByteField("apuInfo154", None), - ByteField("apuInfo155", None), - ByteField("apuInfo156", None), - ByteField("apuInfo157", None), - ByteField("apuInfo158", None), - ByteField("apuInfo159", None), - ByteField("apuInfo160", None), - ByteField("apuInfo161", None), - ByteField("apuInfo162", None), - ByteField("apuInfo163", None), - ByteField("apuInfo164", None), - ByteField("apuInfo165", None), - ByteField("apuInfo166", None), - ByteField("apuInfo167", None), - ByteField("apuInfo168", None), - ByteField("apuInfo169", None), - ByteField("apuInfo170", None), - ByteField("apuInfo171", None), - ByteField("apuInfo172", None), - ByteField("apuInfo173", None), - ByteField("apuInfo174", None), - ByteField("apuInfo175", None), - ByteField("apuInfo176", None), - ByteField("apuInfo177", None), - ByteField("apuInfo178", None), - ByteField("apuInfo179", None), - ByteField("apuInfo180", None), - ByteField("apuInfo181", None), - ByteField("apuInfo182", None), - ByteField("apuInfo183", None), - ByteField("apuInfo184", None), - ByteField("apuInfo185", None), - ByteField("apuInfo186", None), - ByteField("apuInfo187", None), - ByteField("apuInfo188", None), - ByteField("apuInfo189", None), - ByteField("apuInfo190", None), - ByteField("apuInfo191", None), - ByteField("apuInfo192", None), - ByteField("apuInfo193", None), - ByteField("apuInfo194", None), - ByteField("apuInfo195", None), - ByteField("apuInfo196", None), - ByteField("apuInfo197", None), - ByteField("apuInfo198", None), - ByteField("apuInfo199", None), - ByteField("apuInfo200", None), - ByteField("apuInfo201", None), - ByteField("apuInfo202", None), - ByteField("apuInfo203", None), - ByteField("apuInfo204", None), - ByteField("apuInfo205", None), - ByteField("apuInfo206", None), - ByteField("apuInfo207", None), - ByteField("apuInfo208", None), - ByteField("apuInfo209", None), - ByteField("apuInfo210", None), - ByteField("apuInfo211", None), - ByteField("apuInfo212", None), - ByteField("apuInfo213", None), - ByteField("apuInfo214", None), - ByteField("apuInfo215", None), - ByteField("apuInfo216", None), - ByteField("apuInfo217", None), - ByteField("apuInfo218", None), - ByteField("apuInfo219", None), - ByteField("apuInfo220", None), - ByteField("apuInfo221", None), - ByteField("apuInfo222", None), - ByteField("apuInfo223", None), - ByteField("apuInfo224", None), - ByteField("apuInfo225", None), - ByteField("apuInfo226", None), - ByteField("apuInfo227", None), - ByteField("apuInfo228", None), - ByteField("apuInfo229", None), - ByteField("apuInfo230", None), - ByteField("apuInfo231", None), - ByteField("apuInfo232", None), - ByteField("apuInfo233", None), - ByteField("apuInfo234", None), - ByteField("apuInfo235", None), - ByteField("apuInfo236", None), - ByteField("apuInfo237", None), - ByteField("apuInfo238", None), - ByteField("apuInfo239", None), - ByteField("apuInfo240", None), - ByteField("apuInfo241", None), - ByteField("apuInfo242", None), - ByteField("apuInfo243", None), - ByteField("apuInfo244", None), - ByteField("apuInfo245", None), - ByteField("apuInfo246", None), - ByteField("apuInfo247", None), - ByteField("apuInfo248", None), - ByteField("apuInfo249", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 251, a, self.fields_desc) - if self.lengthAD is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - -# -# 10.5.3 Mobility management information elements -# - - -class AuthenticationParameterRAND(Packet): - """Authentication parameter RAND Section 10.5.3.1""" - name = "Authentication Parameter Rand" - fields_desc = [ - ByteField("ieiAPR", None), - BitField("randValue", 0x0, 128) - ] - - -class AuthenticationParameterSRES(Packet): - """Authentication parameter SRES Section 10.5.3.2""" - name = "Authentication Parameter Sres" - fields_desc = [ - ByteField("ieiAPS", None), - BitField("sresValue", 0x0, 40) - ] - - -class CmServiceType(Packet): - """CM service type Section 10.5.3.3""" - name = "CM Service Type" - fields_desc = [ - XBitField("ieiCST", 0x0, 4), - BitField("serviceType", 0x0, 4) - ] - - -class CmServiceTypeAndCiphKeySeqNr(Packet): - name = "CM Service Type and Cipher Key Sequence Number" - fields_desc = [ - BitField("keySeq", 0x0, 3), - BitField("spare", 0x0, 1), - BitField("serviceType", 0x0, 4) - ] - - -class IdentityType(Packet): - """Identity type Section 10.5.3.4""" - name = "Identity Type" - fields_desc = [ - XBitField("ieiIT", 0x0, 4), - BitField("spare", 0x0, 1), - BitField("idType", 0x1, 3) - ] - - -# Fix 1/2 len problem -class IdentityTypeAndSpareHalfOctet(Packet): - name = "Identity Type and Spare Half Octet" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("idType", 0x1, 3), - BitField("spareHalfOctets", 0x0, 4) - ] - - -class LocationUpdatingType(Packet): - """Location updating type Section 10.5.3.5""" - name = "Location Updating Type" - fields_desc = [ - XBitField("ieiLUT", 0x0, 4), - BitField("for", 0x0, 1), - BitField("spare", 0x0, 1), - BitField("lut", 0x0, 2) - ] - - -class LocationUpdatingTypeAndCiphKeySeqNr(Packet): - name = "Location Updating Type and Cipher Key Sequence Number" - fields_desc = [ - BitField("for", 0x0, 1), - BitField("spare", 0x0, 1), - BitField("lut", 0x0, 2), - BitField("spare", 0x0, 1), - BitField("keySeq", 0x0, 3) - ] - - -# len 3 to L3 max (251) (done) -class NetworkNameHdr(Packet): - """Network Name Section 10.5.3.5a""" - name = "Network Name" - fields_desc = [ - BitField("eightBitNN", None, 1), - XBitField("ieiNN", None, 7), - - XByteField("lengthNN", None), - - BitField("ext1", 0x1, 1), - BitField("codingScheme", 0x0, 3), - BitField("addCi", 0x0, 1), - BitField("nbSpare", 0x0, 3), - # optional - ByteField("txtString1", None), - ByteField("txtString2", None), - ByteField("txtString3", None), - ByteField("txtString4", None), - ByteField("txtString5", None), - ByteField("txtString6", None), - ByteField("txtString7", None), - ByteField("txtString8", None), - ByteField("txtString9", None), - ByteField("txtString10", None), - ByteField("txtString11", None), - ByteField("txtString12", None), - ByteField("txtString13", None), - ByteField("txtString14", None), - ByteField("txtString15", None), - ByteField("txtString16", None), - ByteField("txtString17", None), - ByteField("txtString18", None), - ByteField("txtString19", None), - ByteField("txtString20", None), - ByteField("txtString21", None), - ByteField("txtString22", None), - ByteField("txtString23", None), - ByteField("txtString24", None), - ByteField("txtString25", None), - ByteField("txtString26", None), - ByteField("txtString27", None), - ByteField("txtString28", None), - ByteField("txtString29", None), - ByteField("txtString30", None), - ByteField("txtString31", None), - ByteField("txtString32", None), - ByteField("txtString33", None), - ByteField("txtString34", None), - ByteField("txtString35", None), - ByteField("txtString36", None), - ByteField("txtString37", None), - ByteField("txtString38", None), - ByteField("txtString39", None), - ByteField("txtString40", None), - ByteField("txtString41", None), - ByteField("txtString42", None), - ByteField("txtString43", None), - ByteField("txtString44", None), - ByteField("txtString45", None), - ByteField("txtString46", None), - ByteField("txtString47", None), - ByteField("txtString48", None), - ByteField("txtString49", None), - ByteField("txtString50", None), - ByteField("txtString51", None), - ByteField("txtString52", None), - ByteField("txtString53", None), - ByteField("txtString54", None), - ByteField("txtString55", None), - ByteField("txtString56", None), - ByteField("txtString57", None), - ByteField("txtString58", None), - ByteField("txtString59", None), - ByteField("txtString60", None), - ByteField("txtString61", None), - ByteField("txtString62", None), - ByteField("txtString63", None), - ByteField("txtString64", None), - ByteField("txtString65", None), - ByteField("txtString66", None), - ByteField("txtString67", None), - ByteField("txtString68", None), - ByteField("txtString69", None), - ByteField("txtString70", None), - ByteField("txtString71", None), - ByteField("txtString72", None), - ByteField("txtString73", None), - ByteField("txtString74", None), - ByteField("txtString75", None), - ByteField("txtString76", None), - ByteField("txtString77", None), - ByteField("txtString78", None), - ByteField("txtString79", None), - ByteField("txtString80", None), - ByteField("txtString81", None), - ByteField("txtString82", None), - ByteField("txtString83", None), - ByteField("txtString84", None), - ByteField("txtString85", None), - ByteField("txtString86", None), - ByteField("txtString87", None), - ByteField("txtString88", None), - ByteField("txtString89", None), - ByteField("txtString90", None), - ByteField("txtString91", None), - ByteField("txtString92", None), - ByteField("txtString93", None), - ByteField("txtString94", None), - ByteField("txtString95", None), - ByteField("txtString96", None), - ByteField("txtString97", None), - ByteField("txtString98", None), - ByteField("txtString99", None), - ByteField("txtString100", None), - ByteField("txtString101", None), - ByteField("txtString102", None), - ByteField("txtString103", None), - ByteField("txtString104", None), - ByteField("txtString105", None), - ByteField("txtString106", None), - ByteField("txtString107", None), - ByteField("txtString108", None), - ByteField("txtString109", None), - ByteField("txtString110", None), - ByteField("txtString111", None), - ByteField("txtString112", None), - ByteField("txtString113", None), - ByteField("txtString114", None), - ByteField("txtString115", None), - ByteField("txtString116", None), - ByteField("txtString117", None), - ByteField("txtString118", None), - ByteField("txtString119", None), - ByteField("txtString120", None), - ByteField("txtString121", None), - ByteField("txtString122", None), - ByteField("txtString123", None), - ByteField("txtString124", None), - ByteField("txtString125", None), - ByteField("txtString126", None), - ByteField("txtString127", None), - ByteField("txtString128", None), - ByteField("txtString129", None), - ByteField("txtString130", None), - ByteField("txtString131", None), - ByteField("txtString132", None), - ByteField("txtString133", None), - ByteField("txtString134", None), - ByteField("txtString135", None), - ByteField("txtString136", None), - ByteField("txtString137", None), - ByteField("txtString138", None), - ByteField("txtString139", None), - ByteField("txtString140", None), - ByteField("txtString141", None), - ByteField("txtString142", None), - ByteField("txtString143", None), - ByteField("txtString144", None), - ByteField("txtString145", None), - ByteField("txtString146", None), - ByteField("txtString147", None), - ByteField("txtString148", None), - ByteField("txtString149", None), - ByteField("txtString150", None), - ByteField("txtString151", None), - ByteField("txtString152", None), - ByteField("txtString153", None), - ByteField("txtString154", None), - ByteField("txtString155", None), - ByteField("txtString156", None), - ByteField("txtString157", None), - ByteField("txtString158", None), - ByteField("txtString159", None), - ByteField("txtString160", None), - ByteField("txtString161", None), - ByteField("txtString162", None), - ByteField("txtString163", None), - ByteField("txtString164", None), - ByteField("txtString165", None), - ByteField("txtString166", None), - ByteField("txtString167", None), - ByteField("txtString168", None), - ByteField("txtString169", None), - ByteField("txtString170", None), - ByteField("txtString171", None), - ByteField("txtString172", None), - ByteField("txtString173", None), - ByteField("txtString174", None), - ByteField("txtString175", None), - ByteField("txtString176", None), - ByteField("txtString177", None), - ByteField("txtString178", None), - ByteField("txtString179", None), - ByteField("txtString180", None), - ByteField("txtString181", None), - ByteField("txtString182", None), - ByteField("txtString183", None), - ByteField("txtString184", None), - ByteField("txtString185", None), - ByteField("txtString186", None), - ByteField("txtString187", None), - ByteField("txtString188", None), - ByteField("txtString189", None), - ByteField("txtString190", None), - ByteField("txtString191", None), - ByteField("txtString192", None), - ByteField("txtString193", None), - ByteField("txtString194", None), - ByteField("txtString195", None), - ByteField("txtString196", None), - ByteField("txtString197", None), - ByteField("txtString198", None), - ByteField("txtString199", None), - ByteField("txtString200", None), - ByteField("txtString201", None), - ByteField("txtString202", None), - ByteField("txtString203", None), - ByteField("txtString204", None), - ByteField("txtString205", None), - ByteField("txtString206", None), - ByteField("txtString207", None), - ByteField("txtString208", None), - ByteField("txtString209", None), - ByteField("txtString210", None), - ByteField("txtString211", None), - ByteField("txtString212", None), - ByteField("txtString213", None), - ByteField("txtString214", None), - ByteField("txtString215", None), - ByteField("txtString216", None), - ByteField("txtString217", None), - ByteField("txtString218", None), - ByteField("txtString219", None), - ByteField("txtString220", None), - ByteField("txtString221", None), - ByteField("txtString222", None), - ByteField("txtString223", None), - ByteField("txtString224", None), - ByteField("txtString225", None), - ByteField("txtString226", None), - ByteField("txtString227", None), - ByteField("txtString228", None), - ByteField("txtString229", None), - ByteField("txtString230", None), - ByteField("txtString231", None), - ByteField("txtString232", None), - ByteField("txtString233", None), - ByteField("txtString234", None), - ByteField("txtString235", None), - ByteField("txtString236", None), - ByteField("txtString237", None), - ByteField("txtString238", None), - ByteField("txtString239", None), - ByteField("txtString240", None), - ByteField("txtString241", None), - ByteField("txtString242", None), - ByteField("txtString243", None), - ByteField("txtString244", None), - ByteField("txtString245", None), - ByteField("txtString246", None), - ByteField("txtString247", None), - ByteField("txtString248", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(3, 251, a, self.fields_desc) - if self.lengthNN is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class RejectCause(Packet): - """Reject cause Section 10.5.3.6""" - name = "Reject Cause" - fields_desc = [ - ByteField("ieiRC", 0x0), - ByteField("rejCause", 0x0) - ] - - -class FollowOnProceed(Packet): - """Follow-on Proceed Section 10.5.3.7""" - name = "Follow-on Proceed" - fields_desc = [ - ByteField("ieiFOP", 0x0), - ] - - -class TimeZoneHdr(Packet): - """Time Zone Section 10.5.3.8""" - name = "Time Zone" - fields_desc = [ - BitField("eightBitTZ", None, 1), - XBitField("ieiTZ", None, 7), - ByteField("timeZone", 0x0), - ] - - -class TimeZoneAndTimeHdr(Packet): - """Time Zone and Time Section 10.5.3.9""" - name = "Time Zone and Time" - fields_desc = [ - BitField("eightBitTZAT", None, 1), - XBitField("ieiTZAT", None, 7), - ByteField("year", 0x0), - ByteField("month", 0x0), - ByteField("day", 0x0), - ByteField("hour", 0x0), - ByteField("minute", 0x0), - ByteField("second", 0x0), - ByteField("timeZone", 0x0) - ] - - -class CtsPermissionHdr(Packet): - """CTS permission Section 10.5.3.10""" - name = "Cts Permission" - fields_desc = [ - BitField("eightBitCP", None, 1), - XBitField("ieiCP", None, 7), - ] - - -class LsaIdentifierHdr(Packet): - """LSA Identifier Section 10.5.3.11""" - name = "Lsa Identifier" - fields_desc = [ - BitField("eightBitLI", None, 1), - XBitField("ieiLI", None, 7), - ByteField("lsaID", 0x0), - ByteField("lsaID1", 0x0), - ByteField("lsaID2", 0x0) - ] - - -# -# 10.5.4 Call control information elements -# - -#10.5.4.1 Extensions of codesets -# This is only text and no packet - -class LockingShiftProcedureHdr(Packet): - """Locking shift procedure Section 10.5.4.2""" - name = "Locking Shift Procedure" - fields_desc = [ - XBitField("ieiLSP", None, 4), - BitField("lockShift", 0x0, 1), - BitField("codesetId", 0x0, 3) - ] - - -class NonLockingShiftProcedureHdr(Packet): - """Non-locking shift procedure Section 10.5.4.3""" - name = "Non-locking Shift Procedure" - fields_desc = [ - XBitField("ieiNLSP", None, 4), - BitField("nonLockShift", 0x1, 1), - BitField("codesetId", 0x0, 3) - ] - - -class AuxiliaryStatesHdr(Packet): - """Auxiliary states Section 10.5.4.4""" - name = "Auxiliary States" - fields_desc = [ - BitField("eightBitAS", None, 1), - XBitField("ieiAS", None, 7), - XByteField("lengthAS", 0x3), - BitField("ext", 0x1, 1), - BitField("spare", 0x0, 3), - BitField("holdState", 0x0, 2), - BitField("mptyState", 0x0, 2) - ] - - -# len 3 to 15 -class BearerCapabilityHdr(Packet): - """Bearer capability Section 10.5.4.5""" - name = "Bearer Capability" - fields_desc = [ - BitField("eightBitBC", None, 1), - XBitField("ieiBC", None, 7), - - XByteField("lengthBC", None), - - BitField("ext0", 0x1, 1), - BitField("radioChReq", 0x1, 2), - BitField("codingStd", 0x0, 1), - BitField("transMode", 0x0, 1), - BitField("infoTransCa", 0x0, 3), - # optional - ConditionalField(BitField("ext1", 0x1, 1), - lambda pkt: pkt.ext0 == 0), - ConditionalField(BitField("coding", None, 1), - lambda pkt: pkt.ext0 == 0), - ConditionalField(BitField("spare", None, 2), - lambda pkt: pkt.ext0 == 0), - ConditionalField(BitField("speechVers", 0x0, 4), - lambda pkt: pkt.ext0 == 0), - - ConditionalField(BitField("ext2", 0x1, 1), - lambda pkt: pkt.ext1 == 0), - ConditionalField(BitField("compress", None, 1), - lambda pkt: pkt.ext1 == 0), - ConditionalField(BitField("structure", None, 2), - lambda pkt: pkt.ext1 == 0), - ConditionalField(BitField("dupMode", None, 1), - lambda pkt: pkt.ext1 == 0), - ConditionalField(BitField("config", None, 1), - lambda pkt: pkt.ext1 == 0), - ConditionalField(BitField("nirr", None, 1), - lambda pkt: pkt.ext1 == 0), - ConditionalField(BitField("establi", 0x0, 1), - lambda pkt: pkt.ext1 == 0), - - BitField("ext3", None, 1), - BitField("accessId", None, 2), - BitField("rateAda", None, 2), - BitField("signaling", None, 3), - - ConditionalField(BitField("ext4", None, 1), - lambda pkt: pkt.ext3 == 0), - ConditionalField(BitField("otherITC", None, 2), - lambda pkt: pkt.ext3 == 0), - ConditionalField(BitField("otherRate", None, 2), - lambda pkt: pkt.ext3 == 0), - ConditionalField(BitField("spare1", 0x0, 3), - lambda pkt: pkt.ext3 == 0), - - ConditionalField(BitField("ext5", 0x1, 1), - lambda pkt: pkt.ext4 == 0), - ConditionalField(BitField("hdr", None, 1), - lambda pkt: pkt.ext4 == 0), - ConditionalField(BitField("multiFr", None, 1), - lambda pkt: pkt.ext4 == 0), - ConditionalField(BitField("mode", None, 1), - lambda pkt: pkt.ext4 == 0), - ConditionalField(BitField("lli", None, 1), - lambda pkt: pkt.ext4 == 0), - ConditionalField(BitField("assig", None, 1), - lambda pkt: pkt.ext4 == 0), - ConditionalField(BitField("inbNeg", None, 1), - lambda pkt: pkt.ext4 == 0), - ConditionalField(BitField("spare2", 0x0, 1), - lambda pkt: pkt.ext4 == 0), - - BitField("ext6", None, 1), - BitField("layer1Id", None, 2), - BitField("userInf", None, 4), - BitField("sync", None, 1), - - ConditionalField(BitField("ext7", None, 1), - lambda pkt: pkt.ext6 == 0), - ConditionalField(BitField("stopBit", None, 1), - lambda pkt: pkt.ext6 == 0), - ConditionalField(BitField("negoc", None, 1), - lambda pkt: pkt.ext6 == 0), - ConditionalField(BitField("nbDataBit", None, 1), - lambda pkt: pkt.ext6 == 0), - ConditionalField(BitField("userRate", None, 4), - lambda pkt: pkt.ext6 == 0), - - ConditionalField(BitField("ext8", None, 1), - lambda pkt: pkt.ext7 == 0), - ConditionalField(BitField("interRate", None, 2), - lambda pkt: pkt.ext7 == 0), - ConditionalField(BitField("nicTX", None, 1), - lambda pkt: pkt.ext7 == 0), - ConditionalField(BitField("nicRX", None, 1), - lambda pkt: pkt.ext7 == 0), - ConditionalField(BitField("parity", None, 3), - lambda pkt: pkt.ext7 == 0), - - ConditionalField(BitField("ext9", None, 1), - lambda pkt: pkt.ext8 == 0), - ConditionalField(BitField("connEle", None, 2), - lambda pkt: pkt.ext8 == 0), - ConditionalField(BitField("modemType", None, 5), - lambda pkt: pkt.ext8 == 0), - - ConditionalField(BitField("ext10", None, 1), - lambda pkt: pkt.ext9 == 0), - ConditionalField(BitField("otherModemType", None, 2), - lambda pkt: pkt.ext9 == 0), - ConditionalField(BitField("netUserRate", None, 5), - lambda pkt: pkt.ext9 == 0), - - ConditionalField(BitField("ext11", None, 1), - lambda pkt: pkt.ext10 == 0), - ConditionalField(BitField("chanCoding", None, 4), - lambda pkt: pkt.ext10 == 0), - ConditionalField(BitField("maxTrafficChan", None, 3), - lambda pkt: pkt.ext10 == 0), - - ConditionalField(BitField("ext12", None, 1), - lambda pkt: pkt.ext11 == 0), - ConditionalField(BitField("uimi", None, 3), - lambda pkt: pkt.ext11 == 0), - ConditionalField(BitField("airInterfaceUserRate", None, 4), - lambda pkt: pkt.ext11 == 0), - - ConditionalField(BitField("ext13", 0x1, 1), - lambda pkt: pkt.ext12 == 0), - ConditionalField(BitField("layer2Ch", None, 2), - lambda pkt: pkt.ext12 == 0), - ConditionalField(BitField("userInfoL2", 0x0, 5), - lambda pkt: pkt.ext12 == 0) - ] - -# We have a bug here. packet is not working if used in message - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(3, 15, a, self.fields_desc) - if res[0] is not 0: - p = p[:-res[0]] - # avoids a bug. find better way - if len(p) is 5: - p = p[:-2] - if self.lengthBC is None: - print("len von a %s" % (len(p),)) - p = p[:1] + struct.pack(">B", len(p)-3) + p[2:] - return p + pay - - -class CallControlCapabilitiesHdr(Packet): - """Call Control Capabilities Section 10.5.4.5a""" - name = "Call Control Capabilities" - fields_desc = [ - BitField("eightBitCCC", None, 1), - XBitField("ieiCCC", None, 7), - XByteField("lengthCCC", 0x3), - BitField("spare", 0x0, 6), - BitField("pcp", 0x0, 1), - BitField("dtmf", 0x0, 1) - ] - - -class CallStateHdr(Packet): - """Call State Section 10.5.4.6""" - name = "Call State" - fields_desc = [ - BitField("eightBitCS", None, 1), - XBitField("ieiCS", None, 7), - BitField("codingStd", 0x0, 2), - BitField("stateValue", 0x0, 6) - ] - - -# len 3 to 43 -class CalledPartyBcdNumberHdr(Packet): - """Called party BCD number Section 10.5.4.7""" - name = "Called Party BCD Number" - fields_desc = [ - BitField("eightBitCPBN", None, 1), - XBitField("ieiCPBN", None, 7), - XByteField("lengthCPBN", None), - BitField("ext", 0x1, 1), - BitField("typeNb", 0x0, 3), - BitField("nbPlanId", 0x0, 4), - # optional - BitField("nbDigit2", None, 4), - BitField("nbDigit1", None, 4), - BitField("nbDigit4", None, 4), - BitField("nbDigit3", None, 4), - - BitField("nbDigit6", None, 4), - BitField("nbDigit5", None, 4), - BitField("nbDigit8", None, 4), - BitField("nbDigit7", None, 4), - - BitField("nbDigit10", None, 4), - BitField("nbDigit9", None, 4), - BitField("nbDigit12", None, 4), - BitField("nbDigit11", None, 4), - - BitField("nbDigit14", None, 4), - BitField("nbDigit13", None, 4), - BitField("nbDigit16", None, 4), - BitField("nbDigit15", None, 4), - - BitField("nbDigit18", None, 4), - BitField("nbDigit17", None, 4), - BitField("nbDigit20", None, 4), - BitField("nbDigit19", None, 4), - - BitField("nbDigit22", None, 4), - BitField("nbDigit21", None, 4), - BitField("nbDigit24", None, 4), - BitField("nbDigit23", None, 4), - - BitField("nbDigit26", None, 4), - BitField("nbDigit25", None, 4), - BitField("nbDigit28", None, 4), - BitField("nbDigit27", None, 4), - - BitField("nbDigit30", None, 4), - BitField("nbDigit29", None, 4), - BitField("nbDigit32", None, 4), - BitField("nbDigit31", None, 4), - - BitField("nbDigit34", None, 4), - BitField("nbDigit33", None, 4), - BitField("nbDigit36", None, 4), - BitField("nbDigit35", None, 4), - - BitField("nbDigit38", None, 4), - BitField("nbDigit37", None, 4), - BitField("nbDigit40", None, 4), - BitField("nbDigit39", None, 4), -# ^^^^^^ 20 first optional bytes ^^^^^^^^^^^^^^^ - BitField("nbDigit42", None, 4), - BitField("nbDigit41", None, 4), - BitField("nbDigit44", None, 4), - BitField("nbDigit43", None, 4), - - BitField("nbDigit46", None, 4), - BitField("nbDigit45", None, 4), - BitField("nbDigit48", None, 4), - BitField("nbDigit47", None, 4), - - BitField("nbDigit50", None, 4), - BitField("nbDigit49", None, 4), - BitField("nbDigit52", None, 4), - BitField("nbDigit51", None, 4), - - BitField("nbDigit54", None, 4), - BitField("nbDigit53", None, 4), - BitField("nbDigit56", None, 4), - BitField("nbDigit55", None, 4), - - BitField("nbDigit58", None, 4), - BitField("nbDigit57", None, 4), - BitField("nbDigit60", None, 4), - BitField("nbDigit59", None, 4), - - BitField("nbDigit62", None, 4), - BitField("nbDigit61", None, 4), - BitField("nbDigit64", None, 4), - BitField("nbDigit63", None, 4), - - BitField("nbDigit66", None, 4), - BitField("nbDigit65", None, 4), - BitField("nbDigit68", None, 4), - BitField("nbDigit67", None, 4), - - BitField("nbDigit70", None, 4), - BitField("nbDigit69", None, 4), - BitField("nbDigit72", None, 4), - BitField("nbDigit71", None, 4), - - BitField("nbDigit74", None, 4), - BitField("nbDigit73", None, 4), - BitField("nbDigit76", None, 4), - BitField("nbDigit75", None, 4), - - BitField("nbDigit78", None, 4), - BitField("nbDigit77", None, 4), - BitField("nbDigit80", None, 4), - BitField("nbDigit79", None, 4), - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(3, 43, a, self.fields_desc, 2) - if self.lengthCPBN is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# len 2 to 23 -class CalledPartySubaddressHdr(Packet): - """Called party subaddress Section 10.5.4.8""" - name = "Called Party Subaddress" - fields_desc = [ - BitField("eightBitCPS", None, 1), - XBitField("ieiCPS", None, 7), - XByteField("lengthCPS", None), - # optional - BitField("ext", None, 1), - BitField("subAddr", None, 3), - BitField("oddEven", None, 1), - BitField("spare", None, 3), - - ByteField("subInfo0", None), - ByteField("subInfo1", None), - ByteField("subInfo2", None), - ByteField("subInfo3", None), - ByteField("subInfo4", None), - ByteField("subInfo5", None), - ByteField("subInfo6", None), - ByteField("subInfo7", None), - ByteField("subInfo8", None), - ByteField("subInfo9", None), - ByteField("subInfo10", None), - ByteField("subInfo11", None), - ByteField("subInfo12", None), - ByteField("subInfo13", None), - ByteField("subInfo14", None), - ByteField("subInfo15", None), - ByteField("subInfo16", None), - ByteField("subInfo17", None), - ByteField("subInfo18", None), - ByteField("subInfo19", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 23, a, self.fields_desc) - if self.lengthCPS is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# len 3 to 14 -class CallingPartyBcdNumberHdr(Packet): - """Called party subaddress Section 10.5.4.9""" - name = "Called Party Subaddress" - fields_desc = [ - BitField("eightBitCPBN", None, 1), - XBitField("ieiCPBN", None, 7), - XByteField("lengthCPBN", None), - BitField("ext", 0x1, 1), - BitField("typeNb", 0x0, 3), - BitField("nbPlanId", 0x0, 4), - # optional - ConditionalField(BitField("ext1", 0x1, 1), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("presId", None, 2), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("spare", None, 3), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("screenId", 0x0, 2), - lambda pkt: pkt.ext == 0), - - BitField("nbDigit2", None, 4), - BitField("nbDigit1", None, 4), - - BitField("nbDigit4", None, 4), - BitField("nbDigit3", None, 4), - - BitField("nbDigit6", None, 4), - BitField("nbDigit5", None, 4), - - BitField("nbDigit8", None, 4), - BitField("nbDigit7", None, 4), - - BitField("nbDigit10", None, 4), - BitField("nbDigit9", None, 4), - - BitField("nbDigit12", None, 4), - BitField("nbDigit11", None, 4), - - BitField("nbDigit14", None, 4), - BitField("nbDigit13", None, 4), - - BitField("nbDigit16", None, 4), - BitField("nbDigit15", None, 4), - - BitField("nbDigit18", None, 4), - BitField("nbDigit17", None, 4), - - BitField("nbDigit20", None, 4), - BitField("nbDigit19", None, 4), - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(4, 14, a, self.fields_desc) - if res[0] is not 0: - p = p[:-res[0]] - if self.lengthCPBN is None: - p = p[:1] + struct.pack(">B", len(p)-2) + p[2:] - return p + pay - - -# len 2 to 23 -class CallingPartySubaddressHdr(Packet): - """Calling party subaddress Section 10.5.4.10""" - name = "Calling Party Subaddress" - fields_desc = [ - BitField("eightBitCPS", None, 1), - XBitField("ieiCPS", None, 7), - XByteField("lengthCPS", None), - # optional - BitField("ext1", None, 1), - BitField("typeAddr", None, 3), - BitField("oddEven", None, 1), - BitField("spare", None, 3), - - ByteField("subInfo0", None), - ByteField("subInfo1", None), - ByteField("subInfo2", None), - ByteField("subInfo3", None), - ByteField("subInfo4", None), - ByteField("subInfo5", None), - ByteField("subInfo6", None), - ByteField("subInfo7", None), - ByteField("subInfo8", None), - ByteField("subInfo9", None), - ByteField("subInfo10", None), - ByteField("subInfo11", None), - ByteField("subInfo12", None), - ByteField("subInfo13", None), - ByteField("subInfo14", None), - ByteField("subInfo15", None), - ByteField("subInfo16", None), - ByteField("subInfo17", None), - ByteField("subInfo18", None), - ByteField("subInfo19", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 23, a, self.fields_desc) - if self.lengthCPS is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# len 4 to 32 -class CauseHdr(Packet): - """Cause Section 10.5.4.11""" - name = "Cause" - fields_desc = [ - BitField("eightBitC", None, 1), - XBitField("ieiC", None, 7), - - XByteField("lengthC", None), - - BitField("ext", 0x1, 1), - BitField("codingStd", 0x0, 2), - BitField("spare", 0x0, 1), - BitField("location", 0x0, 4), - - ConditionalField(BitField("ext1", 0x1, 1), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("recommendation", 0x0, 7), - lambda pkt: pkt.ext == 0), - # optional - BitField("ext2", None, 1), - BitField("causeValue", None, 7), - - ByteField("diagnositc0", None), - ByteField("diagnositc1", None), - ByteField("diagnositc2", None), - ByteField("diagnositc3", None), - ByteField("diagnositc4", None), - ByteField("diagnositc5", None), - ByteField("diagnositc6", None), - ByteField("diagnositc7", None), - ByteField("diagnositc8", None), - ByteField("diagnositc9", None), - ByteField("diagnositc10", None), - ByteField("diagnositc11", None), - ByteField("diagnositc12", None), - ByteField("diagnositc13", None), - ByteField("diagnositc14", None), - ByteField("diagnositc15", None), - ByteField("diagnositc16", None), - ByteField("diagnositc17", None), - ByteField("diagnositc18", None), - ByteField("diagnositc19", None), - ByteField("diagnositc20", None), - ByteField("diagnositc21", None), - ByteField("diagnositc22", None), - ByteField("diagnositc23", None), - ByteField("diagnositc24", None), - ByteField("diagnositc25", None), - ByteField("diagnositc26", None), - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(4, 32, a, self.fields_desc) - if res[0] is not 0: - p = p[:-res[0]] - if self.lengthC is None: - p = p[:1] + struct.pack(">B", len(p)-2) + p[2:] - return p + pay - - -class ClirSuppressionHdr(Packet): - """CLIR suppression Section 10.5.4.11a""" - name = "Clir Suppression" - fields_desc = [ - BitField("eightBitCS", None, 1), - XBitField("ieiCS", None, 7), - ] - - -class ClirInvocationHdr(Packet): - """CLIR invocation Section 10.5.4.11b""" - name = "Clir Invocation" - fields_desc = [ - BitField("eightBitCI", None, 1), - XBitField("ieiCI", None, 7), - ] - - -class CongestionLevelHdr(Packet): - """Congestion level Section 10.5.4.12""" - name = "Congestion Level" - fields_desc = [ - XBitField("ieiCL", None, 4), - BitField("notDef", 0x0, 4) - ] - - -# Fix 1/2 len problem -class CongestionLevelAndSpareHalfOctets(Packet): - name = "Congestion Level and Spare Half Octets" - fields_desc = [ - BitField("ieiCL", 0x0, 4), - BitField("spareHalfOctets", 0x0, 4) - ] - - -# len 3 to 14 -class ConnectedNumberHdr(Packet): - """Connected number Section 10.5.4.13""" - name = "Connected Number" - fields_desc = [ - BitField("eightBitCN", None, 1), - XBitField("ieiCN", None, 7), - - XByteField("lengthCN", None), - - BitField("ext", 0x1, 1), - BitField("typeNb", 0x0, 3), - BitField("typePlanId", 0x0, 4), - # optional - ConditionalField(BitField("ext1", 0x1, 1), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("presId", None, 2), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("spare", None, 3), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("screenId", None, 2), - lambda pkt: pkt.ext == 0), - - BitField("nbDigit2", None, 4), - BitField("nbDigit1", None, 4), - - BitField("nbDigit4", None, 4), - BitField("nbDigit3", None, 4), - - BitField("nbDigit6", None, 4), - BitField("nbDigit5", None, 4), - - BitField("nbDigit8", None, 4), - BitField("nbDigit7", None, 4), - - BitField("nbDigit10", None, 4), - BitField("nbDigit9", None, 4), - - BitField("nbDigit12", None, 4), - BitField("nbDigit11", None, 4), - - BitField("nbDigit14", None, 4), - BitField("nbDigit13", None, 4), - - BitField("nbDigit16", None, 4), - BitField("nbDigit15", None, 4), - - BitField("nbDigit18", None, 4), - BitField("nbDigit17", None, 4), - - BitField("nbDigit20", None, 4), - BitField("nbDigit19", None, 4) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - sum1 = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(3, 14, a, self.fields_desc) - if res[0] is not 0: - p = p[:-res[0]] - if self.lengthCN is None: - p = p[:1] + struct.pack(">B", len(p)-2) + p[2:] - return p + pay - - -# len 2 to 23 -class ConnectedSubaddressHdr(Packet): - """Connected subaddress Section 10.5.4.14""" - name = "Connected Subaddress" - fields_desc = [ - BitField("eightBitCS", None, 1), - XBitField("ieiCS", None, 7), - - XByteField("lengthCS", None), - # optional - BitField("ext", None, 1), - BitField("typeOfSub", None, 3), - BitField("oddEven", None, 1), - BitField("spare", None, 3), - - ByteField("subInfo0", None), - ByteField("subInfo1", None), - ByteField("subInfo2", None), - ByteField("subInfo3", None), - ByteField("subInfo4", None), - ByteField("subInfo5", None), - ByteField("subInfo6", None), - ByteField("subInfo7", None), - ByteField("subInfo8", None), - ByteField("subInfo9", None), - ByteField("subInfo10", None), - ByteField("subInfo11", None), - ByteField("subInfo12", None), - ByteField("subInfo13", None), - ByteField("subInfo14", None), - ByteField("subInfo15", None), - ByteField("subInfo16", None), - ByteField("subInfo17", None), - ByteField("subInfo18", None), - ByteField("subInfo19", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 23, a, self.fields_desc) - if self.lengthCS is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# len 2 to L3 (251) (done) -class FacilityHdr(Packet): - """Facility Section 10.5.4.15""" - name = "Facility" - fields_desc = [ - BitField("eightBitF", None, 1), - XBitField("ieiF", None, 7), - XByteField("lengthF", None), - # optional - ByteField("facilityInfo1", None), - ByteField("facilityInfo2", None), - ByteField("facilityInfo3", None), - ByteField("facilityInfo4", None), - ByteField("facilityInfo5", None), - ByteField("facilityInfo6", None), - ByteField("facilityInfo7", None), - ByteField("facilityInfo8", None), - ByteField("facilityInfo9", None), - ByteField("facilityInfo10", None), - ByteField("facilityInfo11", None), - ByteField("facilityInfo12", None), - ByteField("facilityInfo13", None), - ByteField("facilityInfo14", None), - ByteField("facilityInfo15", None), - ByteField("facilityInfo16", None), - ByteField("facilityInfo17", None), - ByteField("facilityInfo18", None), - ByteField("facilityInfo19", None), - ByteField("facilityInfo20", None), - ByteField("facilityInfo21", None), - ByteField("facilityInfo22", None), - ByteField("facilityInfo23", None), - ByteField("facilityInfo24", None), - ByteField("facilityInfo25", None), - ByteField("facilityInfo26", None), - ByteField("facilityInfo27", None), - ByteField("facilityInfo28", None), - ByteField("facilityInfo29", None), - ByteField("facilityInfo30", None), - ByteField("facilityInfo31", None), - ByteField("facilityInfo32", None), - ByteField("facilityInfo33", None), - ByteField("facilityInfo34", None), - ByteField("facilityInfo35", None), - ByteField("facilityInfo36", None), - ByteField("facilityInfo37", None), - ByteField("facilityInfo38", None), - ByteField("facilityInfo39", None), - ByteField("facilityInfo40", None), - ByteField("facilityInfo41", None), - ByteField("facilityInfo42", None), - ByteField("facilityInfo43", None), - ByteField("facilityInfo44", None), - ByteField("facilityInfo45", None), - ByteField("facilityInfo46", None), - ByteField("facilityInfo47", None), - ByteField("facilityInfo48", None), - ByteField("facilityInfo49", None), - ByteField("facilityInfo50", None), - ByteField("facilityInfo51", None), - ByteField("facilityInfo52", None), - ByteField("facilityInfo53", None), - ByteField("facilityInfo54", None), - ByteField("facilityInfo55", None), - ByteField("facilityInfo56", None), - ByteField("facilityInfo57", None), - ByteField("facilityInfo58", None), - ByteField("facilityInfo59", None), - ByteField("facilityInfo60", None), - ByteField("facilityInfo61", None), - ByteField("facilityInfo62", None), - ByteField("facilityInfo63", None), - ByteField("facilityInfo64", None), - ByteField("facilityInfo65", None), - ByteField("facilityInfo66", None), - ByteField("facilityInfo67", None), - ByteField("facilityInfo68", None), - ByteField("facilityInfo69", None), - ByteField("facilityInfo70", None), - ByteField("facilityInfo71", None), - ByteField("facilityInfo72", None), - ByteField("facilityInfo73", None), - ByteField("facilityInfo74", None), - ByteField("facilityInfo75", None), - ByteField("facilityInfo76", None), - ByteField("facilityInfo77", None), - ByteField("facilityInfo78", None), - ByteField("facilityInfo79", None), - ByteField("facilityInfo80", None), - ByteField("facilityInfo81", None), - ByteField("facilityInfo82", None), - ByteField("facilityInfo83", None), - ByteField("facilityInfo84", None), - ByteField("facilityInfo85", None), - ByteField("facilityInfo86", None), - ByteField("facilityInfo87", None), - ByteField("facilityInfo88", None), - ByteField("facilityInfo89", None), - ByteField("facilityInfo90", None), - ByteField("facilityInfo91", None), - ByteField("facilityInfo92", None), - ByteField("facilityInfo93", None), - ByteField("facilityInfo94", None), - ByteField("facilityInfo95", None), - ByteField("facilityInfo96", None), - ByteField("facilityInfo97", None), - ByteField("facilityInfo98", None), - ByteField("facilityInfo99", None), - ByteField("facilityInfo100", None), - ByteField("facilityInfo101", None), - ByteField("facilityInfo102", None), - ByteField("facilityInfo103", None), - ByteField("facilityInfo104", None), - ByteField("facilityInfo105", None), - ByteField("facilityInfo106", None), - ByteField("facilityInfo107", None), - ByteField("facilityInfo108", None), - ByteField("facilityInfo109", None), - ByteField("facilityInfo110", None), - ByteField("facilityInfo111", None), - ByteField("facilityInfo112", None), - ByteField("facilityInfo113", None), - ByteField("facilityInfo114", None), - ByteField("facilityInfo115", None), - ByteField("facilityInfo116", None), - ByteField("facilityInfo117", None), - ByteField("facilityInfo118", None), - ByteField("facilityInfo119", None), - ByteField("facilityInfo120", None), - ByteField("facilityInfo121", None), - ByteField("facilityInfo122", None), - ByteField("facilityInfo123", None), - ByteField("facilityInfo124", None), - ByteField("facilityInfo125", None), - ByteField("facilityInfo126", None), - ByteField("facilityInfo127", None), - ByteField("facilityInfo128", None), - ByteField("facilityInfo129", None), - ByteField("facilityInfo130", None), - ByteField("facilityInfo131", None), - ByteField("facilityInfo132", None), - ByteField("facilityInfo133", None), - ByteField("facilityInfo134", None), - ByteField("facilityInfo135", None), - ByteField("facilityInfo136", None), - ByteField("facilityInfo137", None), - ByteField("facilityInfo138", None), - ByteField("facilityInfo139", None), - ByteField("facilityInfo140", None), - ByteField("facilityInfo141", None), - ByteField("facilityInfo142", None), - ByteField("facilityInfo143", None), - ByteField("facilityInfo144", None), - ByteField("facilityInfo145", None), - ByteField("facilityInfo146", None), - ByteField("facilityInfo147", None), - ByteField("facilityInfo148", None), - ByteField("facilityInfo149", None), - ByteField("facilityInfo150", None), - ByteField("facilityInfo151", None), - ByteField("facilityInfo152", None), - ByteField("facilityInfo153", None), - ByteField("facilityInfo154", None), - ByteField("facilityInfo155", None), - ByteField("facilityInfo156", None), - ByteField("facilityInfo157", None), - ByteField("facilityInfo158", None), - ByteField("facilityInfo159", None), - ByteField("facilityInfo160", None), - ByteField("facilityInfo161", None), - ByteField("facilityInfo162", None), - ByteField("facilityInfo163", None), - ByteField("facilityInfo164", None), - ByteField("facilityInfo165", None), - ByteField("facilityInfo166", None), - ByteField("facilityInfo167", None), - ByteField("facilityInfo168", None), - ByteField("facilityInfo169", None), - ByteField("facilityInfo170", None), - ByteField("facilityInfo171", None), - ByteField("facilityInfo172", None), - ByteField("facilityInfo173", None), - ByteField("facilityInfo174", None), - ByteField("facilityInfo175", None), - ByteField("facilityInfo176", None), - ByteField("facilityInfo177", None), - ByteField("facilityInfo178", None), - ByteField("facilityInfo179", None), - ByteField("facilityInfo180", None), - ByteField("facilityInfo181", None), - ByteField("facilityInfo182", None), - ByteField("facilityInfo183", None), - ByteField("facilityInfo184", None), - ByteField("facilityInfo185", None), - ByteField("facilityInfo186", None), - ByteField("facilityInfo187", None), - ByteField("facilityInfo188", None), - ByteField("facilityInfo189", None), - ByteField("facilityInfo190", None), - ByteField("facilityInfo191", None), - ByteField("facilityInfo192", None), - ByteField("facilityInfo193", None), - ByteField("facilityInfo194", None), - ByteField("facilityInfo195", None), - ByteField("facilityInfo196", None), - ByteField("facilityInfo197", None), - ByteField("facilityInfo198", None), - ByteField("facilityInfo199", None), - ByteField("facilityInfo200", None), - ByteField("facilityInfo201", None), - ByteField("facilityInfo202", None), - ByteField("facilityInfo203", None), - ByteField("facilityInfo204", None), - ByteField("facilityInfo205", None), - ByteField("facilityInfo206", None), - ByteField("facilityInfo207", None), - ByteField("facilityInfo208", None), - ByteField("facilityInfo209", None), - ByteField("facilityInfo210", None), - ByteField("facilityInfo211", None), - ByteField("facilityInfo212", None), - ByteField("facilityInfo213", None), - ByteField("facilityInfo214", None), - ByteField("facilityInfo215", None), - ByteField("facilityInfo216", None), - ByteField("facilityInfo217", None), - ByteField("facilityInfo218", None), - ByteField("facilityInfo219", None), - ByteField("facilityInfo220", None), - ByteField("facilityInfo221", None), - ByteField("facilityInfo222", None), - ByteField("facilityInfo223", None), - ByteField("facilityInfo224", None), - ByteField("facilityInfo225", None), - ByteField("facilityInfo226", None), - ByteField("facilityInfo227", None), - ByteField("facilityInfo228", None), - ByteField("facilityInfo229", None), - ByteField("facilityInfo230", None), - ByteField("facilityInfo231", None), - ByteField("facilityInfo232", None), - ByteField("facilityInfo233", None), - ByteField("facilityInfo234", None), - ByteField("facilityInfo235", None), - ByteField("facilityInfo236", None), - ByteField("facilityInfo237", None), - ByteField("facilityInfo238", None), - ByteField("facilityInfo239", None), - ByteField("facilityInfo240", None), - ByteField("facilityInfo241", None), - ByteField("facilityInfo242", None), - ByteField("facilityInfo243", None), - ByteField("facilityInfo244", None), - ByteField("facilityInfo245", None), - ByteField("facilityInfo246", None), - ByteField("facilityInfo247", None), - ByteField("facilityInfo248", None), - ByteField("facilityInfo249", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 251, a, self.fields_desc) - if self.lengthF is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -#len 2 to 5 -class HighLayerCompatibilityHdr(Packet): - """High layer compatibility Section 10.5.4.16""" - name = "High Layer Compatibility" - fields_desc = [ - BitField("eightBitHLC", None, 1), - XBitField("ieiHLC", None, 7), - - XByteField("lengthHLC", None), - # optional - BitField("ext", None, 1), - BitField("codingStd", None, 2), - BitField("interpret", None, 3), - BitField("presMeth", None, 2), - - BitField("ext1", None, 1), - BitField("highLayerId", None, 7), - - ConditionalField(BitField("ext2", 0x1, 1), - lambda pkt: pkt.ext1 == 0), - ConditionalField(BitField("exHiLayerId", 0x0, 7), - lambda pkt: pkt.ext1 == 0) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 5, a, self.fields_desc) - if res[0] is not 0: - p = p[:-res[0]] - if self.lengthHLC is None: - p = p[:1] + struct.pack(">B", len(p)-2) + p[2:] - return p + pay -# -# 10.5.4.16.1 Static conditions for the high layer -# compatibility IE contents -# - - -class KeypadFacilityHdr(Packet): - """Keypad facility Section 10.5.4.17""" - name = "Keypad Facility" - fields_desc = [ - BitField("eightBitKF", None, 1), - XBitField("ieiKF", None, 7), - BitField("spare", 0x0, 1), - BitField("keyPadInfo", 0x0, 7) - ] - - -# len 2 to 15 -class LowLayerCompatibilityHdr(Packet): - """Low layer compatibility Section 10.5.4.18""" - name = "Low Layer Compatibility" - fields_desc = [ - BitField("eightBitLLC", None, 1), - XBitField("ieiLLC", None, 7), - - XByteField("lengthLLC", None), - # optional - ByteField("rest0", None), - ByteField("rest1", None), - ByteField("rest2", None), - ByteField("rest3", None), - ByteField("rest4", None), - ByteField("rest5", None), - ByteField("rest6", None), - ByteField("rest7", None), - ByteField("rest8", None), - ByteField("rest9", None), - ByteField("rest10", None), - ByteField("rest11", None), - ByteField("rest12", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 15, a, self.fields_desc) - if self.lengthLLC is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class MoreDataHdr(Packet): - """More data Section 10.5.4.19""" - name = "More Data" - fields_desc = [ - BitField("eightBitMD", None, 1), - XBitField("ieiMD", None, 7), - ] - - -class NotificationIndicatorHdr(Packet): - """Notification indicator Section 10.5.4.20""" - name = "Notification Indicator" - fields_desc = [ - BitField("eightBitNI", None, 1), - XBitField("ieiNI", None, 7), - BitField("ext", 0x1, 1), - BitField("notifDesc", 0x0, 7) - ] - - -class ProgressIndicatorHdr(Packet): - """Progress indicator Section 10.5.4.21""" - name = "Progress Indicator" - fields_desc = [ - BitField("eightBitPI", None, 1), - XBitField("ieiPI", None, 7), - XByteField("lengthPI", 0x2), - BitField("ext", 0x1, 1), - BitField("codingStd", 0x0, 2), - BitField("spare", 0x0, 1), - BitField("location", 0x0, 4), - BitField("ext1", 0x1, 1), - BitField("progressDesc", 0x0, 7) - ] - - -class RecallTypeHdr(Packet): - """Recall type $(CCBS)$ Section 10.5.4.21a""" - name = "Recall Type $(CCBS)$" - fields_desc = [ - BitField("eightBitRT", None, 1), - XBitField("ieiRT", None, 7), - BitField("spare", 0x0, 5), - BitField("recallType", 0x0, 3) - ] - - -# len 3 to 19 -class RedirectingPartyBcdNumberHdr(Packet): - """Redirecting party BCD number Section 10.5.4.21b""" - name = "Redirecting Party BCD Number" - fields_desc = [ - BitField("eightBitRPBN", None, 1), - XBitField("ieiRPBN", None, 7), - - XByteField("lengthRPBN", None), - - BitField("ext", 0x1, 1), - BitField("typeNb", 0x0, 3), - BitField("numberingPlan", 0x0, 4), - # optional - ConditionalField(BitField("ext1", 0x1, 1), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("presId", None, 2), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("spare", None, 3), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("screenId", None, 2), - lambda pkt: pkt.ext == 0), - - BitField("nbDigit2", None, 4), - BitField("nbDigit1", None, 4), - - BitField("nbDigit4", None, 4), - BitField("nbDigit3", None, 4), - - BitField("nbDigit6", None, 4), - BitField("nbDigit5", None, 4), - - BitField("nbDigit8", None, 4), - BitField("nbDigit7", None, 4), - - BitField("nbDigit10", None, 4), - BitField("nbDigit9", None, 4), - - BitField("nbDigit12", None, 4), - BitField("nbDigit11", None, 4), - - BitField("nbDigit14", None, 4), - BitField("nbDigit13", None, 4), - - BitField("nbDigit16", None, 4), - BitField("nbDigit15", None, 4), - - BitField("nbDigit18", None, 4), - BitField("nbDigit17", None, 4), - - BitField("nbDigit20", None, 4), - BitField("nbDigit19", None, 4), - - BitField("nbDigit22", None, 4), - BitField("nbDigit21", None, 4), - - BitField("nbDigit24", None, 4), - BitField("nbDigit23", None, 4), - - BitField("nbDigit26", None, 4), - BitField("nbDigit25", None, 4), - - BitField("nbDigit28", None, 4), - BitField("nbDigit27", None, 4), - - BitField("nbDigit30", None, 4), - BitField("nbDigit29", None, 4), - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(3, 19, a, self.fields_desc) - if res[0] is not 0: - p = p[:-res[0]] - if self.lengthRPBN is None: - p = p[:1] + struct.pack(">B", len(p)-2) + p[2:] - return p + pay - - -# length 2 to 23 -class RedirectingPartySubaddressHdr(Packet): - """Redirecting party subaddress Section 10.5.4.21c""" - name = "Redirecting Party BCD Number" - fields_desc = [ - BitField("eightBitRPS", None, 1), - XBitField("ieiRPS", None, 7), - - XByteField("lengthRPS", None), - # optional - BitField("ext", None, 1), - BitField("typeSub", None, 3), - BitField("oddEven", None, 1), - BitField("spare", None, 3), - - ByteField("subInfo0", None), - ByteField("subInfo1", None), - ByteField("subInfo2", None), - ByteField("subInfo3", None), - ByteField("subInfo4", None), - ByteField("subInfo5", None), - ByteField("subInfo6", None), - ByteField("subInfo7", None), - ByteField("subInfo8", None), - ByteField("subInfo9", None), - ByteField("subInfo10", None), - ByteField("subInfo11", None), - ByteField("subInfo12", None), - ByteField("subInfo13", None), - ByteField("subInfo14", None), - ByteField("subInfo15", None), - ByteField("subInfo16", None), - ByteField("subInfo17", None), - ByteField("subInfo18", None), - ByteField("subInfo19", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 23, a, self.fields_desc) - if self.lengthRPS is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class RepeatIndicatorHdr(Packet): - """Repeat indicator Section 10.5.4.22""" - name = "Repeat Indicator" - fields_desc = [ - XBitField("ieiRI", None, 4), - BitField("repeatIndic", 0x0, 4) - ] - - -class ReverseCallSetupDirectionHdr(Packet): - """Reverse call setup direction Section 10.5.4.22a""" - name = "Reverse Call Setup Direction" - fields_desc = [ - ByteField("ieiRCSD", 0x0) - ] - - -# no upper length min 2(max for L3) (251) -class SetupContainerHdr(Packet): - """SETUP Container $(CCBS)$ Section 10.5.4.22b""" - name = "Setup Container $(CCBS)$" - fields_desc = [ - BitField("eightBitSC", None, 1), - XBitField("ieiSC", None, 7), - XByteField("lengthSC", None), - # optional - ByteField("mess1", None), - ByteField("mess2", None), - ByteField("mess3", None), - ByteField("mess4", None), - ByteField("mess5", None), - ByteField("mess6", None), - ByteField("mess7", None), - ByteField("mess8", None), - ByteField("mess9", None), - ByteField("mess10", None), - ByteField("mess11", None), - ByteField("mess12", None), - ByteField("mess13", None), - ByteField("mess14", None), - ByteField("mess15", None), - ByteField("mess16", None), - ByteField("mess17", None), - ByteField("mess18", None), - ByteField("mess19", None), - ByteField("mess20", None), - ByteField("mess21", None), - ByteField("mess22", None), - ByteField("mess23", None), - ByteField("mess24", None), - ByteField("mess25", None), - ByteField("mess26", None), - ByteField("mess27", None), - ByteField("mess28", None), - ByteField("mess29", None), - ByteField("mess30", None), - ByteField("mess31", None), - ByteField("mess32", None), - ByteField("mess33", None), - ByteField("mess34", None), - ByteField("mess35", None), - ByteField("mess36", None), - ByteField("mess37", None), - ByteField("mess38", None), - ByteField("mess39", None), - ByteField("mess40", None), - ByteField("mess41", None), - ByteField("mess42", None), - ByteField("mess43", None), - ByteField("mess44", None), - ByteField("mess45", None), - ByteField("mess46", None), - ByteField("mess47", None), - ByteField("mess48", None), - ByteField("mess49", None), - ByteField("mess50", None), - ByteField("mess51", None), - ByteField("mess52", None), - ByteField("mess53", None), - ByteField("mess54", None), - ByteField("mess55", None), - ByteField("mess56", None), - ByteField("mess57", None), - ByteField("mess58", None), - ByteField("mess59", None), - ByteField("mess60", None), - ByteField("mess61", None), - ByteField("mess62", None), - ByteField("mess63", None), - ByteField("mess64", None), - ByteField("mess65", None), - ByteField("mess66", None), - ByteField("mess67", None), - ByteField("mess68", None), - ByteField("mess69", None), - ByteField("mess70", None), - ByteField("mess71", None), - ByteField("mess72", None), - ByteField("mess73", None), - ByteField("mess74", None), - ByteField("mess75", None), - ByteField("mess76", None), - ByteField("mess77", None), - ByteField("mess78", None), - ByteField("mess79", None), - ByteField("mess80", None), - ByteField("mess81", None), - ByteField("mess82", None), - ByteField("mess83", None), - ByteField("mess84", None), - ByteField("mess85", None), - ByteField("mess86", None), - ByteField("mess87", None), - ByteField("mess88", None), - ByteField("mess89", None), - ByteField("mess90", None), - ByteField("mess91", None), - ByteField("mess92", None), - ByteField("mess93", None), - ByteField("mess94", None), - ByteField("mess95", None), - ByteField("mess96", None), - ByteField("mess97", None), - ByteField("mess98", None), - ByteField("mess99", None), - ByteField("mess100", None), - ByteField("mess101", None), - ByteField("mess102", None), - ByteField("mess103", None), - ByteField("mess104", None), - ByteField("mess105", None), - ByteField("mess106", None), - ByteField("mess107", None), - ByteField("mess108", None), - ByteField("mess109", None), - ByteField("mess110", None), - ByteField("mess111", None), - ByteField("mess112", None), - ByteField("mess113", None), - ByteField("mess114", None), - ByteField("mess115", None), - ByteField("mess116", None), - ByteField("mess117", None), - ByteField("mess118", None), - ByteField("mess119", None), - ByteField("mess120", None), - ByteField("mess121", None), - ByteField("mess122", None), - ByteField("mess123", None), - ByteField("mess124", None), - ByteField("mess125", None), - ByteField("mess126", None), - ByteField("mess127", None), - ByteField("mess128", None), - ByteField("mess129", None), - ByteField("mess130", None), - ByteField("mess131", None), - ByteField("mess132", None), - ByteField("mess133", None), - ByteField("mess134", None), - ByteField("mess135", None), - ByteField("mess136", None), - ByteField("mess137", None), - ByteField("mess138", None), - ByteField("mess139", None), - ByteField("mess140", None), - ByteField("mess141", None), - ByteField("mess142", None), - ByteField("mess143", None), - ByteField("mess144", None), - ByteField("mess145", None), - ByteField("mess146", None), - ByteField("mess147", None), - ByteField("mess148", None), - ByteField("mess149", None), - ByteField("mess150", None), - ByteField("mess151", None), - ByteField("mess152", None), - ByteField("mess153", None), - ByteField("mess154", None), - ByteField("mess155", None), - ByteField("mess156", None), - ByteField("mess157", None), - ByteField("mess158", None), - ByteField("mess159", None), - ByteField("mess160", None), - ByteField("mess161", None), - ByteField("mess162", None), - ByteField("mess163", None), - ByteField("mess164", None), - ByteField("mess165", None), - ByteField("mess166", None), - ByteField("mess167", None), - ByteField("mess168", None), - ByteField("mess169", None), - ByteField("mess170", None), - ByteField("mess171", None), - ByteField("mess172", None), - ByteField("mess173", None), - ByteField("mess174", None), - ByteField("mess175", None), - ByteField("mess176", None), - ByteField("mess177", None), - ByteField("mess178", None), - ByteField("mess179", None), - ByteField("mess180", None), - ByteField("mess181", None), - ByteField("mess182", None), - ByteField("mess183", None), - ByteField("mess184", None), - ByteField("mess185", None), - ByteField("mess186", None), - ByteField("mess187", None), - ByteField("mess188", None), - ByteField("mess189", None), - ByteField("mess190", None), - ByteField("mess191", None), - ByteField("mess192", None), - ByteField("mess193", None), - ByteField("mess194", None), - ByteField("mess195", None), - ByteField("mess196", None), - ByteField("mess197", None), - ByteField("mess198", None), - ByteField("mess199", None), - ByteField("mess200", None), - ByteField("mess201", None), - ByteField("mess202", None), - ByteField("mess203", None), - ByteField("mess204", None), - ByteField("mess205", None), - ByteField("mess206", None), - ByteField("mess207", None), - ByteField("mess208", None), - ByteField("mess209", None), - ByteField("mess210", None), - ByteField("mess211", None), - ByteField("mess212", None), - ByteField("mess213", None), - ByteField("mess214", None), - ByteField("mess215", None), - ByteField("mess216", None), - ByteField("mess217", None), - ByteField("mess218", None), - ByteField("mess219", None), - ByteField("mess220", None), - ByteField("mess221", None), - ByteField("mess222", None), - ByteField("mess223", None), - ByteField("mess224", None), - ByteField("mess225", None), - ByteField("mess226", None), - ByteField("mess227", None), - ByteField("mess228", None), - ByteField("mess229", None), - ByteField("mess230", None), - ByteField("mess231", None), - ByteField("mess232", None), - ByteField("mess233", None), - ByteField("mess234", None), - ByteField("mess235", None), - ByteField("mess236", None), - ByteField("mess237", None), - ByteField("mess238", None), - ByteField("mess239", None), - ByteField("mess240", None), - ByteField("mess241", None), - ByteField("mess242", None), - ByteField("mess243", None), - ByteField("mess244", None), - ByteField("mess245", None), - ByteField("mess246", None), - ByteField("mess247", None), - ByteField("mess248", None), - ByteField("mess249", None), - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 251, a, self.fields_desc) - if self.lengthSC is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class SignalHdr(Packet): - """Signal Section 10.5.4.23""" - name = "Signal" - fields_desc = [ - BitField("eightBitS", None, 1), - XBitField("ieiS", None, 7), - ByteField("sigValue", 0x0) - ] - - -# length 2 to max for L3 message (251) -class SsVersionIndicatorHdr(Packet): - """SS Version Indicator Section 10.5.4.24""" - name = "SS Version Indicator" - fields_desc = [ - BitField("eightBitSVI", None, 1), - XBitField("ieiSVI", None, 7), - XByteField("lengthSVI", None), - # optional - ByteField("info1", None), - ByteField("info2", None), - ByteField("info3", None), - ByteField("info4", None), - ByteField("info5", None), - ByteField("info6", None), - ByteField("info7", None), - ByteField("info8", None), - ByteField("info9", None), - ByteField("info10", None), - ByteField("info11", None), - ByteField("info12", None), - ByteField("info13", None), - ByteField("info14", None), - ByteField("info15", None), - ByteField("info16", None), - ByteField("info17", None), - ByteField("info18", None), - ByteField("info19", None), - ByteField("info20", None), - ByteField("info21", None), - ByteField("info22", None), - ByteField("info23", None), - ByteField("info24", None), - ByteField("info25", None), - ByteField("info26", None), - ByteField("info27", None), - ByteField("info28", None), - ByteField("info29", None), - ByteField("info30", None), - ByteField("info31", None), - ByteField("info32", None), - ByteField("info33", None), - ByteField("info34", None), - ByteField("info35", None), - ByteField("info36", None), - ByteField("info37", None), - ByteField("info38", None), - ByteField("info39", None), - ByteField("info40", None), - ByteField("info41", None), - ByteField("info42", None), - ByteField("info43", None), - ByteField("info44", None), - ByteField("info45", None), - ByteField("info46", None), - ByteField("info47", None), - ByteField("info48", None), - ByteField("info49", None), - ByteField("info50", None), - ByteField("info51", None), - ByteField("info52", None), - ByteField("info53", None), - ByteField("info54", None), - ByteField("info55", None), - ByteField("info56", None), - ByteField("info57", None), - ByteField("info58", None), - ByteField("info59", None), - ByteField("info60", None), - ByteField("info61", None), - ByteField("info62", None), - ByteField("info63", None), - ByteField("info64", None), - ByteField("info65", None), - ByteField("info66", None), - ByteField("info67", None), - ByteField("info68", None), - ByteField("info69", None), - ByteField("info70", None), - ByteField("info71", None), - ByteField("info72", None), - ByteField("info73", None), - ByteField("info74", None), - ByteField("info75", None), - ByteField("info76", None), - ByteField("info77", None), - ByteField("info78", None), - ByteField("info79", None), - ByteField("info80", None), - ByteField("info81", None), - ByteField("info82", None), - ByteField("info83", None), - ByteField("info84", None), - ByteField("info85", None), - ByteField("info86", None), - ByteField("info87", None), - ByteField("info88", None), - ByteField("info89", None), - ByteField("info90", None), - ByteField("info91", None), - ByteField("info92", None), - ByteField("info93", None), - ByteField("info94", None), - ByteField("info95", None), - ByteField("info96", None), - ByteField("info97", None), - ByteField("info98", None), - ByteField("info99", None), - ByteField("info100", None), - ByteField("info101", None), - ByteField("info102", None), - ByteField("info103", None), - ByteField("info104", None), - ByteField("info105", None), - ByteField("info106", None), - ByteField("info107", None), - ByteField("info108", None), - ByteField("info109", None), - ByteField("info110", None), - ByteField("info111", None), - ByteField("info112", None), - ByteField("info113", None), - ByteField("info114", None), - ByteField("info115", None), - ByteField("info116", None), - ByteField("info117", None), - ByteField("info118", None), - ByteField("info119", None), - ByteField("info120", None), - ByteField("info121", None), - ByteField("info122", None), - ByteField("info123", None), - ByteField("info124", None), - ByteField("info125", None), - ByteField("info126", None), - ByteField("info127", None), - ByteField("info128", None), - ByteField("info129", None), - ByteField("info130", None), - ByteField("info131", None), - ByteField("info132", None), - ByteField("info133", None), - ByteField("info134", None), - ByteField("info135", None), - ByteField("info136", None), - ByteField("info137", None), - ByteField("info138", None), - ByteField("info139", None), - ByteField("info140", None), - ByteField("info141", None), - ByteField("info142", None), - ByteField("info143", None), - ByteField("info144", None), - ByteField("info145", None), - ByteField("info146", None), - ByteField("info147", None), - ByteField("info148", None), - ByteField("info149", None), - ByteField("info150", None), - ByteField("info151", None), - ByteField("info152", None), - ByteField("info153", None), - ByteField("info154", None), - ByteField("info155", None), - ByteField("info156", None), - ByteField("info157", None), - ByteField("info158", None), - ByteField("info159", None), - ByteField("info160", None), - ByteField("info161", None), - ByteField("info162", None), - ByteField("info163", None), - ByteField("info164", None), - ByteField("info165", None), - ByteField("info166", None), - ByteField("info167", None), - ByteField("info168", None), - ByteField("info169", None), - ByteField("info170", None), - ByteField("info171", None), - ByteField("info172", None), - ByteField("info173", None), - ByteField("info174", None), - ByteField("info175", None), - ByteField("info176", None), - ByteField("info177", None), - ByteField("info178", None), - ByteField("info179", None), - ByteField("info180", None), - ByteField("info181", None), - ByteField("info182", None), - ByteField("info183", None), - ByteField("info184", None), - ByteField("info185", None), - ByteField("info186", None), - ByteField("info187", None), - ByteField("info188", None), - ByteField("info189", None), - ByteField("info190", None), - ByteField("info191", None), - ByteField("info192", None), - ByteField("info193", None), - ByteField("info194", None), - ByteField("info195", None), - ByteField("info196", None), - ByteField("info197", None), - ByteField("info198", None), - ByteField("info199", None), - ByteField("info200", None), - ByteField("info201", None), - ByteField("info202", None), - ByteField("info203", None), - ByteField("info204", None), - ByteField("info205", None), - ByteField("info206", None), - ByteField("info207", None), - ByteField("info208", None), - ByteField("info209", None), - ByteField("info210", None), - ByteField("info211", None), - ByteField("info212", None), - ByteField("info213", None), - ByteField("info214", None), - ByteField("info215", None), - ByteField("info216", None), - ByteField("info217", None), - ByteField("info218", None), - ByteField("info219", None), - ByteField("info220", None), - ByteField("info221", None), - ByteField("info222", None), - ByteField("info223", None), - ByteField("info224", None), - ByteField("info225", None), - ByteField("info226", None), - ByteField("info227", None), - ByteField("info228", None), - ByteField("info229", None), - ByteField("info230", None), - ByteField("info231", None), - ByteField("info232", None), - ByteField("info233", None), - ByteField("info234", None), - ByteField("info235", None), - ByteField("info236", None), - ByteField("info237", None), - ByteField("info238", None), - ByteField("info239", None), - ByteField("info240", None), - ByteField("info241", None), - ByteField("info242", None), - ByteField("info243", None), - ByteField("info244", None), - ByteField("info245", None), - ByteField("info246", None), - ByteField("info247", None), - ByteField("info248", None), - ByteField("info249", None), - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 251, a, self.fields_desc) - if self.lengthSVI is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# length 3 to 35 or 131 -class UserUserHdr(Packet): - """User-user Section 10.5.4.25""" - name = "User-User" - fields_desc = [ - BitField("eightBitUU", None, 1), - XBitField("ieiUU", None, 7), - - XByteField("lengthUU", None), # dynamic length of field depending - # of the type of message - # let user decide which length he - # wants to take - # => more fuzzing options - ByteField("userUserPD", 0x0), - # optional - ByteField("userUserInfo1", None), - ByteField("userUserInfo2", None), - ByteField("userUserInfo3", None), - ByteField("userUserInfo4", None), - ByteField("userUserInfo5", None), - ByteField("userUserInfo6", None), - ByteField("userUserInfo7", None), - ByteField("userUserInfo8", None), - ByteField("userUserInfo9", None), - ByteField("userUserInfo10", None), - ByteField("userUserInfo11", None), - ByteField("userUserInfo12", None), - ByteField("userUserInfo13", None), - ByteField("userUserInfo14", None), - ByteField("userUserInfo15", None), - ByteField("userUserInfo16", None), - ByteField("userUserInfo17", None), - ByteField("userUserInfo18", None), - ByteField("userUserInfo19", None), - ByteField("userUserInfo20", None), - ByteField("userUserInfo21", None), - ByteField("userUserInfo22", None), - ByteField("userUserInfo23", None), - ByteField("userUserInfo24", None), - ByteField("userUserInfo25", None), - ByteField("userUserInfo26", None), - ByteField("userUserInfo27", None), - ByteField("userUserInfo28", None), - ByteField("userUserInfo29", None), - ByteField("userUserInfo30", None), - ByteField("userUserInfo31", None), - ByteField("userUserInfo32", None), - # long packet - ByteField("userUserInfo33", None), - ByteField("userUserInfo34", None), - ByteField("userUserInfo35", None), - ByteField("userUserInfo36", None), - ByteField("userUserInfo37", None), - ByteField("userUserInfo38", None), - ByteField("userUserInfo39", None), - ByteField("userUserInfo40", None), - ByteField("userUserInfo41", None), - ByteField("userUserInfo42", None), - ByteField("userUserInfo43", None), - ByteField("userUserInfo44", None), - ByteField("userUserInfo45", None), - ByteField("userUserInfo46", None), - ByteField("userUserInfo47", None), - ByteField("userUserInfo48", None), - ByteField("userUserInfo49", None), - ByteField("userUserInfo50", None), - ByteField("userUserInfo51", None), - ByteField("userUserInfo52", None), - ByteField("userUserInfo53", None), - ByteField("userUserInfo54", None), - ByteField("userUserInfo55", None), - ByteField("userUserInfo56", None), - ByteField("userUserInfo57", None), - ByteField("userUserInfo58", None), - ByteField("userUserInfo59", None), - ByteField("userUserInfo60", None), - ByteField("userUserInfo61", None), - ByteField("userUserInfo62", None), - ByteField("userUserInfo63", None), - ByteField("userUserInfo64", None), - ByteField("userUserInfo65", None), - ByteField("userUserInfo66", None), - ByteField("userUserInfo67", None), - ByteField("userUserInfo68", None), - ByteField("userUserInfo69", None), - ByteField("userUserInfo70", None), - ByteField("userUserInfo71", None), - ByteField("userUserInfo72", None), - ByteField("userUserInfo73", None), - ByteField("userUserInfo74", None), - ByteField("userUserInfo75", None), - ByteField("userUserInfo76", None), - ByteField("userUserInfo77", None), - ByteField("userUserInfo78", None), - ByteField("userUserInfo79", None), - ByteField("userUserInfo80", None), - ByteField("userUserInfo81", None), - ByteField("userUserInfo82", None), - ByteField("userUserInfo83", None), - ByteField("userUserInfo84", None), - ByteField("userUserInfo85", None), - ByteField("userUserInfo86", None), - ByteField("userUserInfo87", None), - ByteField("userUserInfo88", None), - ByteField("userUserInfo89", None), - ByteField("userUserInfo90", None), - ByteField("userUserInfo91", None), - ByteField("userUserInfo92", None), - ByteField("userUserInfo93", None), - ByteField("userUserInfo94", None), - ByteField("userUserInfo95", None), - ByteField("userUserInfo96", None), - ByteField("userUserInfo97", None), - ByteField("userUserInfo98", None), - ByteField("userUserInfo99", None), - ByteField("userUserInfo100", None), - ByteField("userUserInfo101", None), - ByteField("userUserInfo102", None), - ByteField("userUserInfo103", None), - ByteField("userUserInfo104", None), - ByteField("userUserInfo105", None), - ByteField("userUserInfo106", None), - ByteField("userUserInfo107", None), - ByteField("userUserInfo108", None), - ByteField("userUserInfo109", None), - ByteField("userUserInfo110", None), - ByteField("userUserInfo111", None), - ByteField("userUserInfo112", None), - ByteField("userUserInfo113", None), - ByteField("userUserInfo114", None), - ByteField("userUserInfo115", None), - ByteField("userUserInfo116", None), - ByteField("userUserInfo117", None), - ByteField("userUserInfo118", None), - ByteField("userUserInfo119", None), - ByteField("userUserInfo120", None), - ByteField("userUserInfo121", None), - ByteField("userUserInfo122", None), - ByteField("userUserInfo123", None), - ByteField("userUserInfo124", None), - ByteField("userUserInfo125", None), - ByteField("userUserInfo126", None), - ByteField("userUserInfo127", None), - ByteField("userUserInfo128", None), - ByteField("userUserInfo129", None), - ByteField("userUserInfo130", None), - ByteField("userUserInfo131", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(3, 131, a, self.fields_desc) - if self.lengthUU is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class AlertingPatternHdr(Packet): - """Alerting Pattern 10.5.4.26""" - name = "Alerting Pattern" - fields_desc = [ - BitField("eightBitAP", None, 1), - XBitField("ieiAP", None, 7), - XByteField("lengthAP", 0x3), - BitField("spare", 0x0, 4), - BitField("alertingValue", 0x0, 4) - ] - - -class AllowedActionsHdr(Packet): - """Allowed actions $(CCBS)$ Section 10.5.4.26""" - name = "Allowed Actions $(CCBS)$" - fields_desc = [ - BitField("eightBitAA", None, 1), - XBitField("ieiAA", None, 7), - XByteField("lengthAP", 0x3), - BitField("CCBS", 0x0, 1), - BitField("spare", 0x0, 7) - ] - - -# -# 10.5.5 GPRS mobility management information elements -# - -class AttachResult(Packet): - """Attach result Section 10.5.5.1""" - name = "Attach Result" - fields_desc = [ - XBitField("ieiAR", 0x0, 4), - BitField("spare", 0x0, 1), - BitField("result", 0x1, 3) - ] - - -class AttachTypeHdr(Packet): - """Attach type Section 10.5.5.2""" - name = "Attach Type" - fields_desc = [ - XBitField("ieiAT", None, 4), - BitField("spare", 0x0, 1), - BitField("type", 0x1, 3) - ] - - -# Fix 1/2 len problem -class AttachTypeAndCiphKeySeqNr(Packet): - name = "Attach Type and Cipher Key Sequence Number" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("type", 0x1, 3), - BitField("spareHalfOctets", 0x0, 4) - ] - - -class CipheringAlgorithm(Packet): - """Ciphering algorithm Section 10.5.5.3""" - name = "Ciphering Algorithm" - fields_desc = [ - XBitField("ieiCA", 0x0, 4), - BitField("spare", 0x0, 1), - BitField("type", 0x1, 3) - ] - - -# Fix 1/2 len problem -class CipheringAlgorithmAndImeisvRequest(Packet): - name = "Ciphering Algorithm and Imeisv Request" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("type", 0x1, 3), - BitField("spare", 0x0, 1), - BitField("imeisvVal", 0x0, 3) - ] - - -# [Spare] -class TmsiStatus(Packet): - """[Spare] TMSI status Section 10.5.5.4""" - name = "[Spare] TMSI Status" - fields_desc = [ - XBitField("ieiTS", None, 4), - BitField("spare", 0x0, 3), - BitField("flag", 0x1, 1) - ] - - -class DetachType(Packet): - """Detach type Section 10.5.5.5""" - name = "Detach Type" - fields_desc = [ - XBitField("ieiDT", 0x0, 4), - BitField("poweroff", 0x0, 1), - BitField("type", 0x1, 3) - ] - - -# Fix 1/2 len problem -class DetachTypeAndForceToStandby(Packet): - name = "Detach Type and Force To Standby" - fields_desc = [ - BitField("poweroff", 0x0, 1), - BitField("type", 0x1, 3), - BitField("spare", 0x0, 1), - BitField("forceStandby", 0x0, 3) - ] - - -# Fix 1/2 len problem -class DetachTypeAndSpareHalfOctets(Packet): - name = "Detach Type and Spare Half Octets" - fields_desc = [ - BitField("poweroff", 0x0, 1), - BitField("type", 0x1, 3), - BitField("spareHalfOctets", 0x0, 4) - ] - - -class DrxParameter(Packet): - """DRX parameter Section 10.5.5.6""" - name = "DRX Parameter" - fields_desc = [ - ByteField("ieiDP", 0x0), - ByteField("splitPG", 0x0), - BitField("spare", 0x0, 4), - BitField("splitCCCH", 0x0, 1), - BitField("NonDrxTimer", 0x1, 3) - ] - - -class ForceToStandby(Packet): - """Force to standby Section 10.5.5.7""" - name = "Force To Standby" - fields_desc = [ - XBitField("ieiFTS", 0x0, 4), - BitField("spare", 0x0, 1), - BitField("forceStandby", 0x0, 3) - ] - - -# Fix 1/2 len problem -class ForceToStandbyAndAcReferenceNumber(Packet): - name = "Force To Standby And Ac Reference Number" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("forceStandby", 0x0, 3), - BitField("acRefVal", 0x0, 4) - ] - - -# Fix 1/2 len problem -class ForceToStandbyAndUpdateResult(Packet): - name = "Force To Standby And Update Result" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("forceStandby", 0x0, 3), - BitField("spare", 0x0, 1), - BitField("updateResVal", 0x0, 3) - ] - - -# Fix 1/2 len problem -class ForceToStandbyAndSpareHalfOctets(Packet): - name = "Force To Standby And Spare Half Octets" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("forceStandby", 0x0, 3), - BitField("spareHalfOctets", 0x0, 4) - ] - - -class PTmsiSignature(Packet): - """P-TMSI signature Section 10.5.5.8""" - name = "P-TMSI Signature" - fields_desc = [ - ByteField("ieiPTS", 0x0), - BitField("sgnature", 0x0, 24) - ] - - -class IdentityType2(Packet): - """Identity type 2 Section 10.5.5.9""" - name = "Identity Type 2" - fields_desc = [ - XBitField("ieiIT2", 0x0, 4), - BitField("spare", 0x0, 1), - BitField("typeOfIdentity", 0x0, 3) - ] - - -# Fix 1/2 len problem -class IdentityType2AndforceToStandby(Packet): - name = "Identity Type 2 and Force to Standby" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("typeOfIdentity", 0x0, 3), - BitField("spare", 0x0, 1), - BitField("forceStandby", 0x0, 3) - ] - - -class ImeisvRequest(Packet): - """IMEISV request Section 10.5.5.10""" - name = "IMEISV Request" - fields_desc = [ - XBitField("ieiIR", 0x0, 4), - BitField("spare", 0x0, 1), - BitField("imeisvVal", 0x0, 3) - ] - - -# Fix 1/2 len problem -class ImeisvRequestAndForceToStandby(Packet): - name = "IMEISV Request and Force To Standby" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("imeisvVal", 0x0, 3), - BitField("spareHalfOctets", 0x0, 4) - ] - - -# length 4 to 19 -class ReceiveNpduNumbersList(Packet): - """Receive N-PDU Numbers list Section 10.5.5.11""" - name = "Receive N-PDU Numbers list" - fields_desc = [ - ByteField("ieiRNNL", 0x0), - - XByteField("lengthRNNL", None), - - BitField("nbList0", 0x0, 16), - # optional - ByteField("nbList1", None), - ByteField("nbList2", None), - ByteField("nbList3", None), - ByteField("nbList4", None), - ByteField("nbList5", None), - ByteField("nbList6", None), - ByteField("nbList7", None), - ByteField("nbList8", None), - ByteField("nbList9", None), - ByteField("nbList10", None), - ByteField("nbList11", None), - ByteField("nbList12", None), - ByteField("nbList13", None), - ByteField("nbList14", None), - ByteField("nbList15", None), - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(4, 19, a, self.fields_desc) - if self.lengthRNNL is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class MsNetworkCapability(Packet): - """MS network capability Section 10.5.5.12""" - name = "MS Network Capability" - fields_desc = [ - ByteField("ieiMNC", 0x0), - XByteField("lengthMNC", 0x3), - ByteField("msNetValue", 0x0) - ] - - -# length 6 to 14 -class MsRadioAccessCapability(Packet): - """MS Radio Access capability Section 10.5.5.12a""" - name = "MS Radio Access Capability" - fields_desc = [ - ByteField("ieiMRAC", 0x24), - - XByteField("lengthMRAC", None), - - BitField("spare1", 0x0, 1), # ... - - BitField("accessCap", 0x0, 4), - BitField("accessTechType", 0x0, 4), - # access capability - BitField("bool", 0x0, 1), - BitField("lengthContent", 0x0, 7), - BitField("spare1", 0x0, 1), # ... - # content - BitField("pwrCap", 0x0, 3), - BitField("bool1", 0x0, 1), - BitField("a51", 0x0, 1), - BitField("a52", 0x0, 1), - BitField("a53", 0x0, 1), - BitField("a54", 0x0, 1), - - BitField("a55", 0x0, 1), - BitField("a56", 0x0, 1), - BitField("a57", 0x0, 1), - BitField("esInd", 0x0, 1), - BitField("ps", 0x0, 1), - BitField("vgcs", 0x0, 1), - BitField("vbs", 0x0, 1), - BitField("bool2", 0x0, 1), - # multislot - BitField("bool3", 0x0, 1), - BitField("hscsd", 0x0, 5), - - BitField("bool4", 0x0, 1), - BitField("gprs", 0x0, 5), - BitField("gprsExt", 0x0, 1), - BitField("bool5", 0x0, 1), - - BitField("smsVal", 0x0, 4), - BitField("smVal", 0x0, 4) - ] - - -# 10.5.5.13 Spare -# This is intentionally left spare. - -class GmmCause(Packet): - """GMM cause Section 10.5.5.14""" - name = "GMM Cause" - fields_desc = [ - ByteField("ieiGC", 0x0), - ByteField("causeValue", 0x0) - ] - - -class RoutingAreaIdentification(Packet): - """Routing area identification Section 10.5.5.15""" - name = "Routing Area Identification" - fields_desc = [ - ByteField("ieiRAI", 0x0), - BitField("mccDigit2", 0x0, 4), - BitField("mccDigit1", 0x0, 4), - BitField("mncDigit3", 0x0, 4), - BitField("mccDigit3", 0x0, 4), - BitField("mccDigit2", 0x0, 4), - BitField("mccDigit1", 0x0, 4), - ByteField("LAC", 0x0), - ByteField("LAC1", 0x0), - ByteField("LAC", 0x0) - ] -# 10.5.5.16 Spare -# This is intentionally left spare. - - -class UpdateResult(Packet): - """Update result Section 10.5.5.17""" - name = "Update Result" - fields_desc = [ - XBitField("ieiUR", 0x0, 4), - BitField("spare", 0x0, 1), - BitField("updateResVal", 0x0, 3) - ] - - -class UpdateType(Packet): - """Update type Section 10.5.5.18""" - name = "Update Type" - fields_desc = [ - XBitField("ieiUT", 0x0, 4), - BitField("spare", 0x0, 1), - BitField("updateTypeVal", 0x0, 3) - ] - - -# Fix 1/2 len problem -class UpdateTypeAndCiphKeySeqNr(Packet): - name = "Update Type and Cipher Key Sequence Number" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("updateTypeVal", 0x0, 3), - BitField("spare", 0x0, 1), - BitField("keySeq", 0x0, 3) - ] - - -class AcReferenceNumber(Packet): - """A&C reference number Section 10.5.5.19""" - name = "A&C Reference Number" - fields_desc = [ - XBitField("ieiARN", 0x0, 4), - BitField("acRefVal", 0x0, 4) - ] - - -# Fix 1/2 len problem -class AcReferenceNumberAndSpareHalfOctets(Packet): - name = "A&C Reference Number and Spare Half Octets" - fields_desc = [ - BitField("acRefVal", 0x0, 4), - BitField("spareHalfOctets", 0x0, 4) - ] -# -# 10.5.6 Session management information elements -# -# length 3 to 102 - - -class AccessPointName(Packet): - """Access Point Name Section 10.5.6.1""" - name = "Access Point Name" - fields_desc = [ - ByteField("ieiAPN", 0x0), - XByteField("lengthAPN", None), - ByteField("apName", 0x0), - # optional - ByteField("apName1", None), - ByteField("apName2", None), - ByteField("apName3", None), - ByteField("apName4", None), - ByteField("apName5", None), - ByteField("apName6", None), - ByteField("apName7", None), - ByteField("apName8", None), - ByteField("apName9", None), - ByteField("apName10", None), - ByteField("apName11", None), - ByteField("apName12", None), - ByteField("apName13", None), - ByteField("apName14", None), - ByteField("apName15", None), - ByteField("apName16", None), - ByteField("apName17", None), - ByteField("apName18", None), - ByteField("apName19", None), - ByteField("apName20", None), - ByteField("apName21", None), - ByteField("apName22", None), - ByteField("apName23", None), - ByteField("apName24", None), - ByteField("apName25", None), - ByteField("apName26", None), - ByteField("apName27", None), - ByteField("apName28", None), - ByteField("apName29", None), - ByteField("apName30", None), - ByteField("apName31", None), - ByteField("apName32", None), - ByteField("apName33", None), - ByteField("apName34", None), - ByteField("apName35", None), - ByteField("apName36", None), - ByteField("apName37", None), - ByteField("apName38", None), - ByteField("apName39", None), - ByteField("apName40", None), - ByteField("apName41", None), - ByteField("apName42", None), - ByteField("apName43", None), - ByteField("apName44", None), - ByteField("apName45", None), - ByteField("apName46", None), - ByteField("apName47", None), - ByteField("apName48", None), - ByteField("apName49", None), - ByteField("apName50", None), - ByteField("apName51", None), - ByteField("apName52", None), - ByteField("apName53", None), - ByteField("apName54", None), - ByteField("apName55", None), - ByteField("apName56", None), - ByteField("apName57", None), - ByteField("apName58", None), - ByteField("apName59", None), - ByteField("apName60", None), - ByteField("apName61", None), - ByteField("apName62", None), - ByteField("apName63", None), - ByteField("apName64", None), - ByteField("apName65", None), - ByteField("apName66", None), - ByteField("apName67", None), - ByteField("apName68", None), - ByteField("apName69", None), - ByteField("apName70", None), - ByteField("apName71", None), - ByteField("apName72", None), - ByteField("apName73", None), - ByteField("apName74", None), - ByteField("apName75", None), - ByteField("apName76", None), - ByteField("apName77", None), - ByteField("apName78", None), - ByteField("apName79", None), - ByteField("apName80", None), - ByteField("apName81", None), - ByteField("apName82", None), - ByteField("apName83", None), - ByteField("apName84", None), - ByteField("apName85", None), - ByteField("apName86", None), - ByteField("apName87", None), - ByteField("apName88", None), - ByteField("apName89", None), - ByteField("apName90", None), - ByteField("apName91", None), - ByteField("apName92", None), - ByteField("apName93", None), - ByteField("apName94", None), - ByteField("apName95", None), - ByteField("apName96", None), - ByteField("apName97", None), - ByteField("apName98", None), - ByteField("apName99", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(3, 102, a, self.fields_desc) - if self.lengthAPN is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class NetworkServiceAccessPointIdentifier(Packet): - """Network service access point identifier Section 10.5.6.2""" - name = "Network Service Access Point Identifier" - fields_desc = [ - ByteField("ieiNSAPI", 0x0), - BitField("spare", 0x0, 4), - BitField("nsapiVal", 0x0, 4) - ] - - -# length 2 to 253 -class ProtocolConfigurationOptions(Packet): - """Protocol configuration options Section 10.5.6.3""" - name = "Protocol Configuration Options" - fields_desc = [ - ByteField("ieiPCO", 0x0), - - XByteField("lengthPCO", None), - # optional - BitField("ext", None, 1), - BitField("spare", None, 4), - BitField("configProto", None, 3), - - ByteField("protoId1", None), - ByteField("lenProto1", None), - ByteField("proto1Content", None), - - ByteField("protoId2", None), - ByteField("lenProto2", None), - ByteField("proto2Content", None), - - ByteField("protoId3", None), - ByteField("lenProto3", None), - ByteField("proto3Content", None), - - ByteField("protoId4", None), - ByteField("lenProto4", None), - ByteField("proto4Content", None), - - - ByteField("protoId5", None), - ByteField("lenProto5", None), - ByteField("proto5Content", None), - - ByteField("protoId6", None), - ByteField("lenProto6", None), - ByteField("proto6Content", None), - - ByteField("protoId7", None), - ByteField("lenProto7", None), - ByteField("proto7Content", None), - - ByteField("protoId8", None), - ByteField("lenProto8", None), - ByteField("proto8Content", None), - - ByteField("protoId9", None), - ByteField("lenProto9", None), - ByteField("proto9Content", None), - - ByteField("protoId10", None), - ByteField("lenProto10", None), - ByteField("proto10Content", None), - - ByteField("protoId11", None), - ByteField("lenProto11", None), - ByteField("proto11Content", None), - - ByteField("protoId12", None), - ByteField("lenProto12", None), - ByteField("proto12Content", None), - - ByteField("protoId13", None), - ByteField("lenProto13", None), - ByteField("proto13Content", None), - - ByteField("protoId14", None), - ByteField("lenProto14", None), - ByteField("proto14Content", None), - - ByteField("protoId15", None), - ByteField("lenProto15", None), - ByteField("proto15Content", None), - - ByteField("protoId16", None), - ByteField("lenProto16", None), - ByteField("proto16Content", None), - - ByteField("protoId17", None), - ByteField("lenProto17", None), - ByteField("proto17Content", None), - - ByteField("protoId18", None), - ByteField("lenProto18", None), - ByteField("proto18Content", None), - - ByteField("protoId19", None), - ByteField("lenProto19", None), - ByteField("proto19Content", None), - - ByteField("protoId20", None), - ByteField("lenProto20", None), - ByteField("proto20Content", None), - - ByteField("protoId21", None), - ByteField("lenProto21", None), - ByteField("proto21Content", None), - - ByteField("protoId22", None), - ByteField("lenProto22", None), - ByteField("proto22Content", None), - - ByteField("protoId23", None), - ByteField("lenProto23", None), - ByteField("proto23Content", None), - - ByteField("protoId24", None), - ByteField("lenProto24", None), - ByteField("proto24Content", None), - - ByteField("protoId25", None), - ByteField("lenProto25", None), - ByteField("proto25Content", None), - - ByteField("protoId26", None), - ByteField("lenProto26", None), - ByteField("proto26Content", None), - - ByteField("protoId27", None), - ByteField("lenProto27", None), - ByteField("proto27Content", None), - - ByteField("protoId28", None), - ByteField("lenProto28", None), - ByteField("proto28Content", None), - - ByteField("protoId29", None), - ByteField("lenProto29", None), - ByteField("proto29Content", None), - - ByteField("protoId30", None), - ByteField("lenProto30", None), - ByteField("proto30Content", None), - - ByteField("protoId31", None), - ByteField("lenProto31", None), - ByteField("proto31Content", None), - - ByteField("protoId32", None), - ByteField("lenProto32", None), - ByteField("proto32Content", None), - - ByteField("protoId33", None), - ByteField("lenProto33", None), - ByteField("proto33Content", None), - - ByteField("protoId34", None), - ByteField("lenProto34", None), - ByteField("proto34Content", None), - - ByteField("protoId35", None), - ByteField("lenProto35", None), - ByteField("proto35Content", None), - - ByteField("protoId36", None), - ByteField("lenProto36", None), - ByteField("proto36Content", None), - - ByteField("protoId37", None), - ByteField("lenProto37", None), - ByteField("proto37Content", None), - - ByteField("protoId38", None), - ByteField("lenProto38", None), - ByteField("proto38Content", None), - - ByteField("protoId39", None), - ByteField("lenProto39", None), - ByteField("proto39Content", None), - - ByteField("protoId40", None), - ByteField("lenProto40", None), - ByteField("proto40Content", None), - - ByteField("protoId41", None), - ByteField("lenProto41", None), - ByteField("proto41Content", None), - - ByteField("protoId42", None), - ByteField("lenProto42", None), - ByteField("proto42Content", None), - - ByteField("protoId43", None), - ByteField("lenProto43", None), - ByteField("proto43Content", None), - - ByteField("protoId44", None), - ByteField("lenProto44", None), - ByteField("proto44Content", None), - - ByteField("protoId45", None), - ByteField("lenProto45", None), - ByteField("proto45Content", None), - - ByteField("protoId46", None), - ByteField("lenProto46", None), - ByteField("proto46Content", None), - - ByteField("protoId47", None), - ByteField("lenProto47", None), - ByteField("proto47Content", None), - - ByteField("protoId48", None), - ByteField("lenProto48", None), - ByteField("proto48Content", None), - - ByteField("protoId49", None), - ByteField("lenProto49", None), - ByteField("proto49Content", None), - - ByteField("protoId50", None), - ByteField("lenProto50", None), - ByteField("proto50Content", None), - - ByteField("protoId51", None), - ByteField("lenProto51", None), - ByteField("proto51Content", None), - - ByteField("protoId52", None), - ByteField("lenProto52", None), - ByteField("proto52Content", None), - - ByteField("protoId53", None), - ByteField("lenProto53", None), - ByteField("proto53Content", None), - - ByteField("protoId54", None), - ByteField("lenProto54", None), - ByteField("proto54Content", None), - - ByteField("protoId55", None), - ByteField("lenProto55", None), - ByteField("proto55Content", None), - - ByteField("protoId56", None), - ByteField("lenProto56", None), - ByteField("proto56Content", None), - - ByteField("protoId57", None), - ByteField("lenProto57", None), - ByteField("proto57Content", None), - - ByteField("protoId58", None), - ByteField("lenProto58", None), - ByteField("proto58Content", None), - - ByteField("protoId59", None), - ByteField("lenProto59", None), - ByteField("proto59Content", None), - - ByteField("protoId60", None), - ByteField("lenProto60", None), - ByteField("proto60Content", None), - - ByteField("protoId61", None), - ByteField("lenProto61", None), - ByteField("proto61Content", None), - - ByteField("protoId62", None), - ByteField("lenProto62", None), - ByteField("proto62Content", None), - - ByteField("protoId63", None), - ByteField("lenProto63", None), - ByteField("proto63Content", None), - - ByteField("protoId64", None), - ByteField("lenProto64", None), - ByteField("proto64Content", None), - - ByteField("protoId65", None), - ByteField("lenProto65", None), - ByteField("proto65Content", None), - - ByteField("protoId66", None), - ByteField("lenProto66", None), - ByteField("proto66Content", None), - - ByteField("protoId67", None), - ByteField("lenProto67", None), - ByteField("proto67Content", None), - - ByteField("protoId68", None), - ByteField("lenProto68", None), - ByteField("proto68Content", None), - - ByteField("protoId69", None), - ByteField("lenProto69", None), - ByteField("proto69Content", None), - - ByteField("protoId70", None), - ByteField("lenProto70", None), - ByteField("proto70Content", None), - - ByteField("protoId71", None), - ByteField("lenProto71", None), - ByteField("proto71Content", None), - - ByteField("protoId72", None), - ByteField("lenProto72", None), - ByteField("proto72Content", None), - - ByteField("protoId73", None), - ByteField("lenProto73", None), - ByteField("proto73Content", None), - - ByteField("protoId74", None), - ByteField("lenProto74", None), - ByteField("proto74Content", None), - - ByteField("protoId75", None), - ByteField("lenProto75", None), - ByteField("proto75Content", None), - - ByteField("protoId76", None), - ByteField("lenProto76", None), - ByteField("proto76Content", None), - - ByteField("protoId77", None), - ByteField("lenProto77", None), - ByteField("proto77Content", None), - - ByteField("protoId78", None), - ByteField("lenProto78", None), - ByteField("proto78Content", None), - - ByteField("protoId79", None), - ByteField("lenProto79", None), - ByteField("proto79Content", None), - - ByteField("protoId80", None), - ByteField("lenProto80", None), - ByteField("proto80Content", None), - - ByteField("protoId81", None), - ByteField("lenProto81", None), - ByteField("proto81Content", None), - - ByteField("protoId82", None), - ByteField("lenProto82", None), - ByteField("proto82Content", None), - - ByteField("protoId83", None), - ByteField("lenProto83", None), - ByteField("proto83Content", None), - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 253, a, self.fields_desc) - if self.lengthPCO is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# len 4 to 20 -class PacketDataProtocolAddress(Packet): - """Packet data protocol address Section 10.5.6.4""" - name = "Packet Data Protocol Address" - fields_desc = [ - ByteField("ieiPDPA", 0x0), - - XByteField("lengthPDPA", None), - - BitField("spare", 0x0, 4), - BitField("pdpTypeOrga", 0x0, 4), - - ByteField("pdpTypeNb", 0x0), - # optional - ByteField("addressInfo1", None), - ByteField("addressInfo2", None), - ByteField("addressInfo3", None), - ByteField("addressInfo4", None), - ByteField("addressInfo5", None), - ByteField("addressInfo6", None), - ByteField("addressInfo7", None), - ByteField("addressInfo8", None), - ByteField("addressInfo9", None), - ByteField("addressInfo10", None), - ByteField("addressInfo11", None), - ByteField("addressInfo12", None), - ByteField("addressInfo13", None), - ByteField("addressInfo14", None), - ByteField("addressInfo15", None), - ByteField("addressInfo16", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(4, 20, a, self.fields_desc) - if self.lengthPDPA is None: - p = p[:1] + struct.pack(">B", res[1]) + p[2:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class QualityOfService(Packet): - """Quality of service Section 10.5.6.5""" - name = "Quality of Service" - fields_desc = [ - ByteField("ieiQOS", 0x0), - XByteField("lengthQOS", 0x5), - - BitField("spare", 0x0, 2), - BitField("delayClass", 0x0, 3), - BitField("reliaClass", 0x0, 3), - - BitField("peak", 0x0, 4), - BitField("spare", 0x0, 1), - BitField("precedenceCl", 0x0, 3), - - BitField("spare", 0x0, 3), - BitField("mean", 0x0, 5) - ] - - -class SmCause(Packet): - """SM cause Section 10.5.6.6""" - name = "SM Cause" - fields_desc = [ - ByteField("ieiSC", 0x0), - ByteField("causeVal", 0x0) - ] - -# 10.5.6.7 Spare -# This is intentionally left spare. - - -class AaDeactivationCause(Packet): - """AA deactivation cause Section 10.5.6.8""" - name = "AA Deactivation Cause" - fields_desc = [ - XBitField("ieiADC", 0x0, 4), - BitField("spare", 0x0, 1), - BitField("aaVal", 0x0, 3) - ] - - -# Fix 1/2 len problem -class AaDeactivationCauseAndSpareHalfOctets(Packet): - name = "AA Deactivation Cause and Spare Half Octets" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("aaVal", 0x0, 3), - BitField("spareHalfOctets", 0x0, 4) - ] - - -class LlcServiceAccessPointIdentifier(Packet): - """LLC service access point identifier Section 10.5.6.9""" - name = "LLC Service Access Point Identifier" - fields_desc = [ - ByteField("ieiLSAPI", None), - BitField("spare", 0x0, 4), - BitField("llcVal", 0x0, 4) - ] - - -# -# 10.5.7 GPRS Common information elements -# - -# 10.5.7.1 [Spare] - -class RadioPriority(Packet): - """Radio priority Section 10.5.7.2""" - name = "Radio Priority" - fields_desc = [ - XBitField("ieiRP", 0x0, 4), - BitField("spare", 0x1, 1), - BitField("rplv", 0x0, 3) - ] - - -# Fix 1/2 len problem -class RadioPriorityAndSpareHalfOctets(Packet): - name = "Radio Priority and Spare Half Octets" - fields_desc = [ - BitField("spare", 0x1, 1), - BitField("rplv", 0x0, 3), - BitField("spareHalfOctets", 0x0, 4) - ] - - -class GprsTimer(Packet): - """GPRS Timer Section 10.5.7.3""" - name = "GPRS Timer" - fields_desc = [ - ByteField("ieiGT", 0x0), - BitField("unit", 0x0, 3), - BitField("timerVal", 0x0, 5) - ] - - -class CellIdentity(Packet): - """ Cell identity Section 10.5.1.1 """ - name = "Cell Identity" - fields_desc = [ - ByteField("ciValue1", 0x0), - ByteField("ciValue2", 0x0) - ] - - -class CiphKeySeqNr(Packet): - """ Ciphering Key Sequence Number Section 10.5.1.2 """ - name = "Cipher Key Sequence Number" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("keySeq", 0x0, 3) - ] - - -class LocalAreaId(Packet): - """ Local Area Identification Section 10.5.1.3 """ - name = "Location Area Identification" - fields_desc = [ - BitField("mccDigit2", 0x0, 4), - BitField("mccDigit1", 0x0, 4), - BitField("mncDigit3", 0x0, 4), - BitField("mccDigit3", 0x0, 4), - BitField("mncDigit2", 0x0, 4), - BitField("mncDigit1", 0x0, 4), - ByteField("lac1", 0x0), - ByteField("lac2", 0x0) - ] -# -# The Mobile Identity is a type 4 information element with a minimum -# length of 3 octet and 11 octets length maximal. -# - - -# len 3 - 11 -class MobileId(Packet): - """ Mobile Identity Section 10.5.1.4 """ - name = "Mobile Identity" - fields_desc = [ - XByteField("lengthMI", None), - BitField("idDigit1", 0x0, 4), - BitField("oddEven", 0x0, 1), - BitField("typeOfId", 0x0, 3), - - BitField("idDigit2_1", None, 4), # optional - BitField("idDigit2", None, 4), - BitField("idDigit3_1", None, 4), - BitField("idDigit3", None, 4), - BitField("idDigit4_1", None, 4), - BitField("idDigit4", None, 4), - BitField("idDigit5_1", None, 4), - BitField("idDigit5", None, 4), - BitField("idDigit6_1", None, 4), - BitField("idDigit6", None, 4), - BitField("idDigit7_1", None, 4), - BitField("idDigit7", None, 4), - BitField("idDigit8_1", None, 4), - BitField("idDigit8", None, 4), - BitField("idDigit9_1", None, 4), - BitField("idDigit9", None, 4), - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 10, a, self.fields_desc, 1) - if self.lengthMI is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class MobileStationClassmark1(Packet): - """ Mobile Station Classmark 1 Section 10.5.1.5 """ - name = "Mobile Station Classmark 1" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("revisionLvl", 0x0, 2), - BitField("esInd", 0x0, 1), - BitField("a51", 0x0, 1), - BitField("rfPowerCap", 0x0, 3) - ] - - -class MobileStationClassmark2(Packet): - """ Mobile Station Classmark 2 Section 10.5.1.6 """ - name = "Mobile Station Classmark 2" - fields_desc = [ - XByteField("lengthMSC2", 0x3), - BitField("spare", 0x0, 1), - BitField("revisionLvl", 0x0, 2), - BitField("esInd", 0x0, 1), - BitField("a51", 0x0, 1), - BitField("rfPowerCap", 0x0, 3), - BitField("spare1", 0x0, 1), - BitField("psCap", 0x0, 1), - BitField("ssScreenInd", 0x0, 2), - BitField("smCaPabi", 0x0, 1), - BitField("vbs", 0x0, 1), - BitField("vgcs", 0x0, 1), - BitField("fc", 0x0, 1), - BitField("cm3", 0x0, 1), - BitField("spare2", 0x0, 1), - BitField("lcsvaCap", 0x0, 1), - BitField("spare3", 0x0, 1), - BitField("soLsa", 0x0, 1), - BitField("cmsp", 0x0, 1), - BitField("a53", 0x0, 1), - BitField("a52", 0x0, 1) - ] - - -class DescriptiveGroupOrBroadcastCallReference(Packet): - """ Descriptive group or broadcast call reference Section 10.5.1.9 """ - name = "Descriptive Group or Broadcast Call Reference" - fields_desc = [ - BitField("binCallRef", 0x0, 27), - BitField("sf", 0x0, 1), - BitField("fa", 0x0, 1), - BitField("callPrio", 0x0, 3), - BitField("cipherInfo", 0x0, 4), - BitField("spare1", 0x0, 1), - BitField("spare2", 0x0, 1), - BitField("spare3", 0x0, 1), - BitField("spare4", 0x0, 1) - ] - - -class PdAndSapi(Packet): - """ PD and SAPI $(CCBS)$ Section 10.5.1.10a """ - name = "PD and SAPI $(CCBS)$" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("sapi", 0x0, 2), - BitField("pd", 0x0, 4) - ] - - -class PriorityLevel(Packet): - """ Priority Level Section 10.5.1.11 """ - name = "Priority Level" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("callPrio", 0x0, 3) - ] - -# -# Radio Resource management information elements -# - - -# len 6 to max for L3 message (251) -class BaRange(Packet): - """ BA Range Section 10.5.2.1a """ - name = "BA Range" - fields_desc = [ - - XByteField("lengthBR", None), -#error: byte format requires -128 <= number <= 127 - ByteField("nrOfRanges", 0x0), -# # rX = range X -# # L o = Lower H i = higher -# # H p = high Part Lp = low Part - ByteField("r1LoHp", 0x0), - - BitField("r1LoLp", 0x0, 3), - BitField("r1HiHp", 0x0, 5), - - BitField("r1HiLp", 0x0, 4), - BitField("r2LoHp", 0x0, 4), - # optional - BitField("r2LoLp", None, 5), - BitField("r2HiHp", None, 3), - - ByteField("r2HiLp", None), - ByteField("r3LoHp", None), - - BitField("r3LoLp", None, 5), - BitField("r3HiHp", None, 3), - - ByteField("r3HiLp", None), - ByteField("r4LoHp", None), - - BitField("r4LoLp", None, 5), - BitField("r4HiHp", None, 3), - ByteField("r4HiLp", None), - ByteField("r5LoHp", None), - - BitField("r5LoLp", None, 5), - BitField("r5HiHp", None, 3), - ByteField("r5HiLp", None), - ByteField("r6LoHp", None), - - BitField("r6LoLp", None, 5), - BitField("r6HiHp", None, 3), - ByteField("r6HiLp", None), - ByteField("r7LoHp", None), - - BitField("r7LoLp", None, 5), - BitField("r7HiHp", None, 3), - ByteField("r7HiLp", None), - ByteField("r8LoHp", None), - - BitField("r8LoLp", None, 5), - BitField("r8HiHp", None, 3), - ByteField("r8HiLp", None), - ByteField("r9LoHp", None), - - BitField("r9LoLp", None, 5), - BitField("r9HiHp", None, 3), - ByteField("r9HiLp", None), - ByteField("r10LoHp", None), - - BitField("r10LoLp", None, 5), - BitField("r10HiHp", None, 3), - ByteField("r10HiLp", None), - ByteField("r11LoHp", None), - - BitField("r11LoLp", None, 5), - BitField("r11HiHp", None, 3), - ByteField("r11HiLp", None), - ByteField("r12LoHp", None), - - BitField("r12LoLp", None, 5), - BitField("r12HiHp", None, 3), - ByteField("r12HiLp", None), - ByteField("r13LoHp", None), - - BitField("r13LoLp", None, 5), - BitField("r13HiHp", None, 3), - ByteField("r13HiLp", None), - ByteField("r14LoHp", None), - - BitField("r14LoLp", None, 5), - BitField("r14HiHp", None, 3), - ByteField("r14HiLp", None), - ByteField("r15LoHp", None), - - BitField("r15LoLp", None, 5), - BitField("r15HiHp", None, 3), - ByteField("r15HiLp", None), - ByteField("r16LoHp", None), - - BitField("r16LoLp", None, 5), - BitField("r16HiHp", None, 3), - ByteField("r16HiLp", None), - ByteField("r17LoHp", None), - - BitField("r17LoLp", None, 5), - BitField("r17HiHp", None, 3), - ByteField("r17HiLp", None), - ByteField("r18LoHp", None), - - BitField("r18LoLp", None, 5), - BitField("r18HiHp", None, 3), - ByteField("r18HiLp", None), - ByteField("r19LoHp", None), - - BitField("r19LoLp", None, 5), - BitField("r19HiHp", None, 3), - ByteField("r19HiLp", None), - ByteField("r20LoHp", None), - - BitField("r20LoLp", None, 5), - BitField("r20HiHp", None, 3), - ByteField("r20HiLp", None), - ByteField("r21LoHp", None), - - BitField("r21LoLp", None, 5), - BitField("r21HiHp", None, 3), - ByteField("r21HiLp", None), - ByteField("r22LoHp", None), - - BitField("r22LoLp", None, 5), - BitField("r22HiHp", None, 3), - ByteField("r22HiLp", None), - ByteField("r23LoHp", None), - - BitField("r23LoLp", None, 5), - BitField("r23HiHp", None, 3), - ByteField("r23HiLp", None), - ByteField("r24LoHp", None), - - BitField("r24LoLp", None, 5), - BitField("r24HiHp", None, 3), - ByteField("r24HiLp", None), - ByteField("r25LoHp", None), - - BitField("r25LoLp", None, 5), - BitField("r25HiHp", None, 3), - ByteField("r25HiLp", None), - ByteField("r26LoHp", None), - - BitField("r26LoLp", None, 5), - BitField("r26HiHp", None, 3), - ByteField("r26HiLp", None), - ByteField("r27LoHp", None), - - BitField("r27LoLp", None, 5), - BitField("r27HiHp", None, 3), - ByteField("r27HiLp", None), - ByteField("r28LoHp", None), - - BitField("r28LoLp", None, 5), - BitField("r28HiHp", None, 3), - ByteField("r28HiLp", None), - ByteField("r29LoHp", None), - - BitField("r29LoLp", None, 5), - BitField("r29HiHp", None, 3), - ByteField("r29HiLp", None), - ByteField("r30LoHp", None), - - BitField("r30LoLp", None, 5), - BitField("r30HiHp", None, 3), - ByteField("r30HiLp", None), - ByteField("r31LoHp", None), - - BitField("r31LoLp", None, 5), - BitField("r31HiHp", None, 3), - ByteField("r31HiLp", None), - ByteField("r32LoHp", None), - - BitField("r32LoLp", None, 5), - BitField("r32HiHp", None, 3), - ByteField("r32HiLp", None), - ByteField("r33LoHp", None), - - BitField("r33LoLp", None, 5), - BitField("r33HiHp", None, 3), - ByteField("r33HiLp", None), - ByteField("r34LoHp", None), - - BitField("r34LoLp", None, 5), - BitField("r34HiHp", None, 3), - ByteField("r34HiLp", None), - ByteField("r35LoHp", None), - - BitField("r35LoLp", None, 5), - BitField("r35HiHp", None, 3), - ByteField("r35HiLp", None), - ByteField("r36LoHp", None), - - BitField("r36LoLp", None, 5), - BitField("r36HiHp", None, 3), - ByteField("r36HiLp", None), - ByteField("r37LoHp", None), - - BitField("r37LoLp", None, 5), - BitField("r37HiHp", None, 3), - ByteField("r37HiLp", None), - ByteField("r38LoHp", None), - - BitField("r38LoLp", None, 5), - BitField("r38HiHp", None, 3), - ByteField("r38HiLp", None), - ByteField("r39LoHp", None), - - BitField("r39LoLp", None, 5), - BitField("r39HiHp", None, 3), - ByteField("r39HiLp", None), - ByteField("r40LoHp", None), - - BitField("r40LoLp", None, 5), - BitField("r40HiHp", None, 3), - ByteField("r40HiLp", None), - ByteField("r41LoHp", None), - - BitField("r41LoLp", None, 5), - BitField("r41HiHp", None, 3), - ByteField("r41HiLp", None), - ByteField("r42LoHp", None), - - BitField("r42LoLp", None, 5), - BitField("r42HiHp", None, 3), - ByteField("r42HiLp", None), - ByteField("r43LoHp", None), - - BitField("r43LoLp", None, 5), - BitField("r43HiHp", None, 3), - ByteField("r43HiLp", None), - ByteField("r44LoHp", None), - - BitField("r44LoLp", None, 5), - BitField("r44HiHp", None, 3), - ByteField("r44HiLp", None), - ByteField("r45LoHp", None), - - BitField("r45LoLp", None, 5), - BitField("r45HiHp", None, 3), - ByteField("r45HiLp", None), - ByteField("r46LoHp", None), - - BitField("r46LoLp", None, 5), - BitField("r46HiHp", None, 3), - ByteField("r46HiLp", None), - ByteField("r47LoHp", None), - - BitField("r47LoLp", None, 5), - BitField("r47HiHp", None, 3), - ByteField("r47HiLp", None), - ByteField("r48LoHp", None), - - BitField("r48LoLp", None, 5), - BitField("r48HiHp", None, 3), - ByteField("r48HiLp", None), - ByteField("r49LoHp", None), - - BitField("r49LoLp", None, 5), - BitField("r49HiHp", None, 3), - ByteField("r49HiLp", None), - ByteField("r50LoHp", None), - - BitField("r50LoLp", None, 5), - BitField("r50HiHp", None, 3), - ByteField("r50HiLp", None), - ByteField("r51LoHp", None), - - BitField("r51LoLp", None, 5), - BitField("r51HiHp", None, 3), - ByteField("r51HiLp", None), - ByteField("r52LoHp", None), - - BitField("r52LoLp", None, 5), - BitField("r52HiHp", None, 3), - ByteField("r52HiLp", None), - ByteField("r53LoHp", None), - - BitField("r53LoLp", None, 5), - BitField("r53HiHp", None, 3), - ByteField("r53HiLp", None), - ByteField("r54LoHp", None), - - BitField("r54LoLp", None, 5), - BitField("r54HiHp", None, 3), - ByteField("r54HiLp", None), - ByteField("r55LoHp", None), - - BitField("r55LoLp", None, 5), - BitField("r55HiHp", None, 3), - ByteField("r55HiLp", None), - ByteField("r56LoHp", None), - - BitField("r56LoLp", None, 5), - BitField("r56HiHp", None, 3), - ByteField("r56HiLp", None), - ByteField("r57LoHp", None), - - BitField("r57LoLp", None, 5), - BitField("r57HiHp", None, 3), - ByteField("r57HiLp", None), - ByteField("r58LoHp", None), - - BitField("r58LoLp", None, 5), - BitField("r58HiHp", None, 3), - ByteField("r58HiLp", None), - ByteField("r59LoHp", None), - - BitField("r59LoLp", None, 5), - BitField("r59HiHp", None, 3), - ByteField("r59HiLp", None), - ByteField("r60LoHp", None), - - BitField("r60LoLp", None, 5), - BitField("r60HiHp", None, 3), - ByteField("r60HiLp", None), - ByteField("r61LoHp", None), - - BitField("r61LoLp", None, 5), - BitField("r61HiHp", None, 3), - ByteField("r61HiLp", None), - ByteField("r62LoHp", None), - - BitField("r62LoLp", None, 5), - BitField("r62HiHp", None, 3), - ByteField("r62HiLp", None), - ByteField("r63LoHp", None), - - BitField("r63LoLp", None, 5), - BitField("r63HiHp", None, 3), - ByteField("r63HiLp", None), - ByteField("r64LoHp", None), - - BitField("r64LoLp", None, 5), - BitField("r64HiHp", None, 3), - ByteField("r64HiLp", None), - ByteField("r65LoHp", None), - - BitField("r65LoLp", None, 5), - BitField("r65HiHp", None, 3), - ByteField("r65HiLp", None), - ByteField("r66LoHp", None), - - BitField("r66LoLp", None, 5), - BitField("r66HiHp", None, 3), - ByteField("r66HiLp", None), - ByteField("r67LoHp", None), - - BitField("r67LoLp", None, 5), - BitField("r67HiHp", None, 3), - ByteField("r67HiLp", None), - ByteField("r68LoHp", None), - - BitField("r68LoLp", None, 5), - BitField("r68HiHp", None, 3), - ByteField("r68HiLp", None), - ByteField("r69LoHp", None), - - BitField("r69LoLp", None, 5), - BitField("r69HiHp", None, 3), - ByteField("r69HiLp", None), - ByteField("r70LoHp", None), - - BitField("r70LoLp", None, 5), - BitField("r70HiHp", None, 3), - ByteField("r70HiLp", None), - ByteField("r71LoHp", None), - - BitField("r71LoLp", None, 5), - BitField("r71HiHp", None, 3), - ByteField("r71HiLp", None), - ByteField("r72LoHp", None), - - BitField("r72LoLp", None, 5), - BitField("r72HiHp", None, 3), - ByteField("r72HiLp", None), - ByteField("r73LoHp", None), - - BitField("r73LoLp", None, 5), - BitField("r73HiHp", None, 3), - ByteField("r73HiLp", None), - ByteField("r74LoHp", None), - - BitField("r74LoLp", None, 5), - BitField("r74HiHp", None, 3), - ByteField("r74HiLp", None), - ByteField("r75LoHp", None), - - BitField("r75LoLp", None, 5), - BitField("r75HiHp", None, 3), - ByteField("r75HiLp", None), - ByteField("r76LoHp", None), - - BitField("r76LoLp", None, 5), - BitField("r76HiHp", None, 3), - ByteField("r76HiLp", None), - ByteField("r77LoHp", None), - - BitField("r77LoLp", None, 5), - BitField("r77HiHp", None, 3), - ByteField("r77HiLp", None), - ByteField("r78LoHp", None), - - BitField("r78LoLp", None, 5), - BitField("r78HiHp", None, 3), - ByteField("r78HiLp", None), - ByteField("r79LoHp", None), - - BitField("r79LoLp", None, 5), - BitField("r79HiHp", None, 3), - ByteField("r79HiLp", None), - ByteField("r80LoHp", None), - - BitField("r80LoLp", None, 5), - BitField("r80HiHp", None, 3), - ByteField("r80HiLp", None), - ByteField("r81LoHp", None), - - BitField("r81LoLp", None, 5), - BitField("r81HiHp", None, 3), - ByteField("r81HiLp", None), - ByteField("r82LoHp", None), - - BitField("r82LoLp", None, 5), - BitField("r82HiHp", None, 3), - ByteField("r82HiLp", None), - ByteField("r83LoHp", None), - - BitField("r83LoLp", None, 5), - BitField("r83HiHp", None, 3), - ByteField("r83HiLp", None), - ByteField("r84LoHp", None), - - BitField("r84LoLp", None, 5), - BitField("r84HiHp", None, 3), - ByteField("r84HiLp", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(5, 253, a, self.fields_desc, 1) - if self.lengthBR is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# len 3 to max for L3 message (251) -class BaListPref(Packet): - """ BA List Pref Section 10.5.2.1c """ - name = "BA List Pref" - fields_desc = [ - XByteField("lengthBLP", None), - - BitField("fixBit", 0x0, 1), - BitField("rangeLower", 0x0, 10), - BitField("fixBit2", 0x0, 1), - BitField("rangeUpper", 0x0, 10), - BitField("baFreq", 0x0, 10), - BitField("sparePad", 0x0, 8) - ] - - -# len 17 || Have a look at the specs for the field format -# Bit map 0 format -# Range 1024 format -# Range 512 format -# Range 256 format -# Range 128 format -# Variable bit map format -class CellChannelDescription(Packet): - """ Cell Channel Description Section 10.5.2.1b """ - name = "Cell Channel Description " - fields_desc = [ - BitField("bit128", 0x0, 1), - BitField("bit127", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("spare2", 0x0, 1), - BitField("bit124", 0x0, 1), - BitField("bit123", 0x0, 1), - BitField("bit122", 0x0, 1), - BitField("bit121", 0x0, 1), - ByteField("bit120", 0x0), - ByteField("bit112", 0x0), - ByteField("bit104", 0x0), - ByteField("bit96", 0x0), - ByteField("bit88", 0x0), - ByteField("bit80", 0x0), - ByteField("bit72", 0x0), - ByteField("bit64", 0x0), - ByteField("bit56", 0x0), - ByteField("bit48", 0x0), - ByteField("bit40", 0x0), - ByteField("bit32", 0x0), - ByteField("bit24", 0x0), - ByteField("bit16", 0x0), - ByteField("bit8", 0x0) - ] - - -class CellDescription(Packet): - """ Cell Description Section 10.5.2.2 """ - name = "Cell Description" - fields_desc = [ - BitField("bcchHigh", 0x0, 2), - BitField("ncc", 0x0, 3), - BitField("bcc", 0x0, 3), - ByteField("bcchLow", 0x0) - ] - - -class CellOptionsBCCH(Packet): - """ Cell Options (BCCH) Section 10.5.2.3 """ - name = "Cell Options (BCCH)" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("pwrc", 0x0, 1), - BitField("dtx", 0x0, 2), - BitField("rLinkTout", 0x0, 4) - ] - - -class CellOptionsSACCH(Packet): - """ Cell Options (SACCH) Section 10.5.2.3a """ - name = "Cell Options (SACCH)" - fields_desc = [ - BitField("dtx", 0x0, 1), - BitField("pwrc", 0x0, 1), - BitField("dtx", 0x0, 1), - BitField("rLinkTout", 0x0, 4) - ] - - -class CellSelectionParameters(Packet): - """ Cell Selection Parameters Section 10.5.2.4 """ - name = "Cell Selection Parameters" - fields_desc = [ - BitField("cellReselect", 0x0, 3), - BitField("msTxPwrMax", 0x0, 5), - BitField("acs", None, 1), - BitField("neci", None, 1), - BitField("rxlenAccMin", None, 6) - ] - - -class MacModeAndChannelCodingRequest(Packet): - """ MAC Mode and Channel Coding Requested Section 10.5.2.4a """ - name = "MAC Mode and Channel Coding Requested" - fields_desc = [ - BitField("macMode", 0x0, 2), - BitField("cs", 0x0, 2) - ] - - -class ChannelDescription(Packet): - """ Channel Description Section 10.5.2.5 """ - name = "Channel Description" - fields_desc = [ - - BitField("channelTyp", 0x0, 5), - BitField("tn", 0x0, 3), - - BitField("tsc", 0x0, 3), - BitField("h", 0x1, 1), - BitField("maioHi", 0x0, 4), - - BitField("maioLo", 0x0, 2), - BitField("hsn", 0x0, 6) - ] - - -class ChannelDescription2(Packet): - """ Channel Description 2 Section 10.5.2.5a """ - name = "Channel Description 2" - fields_desc = [ - BitField("channelTyp", 0x0, 5), - BitField("tn", 0x0, 3), - BitField("tsc", 0x0, 3), - BitField("h", 0x0, 1), - # if h=1 - # BitField("maioHi", 0x0, 4), - # BitField("maioLo", 0x0, 2), - # BitField("hsn", 0x0, 6) - BitField("spare", 0x0, 2), - BitField("arfcnHigh", 0x0, 2), - ByteField("arfcnLow", 0x0) - ] - - -class ChannelMode(Packet): - """ Channel Mode Section 10.5.2.6 """ - name = "Channel Mode" - fields_desc = [ - ByteField("mode", 0x0) - ] - - -class ChannelMode2(Packet): - """ Channel Mode 2 Section 10.5.2.7 """ - name = "Channel Mode 2" - fields_desc = [ - ByteField("mode", 0x0) - ] - - -class ChannelNeeded(Packet): - """ Channel Needed Section 10.5.2.8 """ - name = "Channel Needed" - fields_desc = [ - BitField("channel2", 0x0, 2), - BitField("channel1", 0x0, 2), - ] - - -class ChannelRequestDescription(Packet): - """Channel Request Description Section 10.5.2.8a """ - name = "Channel Request Description" - fields_desc = [ - BitField("mt", 0x0, 1), - ConditionalField(BitField("spare", 0x0, 39), - lambda pkt: pkt.mt == 0), - ConditionalField(BitField("spare", 0x0, 3), - lambda pkt: pkt.mt == 1), - ConditionalField(BitField("priority", 0x0, 2), - lambda pkt: pkt.mt == 1), - ConditionalField(BitField("rlcMode", 0x0, 1), - lambda pkt: pkt.mt == 1), - ConditionalField(BitField("llcFrame", 0x1, 1), - lambda pkt: pkt.mt == 1), - ConditionalField(ByteField("reqBandMsb", 0x0), - lambda pkt: pkt.mt == 1), - ConditionalField(ByteField("reqBandLsb", 0x0), - lambda pkt: pkt.mt == 1), - ConditionalField(ByteField("rlcMsb", 0x0), - lambda pkt: pkt.mt == 1), - ConditionalField(ByteField("rlcLsb", 0x0), - lambda pkt: pkt.mt == 1) - ] - - -class CipherModeSetting(Packet): - """Cipher Mode Setting Section 10.5.2.9 """ - name = "Cipher Mode Setting" - fields_desc = [ - BitField("algoId", 0x0, 3), - BitField("sc", 0x0, 1), - ] - - -class CipherResponse(Packet): - """Cipher Response Section 10.5.2.10 """ - name = "Cipher Response" - fields_desc = [ - BitField("spare", 0x0, 3), - BitField("cr", 0x0, 1), - ] - - -class ControlChannelDescription(Packet): - """Control Channel Description Section 10.5.2.11 """ - name = "Control Channel Description" - fields_desc = [ - - BitField("spare", 0x0, 1), - BitField("att", 0x0, 1), - BitField("bsAgBlksRes", 0x0, 3), - BitField("ccchConf", 0x0, 3), - - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("spare2", 0x0, 1), - BitField("spare3", 0x0, 1), - BitField("spare4", 0x0, 1), - BitField("bsPaMfrms", 0x0, 3), - - ByteField("t3212", 0x0) - ] - - -class FrequencyChannelSequence(Packet): - """Frequency Channel Sequence Section 10.5.2.12""" - name = "Frequency Channel Sequence" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("lowestArfcn", 0x0, 7), - BitField("skipArfcn01", 0x0, 4), - BitField("skipArfcn02", 0x0, 4), - BitField("skipArfcn03", 0x0, 4), - BitField("skipArfcn04", 0x0, 4), - BitField("skipArfcn05", 0x0, 4), - BitField("skipArfcn06", 0x0, 4), - BitField("skipArfcn07", 0x0, 4), - BitField("skipArfcn08", 0x0, 4), - BitField("skipArfcn09", 0x0, 4), - BitField("skipArfcn10", 0x0, 4), - BitField("skipArfcn11", 0x0, 4), - BitField("skipArfcn12", 0x0, 4), - BitField("skipArfcn13", 0x0, 4), - BitField("skipArfcn14", 0x0, 4), - BitField("skipArfcn15", 0x0, 4), - BitField("skipArfcn16", 0x0, 4) - ] - - -class FrequencyList(Packet): - """Frequency List Section 10.5.2.13""" - name = "Frequency List" - # Problem: - # There are several formats for the Frequency List information - # element, distinguished by the "format indicator" subfield. - # Some formats are frequency bit maps, the others use a special encoding - # scheme. - fields_desc = [ - XByteField("lengthFL", None), - - BitField("formatID", 0x0, 2), - BitField("spare", 0x0, 2), - BitField("arfcn124", 0x0, 1), - BitField("arfcn123", 0x0, 1), - BitField("arfcn122", 0x0, 1), - BitField("arfcn121", 0x0, 1), - - ByteField("arfcn120", 0x0), - ByteField("arfcn112", 0x0), - ByteField("arfcn104", 0x0), - ByteField("arfcn96", 0x0), - ByteField("arfcn88", 0x0), - ByteField("arfcn80", 0x0), - ByteField("arfcn72", 0x0), - ByteField("arfcn64", 0x0), - ByteField("arfcn56", 0x0), - ByteField("arfcn48", 0x0), - ByteField("arfcn40", 0x0), - ByteField("arfcn32", 0x0), - ByteField("arfcn24", 0x0), - ByteField("arfcn16", 0x0), - ByteField("arfcn8", 0x0) - ] - - -# len 4 to 13 -class GroupChannelDescription(Packet): - """Group Channel Description Section 10.5.2.14b""" - name = "Group Channel Description" - fields_desc = [ - XByteField("lengthGCD", None), - - BitField("channelType", 0x0, 5), - BitField("tn", 0x0, 3), - - BitField("tsc", 0x0, 3), - BitField("h", 0x0, 1), - # if h == 0 the packet looks the following way: - ConditionalField(BitField("spare", 0x0, 2), - lambda pkt: pkt. h == 0x0), - ConditionalField(BitField("arfcnHi", 0x0, 2), - lambda pkt: pkt. h == 0x0), - ConditionalField(ByteField("arfcnLo", None), - lambda pkt: pkt. h == 0x0), - # if h == 1 the packet looks the following way: - ConditionalField(BitField("maioHi", 0x0, 4), - lambda pkt: pkt. h == 0x1), - ConditionalField(BitField("maioLo", None, 2), - lambda pkt: pkt. h == 0x1), - ConditionalField(BitField("hsn", None, 6), - lambda pkt: pkt. h == 0x1), - # finished with conditional fields - ByteField("maC6", None), - ByteField("maC7", None), - ByteField("maC8", None), - ByteField("maC9", None), - ByteField("maC10", None), - ByteField("maC11", None), - ByteField("maC12", None), - ByteField("maC13", None), - ByteField("maC14", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(4, 13, a, self.fields_desc, 1) - if self.lengthGCD is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class GprsResumption(Packet): - """GPRS Resumption Section 10.5.2.14c""" - name = "GPRS Resumption" - fields_desc = [ - BitField("spare", 0x0, 3), - BitField("ack", 0x0, 1) - ] - - -class HandoverReference(Packet): - """Handover Reference Section 10.5.2.15""" - name = "Handover Reference" - fields_desc = [ - ByteField("handoverRef", 0x0) - ] - - -class IraRestOctets(Packet): - """IAR Rest Octets Section 10.5.2.17""" - name = "IAR Rest Octets" - fields_desc = [ - BitField("spare01", 0x0, 1), - BitField("spare02", 0x0, 1), - BitField("spare03", 0x1, 1), - BitField("spare04", 0x0, 1), - BitField("spare05", 0x1, 1), - BitField("spare06", 0x0, 1), - BitField("spare07", 0x1, 1), - BitField("spare08", 0x1, 1), - BitField("spare09", 0x0, 1), - BitField("spare10", 0x0, 1), - BitField("spare11", 0x1, 1), - BitField("spare12", 0x0, 1), - BitField("spare13", 0x1, 1), - BitField("spare14", 0x0, 1), - BitField("spare15", 0x1, 1), - BitField("spare16", 0x1, 1), - BitField("spare17", 0x0, 1), - BitField("spare18", 0x0, 1), - BitField("spare19", 0x1, 1), - BitField("spare20", 0x0, 1), - BitField("spare21", 0x1, 1), - BitField("spare22", 0x0, 1), - BitField("spare23", 0x1, 1), - BitField("spare24", 0x1, 1) - ] - - -# len is 1 to 5 what do we do with the variable size? no lenght -# field?! WTF -class IaxRestOctets(Packet): - """IAX Rest Octets Section 10.5.2.18""" - name = "IAX Rest Octets" - fields_desc = [ - BitField("spare01", 0x0, 1), - BitField("spare02", 0x0, 1), - BitField("spare03", 0x1, 1), - BitField("spare04", 0x0, 1), - BitField("spare05", 0x1, 1), - BitField("spare06", 0x0, 1), - BitField("spare07", 0x1, 1), - BitField("spare08", 0x1, 1), - ByteField("spareB1", None), - ByteField("spareB2", None), - ByteField("spareB3", None) - ] - - -class L2PseudoLength(Packet): - """L2 Pseudo Length Section 10.5.2.19""" - name = "L2 Pseudo Length" - fields_desc = [ - BitField("l2pLength", None, 6), - BitField("bit2", 0x0, 1), - BitField("bit1", 0x1, 1) - ] - - -class MeasurementResults(Packet): - """Measurement Results Section 10.5.2.20""" - name = "Measurement Results" - fields_desc = [ - BitField("baUsed", 0x0, 1), - BitField("dtxUsed", 0x0, 1), - BitField("rxLevFull", 0x0, 6), - - BitField("spare", 0x0, 1), - BitField("measValid", 0x0, 1), - BitField("rxLevSub", 0x0, 6), - - BitField("spare0", 0x0, 1), - BitField("rxqualFull", 0x0, 3), - BitField("rxqualSub", 0x0, 3), - BitField("noNcellHi", 0x0, 1), - - BitField("noNcellLo", 0x0, 2), - BitField("rxlevC1", 0x0, 6), - - BitField("bcchC1", 0x0, 5), - BitField("bsicC1Hi", 0x0, 3), - - BitField("bsicC1Lo", 0x0, 3), - BitField("rxlevC2", 0x0, 5), - - BitField("rxlevC2Lo", 0x0, 1), - BitField("bcchC2", 0x0, 5), - BitField("bsicC2Hi", 0x0, 2), - - BitField("bscicC2Lo", 0x0, 4), - BitField("bscicC2Hi", 0x0, 4), - - BitField("rxlevC3Lo", 0x0, 2), - BitField("bcchC3", 0x0, 5), - BitField("rxlevC3Hi", 0x0, 1), - - BitField("bsicC3Lo", 0x0, 5), - BitField("bsicC3Hi", 0x0, 3), - - BitField("rxlevC4Lo", 0x0, 3), - BitField("bcchC4", 0x0, 5), - - BitField("bsicC4", 0x0, 6), - BitField("rxlevC5Hi", 0x0, 2), - - BitField("rxlevC5Lo", 0x0, 4), - BitField("bcchC5Hi", 0x0, 4), - - BitField("bcchC5Lo", 0x0, 1), - BitField("bsicC5", 0x0, 6), - BitField("rxlevC6", 0x0, 1), - - BitField("rxlevC6Lo", 0x0, 5), - BitField("bcchC6Hi", 0x0, 3), - - BitField("bcchC6Lo", 0x0, 3), - BitField("bsicC6", 0x0, 5) - ] - - -class GprsMeasurementResults(Packet): - """GPRS Measurement Results Section 10.5.2.20a""" - name = "GPRS Measurement Results" - fields_desc = [ - BitField("cValue", 0x0, 6), - BitField("rxqualHi", 0x0, 2), - BitField("rxqL", 0x0, 1), - BitField("spare", 0x0, 1), - BitField("signVar", 0x0, 6) - ] - - -# len 3 to 10 -class MobileAllocation(Packet): - """Mobile Allocation Section 10.5.2.21""" - name = "Mobile Allocation" - fields_desc = [ - XByteField("lengthMA", None), - ByteField("maC64", 0x12), - ByteField("maC56", None), # optional fields start here - ByteField("maC48", None), - ByteField("maC40", None), - ByteField("maC32", None), - ByteField("maC24", None), - ByteField("maC16", None), - ByteField("maC8", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 9, a, self.fields_desc, 1) - if self.lengthMA is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class MobileTimeDifference(Packet): - """Mobile Time Difference Section 10.5.2.21a""" - name = "Mobile Time Difference" - fields_desc = [ - XByteField("lengthMTD", 0x5), - ByteField("valueHi", 0x0), - ByteField("valueCnt", 0x0), - BitField("valueLow", 0x0, 5), - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("spare2", 0x0, 1) - ] - - -# min 4 octets max 8 -class MultiRateConfiguration(Packet): - """ MultiRate configuration Section 10.5.2.21aa""" - name = "MultiRate Configuration" - # This packet has a variable length and hence structure. This packet - # implements the longuest possible packet. If you biuild a shorter - # packet, for example having only 6 bytes, the last 4 bytes are named - # "Spare" in the specs. Here they are named "threshold2" - fields_desc = [ - XByteField("lengthMRC", None), - - BitField("mrVersion", 0x0, 3), - BitField("spare", 0x0, 1), - BitField("icmi", 0x0, 1), - BitField("spare", 0x0, 1), - BitField("startMode", 0x0, 2), - - ByteField("amrCodec", None), - - BitField("spare", None, 2), - BitField("threshold1", None, 6), - - BitField("hysteresis1", None, 4), - BitField("threshold2", None, 4), - - BitField("threshold2cnt", None, 2), - BitField("hysteresis2", None, 4), - BitField("threshold3", None, 2), - - BitField("threshold3cnt", None, 4), - BitField("hysteresis3", None, 4) - ] - - def post_build(self, p, pay): - # we set the length - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(3, 7, a, self.fields_desc, 1) - if self.lengthMRC is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# len 2 to 11 -class MultislotAllocation(Packet): - """Multislot Allocation Section 10.5.2.21b""" - name = "Multislot Allocation" - fields_desc = [ - XByteField("lengthMSA", None), - BitField("ext0", 0x1, 1), - BitField("da", 0x0, 7), - ConditionalField(BitField("ext1", 0x1, 1), # optional - lambda pkt: pkt.ext0 == 0), - ConditionalField(BitField("ua", 0x0, 7), - lambda pkt: pkt.ext0 == 0), - ByteField("chan1", None), - ByteField("chan2", None), - ByteField("chan3", None), - ByteField("chan4", None), - ByteField("chan5", None), - ByteField("chan6", None), - ByteField("chan7", None), - ByteField("chan8", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(1, 11, a, self.fields_desc, 1) - if res[0] is not 0: - p = p[:-res[0]] - if self.lengthMSA is None: - p = struct.pack(">B", len(p)-1) + p[1:] - return p + pay - - -class NcMode(Packet): - """NC mode Section 10.5.2.21c""" - name = "NC Mode" - fields_desc = [ - BitField("spare", 0x0, 2), - BitField("ncMode", 0x0, 2) - ] - - -class NeighbourCellsDescription(Packet): - """Neighbour Cells Description Section 10.5.2.22""" - name = "Neighbour Cells Description" - fields_desc = [ - BitField("bit128", 0x0, 1), - BitField("bit127", 0x0, 1), - BitField("extInd", 0x0, 1), - BitField("baInd", 0x0, 1), - BitField("bit124", 0x0, 1), - BitField("bit123", 0x0, 1), - BitField("bit122", 0x0, 1), - BitField("bit121", 0x0, 1), - BitField("120bits", 0x0, 120) - ] - - -class NeighbourCellsDescription2(Packet): - """Neighbour Cells Description 2 Section 10.5.2.22a""" - name = "Neighbour Cells Description 2" - fields_desc = [ - BitField("bit128", 0x0, 1), - BitField("multiband", 0x0, 2), - BitField("baInd", 0x0, 1), - BitField("bit124", 0x0, 1), - BitField("bit123", 0x0, 1), - BitField("bit122", 0x0, 1), - BitField("bit121", 0x0, 1), - BitField("120bits", 0x0, 120) - ] - - -# len 4 -# strange packet, lots of valid formats - -# ideas for the dynamic packets: -# 1] for user interaction: Create an interactive "builder" based on a -# Q/A process (not very scapy like) -# 2] for usage in scripts, create an alternative packet for every -# possible packet layout -# - -class DedicatedModeOrTBF(Packet): - """Dedicated mode or TBF Section 10.5.2.25b""" - name = "Dedicated Mode or TBF" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("tma", 0x0, 1), - BitField("downlink", 0x0, 1), - BitField("td", 0x0, 1) - ] - - -class PageMode(Packet): - """Page Mode Section 10.5.2.26""" - name = "Page Mode" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("pm", 0x0, 2) - ] - - -class NccPermitted(Packet): - """NCC Permitted Section 10.5.2.27""" - name = "NCC Permited" - fields_desc = [ - ByteField("nccPerm", 0x0) - ] - - -class PowerCommand(Packet): - """Power Command Section 10.5.2.28""" - name = "Power Command" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("spare2", 0x0, 1), - BitField("powerLvl", 0x0, 5) - ] - - -class PowerCommandAndAccessType(Packet): - """Power Command and access type Section 10.5.2.28a""" - name = "Power Command and Access Type" - fields_desc = [ - BitField("atc", 0x0, 1), - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("powerLvl", 0x0, 5) - ] - - -class RachControlParameters(Packet): - """RACH Control Parameters Section 10.5.2.29""" - name = "RACH Control Parameters" - fields_desc = [ - BitField("maxRetrans", 0x0, 2), - BitField("txInteger", 0x0, 4), - BitField("cellBarrAccess", 0x0, 1), - BitField("re", 0x0, 1), - BitField("ACC15", 0x0, 1), - BitField("ACC14", 0x0, 1), - BitField("ACC13", 0x0, 1), - BitField("ACC12", 0x0, 1), - BitField("ACC11", 0x0, 1), - BitField("ACC10", 0x0, 1), - BitField("ACC09", 0x0, 1), - BitField("ACC08", 0x0, 1), - BitField("ACC07", 0x0, 1), - BitField("ACC06", 0x0, 1), - BitField("ACC05", 0x0, 1), - BitField("ACC04", 0x0, 1), - BitField("ACC03", 0x0, 1), - BitField("ACC02", 0x0, 1), - BitField("ACC01", 0x0, 1), - BitField("ACC00", 0x0, 1), - ] - - -class RequestReference(Packet): - """Request Reference Section 10.5.2.30""" - name = "Request Reference" - fields_desc = [ - ByteField("ra", 0x0), - BitField("t1", 0x0, 5), - BitField("t3Hi", 0x0, 3), - BitField("t3Lo", 0x0, 3), - BitField("t2", 0x0, 5) - ] - - -class RrCause(Packet): - """RR Cause Section 10.5.2.31""" - name = "RR Cause" - fields_desc = [ - ByteField("rrCause", 0x0) - ] - - -class StartingTime(Packet): - """Starting Time Section 10.5.2.38""" - name = "Starting Time" - fields_desc = [ - ByteField("ra", 0x0), - BitField("t1", 0x0, 5), - BitField("t3Hi", 0x0, 3), - BitField("t3Lo", 0x0, 3), - BitField("t2", 0x0, 5) - ] - - -class SynchronizationIndication(Packet): - """Synchronization Indication Section 10.5.2.39""" - name = "Synchronization Indication" - fields_desc = [ - BitField("nci", 0x0, 1), - BitField("rot", 0x0, 1), - BitField("si", 0x0, 2) - ] - - -class TimingAdvance(Packet): - """Timing Advance Section 10.5.2.40""" - name = "Timing Advance" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1), - BitField("timingVal", 0x0, 6) - ] - - -class TimeDifference(Packet): - """ Time Difference Section 10.5.2.41""" - name = "Time Difference" - fields_desc = [ - XByteField("lengthTD", 0x3), - ByteField("timeValue", 0x0) - ] - - -class Tlli(Packet): - """ TLLI Section Section 10.5.2.41a""" - name = "TLLI" - fields_desc = [ - ByteField("value", 0x0), - ByteField("value1", 0x0), - ByteField("value2", 0x0), - ByteField("value3", 0x0) - ] - - -class TmsiPTmsi(Packet): - """ TMSI/P-TMSI Section 10.5.2.42""" - name = "TMSI/P-TMSI" - fields_desc = [ - ByteField("value", 0x0), - ByteField("value1", 0x0), - ByteField("value2", 0x0), - ByteField("value3", 0x0) - ] - - -class VgcsTargetModeIdentication(Packet): - """ VGCS target Mode Indication 10.5.2.42a""" - name = "VGCS Target Mode Indication" - fields_desc = [ - XByteField("lengthVTMI", 0x2), - BitField("targerMode", 0x0, 2), - BitField("cipherKeyNb", 0x0, 4), - BitField("spare", 0x0, 1), - BitField("spare1", 0x0, 1) - ] - - -class WaitIndication(Packet): - """ Wait Indication Section 10.5.2.43""" - name = "Wait Indication" - fields_desc = [ # asciiart of specs strange - ByteField("timeoutVal", 0x0) - ] - - -#class Si10RestOctets(Packet): -# """SI10 rest octets 10.5.2.44""" -# name = "SI10 rest octets" -# fields_desc = [ - - -# len 17 -class ExtendedMeasurementResults(Packet): - """EXTENDED MEASUREMENT RESULTS Section 10.5.2.45""" - name = "Extended Measurement Results" - fields_desc = [ - - BitField("scUsed", None, 1), - BitField("dtxUsed", None, 1), - BitField("rxLevC0", None, 6), - - BitField("rxLevC1", None, 6), - BitField("rxLevC2Hi", None, 2), - - BitField("rxLevC2Lo", None, 4), - BitField("rxLevC3Hi", None, 4), - - BitField("rxLevC3Lo", None, 3), - BitField("rxLevC4", None, 5), - - BitField("rxLevC5", None, 6), - BitField("rxLevC6Hi", None, 2), - - BitField("rxLevC6Lo", None, 4), - BitField("rxLevC7Hi", None, 4), - - BitField("rxLevC7Lo", None, 2), - BitField("rxLevC8", None, 6), - - BitField("rxLevC9", None, 6), - BitField("rxLevC10Hi", None, 2), - - BitField("rxLevC10Lo", None, 4), - BitField("rxLevC11Hi", None, 4), - - BitField("rxLevC13Lo", None, 2), - BitField("rxLevC12", None, 6), - - BitField("rxLevC13", None, 6), - BitField("rxLevC14Hi", None, 2), - - BitField("rxLevC14Lo", None, 4), - BitField("rxLevC15Hi", None, 4), - - BitField("rxLevC15Lo", None, 2), - BitField("rxLevC16", None, 6), - - - BitField("rxLevC17", None, 6), - BitField("rxLevC18Hi", None, 2), - - BitField("rxLevC18Lo", None, 4), - BitField("rxLevC19Hi", None, 4), - - BitField("rxLevC19Lo", None, 2), - BitField("rxLevC20", None, 6) - ] - - -# len 17 -class ExtendedMeasurementFrequencyList(Packet): - """Extended Measurement Frequency List Section 10.5.2.46""" - name = "Extended Measurement Frequency List" - fields_desc = [ - - BitField("bit128", 0x0, 1), - BitField("bit127", 0x0, 1), - BitField("spare", 0x0, 1), - BitField("seqCode", 0x0, 1), - BitField("bit124", 0x0, 1), - BitField("bit123", 0x0, 1), - BitField("bit122", 0x0, 1), - BitField("bit121", 0x0, 1), - - BitField("bitsRest", 0x0, 128) - ] - - -class SuspensionCause(Packet): - """Suspension Cause Section 10.5.2.47""" - name = "Suspension Cause" - fields_desc = [ - ByteField("suspVal", 0x0) - ] - - -class ApduID(Packet): - """APDU Flags Section 10.5.2.48""" - name = "Apdu Id" - fields_desc = [ - BitField("id", None, 4) - ] - - -class ApduFlags(Packet): - """APDU Flags Section 10.5.2.49""" - name = "Apdu Flags" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("cr", 0x0, 1), - BitField("firstSeg", 0x0, 1), - BitField("lastSeg", 0x0, 1) - ] - - -# len 1 to max L3 (251) (done) -class ApduData(Packet): - """APDU Data Section 10.5.2.50""" - name = "Apdu Data" - fields_desc = [ - XByteField("lengthAD", None), - #optional - ByteField("apuInfo1", None), - ByteField("apuInfo2", None), - ByteField("apuInfo3", None), - ByteField("apuInfo4", None), - ByteField("apuInfo5", None), - ByteField("apuInfo6", None), - ByteField("apuInfo7", None), - ByteField("apuInfo8", None), - ByteField("apuInfo9", None), - ByteField("apuInfo10", None), - ByteField("apuInfo11", None), - ByteField("apuInfo12", None), - ByteField("apuInfo13", None), - ByteField("apuInfo14", None), - ByteField("apuInfo15", None), - ByteField("apuInfo16", None), - ByteField("apuInfo17", None), - ByteField("apuInfo18", None), - ByteField("apuInfo19", None), - ByteField("apuInfo20", None), - ByteField("apuInfo21", None), - ByteField("apuInfo22", None), - ByteField("apuInfo23", None), - ByteField("apuInfo24", None), - ByteField("apuInfo25", None), - ByteField("apuInfo26", None), - ByteField("apuInfo27", None), - ByteField("apuInfo28", None), - ByteField("apuInfo29", None), - ByteField("apuInfo30", None), - ByteField("apuInfo31", None), - ByteField("apuInfo32", None), - ByteField("apuInfo33", None), - ByteField("apuInfo34", None), - ByteField("apuInfo35", None), - ByteField("apuInfo36", None), - ByteField("apuInfo37", None), - ByteField("apuInfo38", None), - ByteField("apuInfo39", None), - ByteField("apuInfo40", None), - ByteField("apuInfo41", None), - ByteField("apuInfo42", None), - ByteField("apuInfo43", None), - ByteField("apuInfo44", None), - ByteField("apuInfo45", None), - ByteField("apuInfo46", None), - ByteField("apuInfo47", None), - ByteField("apuInfo48", None), - ByteField("apuInfo49", None), - ByteField("apuInfo50", None), - ByteField("apuInfo51", None), - ByteField("apuInfo52", None), - ByteField("apuInfo53", None), - ByteField("apuInfo54", None), - ByteField("apuInfo55", None), - ByteField("apuInfo56", None), - ByteField("apuInfo57", None), - ByteField("apuInfo58", None), - ByteField("apuInfo59", None), - ByteField("apuInfo60", None), - ByteField("apuInfo61", None), - ByteField("apuInfo62", None), - ByteField("apuInfo63", None), - ByteField("apuInfo64", None), - ByteField("apuInfo65", None), - ByteField("apuInfo66", None), - ByteField("apuInfo67", None), - ByteField("apuInfo68", None), - ByteField("apuInfo69", None), - ByteField("apuInfo70", None), - ByteField("apuInfo71", None), - ByteField("apuInfo72", None), - ByteField("apuInfo73", None), - ByteField("apuInfo74", None), - ByteField("apuInfo75", None), - ByteField("apuInfo76", None), - ByteField("apuInfo77", None), - ByteField("apuInfo78", None), - ByteField("apuInfo79", None), - ByteField("apuInfo80", None), - ByteField("apuInfo81", None), - ByteField("apuInfo82", None), - ByteField("apuInfo83", None), - ByteField("apuInfo84", None), - ByteField("apuInfo85", None), - ByteField("apuInfo86", None), - ByteField("apuInfo87", None), - ByteField("apuInfo88", None), - ByteField("apuInfo89", None), - ByteField("apuInfo90", None), - ByteField("apuInfo91", None), - ByteField("apuInfo92", None), - ByteField("apuInfo93", None), - ByteField("apuInfo94", None), - ByteField("apuInfo95", None), - ByteField("apuInfo96", None), - ByteField("apuInfo97", None), - ByteField("apuInfo98", None), - ByteField("apuInfo99", None), - ByteField("apuInfo100", None), - ByteField("apuInfo101", None), - ByteField("apuInfo102", None), - ByteField("apuInfo103", None), - ByteField("apuInfo104", None), - ByteField("apuInfo105", None), - ByteField("apuInfo106", None), - ByteField("apuInfo107", None), - ByteField("apuInfo108", None), - ByteField("apuInfo109", None), - ByteField("apuInfo110", None), - ByteField("apuInfo111", None), - ByteField("apuInfo112", None), - ByteField("apuInfo113", None), - ByteField("apuInfo114", None), - ByteField("apuInfo115", None), - ByteField("apuInfo116", None), - ByteField("apuInfo117", None), - ByteField("apuInfo118", None), - ByteField("apuInfo119", None), - ByteField("apuInfo120", None), - ByteField("apuInfo121", None), - ByteField("apuInfo122", None), - ByteField("apuInfo123", None), - ByteField("apuInfo124", None), - ByteField("apuInfo125", None), - ByteField("apuInfo126", None), - ByteField("apuInfo127", None), - ByteField("apuInfo128", None), - ByteField("apuInfo129", None), - ByteField("apuInfo130", None), - ByteField("apuInfo131", None), - ByteField("apuInfo132", None), - ByteField("apuInfo133", None), - ByteField("apuInfo134", None), - ByteField("apuInfo135", None), - ByteField("apuInfo136", None), - ByteField("apuInfo137", None), - ByteField("apuInfo138", None), - ByteField("apuInfo139", None), - ByteField("apuInfo140", None), - ByteField("apuInfo141", None), - ByteField("apuInfo142", None), - ByteField("apuInfo143", None), - ByteField("apuInfo144", None), - ByteField("apuInfo145", None), - ByteField("apuInfo146", None), - ByteField("apuInfo147", None), - ByteField("apuInfo148", None), - ByteField("apuInfo149", None), - ByteField("apuInfo150", None), - ByteField("apuInfo151", None), - ByteField("apuInfo152", None), - ByteField("apuInfo153", None), - ByteField("apuInfo154", None), - ByteField("apuInfo155", None), - ByteField("apuInfo156", None), - ByteField("apuInfo157", None), - ByteField("apuInfo158", None), - ByteField("apuInfo159", None), - ByteField("apuInfo160", None), - ByteField("apuInfo161", None), - ByteField("apuInfo162", None), - ByteField("apuInfo163", None), - ByteField("apuInfo164", None), - ByteField("apuInfo165", None), - ByteField("apuInfo166", None), - ByteField("apuInfo167", None), - ByteField("apuInfo168", None), - ByteField("apuInfo169", None), - ByteField("apuInfo170", None), - ByteField("apuInfo171", None), - ByteField("apuInfo172", None), - ByteField("apuInfo173", None), - ByteField("apuInfo174", None), - ByteField("apuInfo175", None), - ByteField("apuInfo176", None), - ByteField("apuInfo177", None), - ByteField("apuInfo178", None), - ByteField("apuInfo179", None), - ByteField("apuInfo180", None), - ByteField("apuInfo181", None), - ByteField("apuInfo182", None), - ByteField("apuInfo183", None), - ByteField("apuInfo184", None), - ByteField("apuInfo185", None), - ByteField("apuInfo186", None), - ByteField("apuInfo187", None), - ByteField("apuInfo188", None), - ByteField("apuInfo189", None), - ByteField("apuInfo190", None), - ByteField("apuInfo191", None), - ByteField("apuInfo192", None), - ByteField("apuInfo193", None), - ByteField("apuInfo194", None), - ByteField("apuInfo195", None), - ByteField("apuInfo196", None), - ByteField("apuInfo197", None), - ByteField("apuInfo198", None), - ByteField("apuInfo199", None), - ByteField("apuInfo200", None), - ByteField("apuInfo201", None), - ByteField("apuInfo202", None), - ByteField("apuInfo203", None), - ByteField("apuInfo204", None), - ByteField("apuInfo205", None), - ByteField("apuInfo206", None), - ByteField("apuInfo207", None), - ByteField("apuInfo208", None), - ByteField("apuInfo209", None), - ByteField("apuInfo210", None), - ByteField("apuInfo211", None), - ByteField("apuInfo212", None), - ByteField("apuInfo213", None), - ByteField("apuInfo214", None), - ByteField("apuInfo215", None), - ByteField("apuInfo216", None), - ByteField("apuInfo217", None), - ByteField("apuInfo218", None), - ByteField("apuInfo219", None), - ByteField("apuInfo220", None), - ByteField("apuInfo221", None), - ByteField("apuInfo222", None), - ByteField("apuInfo223", None), - ByteField("apuInfo224", None), - ByteField("apuInfo225", None), - ByteField("apuInfo226", None), - ByteField("apuInfo227", None), - ByteField("apuInfo228", None), - ByteField("apuInfo229", None), - ByteField("apuInfo230", None), - ByteField("apuInfo231", None), - ByteField("apuInfo232", None), - ByteField("apuInfo233", None), - ByteField("apuInfo234", None), - ByteField("apuInfo235", None), - ByteField("apuInfo236", None), - ByteField("apuInfo237", None), - ByteField("apuInfo238", None), - ByteField("apuInfo239", None), - ByteField("apuInfo240", None), - ByteField("apuInfo241", None), - ByteField("apuInfo242", None), - ByteField("apuInfo243", None), - ByteField("apuInfo244", None), - ByteField("apuInfo245", None), - ByteField("apuInfo246", None), - ByteField("apuInfo247", None), - ByteField("apuInfo248", None), - ByteField("apuInfo249", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(1, 250, a, self.fields_desc, 1) - if self.lengthAD is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay -# -# 10.5.3 Mobility management information elements -# - - -# len 3 to L3 max (251) (done) -class NetworkName(Packet): - """Network Name Section 10.5.3.5a""" - name = "Network Name" - fields_desc = [ - - XByteField("lengthNN", None), - - BitField("ext", 0x1, 1), - BitField("codingScheme", 0x0, 3), - BitField("addCi", 0x0, 1), - BitField("nbSpare", 0x0, 3), - # optional - ByteField("txtString1", None), - ByteField("txtString2", None), - ByteField("txtString3", None), - ByteField("txtString4", None), - ByteField("txtString5", None), - ByteField("txtString6", None), - ByteField("txtString7", None), - ByteField("txtString8", None), - ByteField("txtString9", None), - ByteField("txtString10", None), - ByteField("txtString11", None), - ByteField("txtString12", None), - ByteField("txtString13", None), - ByteField("txtString14", None), - ByteField("txtString15", None), - ByteField("txtString16", None), - ByteField("txtString17", None), - ByteField("txtString18", None), - ByteField("txtString19", None), - ByteField("txtString20", None), - ByteField("txtString21", None), - ByteField("txtString22", None), - ByteField("txtString23", None), - ByteField("txtString24", None), - ByteField("txtString25", None), - ByteField("txtString26", None), - ByteField("txtString27", None), - ByteField("txtString28", None), - ByteField("txtString29", None), - ByteField("txtString30", None), - ByteField("txtString31", None), - ByteField("txtString32", None), - ByteField("txtString33", None), - ByteField("txtString34", None), - ByteField("txtString35", None), - ByteField("txtString36", None), - ByteField("txtString37", None), - ByteField("txtString38", None), - ByteField("txtString39", None), - ByteField("txtString40", None), - ByteField("txtString41", None), - ByteField("txtString42", None), - ByteField("txtString43", None), - ByteField("txtString44", None), - ByteField("txtString45", None), - ByteField("txtString46", None), - ByteField("txtString47", None), - ByteField("txtString48", None), - ByteField("txtString49", None), - ByteField("txtString50", None), - ByteField("txtString51", None), - ByteField("txtString52", None), - ByteField("txtString53", None), - ByteField("txtString54", None), - ByteField("txtString55", None), - ByteField("txtString56", None), - ByteField("txtString57", None), - ByteField("txtString58", None), - ByteField("txtString59", None), - ByteField("txtString60", None), - ByteField("txtString61", None), - ByteField("txtString62", None), - ByteField("txtString63", None), - ByteField("txtString64", None), - ByteField("txtString65", None), - ByteField("txtString66", None), - ByteField("txtString67", None), - ByteField("txtString68", None), - ByteField("txtString69", None), - ByteField("txtString70", None), - ByteField("txtString71", None), - ByteField("txtString72", None), - ByteField("txtString73", None), - ByteField("txtString74", None), - ByteField("txtString75", None), - ByteField("txtString76", None), - ByteField("txtString77", None), - ByteField("txtString78", None), - ByteField("txtString79", None), - ByteField("txtString80", None), - ByteField("txtString81", None), - ByteField("txtString82", None), - ByteField("txtString83", None), - ByteField("txtString84", None), - ByteField("txtString85", None), - ByteField("txtString86", None), - ByteField("txtString87", None), - ByteField("txtString88", None), - ByteField("txtString89", None), - ByteField("txtString90", None), - ByteField("txtString91", None), - ByteField("txtString92", None), - ByteField("txtString93", None), - ByteField("txtString94", None), - ByteField("txtString95", None), - ByteField("txtString96", None), - ByteField("txtString97", None), - ByteField("txtString98", None), - ByteField("txtString99", None), - ByteField("txtString100", None), - ByteField("txtString101", None), - ByteField("txtString102", None), - ByteField("txtString103", None), - ByteField("txtString104", None), - ByteField("txtString105", None), - ByteField("txtString106", None), - ByteField("txtString107", None), - ByteField("txtString108", None), - ByteField("txtString109", None), - ByteField("txtString110", None), - ByteField("txtString111", None), - ByteField("txtString112", None), - ByteField("txtString113", None), - ByteField("txtString114", None), - ByteField("txtString115", None), - ByteField("txtString116", None), - ByteField("txtString117", None), - ByteField("txtString118", None), - ByteField("txtString119", None), - ByteField("txtString120", None), - ByteField("txtString121", None), - ByteField("txtString122", None), - ByteField("txtString123", None), - ByteField("txtString124", None), - ByteField("txtString125", None), - ByteField("txtString126", None), - ByteField("txtString127", None), - ByteField("txtString128", None), - ByteField("txtString129", None), - ByteField("txtString130", None), - ByteField("txtString131", None), - ByteField("txtString132", None), - ByteField("txtString133", None), - ByteField("txtString134", None), - ByteField("txtString135", None), - ByteField("txtString136", None), - ByteField("txtString137", None), - ByteField("txtString138", None), - ByteField("txtString139", None), - ByteField("txtString140", None), - ByteField("txtString141", None), - ByteField("txtString142", None), - ByteField("txtString143", None), - ByteField("txtString144", None), - ByteField("txtString145", None), - ByteField("txtString146", None), - ByteField("txtString147", None), - ByteField("txtString148", None), - ByteField("txtString149", None), - ByteField("txtString150", None), - ByteField("txtString151", None), - ByteField("txtString152", None), - ByteField("txtString153", None), - ByteField("txtString154", None), - ByteField("txtString155", None), - ByteField("txtString156", None), - ByteField("txtString157", None), - ByteField("txtString158", None), - ByteField("txtString159", None), - ByteField("txtString160", None), - ByteField("txtString161", None), - ByteField("txtString162", None), - ByteField("txtString163", None), - ByteField("txtString164", None), - ByteField("txtString165", None), - ByteField("txtString166", None), - ByteField("txtString167", None), - ByteField("txtString168", None), - ByteField("txtString169", None), - ByteField("txtString170", None), - ByteField("txtString171", None), - ByteField("txtString172", None), - ByteField("txtString173", None), - ByteField("txtString174", None), - ByteField("txtString175", None), - ByteField("txtString176", None), - ByteField("txtString177", None), - ByteField("txtString178", None), - ByteField("txtString179", None), - ByteField("txtString180", None), - ByteField("txtString181", None), - ByteField("txtString182", None), - ByteField("txtString183", None), - ByteField("txtString184", None), - ByteField("txtString185", None), - ByteField("txtString186", None), - ByteField("txtString187", None), - ByteField("txtString188", None), - ByteField("txtString189", None), - ByteField("txtString190", None), - ByteField("txtString191", None), - ByteField("txtString192", None), - ByteField("txtString193", None), - ByteField("txtString194", None), - ByteField("txtString195", None), - ByteField("txtString196", None), - ByteField("txtString197", None), - ByteField("txtString198", None), - ByteField("txtString199", None), - ByteField("txtString200", None), - ByteField("txtString201", None), - ByteField("txtString202", None), - ByteField("txtString203", None), - ByteField("txtString204", None), - ByteField("txtString205", None), - ByteField("txtString206", None), - ByteField("txtString207", None), - ByteField("txtString208", None), - ByteField("txtString209", None), - ByteField("txtString210", None), - ByteField("txtString211", None), - ByteField("txtString212", None), - ByteField("txtString213", None), - ByteField("txtString214", None), - ByteField("txtString215", None), - ByteField("txtString216", None), - ByteField("txtString217", None), - ByteField("txtString218", None), - ByteField("txtString219", None), - ByteField("txtString220", None), - ByteField("txtString221", None), - ByteField("txtString222", None), - ByteField("txtString223", None), - ByteField("txtString224", None), - ByteField("txtString225", None), - ByteField("txtString226", None), - ByteField("txtString227", None), - ByteField("txtString228", None), - ByteField("txtString229", None), - ByteField("txtString230", None), - ByteField("txtString231", None), - ByteField("txtString232", None), - ByteField("txtString233", None), - ByteField("txtString234", None), - ByteField("txtString235", None), - ByteField("txtString236", None), - ByteField("txtString237", None), - ByteField("txtString238", None), - ByteField("txtString239", None), - ByteField("txtString240", None), - ByteField("txtString241", None), - ByteField("txtString242", None), - ByteField("txtString243", None), - ByteField("txtString244", None), - ByteField("txtString245", None), - ByteField("txtString246", None), - ByteField("txtString247", None), - ByteField("txtString248", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 250, a, self.fields_desc, 1) - if self.lengthNN is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class TimeZone(Packet): - """Time Zone Section 10.5.3.8""" - name = "Time Zone" - fields_desc = [ - ByteField("timeZone", 0x0), - ] - - -class TimeZoneAndTime(Packet): - """Time Zone and Time Section 10.5.3.9""" - name = "Time Zone and Time" - fields_desc = [ - ByteField("year", 0x0), - ByteField("month", 0x0), - ByteField("day", 0x0), - ByteField("hour", 0x0), - ByteField("minute", 0x0), - ByteField("second", 0x0), - ByteField("timeZone", 0x0) - ] - - -class CtsPermission(Packet): - """CTS permission Section 10.5.3.10""" - name = "Cts Permission" - fields_desc = [ - ] - - -class LsaIdentifier(Packet): - """LSA Identifier Section 10.5.3.11""" - name = "Lsa Identifier" - fields_desc = [ - ByteField("lsaID", 0x0), - ByteField("lsaID1", 0x0), - ByteField("lsaID2", 0x0) - ] - - -# -# 10.5.4 Call control information elements -# - -#10.5.4.1 Extensions of codesets -# This is only text and no packet - -class LockingShiftProcedure(Packet): - """Locking shift procedure Section 10.5.4.2""" - name = "Locking Shift Procedure" - fields_desc = [ - BitField("lockShift", 0x0, 1), - BitField("codesetId", 0x0, 3) - ] - - -class NonLockingShiftProcedure(Packet): - """Non-locking shift procedure Section 10.5.4.3""" - name = "Non-locking Shift Procedure" - fields_desc = [ - BitField("nonLockShift", 0x1, 1), - BitField("codesetId", 0x0, 3) - ] - - -class AuxiliaryStates(Packet): - """Auxiliary states Section 10.5.4.4""" - name = "Auxiliary States" - fields_desc = [ - XByteField("lengthAS", 0x3), - BitField("ext", 0x1, 1), - BitField("spare", 0x0, 3), - BitField("holdState", 0x0, 2), - BitField("mptyState", 0x0, 2) - ] - - -# len 3 to 15 -class BearerCapability(Packet): - """Bearer capability Section 10.5.4.5""" - name = "Bearer Capability" - fields_desc = [ - - XByteField("lengthBC", None), - - BitField("ext0", 0x1, 1), - BitField("radioChReq", 0x1, 2), - BitField("codingStd", 0x0, 1), - BitField("transMode", 0x0, 1), - BitField("infoTransCa", 0x0, 3), - # optional - ConditionalField(BitField("ext1", 0x1, 1), - lambda pkt: pkt.ext0 == 0), - ConditionalField(BitField("coding", None, 1), - lambda pkt: pkt.ext0 == 0), - ConditionalField(BitField("spare", None, 2), - lambda pkt: pkt.ext0 == 0), - ConditionalField(BitField("speechVers", 0x0, 4), - lambda pkt: pkt.ext0 == 0), - - ConditionalField(BitField("ext2", 0x1, 1), - lambda pkt: pkt.ext1 == 0), - ConditionalField(BitField("compress", None, 1), - lambda pkt: pkt.ext1 == 0), - ConditionalField(BitField("structure", None, 2), - lambda pkt: pkt.ext1 == 0), - ConditionalField(BitField("dupMode", None, 1), - lambda pkt: pkt.ext1 == 0), - ConditionalField(BitField("config", None, 1), - lambda pkt: pkt.ext1 == 0), - ConditionalField(BitField("nirr", None, 1), - lambda pkt: pkt.ext1 == 0), - ConditionalField(BitField("establi", 0x0, 1), - lambda pkt: pkt.ext1 == 0), - - BitField("ext3", None, 1), - BitField("accessId", None, 2), - BitField("rateAda", None, 2), - BitField("signaling", None, 3), - - ConditionalField(BitField("ext4", None, 1), - lambda pkt: pkt.ext3 == 0), - ConditionalField(BitField("otherITC", None, 2), - lambda pkt: pkt.ext3 == 0), - ConditionalField(BitField("otherRate", None, 2), - lambda pkt: pkt.ext3 == 0), - ConditionalField(BitField("spare1", 0x0, 3), - lambda pkt: pkt.ext3 == 0), - - ConditionalField(BitField("ext5", 0x1, 1), - lambda pkt: pkt.ext4 == 0), - ConditionalField(BitField("hdr", None, 1), - lambda pkt: pkt.ext4 == 0), - ConditionalField(BitField("multiFr", None, 1), - lambda pkt: pkt.ext4 == 0), - ConditionalField(BitField("mode", None, 1), - lambda pkt: pkt.ext4 == 0), - ConditionalField(BitField("lli", None, 1), - lambda pkt: pkt.ext4 == 0), - ConditionalField(BitField("assig", None, 1), - lambda pkt: pkt.ext4 == 0), - ConditionalField(BitField("inbNeg", None, 1), - lambda pkt: pkt.ext4 == 0), - ConditionalField(BitField("spare2", 0x0, 1), - lambda pkt: pkt.ext4 == 0), - - BitField("ext6", None, 1), - BitField("layer1Id", None, 2), - BitField("userInf", None, 4), - BitField("sync", None, 1), - - ConditionalField(BitField("ext7", None, 1), - lambda pkt: pkt.ext6 == 0), - ConditionalField(BitField("stopBit", None, 1), - lambda pkt: pkt.ext6 == 0), - ConditionalField(BitField("negoc", None, 1), - lambda pkt: pkt.ext6 == 0), - ConditionalField(BitField("nbDataBit", None, 1), - lambda pkt: pkt.ext6 == 0), - ConditionalField(BitField("userRate", None, 4), - lambda pkt: pkt.ext6 == 0), - - ConditionalField(BitField("ext8", None, 1), - lambda pkt: pkt.ext7 == 0), - ConditionalField(BitField("interRate", None, 2), - lambda pkt: pkt.ext7 == 0), - ConditionalField(BitField("nicTX", None, 1), - lambda pkt: pkt.ext7 == 0), - ConditionalField(BitField("nicRX", None, 1), - lambda pkt: pkt.ext7 == 0), - ConditionalField(BitField("parity", None, 3), - lambda pkt: pkt.ext7 == 0), - - ConditionalField(BitField("ext9", None, 1), - lambda pkt: pkt.ext8 == 0), - ConditionalField(BitField("connEle", None, 2), - lambda pkt: pkt.ext8 == 0), - ConditionalField(BitField("modemType", None, 5), - lambda pkt: pkt.ext8 == 0), - - ConditionalField(BitField("ext10", None, 1), - lambda pkt: pkt.ext9 == 0), - ConditionalField(BitField("otherModemType", None, 2), - lambda pkt: pkt.ext9 == 0), - ConditionalField(BitField("netUserRate", None, 5), - lambda pkt: pkt.ext9 == 0), - - ConditionalField(BitField("ext11", None, 1), - lambda pkt: pkt.ext10 == 0), - ConditionalField(BitField("chanCoding", None, 4), - lambda pkt: pkt.ext10 == 0), - ConditionalField(BitField("maxTrafficChan", None, 3), - lambda pkt: pkt.ext10 == 0), - - ConditionalField(BitField("ext12", None, 1), - lambda pkt: pkt.ext11 == 0), - ConditionalField(BitField("uimi", None, 3), - lambda pkt: pkt.ext11 == 0), - ConditionalField(BitField("airInterfaceUserRate", None, 4), - lambda pkt: pkt.ext11 == 0), - - ConditionalField(BitField("ext13", 0x1, 1), - lambda pkt: pkt.ext12 == 0), - ConditionalField(BitField("layer2Ch", None, 2), - lambda pkt: pkt.ext12 == 0), - ConditionalField(BitField("userInfoL2", 0x0, 5), - lambda pkt: pkt.ext12 == 0) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 15, a, self.fields_desc, 1) - if res[0] is not 0: - p = p[:-res[0]] - if self.lengthBC is None: - p = struct.pack(">B", len(p)-1) + p[1:] - return p + pay - - -class CallControlCapabilities(Packet): - """Call Control Capabilities Section 10.5.4.5a""" - name = "Call Control Capabilities" - fields_desc = [ - XByteField("lengthCCC", 0x3), - BitField("spare", 0x0, 6), - BitField("pcp", 0x0, 1), - BitField("dtmf", 0x0, 1) - ] - - -class CallState(Packet): - """Call State Section 10.5.4.6""" - name = "Call State" - fields_desc = [ - BitField("codingStd", 0x0, 2), - BitField("stateValue", 0x0, 6) - ] - - -# len 3 to 43 -class CalledPartyBcdNumber(Packet): - """Called party BCD number Section 10.5.4.7""" - name = "Called Party BCD Number" - fields_desc = [ - XByteField("lengthCPBN", None), - BitField("ext", 0x1, 1), - BitField("typeNb", 0x0, 3), - BitField("nbPlanId", 0x0, 4), - # optional - BitField("nbDigit2", None, 4), - BitField("nbDigit1", None, 4), - BitField("nbDigit4", None, 4), - BitField("nbDigit3", None, 4), - - BitField("nbDigit6", None, 4), - BitField("nbDigit5", None, 4), - BitField("nbDigit8", None, 4), - BitField("nbDigit7", None, 4), - - BitField("nbDigit10", None, 4), - BitField("nbDigit9", None, 4), - BitField("nbDigit12", None, 4), - BitField("nbDigit11", None, 4), - - BitField("nbDigit14", None, 4), - BitField("nbDigit13", None, 4), - BitField("nbDigit16", None, 4), - BitField("nbDigit15", None, 4), - - BitField("nbDigit18", None, 4), - BitField("nbDigit17", None, 4), - BitField("nbDigit20", None, 4), - BitField("nbDigit19", None, 4), - - BitField("nbDigit22", None, 4), - BitField("nbDigit21", None, 4), - BitField("nbDigit24", None, 4), - BitField("nbDigit23", None, 4), - - BitField("nbDigit26", None, 4), - BitField("nbDigit25", None, 4), - BitField("nbDigit28", None, 4), - BitField("nbDigit27", None, 4), - - BitField("nbDigit30", None, 4), - BitField("nbDigit29", None, 4), - BitField("nbDigit32", None, 4), - BitField("nbDigit31", None, 4), - - BitField("nbDigit34", None, 4), - BitField("nbDigit33", None, 4), - BitField("nbDigit36", None, 4), - BitField("nbDigit35", None, 4), - - BitField("nbDigit38", None, 4), - BitField("nbDigit37", None, 4), - BitField("nbDigit40", None, 4), - BitField("nbDigit39", None, 4), -# ^^^^^^ 20 first optional bytes ^^^^^^^^^^^^^^^ - BitField("nbDigit42", None, 4), - BitField("nbDigit41", None, 4), - BitField("nbDigit44", None, 4), - BitField("nbDigit43", None, 4), - - BitField("nbDigit46", None, 4), - BitField("nbDigit45", None, 4), - BitField("nbDigit48", None, 4), - BitField("nbDigit47", None, 4), - - BitField("nbDigit50", None, 4), - BitField("nbDigit49", None, 4), - BitField("nbDigit52", None, 4), - BitField("nbDigit51", None, 4), - - BitField("nbDigit54", None, 4), - BitField("nbDigit53", None, 4), - BitField("nbDigit56", None, 4), - BitField("nbDigit55", None, 4), - - BitField("nbDigit58", None, 4), - BitField("nbDigit57", None, 4), - BitField("nbDigit60", None, 4), - BitField("nbDigit59", None, 4), - - BitField("nbDigit62", None, 4), - BitField("nbDigit61", None, 4), - BitField("nbDigit64", None, 4), - BitField("nbDigit63", None, 4), - - BitField("nbDigit66", None, 4), - BitField("nbDigit65", None, 4), - BitField("nbDigit68", None, 4), - BitField("nbDigit67", None, 4), - - BitField("nbDigit70", None, 4), - BitField("nbDigit69", None, 4), - BitField("nbDigit72", None, 4), - BitField("nbDigit71", None, 4), - - BitField("nbDigit74", None, 4), - BitField("nbDigit73", None, 4), - BitField("nbDigit76", None, 4), - BitField("nbDigit75", None, 4), - - BitField("nbDigit78", None, 4), - BitField("nbDigit77", None, 4), - BitField("nbDigit80", None, 4), - BitField("nbDigit79", None, 4), - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 42, a, self.fields_desc, 1) - if self.lengthCPBN is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# len 2 to 23 -class CalledPartySubaddress(Packet): - """Called party subaddress Section 10.5.4.8""" - name = "Called Party Subaddress" - fields_desc = [ - XByteField("lengthCPS", None), - # optional - BitField("ext", None, 1), - BitField("subAddr", None, 3), - BitField("oddEven", None, 1), - BitField("spare", None, 3), - - ByteField("subInfo0", None), - ByteField("subInfo1", None), - ByteField("subInfo2", None), - ByteField("subInfo3", None), - ByteField("subInfo4", None), - ByteField("subInfo5", None), - ByteField("subInfo6", None), - ByteField("subInfo7", None), - ByteField("subInfo8", None), - ByteField("subInfo9", None), - ByteField("subInfo10", None), - ByteField("subInfo11", None), - ByteField("subInfo12", None), - ByteField("subInfo13", None), - ByteField("subInfo14", None), - ByteField("subInfo15", None), - ByteField("subInfo16", None), - ByteField("subInfo17", None), - ByteField("subInfo18", None), - ByteField("subInfo19", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 23, a, self.fields_desc, 1) - if self.lengthCPS is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# len 3 to 14 -class CallingPartyBcdNumber(Packet): - """Called party subaddress Section 10.5.4.9""" - name = "Called Party Subaddress" - fields_desc = [ - XByteField("lengthCPBN", None), - BitField("ext", 0x1, 1), - BitField("typeNb", 0x0, 3), - BitField("nbPlanId", 0x0, 4), - # optional - ConditionalField(BitField("ext1", 0x1, 1), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("presId", None, 2), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("spare", None, 3), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("screenId", 0x0, 2), - lambda pkt: pkt.ext == 0), - - BitField("nbDigit2", None, 4), - BitField("nbDigit1", None, 4), - - BitField("nbDigit4", None, 4), - BitField("nbDigit3", None, 4), - - BitField("nbDigit6", None, 4), - BitField("nbDigit5", None, 4), - - BitField("nbDigit8", None, 4), - BitField("nbDigit7", None, 4), - - BitField("nbDigit10", None, 4), - BitField("nbDigit9", None, 4), - - BitField("nbDigit12", None, 4), - BitField("nbDigit11", None, 4), - - BitField("nbDigit14", None, 4), - BitField("nbDigit13", None, 4), - - BitField("nbDigit16", None, 4), - BitField("nbDigit15", None, 4), - - BitField("nbDigit18", None, 4), - BitField("nbDigit17", None, 4), - - BitField("nbDigit20", None, 4), - BitField("nbDigit19", None, 4), - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 13, a, self.fields_desc, 1) - if res[0] is not 0: - p = p[:-res[0]] - if self.lengthCPBN is None: - p = struct.pack(">B", len(p)-1) + p[1:] - return p + pay - - -# len 2 to 23 -class CallingPartySubaddress(Packet): - """Calling party subaddress Section 10.5.4.10""" - name = "Calling Party Subaddress" - fields_desc = [ - XByteField("lengthCPS", None), - # optional - BitField("ext1", None, 1), - BitField("typeAddr", None, 3), - BitField("oddEven", None, 1), - BitField("spare", None, 3), - - ByteField("subInfo0", None), - ByteField("subInfo1", None), - ByteField("subInfo2", None), - ByteField("subInfo3", None), - ByteField("subInfo4", None), - ByteField("subInfo5", None), - ByteField("subInfo6", None), - ByteField("subInfo7", None), - ByteField("subInfo8", None), - ByteField("subInfo9", None), - ByteField("subInfo10", None), - ByteField("subInfo11", None), - ByteField("subInfo12", None), - ByteField("subInfo13", None), - ByteField("subInfo14", None), - ByteField("subInfo15", None), - ByteField("subInfo16", None), - ByteField("subInfo17", None), - ByteField("subInfo18", None), - ByteField("subInfo19", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(1, 22, a, self.fields_desc, 1) - if self.lengthCPS is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# len 4 to 32 -class Cause(Packet): - """Cause Section 10.5.4.11""" - name = "Cause" - fields_desc = [ - - XByteField("lengthC", None), - - BitField("ext", 0x1, 1), - BitField("codingStd", 0x0, 2), - BitField("spare", 0x0, 1), - BitField("location", 0x0, 4), - - ConditionalField(BitField("ext1", 0x1, 1), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("recommendation", 0x1, 7), - lambda pkt: pkt.ext == 0), - # optional - BitField("ext2", None, 1), - BitField("causeValue", None, 7), - - ByteField("diagnositc0", None), - ByteField("diagnositc1", None), - ByteField("diagnositc2", None), - ByteField("diagnositc3", None), - ByteField("diagnositc4", None), - ByteField("diagnositc5", None), - ByteField("diagnositc6", None), - ByteField("diagnositc7", None), - ByteField("diagnositc8", None), - ByteField("diagnositc9", None), - ByteField("diagnositc10", None), - ByteField("diagnositc11", None), - ByteField("diagnositc12", None), - ByteField("diagnositc13", None), - ByteField("diagnositc14", None), - ByteField("diagnositc15", None), - ByteField("diagnositc16", None), - ByteField("diagnositc17", None), - ByteField("diagnositc18", None), - ByteField("diagnositc19", None), - ByteField("diagnositc20", None), - ByteField("diagnositc21", None), - ByteField("diagnositc22", None), - ByteField("diagnositc23", None), - ByteField("diagnositc24", None), - ByteField("diagnositc25", None), - ByteField("diagnositc26", None), - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(3, 31, a, self.fields_desc, 1) - if res[0] is not 0: - p = p[:-res[0]] - if self.lengthC is None: - p = struct.pack(">B", len(p)-1) + p[1:] - return p + pay - - -class ClirSuppression(Packet): - """CLIR suppression Section 10.5.4.11a""" - name = "Clir Suppression" - fields_desc = [ - ] - - -class ClirInvocation(Packet): - """CLIR invocation Section 10.5.4.11b""" - name = "Clir Invocation" - fields_desc = [ - ] - - -class CongestionLevel(Packet): - """Congestion level Section 10.5.4.12""" - name = "Congestion Level" - fields_desc = [ - BitField("notDef", 0x0, 4) # not defined by the std - ] - - -# len 3 to 14 -class ConnectedNumber(Packet): - """Connected number Section 10.5.4.13""" - name = "Connected Number" - fields_desc = [ - - XByteField("lengthCN", None), - - BitField("ext", 0x1, 1), - BitField("typeNb", 0x0, 3), - BitField("typePlanId", 0x0, 4), - # optional - ConditionalField(BitField("ext1", 0x1, 1), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("presId", None, 2), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("spare", None, 3), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("screenId", None, 2), - lambda pkt: pkt.ext == 0), - - BitField("nbDigit2", None, 4), - BitField("nbDigit1", None, 4), - - BitField("nbDigit4", None, 4), - BitField("nbDigit3", None, 4), - - BitField("nbDigit6", None, 4), - BitField("nbDigit5", None, 4), - - BitField("nbDigit8", None, 4), - BitField("nbDigit7", None, 4), - - BitField("nbDigit10", None, 4), - BitField("nbDigit9", None, 4), - - BitField("nbDigit12", None, 4), - BitField("nbDigit11", None, 4), - - BitField("nbDigit14", None, 4), - BitField("nbDigit13", None, 4), - - BitField("nbDigit16", None, 4), - BitField("nbDigit15", None, 4), - - BitField("nbDigit18", None, 4), - BitField("nbDigit17", None, 4), - - BitField("nbDigit20", None, 4), - BitField("nbDigit19", None, 4) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 13, a, self.fields_desc, 1) - if res[0] is not 0: - p = p[:-res[0]] - if self.lengthCN is None: - p = struct.pack(">B", len(p)-1) + p[1:] - return p + pay - - -# len 2 to 23 -class ConnectedSubaddress(Packet): - """Connected subaddress Section 10.5.4.14""" - name = "Connected Subaddress" - fields_desc = [ - - XByteField("lengthCS", None), - # optional - BitField("ext", None, 1), - BitField("typeOfSub", None, 3), - BitField("oddEven", None, 1), - BitField("spare", None, 3), - - ByteField("subInfo0", None), - ByteField("subInfo1", None), - ByteField("subInfo2", None), - ByteField("subInfo3", None), - ByteField("subInfo4", None), - ByteField("subInfo5", None), - ByteField("subInfo6", None), - ByteField("subInfo7", None), - ByteField("subInfo8", None), - ByteField("subInfo9", None), - ByteField("subInfo10", None), - ByteField("subInfo11", None), - ByteField("subInfo12", None), - ByteField("subInfo13", None), - ByteField("subInfo14", None), - ByteField("subInfo15", None), - ByteField("subInfo16", None), - ByteField("subInfo17", None), - ByteField("subInfo18", None), - ByteField("subInfo19", None) - ] - - def post_build(self, p, pay): - aList = [] - a = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - for i in aList: - a.append(getattr(self, i)) - res = adapt(1, 22, a, self.fields_desc, 1) - if self.lengthCS is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# len 2 to L3 (251) (done) -class Facility(Packet): - """Facility Section 10.5.4.15""" - name = "Facility" - fields_desc = [ - XByteField("lengthF", None), - # optional - ByteField("facilityInfo1", None), - ByteField("facilityInfo2", None), - ByteField("facilityInfo3", None), - ByteField("facilityInfo4", None), - ByteField("facilityInfo5", None), - ByteField("facilityInfo6", None), - ByteField("facilityInfo7", None), - ByteField("facilityInfo8", None), - ByteField("facilityInfo9", None), - ByteField("facilityInfo10", None), - ByteField("facilityInfo11", None), - ByteField("facilityInfo12", None), - ByteField("facilityInfo13", None), - ByteField("facilityInfo14", None), - ByteField("facilityInfo15", None), - ByteField("facilityInfo16", None), - ByteField("facilityInfo17", None), - ByteField("facilityInfo18", None), - ByteField("facilityInfo19", None), - ByteField("facilityInfo20", None), - ByteField("facilityInfo21", None), - ByteField("facilityInfo22", None), - ByteField("facilityInfo23", None), - ByteField("facilityInfo24", None), - ByteField("facilityInfo25", None), - ByteField("facilityInfo26", None), - ByteField("facilityInfo27", None), - ByteField("facilityInfo28", None), - ByteField("facilityInfo29", None), - ByteField("facilityInfo30", None), - ByteField("facilityInfo31", None), - ByteField("facilityInfo32", None), - ByteField("facilityInfo33", None), - ByteField("facilityInfo34", None), - ByteField("facilityInfo35", None), - ByteField("facilityInfo36", None), - ByteField("facilityInfo37", None), - ByteField("facilityInfo38", None), - ByteField("facilityInfo39", None), - ByteField("facilityInfo40", None), - ByteField("facilityInfo41", None), - ByteField("facilityInfo42", None), - ByteField("facilityInfo43", None), - ByteField("facilityInfo44", None), - ByteField("facilityInfo45", None), - ByteField("facilityInfo46", None), - ByteField("facilityInfo47", None), - ByteField("facilityInfo48", None), - ByteField("facilityInfo49", None), - ByteField("facilityInfo50", None), - ByteField("facilityInfo51", None), - ByteField("facilityInfo52", None), - ByteField("facilityInfo53", None), - ByteField("facilityInfo54", None), - ByteField("facilityInfo55", None), - ByteField("facilityInfo56", None), - ByteField("facilityInfo57", None), - ByteField("facilityInfo58", None), - ByteField("facilityInfo59", None), - ByteField("facilityInfo60", None), - ByteField("facilityInfo61", None), - ByteField("facilityInfo62", None), - ByteField("facilityInfo63", None), - ByteField("facilityInfo64", None), - ByteField("facilityInfo65", None), - ByteField("facilityInfo66", None), - ByteField("facilityInfo67", None), - ByteField("facilityInfo68", None), - ByteField("facilityInfo69", None), - ByteField("facilityInfo70", None), - ByteField("facilityInfo71", None), - ByteField("facilityInfo72", None), - ByteField("facilityInfo73", None), - ByteField("facilityInfo74", None), - ByteField("facilityInfo75", None), - ByteField("facilityInfo76", None), - ByteField("facilityInfo77", None), - ByteField("facilityInfo78", None), - ByteField("facilityInfo79", None), - ByteField("facilityInfo80", None), - ByteField("facilityInfo81", None), - ByteField("facilityInfo82", None), - ByteField("facilityInfo83", None), - ByteField("facilityInfo84", None), - ByteField("facilityInfo85", None), - ByteField("facilityInfo86", None), - ByteField("facilityInfo87", None), - ByteField("facilityInfo88", None), - ByteField("facilityInfo89", None), - ByteField("facilityInfo90", None), - ByteField("facilityInfo91", None), - ByteField("facilityInfo92", None), - ByteField("facilityInfo93", None), - ByteField("facilityInfo94", None), - ByteField("facilityInfo95", None), - ByteField("facilityInfo96", None), - ByteField("facilityInfo97", None), - ByteField("facilityInfo98", None), - ByteField("facilityInfo99", None), - ByteField("facilityInfo100", None), - ByteField("facilityInfo101", None), - ByteField("facilityInfo102", None), - ByteField("facilityInfo103", None), - ByteField("facilityInfo104", None), - ByteField("facilityInfo105", None), - ByteField("facilityInfo106", None), - ByteField("facilityInfo107", None), - ByteField("facilityInfo108", None), - ByteField("facilityInfo109", None), - ByteField("facilityInfo110", None), - ByteField("facilityInfo111", None), - ByteField("facilityInfo112", None), - ByteField("facilityInfo113", None), - ByteField("facilityInfo114", None), - ByteField("facilityInfo115", None), - ByteField("facilityInfo116", None), - ByteField("facilityInfo117", None), - ByteField("facilityInfo118", None), - ByteField("facilityInfo119", None), - ByteField("facilityInfo120", None), - ByteField("facilityInfo121", None), - ByteField("facilityInfo122", None), - ByteField("facilityInfo123", None), - ByteField("facilityInfo124", None), - ByteField("facilityInfo125", None), - ByteField("facilityInfo126", None), - ByteField("facilityInfo127", None), - ByteField("facilityInfo128", None), - ByteField("facilityInfo129", None), - ByteField("facilityInfo130", None), - ByteField("facilityInfo131", None), - ByteField("facilityInfo132", None), - ByteField("facilityInfo133", None), - ByteField("facilityInfo134", None), - ByteField("facilityInfo135", None), - ByteField("facilityInfo136", None), - ByteField("facilityInfo137", None), - ByteField("facilityInfo138", None), - ByteField("facilityInfo139", None), - ByteField("facilityInfo140", None), - ByteField("facilityInfo141", None), - ByteField("facilityInfo142", None), - ByteField("facilityInfo143", None), - ByteField("facilityInfo144", None), - ByteField("facilityInfo145", None), - ByteField("facilityInfo146", None), - ByteField("facilityInfo147", None), - ByteField("facilityInfo148", None), - ByteField("facilityInfo149", None), - ByteField("facilityInfo150", None), - ByteField("facilityInfo151", None), - ByteField("facilityInfo152", None), - ByteField("facilityInfo153", None), - ByteField("facilityInfo154", None), - ByteField("facilityInfo155", None), - ByteField("facilityInfo156", None), - ByteField("facilityInfo157", None), - ByteField("facilityInfo158", None), - ByteField("facilityInfo159", None), - ByteField("facilityInfo160", None), - ByteField("facilityInfo161", None), - ByteField("facilityInfo162", None), - ByteField("facilityInfo163", None), - ByteField("facilityInfo164", None), - ByteField("facilityInfo165", None), - ByteField("facilityInfo166", None), - ByteField("facilityInfo167", None), - ByteField("facilityInfo168", None), - ByteField("facilityInfo169", None), - ByteField("facilityInfo170", None), - ByteField("facilityInfo171", None), - ByteField("facilityInfo172", None), - ByteField("facilityInfo173", None), - ByteField("facilityInfo174", None), - ByteField("facilityInfo175", None), - ByteField("facilityInfo176", None), - ByteField("facilityInfo177", None), - ByteField("facilityInfo178", None), - ByteField("facilityInfo179", None), - ByteField("facilityInfo180", None), - ByteField("facilityInfo181", None), - ByteField("facilityInfo182", None), - ByteField("facilityInfo183", None), - ByteField("facilityInfo184", None), - ByteField("facilityInfo185", None), - ByteField("facilityInfo186", None), - ByteField("facilityInfo187", None), - ByteField("facilityInfo188", None), - ByteField("facilityInfo189", None), - ByteField("facilityInfo190", None), - ByteField("facilityInfo191", None), - ByteField("facilityInfo192", None), - ByteField("facilityInfo193", None), - ByteField("facilityInfo194", None), - ByteField("facilityInfo195", None), - ByteField("facilityInfo196", None), - ByteField("facilityInfo197", None), - ByteField("facilityInfo198", None), - ByteField("facilityInfo199", None), - ByteField("facilityInfo200", None), - ByteField("facilityInfo201", None), - ByteField("facilityInfo202", None), - ByteField("facilityInfo203", None), - ByteField("facilityInfo204", None), - ByteField("facilityInfo205", None), - ByteField("facilityInfo206", None), - ByteField("facilityInfo207", None), - ByteField("facilityInfo208", None), - ByteField("facilityInfo209", None), - ByteField("facilityInfo210", None), - ByteField("facilityInfo211", None), - ByteField("facilityInfo212", None), - ByteField("facilityInfo213", None), - ByteField("facilityInfo214", None), - ByteField("facilityInfo215", None), - ByteField("facilityInfo216", None), - ByteField("facilityInfo217", None), - ByteField("facilityInfo218", None), - ByteField("facilityInfo219", None), - ByteField("facilityInfo220", None), - ByteField("facilityInfo221", None), - ByteField("facilityInfo222", None), - ByteField("facilityInfo223", None), - ByteField("facilityInfo224", None), - ByteField("facilityInfo225", None), - ByteField("facilityInfo226", None), - ByteField("facilityInfo227", None), - ByteField("facilityInfo228", None), - ByteField("facilityInfo229", None), - ByteField("facilityInfo230", None), - ByteField("facilityInfo231", None), - ByteField("facilityInfo232", None), - ByteField("facilityInfo233", None), - ByteField("facilityInfo234", None), - ByteField("facilityInfo235", None), - ByteField("facilityInfo236", None), - ByteField("facilityInfo237", None), - ByteField("facilityInfo238", None), - ByteField("facilityInfo239", None), - ByteField("facilityInfo240", None), - ByteField("facilityInfo241", None), - ByteField("facilityInfo242", None), - ByteField("facilityInfo243", None), - ByteField("facilityInfo244", None), - ByteField("facilityInfo245", None), - ByteField("facilityInfo246", None), - ByteField("facilityInfo247", None), - ByteField("facilityInfo248", None), - ByteField("facilityInfo249", None) - ] - - def post_build(self, p, pay): - aList = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - a = [] - for i in aList: - a.append(getattr(self, i)) - res = adapt(7, 250, a, self.fields_desc, 1) - if self.lengthF is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -#len 2 to 5 -class HighLayerCompatibility(Packet): - """High layer compatibility Section 10.5.4.16""" - name = "High Layer Compatibility" - fields_desc = [ - - XByteField("lengthHLC", None), - # optional - BitField("ext", None, 1), - BitField("codingStd", None, 2), - BitField("interpret", None, 3), - BitField("presMeth", None, 2), - - BitField("ext1", None, 1), - BitField("highLayerId", None, 7), - - ConditionalField(BitField("ext2", 0x1, 1), - lambda pkt: pkt.ext1 == 0), - ConditionalField(BitField("exHiLayerId", 0x0, 7), - lambda pkt: pkt.ext1 == 0), - ] - - def post_build(self, p, pay): - aList = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - a = [] - for i in aList: - a.append(getattr(self, i)) - res = adapt(1, 4, a, self.fields_desc, 1) - if res[0] is not 0: - p = p[:-res[0]] - if self.lengthHLC is None: - p = struct.pack(">B", len(p)-1) + p[1:] - return p + pay -# -# 10.5.4.16.1 Static conditions for the high layer -# compatibility IE contents -# - - -class KeypadFacility(Packet): - """Keypad facility Section 10.5.4.17""" - name = "Keypad Facility" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("keyPadInfo", 0x0, 7) - ] - - -# len 2 to 15 -class LowLayerCompatibility(Packet): - """Low layer compatibility Section 10.5.4.18""" - name = "Low Layer Compatibility" - fields_desc = [ - - XByteField("lengthLLC", None), - # optional - ByteField("rest0", None), - ByteField("rest1", None), - ByteField("rest2", None), - ByteField("rest3", None), - ByteField("rest4", None), - ByteField("rest5", None), - ByteField("rest6", None), - ByteField("rest7", None), - ByteField("rest8", None), - ByteField("rest9", None), - ByteField("rest10", None), - ByteField("rest11", None), - ByteField("rest12", None) - ] - - def post_build(self, p, pay): - aList = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - a = [] - for i in aList: - a.append(getattr(self, i)) - res = adapt(1, 14, a, self.fields_desc, 1) - if self.lengthLLC is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class MoreData(Packet): - """More data Section 10.5.4.19""" - name = "More Data" - fields_desc = [ - ] - - -class NotificationIndicator(Packet): - """Notification indicator Section 10.5.4.20""" - name = "Notification Indicator" - fields_desc = [ - BitField("ext1", 0x1, 1), - BitField("notifDesc", 0x0, 7) - ] - - -class ProgressIndicator(Packet): - """Progress indicator Section 10.5.4.21""" - name = "Progress Indicator" - fields_desc = [ - XByteField("lengthPI", 0x2), - BitField("ext", 0x1, 1), - BitField("codingStd", 0x0, 2), - BitField("spare", 0x0, 1), - BitField("location", 0x0, 4), - BitField("ext1", 0x1, 1), - BitField("progressDesc", 0x0, 7) - ] - - -class RecallType(Packet): - """Recall type $(CCBS)$ Section 10.5.4.21a""" - name = "Recall Type $(CCBS)$" - fields_desc = [ - BitField("spare", 0x0, 5), - BitField("recallType", 0x0, 3) - ] - - -# len 3 to 19 -class RedirectingPartyBcdNumber(Packet): - """Redirecting party BCD number Section 10.5.4.21b""" - name = "Redirecting Party BCD Number" - fields_desc = [ - - XByteField("lengthRPBN", None), - - BitField("ext", 0x1, 1), - BitField("typeNb", 0x0, 3), - BitField("numberingPlan", 0x0, 4), - # optional - ConditionalField(BitField("ext1", 0x1, 1), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("presId", 0x0, 2), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("spare", 0x0, 3), - lambda pkt: pkt.ext == 0), - ConditionalField(BitField("screenId", 0x0, 2), - lambda pkt: pkt.ext == 0), - - BitField("nbDigit2", None, 4), - BitField("nbDigit1", None, 4), - - BitField("nbDigit4", None, 4), - BitField("nbDigit3", None, 4), - - BitField("nbDigit6", None, 4), - BitField("nbDigit5", None, 4), - - BitField("nbDigit8", None, 4), - BitField("nbDigit7", None, 4), - - BitField("nbDigit10", None, 4), - BitField("nbDigit9", None, 4), - - BitField("nbDigit12", None, 4), - BitField("nbDigit11", None, 4), - - BitField("nbDigit14", None, 4), - BitField("nbDigit13", None, 4), - - BitField("nbDigit16", None, 4), - BitField("nbDigit15", None, 4), - - BitField("nbDigit18", None, 4), - BitField("nbDigit17", None, 4), - - BitField("nbDigit20", None, 4), - BitField("nbDigit19", None, 4), - - BitField("nbDigit22", None, 4), - BitField("nbDigit21", None, 4), - - BitField("nbDigit24", None, 4), - BitField("nbDigit23", None, 4), - - BitField("nbDigit26", None, 4), - BitField("nbDigit25", None, 4), - - BitField("nbDigit28", None, 4), - BitField("nbDigit27", None, 4), - - BitField("nbDigit30", None, 4), - BitField("nbDigit29", None, 4), - ] - - def post_build(self, p, pay): - aList = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - a = [] - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 18, a, self.fields_desc, 1) - if res[0] is not 0: - p = p[:-res[0]] - if self.lengthRPBN is None: - p = struct.pack(">B", len(p)-1) + p[1:] - return p + pay - - -# length 2 to 23 -class RedirectingPartySubaddress(Packet): - """Redirecting party subaddress Section 10.5.4.21c""" - name = "Redirecting Party BCD Number" - fields_desc = [ - - XByteField("lengthRPS", None), - # optional - BitField("ext", None, 1), - BitField("typeSub", None, 3), - BitField("oddEven", None, 1), - BitField("spare", None, 3), - - ByteField("subInfo0", None), - ByteField("subInfo1", None), - ByteField("subInfo2", None), - ByteField("subInfo3", None), - ByteField("subInfo4", None), - ByteField("subInfo5", None), - ByteField("subInfo6", None), - ByteField("subInfo7", None), - ByteField("subInfo8", None), - ByteField("subInfo9", None), - ByteField("subInfo10", None), - ByteField("subInfo11", None), - ByteField("subInfo12", None), - ByteField("subInfo13", None), - ByteField("subInfo14", None), - ByteField("subInfo15", None), - ByteField("subInfo16", None), - ByteField("subInfo17", None), - ByteField("subInfo18", None), - ByteField("subInfo19", None) - ] - - def post_build(self, p, pay): - aList = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - a = [] - for i in aList: - a.append(getattr(self, i)) - res = adapt(1, 22, a, self.fields_desc, 1) - if self.lengthRPS is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class RepeatIndicator(Packet): - """Repeat indicator Section 10.5.4.22""" - name = "Repeat Indicator" - fields_desc = [ - BitField("repeatIndic", 0x0, 4) - ] - - -# no upper length min 2(max for L3) (251) -class SetupContainer(Packet): - """SETUP Container $(CCBS)$ Section 10.5.4.22b""" - name = "Setup Container $(CCBS)$" - fields_desc = [ - XByteField("lengthSC", None), - # optional - ByteField("mess1", None), - ByteField("mess2", None), - ByteField("mess3", None), - ByteField("mess4", None), - ByteField("mess5", None), - ByteField("mess6", None), - ByteField("mess7", None), - ByteField("mess8", None), - ByteField("mess9", None), - ByteField("mess10", None), - ByteField("mess11", None), - ByteField("mess12", None), - ByteField("mess13", None), - ByteField("mess14", None), - ByteField("mess15", None), - ByteField("mess16", None), - ByteField("mess17", None), - ByteField("mess18", None), - ByteField("mess19", None), - ByteField("mess20", None), - ByteField("mess21", None), - ByteField("mess22", None), - ByteField("mess23", None), - ByteField("mess24", None), - ByteField("mess25", None), - ByteField("mess26", None), - ByteField("mess27", None), - ByteField("mess28", None), - ByteField("mess29", None), - ByteField("mess30", None), - ByteField("mess31", None), - ByteField("mess32", None), - ByteField("mess33", None), - ByteField("mess34", None), - ByteField("mess35", None), - ByteField("mess36", None), - ByteField("mess37", None), - ByteField("mess38", None), - ByteField("mess39", None), - ByteField("mess40", None), - ByteField("mess41", None), - ByteField("mess42", None), - ByteField("mess43", None), - ByteField("mess44", None), - ByteField("mess45", None), - ByteField("mess46", None), - ByteField("mess47", None), - ByteField("mess48", None), - ByteField("mess49", None), - ByteField("mess50", None), - ByteField("mess51", None), - ByteField("mess52", None), - ByteField("mess53", None), - ByteField("mess54", None), - ByteField("mess55", None), - ByteField("mess56", None), - ByteField("mess57", None), - ByteField("mess58", None), - ByteField("mess59", None), - ByteField("mess60", None), - ByteField("mess61", None), - ByteField("mess62", None), - ByteField("mess63", None), - ByteField("mess64", None), - ByteField("mess65", None), - ByteField("mess66", None), - ByteField("mess67", None), - ByteField("mess68", None), - ByteField("mess69", None), - ByteField("mess70", None), - ByteField("mess71", None), - ByteField("mess72", None), - ByteField("mess73", None), - ByteField("mess74", None), - ByteField("mess75", None), - ByteField("mess76", None), - ByteField("mess77", None), - ByteField("mess78", None), - ByteField("mess79", None), - ByteField("mess80", None), - ByteField("mess81", None), - ByteField("mess82", None), - ByteField("mess83", None), - ByteField("mess84", None), - ByteField("mess85", None), - ByteField("mess86", None), - ByteField("mess87", None), - ByteField("mess88", None), - ByteField("mess89", None), - ByteField("mess90", None), - ByteField("mess91", None), - ByteField("mess92", None), - ByteField("mess93", None), - ByteField("mess94", None), - ByteField("mess95", None), - ByteField("mess96", None), - ByteField("mess97", None), - ByteField("mess98", None), - ByteField("mess99", None), - ByteField("mess100", None), - ByteField("mess101", None), - ByteField("mess102", None), - ByteField("mess103", None), - ByteField("mess104", None), - ByteField("mess105", None), - ByteField("mess106", None), - ByteField("mess107", None), - ByteField("mess108", None), - ByteField("mess109", None), - ByteField("mess110", None), - ByteField("mess111", None), - ByteField("mess112", None), - ByteField("mess113", None), - ByteField("mess114", None), - ByteField("mess115", None), - ByteField("mess116", None), - ByteField("mess117", None), - ByteField("mess118", None), - ByteField("mess119", None), - ByteField("mess120", None), - ByteField("mess121", None), - ByteField("mess122", None), - ByteField("mess123", None), - ByteField("mess124", None), - ByteField("mess125", None), - ByteField("mess126", None), - ByteField("mess127", None), - ByteField("mess128", None), - ByteField("mess129", None), - ByteField("mess130", None), - ByteField("mess131", None), - ByteField("mess132", None), - ByteField("mess133", None), - ByteField("mess134", None), - ByteField("mess135", None), - ByteField("mess136", None), - ByteField("mess137", None), - ByteField("mess138", None), - ByteField("mess139", None), - ByteField("mess140", None), - ByteField("mess141", None), - ByteField("mess142", None), - ByteField("mess143", None), - ByteField("mess144", None), - ByteField("mess145", None), - ByteField("mess146", None), - ByteField("mess147", None), - ByteField("mess148", None), - ByteField("mess149", None), - ByteField("mess150", None), - ByteField("mess151", None), - ByteField("mess152", None), - ByteField("mess153", None), - ByteField("mess154", None), - ByteField("mess155", None), - ByteField("mess156", None), - ByteField("mess157", None), - ByteField("mess158", None), - ByteField("mess159", None), - ByteField("mess160", None), - ByteField("mess161", None), - ByteField("mess162", None), - ByteField("mess163", None), - ByteField("mess164", None), - ByteField("mess165", None), - ByteField("mess166", None), - ByteField("mess167", None), - ByteField("mess168", None), - ByteField("mess169", None), - ByteField("mess170", None), - ByteField("mess171", None), - ByteField("mess172", None), - ByteField("mess173", None), - ByteField("mess174", None), - ByteField("mess175", None), - ByteField("mess176", None), - ByteField("mess177", None), - ByteField("mess178", None), - ByteField("mess179", None), - ByteField("mess180", None), - ByteField("mess181", None), - ByteField("mess182", None), - ByteField("mess183", None), - ByteField("mess184", None), - ByteField("mess185", None), - ByteField("mess186", None), - ByteField("mess187", None), - ByteField("mess188", None), - ByteField("mess189", None), - ByteField("mess190", None), - ByteField("mess191", None), - ByteField("mess192", None), - ByteField("mess193", None), - ByteField("mess194", None), - ByteField("mess195", None), - ByteField("mess196", None), - ByteField("mess197", None), - ByteField("mess198", None), - ByteField("mess199", None), - ByteField("mess200", None), - ByteField("mess201", None), - ByteField("mess202", None), - ByteField("mess203", None), - ByteField("mess204", None), - ByteField("mess205", None), - ByteField("mess206", None), - ByteField("mess207", None), - ByteField("mess208", None), - ByteField("mess209", None), - ByteField("mess210", None), - ByteField("mess211", None), - ByteField("mess212", None), - ByteField("mess213", None), - ByteField("mess214", None), - ByteField("mess215", None), - ByteField("mess216", None), - ByteField("mess217", None), - ByteField("mess218", None), - ByteField("mess219", None), - ByteField("mess220", None), - ByteField("mess221", None), - ByteField("mess222", None), - ByteField("mess223", None), - ByteField("mess224", None), - ByteField("mess225", None), - ByteField("mess226", None), - ByteField("mess227", None), - ByteField("mess228", None), - ByteField("mess229", None), - ByteField("mess230", None), - ByteField("mess231", None), - ByteField("mess232", None), - ByteField("mess233", None), - ByteField("mess234", None), - ByteField("mess235", None), - ByteField("mess236", None), - ByteField("mess237", None), - ByteField("mess238", None), - ByteField("mess239", None), - ByteField("mess240", None), - ByteField("mess241", None), - ByteField("mess242", None), - ByteField("mess243", None), - ByteField("mess244", None), - ByteField("mess245", None), - ByteField("mess246", None), - ByteField("mess247", None), - ByteField("mess248", None), - ByteField("mess249", None), - ] - - def post_build(self, p, pay): - aList = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - a = [] - for i in aList: - a.append(getattr(self, i)) - res = adapt(1, 250, a, self.fields_desc, 1) - if self.lengthSC is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class Signal(Packet): - """Signal Section 10.5.4.23""" - name = "Signal" - fields_desc = [ - ByteField("sigValue", 0x0) - ] - - -# length 2 to max for L3 message (251) -class SsVersionIndicator(Packet): - """SS Version Indicator Section 10.5.4.24""" - name = "SS Version Indicator" - fields_desc = [ - XByteField("lengthSVI", None), - # optional - ByteField("info1", None), - ByteField("info2", None), - ByteField("info3", None), - ByteField("info4", None), - ByteField("info5", None), - ByteField("info6", None), - ByteField("info7", None), - ByteField("info8", None), - ByteField("info9", None), - ByteField("info10", None), - ByteField("info11", None), - ByteField("info12", None), - ByteField("info13", None), - ByteField("info14", None), - ByteField("info15", None), - ByteField("info16", None), - ByteField("info17", None), - ByteField("info18", None), - ByteField("info19", None), - ByteField("info20", None), - ByteField("info21", None), - ByteField("info22", None), - ByteField("info23", None), - ByteField("info24", None), - ByteField("info25", None), - ByteField("info26", None), - ByteField("info27", None), - ByteField("info28", None), - ByteField("info29", None), - ByteField("info30", None), - ByteField("info31", None), - ByteField("info32", None), - ByteField("info33", None), - ByteField("info34", None), - ByteField("info35", None), - ByteField("info36", None), - ByteField("info37", None), - ByteField("info38", None), - ByteField("info39", None), - ByteField("info40", None), - ByteField("info41", None), - ByteField("info42", None), - ByteField("info43", None), - ByteField("info44", None), - ByteField("info45", None), - ByteField("info46", None), - ByteField("info47", None), - ByteField("info48", None), - ByteField("info49", None), - ByteField("info50", None), - ByteField("info51", None), - ByteField("info52", None), - ByteField("info53", None), - ByteField("info54", None), - ByteField("info55", None), - ByteField("info56", None), - ByteField("info57", None), - ByteField("info58", None), - ByteField("info59", None), - ByteField("info60", None), - ByteField("info61", None), - ByteField("info62", None), - ByteField("info63", None), - ByteField("info64", None), - ByteField("info65", None), - ByteField("info66", None), - ByteField("info67", None), - ByteField("info68", None), - ByteField("info69", None), - ByteField("info70", None), - ByteField("info71", None), - ByteField("info72", None), - ByteField("info73", None), - ByteField("info74", None), - ByteField("info75", None), - ByteField("info76", None), - ByteField("info77", None), - ByteField("info78", None), - ByteField("info79", None), - ByteField("info80", None), - ByteField("info81", None), - ByteField("info82", None), - ByteField("info83", None), - ByteField("info84", None), - ByteField("info85", None), - ByteField("info86", None), - ByteField("info87", None), - ByteField("info88", None), - ByteField("info89", None), - ByteField("info90", None), - ByteField("info91", None), - ByteField("info92", None), - ByteField("info93", None), - ByteField("info94", None), - ByteField("info95", None), - ByteField("info96", None), - ByteField("info97", None), - ByteField("info98", None), - ByteField("info99", None), - ByteField("info100", None), - ByteField("info101", None), - ByteField("info102", None), - ByteField("info103", None), - ByteField("info104", None), - ByteField("info105", None), - ByteField("info106", None), - ByteField("info107", None), - ByteField("info108", None), - ByteField("info109", None), - ByteField("info110", None), - ByteField("info111", None), - ByteField("info112", None), - ByteField("info113", None), - ByteField("info114", None), - ByteField("info115", None), - ByteField("info116", None), - ByteField("info117", None), - ByteField("info118", None), - ByteField("info119", None), - ByteField("info120", None), - ByteField("info121", None), - ByteField("info122", None), - ByteField("info123", None), - ByteField("info124", None), - ByteField("info125", None), - ByteField("info126", None), - ByteField("info127", None), - ByteField("info128", None), - ByteField("info129", None), - ByteField("info130", None), - ByteField("info131", None), - ByteField("info132", None), - ByteField("info133", None), - ByteField("info134", None), - ByteField("info135", None), - ByteField("info136", None), - ByteField("info137", None), - ByteField("info138", None), - ByteField("info139", None), - ByteField("info140", None), - ByteField("info141", None), - ByteField("info142", None), - ByteField("info143", None), - ByteField("info144", None), - ByteField("info145", None), - ByteField("info146", None), - ByteField("info147", None), - ByteField("info148", None), - ByteField("info149", None), - ByteField("info150", None), - ByteField("info151", None), - ByteField("info152", None), - ByteField("info153", None), - ByteField("info154", None), - ByteField("info155", None), - ByteField("info156", None), - ByteField("info157", None), - ByteField("info158", None), - ByteField("info159", None), - ByteField("info160", None), - ByteField("info161", None), - ByteField("info162", None), - ByteField("info163", None), - ByteField("info164", None), - ByteField("info165", None), - ByteField("info166", None), - ByteField("info167", None), - ByteField("info168", None), - ByteField("info169", None), - ByteField("info170", None), - ByteField("info171", None), - ByteField("info172", None), - ByteField("info173", None), - ByteField("info174", None), - ByteField("info175", None), - ByteField("info176", None), - ByteField("info177", None), - ByteField("info178", None), - ByteField("info179", None), - ByteField("info180", None), - ByteField("info181", None), - ByteField("info182", None), - ByteField("info183", None), - ByteField("info184", None), - ByteField("info185", None), - ByteField("info186", None), - ByteField("info187", None), - ByteField("info188", None), - ByteField("info189", None), - ByteField("info190", None), - ByteField("info191", None), - ByteField("info192", None), - ByteField("info193", None), - ByteField("info194", None), - ByteField("info195", None), - ByteField("info196", None), - ByteField("info197", None), - ByteField("info198", None), - ByteField("info199", None), - ByteField("info200", None), - ByteField("info201", None), - ByteField("info202", None), - ByteField("info203", None), - ByteField("info204", None), - ByteField("info205", None), - ByteField("info206", None), - ByteField("info207", None), - ByteField("info208", None), - ByteField("info209", None), - ByteField("info210", None), - ByteField("info211", None), - ByteField("info212", None), - ByteField("info213", None), - ByteField("info214", None), - ByteField("info215", None), - ByteField("info216", None), - ByteField("info217", None), - ByteField("info218", None), - ByteField("info219", None), - ByteField("info220", None), - ByteField("info221", None), - ByteField("info222", None), - ByteField("info223", None), - ByteField("info224", None), - ByteField("info225", None), - ByteField("info226", None), - ByteField("info227", None), - ByteField("info228", None), - ByteField("info229", None), - ByteField("info230", None), - ByteField("info231", None), - ByteField("info232", None), - ByteField("info233", None), - ByteField("info234", None), - ByteField("info235", None), - ByteField("info236", None), - ByteField("info237", None), - ByteField("info238", None), - ByteField("info239", None), - ByteField("info240", None), - ByteField("info241", None), - ByteField("info242", None), - ByteField("info243", None), - ByteField("info244", None), - ByteField("info245", None), - ByteField("info246", None), - ByteField("info247", None), - ByteField("info248", None), - ByteField("info249", None), - ] - - def post_build(self, p, pay): - aList = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - a = [] - for i in aList: - a.append(getattr(self, i)) - res = adapt(1, 250, a, self.fields_desc, 1) - if self.lengthSVI is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -# length 3 to 35 or 131 -class UserUser(Packet): - """User-user Section 10.5.4.25""" - name = "User-User" - fields_desc = [ - - XByteField("lengthUU", None), # dynamic length of field depending - # of the type of message - # let user decide which length he - # wants to take - # => more fuzzing options - ByteField("userUserPD", 0x0), - # optional - ByteField("userUserInfo1", None), - ByteField("userUserInfo2", None), - ByteField("userUserInfo3", None), - ByteField("userUserInfo4", None), - ByteField("userUserInfo5", None), - ByteField("userUserInfo6", None), - ByteField("userUserInfo7", None), - ByteField("userUserInfo8", None), - ByteField("userUserInfo9", None), - ByteField("userUserInfo10", None), - ByteField("userUserInfo11", None), - ByteField("userUserInfo12", None), - ByteField("userUserInfo13", None), - ByteField("userUserInfo14", None), - ByteField("userUserInfo15", None), - ByteField("userUserInfo16", None), - ByteField("userUserInfo17", None), - ByteField("userUserInfo18", None), - ByteField("userUserInfo19", None), - ByteField("userUserInfo20", None), - ByteField("userUserInfo21", None), - ByteField("userUserInfo22", None), - ByteField("userUserInfo23", None), - ByteField("userUserInfo24", None), - ByteField("userUserInfo25", None), - ByteField("userUserInfo26", None), - ByteField("userUserInfo27", None), - ByteField("userUserInfo28", None), - ByteField("userUserInfo29", None), - ByteField("userUserInfo30", None), - ByteField("userUserInfo31", None), - ByteField("userUserInfo32", None), - # long packet - ByteField("userUserInfo33", None), - ByteField("userUserInfo34", None), - ByteField("userUserInfo35", None), - ByteField("userUserInfo36", None), - ByteField("userUserInfo37", None), - ByteField("userUserInfo38", None), - ByteField("userUserInfo39", None), - ByteField("userUserInfo40", None), - ByteField("userUserInfo41", None), - ByteField("userUserInfo42", None), - ByteField("userUserInfo43", None), - ByteField("userUserInfo44", None), - ByteField("userUserInfo45", None), - ByteField("userUserInfo46", None), - ByteField("userUserInfo47", None), - ByteField("userUserInfo48", None), - ByteField("userUserInfo49", None), - ByteField("userUserInfo50", None), - ByteField("userUserInfo51", None), - ByteField("userUserInfo52", None), - ByteField("userUserInfo53", None), - ByteField("userUserInfo54", None), - ByteField("userUserInfo55", None), - ByteField("userUserInfo56", None), - ByteField("userUserInfo57", None), - ByteField("userUserInfo58", None), - ByteField("userUserInfo59", None), - ByteField("userUserInfo60", None), - ByteField("userUserInfo61", None), - ByteField("userUserInfo62", None), - ByteField("userUserInfo63", None), - ByteField("userUserInfo64", None), - ByteField("userUserInfo65", None), - ByteField("userUserInfo66", None), - ByteField("userUserInfo67", None), - ByteField("userUserInfo68", None), - ByteField("userUserInfo69", None), - ByteField("userUserInfo70", None), - ByteField("userUserInfo71", None), - ByteField("userUserInfo72", None), - ByteField("userUserInfo73", None), - ByteField("userUserInfo74", None), - ByteField("userUserInfo75", None), - ByteField("userUserInfo76", None), - ByteField("userUserInfo77", None), - ByteField("userUserInfo78", None), - ByteField("userUserInfo79", None), - ByteField("userUserInfo80", None), - ByteField("userUserInfo81", None), - ByteField("userUserInfo82", None), - ByteField("userUserInfo83", None), - ByteField("userUserInfo84", None), - ByteField("userUserInfo85", None), - ByteField("userUserInfo86", None), - ByteField("userUserInfo87", None), - ByteField("userUserInfo88", None), - ByteField("userUserInfo89", None), - ByteField("userUserInfo90", None), - ByteField("userUserInfo91", None), - ByteField("userUserInfo92", None), - ByteField("userUserInfo93", None), - ByteField("userUserInfo94", None), - ByteField("userUserInfo95", None), - ByteField("userUserInfo96", None), - ByteField("userUserInfo97", None), - ByteField("userUserInfo98", None), - ByteField("userUserInfo99", None), - ByteField("userUserInfo100", None), - ByteField("userUserInfo101", None), - ByteField("userUserInfo102", None), - ByteField("userUserInfo103", None), - ByteField("userUserInfo104", None), - ByteField("userUserInfo105", None), - ByteField("userUserInfo106", None), - ByteField("userUserInfo107", None), - ByteField("userUserInfo108", None), - ByteField("userUserInfo109", None), - ByteField("userUserInfo110", None), - ByteField("userUserInfo111", None), - ByteField("userUserInfo112", None), - ByteField("userUserInfo113", None), - ByteField("userUserInfo114", None), - ByteField("userUserInfo115", None), - ByteField("userUserInfo116", None), - ByteField("userUserInfo117", None), - ByteField("userUserInfo118", None), - ByteField("userUserInfo119", None), - ByteField("userUserInfo120", None), - ByteField("userUserInfo121", None), - ByteField("userUserInfo122", None), - ByteField("userUserInfo123", None), - ByteField("userUserInfo124", None), - ByteField("userUserInfo125", None), - ByteField("userUserInfo126", None), - ByteField("userUserInfo127", None), - ByteField("userUserInfo128", None), - ByteField("userUserInfo129", None), - ByteField("userUserInfo130", None), - ByteField("userUserInfo131", None) - ] - - def post_build(self, p, pay): - aList = [] - i = 0 - for i in range(0, len(self.fields_desc)): - aList.append(self.fields_desc[i].name) - a = [] - for i in aList: - a.append(getattr(self, i)) - res = adapt(2, 133, a, self.fields_desc, 1) - if self.lengthUU is None: - p = struct.pack(">B", res[1]) + p[1:] - if res[0] is not 0: - p = p[:-res[0]] - return p + pay - - -class AlertingPattern(Packet): - """Alerting Pattern 10.5.4.26""" - name = "Alerting Pattern" - fields_desc = [ - XByteField("lengthAP", 0x3), - BitField("spare", 0x0, 4), - BitField("alertingValue", 0x0, 4) - ] - - -class AllowedActions(Packet): - """Allowed actions $(CCBS)$ Section 10.5.4.26""" - name = "Allowed Actions $(CCBS)$" - fields_desc = [ - XByteField("lengthAP", 0x3), - BitField("CCBS", 0x0, 1), - BitField("spare", 0x0, 7) - ] - - -# -# 10.5.5 GPRS mobility management information elements -# - - -class AttachType(Packet): - """Attach type Section 10.5.5.2""" - name = "Attach Type" - fields_desc = [ - BitField("spare", 0x0, 1), - BitField("type", 0x1, 3) - ] - - -if __name__ == "__main__": - interact(mydict=globals(), mybanner="Scapy GSM-UM (Air) Addon") diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/gtp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/gtp.py deleted file mode 100644 index aed80a3e6c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/gtp.py +++ /dev/null @@ -1,928 +0,0 @@ -#! /usr/bin/env python - -# Copyright (C) 2018 Leonardo Monteiro -# 2017 Alexis Sultan -# 2017 Alessio Deiana -# 2014 Guillaume Valadon -# 2012 ffranz -## -# This program is published under a GPLv2 license - -# scapy.contrib.description = GPRS Tunneling Protocol (GTP) -# scapy.contrib.status = loads - -from __future__ import absolute_import -import struct - - -from scapy.compat import chb, orb -from scapy.error import warning -from scapy.fields import BitEnumField, BitField, ByteEnumField, ByteField, \ - ConditionalField, FieldLenField, FieldListField, FlagsField, IntField, \ - IPField, PacketListField, ShortField, StrFixedLenField, StrLenField, \ - XBitField, XByteField, XIntField -from scapy.layers.inet import IP, UDP -from scapy.layers.inet6 import IPv6, IP6Field -from scapy.layers.ppp import PPP -from scapy.modules.six.moves import range -from scapy.packet import bind_layers, bind_bottom_up, bind_top_down, \ - Packet, Raw -from scapy.volatile import RandInt, RandIP, RandNum, RandString - - -# GTP Data types - -RATType = { - 1: "UTRAN", - 2: "GETRAN", - 3: "WLAN", - 4: "GAN", - 5: "HSPA" -} - -GTPmessageType = {1: "echo_request", - 2: "echo_response", - 16: "create_pdp_context_req", - 17: "create_pdp_context_res", - 18: "update_pdp_context_req", - 19: "update_pdp_context_resp", - 20: "delete_pdp_context_req", - 21: "delete_pdp_context_res", - 26: "error_indication", - 27: "pdu_notification_req", - 31: "supported_extension_headers_notification", - 254: "end_marker", - 255: "g_pdu"} - -IEType = {1: "Cause", - 2: "IMSI", - 3: "RAI", - 4: "TLLI", - 5: "P_TMSI", - 8: "IE_ReorderingRequired", - 14: "Recovery", - 15: "SelectionMode", - 16: "TEIDI", - 17: "TEICP", - 19: "TeardownInd", - 20: "NSAPI", - 26: "ChargingChrt", - 27: "TraceReference", - 28: "TraceType", - 127: "ChargingId", - 128: "EndUserAddress", - 131: "AccessPointName", - 132: "ProtocolConfigurationOptions", - 133: "GSNAddress", - 134: "MSInternationalNumber", - 135: "QoS", - 148: "CommonFlags", - 149: "APNRestriction", - 151: "RatType", - 152: "UserLocationInformation", - 153: "MSTimeZone", - 154: "IMEI", - 181: "MSInfoChangeReportingAction", - 184: "BearerControlMode", - 191: "EvolvedAllocationRetentionPriority", - 255: "PrivateExtention"} - -CauseValues = {0: "Request IMSI", - 1: "Request IMEI", - 2: "Request IMSI and IMEI", - 3: "No identity needed", - 4: "MS Refuses", - 5: "MS is not GPRS Responding", - 128: "Request accepted", - 129: "New PDP type due to network preference", - 130: "New PDP type due to single address bearer only", - 192: "Non-existent", - 193: "Invalid message format", - 194: "IMSI not known", - 195: "MS is GPRS Detached", - 196: "MS is not GPRS Responding", - 197: "MS Refuses", - 198: "Version not supported", - 199: "No resources available", - 200: "Service not supported", - 201: "Mandatory IE incorrect", - 202: "Mandatory IE missing", - 203: "Optional IE incorrect", - 204: "System failure", - 205: "Roaming restriction", - 206: "P-TMSI Signature mismatch", - 207: "GPRS connection suspended", - 208: "Authentication failure", - 209: "User authentication failed", - 210: "Context not found", - 211: "All dynamic PDP addresses are occupied", - 212: "No memory is available", - 213: "Reallocation failure", - 214: "Unknown mandatory extension header", - 215: "Semantic error in the TFT operation", - 216: "Syntactic error in TFT operation", - 217: "Semantic errors in packet filter(s)", - 218: "Syntactic errors in packet filter(s)", - 219: "Missing or unknown APN", - 220: "Unknown PDP address or PDP type", - 221: "PDP context without TFT already activated", - 222: "APN access denied : no subscription", - 223: "APN Restriction type incompatibility with currently active PDP Contexts", # noqa: E501 - 224: "MS MBMS Capabilities Insufficient", - 225: "Invalid Correlation : ID", - 226: "MBMS Bearer Context Superseded", - 227: "Bearer Control Mode violation", - 228: "Collision with network initiated request"} - -Selection_Mode = {11111100: "MS or APN", - 11111101: "MS", - 11111110: "NET", - 11111111: "FutureUse"} - -TrueFalse_value = {254: "False", - 255: "True"} - -# http://www.arib.or.jp/IMT-2000/V720Mar09/5_Appendix/Rel8/29/29281-800.pdf -ExtensionHeadersTypes = { - 0: "No more extension headers", - 1: "Reserved", - 2: "Reserved", - 64: "UDP Port", - 192: "PDCP PDU Number", - 193: "Reserved", - 194: "Reserved" -} - - -class TBCDByteField(StrFixedLenField): - - def i2h(self, pkt, val): - return val - - def m2i(self, pkt, val): - ret = [] - for v in val: - byte = orb(v) - left = byte >> 4 - right = byte & 0xf - if left == 0xf: - ret.append(TBCD_TO_ASCII[right:right + 1]) - else: - ret += [TBCD_TO_ASCII[right:right + 1], TBCD_TO_ASCII[left:left + 1]] # noqa: E501 - return b"".join(ret) - - def i2m(self, pkt, val): - val = str(val) - ret_string = "" - for i in range(0, len(val), 2): - tmp = val[i:i + 2] - if len(tmp) == 2: - ret_string += chr(int(tmp[1] + tmp[0], 16)) - else: - ret_string += chr(int("F" + tmp[0], 16)) - return ret_string - - -TBCD_TO_ASCII = b"0123456789*#abc" - - -class GTP_ExtensionHeader(Packet): - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt is None: - return GTP_UDPPort_ExtensionHeader - return cls - - -class GTP_UDPPort_ExtensionHeader(GTP_ExtensionHeader): - fields_desc = [ByteField("length", 0x40), - ShortField("udp_port", None), - ByteEnumField("next_ex", 0, ExtensionHeadersTypes), ] - - -class GTP_PDCP_PDU_ExtensionHeader(GTP_ExtensionHeader): - fields_desc = [ByteField("length", 0x01), - ShortField("pdcp_pdu", None), - ByteEnumField("next_ex", 0, ExtensionHeadersTypes), ] - - -class GTPHeader(Packet): - # 3GPP TS 29.060 V9.1.0 (2009-12) - name = "GTP-C Header" - fields_desc = [BitField("version", 1, 3), - BitField("PT", 1, 1), - BitField("reserved", 0, 1), - BitField("E", 0, 1), - BitField("S", 0, 1), - BitField("PN", 0, 1), - ByteEnumField("gtp_type", None, GTPmessageType), - ShortField("length", None), - IntField("teid", 0), - ConditionalField(XBitField("seq", 0, 16), lambda pkt:pkt.E == 1 or pkt.S == 1 or pkt.PN == 1), # noqa: E501 - ConditionalField(ByteField("npdu", 0), lambda pkt:pkt.E == 1 or pkt.S == 1 or pkt.PN == 1), # noqa: E501 - ConditionalField(ByteEnumField("next_ex", 0, ExtensionHeadersTypes), lambda pkt:pkt.E == 1 or pkt.S == 1 or pkt.PN == 1), ] # noqa: E501 - - def post_build(self, p, pay): - p += pay - if self.length is None: - tmp_len = len(p) - 8 - p = p[:2] + struct.pack("!H", tmp_len) + p[4:] - return p - - def hashret(self): - return struct.pack("B", self.version) + self.payload.hashret() - - def answers(self, other): - return (isinstance(other, GTPHeader) and - self.version == other.version and - self.payload.answers(other.payload)) - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 1: - if (orb(_pkt[0]) >> 5) & 0x7 == 2: - from . import gtp_v2 - return gtp_v2.GTPHeader - if _pkt and len(_pkt) >= 8: - _gtp_type = orb(_pkt[1:2]) - return GTPforcedTypes.get(_gtp_type, GTPHeader) - return cls - - -class GTP_U_Header(GTPHeader): - # 3GPP TS 29.060 V9.1.0 (2009-12) - name = "GTP-U Header" - # GTP-U protocol is used to transmit T-PDUs between GSN pairs (or between an SGSN and an RNC in UMTS), # noqa: E501 - # encapsulated in G-PDUs. A G-PDU is a packet including a GTP-U header and a T-PDU. The Path Protocol # noqa: E501 - # defines the path and the GTP-U header defines the tunnel. Several tunnels may be multiplexed on a single path. # noqa: E501 - - def guess_payload_class(self, payload): - # Snooped from Wireshark - # https://github.com/boundary/wireshark/blob/07eade8124fd1d5386161591b52e177ee6ea849f/epan/dissectors/packet-gtp.c#L8195 # noqa: E501 - if self.gtp_type == 255: - sub_proto = orb(payload[0]) - if sub_proto >= 0x45 and sub_proto <= 0x4e: - return IP - elif (sub_proto & 0xf0) == 0x60: - return IPv6 - else: - return PPP - return GTPHeader.guess_payload_class(self, payload) - - -# Some gtp_types have to be associated with a certain type of header -GTPforcedTypes = { - 16: GTPHeader, - 17: GTPHeader, - 18: GTPHeader, - 19: GTPHeader, - 20: GTPHeader, - 21: GTPHeader, - 26: GTP_U_Header, - 27: GTPHeader, - 254: GTP_U_Header, - 255: GTP_U_Header -} - - -class GTPEchoRequest(Packet): - # 3GPP TS 29.060 V9.1.0 (2009-12) - name = "GTP Echo Request" - - def hashret(self): - return struct.pack("H", self.seq) - - -class IE_Base(Packet): - - def extract_padding(self, pkt): - return "", pkt - - -class IE_Cause(IE_Base): - name = "Cause" - fields_desc = [ByteEnumField("ietype", 1, IEType), - ByteEnumField("CauseValue", None, CauseValues)] - - -class IE_IMSI(IE_Base): - name = "IMSI - Subscriber identity of the MS" - fields_desc = [ByteEnumField("ietype", 2, IEType), - TBCDByteField("imsi", str(RandNum(0, 999999999999999)), 8)] - - -class IE_Routing(IE_Base): - name = "Routing Area Identity" - fields_desc = [ByteEnumField("ietype", 3, IEType), - TBCDByteField("MCC", "", 2), - # MNC: if the third digit of MCC is 0xf, - # then the length of MNC is 1 byte - TBCDByteField("MNC", "", 1), - ShortField("LAC", None), - ByteField("RAC", None)] - - -class IE_ReorderingRequired(IE_Base): - name = "Recovery" - fields_desc = [ByteEnumField("ietype", 8, IEType), - ByteEnumField("reordering_required", 254, TrueFalse_value)] - - -class IE_Recovery(IE_Base): - name = "Recovery" - fields_desc = [ByteEnumField("ietype", 14, IEType), - ByteField("restart_counter", 24)] - - -class IE_SelectionMode(IE_Base): - # Indicates the origin of the APN in the message - name = "Selection Mode" - fields_desc = [ByteEnumField("ietype", 15, IEType), - BitEnumField("SelectionMode", "MS or APN", - 8, Selection_Mode)] - - -class IE_TEIDI(IE_Base): - name = "Tunnel Endpoint Identifier Data" - fields_desc = [ByteEnumField("ietype", 16, IEType), - XIntField("TEIDI", RandInt())] - - -class IE_TEICP(IE_Base): - name = "Tunnel Endpoint Identifier Control Plane" - fields_desc = [ByteEnumField("ietype", 17, IEType), - XIntField("TEICI", RandInt())] - - -class IE_Teardown(IE_Base): - name = "Teardown Indicator" - fields_desc = [ByteEnumField("ietype", 19, IEType), - ByteEnumField("indicator", "True", TrueFalse_value)] - - -class IE_NSAPI(IE_Base): - # Identifies a PDP context in a mobility management context specified by TEICP # noqa: E501 - name = "NSAPI" - fields_desc = [ByteEnumField("ietype", 20, IEType), - XBitField("sparebits", 0x0000, 4), - XBitField("NSAPI", RandNum(0, 15), 4)] - - -class IE_ChargingCharacteristics(IE_Base): - # Way of informing both the SGSN and GGSN of the rules for - name = "Charging Characteristics" - fields_desc = [ByteEnumField("ietype", 26, IEType), - # producing charging information based on operator configured triggers. # noqa: E501 - # 0000 .... .... .... : spare - # .... 1... .... .... : normal charging - # .... .0.. .... .... : prepaid charging - # .... ..0. .... .... : flat rate charging - # .... ...0 .... .... : hot billing charging - # .... .... 0000 0000 : reserved - XBitField("Ch_ChSpare", None, 4), - XBitField("normal_charging", None, 1), - XBitField("prepaid_charging", None, 1), - XBitField("flat_rate_charging", None, 1), - XBitField("hot_billing_charging", None, 1), - XBitField("Ch_ChReserved", 0, 8)] - - -class IE_TraceReference(IE_Base): - # Identifies a record or a collection of records for a particular trace. - name = "Trace Reference" - fields_desc = [ByteEnumField("ietype", 27, IEType), - XBitField("Trace_reference", None, 16)] - - -class IE_TraceType(IE_Base): - # Indicates the type of the trace - name = "Trace Type" - fields_desc = [ByteEnumField("ietype", 28, IEType), - XBitField("Trace_type", None, 16)] - - -class IE_ChargingId(IE_Base): - name = "Charging ID" - fields_desc = [ByteEnumField("ietype", 127, IEType), - XIntField("Charging_id", RandInt())] - - -class IE_EndUserAddress(IE_Base): - # Supply protocol specific information of the external packet - name = "End User Address" - fields_desc = [ByteEnumField("ietype", 128, IEType), - # data network accessed by the GGPRS subscribers. - # - Request - # 1 Type (1byte) - # 2-3 Length (2bytes) - value 2 - # 4 Spare + PDP Type Organization - # 5 PDP Type Number - # - Response - # 6-n PDP Address - ShortField("length", 2), - BitField("SPARE", 15, 4), - BitField("PDPTypeOrganization", 1, 4), - XByteField("PDPTypeNumber", None), - ConditionalField(IPField("PDPAddress", RandIP()), - lambda pkt: pkt.length == 6 or pkt.length == 22), # noqa: E501 - ConditionalField(IP6Field("IPv6_PDPAddress", '::1'), - lambda pkt: pkt.length == 18 or pkt.length == 22)] # noqa: E501 - - -class APNStrLenField(StrLenField): - # Inspired by DNSStrField - def m2i(self, pkt, s): - ret_s = b"" - tmp_s = s - while tmp_s: - tmp_len = orb(tmp_s[0]) + 1 - if tmp_len > len(tmp_s): - warning("APN prematured end of character-string (size=%i, remaining bytes=%i)" % (tmp_len, len(tmp_s))) # noqa: E501 - ret_s += tmp_s[1:tmp_len] - tmp_s = tmp_s[tmp_len:] - if len(tmp_s): - ret_s += b"." - s = ret_s - return s - - def i2m(self, pkt, s): - s = b"".join(chb(len(x)) + x for x in s.split(".")) - return s - - -class IE_AccessPointName(IE_Base): - # Sent by SGSN or by GGSN as defined in 3GPP TS 23.060 - name = "Access Point Name" - fields_desc = [ByteEnumField("ietype", 131, IEType), - ShortField("length", None), - APNStrLenField("APN", "nternet", length_from=lambda x: x.length)] # noqa: E501 - - def post_build(self, p, pay): - if self.length is None: - tmp_len = len(p) - 3 - p = p[:2] + struct.pack("!B", tmp_len) + p[3:] - return p - - -class IE_ProtocolConfigurationOptions(IE_Base): - name = "Protocol Configuration Options" - fields_desc = [ByteEnumField("ietype", 132, IEType), - ShortField("length", 4), - StrLenField("Protocol_Configuration", "", - length_from=lambda x: x.length)] - - -class IE_GSNAddress(IE_Base): - name = "GSN Address" - fields_desc = [ByteEnumField("ietype", 133, IEType), - ShortField("length", 4), - IPField("address", RandIP())] - - -class IE_MSInternationalNumber(IE_Base): - name = "MS International Number" - fields_desc = [ByteEnumField("ietype", 134, IEType), - ShortField("length", None), - FlagsField("flags", 0x91, 8, ["Extension", "", "", "International Number", "", "", "", "ISDN numbering"]), # noqa: E501 - TBCDByteField("digits", "33607080910", length_from=lambda x: x.length - 1)] # noqa: E501 - - -class QoS_Profile(IE_Base): - name = "QoS profile" - fields_desc = [ByteField("qos_ei", 0), - ByteField("length", None), - XBitField("spare", 0x00, 2), - XBitField("delay_class", 0x000, 3), - XBitField("reliability_class", 0x000, 3), - XBitField("peak_troughput", 0x0000, 4), - BitField("spare", 0, 1), - XBitField("precedence_class", 0x000, 3), - XBitField("spare", 0x000, 3), - XBitField("mean_troughput", 0x00000, 5), - XBitField("traffic_class", 0x000, 3), - XBitField("delivery_order", 0x00, 2), - XBitField("delivery_of_err_sdu", 0x000, 3), - ByteField("max_sdu_size", None), - ByteField("max_bitrate_up", None), - ByteField("max_bitrate_down", None), - XBitField("redidual_ber", 0x0000, 4), - XBitField("sdu_err_ratio", 0x0000, 4), - XBitField("transfer_delay", 0x00000, 5), - XBitField("traffic_handling_prio", 0x000, 3), - ByteField("guaranteed_bit_rate_up", None), - ByteField("guaranteed_bit_rate_down", None)] - - -class IE_QoS(IE_Base): - name = "QoS" - fields_desc = [ByteEnumField("ietype", 135, IEType), - ShortField("length", None), - ByteField("allocation_retention_prioiry", 1), - - ConditionalField(XBitField("spare", 0x00, 2), - lambda pkt: pkt.length > 1), - ConditionalField(XBitField("delay_class", 0x000, 3), - lambda pkt: pkt.length > 1), - ConditionalField(XBitField("reliability_class", 0x000, 3), - lambda pkt: pkt.length > 1), - - ConditionalField(XBitField("peak_troughput", 0x0000, 4), - lambda pkt: pkt.length > 2), - ConditionalField(BitField("spare", 0, 1), - lambda pkt: pkt.length > 2), - ConditionalField(XBitField("precedence_class", 0x000, 3), - lambda pkt: pkt.length > 2), - - ConditionalField(XBitField("spare", 0x000, 3), - lambda pkt: pkt.length > 3), - ConditionalField(XBitField("mean_troughput", 0x00000, 5), - lambda pkt: pkt.length > 3), - - ConditionalField(XBitField("traffic_class", 0x000, 3), - lambda pkt: pkt.length > 4), - ConditionalField(XBitField("delivery_order", 0x00, 2), - lambda pkt: pkt.length > 4), - ConditionalField(XBitField("delivery_of_err_sdu", 0x000, 3), - lambda pkt: pkt.length > 4), - - ConditionalField(ByteField("max_sdu_size", None), - lambda pkt: pkt.length > 5), - ConditionalField(ByteField("max_bitrate_up", None), - lambda pkt: pkt.length > 6), - ConditionalField(ByteField("max_bitrate_down", None), - lambda pkt: pkt.length > 7), - - ConditionalField(XBitField("redidual_ber", 0x0000, 4), - lambda pkt: pkt.length > 8), - ConditionalField(XBitField("sdu_err_ratio", 0x0000, 4), - lambda pkt: pkt.length > 8), - ConditionalField(XBitField("transfer_delay", 0x00000, 6), - lambda pkt: pkt.length > 9), - ConditionalField(XBitField("traffic_handling_prio", - 0x000, - 2), - lambda pkt: pkt.length > 9), - - ConditionalField(ByteField("guaranteed_bit_rate_up", None), - lambda pkt: pkt.length > 10), - ConditionalField(ByteField("guaranteed_bit_rate_down", - None), - lambda pkt: pkt.length > 11), - - ConditionalField(XBitField("spare", 0x000, 3), - lambda pkt: pkt.length > 12), - ConditionalField(BitField("signaling_indication", 0, 1), - lambda pkt: pkt.length > 12), - ConditionalField(XBitField("source_stats_desc", 0x0000, 4), - lambda pkt: pkt.length > 12), - - ConditionalField(ByteField("max_bitrate_down_ext", None), - lambda pkt: pkt.length > 13), - ConditionalField(ByteField("guaranteed_bitrate_down_ext", - None), - lambda pkt: pkt.length > 14), - ConditionalField(ByteField("max_bitrate_up_ext", None), - lambda pkt: pkt.length > 15), - ConditionalField(ByteField("guaranteed_bitrate_up_ext", - None), - lambda pkt: pkt.length > 16), - ConditionalField(ByteField("max_bitrate_down_ext2", None), - lambda pkt: pkt.length > 17), - ConditionalField(ByteField("guaranteed_bitrate_down_ext2", - None), - lambda pkt: pkt.length > 18), - ConditionalField(ByteField("max_bitrate_up_ext2", None), - lambda pkt: pkt.length > 19), - ConditionalField(ByteField("guaranteed_bitrate_up_ext2", - None), - lambda pkt: pkt.length > 20)] - - -class IE_CommonFlags(IE_Base): - name = "Common Flags" - fields_desc = [ByteEnumField("ietype", 148, IEType), - ShortField("length", None), - BitField("dual_addr_bearer_fl", 0, 1), - BitField("upgrade_qos_supported", 0, 1), - BitField("nrsn", 0, 1), - BitField("no_qos_nego", 0, 1), - BitField("mbms_cnting_info", 0, 1), - BitField("ran_procedure_ready", 0, 1), - BitField("mbms_service_type", 0, 1), - BitField("prohibit_payload_compression", 0, 1)] - - -class IE_APNRestriction(IE_Base): - name = "APN Restriction" - fields_desc = [ByteEnumField("ietype", 149, IEType), - ShortField("length", 1), - ByteField("restriction_type_value", 0)] - - -class IE_RATType(IE_Base): - name = "Rat Type" - fields_desc = [ByteEnumField("ietype", 151, IEType), - ShortField("length", 1), - ByteEnumField("RAT_Type", None, RATType)] - - -class IE_UserLocationInformation(IE_Base): - name = "User Location Information" - fields_desc = [ByteEnumField("ietype", 152, IEType), - ShortField("length", None), - ByteField("type", 1), - # Only type 1 is currently supported - TBCDByteField("MCC", "", 2), - # MNC: if the third digit of MCC is 0xf, then the length of MNC is 1 byte # noqa: E501 - TBCDByteField("MNC", "", 1), - ShortField("LAC", None), - ShortField("SAC", None)] - - -class IE_MSTimeZone(IE_Base): - name = "MS Time Zone" - fields_desc = [ByteEnumField("ietype", 153, IEType), - ShortField("length", None), - ByteField("timezone", 0), - BitField("Spare", 0, 1), - BitField("Spare", 0, 1), - BitField("Spare", 0, 1), - BitField("Spare", 0, 1), - BitField("Spare", 0, 1), - BitField("Spare", 0, 1), - XBitField("daylight_saving_time", 0x00, 2)] - - -class IE_IMEI(IE_Base): - name = "IMEI" - fields_desc = [ByteEnumField("ietype", 154, IEType), - ShortField("length", None), - TBCDByteField("IMEI", "", length_from=lambda x: x.length)] - - -class IE_MSInfoChangeReportingAction(IE_Base): - name = "MS Info Change Reporting Action" - fields_desc = [ByteEnumField("ietype", 181, IEType), - ShortField("length", 1), - ByteField("Action", 0)] - - -class IE_DirectTunnelFlags(IE_Base): - name = "Direct Tunnel Flags" - fields_desc = [ByteEnumField("ietype", 182, IEType), - ShortField("length", 1), - BitField("Spare", 0, 1), - BitField("Spare", 0, 1), - BitField("Spare", 0, 1), - BitField("Spare", 0, 1), - BitField("Spare", 0, 1), - BitField("EI", 0, 1), - BitField("GCSI", 0, 1), - BitField("DTI", 0, 1)] - - -class IE_BearerControlMode(IE_Base): - name = "Bearer Control Mode" - fields_desc = [ByteEnumField("ietype", 184, IEType), - ShortField("length", 1), - ByteField("bearer_control_mode", 0)] - - -class IE_EvolvedAllocationRetentionPriority(IE_Base): - name = "Evolved Allocation/Retention Priority" - fields_desc = [ByteEnumField("ietype", 191, IEType), - ShortField("length", 1), - BitField("Spare", 0, 1), - BitField("PCI", 0, 1), - XBitField("PL", 0x0000, 4), - BitField("Spare", 0, 1), - BitField("PVI", 0, 1)] - - -class IE_CharginGatewayAddress(IE_Base): - name = "Chargin Gateway Address" - fields_desc = [ByteEnumField("ietype", 251, IEType), - ShortField("length", 4), - ConditionalField(IPField("ipv4_address", "127.0.0.1"), - lambda - pkt: pkt.length == 4), - ConditionalField(IP6Field("ipv6_address", "::1"), lambda - pkt: pkt.length == 16)] - - -class IE_PrivateExtension(IE_Base): - name = "Private Extension" - fields_desc = [ByteEnumField("ietype", 255, IEType), - ShortField("length", 1), - ByteField("extension identifier", 0), - StrLenField("extention_value", "", - length_from=lambda x: x.length)] - - -class IE_ExtensionHeaderList(IE_Base): - name = "Extension Header List" - fields_desc = [ByteEnumField("ietype", 141, IEType), - FieldLenField("length", None, length_of="extension_headers"), # noqa: E501 - FieldListField("extension_headers", [64, 192], ByteField("", 0))] # noqa: E501 - - -class IE_NotImplementedTLV(Packet): - name = "IE not implemented" - fields_desc = [ByteEnumField("ietype", 0, IEType), - ShortField("length", None), - StrLenField("data", "", length_from=lambda x: x.length)] - - def extract_padding(self, pkt): - return "", pkt - - -ietypecls = {1: IE_Cause, - 2: IE_IMSI, - 3: IE_Routing, - 8: IE_ReorderingRequired, - 14: IE_Recovery, - 15: IE_SelectionMode, - 16: IE_TEIDI, - 17: IE_TEICP, - 19: IE_Teardown, - 20: IE_NSAPI, - 26: IE_ChargingCharacteristics, - 27: IE_TraceReference, - 28: IE_TraceType, - 127: IE_ChargingId, - 128: IE_EndUserAddress, - 131: IE_AccessPointName, - 132: IE_ProtocolConfigurationOptions, - 133: IE_GSNAddress, - 134: IE_MSInternationalNumber, - 135: IE_QoS, - 141: IE_ExtensionHeaderList, - 148: IE_CommonFlags, - 149: IE_APNRestriction, - 151: IE_RATType, - 152: IE_UserLocationInformation, - 153: IE_MSTimeZone, - 154: IE_IMEI, - 181: IE_MSInfoChangeReportingAction, - 182: IE_DirectTunnelFlags, - 184: IE_BearerControlMode, - 191: IE_EvolvedAllocationRetentionPriority, - 251: IE_CharginGatewayAddress, - 255: IE_PrivateExtension} - - -def IE_Dispatcher(s): - """Choose the correct Information Element class.""" - if len(s) < 1: - return Raw(s) - # Get the IE type - ietype = orb(s[0]) - cls = ietypecls.get(ietype, Raw) - - # if ietype greater than 128 are TLVs - if cls == Raw and ietype & 128 == 128: - cls = IE_NotImplementedTLV - return cls(s) - - -class GTPEchoResponse(Packet): - # 3GPP TS 29.060 V9.1.0 (2009-12) - name = "GTP Echo Response" - fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)] - - def hashret(self): - return struct.pack("H", self.seq) - - def answers(self, other): - return self.seq == other.seq - - -class GTPCreatePDPContextRequest(Packet): - # 3GPP TS 29.060 V9.1.0 (2009-12) - name = "GTP Create PDP Context Request" - fields_desc = [PacketListField("IE_list", [IE_TEIDI(), IE_NSAPI(), IE_GSNAddress(), # noqa: E501 - IE_GSNAddress(), - IE_NotImplementedTLV(ietype=135, length=15, data=RandString(15))], # noqa: E501 - IE_Dispatcher)] - - def hashret(self): - return struct.pack("H", self.seq) - - -class GTPCreatePDPContextResponse(Packet): - # 3GPP TS 29.060 V9.1.0 (2009-12) - name = "GTP Create PDP Context Response" - fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)] - - def hashret(self): - return struct.pack("H", self.seq) - - def answers(self, other): - return self.seq == other.seq - - -class GTPUpdatePDPContextRequest(Packet): - # 3GPP TS 29.060 V9.1.0 (2009-12) - name = "GTP Update PDP Context Request" - fields_desc = [PacketListField("IE_list", [ - IE_Cause(), - IE_Recovery(), - IE_TEIDI(), - IE_TEICP(), - IE_ChargingId(), - IE_ProtocolConfigurationOptions(), - IE_GSNAddress(), - IE_GSNAddress(), - IE_GSNAddress(), - IE_GSNAddress(), - IE_QoS(), - IE_CharginGatewayAddress(), - IE_CharginGatewayAddress(), - IE_CommonFlags(), - IE_APNRestriction(), - IE_BearerControlMode(), - IE_MSInfoChangeReportingAction(), - IE_EvolvedAllocationRetentionPriority(), - IE_PrivateExtension()], - IE_Dispatcher)] - - def hashret(self): - return struct.pack("H", self.seq) - - -class GTPUpdatePDPContextResponse(Packet): - # 3GPP TS 29.060 V9.1.0 (2009-12) - name = "GTP Update PDP Context Response" - fields_desc = [PacketListField("IE_list", None, IE_Dispatcher)] - - def hashret(self): - return struct.pack("H", self.seq) - - -class GTPErrorIndication(Packet): - # 3GPP TS 29.060 V9.1.0 (2009-12) - name = "GTP Error Indication" - fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)] - - -class GTPDeletePDPContextRequest(Packet): - # 3GPP TS 29.060 V9.1.0 (2009-12) - name = "GTP Delete PDP Context Request" - fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)] - - -class GTPDeletePDPContextResponse(Packet): - # 3GPP TS 29.060 V9.1.0 (2009-12) - name = "GTP Delete PDP Context Response" - fields_desc = [PacketListField("IE_list", [], IE_Dispatcher)] - - -class GTPPDUNotificationRequest(Packet): - # 3GPP TS 29.060 V9.1.0 (2009-12) - name = "GTP PDU Notification Request" - fields_desc = [PacketListField("IE_list", [IE_IMSI(), - IE_TEICP(TEICI=RandInt()), - IE_EndUserAddress(PDPTypeNumber=0x21), # noqa: E501 - IE_AccessPointName(), - IE_GSNAddress(address="127.0.0.1"), # noqa: E501 - ], IE_Dispatcher)] - - -class GTPSupportedExtensionHeadersNotification(Packet): - name = "GTP Supported Extension Headers Notification" - fields_desc = [PacketListField("IE_list", [IE_ExtensionHeaderList(), - ], IE_Dispatcher)] - - -class GTPmorethan1500(Packet): - # 3GPP TS 29.060 V9.1.0 (2009-12) - name = "GTP More than 1500" - fields_desc = [ByteEnumField("IE_Cause", "Cause", IEType), - BitField("IE", 1, 12000), ] - - -# Bind GTP-C -bind_bottom_up(UDP, GTPHeader, dport=2123) -bind_bottom_up(UDP, GTPHeader, sport=2123) -bind_layers(UDP, GTPHeader, dport=2123, sport=2123) -bind_layers(GTPHeader, GTPEchoRequest, gtp_type=1, S=1) -bind_layers(GTPHeader, GTPEchoResponse, gtp_type=2, S=1) -bind_layers(GTPHeader, GTPCreatePDPContextRequest, gtp_type=16) -bind_layers(GTPHeader, GTPCreatePDPContextResponse, gtp_type=17) -bind_layers(GTPHeader, GTPUpdatePDPContextRequest, gtp_type=18) -bind_layers(GTPHeader, GTPUpdatePDPContextResponse, gtp_type=19) -bind_layers(GTPHeader, GTPDeletePDPContextRequest, gtp_type=20) -bind_layers(GTPHeader, GTPDeletePDPContextResponse, gtp_type=21) -bind_layers(GTPHeader, GTPPDUNotificationRequest, gtp_type=27) -bind_layers(GTPHeader, GTPSupportedExtensionHeadersNotification, gtp_type=31, S=1) # noqa: E501 -bind_layers(GTPHeader, GTP_UDPPort_ExtensionHeader, next_ex=64, E=1) -bind_layers(GTPHeader, GTP_PDCP_PDU_ExtensionHeader, next_ex=192, E=1) - -# Bind GTP-U -bind_bottom_up(UDP, GTP_U_Header, dport=2152) -bind_bottom_up(UDP, GTP_U_Header, sport=2152) -bind_layers(UDP, GTP_U_Header, dport=2152, sport=2152) -bind_layers(GTP_U_Header, GTPErrorIndication, gtp_type=26, S=1) -bind_top_down(GTP_U_Header, IP, gtp_type=255) -bind_top_down(GTP_U_Header, IPv6, gtp_type=255) -bind_top_down(GTP_U_Header, PPP, gtp_type=255) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/gtp_v2.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/gtp_v2.py deleted file mode 100755 index af949185e5..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/gtp_v2.py +++ /dev/null @@ -1,936 +0,0 @@ -#! /usr/bin/env python - -# Copyright (C) 2017 Alessio Deiana -# 2017 Alexis Sultan - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = GPRS Tunneling Protocol v2 (GTPv2) -# scapy.contrib.status = loads - -import struct - - -from scapy.compat import orb -from scapy.fields import BitEnumField, BitField, ByteEnumField, ByteField, \ - ConditionalField, IntField, IPField, LongField, PacketField, \ - PacketListField, ShortEnumField, ShortField, StrFixedLenField, \ - StrLenField, ThreeBytesField, XBitField, XIntField, XShortField -from scapy.packet import bind_layers, Packet, Raw -from scapy.volatile import RandIP, RandShort - - -from scapy.contrib import gtp - - -RATType = { - 6: "EUTRAN", -} - -GTPmessageType = {1: "echo_request", - 2: "echo_response", - 32: "create_session_req", - 33: "create_session_res", - 34: "modify_bearer_req", - 35: "modify_bearer_res", - 36: "delete_session_req", - 37: "delete_session_res", - 70: "downlink_data_notif_failure_indic", - 170: "realease_bearers_req", - 171: "realease_bearers_res", - 176: "downlink_data_notif", - 177: "downlink_data_notif_ack", - } - -IEType = {1: "IMSI", - 2: "Cause", - 3: "Recovery Restart", - 71: "APN", - 72: "AMBR", - 73: "EPS Bearer ID", - 74: "IPv4", - 75: "MEI", - 76: "MSISDN", - 77: "Indication", - 78: "Protocol Configuration Options", - 79: "PAA", - 80: "Bearer QoS", - 82: "RAT", - 83: "Serving Network", - 86: "ULI", - 87: "F-TEID", - 93: "Bearer Context", - 94: "Charging ID", - 95: "Charging Characteristics", - 99: "PDN Type", - 114: "UE Time zone", - 126: "Port Number", - 127: "APN Restriction", - 128: "Selection Mode", - 161: "Max MBR/APN-AMBR (MMBR)" - } - -CauseValues = { - 16: "Request Accepted", -} - - -class GTPHeader(Packet): - # 3GPP TS 29.060 V9.1.0 (2009-12) - # without the version - name = "GTP v2 Header" - fields_desc = [BitField("version", 2, 3), - BitField("P", 1, 1), - BitField("T", 1, 1), - BitField("SPARE", 0, 1), - BitField("SPARE", 0, 1), - BitField("SPARE", 0, 1), - ByteEnumField("gtp_type", None, GTPmessageType), - ShortField("length", None), - ConditionalField(IntField("teid", 0), - lambda pkt:pkt.T == 1), - ThreeBytesField("seq", RandShort()), - ByteField("SPARE", 0) - ] - - def post_build(self, p, pay): - p += pay - if self.length is None: - tmp_len = len(p) - 8 - p = p[:2] + struct.pack("!H", tmp_len) + p[4:] - return p - - def hashret(self): - return struct.pack("B", self.version) + self.payload.hashret() - - def answers(self, other): - return (isinstance(other, GTPHeader) and - self.version == other.version and - self.payload.answers(other.payload)) - - -class IE_IPv4(gtp.IE_Base): - name = "IE IPv4" - fields_desc = [ByteEnumField("ietype", 74, IEType), - ShortField("length", 0), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - IPField("address", RandIP())] - - -class IE_MEI(gtp.IE_Base): - name = "IE MEI" - fields_desc = [ByteEnumField("ietype", 75, IEType), - ShortField("length", 0), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - LongField("MEI", 0)] - - -def IE_Dispatcher(s): - """Choose the correct Information Element class.""" - - # Get the IE type - ietype = orb(s[0]) - cls = ietypecls.get(ietype, Raw) - - # if ietype greater than 128 are TLVs - if cls is Raw and ietype > 128: - cls = IE_NotImplementedTLV - - return cls(s) - - -class IE_EPSBearerID(gtp.IE_Base): - name = "IE EPS Bearer ID" - fields_desc = [ByteEnumField("ietype", 73, IEType), - ShortField("length", 0), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - ByteField("EBI", 0)] - - -class IE_RAT(gtp.IE_Base): - name = "IE RAT" - fields_desc = [ByteEnumField("ietype", 82, IEType), - ShortField("length", 0), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - ByteEnumField("RAT_type", None, RATType)] - - -class IE_ServingNetwork(gtp.IE_Base): - name = "IE Serving Network" - fields_desc = [ByteEnumField("ietype", 83, IEType), - ShortField("length", 0), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - gtp.TBCDByteField("MCC", "", 2), - gtp.TBCDByteField("MNC", "", 1)] - - -class ULI_RAI(gtp.IE_Base): - name = "IE Tracking Area Identity" - fields_desc = [ - gtp.TBCDByteField("MCC", "", 2), - # MNC: if the third digit of MCC is 0xf, then the length of - # MNC is 1 byte - gtp.TBCDByteField("MNC", "", 1), - ShortField("LAC", 0), - ShortField("RAC", 0)] - - -class ULI_SAI(gtp.IE_Base): - name = "IE Tracking Area Identity" - fields_desc = [ - gtp.TBCDByteField("MCC", "", 2), - gtp.TBCDByteField("MNC", "", 1), - ShortField("LAC", 0), - ShortField("SAC", 0)] - - -class ULI_TAI(gtp.IE_Base): - name = "IE Tracking Area Identity" - fields_desc = [ - gtp.TBCDByteField("MCC", "", 2), - gtp.TBCDByteField("MNC", "", 1), - ShortField("TAC", 0)] - - -class ULI_ECGI(gtp.IE_Base): - name = "IE E-UTRAN Cell Identifier" - fields_desc = [ - gtp.TBCDByteField("MCC", "", 2), - gtp.TBCDByteField("MNC", "", 1), - BitField("SPARE", 0, 4), - BitField("ECI", 0, 28)] - - -class IE_ULI(gtp.IE_Base): - name = "IE ULI" - fields_desc = [ByteEnumField("ietype", 86, IEType), - ShortField("length", 0), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - BitField("SPARE", 0, 2), - BitField("LAI_Present", 0, 1), - BitField("ECGI_Present", 0, 1), - BitField("TAI_Present", 0, 1), - BitField("RAI_Present", 0, 1), - BitField("SAI_Present", 0, 1), - BitField("CGI_Present", 0, 1), - ConditionalField( - PacketField("SAI", 0, ULI_SAI), lambda pkt: bool(pkt.SAI_Present)), - ConditionalField( - PacketField("RAI", 0, ULI_RAI), lambda pkt: bool(pkt.RAI_Present)), - ConditionalField( - PacketField("TAI", 0, ULI_TAI), lambda pkt: bool(pkt.TAI_Present)), - ConditionalField(PacketField("ECGI", 0, ULI_ECGI), - lambda pkt: bool(pkt.ECGI_Present))] - - -class IE_FTEID(gtp.IE_Base): - name = "IE F-TEID" - fields_desc = [ByteEnumField("ietype", 87, IEType), - ShortField("length", 0), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - BitField("ipv4_present", 0, 1), - BitField("ipv6_present", 0, 1), - BitField("InterfaceType", 0, 6), - XIntField("GRE_Key", 0), - ConditionalField( - IPField("ipv4", RandIP()), lambda pkt: pkt.ipv4_present), - ConditionalField(XBitField("ipv6", "2001::", 128), - lambda pkt: pkt.ipv6_present)] - - -class IE_BearerContext(gtp.IE_Base): - name = "IE Bearer Context" - fields_desc = [ByteEnumField("ietype", 93, IEType), - ShortField("length", 0), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - PacketListField("IE_list", None, IE_Dispatcher, - length_from=lambda pkt: pkt.length)] - - -class IE_NotImplementedTLV(gtp.IE_Base): - name = "IE not implemented" - fields_desc = [ByteEnumField("ietype", 0, IEType), - ShortField("length", None), - StrLenField("data", "", length_from=lambda x: x.length)] - - -class IE_IMSI(gtp.IE_Base): - name = "IE IMSI" - fields_desc = [ByteEnumField("ietype", 1, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - gtp.TBCDByteField("IMSI", "33607080910", - length_from=lambda x: x.length)] - - -class IE_Cause(gtp.IE_Base): - name = "IE Cause" - fields_desc = [ByteEnumField("ietype", 2, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - ByteEnumField("Cause", 1, CauseValues), - BitField("SPARE", 0, 5), - BitField("PCE", 0, 1), - BitField("BCE", 0, 1), - BitField("CS", 0, 1)] - - -class IE_RecoveryRestart(gtp.IE_Base): - name = "IE Recovery Restart" - fields_desc = [ByteEnumField("ietype", 3, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - ByteField("restart_counter", 0)] - - -class IE_APN(gtp.IE_Base): - name = "IE APN" - fields_desc = [ByteEnumField("ietype", 71, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - gtp.APNStrLenField("APN", "internet", - length_from=lambda x: x.length)] - - -class IE_AMBR(gtp.IE_Base): - name = "IE AMBR" - fields_desc = [ByteEnumField("ietype", 72, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - IntField("AMBR_Uplink", 0), - IntField("AMBR_Downlink", 0)] - - -class IE_MSISDN(gtp.IE_Base): - name = "IE MSISDN" - fields_desc = [ByteEnumField("ietype", 76, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - gtp.TBCDByteField("digits", "33123456789", - length_from=lambda x: x.length)] - - -class IE_Indication(gtp.IE_Base): - name = "IE Cause" - fields_desc = [ByteEnumField("ietype", 77, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - BitField("DAF", 0, 1), - BitField("DTF", 0, 1), - BitField("HI", 0, 1), - BitField("DFI", 0, 1), - BitField("OI", 0, 1), - BitField("ISRSI", 0, 1), - BitField("ISRAI", 0, 1), - BitField("SGWCI", 0, 1), - BitField("SQCI", 0, 1), - BitField("UIMSI", 0, 1), - BitField("CFSI", 0, 1), - BitField("CRSI", 0, 1), - BitField("PS", 0, 1), - BitField("PT", 0, 1), - BitField("SI", 0, 1), - BitField("MSV", 0, 1), - - ConditionalField( - BitField("RetLoc", 0, 1), lambda pkt: pkt.length > 2), - ConditionalField( - BitField("PBIC", 0, 1), lambda pkt: pkt.length > 2), - ConditionalField( - BitField("SRNI", 0, 1), lambda pkt: pkt.length > 2), - ConditionalField( - BitField("S6AF", 0, 1), lambda pkt: pkt.length > 2), - ConditionalField( - BitField("S4AF", 0, 1), lambda pkt: pkt.length > 2), - ConditionalField( - BitField("MBMDT", 0, 1), lambda pkt: pkt.length > 2), - ConditionalField( - BitField("ISRAU", 0, 1), lambda pkt: pkt.length > 2), - ConditionalField( - BitField("CCRSI", 0, 1), lambda pkt: pkt.length > 2), - - ConditionalField( - BitField("CPRAI", 0, 1), lambda pkt: pkt.length > 3), - ConditionalField( - BitField("ARRL", 0, 1), lambda pkt: pkt.length > 3), - ConditionalField( - BitField("PPOFF", 0, 1), lambda pkt: pkt.length > 3), - ConditionalField( - BitField("PPON", 0, 1), lambda pkt: pkt.length > 3), - ConditionalField( - BitField("PPSI", 0, 1), lambda pkt: pkt.length > 3), - ConditionalField( - BitField("CSFBI", 0, 1), lambda pkt: pkt.length > 3), - ConditionalField( - BitField("CLII", 0, 1), lambda pkt: pkt.length > 3), - ConditionalField( - BitField("CPSR", 0, 1), lambda pkt: pkt.length > 3), - - ] - - -PDN_TYPES = { - 1: "IPv4", - 2: "IPv6", - 3: "IPv4/IPv6", -} - -PCO_OPTION_TYPES = { - 3: "IPv4", - 129: "Primary DNS Server IP address", - 130: "Primary NBNS Server IP address", - 131: "Secondary DNS Server IP address", - 132: "Secondary NBNS Server IP address", -} - - -class PCO_Option(Packet): - def extract_padding(self, pkt): - return "", pkt - - -class PCO_IPv4(PCO_Option): - name = "IPv4" - fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES), - ByteField("length", 0), - IPField("address", RandIP())] - - -class PCO_Primary_DNS(PCO_Option): - name = "Primary DNS Server IP Address" - fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES), - ByteField("length", 0), - IPField("address", RandIP())] - - -class PCO_Primary_NBNS(PCO_Option): - name = "Primary DNS Server IP Address" - fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES), - ByteField("length", 0), - IPField("address", RandIP())] - - -class PCO_Secondary_DNS(PCO_Option): - name = "Secondary DNS Server IP Address" - fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES), - ByteField("length", 0), - IPField("address", RandIP())] - - -class PCO_Secondary_NBNS(PCO_Option): - name = "Secondary NBNS Server IP Address" - fields_desc = [ByteEnumField("type", None, PCO_OPTION_TYPES), - ByteField("length", 0), - IPField("address", RandIP())] - - -PCO_PROTOCOL_TYPES = { - 0x0001: 'P-CSCF IPv6 Address Request', - 0x0003: 'DNS Server IPv6 Address Request', - 0x0005: 'MS Support of Network Requested Bearer Control indicator', - 0x000a: 'IP Allocation via NAS', - 0x000d: 'DNS Server IPv4 Address Request', - 0x000c: 'P-CSCF IPv4 Address Request', - 0x0010: 'IPv4 Link MTU Request', - 0x8021: 'IPCP', - 0xc023: 'Password Authentication Protocol', - 0xc223: 'Challenge Handshake Authentication Protocol', -} - -PCO_OPTION_CLASSES = { - 3: PCO_IPv4, - 129: PCO_Primary_DNS, - 130: PCO_Primary_NBNS, - 131: PCO_Secondary_DNS, - 132: PCO_Secondary_NBNS, -} - - -def PCO_option_dispatcher(s): - """Choose the correct PCO element.""" - option = orb(s[0]) - - cls = PCO_OPTION_CLASSES.get(option, Raw) - return cls(s) - - -def len_options(pkt): - return pkt.length - 4 if pkt.length else 0 - - -class PCO_P_CSCF_IPv6_Address_Request(PCO_Option): - name = "PCO PCO-P CSCF IPv6 Address Request" - fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES), - ByteField("length", 0), - ConditionalField(XBitField("address", - "2001:db8:0:42::", 128), - lambda pkt: pkt.length)] - - -class PCO_DNS_Server_IPv6(PCO_Option): - name = "PCO DNS Server IPv6 Address Request" - fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES), - ByteField("length", 0), - ConditionalField(XBitField("address", - "2001:db8:0:42::", 128), - lambda pkt: pkt.length)] - - -class PCO_SOF(PCO_Option): - name = "PCO MS Support of Network Requested Bearer Control indicator" - fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES), - ByteField("length", 0), - ] - - -class PCO_PPP(PCO_Option): - name = "PPP IP Control Protocol" - fields_desc = [ByteField("Code", 0), - ByteField("Identifier", 0), - ShortField("length", 0), - PacketListField("Options", None, PCO_option_dispatcher, - length_from=len_options)] - - def extract_padding(self, pkt): - return "", pkt - - -class PCO_IP_Allocation_via_NAS(PCO_Option): - name = "PCO IP Address allocation via NAS Signaling" - fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES), - ByteField("length", 0), - PacketListField("Options", None, PCO_option_dispatcher, - length_from=len_options)] - - -class PCO_P_CSCF_IPv4_Address_Request(PCO_Option): - name = "PCO PCO-P CSCF IPv4 Address Request" - fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES), - ByteField("length", 0), - ConditionalField(IPField("address", RandIP()), - lambda pkt: pkt.length)] - - -class PCO_DNS_Server_IPv4(PCO_Option): - name = "PCO DNS Server IPv4 Address Request" - fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES), - ByteField("length", 0), - ConditionalField(IPField("address", RandIP()), - lambda pkt: pkt.length)] - - -class PCO_IPv4_Link_MTU_Request(PCO_Option): - name = "PCO IPv4 Link MTU Request" - fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES), - ByteField("length", 0), - ConditionalField(ShortField("MTU_size", 1500), - lambda pkt: pkt.length)] - - -class PCO_IPCP(PCO_Option): - name = "PCO Internet Protocol Control Protocol" - fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES), - ByteField("length", 0), - PacketField("PPP", None, PCO_PPP)] - - -class PCO_PPP_Auth(PCO_Option): - name = "PPP Password Authentication Protocol" - fields_desc = [ByteField("Code", 0), - ByteField("Identifier", 0), - ShortField("length", 0), - ByteField("PeerID_length", 0), - ConditionalField(StrFixedLenField( - "PeerID", - "", - length_from=lambda pkt: pkt.PeerID_length), - lambda pkt: pkt.PeerID_length), - ByteField("Password_length", 0), - ConditionalField( - StrFixedLenField( - "Password", - "", - length_from=lambda pkt: pkt.Password_length), - lambda pkt: pkt.Password_length)] - - -class PCO_PasswordAuthentificationProtocol(PCO_Option): - name = "PCO Password Authentication Protocol" - fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES), - ByteField("length", 0), - PacketField("PPP", None, PCO_PPP_Auth)] - - -class PCO_PPP_Challenge(PCO_Option): - name = "PPP Password Authentication Protocol" - fields_desc = [ByteField("Code", 0), - ByteField("Identifier", 0), - ShortField("length", 0), - ByteField("value_size", 0), - ConditionalField(StrFixedLenField( - "value", "", - length_from=lambda pkt: pkt.value_size), - lambda pkt: pkt.value_size), - ConditionalField(StrFixedLenField( - "name", "", - length_from=lambda pkt: pkt.length - pkt.value_size - 5), # noqa: E501 - lambda pkt: pkt.length)] - - -class PCO_ChallengeHandshakeAuthenticationProtocol(PCO_Option): - name = "PCO Password Authentication Protocol" - fields_desc = [ShortEnumField("type", None, PCO_PROTOCOL_TYPES), - ByteField("length", 0), - PacketField("PPP", None, PCO_PPP_Challenge)] - - -PCO_PROTOCOL_CLASSES = { - 0x0001: PCO_P_CSCF_IPv6_Address_Request, - 0x0003: PCO_DNS_Server_IPv6, - 0x0005: PCO_SOF, - 0x000a: PCO_IP_Allocation_via_NAS, - 0x000c: PCO_P_CSCF_IPv4_Address_Request, - 0x000d: PCO_DNS_Server_IPv4, - 0x0010: PCO_IPv4_Link_MTU_Request, - 0x8021: PCO_IPCP, - 0xc023: PCO_PasswordAuthentificationProtocol, - 0xc223: PCO_ChallengeHandshakeAuthenticationProtocol, -} - - -def PCO_protocol_dispatcher(s): - """Choose the correct PCO element.""" - proto_num = orb(s[0]) * 256 + orb(s[1]) - cls = PCO_PROTOCOL_CLASSES.get(proto_num, Raw) - return cls(s) - - -class IE_PCO(gtp.IE_Base): - name = "IE Protocol Configuration Options" - fields_desc = [ByteEnumField("ietype", 78, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - BitField("Extension", 0, 1), - BitField("SPARE", 0, 4), - BitField("PPP", 0, 3), - PacketListField("Protocols", None, PCO_protocol_dispatcher, - length_from=lambda pkt: pkt.length - 1)] - - -class IE_PAA(gtp.IE_Base): - name = "IE PAA" - fields_desc = [ByteEnumField("ietype", 79, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - BitField("SPARE", 0, 5), - BitEnumField("PDN_type", None, 3, PDN_TYPES), - ConditionalField( - ByteField("ipv6_prefix_length", 8), - lambda pkt: pkt.PDN_type in (2, 3)), - ConditionalField( - XBitField("ipv6", "2001:db8:0:42::", 128), - lambda pkt: pkt.PDN_type in (2, 3)), - ConditionalField( - IPField("ipv4", 0), lambda pkt: pkt.PDN_type in (1, 3)), - ] - - -class IE_Bearer_QoS(gtp.IE_Base): - name = "IE Bearer Quality of Service" - fields_desc = [ByteEnumField("ietype", 80, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - BitField("SPARE", 0, 1), - BitField("PCI", 0, 1), - BitField("PriorityLevel", 0, 4), - BitField("SPARE", 0, 1), - BitField("PVI", 0, 1), - ByteField("QCI", 0), - BitField("MaxBitRateForUplink", 0, 40), - BitField("MaxBitRateForDownlink", 0, 40), - BitField("GuaranteedBitRateForUplink", 0, 40), - BitField("GuaranteedBitRateForDownlink", 0, 40)] - - -class IE_ChargingID(gtp.IE_Base): - name = "IE Charging ID" - fields_desc = [ByteEnumField("ietype", 94, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - IntField("ChargingID", 0)] - - -class IE_ChargingCharacteristics(gtp.IE_Base): - name = "IE Charging ID" - fields_desc = [ByteEnumField("ietype", 95, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - XShortField("ChargingCharacteristric", 0)] - - -class IE_PDN_type(gtp.IE_Base): - name = "IE PDN Type" - fields_desc = [ByteEnumField("ietype", 99, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - BitField("SPARE", 0, 5), - BitEnumField("PDN_type", None, 3, PDN_TYPES)] - - -class IE_UE_Timezone(gtp.IE_Base): - name = "IE UE Time zone" - fields_desc = [ByteEnumField("ietype", 114, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - ByteField("Timezone", 0), - ByteField("DST", 0)] - - -class IE_Port_Number(gtp.IE_Base): - name = "IE Port Number" - fields_desc = [ByteEnumField("ietype", 126, IEType), - ShortField("length", 2), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - ShortField("PortNumber", RandShort())] - - -class IE_APN_Restriction(gtp.IE_Base): - name = "IE APN Restriction" - fields_desc = [ByteEnumField("ietype", 127, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - ByteField("APN_Restriction", 0)] - - -class IE_SelectionMode(gtp.IE_Base): - name = "IE Selection Mode" - fields_desc = [ByteEnumField("ietype", 128, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - BitField("SPARE", 0, 6), - BitField("SelectionMode", 0, 2)] - - -class IE_MMBR(gtp.IE_Base): - name = "IE Max MBR/APN-AMBR (MMBR)" - fields_desc = [ByteEnumField("ietype", 72, IEType), - ShortField("length", None), - BitField("CR_flag", 0, 4), - BitField("instance", 0, 4), - IntField("uplink_rate", 0), - IntField("downlink_rate", 0)] - - -ietypecls = {1: IE_IMSI, - 2: IE_Cause, - 3: IE_RecoveryRestart, - 71: IE_APN, - 72: IE_AMBR, - 73: IE_EPSBearerID, - 74: IE_IPv4, - 75: IE_MEI, - 76: IE_MSISDN, - 77: IE_Indication, - 78: IE_PCO, - 79: IE_PAA, - 80: IE_Bearer_QoS, - 82: IE_RAT, - 83: IE_ServingNetwork, - 86: IE_ULI, - 87: IE_FTEID, - 93: IE_BearerContext, - 94: IE_ChargingID, - 95: IE_ChargingCharacteristics, - 99: IE_PDN_type, - 114: IE_UE_Timezone, - 126: IE_Port_Number, - 127: IE_APN_Restriction, - 128: IE_SelectionMode, - 161: IE_MMBR} - -# -# GTPv2 Commands -# 3GPP TS 29.060 V9.1.0 (2009-12) -# - - -class GTPV2Command(Packet): - fields_desc = [PacketListField("IE_list", None, IE_Dispatcher)] - - -class GTPV2EchoRequest(GTPV2Command): - name = "GTPv2 Echo Request" - - -class GTPV2EchoResponse(GTPV2Command): - name = "GTPv2 Echo Response" - - -class GTPV2CreateSessionRequest(GTPV2Command): - name = "GTPv2 Create Session Request" - - -class GTPV2CreateSessionResponse(GTPV2Command): - name = "GTPv2 Create Session Response" - - -class GTPV2DeleteSessionRequest(GTPV2Command): - name = "GTPv2 Delete Session Request" - - -class GTPV2DeleteSessionResponse(GTPV2Command): - name = "GTPv2 Delete Session Request" - - -class GTPV2ModifyBearerCommand(GTPV2Command): - name = "GTPv2 Modify Bearer Command" - - -class GTPV2ModifyBearerFailureNotification(GTPV2Command): - name = "GTPv2 Modify Bearer Command" - - -class GTPV2DownlinkDataNotifFailureIndication(GTPV2Command): - name = "GTPv2 Downlink Data Notification Failure Indication" - - -class GTPV2ModifyBearerRequest(GTPV2Command): - name = "GTPv2 Modify Bearer Request" - - -class GTPV2ModifyBearerResponse(GTPV2Command): - name = "GTPv2 Modify Bearer Response" - - -class GTPV2UpdateBearerRequest(GTPV2Command): - name = "GTPv2 Update Bearer Request" - - -class GTPV2UpdateBearerResponse(GTPV2Command): - name = "GTPv2 Update Bearer Response" - - -class GTPV2DeleteBearerRequest(GTPV2Command): - name = "GTPv2 Delete Bearer Request" - - -class GTPV2SuspendNotification(GTPV2Command): - name = "GTPv2 Suspend Notification" - - -class GTPV2SuspendAcknowledge(GTPV2Command): - name = "GTPv2 Suspend Acknowledge" - - -class GTPV2ResumeNotification(GTPV2Command): - name = "GTPv2 Resume Notification" - - -class GTPV2ResumeAcknowledge(GTPV2Command): - name = "GTPv2 Resume Acknowledge" - - -class GTPV2DeleteBearerResponse(GTPV2Command): - name = "GTPv2 Delete Bearer Response" - - -class GTPV2CreateIndirectDataForwardingTunnelRequest(GTPV2Command): - name = "GTPv2 Create Indirect Data Forwarding Tunnel Request" - - -class GTPV2CreateIndirectDataForwardingTunnelResponse(GTPV2Command): - name = "GTPv2 Create Indirect Data Forwarding Tunnel Response" - - -class GTPV2DeleteIndirectDataForwardingTunnelRequest(GTPV2Command): - name = "GTPv2 Delete Indirect Data Forwarding Tunnel Request" - - -class GTPV2DeleteIndirectDataForwardingTunnelResponse(GTPV2Command): - name = "GTPv2 Delete Indirect Data Forwarding Tunnel Response" - - -class GTPV2ReleaseBearerRequest(GTPV2Command): - name = "GTPv2 Release Bearer Request" - - -class GTPV2ReleaseBearerResponse(GTPV2Command): - name = "GTPv2 Release Bearer Response" - - -class GTPV2DownlinkDataNotif(GTPV2Command): - name = "GTPv2 Download Data Notification" - - -class GTPV2DownlinkDataNotifAck(GTPV2Command): - name = "GTPv2 Download Data Notification Acknowledgment" - - -bind_layers(GTPHeader, GTPV2EchoRequest, gtp_type=1, T=0) -bind_layers(GTPHeader, GTPV2EchoResponse, gtp_type=2, T=0) -bind_layers(GTPHeader, GTPV2CreateSessionRequest, gtp_type=32) -bind_layers(GTPHeader, GTPV2CreateSessionResponse, gtp_type=33) -bind_layers(GTPHeader, GTPV2ModifyBearerRequest, gtp_type=34) -bind_layers(GTPHeader, GTPV2ModifyBearerResponse, gtp_type=35) -bind_layers(GTPHeader, GTPV2DeleteSessionRequest, gtp_type=36) -bind_layers(GTPHeader, GTPV2DeleteSessionResponse, gtp_type=37) -bind_layers(GTPHeader, GTPV2ModifyBearerCommand, gtp_type=64) -bind_layers(GTPHeader, GTPV2ModifyBearerFailureNotification, gtp_type=65) -bind_layers(GTPHeader, GTPV2DownlinkDataNotifFailureIndication, gtp_type=70) -bind_layers(GTPHeader, GTPV2UpdateBearerRequest, gtp_type=97) -bind_layers(GTPHeader, GTPV2UpdateBearerResponse, gtp_type=98) -bind_layers(GTPHeader, GTPV2DeleteBearerRequest, gtp_type=99) -bind_layers(GTPHeader, GTPV2DeleteBearerResponse, gtp_type=100) -bind_layers(GTPHeader, GTPV2SuspendNotification, gtp_type=162) -bind_layers(GTPHeader, GTPV2SuspendAcknowledge, gtp_type=163) -bind_layers(GTPHeader, GTPV2ResumeNotification, gtp_type=164) -bind_layers(GTPHeader, GTPV2ResumeAcknowledge, gtp_type=165) -bind_layers( - GTPHeader, GTPV2CreateIndirectDataForwardingTunnelRequest, gtp_type=166) -bind_layers( - GTPHeader, GTPV2CreateIndirectDataForwardingTunnelResponse, gtp_type=167) -bind_layers( - GTPHeader, GTPV2DeleteIndirectDataForwardingTunnelRequest, gtp_type=168) -bind_layers( - GTPHeader, GTPV2DeleteIndirectDataForwardingTunnelResponse, gtp_type=169) -bind_layers(GTPHeader, GTPV2ReleaseBearerRequest, gtp_type=170) -bind_layers(GTPHeader, GTPV2ReleaseBearerResponse, gtp_type=171) -bind_layers(GTPHeader, GTPV2DownlinkDataNotif, gtp_type=176) -bind_layers(GTPHeader, GTPV2DownlinkDataNotifAck, gtp_type=177) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/homeplugav.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/homeplugav.py deleted file mode 100644 index d7c5782693..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/homeplugav.py +++ /dev/null @@ -1,1333 +0,0 @@ -#! /usr/bin/env python - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = HomePlugAV Layer -# scapy.contrib.status = loads - -from __future__ import absolute_import -import struct - -from scapy.packet import Packet, bind_layers -from scapy.fields import BitField, ByteEnumField, ByteField, \ - ConditionalField, EnumField, FieldLenField, IntField, LEIntField, \ - LELongField, LEShortField, MACField, PacketListField, ShortField, \ - StrFixedLenField, StrLenField, X3BytesField, XByteField, XIntField, \ - XLongField, XShortField -from scapy.layers.l2 import Ether -from scapy.modules.six.moves import range - -""" - Copyright (C) HomePlugAV Layer for Scapy by FlUxIuS (Sebastien Dudek) -""" - -""" - HomePlugAV Management Message Type - Key (type value) : Description -""" -HPAVTypeList = {0xA000: "'Get Device/sw version Request'", - 0xA001: "'Get Device/sw version Confirmation'", - 0xA008: "'Read MAC Memory Request'", - 0xA009: "'Read MAC Memory Confirmation'", - 0xA00C: "'Start MAC Request'", - 0xA00D: "'Start MAC Confirmation'", - 0xA010: "'Get NVM Parameters Request'", - 0xA011: "'Get NVM Parameters Confirmation'", - 0xA01C: "'Reset Device Request'", - 0xA01D: "'Reset Device Confirmation'", - 0xA020: "'Write Module Data Request'", - 0xA024: "'Read Module Data Request'", - 0xA025: "'Read Module Data Confirmation'", - 0xA028: "'Write Module Data to NVM Request'", - 0xA029: "'Write Module Data to NVM Confirmation'", - 0xA034: "'Sniffer Request'", - 0xA035: "'Sniffer Confirmation'", - 0xA036: "'Sniffer Indicates'", - 0xA038: "'Network Information Request'", - 0xA039: "'Network Information Confirmation'", - 0xA048: "'Loopback Request'", - 0xA049: "'Loopback Request Confirmation'", - 0xA050: "'Set Encryption Key Request'", - 0xA051: "'Set Encryption Key Request Confirmation'", - 0xA058: "'Read Configuration Block Request'", - 0xA059: "'Read Configuration Block Confirmation'", - 0xA062: "'Embedded Host Action Required Indication'"} - -HPAVversionList = {0x00: "1.0", - 0x01: "1.1"} - -HPAVDeviceIDList = {0x00: "Unknown", - 0x01: "'INT6000'", - 0x02: "'INT6300'", - 0x03: "'INT6400'", - 0x04: "'AR7400'", - 0x05: "'AR6405'", - 0x20: "'QCA7450/QCA7420'", - 0x21: "'QCA6410/QCA6411'", - 0x22: "'QCA7000'"} - -StationRole = {0x00: "'Station'", - 0x01: "'Proxy coordinator'", - 0x02: "'Central coordinator'"} - -StatusCodes = {0x00: "'Success'", - 0x10: "'Invalid Address'", - 0x14: "'Invalid Length'"} - -DefaultVendor = "Qualcomm" - -######################################################################### -# Qualcomm Vendor Specific Management Message Types; # -# from https://github.com/qca/open-plc-utils/blob/master/mme/qualcomm.h # -######################################################################### -# Commented commands are already in HPAVTypeList, the other have to be implemted # noqa: E501 -QualcommTypeList = { # 0xA000 : "VS_SW_VER", - 0xA004: "VS_WR_MEM", - # 0xA008 : "VS_RD_MEM", - # 0xA00C : "VS_ST_MAC", - # 0xA010 : "VS_GET_NVM", - 0xA014: "VS_RSVD_1", - 0xA018: "VS_RSVD_2", - # 0xA01C : "VS_RS_DEV", - # 0xA020 : "VS_WR_MOD", - # 0xA024 : "VS_RD_MOD", - # 0xA028 : "VS_MOD_NVM", - 0xA02C: "VS_WD_RPT", - 0xA030: "VS_LNK_STATS", - # 0xA034 : "VS_SNIFFER", - # 0xA038 : "VS_NW_INFO", - 0xA03C: "VS_RSVD_3", - 0xA040: "VS_CP_RPT", - 0xA044: "VS_ARPC", - # 0xA050 : "VS_SET_KEY", - 0xA054: "VS_MFG_STRING", - # 0xA058 : "VS_RD_CBLOCK", - 0xA05C: "VS_SET_SDRAM", - 0xA060: "VS_HOST_ACTION", - 0xA068: "VS_OP_ATTRIBUTES", - 0xA06C: "VS_ENET_SETTINGS", - 0xA070: "VS_TONE_MAP_CHAR", - 0xA074: "VS_NW_INFO_STATS", - 0xA078: "VS_SLAVE_MEM", - 0xA07C: "VS_FAC_DEFAULTS", - 0xA07D: "VS_FAC_DEFAULTS_CONFIRM", - 0xA084: "VS_MULTICAST_INFO", - 0xA088: "VS_CLASSIFICATION", - 0xA090: "VS_RX_TONE_MAP_CHAR", - 0xA094: "VS_SET_LED_BEHAVIOR", - 0xA098: "VS_WRITE_AND_EXECUTE_APPLET", - 0xA09C: "VS_MDIO_COMMAND", - 0xA0A0: "VS_SLAVE_REG", - 0xA0A4: "VS_BANDWIDTH_LIMITING", - 0xA0A8: "VS_SNID_OPERATION", - 0xA0AC: "VS_NN_MITIGATE", - 0xA0B0: "VS_MODULE_OPERATION", - 0xA0B4: "VS_DIAG_NETWORK_PROBE", - 0xA0B8: "VS_PL_LINK_STATUS", - 0xA0BC: "VS_GPIO_STATE_CHANGE", - 0xA0C0: "VS_CONN_ADD", - 0xA0C4: "VS_CONN_MOD", - 0xA0C8: "VS_CONN_REL", - 0xA0CC: "VS_CONN_INFO", - 0xA0D0: "VS_MULTIPORT_LNK_STA", - 0xA0DC: "VS_EM_ID_TABLE", - 0xA0E0: "VS_STANDBY", - 0xA0E4: "VS_SLEEPSCHEDULE", - 0xA0E8: "VS_SLEEPSCHEDULE_NOTIFICATION", - 0xA0F0: "VS_MICROCONTROLLER_DIAG", - 0xA0F8: "VS_GET_PROPERTY", - 0xA100: "VS_SET_PROPERTY", - 0xA104: "VS_PHYSWITCH_MDIO", - 0xA10C: "VS_SELFTEST_ONETIME_CONFIG", - 0xA110: "VS_SELFTEST_RESULTS", - 0xA114: "VS_MDU_TRAFFIC_STATS", - 0xA118: "VS_FORWARD_CONFIG", - 0xA200: "VS_HYBRID_INFO"} -# END OF Qualcomm commands # - -EofPadList = [0xA000, 0xA038] # TODO: The complete list of Padding can help to improve the condition in VendorMME Class # noqa: E501 - - -def FragmentCond(pkt): - """ - A fragmentation field condition - TODO: To complete - """ - fragTypeTable = [0xA038, 0xA039] - return ((pkt.version == 0x01) and (pkt.HPtype in fragTypeTable)) - - -class MACManagementHeader(Packet): - name = "MACManagementHeader " - if DefaultVendor == "Qualcomm": - HPAVTypeList.update(QualcommTypeList) - fields_desc = [ByteEnumField("version", 0, HPAVversionList), - EnumField("HPtype", 0xA000, HPAVTypeList, " have fun! - """ - name = "NetworkInfoConfirmation" - fields_desc = [StrFixedLenField("reserved_n1", b"\x00\x00\x3a\x00\x00", 5), - XByteField("LogicalNetworksNumber", 0x01), - PacketListField("NetworksInfos", "", NetworkInfoV11, length_from=lambda pkt: pkt.LogicalNetworksNumber * 26), # noqa: E501 - XByteField("StationsNumber", 0x01), - StrFixedLenField("reserverd_s1", b"\x00\x00\x00\x00\x00", 5), # noqa: E501 - PacketListField("StationsInfos", "", StationInfoV11, length_from=lambda pkt: pkt.StationsNumber * 23)] # noqa: E501 - - -# Description of Embedded Host Action Required Indice -ActionsList = {0x02: "'PIB Update Ready'", - 0x04: "'Loader (Bootloader)'"} - - -class HostActionRequired(Packet): - """ - Embedded Host Action Required Indice - """ - name = "HostActionRequired" - fields_desc = [ByteEnumField("ActionRequired", 0x02, ActionsList)] - - -class LoopbackRequest(Packet): - name = "LoopbackRequest" - fields_desc = [ByteField("Duration", 0x01), - ByteField("reserved_l1", 0x01), - ShortField("LRlength", 0x0000)] - # TODO: Test all possibles data to complete it - - -class LoopbackConfirmation(Packet): - name = "LoopbackConfirmation" - fields_desc = [ByteEnumField("Status", 0x0, StatusCodes), - ByteField("Duration", 0x01), - ShortField("LRlength", 0x0000)] - -################################################################ -# Encryption Key Packets -################################################################ - - -class SetEncryptionKeyRequest(Packet): - name = "SetEncryptionKeyRequest" - fields_desc = [XByteField("EKS", 0x00), - StrFixedLenField("NMK", - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # noqa: E501 - 16), - XByteField("PayloadEncKeySelect", 0x00), - MACField("DestinationMAC", "ff:ff:ff:ff:ff:ff"), - StrFixedLenField("DAK", - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # noqa: E501 - 16)] - - -SetEncKey_Status = {0x00: "Success", - 0x10: "Invalid EKS", - 0x11: "Invalid PKS"} - - -class SetEncryptionKeyConfirmation(Packet): - name = "SetEncryptionKeyConfirmation" - fields_desc = [ByteEnumField("Status", 0x0, SetEncKey_Status)] - -################################################################ -# Default config Packet -################################################################ - - -class QUAResetFactoryConfirm(Packet): - name = "QUAResetFactoryConfirm" - fields_desc = [ByteEnumField("Status", 0x0, StatusCodes)] # TODO : Probably a Status bytefield? # noqa: E501 - -###################################################################### -# NVM Parameters Packets -###################################################################### - - -class GetNVMParametersRequest(Packet): - name = "Get NVM Parameters Request" - fields_desc = [] - - -class GetNVMParametersConfirmation(Packet): - name = "Get NVM Parameters Confirmation" - fields_desc = [ByteEnumField("Status", 0x0, StatusCodes), - LEIntField("NVMType", 0x00000013), - LEIntField("NVMPageSize", 0x00000100), - LEIntField("NVMBlockSize", 0x00010000), - LEIntField("NVMMemorySize", 0x00100000)] - -###################################################################### -# Sniffer Packets -###################################################################### - - -SnifferControlList = {0x0: "'Disabled'", - 0x1: "'Enabled'"} - -SnifferTypeCodes = {0x00: "'Regular'"} - - -class SnifferRequest(Packet): - name = "SnifferRequest" - fields_desc = [ByteEnumField("SnifferControl", 0x0, SnifferControlList)] - - -SnifferCodes = {0x00: "'Success'", - 0x10: "'Invalid Control'"} - - -class SnifferConfirmation(Packet): - name = "SnifferConfirmation" - fields_desc = [ByteEnumField("Status", 0x0, StatusCodes)] - - -DirectionCodes = {0x00: "'Tx'", - 0x01: "'Rx'"} - -ANCodes = {0x00: "'In-home'", - 0x01: "'Access'"} - - -class SnifferIndicate(Packet): - # TODO: Some bitfield have been regrouped for the moment => need more work on it # noqa: E501 - name = "SnifferIndicate" - fields_desc = [ByteEnumField("SnifferType", 0x0, SnifferTypeCodes), - ByteEnumField("Direction", 0x0, DirectionCodes), - LELongField("SystemTime", 0x0), - LEIntField("BeaconTime", 0x0), - XByteField("ShortNetworkID", 0x0), - ByteField("SourceTermEqID", 0), - ByteField("DestTermEqID", 0), - ByteField("LinkID", 0), - XByteField("PayloadEncrKeySelect", 0x0f), - ByteField("PendingPHYblock", 0), - ByteField("BitLoadingEstim", 0), - BitField("ToneMapIndex", 0, size=5), - BitField("NumberofSymbols", 0, size=2), - BitField("PHYblockSize", 0, size=1), - XShortField("FrameLength", 0x0000), - XByteField("ReversegrandLength", 0x0), - BitField("RequestSACKtrans", 0, size=1), - BitField("DataMACstreamCMD", 0, size=3), - BitField("ManNACFrameStreamCMD", 0, size=3), - BitField("reserved_1", 0, size=6), - BitField("MultinetBroadcast", 0, size=1), - BitField("DifferentCPPHYclock", 0, size=1), - BitField("Multicast", 0, size=1), - X3BytesField("FrameControlCheckSeq", 0x000000), - XByteField("ShortNetworkID_", 0x0), - IntField("BeaconTimestamp", 0), - XShortField("BeaconTransOffset_0", 0x0000), - XShortField("BeaconTransOffset_1", 0x0000), - XShortField("BeaconTransOffset_2", 0x0000), - XShortField("BeaconTransOffset_3", 0x0000), - X3BytesField("FrameContrchkSeq", 0x000000)] - -###################################################################### -# Read MAC Memory -##################################################################### - - -class ReadMACMemoryRequest(Packet): - name = "ReadMACMemoryRequest" - fields_desc = [LEIntField("Address", 0x00000000), - LEIntField("Length", 0x00000400), - ] - - -ReadMACStatus = {0x00: "Success", - 0x10: "Invalid Address", - 0x14: "Invalid Length"} - - -class ReadMACMemoryConfirmation(Packet): - name = "ReadMACMemoryConfirmation" - - fields_desc = [ByteEnumField("Status", 0x00, ReadMACStatus), - LEIntField("Address", 0), - FieldLenField("MACLen", None, length_of="MACData", fmt="= pkt.__offset and 0x2 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("reserved_1", 0x0000), - lambda pkt:(0x2 >= pkt.__offset and 0x4 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("PIBLength", 0x0000), - lambda pkt:(0x4 >= pkt.__offset and 0x6 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("reserved_2", 0x0000), - lambda pkt:(0x6 >= pkt.__offset and 0x8 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("checksumPIB", None), - lambda pkt:(0x8 >= pkt.__offset and 0xC <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(MACField("PIBMACAddr", "00:00:00:00:00:00"), - lambda pkt:(0xC >= pkt.__offset and 0x12 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("DAK", - b"\x00" * 16, - 16), - lambda pkt:(0x12 >= pkt.__offset and 0x22 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("reserved_3", 0x0000), - lambda pkt:(0x22 >= pkt.__offset and 0x24 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("ManufactorID", - b"\x00" * 64, - 64), - lambda pkt:(0x24 >= pkt.__offset and 0x64 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("NMK", - b"\x00" * 16, - 16), - lambda pkt:(0x64 >= pkt.__offset and 0x74 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("UserID", - b"\x00" * 64, - 64), - lambda pkt:(0x74 >= pkt.__offset and 0xB4 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("AVLN_ID", - b"\x00" * 64, - 64), - lambda pkt:(0xB4 >= pkt.__offset and 0xF4 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("CCoSelection", 0x00), - lambda pkt:(0xF4 >= pkt.__offset and 0xF5 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("CoExistSelection", 0x00), - lambda pkt:(0xF5 >= pkt.__offset and 0xF6 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("PLFreqSelection", 0x00), - lambda pkt:(0xF6 >= pkt.__offset and 0xF7 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("H3CDowngradeShld", 0x00), - lambda pkt:(0xF7 >= pkt.__offset and 0xF8 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("PreferredNID", - b"\x00" * 7, - 7), - lambda pkt:(0xF8 >= pkt.__offset and 0xFF <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("AutoFWUpgradeable", 0x00), - lambda pkt:(0xFF >= pkt.__offset and 0x100 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("MDUConfiguration", 0x00), - lambda pkt:(0x100 >= pkt.__offset and 0x101 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("MDURole", 0x00), - lambda pkt:(0x101 >= pkt.__offset and 0x102 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("SnifferEnabled", 0x00), - lambda pkt:(0x102 >= pkt.__offset and 0x103 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(MACField("SnifferMACAddrRetrn", "00:00:00:00:00:00"), - lambda pkt:(0x103 >= pkt.__offset and 0x109 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("WireTapEnable", 0x00), - lambda pkt:(0x109 >= pkt.__offset and 0x10A <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("reserved_4", 0x0000), - lambda pkt:(0x10A >= pkt.__offset and 0x10C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("StaticNetworkEnabled", 0x00), - lambda pkt:(0x10C >= pkt.__offset and 0x10D <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("LD_TEI", 0x00), - lambda pkt:(0x10D >= pkt.__offset and 0x10E <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(MACField("CCo_MACAdd", "00:00:00:00:00:00"), - lambda pkt:(0x10E >= pkt.__offset and 0x114 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("SNID", 0x00), - lambda pkt:(0x114 >= pkt.__offset and 0x115 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("NumOfPeerNodes", 0x00), - lambda pkt:(0x115 >= pkt.__offset and 0x116 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(PacketListField("PeerNodes", "", PeerNode, length_from=lambda x: 56), # noqa: E501 - lambda pkt:(0x116 >= pkt.__offset and 0x11C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("reserved_5", - b"\x00" * 62, - 62), - lambda pkt:(0x146 >= pkt.__offset and 0x14e <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("OverideModeDefaults", 0x00), - lambda pkt:(0x18C >= pkt.__offset and 0x18D <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("DisableFlowControl", 0x00), - lambda pkt:(0x18D >= pkt.__offset and 0x18E <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("AdvertisementCapabilities", 0x00), - lambda pkt:(0x18E >= pkt.__offset and 0x18F <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("OverrideMeteringDefaults", 0x00), - lambda pkt:(0x18F >= pkt.__offset and 0x190 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("MaxFramesPerSec", 0), - lambda pkt:(0x190 >= pkt.__offset and 0x194 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("DisableAutoNegotiation", 0x00), - lambda pkt:(0x194 >= pkt.__offset and 0x195 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("EnetSpeedSetting", 0x00), - lambda pkt:(0x195 >= pkt.__offset and 0x196 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("EnetDuplexSetting", 0x00), - lambda pkt:(0x196 >= pkt.__offset and 0x197 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("DisableTxFlowControl", 0x00), - lambda pkt:(0x197 >= pkt.__offset and 0x198 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("DisableRxFlowControl", 0x00), - lambda pkt:(0x198 >= pkt.__offset and 0x199 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("PhyAddressSelection", 0x00), - lambda pkt:(0x199 >= pkt.__offset and 0x19A <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("PhyAddressSelection_Data", 0x00), - lambda pkt:(0x19A >= pkt.__offset and 0x19B <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("reserved_6", 0x00), - lambda pkt:(0x19B >= pkt.__offset and 0x19C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("Force33MHz", 0x00), - lambda pkt:(0x19C >= pkt.__offset and 0x19D <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("LinkStatusOnPowerline", 0x00), - lambda pkt:(0x19D >= pkt.__offset and 0x19E <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("OverrideIdDefaults", 0x00), - lambda pkt:(0x19E >= pkt.__offset and 0x19F <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("OverrideSubIdDefaults", 0x00), - lambda pkt:(0x19F >= pkt.__offset and 0x1A0 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("PCIDeviceID", 0x0000), - lambda pkt:(0x1A0 >= pkt.__offset and 0x1A2 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("PCIVendorID", 0x0000), - lambda pkt:(0x1A2 >= pkt.__offset and 0x1A4 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("reserved_7", 0x00), - lambda pkt:(0x1A4 >= pkt.__offset and 0x1A5 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("PCIClassCode", 0x00), - lambda pkt:(0x1A5 >= pkt.__offset and 0x1A6 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("PCIClassCodeSubClass", 0x00), - lambda pkt:(0x1A6 >= pkt.__offset and 0x1A7 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("PCIRevisionID", 0x00), - lambda pkt:(0x1A7 >= pkt.__offset and 0x1A8 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("PCISubsystemID", 0x0000), - lambda pkt:(0x1A8 >= pkt.__offset and 0x1AA <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("PCISybsystemVendorID", 0x0000), - lambda pkt:(0x1AA >= pkt.__offset and 0x1AC <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("reserved_8", - b"\x00" * 64, - 64), - lambda pkt:(0x1AC >= pkt.__offset and 0x1EC <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("OverrideIGMPDefaults", 0x00), - lambda pkt:(0x1EC >= pkt.__offset and 0x1ED <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("ConfigFlags", 0x00), - lambda pkt:(0x1ED >= pkt.__offset and 0x1EE <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("NumCpToSend_PLFrames", 0x00), - lambda pkt:(0x1EE >= pkt.__offset and 0x1EF <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("reserved_9", - b"\x00" * 29, - 29), - lambda pkt:(0x1EF >= pkt.__offset and 0x20C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("UniCastPriority", 0x00), - lambda pkt:(0x20C >= pkt.__offset and 0x20D <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("McastPriority", 0x00), - lambda pkt:(0x20D >= pkt.__offset and 0x20E <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("IGMPPriority", 0x00), - lambda pkt:(0x20E >= pkt.__offset and 0x20F <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("AVStreamPriority", 0x00), - lambda pkt:(0x20F >= pkt.__offset and 0x210 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("PriorityTTL_0", 0), - lambda pkt:(0x210 >= pkt.__offset and 0x214 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("PriorityTTL_1", 0), - lambda pkt:(0x214 >= pkt.__offset and 0x218 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("PriorityTTL_2", 0), - lambda pkt:(0x218 >= pkt.__offset and 0x21C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("PriorityTTL_3", 0), - lambda pkt:(0x21C >= pkt.__offset and 0x220 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("EnableVLANOver", 0x00), - lambda pkt:(0x220 >= pkt.__offset and 0x221 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("EnableTOSOver", 0x00), - lambda pkt:(0x221 >= pkt.__offset and 0x222 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("reserved_10", 0x0000), - lambda pkt:(0x222 >= pkt.__offset and 0x224 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("VLANPrioTOSPrecMatrix", 0), - lambda pkt:(0x224 >= pkt.__offset and 0x228 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("NumClassifierPriorityMaps", 0), - lambda pkt:(0x228 >= pkt.__offset and 0x22C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("NumAutoConnections", 0), - lambda pkt:(0x22C >= pkt.__offset and 0x230 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(PacketListField("ClassifierPriorityMaps", "", ClassifierPriorityMap, length_from=lambda x: 224), # noqa: E501 - lambda pkt:(0x230 >= pkt.__offset and 0x244 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(PacketListField("AutoConnections", "", AutoConnection, length_from=lambda x: 1600), # noqa: E501 - lambda pkt:(0x310 >= pkt.__offset and 0x36e <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("NumberOfConfigEntries", 0x00), - lambda pkt:(0x950 >= pkt.__offset and 0x951 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(PacketListField("AggregateConfigEntries", "", AggregateConfigEntrie, length_from=lambda x: 16), # noqa: E501 - lambda pkt:(0x951 >= pkt.__offset and 0x961 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(PacketListField("RSVD_CustomAggregationParameters", "", RSVD_CustomAggregationParameter, length_from=lambda x: 48), # noqa: E501 - lambda pkt:(0x961 >= pkt.__offset and 0x991 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("reserved_11", - b"\x00" * 123, - 123), - lambda pkt:(0x991 >= pkt.__offset and 0xA0C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("ToneMaskType", 0), - lambda pkt:(0xA0C >= pkt.__offset and 0xA10 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("ToneMaskEnabled", 0), - lambda pkt:(0xA10 >= pkt.__offset and 0xA14 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("StartTone", 0), - lambda pkt:(0xA14 >= pkt.__offset and 0xA18 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("EndTone", 0), - lambda pkt:(0xA18 >= pkt.__offset and 0xA1C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("reserved_12", - b"\x00" * 12, - 12), - lambda pkt:(0xA1C >= pkt.__offset and 0xA28 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("PsdIndex", 0), - lambda pkt:(0xA28 >= pkt.__offset and 0xA2C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("TxPrescalerType", 0), - lambda pkt:(0xA2C >= pkt.__offset and 0xA30 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(PacketListField("PrescalerValues", "", PrescalerValue, length_from=lambda x: 3600), # noqa: E501 - lambda pkt:(0xA30 >= pkt.__offset and 0xA34 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("reserved_13", - b"\x00" * 1484, - 1484), - lambda pkt:(0x1840 >= pkt.__offset and 0x1E0C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("AllowNEKRotation", 0), - lambda pkt:(0x1E0C >= pkt.__offset and 0x1E10 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("OverrideLocalNEK", 0), - lambda pkt:(0x1E10 >= pkt.__offset and 0x1E14 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("LocalNEKToUse", - b"\x00" * 16, - 16), - lambda pkt:(0x1E14 >= pkt.__offset and 0x1E24 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("OverrideNEKRotationTimer", 0), - lambda pkt:(0x1E24 >= pkt.__offset and 0x1E28 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("NEKRotationTime_Min", 0), - lambda pkt:(0x1E28 >= pkt.__offset and 0x1E2C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("reserved_14", - b"\x00" * 96, - 96), - lambda pkt:(0x1E2C >= pkt.__offset and 0x1E8C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("AVLNMembership", 0), - lambda pkt:(0x1E8C >= pkt.__offset and 0x1E90 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("SimpleConnectTimeout", 0), - lambda pkt:(0x1E90 >= pkt.__offset and 0x1E94 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("EnableLEDThroughputIndicate", 0), - lambda pkt:(0x1E94 >= pkt.__offset and 0x1E95 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("MidLEDThroughputThreshold_Mbps", 0), - lambda pkt:(0x1E95 >= pkt.__offset and 0x1E96 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("HighLEDThroughputThreshold_Mbps", 0), - lambda pkt:(0x1E96 >= pkt.__offset and 0x1E97 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("reserved_15", 0), - lambda pkt:(0x1E97 >= pkt.__offset and 0x1E98 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("EnableUnicastQuieriesToMember", 0), - lambda pkt:(0x1E98 >= pkt.__offset and 0x1E99 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("DisableMLDGroupIDCheckInMAC", 0), - lambda pkt:(0x1E99 >= pkt.__offset and 0x1E9A <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("EnableReportsToNonQuerierHosts", 0), - lambda pkt:(0x1E9A >= pkt.__offset and 0x1E9C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("DisableExpireGroupMembershipInterval", 0), - lambda pkt:(0x1E9C >= pkt.__offset and 0x1EA0 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("DisableLEDTestLights", 0), - lambda pkt:(0x1EA0 >= pkt.__offset and 0x1EA4 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(PacketListField("GPIOMaps", "", GPIOMap, length_from=lambda x: 12), # noqa: E501 - lambda pkt:(0x1EA4 >= pkt.__offset and 0x1EB0 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XLongField("reserved_16", 0), - lambda pkt:(0x1EB0 >= pkt.__offset and 0x1EB8 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("EnableTrafficClass_DSCPOver", 0), - lambda pkt:(0x1EB8 >= pkt.__offset and 0x1EB9 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("TrafficClass_DSCPMatrices", - b"\x00" * 64, - 64), - lambda pkt:(0x1EB9 >= pkt.__offset and 0x1EF9 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("GPIOControl", 0), - lambda pkt:(0x1EF9 >= pkt.__offset and 0x1EFA <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("LEDControl", - b"\x00" * 32, - 32), - lambda pkt:(0x1EFA >= pkt.__offset and 0x1F1A <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("OverrideMinButtonPressHoldTime", 0), - lambda pkt:(0x1F1A >= pkt.__offset and 0x1F1E <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("MinButtonPressHoldTime", 0), - lambda pkt:(0x1F1E >= pkt.__offset and 0x1F22 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("reserved_17", - b"\x00" * 22, - 22), - lambda pkt:(0x1F22 >= pkt.__offset and 0x1F38 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("MemoryProfile", 0), - lambda pkt:(0x1F38 >= pkt.__offset and 0x1F3C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("DisableAllLEDFlashOnWarmReboot", 0), - lambda pkt:(0x1F3C >= pkt.__offset and 0x1F40 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("UplinkLimit_bps", 0), - lambda pkt:(0x1F40 >= pkt.__offset and 0x1F44 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("DownlinkLimit_bps", 0), - lambda pkt:(0x1F44 >= pkt.__offset and 0x1F48 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("MDUStaticSNID", 0), - lambda pkt:(0x1F48 >= pkt.__offset and 0x1F4C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("MitigateEnabled", 0), - lambda pkt:(0x1F4C >= pkt.__offset and 0x1F4D <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("CorrelThreshold", 0), - lambda pkt:(0x1F4D >= pkt.__offset and 0x1F51 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("ScaledTxGain", 0), - lambda pkt:(0x1F51 >= pkt.__offset and 0x1F55 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("ResourceThresholdEnabled", 0), - lambda pkt:(0x1F55 >= pkt.__offset and 0x1F56 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(PacketListField("ReservedPercentageForCaps", "", ReservedPercentageForCap, length_from=lambda x: 4), # noqa: E501 - lambda pkt:(0x1F56 >= pkt.__offset and 0x1F5A <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("PowerSavingMode", 0), - lambda pkt:(0x1F5A >= pkt.__offset and 0x1F5B <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("PowerLEDDutyCycle", 0), - lambda pkt:(0x1F5B >= pkt.__offset and 0x1F5C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("reserved_18", 0), - lambda pkt:(0x1F5C >= pkt.__offset and 0x1F5E <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("LinkUpDurationBeforeReset_ms", 0), - lambda pkt:(0x1F5E >= pkt.__offset and 0x1F62 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("PowerLEDPeriod_ms", 0), - lambda pkt:(0x1F62 >= pkt.__offset and 0x1F66 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("LinkDownDurationBeforeLowPowerMode_ms", 0), # noqa: E501 - lambda pkt:(0x1F66 >= pkt.__offset and 0x1F6A <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("reserved_19", 0), - lambda pkt:(0x1F6A >= pkt.__offset and 0x1F6E <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("AfeGainBusMode", 0), - lambda pkt:(0x1F6E >= pkt.__offset and 0x1F6F <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("EnableDynamicPsd", 0), - lambda pkt:(0x1F6F >= pkt.__offset and 0x1F70 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("ReservedPercentageForTxStreams", 0), - lambda pkt:(0x1F70 >= pkt.__offset and 0x1F71 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("ReservedPercentageForRxStreams", 0), - lambda pkt:(0x1F71 >= pkt.__offset and 0x1F72 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("reserved_20", - b"\x00" * 22, - 22), - lambda pkt:(0x1F72 >= pkt.__offset and 0x1F88 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("LegacyNetworkUpgradeEnable", 0), - lambda pkt:(0x1F88 >= pkt.__offset and 0x1F8C <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("unknown", 0), - lambda pkt:(0x1F8C >= pkt.__offset and 0x1F90 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("MMETTL_us", 0), - lambda pkt:(0x1F90 >= pkt.__offset and 0x1F94 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(PacketListField("ConfigBits", "", ConfigBit, length_from=lambda x: 2), # noqa: E501 - lambda pkt:(0x1F94 >= pkt.__offset and 0x1F96 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("TxToneMapExpiry_ms", 0), - lambda pkt:(0x1F96 >= pkt.__offset and 0x1F9A <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("RxToneMapExpiry_ms", 0), - lambda pkt:(0x1F9A >= pkt.__offset and 0x1F9E <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("TimeoutToResound_ms", 0), - lambda pkt:(0x1F9E >= pkt.__offset and 0x1FA2 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("MissingSackThresholdForUnplugDetection", 0), # noqa: E501 - lambda pkt:(0x1FA2 >= pkt.__offset and 0x1FA6 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(LEIntField("UnplugTimeout_ms", 0), - lambda pkt:(0x1FA6 >= pkt.__offset and 0x1FAA <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(PacketListField("ContentionWindowTableES", "", ContentionWindowTable, length_from=lambda x: 8), # noqa: E501 - lambda pkt:(0x1FAA >= pkt.__offset and 0x1FB2 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(PacketListField("BackoffDeferalCountTableES", "", BackoffDeferalCountTable, length_from=lambda x: 4), # noqa: E501 - lambda pkt:(0x1FB2 >= pkt.__offset and 0x1FB6 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("GoodSoundCountThreshold", 0), - lambda pkt:(0x1FB6 >= pkt.__offset and 0x1FB7 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("SoundCountThreshold_GoodSoundCountPass", 0), # noqa: E501 - lambda pkt:(0x1FB7 >= pkt.__offset and 0x1FB8 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("SoundCountThreshold_GoodSoundCountFail", 0), # noqa: E501 - lambda pkt:(0x1FB8 >= pkt.__offset and 0x1FB9 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("reserved_21", 0), - lambda pkt:(0x1FB9 >= pkt.__offset and 0x1FBB <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("ExclusiveTxPbs_percentage", 0), - lambda pkt:(0x1FBB >= pkt.__offset and 0x1FBC <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("ExclusiveRxPbs_percentage", 0), - lambda pkt:(0x1FBC >= pkt.__offset and 0x1FBD <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("OptimizationBackwardCompatible", 0), - lambda pkt:(0x1FBD >= pkt.__offset and 0x1FBE <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("reserved_21", 0), - lambda pkt:(0x1FBE >= pkt.__offset and 0x1FBF <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("MaxPbsPerSymbol", 0), - lambda pkt:(0x1FBF >= pkt.__offset and 0x1FC0 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("MaxModulation", 0), - lambda pkt:(0x1FC0 >= pkt.__offset and 0x1FC1 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("ContinuousRx", 0), - lambda pkt:(0x1FC1 >= pkt.__offset and 0x1FC2 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("reserved_22", - b"\x00" * 6, - 6), - lambda pkt:(0x1FC2 >= pkt.__offset and 0x1FC8 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("PBControlStatus", 0), - lambda pkt:(0x1FC8 >= pkt.__offset and 0x1FC9 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("STAMembershipMaskEnabled", 0), - lambda pkt:(0x1FC9 >= pkt.__offset and 0x1FCA <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("ExitDefaultEnabled", 0), - lambda pkt:(0x1FCA >= pkt.__offset and 0x1FCB <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("RejectDefaultEnabled", 0), - lambda pkt:(0x1FCB >= pkt.__offset and 0x1FCC <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("ChainingEnabled", 0), - lambda pkt:(0x1FCC >= pkt.__offset and 0x1FCD <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("VendorSpecificNMK", - b"\x00" * 16, - 16), - lambda pkt:(0x1FCD >= pkt.__offset and 0x1FDD <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("LocalMACAddressLimit", 0), - lambda pkt:(0x1FDD >= pkt.__offset and 0x1FDE <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("OverrideBridgeTableAgingTime", 0), - lambda pkt:(0x1FDE >= pkt.__offset and 0x1FDF <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("LocalBridgeTableAgingTime_min", 0), - lambda pkt:(0x1FDF >= pkt.__offset and 0x1FE1 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XShortField("RemoteBridgeTableAgingTime_min", 0), - lambda pkt:(0x1FE1 >= pkt.__offset and 0x1FE3 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("PhySyncReference", 0), - lambda pkt:(0x1FE3 >= pkt.__offset and 0x1FE7 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("reserved_23", 0), - lambda pkt:(0x1FE7 >= pkt.__offset and 0x1FE8 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("reserved_24", 0), - lambda pkt:(0x1FE8 >= pkt.__offset and 0x1FEC <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XIntField("reserved_25", 0), - lambda pkt:(0x1FEC >= pkt.__offset and 0x1FF0 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(StrFixedLenField("reserved_26", - b"\x00" * 24, - 24), - lambda pkt:(0x1FF0 >= pkt.__offset and 0x2008 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("OverrideDefaultLedEventBehavior", 0x80), - lambda pkt:(0x2008 >= pkt.__offset and 0x2009 <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("ReportToHostInfo", 0), - lambda pkt:(0x2009 >= pkt.__offset and 0x200A <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(X3BytesField("reserved_27", 0), - lambda pkt:(0x200A >= pkt.__offset and 0x200D <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("NumBehaviors", 0), - lambda pkt:(0x200D >= pkt.__offset and 0x200E <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(PacketListField("BehaviorBlockArrayES", "", BehaviorBlockArray, length_from=lambda x: 1200), # noqa: E501 - lambda pkt:(0x200E >= pkt.__offset and 0x24BE <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(XByteField("NumEvents", 0), - lambda pkt:(0x24BE >= pkt.__offset and 0x24BF <= pkt.__offset + pkt.__length)), # noqa: E501 - ConditionalField(PacketListField("EventBlockArrayES", "", EventBlockArray, length_from=lambda x: 550), # noqa: E501 - lambda pkt:(0x24BF >= pkt.__offset and 0x26E5 <= pkt.__offset + pkt.__length)), # noqa: E501 - ] - - def __init__(self, packet="", offset=0x0, length=0x400): - self.__offset = offset - self.__length = length - return super(ModulePIB, self).__init__(packet) - - -###################################################################### -# Read MAC Memory -##################################################################### - -StartMACCodes = {0x00: "Success"} - - -class StartMACRequest(Packet): - name = "StartMACRequest" - fields_desc = [ByteEnumField("ModuleID", 0x00, StartMACCodes), - X3BytesField("reserver_1", 0x000000), - LEIntField("ImgLoadStartAddr", 0x00000000), - LEIntField("ImgLength", 0x00000000), - LEIntField("ImgCheckSum", 0x00000000), - LEIntField("ImgStartAddr", 0x00000000), - ] - - -class StartMACConfirmation(Packet): - name = "StartMACConfirmation" - fields_desc = [ByteEnumField("Status", 0x00, StartMACCodes), - XByteField("ModuleID", 0x00), - ] - -###################################################################### -# Reset Device -###################################################################### - - -ResetDeviceCodes = {0x00: "Success"} - - -class ResetDeviceRequest(Packet): - name = "ResetDeviceRequest" - fields_desc = [] - - -class ResetDeviceConfirmation(Packet): - name = "ResetDeviceConfirmation" - fields_desc = [ByteEnumField("Status", 0x00, ResetDeviceCodes)] - -###################################################################### -# Read Configuration Block -###################################################################### - - -ReadConfBlockCodes = {0x00: "Success"} - - -class ReadConfBlockRequest(Packet): - name = "ReadConfBlockRequest" - fields_desc = [] - - -CBImgTCodes = {0x00: "Generic Image", - 0x01: "Synopsis configuration", - 0x02: "Denali configuration", - 0x03: "Denali applet", - 0x04: "Runtime firmware", - 0x05: "OAS client", - 0x06: "Custom image", - 0x07: "Memory control applet", - 0x08: "Power management applet", - 0x09: "OAS client IP stack", - 0x0A: "OAS client TR069", - 0x0B: "SoftLoader", - 0x0C: "Flash layout", - 0x0D: "Unknown", - 0x0E: "Chain manifest", - 0x0F: "Runtime parameters", - 0x10: "Custom module in scratch", - 0x11: "Custom module update applet"} - - -class ConfBlock(Packet): - name = "ConfBlock" - fields_desc = [LEIntField("HeaderVersionNum", 0), - LEIntField("ImgAddrNVM", 0), - LEIntField("ImgAddrSDRAM", 0), - LEIntField("ImgLength", 0), - LEIntField("ImgCheckSum", 0), - LEIntField("EntryPoint", 0), - XByteField("HeaderMinVersion", 0x00), - ByteEnumField("HeaderImgType", 0x00, CBImgTCodes), - XShortField("HeaderIgnoreMask", 0x0000), - LEIntField("HeaderModuleID", 0), - LEIntField("HeaderModuleSubID", 0), - LEIntField("AddrNextHeaderNVM", 0), - LEIntField("HeaderChecksum", 0), - LEIntField("SDRAMsize", 0), - LEIntField("SDRAMConfRegister", 0), - LEIntField("SDRAMTimingRegister_0", 0), - LEIntField("SDRAMTimingRegister_1", 0), - LEIntField("SDRAMControlRegister", 0), - LEIntField("SDRAMRefreshRegister", 0), - LEIntField("MACClockRegister", 0), - LEIntField("reserved_1", 0), ] - - -class ReadConfBlockConfirmation(Packet): - name = "ReadConfBlockConfirmation" - fields_desc = [ByteEnumField("Status", 0x00, ReadConfBlockCodes), - FieldLenField("BlockLen", None, count_of="ConfigurationBlock", fmt="B"), # noqa: E501 - PacketListField("ConfigurationBlock", None, ConfBlock, length_from=lambda pkt:pkt.BlockLen)] # noqa: E501 - - -###################################################################### -# Write Module Data to NVM -###################################################################### - -class WriteModuleData2NVMRequest(Packet): - name = "WriteModuleData2NVMRequest" - fields_desc = [ByteEnumField("ModuleID", 0x02, ModuleIDList)] - - -class WriteModuleData2NVMConfirmation(Packet): - name = "WriteModuleData2NVMConfirmation" - fields_desc = [ByteEnumField("Status", 0x0, StatusCodes), - ByteEnumField("ModuleID", 0x02, ModuleIDList)] - -# END # - - -class HomePlugAV(Packet): - """ - HomePlugAV Packet - by default => gets devices information - """ - name = "HomePlugAV " - fields_desc = [MACManagementHeader, - ConditionalField(XShortField("FragmentInfo", 0x0), FragmentCond), # Fragmentation Field # noqa: E501 - VendorMME] - - def answers(self, other): - return (isinstance(self, HomePlugAV)) - - -bind_layers(Ether, HomePlugAV, {"type": 0x88e1}) - -# +----------+------------+--------------------+ -# | Ethernet | HomePlugAV | Elements + Payload | -# +----------+------------+--------------------+ -bind_layers(HomePlugAV, GetDeviceVersion, {"HPtype": 0xA001}) -bind_layers(HomePlugAV, StartMACRequest, {"HPtype": 0xA00C}) -bind_layers(HomePlugAV, StartMACConfirmation, {"HPtype": 0xA00D}) -bind_layers(HomePlugAV, ResetDeviceRequest, {"HPtype": 0xA01C}) -bind_layers(HomePlugAV, ResetDeviceConfirmation, {"HPtype": 0xA01D}) -bind_layers(HomePlugAV, NetworkInformationRequest, {"HPtype": 0xA038}) -bind_layers(HomePlugAV, ReadMACMemoryRequest, {"HPtype": 0xA008}) -bind_layers(HomePlugAV, ReadMACMemoryConfirmation, {"HPtype": 0xA009}) -bind_layers(HomePlugAV, ReadModuleDataRequest, {"HPtype": 0xA024}) -bind_layers(HomePlugAV, ReadModuleDataConfirmation, {"HPtype": 0xA025}) -bind_layers(HomePlugAV, WriteModuleDataRequest, {"HPtype": 0xA020}) -bind_layers(HomePlugAV, WriteModuleData2NVMRequest, {"HPtype": 0xA028}) -bind_layers(HomePlugAV, WriteModuleData2NVMConfirmation, {"HPtype": 0xA029}) -bind_layers(HomePlugAV, NetworkInfoConfirmationV10, {"HPtype": 0xA039, "version": 0x00}) # noqa: E501 -bind_layers(HomePlugAV, NetworkInfoConfirmationV11, {"HPtype": 0xA039, "version": 0x01}) # noqa: E501 -bind_layers(NetworkInfoConfirmationV10, NetworkInfoV10, {"HPtype": 0xA039, "version": 0x00}) # noqa: E501 -bind_layers(NetworkInfoConfirmationV11, NetworkInfoV11, {"HPtype": 0xA039, "version": 0x01}) # noqa: E501 -bind_layers(HomePlugAV, HostActionRequired, {"HPtype": 0xA062}) -bind_layers(HomePlugAV, LoopbackRequest, {"HPtype": 0xA048}) -bind_layers(HomePlugAV, LoopbackConfirmation, {"HPtype": 0xA049}) -bind_layers(HomePlugAV, SetEncryptionKeyRequest, {"HPtype": 0xA050}) -bind_layers(HomePlugAV, SetEncryptionKeyConfirmation, {"HPtype": 0xA051}) -bind_layers(HomePlugAV, ReadConfBlockRequest, {"HPtype": 0xA058}) -bind_layers(HomePlugAV, ReadConfBlockConfirmation, {"HPtype": 0xA059}) -bind_layers(HomePlugAV, QUAResetFactoryConfirm, {"HPtype": 0xA07D}) -bind_layers(HomePlugAV, GetNVMParametersRequest, {"HPtype": 0xA010}) -bind_layers(HomePlugAV, GetNVMParametersConfirmation, {"HPtype": 0xA011}) -bind_layers(HomePlugAV, SnifferRequest, {"HPtype": 0xA034}) -bind_layers(HomePlugAV, SnifferConfirmation, {"HPtype": 0xA035}) -bind_layers(HomePlugAV, SnifferIndicate, {"HPtype": 0xA036}) - -""" - Credit song : "Western Spaguetti - We are terrorists" -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/http2.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/http2.py deleted file mode 100644 index e94135fdcc..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/http2.py +++ /dev/null @@ -1,2730 +0,0 @@ -############################################################################# -# # -# http2.py --- HTTP/2 support for Scapy # -# see RFC7540 and RFC7541 # -# for more information # -# # -# Copyright (C) 2016 Florian Maury # -# # -# This file is part of Scapy # -# Scapy 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. # -# # -############################################################################# -"""http2 Module -Implements packets and fields required to encode/decode HTTP/2 Frames -and HPack encoded headers -""" - -# scapy.contrib.status=loads -# scapy.contrib.description=HTTP/2 (RFC 7540, RFC 7541) - -# base_classes triggers an unwanted import warning -# flake8: noqa: F821 - -from __future__ import absolute_import -from __future__ import print_function -import abc -import re -import sys -from io import BytesIO -import struct -import scapy.modules.six as six -from scapy.compat import raw, plain_str, bytes_hex, orb, chb, bytes_encode - -# Only required if using mypy-lang for static typing -# Most symbols are used in mypy-interpreted "comments". -# Sized must be one of the superclasses of a class implementing __len__ -try: - from typing import Optional, List, Union, Callable, Any, Tuple, Sized # noqa: F401, E501 -except ImportError: - class Sized(object): - pass - -import scapy.fields as fields -import scapy.packet as packet -import scapy.config as config -import scapy.volatile as volatile -import scapy.error as error - -############################################################################### -# HPACK Integer Fields # -############################################################################### - - -class HPackMagicBitField(fields.BitField): - """ HPackMagicBitField is a BitField variant that cannot be assigned another - value than the default one. This field must not be used where there is - potential for fuzzing. OTOH, this field makes sense (for instance, if the - magic bits are used by a dispatcher to select the payload class) - """ - - __slots__ = ['_magic'] - - def __init__(self, name, default, size): - # type: (str, int, int) -> None - """ - @param str name: this field instance name. - @param int default: this field only valid value. - @param int size: this bitfield bitlength. - @return None - @raise AssertionError - """ - assert(default >= 0) - # size can be negative if encoding is little-endian (see rev property of bitfields) # noqa: E501 - assert(size != 0) - self._magic = default - super(HPackMagicBitField, self).__init__(name, default, size) - - def addfield(self, pkt, s, val): - # type: (Optional[packet.Packet], Union[str, Tuple[str, int, int]], int) -> Union[str, Tuple[str, int, int]] # noqa: E501 - """ - @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused. # noqa: E501 - @param str|(str, int, long) s: either a str if 0 == size%8 or a tuple with the string to add this field to, the # noqa: E501 - number of bits already generated and the generated value so far. - @param int val: unused; must be equal to default value - @return str|(str, int, long): the s string extended with this field machine representation # noqa: E501 - @raise AssertionError - """ - assert val == self._magic, 'val parameter must value {}; received: {}'.format(self._magic, val) # noqa: E501 - return super(HPackMagicBitField, self).addfield(pkt, s, self._magic) - - def getfield(self, pkt, s): - # type: (Optional[packet.Packet], Union[str, Tuple[str, int]]) -> Tuple[Union[Tuple[str, int], str], int] # noqa: E501 - """ - @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused. # noqa: E501 - @param str|(str, int) s: either a str if size%8==0 or a tuple with the string to parse from and the number of # noqa: E501 - bits already consumed by previous bitfield-compatible fields. - @return (str|(str, int), int): Returns the remaining string and the parsed value. May return a tuple if there # noqa: E501 - are remaining bits to parse in the first byte. Returned value is equal to default value # noqa: E501 - @raise AssertionError - """ - r = super(HPackMagicBitField, self).getfield(pkt, s) - assert ( - isinstance(r, tuple) and - len(r) == 2 and - isinstance(r[1], six.integer_types) - ), 'Second element of BitField.getfield return value expected to be an int or a long; API change detected' # noqa: E501 - assert r[1] == self._magic, 'Invalid value parsed from s; error in class guessing detected!' # noqa: E501 - return r - - def h2i(self, pkt, x): - # type: (Optional[packet.Packet], int) -> int - """ - @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused # noqa: E501 - @param int x: unused; must be equal to default value - @return int; default value - @raise AssertionError - """ - assert x == self._magic, \ - 'EINVAL: x: This field is magic. Do not attempt to modify it. Expected value: {}'.format(self._magic) # noqa: E501 - return super(HPackMagicBitField, self).h2i(pkt, self._magic) - - def i2h(self, pkt, x): - # type: (Optional[packet.Packet], int) -> int - """ - @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused # noqa: E501 - @param int x: unused; must be equal to default value - @return int; default value - @raise AssertionError - """ - assert x == self._magic, \ - 'EINVAL: x: This field is magic. Do not attempt to modify it. Expected value: {}'.format(self._magic) # noqa: E501 - return super(HPackMagicBitField, self).i2h(pkt, self._magic) - - def m2i(self, pkt, x): - # type: (Optional[packet.Packet], int) -> int - """ - @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused # noqa: E501 - @param int x: must be the machine representatino of the default value - @return int; default value - @raise AssertionError - """ - r = super(HPackMagicBitField, self).m2i(pkt, x) - assert r == self._magic, 'Invalid value parsed from m2i; error in class guessing detected!' # noqa: E501 - return r - - def i2m(self, pkt, x): - # type: (Optional[packet.Packet], int) -> int - """ - @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused # noqa: E501 - @param int x: unused; must be equal to default value - @return int; default value - @raise AssertionError - """ - assert x == self._magic, \ - 'EINVAL: x: This field is magic. Do not attempt to modify it. Expected value: {}'.format(self._magic) # noqa: E501 - return super(HPackMagicBitField, self).i2m(pkt, self._magic) - - def any2i(self, pkt, x): - # type: (Optional[packet.Packet], int) -> int - """ - @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused # noqa: E501 - @param int x: unused; must be equal to default value - @return int; default value - @raise AssertionError - """ - assert x == self._magic, \ - 'EINVAL: x: This field is magic. Do not attempt to modify it. Expected value: {}'.format(self._magic) # noqa: E501 - return super(HPackMagicBitField, self).any2i(pkt, self._magic) - - -class AbstractUVarIntField(fields.Field): - """AbstractUVarIntField represents an integer as defined in RFC7541 - """ - - __slots__ = ['_max_value', 'size', 'rev'] - """ - :var int size: the bit length of the prefix of this AbstractUVarIntField. It # noqa: E501 - represents the complement of the number of MSB that are used in the - current byte for other purposes by some other BitFields - :var int _max_value: the maximum value that can be stored in the - sole prefix. If the integer equals or exceeds this value, the max prefix - value is assigned to the size first bits and the multibyte representation - is used - :var bool rev: is a fake property, also emulated for the sake of - compatibility with Bitfields - """ - - def __init__(self, name, default, size): - # type: (str, Optional[int], int) -> None - """ - @param str name: the name of this field instance - @param int|None default: positive, null or None default value for this field instance. # noqa: E501 - @param int size: the number of bits to consider in the first byte. Valid range is ]0;8] # noqa: E501 - @return None - @raise AssertionError - """ - assert(default is None or (isinstance(default, six.integer_types) and default >= 0)) # noqa: E501 - assert(0 < size <= 8) - super(AbstractUVarIntField, self).__init__(name, default) - self.size = size - self._max_value = (1 << self.size) - 1 - - # Configuring the fake property that is useless for this class but that is # noqa: E501 - # expected from BitFields - self.rev = False - - def h2i(self, pkt, x): - # type: (Optional[packet.Packet], Optional[int]) -> Optional[int] - """ - @param packet.Packet|None pkt: unused. - @param int|None x: the value to convert. - @return int|None: the converted value. - @raise AssertionError - """ - assert(not isinstance(x, six.integer_types) or x >= 0) - return x - - def i2h(self, pkt, x): - # type: (Optional[packet.Packet], Optional[int]) -> Optional[int] - """ - @param packet.Packet|None pkt: unused. - @param int|None x: the value to convert. - @return: int|None: the converted value. - """ - return x - - def _detect_multi_byte(self, fb): - # type: (str) -> bool - """ _detect_multi_byte returns whether the AbstractUVarIntField is represented on # noqa: E501 - multiple bytes or not. - - A multibyte representation is indicated by all of the first size bits being set # noqa: E501 - - @param str fb: first byte, as a character. - @return bool: True if multibyte repr detected, else False. - @raise AssertionError - """ - assert(isinstance(fb, int) or len(fb) == 1) - return (orb(fb) & self._max_value) == self._max_value - - def _parse_multi_byte(self, s): - # type: (str) -> int - """ _parse_multi_byte parses x as a multibyte representation to get the - int value of this AbstractUVarIntField. - - @param str s: the multibyte string to parse. - @return int: The parsed int value represented by this AbstractUVarIntField. # noqa: E501 - @raise: AssertionError - @raise: Scapy_Exception if the input value encodes an integer larger than 1<<64 # noqa: E501 - """ - - assert(len(s) >= 2) - - tmp_len = len(s) - - value = 0 - i = 1 - byte = orb(s[i]) - # For CPU sake, stops at an arbitrary large number! - max_value = 1 << 64 - # As long as the MSG is set, an another byte must be read - while byte & 0x80: - value += (byte ^ 0x80) << (7 * (i - 1)) - if value > max_value: - raise error.Scapy_Exception( - 'out-of-bound value: the string encodes a value that is too large (>2^{64}): {}'.format(value) # noqa: E501 - ) - i += 1 - assert i < tmp_len, 'EINVAL: x: out-of-bound read: the string ends before the AbstractUVarIntField!' # noqa: E501 - byte = orb(s[i]) - value += byte << (7 * (i - 1)) - value += self._max_value - - assert(value >= 0) - return value - - def m2i(self, pkt, x): - # type: (Optional[packet.Packet], Union[str, Tuple[str, int]]) -> int - """ - A tuple is expected for the "x" param only if "size" is different than 8. If a tuple is received, some bits # noqa: E501 - were consumed by another field. This field consumes the remaining bits, therefore the int of the tuple must # noqa: E501 - equal "size". - - @param packet.Packet|None pkt: unused. - @param str|(str, int) x: the string to convert. If bits were consumed by a previous bitfield-compatible field. # noqa: E501 - @raise AssertionError - """ - assert(isinstance(x, bytes) or (isinstance(x, tuple) and x[1] >= 0)) - - if isinstance(x, tuple): - assert (8 - x[1]) == self.size, 'EINVAL: x: not enough bits remaining in current byte to read the prefix' # noqa: E501 - val = x[0] - else: - assert isinstance(x, bytes) and self.size == 8, 'EINVAL: x: tuple expected when prefix_len is not a full byte' # noqa: E501 - val = x - - if self._detect_multi_byte(val[0]): - ret = self._parse_multi_byte(val) - else: - ret = orb(val[0]) & self._max_value - - assert(ret >= 0) - return ret - - def i2m(self, pkt, x): - # type: (Optional[packet.Packet], int) -> str - """ - @param packet.Packet|None pkt: unused. - @param int x: the value to convert. - @return str: the converted value. - @raise AssertionError - """ - assert(x >= 0) - - if x < self._max_value: - return chb(x) - else: - # The sl list join is a performance trick, because string - # concatenation is not efficient with Python immutable strings - sl = [chb(self._max_value)] - x -= self._max_value - while x >= 0x80: - sl.append(chb(0x80 | (x & 0x7F))) - x >>= 7 - sl.append(chb(x)) - return b''.join(sl) - - def any2i(self, pkt, x): - # type: (Optional[packet.Packet], Union[None, str, int]) -> Optional[int] # noqa: E501 - """ - A "x" value as a string is parsed as a binary encoding of a UVarInt. An int is considered an internal value. # noqa: E501 - None is returned as is. - - @param packet.Packet|None pkt: the packet containing this field; probably unused. # noqa: E501 - @param str|int|None x: the value to convert. - @return int|None: the converted value. - @raise AssertionError - """ - if isinstance(x, type(None)): - return x - if isinstance(x, six.integer_types): - assert(x >= 0) - ret = self.h2i(pkt, x) - assert(isinstance(ret, six.integer_types) and ret >= 0) - return ret - elif isinstance(x, bytes): - ret = self.m2i(pkt, x) - assert (isinstance(ret, six.integer_types) and ret >= 0) - return ret - assert False, 'EINVAL: x: No idea what the parameter format is' - - def i2repr(self, pkt, x): - # type: (Optional[packet.Packet], Optional[int]) -> str - """ - @param packet.Packet|None pkt: probably unused. - @param x: int|None: the positive, null or none value to convert. - @return str: the representation of the value. - """ - return repr(self.i2h(pkt, x)) - - def addfield(self, pkt, s, val): - # type: (Optional[packet.Packet], Union[str, Tuple[str, int, int]], int) -> str # noqa: E501 - """ An AbstractUVarIntField prefix always consumes the remaining bits - of a BitField;if no current BitField is in use (no tuple in - entry) then the prefix length is 8 bits and the whole byte is to - be consumed - @param packet.Packet|None pkt: the packet containing this field. Probably unused. # noqa: E501 - @param str|(str, int, long) s: the string to append this field to. A tuple indicates that some bits were already # noqa: E501 - generated by another bitfield-compatible field. This MUST be the case if "size" is not 8. The int is the # noqa: E501 - number of bits already generated in the first byte of the str. The long is the value that was generated by the # noqa: E501 - previous bitfield-compatible fields. - @param int val: the positive or null value to be added. - @return str: s concatenated with the machine representation of this field. # noqa: E501 - @raise AssertionError - """ - assert(val >= 0) - if isinstance(s, bytes): - assert self.size == 8, 'EINVAL: s: tuple expected when prefix_len is not a full byte' # noqa: E501 - return s + self.i2m(pkt, val) - - # s is a tuple - # assert(s[1] >= 0) - # assert(s[2] >= 0) - # assert (8 - s[1]) == self.size, 'EINVAL: s: not enough bits remaining in current byte to read the prefix' # noqa: E501 - - if val >= self._max_value: - return s[0] + chb((s[2] << self.size) + self._max_value) + self.i2m(pkt, val)[1:] # noqa: E501 - # This AbstractUVarIntField is only one byte long; setting the prefix value # noqa: E501 - # and appending the resulting byte to the string - return s[0] + chb((s[2] << self.size) + orb(self.i2m(pkt, val))) - - @staticmethod - def _detect_bytelen_from_str(s): - # type: (str) -> int - """ _detect_bytelen_from_str returns the length of the machine - representation of an AbstractUVarIntField starting at the beginning - of s and which is assumed to expand over multiple bytes - (value > _max_prefix_value). - - @param str s: the string to parse. It is assumed that it is a multibyte int. # noqa: E501 - @return The bytelength of the AbstractUVarIntField. - @raise AssertionError - """ - assert(len(s) >= 2) - tmp_len = len(s) - - i = 1 - while orb(s[i]) & 0x80 > 0: - i += 1 - assert i < tmp_len, 'EINVAL: s: out-of-bound read: unfinished AbstractUVarIntField detected' # noqa: E501 - ret = i + 1 - - assert(ret >= 0) - return ret - - def i2len(self, pkt, x): - # type: (Optional[packet.Packet], int) -> int - """ - @param packet.Packet|None pkt: unused. - @param int x: the positive or null value whose binary size if requested. # noqa: E501 - @raise AssertionError - """ - assert(x >= 0) - if x < self._max_value: - return 1 - - # x is expressed over multiple bytes - x -= self._max_value - i = 1 - if x == 0: - i += 1 - while x > 0: - x >>= 7 - i += 1 - - ret = i - assert(ret >= 0) - return ret - - def getfield(self, pkt, s): - # type: (Optional[packet.Packet], Union[str, Tuple[str, int]]) -> Tuple[str, int] # noqa: E501 - """ - @param packet.Packet|None pkt: the packet instance containing this field; probably unused. # noqa: E501 - @param str|(str, int) s: the input value to get this field value from. If size is 8, s is a string, else # noqa: E501 - it is a tuple containing the value and an int indicating the number of bits already consumed in the first byte # noqa: E501 - of the str. The number of remaining bits to consume in the first byte must be equal to "size". # noqa: E501 - @return (str, int): the remaining bytes of s and the parsed value. - @raise AssertionError - """ - if isinstance(s, tuple): - assert(len(s) == 2) - temp = s # type: Tuple[str, int] - ts, ti = temp - assert(ti >= 0) - assert 8 - ti == self.size, 'EINVAL: s: not enough bits remaining in current byte to read the prefix' # noqa: E501 - val = ts - else: - assert isinstance(s, bytes) and self.size == 8, 'EINVAL: s: tuple expected when prefix_len is not a full byte' # noqa: E501 - val = s - - if self._detect_multi_byte(val[0]): - tmp_len = self._detect_bytelen_from_str(val) - else: - tmp_len = 1 - - ret = val[tmp_len:], self.m2i(pkt, s) - assert(ret[1] >= 0) - return ret - - def randval(self): - # type: () -> volatile.VolatileValue - """ - @return volatile.VolatileValue: a volatile value for this field "long"-compatible internal value. # noqa: E501 - """ - return volatile.RandLong() - - -class UVarIntField(AbstractUVarIntField): - def __init__(self, name, default, size): - # type: (str, int, int) -> None - """ - @param str name: the name of this field instance. - @param default: the default value for this field instance. default must be positive or null. # noqa: E501 - @raise AssertionError - """ - assert(default >= 0) - assert(0 < size <= 8) - - super(UVarIntField, self).__init__(name, default, size) - self.size = size - self._max_value = (1 << self.size) - 1 - - # Configuring the fake property that is useless for this class but that is # noqa: E501 - # expected from BitFields - self.rev = False - - def h2i(self, pkt, x): - # type: (Optional[packet.Packet], int) -> int - """ h2i is overloaded to restrict the acceptable x values (not None) - - @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused. # noqa: E501 - @param int x: the value to convert. - @return int: the converted value. - @raise AssertionError - """ - ret = super(UVarIntField, self).h2i(pkt, x) - assert(not isinstance(ret, type(None)) and ret >= 0) - return ret - - def i2h(self, pkt, x): - # type: (Optional[packet.Packet], int) -> int - """ i2h is overloaded to restrict the acceptable x values (not None) - - @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused. # noqa: E501 - @param int x: the value to convert. - @return int: the converted value. - @raise AssertionError - """ - ret = super(UVarIntField, self).i2h(pkt, x) - assert(not isinstance(ret, type(None)) and ret >= 0) - return ret - - def any2i(self, pkt, x): - # type: (Optional[packet.Packet], Union[str, int]) -> int - """ any2i is overloaded to restrict the acceptable x values (not None) - - @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused. # noqa: E501 - @param str|int x: the value to convert. - @return int: the converted value. - @raise AssertionError - """ - ret = super(UVarIntField, self).any2i(pkt, x) - assert(not isinstance(ret, type(None)) and ret >= 0) - return ret - - def i2repr(self, pkt, x): - # type: (Optional[packet.Packet], int) -> str - """ i2repr is overloaded to restrict the acceptable x values (not None) - - @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused. # noqa: E501 - @param int x: the value to convert. - @return str: the converted value. - """ - return super(UVarIntField, self).i2repr(pkt, x) - - -class FieldUVarLenField(AbstractUVarIntField): - __slots__ = ['_length_of', '_adjust'] - - def __init__(self, name, default, size, length_of, adjust=lambda x: x): - # type: (str, Optional[int], int, str, Callable[[int], int]) -> None - """ Initializes a FieldUVarLenField - - @param str name: The name of this field instance. - @param int|None default: the default value of this field instance. - @param int size: the number of bits that are occupied by this field in the first byte of a binary string. # noqa: E501 - size must be in the range ]0;8]. - @param str length_of: The name of the field this field value is measuring/representing. # noqa: E501 - @param callable adjust: A function that modifies the value computed from the "length_of" field. # noqa: E501 - - adjust can be used for instance to add a constant to the length_of field # noqa: E501 - length. For instance, let's say that i2len of the length_of field - returns 2. If adjust is lambda x: x+1 In that case, this field will - value 3 at build time. - @return None - @raise AssertionError - """ - assert(default is None or default >= 0) - assert(0 < size <= 8) - - super(FieldUVarLenField, self).__init__(name, default, size) - self._length_of = length_of - self._adjust = adjust - - def addfield(self, pkt, s, val): - # type: (Optional[packet.Packet], Union[str, Tuple[str, int, int]], Optional[int]) -> str # noqa: E501 - """ - @param packet.Packet|None pkt: the packet instance containing this field instance. This parameter must not be # noqa: E501 - None if the val parameter is. - @param str|(str, int, long) s: the string to append this field to. A tuple indicates that some bits were already # noqa: E501 - generated by another bitfield-compatible field. This MUST be the case if "size" is not 8. The int is the # noqa: E501 - number of bits already generated in the first byte of the str. The long is the value that was generated by the # noqa: E501 - previous bitfield-compatible fields. - @param int|None val: the positive or null value to be added. If None, the value is computed from pkt. # noqa: E501 - @return str: s concatenated with the machine representation of this field. # noqa: E501 - @raise AssertionError - """ - if val is None: - assert isinstance(pkt, packet.Packet), \ - 'EINVAL: pkt: Packet expected when val is None; received {}'.format(type(pkt)) # noqa: E501 - val = self._compute_value(pkt) - return super(FieldUVarLenField, self).addfield(pkt, s, val) - - def i2m(self, pkt, x): - # type: (Optional[packet.Packet], Optional[int]) -> str - """ - @param packet.Packet|None pkt: the packet instance containing this field instance. This parameter must not be # noqa: E501 - None if the x parameter is. - @param int|None x: the positive or null value to be added. If None, the value is computed from pkt. # noqa: E501 - @return str - @raise AssertionError - """ - if x is None: - assert isinstance(pkt, packet.Packet), \ - 'EINVAL: pkt: Packet expected when x is None; received {}'.format(type(pkt)) # noqa: E501 - x = self._compute_value(pkt) - return super(FieldUVarLenField, self).i2m(pkt, x) - - def _compute_value(self, pkt): - # type: (packet.Packet) -> int - """ Computes the value of this field based on the provided packet and - the length_of field and the adjust callback - - @param packet.Packet pkt: the packet from which is computed this field value. # noqa: E501 - @return int: the computed value for this field. - @raise KeyError: the packet nor its payload do not contain an attribute - with the length_of name. - @raise AssertionError - @raise KeyError if _length_of is not one of pkt fields - """ - fld, fval = pkt.getfield_and_val(self._length_of) - val = fld.i2len(pkt, fval) - ret = self._adjust(val) - assert(ret >= 0) - return ret - -############################################################################### -# HPACK String Fields # -############################################################################### - -# Welcome the magic of Python inconsistencies ! -# https://stackoverflow.com/a/41622155 - - -if sys.version_info >= (3, 4): - ABC = abc.ABC -else: - ABC = abc.ABCMeta('ABC', (), {}) - - -class HPackStringsInterface(ABC, Sized): - @abc.abstractmethod - def __str__(self): - pass - - def __bytes__(self): - r = self.__str__() - return bytes_encode(r) - - @abc.abstractmethod - def origin(self): - pass - - @abc.abstractmethod - def __len__(self): - pass - - -class HPackLiteralString(HPackStringsInterface): - """ HPackLiteralString is a string. This class is used as a marker and - implements an interface in common with HPackZString - """ - __slots__ = ['_s'] - - def __init__(self, s): - # type: (str) -> None - self._s = s - - def __str__(self): - # type: () -> str - return self._s - - def origin(self): - # type: () -> str - return plain_str(self._s) - - def __len__(self): - # type: () -> int - return len(self._s) - - -class EOS(object): - """ Simple "marker" to designate the End Of String symbol in the huffman table - """ - - -class HuffmanNode(object): - """ HuffmanNode is an entry of the binary tree used for encoding/decoding - HPack compressed HTTP/2 headers - """ - - __slots__ = ['left', 'right'] - """@var l: the left branch of this node - @var r: the right branch of this Node - - These variables can value None (leaf node), another HuffmanNode, or a - symbol. Symbols are either a character or the End Of String symbol (class - EOS) - """ - - def __init__(self, left, right): - # type: (Union[None, HuffmanNode, EOS, str], Union[None, HuffmanNode, EOS, str]) -> None # noqa: E501 - self.left = left - self.right = right - - def __getitem__(self, b): - # type: (int) -> Union[None, HuffmanNode, EOS, str] - return self.right if b else self.left - - def __setitem__(self, b, val): - # type: (int, Union[None, HuffmanNode, EOS, str]) -> None - if b: - self.right = val - else: - self.left = val - - def __str__(self): - # type: () -> str - return self.__repr__() - - def __repr__(self): - # type: () -> str - return '({}, {})'.format(self.left, self.right) - - -class InvalidEncodingException(Exception): - """ InvalidEncodingException is raised when a supposedly huffman-encoded - string is decoded and a decoding error arises - """ - - -class HPackZString(HPackStringsInterface): - __slots__ = ['_s', '_encoded'] - - # From RFC 7541 - # Tuple is (code,code bitlength) - # The bitlength is required to know how long the left padding - # (implicit 0's) there are - static_huffman_code = [ - (0x1ff8, 13), - (0x7fffd8, 23), - (0xfffffe2, 28), - (0xfffffe3, 28), - (0xfffffe4, 28), - (0xfffffe5, 28), - (0xfffffe6, 28), - (0xfffffe7, 28), - (0xfffffe8, 28), - (0xffffea, 24), - (0x3ffffffc, 30), - (0xfffffe9, 28), - (0xfffffea, 28), - (0x3ffffffd, 30), - (0xfffffeb, 28), - (0xfffffec, 28), - (0xfffffed, 28), - (0xfffffee, 28), - (0xfffffef, 28), - (0xffffff0, 28), - (0xffffff1, 28), - (0xffffff2, 28), - (0x3ffffffe, 30), - (0xffffff3, 28), - (0xffffff4, 28), - (0xffffff5, 28), - (0xffffff6, 28), - (0xffffff7, 28), - (0xffffff8, 28), - (0xffffff9, 28), - (0xffffffa, 28), - (0xffffffb, 28), - (0x14, 6), - (0x3f8, 10), - (0x3f9, 10), - (0xffa, 12), - (0x1ff9, 13), - (0x15, 6), - (0xf8, 8), - (0x7fa, 11), - (0x3fa, 10), - (0x3fb, 10), - (0xf9, 8), - (0x7fb, 11), - (0xfa, 8), - (0x16, 6), - (0x17, 6), - (0x18, 6), - (0x0, 5), - (0x1, 5), - (0x2, 5), - (0x19, 6), - (0x1a, 6), - (0x1b, 6), - (0x1c, 6), - (0x1d, 6), - (0x1e, 6), - (0x1f, 6), - (0x5c, 7), - (0xfb, 8), - (0x7ffc, 15), - (0x20, 6), - (0xffb, 12), - (0x3fc, 10), - (0x1ffa, 13), - (0x21, 6), - (0x5d, 7), - (0x5e, 7), - (0x5f, 7), - (0x60, 7), - (0x61, 7), - (0x62, 7), - (0x63, 7), - (0x64, 7), - (0x65, 7), - (0x66, 7), - (0x67, 7), - (0x68, 7), - (0x69, 7), - (0x6a, 7), - (0x6b, 7), - (0x6c, 7), - (0x6d, 7), - (0x6e, 7), - (0x6f, 7), - (0x70, 7), - (0x71, 7), - (0x72, 7), - (0xfc, 8), - (0x73, 7), - (0xfd, 8), - (0x1ffb, 13), - (0x7fff0, 19), - (0x1ffc, 13), - (0x3ffc, 14), - (0x22, 6), - (0x7ffd, 15), - (0x3, 5), - (0x23, 6), - (0x4, 5), - (0x24, 6), - (0x5, 5), - (0x25, 6), - (0x26, 6), - (0x27, 6), - (0x6, 5), - (0x74, 7), - (0x75, 7), - (0x28, 6), - (0x29, 6), - (0x2a, 6), - (0x7, 5), - (0x2b, 6), - (0x76, 7), - (0x2c, 6), - (0x8, 5), - (0x9, 5), - (0x2d, 6), - (0x77, 7), - (0x78, 7), - (0x79, 7), - (0x7a, 7), - (0x7b, 7), - (0x7ffe, 15), - (0x7fc, 11), - (0x3ffd, 14), - (0x1ffd, 13), - (0xffffffc, 28), - (0xfffe6, 20), - (0x3fffd2, 22), - (0xfffe7, 20), - (0xfffe8, 20), - (0x3fffd3, 22), - (0x3fffd4, 22), - (0x3fffd5, 22), - (0x7fffd9, 23), - (0x3fffd6, 22), - (0x7fffda, 23), - (0x7fffdb, 23), - (0x7fffdc, 23), - (0x7fffdd, 23), - (0x7fffde, 23), - (0xffffeb, 24), - (0x7fffdf, 23), - (0xffffec, 24), - (0xffffed, 24), - (0x3fffd7, 22), - (0x7fffe0, 23), - (0xffffee, 24), - (0x7fffe1, 23), - (0x7fffe2, 23), - (0x7fffe3, 23), - (0x7fffe4, 23), - (0x1fffdc, 21), - (0x3fffd8, 22), - (0x7fffe5, 23), - (0x3fffd9, 22), - (0x7fffe6, 23), - (0x7fffe7, 23), - (0xffffef, 24), - (0x3fffda, 22), - (0x1fffdd, 21), - (0xfffe9, 20), - (0x3fffdb, 22), - (0x3fffdc, 22), - (0x7fffe8, 23), - (0x7fffe9, 23), - (0x1fffde, 21), - (0x7fffea, 23), - (0x3fffdd, 22), - (0x3fffde, 22), - (0xfffff0, 24), - (0x1fffdf, 21), - (0x3fffdf, 22), - (0x7fffeb, 23), - (0x7fffec, 23), - (0x1fffe0, 21), - (0x1fffe1, 21), - (0x3fffe0, 22), - (0x1fffe2, 21), - (0x7fffed, 23), - (0x3fffe1, 22), - (0x7fffee, 23), - (0x7fffef, 23), - (0xfffea, 20), - (0x3fffe2, 22), - (0x3fffe3, 22), - (0x3fffe4, 22), - (0x7ffff0, 23), - (0x3fffe5, 22), - (0x3fffe6, 22), - (0x7ffff1, 23), - (0x3ffffe0, 26), - (0x3ffffe1, 26), - (0xfffeb, 20), - (0x7fff1, 19), - (0x3fffe7, 22), - (0x7ffff2, 23), - (0x3fffe8, 22), - (0x1ffffec, 25), - (0x3ffffe2, 26), - (0x3ffffe3, 26), - (0x3ffffe4, 26), - (0x7ffffde, 27), - (0x7ffffdf, 27), - (0x3ffffe5, 26), - (0xfffff1, 24), - (0x1ffffed, 25), - (0x7fff2, 19), - (0x1fffe3, 21), - (0x3ffffe6, 26), - (0x7ffffe0, 27), - (0x7ffffe1, 27), - (0x3ffffe7, 26), - (0x7ffffe2, 27), - (0xfffff2, 24), - (0x1fffe4, 21), - (0x1fffe5, 21), - (0x3ffffe8, 26), - (0x3ffffe9, 26), - (0xffffffd, 28), - (0x7ffffe3, 27), - (0x7ffffe4, 27), - (0x7ffffe5, 27), - (0xfffec, 20), - (0xfffff3, 24), - (0xfffed, 20), - (0x1fffe6, 21), - (0x3fffe9, 22), - (0x1fffe7, 21), - (0x1fffe8, 21), - (0x7ffff3, 23), - (0x3fffea, 22), - (0x3fffeb, 22), - (0x1ffffee, 25), - (0x1ffffef, 25), - (0xfffff4, 24), - (0xfffff5, 24), - (0x3ffffea, 26), - (0x7ffff4, 23), - (0x3ffffeb, 26), - (0x7ffffe6, 27), - (0x3ffffec, 26), - (0x3ffffed, 26), - (0x7ffffe7, 27), - (0x7ffffe8, 27), - (0x7ffffe9, 27), - (0x7ffffea, 27), - (0x7ffffeb, 27), - (0xffffffe, 28), - (0x7ffffec, 27), - (0x7ffffed, 27), - (0x7ffffee, 27), - (0x7ffffef, 27), - (0x7fffff0, 27), - (0x3ffffee, 26), - (0x3fffffff, 30) - ] - - static_huffman_tree = None - - @classmethod - def _huffman_encode_char(cls, c): - # type: (Union[str, EOS]) -> Tuple[int, int] - """ huffman_encode_char assumes that the static_huffman_tree was - previously initialized - - @param str|EOS c: a symbol to encode - @return (int, int): the bitstring of the symbol and its bitlength - @raise AssertionError - """ - if isinstance(c, EOS): - return cls.static_huffman_code[-1] - else: - assert(isinstance(c, int) or len(c) == 1) - return cls.static_huffman_code[orb(c)] - - @classmethod - def huffman_encode(cls, s): - # type: (str) -> Tuple[int, int] - """ huffman_encode returns the bitstring and the bitlength of the - bitstring representing the string provided as a parameter - - @param str s: the string to encode - @return (int, int): the bitstring of s and its bitlength - @raise AssertionError - """ - i = 0 - ibl = 0 - for c in s: - val, bl = cls._huffman_encode_char(c) - i = (i << bl) + val - ibl += bl - - padlen = 8 - (ibl % 8) - if padlen != 8: - val, bl = cls._huffman_encode_char(EOS()) - i = (i << padlen) + (val >> (bl - padlen)) - ibl += padlen - - ret = i, ibl - assert(ret[0] >= 0) - assert (ret[1] >= 0) - return ret - - @classmethod - def huffman_decode(cls, i, ibl): - # type: (int, int) -> str - """ huffman_decode decodes the bitstring provided as parameters. - - @param int i: the bitstring to decode - @param int ibl: the bitlength of i - @return str: the string decoded from the bitstring - @raise AssertionError, InvalidEncodingException - """ - assert(i >= 0) - assert(ibl >= 0) - - if isinstance(cls.static_huffman_tree, type(None)): - cls.huffman_compute_decode_tree() - assert(not isinstance(cls.static_huffman_tree, type(None))) - - s = [] - j = 0 - interrupted = False - cur = cls.static_huffman_tree - cur_sym = 0 - cur_sym_bl = 0 - while j < ibl: - b = (i >> (ibl - j - 1)) & 1 - cur_sym = (cur_sym << 1) + b - cur_sym_bl += 1 - elmt = cur[b] - - if isinstance(elmt, HuffmanNode): - interrupted = True - cur = elmt - if isinstance(cur, type(None)): - raise AssertionError() - elif isinstance(elmt, EOS): - raise InvalidEncodingException('Huffman decoder met the full EOS symbol') # noqa: E501 - elif isinstance(elmt, bytes): - interrupted = False - s.append(elmt) - cur = cls.static_huffman_tree - cur_sym = 0 - cur_sym_bl = 0 - else: - raise InvalidEncodingException('Should never happen, so incidentally it will') # noqa: E501 - j += 1 - - if interrupted: - # Interrupted values true if the bitstring ends in the middle of a - # symbol; this symbol must be, according to RFC7541 par5.2 the MSB - # of the EOS symbol - if cur_sym_bl > 7: - raise InvalidEncodingException('Huffman decoder is detecting padding longer than 7 bits') # noqa: E501 - eos_symbol = cls.static_huffman_code[-1] - eos_msb = eos_symbol[0] >> (eos_symbol[1] - cur_sym_bl) - if eos_msb != cur_sym: - raise InvalidEncodingException('Huffman decoder is detecting unexpected padding format') # noqa: E501 - return b''.join(s) - - @classmethod - def huffman_conv2str(cls, bit_str, bit_len): - # type: (int, int) -> str - """ huffman_conv2str converts a bitstring of bit_len bitlength into a - binary string. It DOES NOT compress/decompress the bitstring! - - @param int bit_str: the bitstring to convert. - @param int bit_len: the bitlength of bit_str. - @return str: the converted bitstring as a bytestring. - @raise AssertionError - """ - assert(bit_str >= 0) - assert(bit_len >= 0) - - byte_len = bit_len // 8 - rem_bit = bit_len % 8 - if rem_bit != 0: - bit_str <<= 8 - rem_bit - byte_len += 1 - - # As usual the list/join tricks is a performance trick to build - # efficiently a Python string - s = [] # type: List[str] - i = 0 - while i < byte_len: - s.insert(0, chb((bit_str >> (i * 8)) & 0xFF)) - i += 1 - return b''.join(s) - - @classmethod - def huffman_conv2bitstring(cls, s): - # type: (str) -> Tuple[int, int] - """ huffman_conv2bitstring converts a string into its bitstring - representation. It returns a tuple: the bitstring and its bitlength. - This function DOES NOT compress/decompress the string! - - @param str s: the bytestring to convert. - @return (int, int): the bitstring of s, and its bitlength. - @raise AssertionError - """ - i = 0 - ibl = len(s) * 8 - for c in s: - i = (i << 8) + orb(c) - - ret = i, ibl - assert(ret[0] >= 0) - assert(ret[1] >= 0) - return ret - - @classmethod - def huffman_compute_decode_tree(cls): - # type: () -> None - """ huffman_compute_decode_tree initializes/builds the static_huffman_tree - - @return None - @raise InvalidEncodingException if there is an encoding problem - """ - cls.static_huffman_tree = HuffmanNode(None, None) - i = 0 - for entry in cls.static_huffman_code: - parent = cls.static_huffman_tree - for idx in range(entry[1] - 1, -1, -1): - b = (entry[0] >> idx) & 1 - if isinstance(parent[b], bytes): - raise InvalidEncodingException('Huffman unique prefix violation :/') # noqa: E501 - if idx == 0: - parent[b] = chb(i) if i < 256 else EOS() - elif parent[b] is None: - parent[b] = HuffmanNode(None, None) - parent = parent[b] - i += 1 - - def __init__(self, s): - # type: (str) -> None - self._s = s - i, ibl = type(self).huffman_encode(s) - self._encoded = type(self).huffman_conv2str(i, ibl) - - def __str__(self): - # type: () -> str - return self._encoded - - def origin(self): - # type: () -> str - return plain_str(self._s) - - def __len__(self): - # type: () -> int - return len(self._encoded) - - -class HPackStrLenField(fields.Field): - """ HPackStrLenField is a StrLenField variant specialized for HTTP/2 HPack - - This variant uses an internal representation that implements HPackStringsInterface. # noqa: E501 - """ - __slots__ = ['_length_from', '_type_from'] - - def __init__(self, name, default, length_from, type_from): - # type: (str, HPackStringsInterface, Callable[[packet.Packet], int], str) -> None # noqa: E501 - super(HPackStrLenField, self).__init__(name, default) - self._length_from = length_from - self._type_from = type_from - - def addfield(self, pkt, s, val): - # type: (Optional[packet.Packet], str, HPackStringsInterface) -> str - return s + self.i2m(pkt, val) - - @staticmethod - def _parse(t, s): - # type: (bool, str) -> HPackStringsInterface - """ - @param bool t: whether this string is a huffman compressed string. - @param str s: the string to parse. - @return HPackStringsInterface: either a HPackLiteralString or HPackZString, depending on t. # noqa: E501 - @raise InvalidEncodingException - """ - if t: - i, ibl = HPackZString.huffman_conv2bitstring(s) - return HPackZString(HPackZString.huffman_decode(i, ibl)) - return HPackLiteralString(s) - - def getfield(self, pkt, s): - # type: (packet.Packet, str) -> Tuple[str, HPackStringsInterface] - """ - @param packet.Packet pkt: the packet instance containing this field instance. # noqa: E501 - @param str s: the string to parse this field from. - @return (str, HPackStringsInterface): the remaining string after this field was carved out & the extracted # noqa: E501 - value. - @raise KeyError if "type_from" is not a field of pkt or its payloads. - @raise InvalidEncodingException - """ - tmp_len = self._length_from(pkt) - t = pkt.getfieldval(self._type_from) == 1 - return s[tmp_len:], self._parse(t, s[:tmp_len]) - - def i2h(self, pkt, x): - # type: (Optional[packet.Packet], HPackStringsInterface) -> str - fmt = '' - if isinstance(x, HPackLiteralString): - fmt = "HPackLiteralString({})" - elif isinstance(x, HPackZString): - fmt = "HPackZString({})" - return fmt.format(x.origin()) - - def h2i(self, pkt, x): - # type: (packet.Packet, str) -> HPackStringsInterface - return HPackLiteralString(x) - - def m2i(self, pkt, x): - # type: (packet.Packet, str) -> HPackStringsInterface - """ - @param packet.Packet pkt: the packet instance containing this field instance. # noqa: E501 - @param str x: the string to parse. - @return HPackStringsInterface: the internal type of the value parsed from x. # noqa: E501 - @raise AssertionError - @raise InvalidEncodingException - @raise KeyError if _type_from is not one of pkt fields. - """ - t = pkt.getfieldval(self._type_from) - tmp_len = self._length_from(pkt) - - assert t is not None and tmp_len is not None, 'Conversion from string impossible: no type or length specified' # noqa: E501 - - return self._parse(t == 1, x[:tmp_len]) - - def any2i(self, pkt, x): - # type: (Optional[packet.Packet], Union[str, HPackStringsInterface]) -> HPackStringsInterface # noqa: E501 - """ - @param packet.Packet|None pkt: the packet instance containing this field instance. # noqa: E501 - @param str|HPackStringsInterface x: the value to convert - @return HPackStringsInterface: the Scapy internal value for this field - @raise AssertionError, InvalidEncodingException - """ - if isinstance(x, bytes): - assert(isinstance(pkt, packet.Packet)) - return self.m2i(pkt, x) - assert(isinstance(x, HPackStringsInterface)) - return x - - def i2m(self, pkt, x): - # type: (Optional[packet.Packet], HPackStringsInterface) -> str - return raw(x) - - def i2len(self, pkt, x): - # type: (Optional[packet.Packet], HPackStringsInterface) -> int - return len(x) - - def i2repr(self, pkt, x): - # type: (Optional[packet.Packet], HPackStringsInterface) -> str - return repr(self.i2h(pkt, x)) - -############################################################################### -# HPACK Packets # -############################################################################### - - -class HPackHdrString(packet.Packet): - """ HPackHdrString is a packet that that is serialized into a RFC7541 par5.2 - string literal repr. - """ - name = 'HPack Header String' - fields_desc = [ - fields.BitEnumField('type', None, 1, {0: 'Literal', 1: 'Compressed'}), - FieldUVarLenField('len', None, 7, length_of='data'), - HPackStrLenField( - 'data', HPackLiteralString(''), - length_from=lambda pkt: pkt.getfieldval('len'), - type_from='type' - ) - ] - - def guess_payload_class(self, payload): - # type: (str) -> base_classes.Packet_metaclass - # Trick to tell scapy that the remaining bytes of the currently - # dissected string is not a payload of this packet but of some other - # underlayer packet - return config.conf.padding_layer - - def self_build(self, field_pos_list=None): - # type: (Any) -> str - """self_build is overridden because type and len are determined at - build time, based on the "data" field internal type - """ - if self.getfieldval('type') is None: - self.type = 1 if isinstance(self.getfieldval('data'), HPackZString) else 0 # noqa: E501 - return super(HPackHdrString, self).self_build(field_pos_list) - - -class HPackHeaders(packet.Packet): - """HPackHeaders uses the "dispatch_hook" trick of Packet_metaclass to select - the correct HPack header packet type. For this, the first byte of the string # noqa: E501 - to dissect is snooped on. - """ - @classmethod - def dispatch_hook(cls, s=None, *_args, **_kwds): - # type: (Optional[str], *Any, **Any) -> base_classes.Packet_metaclass - """dispatch_hook returns the subclass of HPackHeaders that must be used - to dissect the string. - """ - if s is None: - return config.conf.raw_layer - fb = orb(s[0]) - if fb & 0x80 != 0: - return HPackIndexedHdr - if fb & 0x40 != 0: - return HPackLitHdrFldWithIncrIndexing - if fb & 0x20 != 0: - return HPackDynamicSizeUpdate - return HPackLitHdrFldWithoutIndexing - - def guess_payload_class(self, payload): - # type: (str) -> base_classes.Packet_metaclass - return config.conf.padding_layer - - -class HPackIndexedHdr(HPackHeaders): - """ HPackIndexedHdr implements RFC 7541 par6.1 - """ - name = 'HPack Indexed Header Field' - fields_desc = [ - HPackMagicBitField('magic', 1, 1), - UVarIntField('index', 2, 7) # Default "2" is ":method GET" - ] - - -class HPackLitHdrFldWithIncrIndexing(HPackHeaders): - """ HPackLitHdrFldWithIncrIndexing implements RFC 7541 par6.2.1 - """ - name = 'HPack Literal Header With Incremental Indexing' - fields_desc = [ - HPackMagicBitField('magic', 1, 2), - UVarIntField('index', 0, 6), # Default is New Name - fields.ConditionalField( - fields.PacketField('hdr_name', None, HPackHdrString), - lambda pkt: pkt.getfieldval('index') == 0 - ), - fields.PacketField('hdr_value', None, HPackHdrString) - ] - - -class HPackLitHdrFldWithoutIndexing(HPackHeaders): - """ HPackLitHdrFldWithIncrIndexing implements RFC 7541 par6.2.2 - and par6.2.3 - """ - name = 'HPack Literal Header Without Indexing (or Never Indexing)' - fields_desc = [ - HPackMagicBitField('magic', 0, 3), - fields.BitEnumField( - 'never_index', 0, 1, - {0: "Don't Index", 1: 'Never Index'} - ), - UVarIntField('index', 0, 4), # Default is New Name - fields.ConditionalField( - fields.PacketField('hdr_name', None, HPackHdrString), - lambda pkt: pkt.getfieldval('index') == 0 - ), - fields.PacketField('hdr_value', None, HPackHdrString) - ] - - -class HPackDynamicSizeUpdate(HPackHeaders): - """ HPackDynamicSizeUpdate implements RFC 7541 par6.3 - """ - name = 'HPack Dynamic Size Update' - fields_desc = [ - HPackMagicBitField('magic', 1, 3), - UVarIntField('max_size', 0, 5) - ] - -############################################################################### -# HTTP/2 Frames # -############################################################################### - - -class H2FramePayload(packet.Packet): - """ H2FramePayload is an empty class that is a super class of all Scapy - HTTP/2 Frame Packets - """ - -# HTTP/2 Data Frame Packets # # noqa: E501 - - -class H2DataFrame(H2FramePayload): - """ H2DataFrame implements RFC7540 par6.1 - This packet is the Data Frame to use when there is no padding. - """ - type_id = 0 - END_STREAM_FLAG = 0 # 0x1 - PADDED_FLAG = 3 # 0x8 - flags = { - END_STREAM_FLAG: fields.MultiFlagsEntry('ES', 'End Stream'), - PADDED_FLAG: fields.MultiFlagsEntry('P', 'Padded') - } - - name = 'HTTP/2 Data Frame' - fields_desc = [ - fields.StrField('data', '') - ] - - -class H2PaddedDataFrame(H2DataFrame): - """ H2DataFrame implements RFC7540 par6.1 - This packet is the Data Frame to use when there is padding. - """ - __slots__ = ['s_len'] - - name = 'HTTP/2 Padded Data Frame' - fields_desc = [ - fields.FieldLenField('padlen', None, length_of='padding', fmt="B"), - fields.StrLenField('data', '', - length_from=lambda pkt: pkt.get_data_len() - ), - fields.StrLenField('padding', '', - length_from=lambda pkt: pkt.getfieldval('padlen') - ) - ] - - def get_data_len(self): - # type: () -> int - """ get_data_len computes the length of the data field - - To do this computation, the length of the padlen field and the actual - padding is subtracted to the string that was provided to the pre_dissect # noqa: E501 - fun of the pkt parameter - @return int; length of the data part of the HTTP/2 frame packet provided as parameter # noqa: E501 - @raise AssertionError - """ - padding_len = self.getfieldval('padlen') - fld, fval = self.getfield_and_val('padlen') - padding_len_len = fld.i2len(self, fval) - - ret = self.s_len - padding_len_len - padding_len - assert(ret >= 0) - return ret - - def pre_dissect(self, s): - # type: (str) -> str - """pre_dissect is filling the s_len property of this instance. This - property is later used during the getfield call of the "data" field when # noqa: E501 - trying to evaluate the length of the StrLenField! This "trick" works - because the underlayer packet (H2Frame) is assumed to override the - "extract_padding" method and to only provide to this packet the data - necessary for this packet. Tricky, tricky, will break some day probably! # noqa: E501 - """ - self.s_len = len(s) - return s - - -# HTTP/2 Header Frame Packets # # noqa: E501 - -class H2AbstractHeadersFrame(H2FramePayload): - """Superclass of all variants of HTTP/2 Header Frame Packets. - May be used for type checking. - """ - - -class H2HeadersFrame(H2AbstractHeadersFrame): - """ H2HeadersFrame implements RFC 7540 par6.2 Headers Frame - when there is no padding and no priority information - - The choice of decomposing into four classes is probably preferable to having # noqa: E501 - numerous conditional fields based on the underlayer :/ - """ - type_id = 1 - END_STREAM_FLAG = 0 # 0x1 - END_HEADERS_FLAG = 2 # 0x4 - PADDED_FLAG = 3 # 0x8 - PRIORITY_FLAG = 5 # 0x20 - flags = { - END_STREAM_FLAG: fields.MultiFlagsEntry('ES', 'End Stream'), - END_HEADERS_FLAG: fields.MultiFlagsEntry('EH', 'End Headers'), - PADDED_FLAG: fields.MultiFlagsEntry('P', 'Padded'), - PRIORITY_FLAG: fields.MultiFlagsEntry('+', 'Priority') - } - - name = 'HTTP/2 Headers Frame' - fields_desc = [ - fields.PacketListField('hdrs', [], HPackHeaders) - ] - - -class H2PaddedHeadersFrame(H2AbstractHeadersFrame): - """ H2PaddedHeadersFrame is the variant of H2HeadersFrame where padding flag - is set and priority flag is cleared - """ - __slots__ = ['s_len'] - - name = 'HTTP/2 Headers Frame with Padding' - fields_desc = [ - fields.FieldLenField('padlen', None, length_of='padding', fmt='B'), - fields.PacketListField('hdrs', [], HPackHeaders, - length_from=lambda pkt: pkt.get_hdrs_len() - ), - fields.StrLenField('padding', '', - length_from=lambda pkt: pkt.getfieldval('padlen') - ) - ] - - def get_hdrs_len(self): - # type: () -> int - """ get_hdrs_len computes the length of the hdrs field - - To do this computation, the length of the padlen field and the actual - padding is subtracted to the string that was provided to the pre_dissect # noqa: E501 - fun of the pkt parameter. - @return int; length of the data part of the HTTP/2 frame packet provided as parameter # noqa: E501 - @raise AssertionError - """ - padding_len = self.getfieldval('padlen') - fld, fval = self.getfield_and_val('padlen') - padding_len_len = fld.i2len(self, fval) - - ret = self.s_len - padding_len_len - padding_len - assert(ret >= 0) - return ret - - def pre_dissect(self, s): - # type: (str) -> str - """pre_dissect is filling the s_len property of this instance. This - property is later used during the parsing of the hdrs PacketListField - when trying to evaluate the length of the PacketListField! This "trick" - works because the underlayer packet (H2Frame) is assumed to override the # noqa: E501 - "extract_padding" method and to only provide to this packet the data - necessary for this packet. Tricky, tricky, will break some day probably! # noqa: E501 - """ - self.s_len = len(s) - return s - - -class H2PriorityHeadersFrame(H2AbstractHeadersFrame): - """ H2PriorityHeadersFrame is the variant of H2HeadersFrame where priority flag - is set and padding flag is cleared - """ - __slots__ = ['s_len'] - - name = 'HTTP/2 Headers Frame with Priority' - fields_desc = [ - fields.BitField('exclusive', 0, 1), - fields.BitField('stream_dependency', 0, 31), - fields.ByteField('weight', 0), - # This PacketListField will consume all remaining bytes; not a problem - # because the underlayer (H2Frame) overrides "extract_padding" so that - # this Packet only get to parser what it needs to - fields.PacketListField('hdrs', [], HPackHeaders), - ] - - -class H2PaddedPriorityHeadersFrame(H2AbstractHeadersFrame): - """ H2PaddedPriorityHeadersFrame is the variant of H2HeadersFrame where - both priority and padding flags are set - """ - __slots__ = ['s_len'] - - name = 'HTTP/2 Headers Frame with Padding and Priority' - fields_desc = [ - fields.FieldLenField('padlen', None, length_of='padding', fmt='B'), - fields.BitField('exclusive', 0, 1), - fields.BitField('stream_dependency', 0, 31), - fields.ByteField('weight', 0), - fields.PacketListField('hdrs', [], HPackHeaders, - length_from=lambda pkt: pkt.get_hdrs_len() - ), - fields.StrLenField('padding', '', - length_from=lambda pkt: pkt.getfieldval('padlen') - ) - ] - - def get_hdrs_len(self): - # type: () -> int - """ get_hdrs_len computes the length of the hdrs field - - To do this computation, the length of the padlen field, the priority - information fields and the actual padding is subtracted to the string - that was provided to the pre_dissect fun of the pkt parameter. - @return int: the length of the hdrs field - @raise AssertionError - """ - - padding_len = self.getfieldval('padlen') - fld, fval = self.getfield_and_val('padlen') - padding_len_len = fld.i2len(self, fval) - bit_cnt = self.get_field('exclusive').size - bit_cnt += self.get_field('stream_dependency').size - fld, fval = self.getfield_and_val('weight') - weight_len = fld.i2len(self, fval) - ret = int(self.s_len - - padding_len_len - - padding_len - - (bit_cnt / 8) - - weight_len - ) - assert(ret >= 0) - return ret - - def pre_dissect(self, s): - # type: (str) -> str - """pre_dissect is filling the s_len property of this instance. This - property is later used during the parsing of the hdrs PacketListField - when trying to evaluate the length of the PacketListField! This "trick" - works because the underlayer packet (H2Frame) is assumed to override the # noqa: E501 - "extract_padding" method and to only provide to this packet the data - necessary for this packet. Tricky, tricky, will break some day probably! # noqa: E501 - """ - self.s_len = len(s) - return s - -# HTTP/2 Priority Frame Packets # # noqa: E501 - - -class H2PriorityFrame(H2FramePayload): - """ H2PriorityFrame implements RFC 7540 par6.3 - """ - type_id = 2 - name = 'HTTP/2 Priority Frame' - fields_desc = [ - fields.BitField('exclusive', 0, 1), - fields.BitField('stream_dependency', 0, 31), - fields.ByteField('weight', 0) - ] - -# HTTP/2 Errors # # noqa: E501 - - -class H2ErrorCodes(object): - """ H2ErrorCodes is an enumeration of the error codes defined in - RFC7540 par7. - This enumeration is not part of any frame because the error codes are in - common with H2ResetFrame and H2GoAwayFrame. - """ - - NO_ERROR = 0x0 - PROTOCOL_ERROR = 0x1 - INTERNAL_ERROR = 0x2 - FLOW_CONTROL_ERROR = 0x3 - SETTINGS_TIMEOUT = 0x4 - STREAM_CLOSED = 0x5 - FRAME_SIZE_ERROR = 0x6 - REFUSED_STREAM = 0x7 - CANCEL = 0x8 - COMPRESSION_ERROR = 0x9 - CONNECT_ERROR = 0xa - ENHANCE_YOUR_CALM = 0xb - INADEQUATE_SECURITY = 0xc - HTTP_1_1_REQUIRED = 0xd - - literal = { - NO_ERROR: 'No error', - PROTOCOL_ERROR: 'Protocol error', - INTERNAL_ERROR: 'Internal error', - FLOW_CONTROL_ERROR: 'Flow control error', - SETTINGS_TIMEOUT: 'Settings timeout', - STREAM_CLOSED: 'Stream closed', - FRAME_SIZE_ERROR: 'Frame size error', - REFUSED_STREAM: 'Refused stream', - CANCEL: 'Cancel', - COMPRESSION_ERROR: 'Compression error', - CONNECT_ERROR: 'Control error', - ENHANCE_YOUR_CALM: 'Enhance your calm', - INADEQUATE_SECURITY: 'Inadequate security', - HTTP_1_1_REQUIRED: 'HTTP/1.1 required' - } - - -# HTTP/2 Reset Frame Packets # # noqa: E501 - -class H2ResetFrame(H2FramePayload): - """ H2ResetFrame implements RFC 7540 par6.4 - """ - type_id = 3 - name = 'HTTP/2 Reset Frame' - fields_desc = [ - fields.EnumField('error', 0, H2ErrorCodes.literal, fmt='!I') - ] - - -# HTTP/2 Settings Frame Packets # # noqa: E501 - -class H2Setting(packet.Packet): - """ H2Setting implements a setting, as defined in RFC7540 par6.5.1 - """ - SETTINGS_HEADER_TABLE_SIZE = 0x1 - SETTINGS_ENABLE_PUSH = 0x2 - SETTINGS_MAX_CONCURRENT_STREAMS = 0x3 - SETTINGS_INITIAL_WINDOW_SIZE = 0x4 - SETTINGS_MAX_FRAME_SIZE = 0x5 - SETTINGS_MAX_HEADER_LIST_SIZE = 0x6 - - name = 'HTTP/2 Setting' - fields_desc = [ - fields.EnumField('id', 0, { - SETTINGS_HEADER_TABLE_SIZE: 'Header table size', - SETTINGS_ENABLE_PUSH: 'Enable push', - SETTINGS_MAX_CONCURRENT_STREAMS: 'Max concurrent streams', - SETTINGS_INITIAL_WINDOW_SIZE: 'Initial window size', - SETTINGS_MAX_FRAME_SIZE: 'Max frame size', - SETTINGS_MAX_HEADER_LIST_SIZE: 'Max header list size' - }, fmt='!H'), - fields.IntField('value', 0) - ] - - def guess_payload_class(self, payload): - # type: (str) -> base_classes.Packet_metaclass - return config.conf.padding_layer - - -class H2SettingsFrame(H2FramePayload): - """ H2SettingsFrame implements RFC7540 par6.5 - """ - type_id = 4 - ACK_FLAG = 0 # 0x1 - flags = { - ACK_FLAG: fields.MultiFlagsEntry('A', 'ACK') - } - - name = 'HTTP/2 Settings Frame' - fields_desc = [ - fields.PacketListField('settings', [], H2Setting) - ] - - def __init__(self, *args, **kwargs): - """__init__ initializes this H2SettingsFrame - - If a _pkt arg is provided (by keyword), then this is an initialization - from a string to dissect and therefore the length of the string to - dissect have distinctive characteristics that we might want to check. - This is possible because the underlayer packet (H2Frame) overrides - extract_padding method to provided only the string that must be parsed - by this packet! - @raise AssertionError - """ - - # RFC7540 par6.5 p36 - assert( - len(args) == 0 or ( - isinstance(args[0], bytes) and - len(args[0]) % 6 == 0 - ) - ), 'Invalid settings frame; length is not a multiple of 6' - super(H2SettingsFrame, self).__init__(*args, **kwargs) - -# HTTP/2 Push Promise Frame Packets # # noqa: E501 - - -class H2PushPromiseFrame(H2FramePayload): - """ H2PushPromiseFrame implements RFC7540 par6.6. This packet - is the variant to use when the underlayer padding flag is cleared - """ - type_id = 5 - END_HEADERS_FLAG = 2 # 0x4 - PADDED_FLAG = 3 # 0x8 - flags = { - END_HEADERS_FLAG: fields.MultiFlagsEntry('EH', 'End Headers'), - PADDED_FLAG: fields.MultiFlagsEntry('P', 'Padded') - } - - name = 'HTTP/2 Push Promise Frame' - fields_desc = [ - fields.BitField('reserved', 0, 1), - fields.BitField('stream_id', 0, 31), - fields.PacketListField('hdrs', [], HPackHeaders) - ] - - -class H2PaddedPushPromiseFrame(H2PushPromiseFrame): - """ H2PaddedPushPromiseFrame implements RFC7540 par6.6. This - packet is the variant to use when the underlayer padding flag is set - """ - __slots__ = ['s_len'] - - name = 'HTTP/2 Padded Push Promise Frame' - fields_desc = [ - fields.FieldLenField('padlen', None, length_of='padding', fmt='B'), - fields.BitField('reserved', 0, 1), - fields.BitField('stream_id', 0, 31), - fields.PacketListField('hdrs', [], HPackHeaders, - length_from=lambda pkt: pkt.get_hdrs_len() - ), - fields.StrLenField('padding', '', - length_from=lambda pkt: pkt.getfieldval('padlen') - ) - ] - - def get_hdrs_len(self): - # type: () -> int - """ get_hdrs_len computes the length of the hdrs field - - To do this computation, the length of the padlen field, reserved, - stream_id and the actual padding is subtracted to the string that was - provided to the pre_dissect fun of the pkt parameter. - @return int: the length of the hdrs field - @raise AssertionError - """ - fld, padding_len = self.getfield_and_val('padlen') - padding_len_len = fld.i2len(self, padding_len) - bit_len = self.get_field('reserved').size - bit_len += self.get_field('stream_id').size - - ret = int(self.s_len - - padding_len_len - - padding_len - - (bit_len / 8) - ) - assert(ret >= 0) - return ret - - def pre_dissect(self, s): - # type: (str) -> str - """pre_dissect is filling the s_len property of this instance. This - property is later used during the parsing of the hdrs PacketListField - when trying to evaluate the length of the PacketListField! This "trick" - works because the underlayer packet (H2Frame) is assumed to override the # noqa: E501 - "extract_padding" method and to only provide to this packet the data - necessary for this packet. Tricky, tricky, will break some day probably! # noqa: E501 - """ - self.s_len = len(s) - return s - -# HTTP/2 Ping Frame Packets # # noqa: E501 - - -class H2PingFrame(H2FramePayload): - """ H2PingFrame implements the RFC 7540 par6.7 - """ - type_id = 6 - ACK_FLAG = 0 # 0x1 - flags = { - ACK_FLAG: fields.MultiFlagsEntry('A', 'ACK') - } - - name = 'HTTP/2 Ping Frame' - fields_desc = [ - fields.LongField('opaque', 0) - ] - - def __init__(self, *args, **kwargs): - """ - @raise AssertionError - """ - # RFC7540 par6.7 p42 - assert( - len(args) == 0 or ( - (isinstance(args[0], bytes) or - isinstance(args[0], str)) and - len(args[0]) == 8 - ) - ), 'Invalid ping frame; length is not 8' - super(H2PingFrame, self).__init__(*args, **kwargs) - - -# HTTP/2 GoAway Frame Packets # # noqa: E501 - -class H2GoAwayFrame(H2FramePayload): - """ H2GoAwayFrame implements the RFC 7540 par6.8 - """ - type_id = 7 - - name = 'HTTP/2 Go Away Frame' - fields_desc = [ - fields.BitField('reserved', 0, 1), - fields.BitField('last_stream_id', 0, 31), - fields.EnumField('error', 0, H2ErrorCodes.literal, fmt='!I'), - fields.StrField('additional_data', '') - ] - -# HTTP/2 Window Update Frame Packets # # noqa: E501 - - -class H2WindowUpdateFrame(H2FramePayload): - """ H2WindowUpdateFrame implements the RFC 7540 par6.9 - """ - type_id = 8 - - name = 'HTTP/2 Window Update Frame' - fields_desc = [ - fields.BitField('reserved', 0, 1), - fields.BitField('win_size_incr', 0, 31) - ] - - def __init__(self, *args, **kwargs): - """ - @raise AssertionError - """ - # RFC7540 par6.9 p46 - assert( - len(args) == 0 or ( - (isinstance(args[0], bytes) or - isinstance(args[0], str)) and - len(args[0]) == 4 - ) - ), 'Invalid window update frame; length is not 4' - super(H2WindowUpdateFrame, self).__init__(*args, **kwargs) - -# HTTP/2 Continuation Frame Packets # # noqa: E501 - - -class H2ContinuationFrame(H2FramePayload): - """ H2ContinuationFrame implements the RFC 7540 par6.10 - """ - type_id = 9 - END_HEADERS_FLAG = 2 # Ox4 - flags = { - END_HEADERS_FLAG: fields.MultiFlagsEntry('EH', 'End Headers') - } - - name = 'HTTP/2 Continuation Frame' - fields_desc = [ - fields.PacketListField('hdrs', [], HPackHeaders) - ] - -# HTTP/2 Base Frame Packets # # noqa: E501 - - -class H2Frame(packet.Packet): - """ H2Frame implements the frame structure as defined in RFC 7540 par4.1 - - This packet may have a payload (one of the H2FramePayload) or none, in some - rare cases such as settings acknowledgement) - """ - name = 'HTTP/2 Frame' - fields_desc = [ - fields.X3BytesField('len', None), - fields.EnumField('type', None, { - 0: 'DataFrm', - 1: 'HdrsFrm', - 2: 'PrioFrm', - 3: 'RstFrm', - 4: 'SetFrm', - 5: 'PushFrm', - 6: 'PingFrm', - 7: 'GoawayFrm', - 8: 'WinFrm', - 9: 'ContFrm' - }, "b"), - fields.MultiFlagsField('flags', set(), 8, { - H2DataFrame.type_id: H2DataFrame.flags, - H2HeadersFrame.type_id: H2HeadersFrame.flags, - H2PushPromiseFrame.type_id: H2PushPromiseFrame.flags, - H2SettingsFrame.type_id: H2SettingsFrame.flags, - H2PingFrame.type_id: H2PingFrame.flags, - H2ContinuationFrame.type_id: H2ContinuationFrame.flags, - }, - depends_on=lambda pkt: pkt.getfieldval('type') - ), - fields.BitField('reserved', 0, 1), - fields.BitField('stream_id', 0, 31) - ] - - def guess_payload_class(self, payload): - # type: (str) -> base_classes.Packet_metaclass - """ guess_payload_class returns the Class object to use for parsing a payload - This function uses the H2Frame.type field value to decide which payload to parse. The implement cannot be # noqa: E501 - performed using the simple bind_layers helper because sometimes the selection of which Class object to return # noqa: E501 - also depends on the H2Frame.flags value. - - @param payload: - @return: - """ - if len(payload) == 0: - return packet.NoPayload - - t = self.getfieldval('type') - if t == H2DataFrame.type_id: - if H2DataFrame.flags[H2DataFrame.PADDED_FLAG].short in self.getfieldval('flags'): # noqa: E501 - return H2PaddedDataFrame - return H2DataFrame - - if t == H2HeadersFrame.type_id: - if H2HeadersFrame.flags[H2HeadersFrame.PADDED_FLAG].short in self.getfieldval('flags'): # noqa: E501 - if H2HeadersFrame.flags[H2HeadersFrame.PRIORITY_FLAG].short in self.getfieldval('flags'): # noqa: E501 - return H2PaddedPriorityHeadersFrame - else: - return H2PaddedHeadersFrame - elif H2HeadersFrame.flags[H2HeadersFrame.PRIORITY_FLAG].short in self.getfieldval('flags'): # noqa: E501 - return H2PriorityHeadersFrame - return H2HeadersFrame - - if t == H2PriorityFrame.type_id: - return H2PriorityFrame - - if t == H2ResetFrame.type_id: - return H2ResetFrame - - if t == H2SettingsFrame.type_id: - return H2SettingsFrame - - if t == H2PushPromiseFrame.type_id: - if H2PushPromiseFrame.flags[H2PushPromiseFrame.PADDED_FLAG].short in self.getfieldval('flags'): # noqa: E501 - return H2PaddedPushPromiseFrame - return H2PushPromiseFrame - - if t == H2PingFrame.type_id: - return H2PingFrame - - if t == H2GoAwayFrame.type_id: - return H2GoAwayFrame - - if t == H2WindowUpdateFrame.type_id: - return H2WindowUpdateFrame - - if t == H2ContinuationFrame.type_id: - return H2ContinuationFrame - - return config.conf.padding_layer - - def extract_padding(self, s): - # type: (str) -> Tuple[str, str] - """ - @param str s: the string from which to tell the padding and the payload data apart # noqa: E501 - @return (str, str): the padding and the payload data strings - @raise AssertionError - """ - assert isinstance(self.len, six.integer_types) and self.len >= 0, 'Invalid length: negative len?' # noqa: E501 - assert len(s) >= self.len, 'Invalid length: string too short for this length' # noqa: E501 - return s[:self.len], s[self.len:] - - def post_build(self, p, pay): - # type: (str, str) -> str - """ - @param str p: the stringified packet - @param str pay: the stringified payload - @return str: the stringified packet and payload, with the packet length field "patched" # noqa: E501 - @raise AssertionError - """ - # This logic, while awkward in the post_build and more reasonable in - # a self_build is implemented here for performance tricks reason - if self.getfieldval('len') is None: - assert(len(pay) < (1 << 24)), 'Invalid length: payload is too long' - p = struct.pack('!L', len(pay))[1:] + p[3:] - return super(H2Frame, self).post_build(p, pay) - - -class H2Seq(packet.Packet): - """ H2Seq is a helper packet that contains several H2Frames and their - payload. This packet can be used, for instance, while reading manually from - a TCP socket. - """ - name = 'HTTP/2 Frame Sequence' - fields_desc = [ - fields.PacketListField('frames', [], H2Frame) - ] - - def guess_payload_class(self, payload): - # type: (str) -> base_classes.Packet_metaclass - return config.conf.padding_layer - - -packet.bind_layers(H2Frame, H2DataFrame, {'type': H2DataFrame.type_id}) -packet.bind_layers(H2Frame, H2PaddedDataFrame, {'type': H2DataFrame.type_id}) -packet.bind_layers(H2Frame, H2HeadersFrame, {'type': H2HeadersFrame.type_id}) -packet.bind_layers(H2Frame, H2PaddedHeadersFrame, {'type': H2HeadersFrame.type_id}) # noqa: E501 -packet.bind_layers(H2Frame, H2PriorityHeadersFrame, {'type': H2HeadersFrame.type_id}) # noqa: E501 -packet.bind_layers(H2Frame, H2PaddedPriorityHeadersFrame, {'type': H2HeadersFrame.type_id}) # noqa: E501 -packet.bind_layers(H2Frame, H2PriorityFrame, {'type': H2PriorityFrame.type_id}) -packet.bind_layers(H2Frame, H2ResetFrame, {'type': H2ResetFrame.type_id}) -packet.bind_layers(H2Frame, H2SettingsFrame, {'type': H2SettingsFrame.type_id}) -packet.bind_layers(H2Frame, H2PingFrame, {'type': H2PingFrame.type_id}) -packet.bind_layers(H2Frame, H2PushPromiseFrame, {'type': H2PushPromiseFrame.type_id}) # noqa: E501 -packet.bind_layers(H2Frame, H2PaddedPushPromiseFrame, {'type': H2PaddedPushPromiseFrame.type_id}) # noqa: E501 -packet.bind_layers(H2Frame, H2GoAwayFrame, {'type': H2GoAwayFrame.type_id}) -packet.bind_layers(H2Frame, H2WindowUpdateFrame, {'type': H2WindowUpdateFrame.type_id}) # noqa: E501 -packet.bind_layers(H2Frame, H2ContinuationFrame, {'type': H2ContinuationFrame.type_id}) # noqa: E501 - - -# HTTP/2 Connection Preface # # noqa: E501 -# From RFC 7540 par3.5 -H2_CLIENT_CONNECTION_PREFACE = bytes_hex('505249202a20485454502f322e300d0a0d0a534d0d0a0d0a') # noqa: E501 - - -############################################################################### -# HTTP/2 Helpers # -############################################################################### - -class HPackHdrEntry(Sized): - """ HPackHdrEntry is an entry of the HPackHdrTable helper - - Each HPackHdrEntry instance is a header line (name and value). Names are - normalized (lowercase), according to RFC 7540 par8.1.2 - """ - __slots__ = ['_name', '_len', '_value'] - - def __init__(self, name, value): - # type: (str, str) -> None - """ - @raise AssertionError - """ - assert(len(name) > 0) - - self._name = name.lower() - self._value = value - - # 32 bytes is an RFC-hardcoded value: see RFC 7541 par4.1 - self._len = (32 + len(self._name) + len(self._value)) - - def name(self): - # type: () -> str - return self._name - - def value(self): - # type: () -> str - return self._value - - def size(self): - # type: () -> int - """ size returns the "length" of the header entry, as defined in - RFC 7541 par4.1. - """ - return self._len - - __len__ = size - - def __str__(self): - # type: () -> str - """ __str__ returns the header as it would be formatted in textual format - """ - if self._name.startswith(':'): - return "{} {}".format(self._name, self._value) - else: - return "{}: {}".format(self._name, self._value) - - def __bytes__(self): - return bytes_encode(self.__str__()) - - -class HPackHdrTable(Sized): - """ HPackHdrTable is a helper class that implements some of the logic - associated with indexing of headers (read and write operations in this - "registry". THe HPackHdrTable also implements convenience functions to easily # noqa: E501 - convert to and from textual representation and binary representation of - a HTTP/2 requests - """ - __slots__ = [ - '_dynamic_table', - '_dynamic_table_max_size', - '_dynamic_table_cap_size', - '_regexp' - ] - """:var _dynamic_table: the list containing entries requested to be added by - the peer and registered with a register() call - :var _dynamic_table_max_size: the current maximum size of the dynamic table - in bytes. This value is updated with the Dynamic Table Size Update messages - defined in RFC 7541 par6.3 - :var _dynamic_table_cap_size: the maximum size of the dynamic table in - bytes. This value is updated with the SETTINGS_HEADER_TABLE_SIZE HTTP/2 - setting. - """ - - # Manually imported from RFC 7541 Appendix A - _static_entries = { - 1: HPackHdrEntry(':authority', ''), - 2: HPackHdrEntry(':method', 'GET'), - 3: HPackHdrEntry(':method', 'POST'), - 4: HPackHdrEntry(':path', '/'), - 5: HPackHdrEntry(':path', '/index.html'), - 6: HPackHdrEntry(':scheme', 'http'), - 7: HPackHdrEntry(':scheme', 'https'), - 8: HPackHdrEntry(':status', '200'), - 9: HPackHdrEntry(':status', '204'), - 10: HPackHdrEntry(':status', '206'), - 11: HPackHdrEntry(':status', '304'), - 12: HPackHdrEntry(':status', '400'), - 13: HPackHdrEntry(':status', '404'), - 14: HPackHdrEntry(':status', '500'), - 15: HPackHdrEntry('accept-charset', ''), - 16: HPackHdrEntry('accept-encoding', 'gzip, deflate'), - 17: HPackHdrEntry('accept-language', ''), - 18: HPackHdrEntry('accept-ranges', ''), - 19: HPackHdrEntry('accept', ''), - 20: HPackHdrEntry('access-control-allow-origin', ''), - 21: HPackHdrEntry('age', ''), - 22: HPackHdrEntry('allow', ''), - 23: HPackHdrEntry('authorization', ''), - 24: HPackHdrEntry('cache-control', ''), - 25: HPackHdrEntry('content-disposition', ''), - 26: HPackHdrEntry('content-encoding', ''), - 27: HPackHdrEntry('content-language', ''), - 28: HPackHdrEntry('content-length', ''), - 29: HPackHdrEntry('content-location', ''), - 30: HPackHdrEntry('content-range', ''), - 31: HPackHdrEntry('content-type', ''), - 32: HPackHdrEntry('cookie', ''), - 33: HPackHdrEntry('date', ''), - 34: HPackHdrEntry('etag', ''), - 35: HPackHdrEntry('expect', ''), - 36: HPackHdrEntry('expires', ''), - 37: HPackHdrEntry('from', ''), - 38: HPackHdrEntry('host', ''), - 39: HPackHdrEntry('if-match', ''), - 40: HPackHdrEntry('if-modified-since', ''), - 41: HPackHdrEntry('if-none-match', ''), - 42: HPackHdrEntry('if-range', ''), - 43: HPackHdrEntry('if-unmodified-since', ''), - 44: HPackHdrEntry('last-modified', ''), - 45: HPackHdrEntry('link', ''), - 46: HPackHdrEntry('location', ''), - 47: HPackHdrEntry('max-forwards', ''), - 48: HPackHdrEntry('proxy-authenticate', ''), - 49: HPackHdrEntry('proxy-authorization', ''), - 50: HPackHdrEntry('range', ''), - 51: HPackHdrEntry('referer', ''), - 52: HPackHdrEntry('refresh', ''), - 53: HPackHdrEntry('retry-after', ''), - 54: HPackHdrEntry('server', ''), - 55: HPackHdrEntry('set-cookie', ''), - 56: HPackHdrEntry('strict-transport-security', ''), - 57: HPackHdrEntry('transfer-encoding', ''), - 58: HPackHdrEntry('user-agent', ''), - 59: HPackHdrEntry('vary', ''), - 60: HPackHdrEntry('via', ''), - 61: HPackHdrEntry('www-authenticate', ''), - } - - # The value of this variable cannot be determined at declaration time. It is # noqa: E501 - # initialized by an init_static_table call - _static_entries_last_idx = None - - @classmethod - def init_static_table(cls): - # type: () -> None - cls._static_entries_last_idx = max(cls._static_entries) - - def __init__(self, dynamic_table_max_size=4096, dynamic_table_cap_size=4096): # noqa: E501 - # type: (int, int) -> None - """ - @param int dynamic_table_max_size: the current maximum size of the dynamic entry table in bytes # noqa: E501 - @param int dynamic_table_cap_size: the maximum-maximum size of the dynamic entry table in bytes # noqa: E501 - @raises AssertionError - """ - self._regexp = None - if isinstance(type(self)._static_entries_last_idx, type(None)): - type(self).init_static_table() - - assert dynamic_table_max_size <= dynamic_table_cap_size, \ - 'EINVAL: dynamic_table_max_size too large; expected value is less or equal to dynamic_table_cap_size' # noqa: E501 - - self._dynamic_table = [] # type: List[HPackHdrEntry] - self._dynamic_table_max_size = dynamic_table_max_size - self._dynamic_table_cap_size = dynamic_table_cap_size - - def __getitem__(self, idx): - # type: (int) -> HPackHdrEntry - """Gets an element from the header tables (static or dynamic indifferently) - - @param int idx: the index number of the entry to retrieve. If the index - value is superior to the last index of the static entry table, then the - dynamic entry type is requested, following the procedure described in - RFC 7541 par2.3.3 - @return HPackHdrEntry: the entry defined at this requested index. If the entry does not exist, KeyError is # noqa: E501 - raised - @raise KeyError, AssertionError - """ - assert(idx >= 0) - if idx > type(self)._static_entries_last_idx: - idx -= type(self)._static_entries_last_idx + 1 - if idx >= len(self._dynamic_table): - raise KeyError( - 'EINVAL: idx: out-of-bound read: {}; maximum index: {}'.format(idx, len(self._dynamic_table)) # noqa: E501 - ) - return self._dynamic_table[idx] - return type(self)._static_entries[idx] - - def resize(self, ns): - # type: (int) -> None - """Resize the dynamic table. If the new size (ns) must be between 0 and - the cap size. If the new size is lower than the current size of the - dynamic table, entries are evicted. - @param int ns: the new size of the dynamic table - @raise AssertionError - """ - assert 0 <= ns <= self._dynamic_table_cap_size, \ - 'EINVAL: ns: out-of-range value; expected value is in the range [0;{}['.format(self._dynamic_table_cap_size) # noqa: E501 - - old_size = self._dynamic_table_max_size - self._dynamic_table_max_size = ns - if old_size > self._dynamic_table_max_size: - self._reduce_dynamic_table() - - def recap(self, nc): - # type: (int) -> None - """recap changes the maximum size limit of the dynamic table. It also - proceeds to a resize(), if the new size is lower than the previous one. - @param int nc: the new cap of the dynamic table (that is the maximum-maximum size) # noqa: E501 - @raise AssertionError - """ - assert(nc >= 0) - t = self._dynamic_table_cap_size > nc - self._dynamic_table_cap_size = nc - - if t: - # The RFC is not clear about whether this resize should happen; - # we do it anyway - self.resize(nc) - - def _reduce_dynamic_table(self, new_entry_size=0): - # type: (int) -> None - """_reduce_dynamic_table evicts entries from the dynamic table until it - fits in less than the current size limit. The optional parameter, - new_entry_size, allows the resize to happen so that a new entry of this - size fits in. - @param int new_entry_size: if called before adding a new entry, the size of the new entry in bytes (following # noqa: E501 - the RFC7541 definition of the size of an entry) - @raise AssertionError - """ - assert(new_entry_size >= 0) - cur_sz = len(self) - dyn_tbl_sz = len(self._dynamic_table) - while dyn_tbl_sz > 0 and cur_sz + new_entry_size > self._dynamic_table_max_size: # noqa: E501 - last_elmt_sz = len(self._dynamic_table[-1]) - self._dynamic_table.pop() - dyn_tbl_sz -= 1 - cur_sz -= last_elmt_sz - - def register(self, hdrs): - # type: (Union[HPackLitHdrFldWithIncrIndexing, H2Frame, List[HPackHeaders]]) -> None # noqa: E501 - """register adds to this table the instances of - HPackLitHdrFldWithIncrIndexing provided as parameters. - - A H2Frame with a H2HeadersFrame payload can be provided, as much as a - python list of HPackHeaders or a single HPackLitHdrFldWithIncrIndexing - instance. - @param HPackLitHdrFldWithIncrIndexing|H2Frame|list of HPackHeaders hdrs: the header(s) to register # noqa: E501 - @raise AssertionError - """ - if isinstance(hdrs, H2Frame): - hdrs = [hdr for hdr in hdrs.payload.hdrs if isinstance(hdr, HPackLitHdrFldWithIncrIndexing)] # noqa: E501 - elif isinstance(hdrs, HPackLitHdrFldWithIncrIndexing): - hdrs = [hdrs] - else: - hdrs = [hdr for hdr in hdrs if isinstance(hdr, HPackLitHdrFldWithIncrIndexing)] # noqa: E501 - - for hdr in hdrs: - if hdr.index == 0: - hdr_name = hdr.hdr_name.getfieldval('data').origin() - else: - idx = int(hdr.index) - hdr_name = self[idx].name() - hdr_value = hdr.hdr_value.getfieldval('data').origin() - - # Note: we do not delete any existing hdrentry with the same names - # and values, as dictated by RFC 7541 par2.3.2 - - entry = HPackHdrEntry(hdr_name, hdr_value) - # According to RFC7541 par4.4, "Before a new entry is added to - # the dynamic table, entries are evicted - # from the end of the dynamic table until the size of the dynamic - # table is less than or equal to (maximum size - new entry size) - # or until the table is empty" - # Also, "It is not an error to attempt to add an entry that is - # larger than the maximum size; an attempt to add an entry larger - # than the maximum size causes the table to be emptied of all - # existing entries and results in an empty table" - # For this reason, we first call the _reduce_dynamic_table and - # then throw an assertion error if the new entry does not fit in - new_entry_len = len(entry) - self._reduce_dynamic_table(new_entry_len) - assert(new_entry_len <= self._dynamic_table_max_size) - self._dynamic_table.insert(0, entry) - - def get_idx_by_name(self, name): - # type: (str) -> Optional[int] - """ get_idx_by_name returns the index of a matching registered header - - This implementation will prefer returning a static entry index whenever - possible. If multiple matching header name are found in the static - table, there is insurance that the first entry (lowest index number) - will be returned. - If no matching header is found, this method returns None. - """ - name = name.lower() - for key, val in six.iteritems(type(self)._static_entries): - if val.name() == name: - return key - for idx, val in enumerate(self._dynamic_table): - if val.name() == name: - return type(self)._static_entries_last_idx + idx + 1 - return None - - def get_idx_by_name_and_value(self, name, value): - # type: (str, str) -> Optional[int] - """ get_idx_by_name_and_value returns the index of a matching registered - header - - This implementation will prefer returning a static entry index whenever - possible. If multiple matching headers are found in the dynamic table, - the lowest index is returned - If no matching header is found, this method returns None. - """ - name = name.lower() - for key, val in six.iteritems(type(self)._static_entries): - if val.name() == name and val.value() == value: - return key - for idx, val in enumerate(self._dynamic_table): - if val.name() == name and val.value() == value: - return type(self)._static_entries_last_idx + idx + 1 - return None - - def __len__(self): - # type: () -> int - """ __len__ returns the summed length of all dynamic entries - """ - return sum(len(x) for x in self._dynamic_table) - - def gen_txt_repr(self, hdrs, register=True): - # type: (Union[H2Frame, List[HPackHeaders]], Optional[bool]) -> str - """ gen_txt_repr returns a "textual" representation of the provided - headers. - - The output of this function is compatible with the input of - parse_txt_hdrs. - @param H2Frame|list of HPackHeaders hdrs: the list of headers to convert to textual representation # noqa: E501 - @param bool: whether incremental headers should be added to the dynamic table as we generate the text # noqa: E501 - representation - @return str: the textual representation of the provided headers - @raise AssertionError - """ - lst = [] - if isinstance(hdrs, H2Frame): - hdrs = hdrs.payload.hdrs - - for hdr in hdrs: - try: - if isinstance(hdr, HPackIndexedHdr): - lst.append('{}'.format(self[hdr.index])) - elif isinstance(hdr, ( - HPackLitHdrFldWithIncrIndexing, - HPackLitHdrFldWithoutIndexing - )): - if hdr.index != 0: - name = self[hdr.index].name() - else: - name = hdr.hdr_name.getfieldval('data').origin() - if name.startswith(':'): - lst.append( - '{} {}'.format( - name, - hdr.hdr_value.getfieldval('data').origin() - ) - ) - else: - lst.append( - '{}: {}'.format( - name, - hdr.hdr_value.getfieldval('data').origin() - ) - ) - if register and isinstance(hdr, HPackLitHdrFldWithIncrIndexing): # noqa: E501 - self.register(hdr) - except KeyError as e: # raised when an index is out-of-bound - print(e) - continue - return '\n'.join(lst) - - @staticmethod - def _optimize_header_length_and_packetify(s): - # type: (str) -> HPackHdrString - # type: (str) -> HPackHdrString - zs = HPackZString(s) - if len(zs) >= len(s): - return HPackHdrString(data=HPackLiteralString(s)) - return HPackHdrString(data=zs) - - def _convert_a_header_to_a_h2_header(self, hdr_name, hdr_value, is_sensitive, should_index): # noqa: E501 - # type: (str, str, Callable[[str, str], bool], Callable[[str], bool]) -> Tuple[HPackHeaders, int] # noqa: E501 - """ _convert_a_header_to_a_h2_header builds a HPackHeaders from a header - name and a value. It returns a HPackIndexedHdr whenever possible. If not, # noqa: E501 - it returns a HPackLitHdrFldWithoutIndexing or a - HPackLitHdrFldWithIncrIndexing, based on the should_index callback. - HPackLitHdrFldWithoutIndexing is forced if the is_sensitive callback - returns True and its never_index bit is set. - """ - - # If both name and value are already indexed - idx = self.get_idx_by_name_and_value(hdr_name, hdr_value) - if idx is not None: - return HPackIndexedHdr(index=idx), len(self[idx]) - - # The value is not indexed for this headers - - hdr_value = self._optimize_header_length_and_packetify(hdr_value) - - # Searching if the header name is indexed - idx = self.get_idx_by_name(hdr_name) - if idx is not None: - if is_sensitive( - hdr_name, - hdr_value.getfieldval('data').origin() - ): - return HPackLitHdrFldWithoutIndexing( - never_index=1, - index=idx, - hdr_value=hdr_value - ), len( - HPackHdrEntry( - self[idx].name(), - hdr_value.getfieldval('data').origin() - ) - ) - if should_index(hdr_name): - return HPackLitHdrFldWithIncrIndexing( - index=idx, - hdr_value=hdr_value - ), len( - HPackHdrEntry( - self[idx].name(), - hdr_value.getfieldval('data').origin() - ) - ) - return HPackLitHdrFldWithoutIndexing( - index=idx, - hdr_value=hdr_value - ), len( - HPackHdrEntry( - self[idx].name(), - hdr_value.getfieldval('data').origin() - ) - ) - - hdr_name = self._optimize_header_length_and_packetify(hdr_name) - - if is_sensitive( - hdr_name.getfieldval('data').origin(), - hdr_value.getfieldval('data').origin() - ): - return HPackLitHdrFldWithoutIndexing( - never_index=1, - index=0, - hdr_name=hdr_name, - hdr_value=hdr_value - ), len( - HPackHdrEntry( - hdr_name.getfieldval('data').origin(), - hdr_value.getfieldval('data').origin() - ) - ) - if should_index(hdr_name.getfieldval('data').origin()): - return HPackLitHdrFldWithIncrIndexing( - index=0, - hdr_name=hdr_name, - hdr_value=hdr_value - ), len( - HPackHdrEntry( - hdr_name.getfieldval('data').origin(), - hdr_value.getfieldval('data').origin() - ) - ) - return HPackLitHdrFldWithoutIndexing( - index=0, - hdr_name=hdr_name, - hdr_value=hdr_value - ), len( - HPackHdrEntry( - hdr_name.getfieldval('data').origin(), - hdr_value.getfieldval('data').origin() - ) - ) - - def _parse_header_line(self, l): - # type: (str) -> Union[Tuple[None, None], Tuple[str, str]] - - if self._regexp is None: - self._regexp = re.compile(br'^(?::([a-z\-0-9]+)|([a-z\-0-9]+):)\s+(.+)$') # noqa: E501 - - hdr_line = l.rstrip() - grp = self._regexp.match(hdr_line) - - if grp is None or len(grp.groups()) != 3: - return None, None - - if grp.group(1) is not None: - hdr_name = b':' + grp.group(1) - else: - hdr_name = grp.group(2) - return plain_str(hdr_name.lower()), plain_str(grp.group(3)) - - def parse_txt_hdrs(self, - s, # type: str - stream_id=1, # type: int - body=None, # type: Optional[str] - max_frm_sz=4096, # type: int - max_hdr_lst_sz=0, # type: int - is_sensitive=lambda n, v: False, # type: Callable[[str, str], bool] # noqa: E501 - should_index=lambda x: False, # type: Callable[[str], bool] # noqa: E501 - register=True, # type: bool - ): - # type: (...) -> H2Seq - """ parse_txt_hdrs parses headers expressed in text and converts them - into a series of H2Frames with the "correct" flags. A body can be provided # noqa: E501 - in which case, the data frames are added, bearing the End Stream flag, - instead of the H2HeadersFrame/H2ContinuationFrame. The generated frames - may respect max_frm_sz (SETTINGS_MAX_FRAME_SIZE) and - max_hdr_lst_sz (SETTINGS_MAX_HEADER_LIST_SIZE) if provided. The headers - are split into multiple headers fragment (and H2Frames) to respect these # noqa: E501 - limits. Also, a callback can be provided to tell if a header should be - never indexed (sensitive headers, such as cookies), and another callback # noqa: E501 - say if the header should be registered into the index table at all. - For an header to be registered, the is_sensitive callback must return - False AND the should_index callback should return True. This is the - default behavior. - - @param str s: the string to parse for headers - @param int stream_id: the stream id to use in the generated H2Frames - @param str|None body: the eventual body of the request, that is added to the generated frames # noqa: E501 - @param int max_frm_sz: the maximum frame size. This is used to split the headers and data frames according to # noqa: E501 - the maximum frame size negotiated for this connection - @param int max_hdr_lst_sz: the maximum size of a "header fragment" as defined in RFC7540 # noqa: E501 - @param callable is_sensitive: callback that returns True if the provided header is sensible and must be stored # noqa: E501 - in a header packet requesting this header never to be indexed - @param callable should_index: callback that returns True if the provided header should be stored in a header # noqa: E501 - packet requesting indexation in the dynamic header table. - @param bool register: whether to register new headers with incremental indexing as we parse them # noqa: E501 - @raise Exception - """ - - sio = BytesIO(s) - - base_frm_len = len(raw(H2Frame())) - - ret = H2Seq() - cur_frm = H2HeadersFrame() # type: Union[H2HeadersFrame, H2ContinuationFrame] # noqa: E501 - cur_hdr_sz = 0 - - # For each line in the headers str to parse - for hdr_line in sio: - hdr_name, hdr_value = self._parse_header_line(hdr_line) - if hdr_name is None: - continue - - new_hdr, new_hdr_len = self._convert_a_header_to_a_h2_header( - hdr_name, hdr_value, is_sensitive, should_index - ) - new_hdr_bin_len = len(raw(new_hdr)) - - if register and isinstance(new_hdr, HPackLitHdrFldWithIncrIndexing): # noqa: E501 - self.register(new_hdr) - - # The new header binary length (+ base frame size) must not exceed - # the maximum frame size or it will just never fit. Also, the - # header entry length (as specified in RFC7540 par6.5.2) must not - # exceed the maximum length of a header fragment or it will just - # never fit - if (new_hdr_bin_len + base_frm_len > max_frm_sz or - (max_hdr_lst_sz != 0 and new_hdr_len > max_hdr_lst_sz)): - raise Exception('Header too long: {}'.format(hdr_name)) - - if (max_frm_sz < len(raw(cur_frm)) + base_frm_len + new_hdr_len or - ( - max_hdr_lst_sz != 0 and - max_hdr_lst_sz < cur_hdr_sz + new_hdr_len - ) - ): - flags = set() - if isinstance(cur_frm, H2HeadersFrame) and not body: - flags.add('ES') - ret.frames.append(H2Frame(stream_id=stream_id, flags=flags) / cur_frm) # noqa: E501 - cur_frm = H2ContinuationFrame() - cur_hdr_sz = 0 - - hdr_list = cur_frm.hdrs - hdr_list += new_hdr - cur_hdr_sz += new_hdr_len - - flags = {'EH'} - if isinstance(cur_frm, H2HeadersFrame) and not body: - flags.add('ES') - ret.frames.append(H2Frame(stream_id=stream_id, flags=flags) / cur_frm) - - if body: - base_data_frm_len = len(raw(H2DataFrame())) - sio = BytesIO(body) - frgmt = sio.read(max_frm_sz - base_data_frm_len - base_frm_len) - while frgmt: - nxt_frgmt = sio.read(max_frm_sz - base_data_frm_len - base_frm_len) # noqa: E501 - flags = set() - if len(nxt_frgmt) == 0: - flags.add('ES') - ret.frames.append( - H2Frame(stream_id=stream_id, flags=flags) / H2DataFrame(data=frgmt) # noqa: E501 - ) - frgmt = nxt_frgmt - return ret diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ibeacon.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/ibeacon.py deleted file mode 100644 index fddae43190..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ibeacon.py +++ /dev/null @@ -1,101 +0,0 @@ -# -*- mode: python3; indent-tabs-mode: nil; tab-width: 4 -*- -# ibeacon.py - protocol handlers for iBeacons and other Apple devices -# -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Michael Farrell -# This program is published under a GPLv2 (or later) license -# -# scapy.contrib.description = iBeacon BLE proximity beacon -# scapy.contrib.status = loads -""" -scapy.contrib.ibeacon - Apple iBeacon Bluetooth LE proximity beacons. - -Packet format documentation can be found at at: - -* https://en.wikipedia.org/wiki/IBeacon#Packet_Structure_Byte_Map (public) -* https://developer.apple.com/ibeacon/ (official, requires license) - -""" - -from scapy.fields import ByteEnumField, LenField, PacketListField, \ - ShortField, SignedByteField, UUIDField -from scapy.layers.bluetooth import EIR_Hdr, EIR_Manufacturer_Specific_Data, \ - LowEnergyBeaconHelper -from scapy.packet import bind_layers, Packet - -APPLE_MFG = 0x004c - - -class Apple_BLE_Submessage(Packet, LowEnergyBeaconHelper): - """ - A basic Apple submessage. - """ - - name = "Apple BLE submessage" - fields_desc = [ - ByteEnumField("subtype", None, { - 0x02: "ibeacon", - 0x05: "airdrop", - 0x07: "airpods", - 0x09: "airplay_sink", - 0x0a: "airplay_src", - 0x0c: "handoff", - 0x10: "nearby", - }), - LenField("len", None, fmt="B") - ] - - def extract_padding(self, s): - # Needed to end each EIR_Element packet and make PacketListField work. - return s[:self.len], s[self.len:] - - # These methods are here in case you only want to send 1 submessage. - # It creates an Apple_BLE_Frame to wrap your (single) Apple_BLE_Submessage. - def build_frame(self): - """Wraps this submessage in a Apple_BLE_Frame.""" - return Apple_BLE_Frame(plist=[self]) - - def build_eir(self): - """See Apple_BLE_Frame.build_eir.""" - return self.build_frame().build_eir() - - -class Apple_BLE_Frame(Packet, LowEnergyBeaconHelper): - """ - The wrapper for a BLE manufacturer-specific data advertisement from Apple - devices. - - Each advertisement is composed of one or multiple submessages. - - The length of this field comes from the EIR_Hdr. - """ - name = "Apple BLE broadcast frame" - fields_desc = [ - PacketListField("plist", None, Apple_BLE_Submessage) - ] - - def build_eir(self): - """Builds a list of EIR messages to wrap this frame.""" - - return LowEnergyBeaconHelper.base_eir + [ - EIR_Hdr() / EIR_Manufacturer_Specific_Data() / self - ] - - -class IBeacon_Data(Packet): - """ - iBeacon broadcast data frame. Composed on top of an Apple_BLE_Submessage. - """ - name = "iBeacon data" - fields_desc = [ - UUIDField("uuid", None, uuid_fmt=UUIDField.FORMAT_BE), - ShortField("major", None), - ShortField("minor", None), - SignedByteField("tx_power", None), - ] - - -bind_layers(EIR_Manufacturer_Specific_Data, Apple_BLE_Frame, - company_id=APPLE_MFG) -bind_layers(Apple_BLE_Submessage, IBeacon_Data, subtype=2) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/icmp_extensions.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/icmp_extensions.py deleted file mode 100644 index 7abd4c055e..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/icmp_extensions.py +++ /dev/null @@ -1,200 +0,0 @@ -#! /usr/bin/env python - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = ICMP Extensions -# scapy.contrib.status = loads - -from __future__ import absolute_import -import struct - -import scapy -from scapy.packet import Packet, bind_layers -from scapy.fields import BitField, ByteField, ConditionalField, \ - FieldLenField, IPField, IntField, PacketListField, ShortField, \ - StrLenField -from scapy.layers.inet import IP, ICMP, checksum -from scapy.layers.inet6 import IP6Field -from scapy.error import warning -from scapy.contrib.mpls import MPLS -import scapy.modules.six as six -from scapy.config import conf - - -class ICMPExtensionObject(Packet): - name = 'ICMP Extension Object' - fields_desc = [ShortField('len', None), - ByteField('classnum', 0), - ByteField('classtype', 0)] - - def post_build(self, p, pay): - if self.len is None: - tmp_len = len(p) + len(pay) - p = struct.pack('!H', tmp_len) + p[2:] - return p + pay - - -class ICMPExtensionHeader(Packet): - name = 'ICMP Extension Header (RFC4884)' - fields_desc = [BitField('version', 2, 4), - BitField('reserved', 0, 12), - BitField('chksum', None, 16)] - - _min_ieo_len = len(ICMPExtensionObject()) - - def post_build(self, p, pay): - if self.chksum is None: - ck = checksum(p) - p = p[:2] + chr(ck >> 8) + chr(ck & 0xff) + p[4:] - return p + pay - - def guess_payload_class(self, payload): - if len(payload) < self._min_ieo_len: - return Packet.guess_payload_class(self, payload) - - # Look at fields of the generic ICMPExtensionObject to determine which - # bound extension type to use. - ieo = ICMPExtensionObject(payload) - if ieo.len < self._min_ieo_len: - return Packet.guess_payload_class(self, payload) - - for fval, cls in self.payload_guess: - if all(hasattr(ieo, k) and v == ieo.getfieldval(k) - for k, v in six.iteritems(fval)): - return cls - return ICMPExtensionObject - - -def ICMPExtension_post_dissection(self, pkt): - # RFC4884 section 5.2 says if the ICMP packet length - # is >144 then ICMP extensions start at byte 137. - - lastlayer = pkt.lastlayer() - if not isinstance(lastlayer, conf.padding_layer): - return - - if IP in pkt: - if (ICMP in pkt and - pkt[ICMP].type in [3, 11, 12] and - pkt.len > 144): - bytes = pkt[ICMP].build()[136:] - else: - return - elif scapy.layers.inet6.IPv6 in pkt: - if ((scapy.layers.inet6.ICMPv6TimeExceeded in pkt or - scapy.layers.inet6.ICMPv6DestUnreach in pkt) and - pkt.plen > 144): - bytes = pkt[scapy.layers.inet6.ICMPv6TimeExceeded].build()[136:] - else: - return - else: - return - - # validate checksum - ieh = ICMPExtensionHeader(bytes) - if checksum(ieh.build()): - return # failed - - lastlayer.load = lastlayer.load[:-len(ieh)] - lastlayer.add_payload(ieh) - - -class ICMPExtensionMPLS(ICMPExtensionObject): - name = 'ICMP Extension Object - MPLS (RFC4950)' - - fields_desc = [ShortField('len', None), - ByteField('classnum', 1), - ByteField('classtype', 1), - PacketListField('stack', [], MPLS, - length_from=lambda pkt: pkt.len - 4)] - - -class ICMPExtensionInterfaceInformation(ICMPExtensionObject): - name = 'ICMP Extension Object - Interface Information Object (RFC5837)' - - fields_desc = [ShortField('len', None), - ByteField('classnum', 2), - BitField('interface_role', 0, 2), - BitField('reserved', 0, 2), - BitField('has_ifindex', 0, 1), - BitField('has_ipaddr', 0, 1), - BitField('has_ifname', 0, 1), - BitField('has_mtu', 0, 1), - - ConditionalField( - IntField('ifindex', None), - lambda pkt: pkt.has_ifindex == 1), - - ConditionalField( - ShortField('afi', None), - lambda pkt: pkt.has_ipaddr == 1), - ConditionalField( - ShortField('reserved2', 0), - lambda pkt: pkt.has_ipaddr == 1), - ConditionalField( - IPField('ip4', None), - lambda pkt: pkt.afi == 1), - ConditionalField( - IP6Field('ip6', None), - lambda pkt: pkt.afi == 2), - - ConditionalField( - FieldLenField('ifname_len', None, fmt='B', - length_of='ifname'), - lambda pkt: pkt.has_ifname == 1), - ConditionalField( - StrLenField('ifname', None, - length_from=lambda pkt: pkt.ifname_len), - lambda pkt: pkt.has_ifname == 1), - - ConditionalField( - IntField('mtu', None), - lambda pkt: pkt.has_mtu == 1)] - - def self_build(self, field_pos_list=None): - if self.afi is None: - if self.ip4 is not None: - self.afi = 1 - elif self.ip6 is not None: - self.afi = 2 - - if self.has_ifindex and self.ifindex is None: - warning('has_ifindex set but ifindex is not set.') - if self.has_ipaddr and self.afi is None: - warning('has_ipaddr set but afi is not set.') - if self.has_ipaddr and self.ip4 is None and self.ip6 is None: - warning('has_ipaddr set but ip4 or ip6 is not set.') - if self.has_ifname and self.ifname is None: - warning('has_ifname set but ifname is not set.') - if self.has_mtu and self.mtu is None: - warning('has_mtu set but mtu is not set.') - - return ICMPExtensionObject.self_build(self, field_pos_list=field_pos_list) # noqa: E501 - - -# Add the post_dissection() method to the existing ICMPv4 and -# ICMPv6 error messages -scapy.layers.inet.ICMPerror.post_dissection = ICMPExtension_post_dissection -scapy.layers.inet.TCPerror.post_dissection = ICMPExtension_post_dissection -scapy.layers.inet.UDPerror.post_dissection = ICMPExtension_post_dissection - -scapy.layers.inet6.ICMPv6DestUnreach.post_dissection = ICMPExtension_post_dissection # noqa: E501 -scapy.layers.inet6.ICMPv6TimeExceeded.post_dissection = ICMPExtension_post_dissection # noqa: E501 - - -# ICMPExtensionHeader looks at fields from the upper layer object when -# determining which upper layer to use. -bind_layers(ICMPExtensionHeader, ICMPExtensionMPLS, classnum=1, classtype=1) -bind_layers(ICMPExtensionHeader, ICMPExtensionInterfaceInformation, classnum=2) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ife.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/ife.py deleted file mode 100644 index b331c0e1d9..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ife.py +++ /dev/null @@ -1,125 +0,0 @@ -#! /usr/bin/env python -# -# scapy.contrib.description = ForCES Inter-FE LFB type (IFE) -# scapy.contrib.status = loads - -""" - IFE - ForCES Inter-FE LFB type - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - :author: Alexander Aring, aring@mojatatu.com - :license: GPLv2 - - This module is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This module 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. - - :description: - - This module provides Scapy layers for the IFE protocol. - - normative references: - - RFC 8013 - Forwarding and Control Element Separation (ForCES) - Inter-FE Logical Functional Block (LFB) - https://tools.ietf.org/html/rfc8013 -""" - -import functools - -from scapy.data import ETHER_TYPES -from scapy.packet import Packet, bind_layers -from scapy.fields import FieldLenField, PacketListField, IntField, \ - MultipleTypeField, ShortField, ShortEnumField, StrField, PadField -from scapy.layers.l2 import Ether - -ETH_P_IFE = 0xed3e -ETHER_TYPES['IFE'] = ETH_P_IFE - -# The value to set for the skb mark. -IFE_META_SKBMARK = 0x0001 -IFE_META_HASHID = 0x0002 -# Value to set for priority in the skb structure. -IFE_META_PRIO = 0x0003 -IFE_META_QMAP = 0x0004 -# Value to set for the traffic control index in the skb structure. -IFE_META_TCINDEX = 0x0005 - -IFE_META_TYPES = { - IFE_META_SKBMARK: "SKBMark", - IFE_META_HASHID: "HashID", - IFE_META_PRIO: "Prio", - IFE_META_QMAP: "QMap", - IFE_META_TCINDEX: "TCIndex" -} - -IFE_TYPES_SHORT = [IFE_META_TCINDEX] -IFE_TYPES_INT = [ - IFE_META_SKBMARK, - IFE_META_PRIO, -] - - -class IFETlv(Packet): - """ - Parent Class interhit by all ForCES TLV strucutures - """ - name = "IFETlv" - - fields_desc = [ - ShortEnumField("type", 0, IFE_META_TYPES), - FieldLenField("length", None, length_of="value", - adjust=lambda pkt, x: x + 4), - MultipleTypeField( - [ - (PadField(ShortField("value", 0), 4, padwith=b'\x00'), - lambda pkt: pkt.type in IFE_TYPES_SHORT), - (PadField(IntField("value", 0), 4, padwith=b'\x00'), - lambda pkt: pkt.type in IFE_TYPES_INT), - ], - PadField(IntField("value", 0), 4, padwith=b'\x00') - ), - ] - - def extract_padding(self, s): - return "", s - - -class IFETlvStr(IFETlv): - """ - A IFE TLV with variable payload - """ - fields_desc = [ - ShortEnumField("type", 0, IFE_META_TYPES), - FieldLenField("length", None, length_of="value", - adjust=lambda pkt, x: x + 4), - StrField("value", "") - ] - - -class IFE(Packet): - """ - Main IFE Packet Class - """ - name = "IFE" - - fields_desc = [ - FieldLenField("mdlen", None, length_of="tlvs", - adjust=lambda pkt, x: x + 2), - PacketListField("tlvs", None, IFETlv), - ] - - -IFESKBMark = functools.partial(IFETlv, type=IFE_META_SKBMARK) -IFEHashID = functools.partial(IFETlv, type=IFE_META_HASHID) -IFEPrio = functools.partial(IFETlv, type=IFE_META_PRIO) -IFEQMap = functools.partial(IFETlv, type=IFE_META_QMAP) -IFETCIndex = functools.partial(IFETlv, type=IFE_META_TCINDEX) - -bind_layers(Ether, IFE, type=ETH_P_IFE) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/igmp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/igmp.py deleted file mode 100644 index e50a27d252..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/igmp.py +++ /dev/null @@ -1,165 +0,0 @@ -#! /usr/bin/env python - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# flake8: noqa: E501 - -# scapy.contrib.description = Internet Group Management Protocol v1/v2 (IGMP/IGMPv2) -# scapy.contrib.status = loads - -from __future__ import print_function -from scapy.compat import chb, orb -from scapy.error import warning -from scapy.fields import ByteEnumField, ByteField, IPField, XShortField -from scapy.layers.inet import IP, IPOption_Router_Alert -from scapy.layers.l2 import Ether, getmacbyip -from scapy.packet import bind_layers, Packet -from scapy.utils import atol, checksum - - -def isValidMCAddr(ip): - """convert dotted quad string to long and check the first octet""" - FirstOct = atol(ip) >> 24 & 0xFF - return (FirstOct >= 224) and (FirstOct <= 239) - - -class IGMP(Packet): - """IGMP Message Class for v1 and v2. - -This class is derived from class Packet. You need call "igmpize()" -so the packet is transformed according the RFC when sent. -a=Ether(src="00:01:02:03:04:05") -b=IP(src="1.2.3.4") -c=IGMP(type=0x12, gaddr="224.2.3.4") -x = a/b/c -x[IGMP].igmpize() -sendp(a/b/c, iface="en0") - - Parameters: - type IGMP type field, 0x11, 0x12, 0x16 or 0x17 - mrcode Maximum Response time (zero for v1) - gaddr Multicast Group Address 224.x.x.x/4 - -See RFC2236, Section 2. Introduction for definitions of proper -IGMPv2 message format http://www.faqs.org/rfcs/rfc2236.html - - """ - name = "IGMP" - - igmptypes = {0x11: "Group Membership Query", - 0x12: "Version 1 - Membership Report", - 0x16: "Version 2 - Membership Report", - 0x17: "Leave Group"} - - fields_desc = [ByteEnumField("type", 0x11, igmptypes), - ByteField("mrcode", 20), - XShortField("chksum", None), - IPField("gaddr", "0.0.0.0")] - - def post_build(self, p, pay): - """Called implicitly before a packet is sent to compute and place IGMP checksum. - - Parameters: - self The instantiation of an IGMP class - p The IGMP message in hex in network byte order - pay Additional payload for the IGMP message - """ - p += pay - if self.chksum is None: - ck = checksum(p) - # TRex Change - p = p[:2] + bytes([ck>>8]) + bytes([ck&0xff]) + p[4:] - return p - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 4: - from scapy.contrib.igmpv3 import IGMPv3 - if orb(_pkt[0]) in [0x22, 0x30, 0x31, 0x32]: - return IGMPv3 - if orb(_pkt[0]) == 0x11 and len(_pkt) >= 12: - return IGMPv3 - return IGMP - - def igmpize(self): - """Called to explicitly fixup the packet according to the IGMP RFC - - The rules are: - General: - 1. the Max Response time is meaningful only in Membership Queries and should be zero - IP: - 1. Send General Group Query to 224.0.0.1 (all systems) - 2. Send Leave Group to 224.0.0.2 (all routers) - 3a.Otherwise send the packet to the group address - 3b.Send reports/joins to the group address - 4. ttl = 1 (RFC 2236, section 2) - 5. send the packet with the router alert IP option (RFC 2236, section 2) - Ether: - 1. Recalculate destination - - Returns: - True The tuple ether/ip/self passed all check and represents - a proper IGMP packet. - False One of more validation checks failed and no fields - were adjusted. - - The function will examine the IGMP message to assure proper format. - Corrections will be attempted if possible. The IP header is then properly - adjusted to ensure correct formatting and assignment. The Ethernet header - is then adjusted to the proper IGMP packet format. - """ - gaddr = self.gaddr if hasattr(self, "gaddr") and self.gaddr else "0.0.0.0" # noqa: E501 - underlayer = self.underlayer - if self.type not in [0x11, 0x30]: # General Rule 1 # noqa: E501 - self.mrcode = 0 - if isinstance(underlayer, IP): - if (self.type == 0x11): - if (gaddr == "0.0.0.0"): - underlayer.dst = "224.0.0.1" # IP rule 1 # noqa: E501 - elif isValidMCAddr(gaddr): - underlayer.dst = gaddr # IP rule 3a # noqa: E501 - else: - warning("Invalid IGMP Group Address detected !") - return False - elif ((self.type == 0x17) and isValidMCAddr(gaddr)): - underlayer.dst = "224.0.0.2" # IP rule 2 # noqa: E501 - elif ((self.type == 0x12) or (self.type == 0x16)) and (isValidMCAddr(gaddr)): # noqa: E501 - underlayer.dst = gaddr # IP rule 3b # noqa: E501 - else: - warning("Invalid IGMP Type detected !") - return False - if not any(isinstance(x, IPOption_Router_Alert) for x in underlayer.options): # noqa: E501 - underlayer.options.append(IPOption_Router_Alert()) - underlayer.ttl = 1 # IP rule 4 - _root = self.firstlayer() - if _root.haslayer(Ether): - # Force recalculate Ether dst - _root[Ether].dst = getmacbyip(underlayer.dst) # Ether rule 1 # noqa: E501 - from scapy.contrib.igmpv3 import IGMPv3 - if isinstance(self, IGMPv3): - self.encode_maxrespcode() - return True - - def mysummary(self): - """Display a summary of the IGMP object.""" - if isinstance(self.underlayer, IP): - return self.underlayer.sprintf("IGMP: %IP.src% > %IP.dst% %IGMP.type% %IGMP.gaddr%") # noqa: E501 - else: - return self.sprintf("IGMP %IGMP.type% %IGMP.gaddr%") - - -bind_layers(IP, IGMP, frag=0, - proto=2, - ttl=1) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/igmpv3.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/igmpv3.py deleted file mode 100644 index 97db70d6fd..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/igmpv3.py +++ /dev/null @@ -1,179 +0,0 @@ -#! /usr/bin/env python - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = Internet Group Management Protocol v3 (IGMPv3) -# scapy.contrib.status = loads - -from __future__ import print_function -from scapy.packet import Packet, bind_layers -from scapy.fields import BitField, ByteEnumField, ByteField, FieldLenField, \ - FieldListField, IPField, PacketListField, ShortField, XShortField -from scapy.compat import orb -from scapy.layers.inet import IP -from scapy.contrib.igmp import IGMP -from scapy.config import conf - -""" Based on the following references - http://www.iana.org/assignments/igmp-type-numbers - http://www.rfc-editor.org/rfc/pdfrfc/rfc3376.txt.pdf - -""" - -# See RFC3376, Section 4. Message Formats for definitions of proper IGMPv3 message format # noqa: E501 -# http://www.faqs.org/rfcs/rfc3376.html -# -# See RFC4286, For definitions of proper messages for Multicast Router Discovery. # noqa: E501 -# http://www.faqs.org/rfcs/rfc4286.html -# - - -class IGMPv3(IGMP): - """IGMP Message Class for v3. - - This class is derived from class Packet. - The fields defined below are a - direct interpretation of the v3 Membership Query Message. - Fields 'type' through 'qqic' are directly assignable. - For 'numsrc', do not assign a value. - Instead add to the 'srcaddrs' list to auto-set 'numsrc'. To - assign values to 'srcaddrs', use the following methods: - c = IGMPv3() - c.srcaddrs = ['1.2.3.4', '5.6.7.8'] - c.srcaddrs += ['192.168.10.24'] - At this point, 'c.numsrc' is three (3) - - 'chksum' is automagically calculated before the packet is sent. - - 'mrcode' is also the Advertisement Interval field - - """ - name = "IGMPv3" - igmpv3types = {0x11: "Membership Query", - 0x22: "Version 3 Membership Report", - 0x30: "Multicast Router Advertisement", - 0x31: "Multicast Router Solicitation", - 0x32: "Multicast Router Termination"} - - fields_desc = [ByteEnumField("type", 0x11, igmpv3types), - ByteField("mrcode", 20), - XShortField("chksum", None)] - - def encode_maxrespcode(self): - """Encode and replace the mrcode value to its IGMPv3 encoded time value if needed, # noqa: E501 - as specified in rfc3376#section-4.1.1. - - If value < 128, return the value specified. If >= 128, encode as a floating # noqa: E501 - point value. Value can be 0 - 31744. - """ - value = self.mrcode - if value < 128: - code = value - elif value > 31743: - code = 255 - else: - exp = 0 - value >>= 3 - while(value > 31): - exp += 1 - value >>= 1 - exp <<= 4 - code = 0x80 | exp | (value & 0x0F) - self.mrcode = code - - def mysummary(self): - """Display a summary of the IGMPv3 object.""" - if isinstance(self.underlayer, IP): - return self.underlayer.sprintf("IGMPv3: %IP.src% > %IP.dst% %IGMPv3.type%") # noqa: E501 - else: - return self.sprintf("IGMPv3 %IGMPv3.type%") - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 4: - if orb(_pkt[0]) in [0x12, 0x16, 0x17]: - return IGMP - elif orb(_pkt[0]) == 0x11 and len(_pkt) < 12: - return IGMP - return IGMPv3 - - -class IGMPv3mq(Packet): - """IGMPv3 Membership Query. - Payload of IGMPv3 when type=0x11""" - name = "IGMPv3mq" - fields_desc = [IPField("gaddr", "0.0.0.0"), - BitField("resv", 0, 4), - BitField("s", 0, 1), - BitField("qrv", 0, 3), - ByteField("qqic", 0), - FieldLenField("numsrc", None, count_of="srcaddrs"), - FieldListField("srcaddrs", None, IPField("sa", "0.0.0.0"), count_from=lambda x: x.numsrc)] # noqa: E501 - - -class IGMPv3gr(Packet): - """IGMP Group Record for IGMPv3 Membership Report - - This class is derived from class Packet and should be added in the records - of an instantiation of class IGMPv3mr. - """ - name = "IGMPv3gr" - igmpv3grtypes = {1: "Mode Is Include", - 2: "Mode Is Exclude", - 3: "Change To Include Mode", - 4: "Change To Exclude Mode", - 5: "Allow New Sources", - 6: "Block Old Sources"} - - fields_desc = [ByteEnumField("rtype", 1, igmpv3grtypes), - ByteField("auxdlen", 0), - FieldLenField("numsrc", None, count_of="srcaddrs"), - IPField("maddr", "0.0.0.0"), - FieldListField("srcaddrs", [], IPField("sa", "0.0.0.0"), count_from=lambda x: x.numsrc)] # noqa: E501 - - def mysummary(self): - """Display a summary of the IGMPv3 group record.""" - return self.sprintf("IGMPv3 Group Record %IGMPv3gr.type% %IGMPv3gr.maddr%") # noqa: E501 - - def default_payload_class(self, payload): - return conf.padding_layer - - -class IGMPv3mr(Packet): - """IGMP Membership Report extension for IGMPv3. - Payload of IGMPv3 when type=0x22""" - name = "IGMPv3mr" - fields_desc = [XShortField("res2", 0), - FieldLenField("numgrp", None, count_of="records"), - PacketListField("records", [], IGMPv3gr, count_from=lambda x: x.numgrp)] # noqa: E501 - - -class IGMPv3mra(Packet): - """IGMP Multicas Router Advertisement extension for IGMPv3. - Payload of IGMPv3 when type=0x30""" - name = "IGMPv3mra" - fields_desc = [ShortField("qryIntvl", 0), - ShortField("robust", 0)] - - -bind_layers(IP, IGMPv3, frag=0, - proto=2, - ttl=1, - tos=0xc0, - dst='224.0.0.22') - -bind_layers(IGMPv3, IGMPv3mq, type=0x11) -bind_layers(IGMPv3, IGMPv3mr, type=0x22, mrcode=0x0) -bind_layers(IGMPv3, IGMPv3mra, type=0x30) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ikev2.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/ikev2.py deleted file mode 100644 index 60b2048004..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ikev2.py +++ /dev/null @@ -1,802 +0,0 @@ -#!/usr/bin/env python - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = Internet Key Exchange v2 (IKEv2) -# scapy.contrib.status = loads - -import logging -import struct - - -# Modified from the original ISAKMP code by Yaron Sheffer , June 2010. # noqa: E501 - -from scapy.packet import Packet, bind_layers, split_layers, Raw -from scapy.fields import ByteEnumField, ByteField, ConditionalField, \ - FieldLenField, FlagsField, IP6Field, IPField, IntField, MultiEnumField, \ - PacketField, PacketLenField, PacketListField, ShortEnumField, ShortField, \ - StrFixedLenField, StrLenField, X3BytesField, XByteField -from scapy.layers.x509 import X509_Cert, X509_CRL -from scapy.layers.inet import IP, UDP -from scapy.layers.isakmp import ISAKMP -from scapy.sendrecv import sr -from scapy.config import conf -from scapy.volatile import RandString - -# see http://www.iana.org/assignments/ikev2-parameters for details -IKEv2AttributeTypes = {"Encryption": (1, {"DES-IV64": 1, - "DES": 2, - "3DES": 3, - "RC5": 4, - "IDEA": 5, - "CAST": 6, - "Blowfish": 7, - "3IDEA": 8, - "DES-IV32": 9, - "AES-CBC": 12, - "AES-CTR": 13, - "AES-CCM-8": 14, - "AES-CCM-12": 15, - "AES-CCM-16": 16, - "AES-GCM-8ICV": 18, - "AES-GCM-12ICV": 19, - "AES-GCM-16ICV": 20, - "Camellia-CBC": 23, - "Camellia-CTR": 24, - "Camellia-CCM-8ICV": 25, - "Camellia-CCM-12ICV": 26, - "Camellia-CCM-16ICV": 27, - }, 0), - "PRF": (2, {"PRF_HMAC_MD5": 1, - "PRF_HMAC_SHA1": 2, - "PRF_HMAC_TIGER": 3, - "PRF_AES128_XCBC": 4, - "PRF_HMAC_SHA2_256": 5, - "PRF_HMAC_SHA2_384": 6, - "PRF_HMAC_SHA2_512": 7, - "PRF_AES128_CMAC": 8, - }, 0), - "Integrity": (3, {"HMAC-MD5-96": 1, - "HMAC-SHA1-96": 2, - "DES-MAC": 3, - "KPDK-MD5": 4, - "AES-XCBC-96": 5, - "HMAC-MD5-128": 6, - "HMAC-SHA1-160": 7, - "AES-CMAC-96": 8, - "AES-128-GMAC": 9, - "AES-192-GMAC": 10, - "AES-256-GMAC": 11, - "SHA2-256-128": 12, - "SHA2-384-192": 13, - "SHA2-512-256": 14, - }, 0), - "GroupDesc": (4, {"768MODPgr": 1, - "1024MODPgr": 2, - "1536MODPgr": 5, - "2048MODPgr": 14, - "3072MODPgr": 15, - "4096MODPgr": 16, - "6144MODPgr": 17, - "8192MODPgr": 18, - "256randECPgr": 19, - "384randECPgr": 20, - "521randECPgr": 21, - "1024MODP160POSgr": 22, - "2048MODP224POSgr": 23, - "2048MODP256POSgr": 24, - "192randECPgr": 25, - "224randECPgr": 26, - }, 0), - "Extended Sequence Number": (5, {"No ESN": 0, - "ESN": 1}, 0), - } - -IKEv2AuthenticationTypes = { - 0: "Reserved", - 1: "RSA Digital Signature", - 2: "Shared Key Message Integrity Code", - 3: "DSS Digital Signature", - 9: "ECDSA with SHA-256 on the P-256 curve", - 10: "ECDSA with SHA-384 on the P-384 curve", - 11: "ECDSA with SHA-512 on the P-521 curve", - 12: "Generic Secure Password Authentication Method", - 13: "NULL Authentication", - 14: "Digital Signature" -} - -IKEv2NotifyMessageTypes = { - 1: "UNSUPPORTED_CRITICAL_PAYLOAD", - 4: "INVALID_IKE_SPI", - 5: "INVALID_MAJOR_VERSION", - 7: "INVALID_SYNTAX", - 9: "INVALID_MESSAGE_ID", - 11: "INVALID_SPI", - 14: "NO_PROPOSAL_CHOSEN", - 17: "INVALID_KE_PAYLOAD", - 24: "AUTHENTICATION_FAILED", - 34: "SINGLE_PAIR_REQUIRED", - 35: "NO_ADDITIONAL_SAS", - 36: "INTERNAL_ADDRESS_FAILURE", - 37: "FAILED_CP_REQUIRED", - 38: "TS_UNACCEPTABLE", - 39: "INVALID_SELECTORS", - 40: "UNACCEPTABLE_ADDRESSES", - 41: "UNEXPECTED_NAT_DETECTED", - 42: "USE_ASSIGNED_HoA", - 43: "TEMPORARY_FAILURE", - 44: "CHILD_SA_NOT_FOUND", - 45: "INVALID_GROUP_ID", - 46: "AUTHORIZATION_FAILED", - 16384: "INITIAL_CONTACT", - 16385: "SET_WINDOW_SIZE", - 16386: "ADDITIONAL_TS_POSSIBLE", - 16387: "IPCOMP_SUPPORTED", - 16388: "NAT_DETECTION_SOURCE_IP", - 16389: "NAT_DETECTION_DESTINATION_IP", - 16390: "COOKIE", - 16391: "USE_TRANSPORT_MODE", - 16392: "HTTP_CERT_LOOKUP_SUPPORTED", - 16393: "REKEY_SA", - 16394: "ESP_TFC_PADDING_NOT_SUPPORTED", - 16395: "NON_FIRST_FRAGMENTS_ALSO", - 16396: "MOBIKE_SUPPORTED", - 16397: "ADDITIONAL_IP4_ADDRESS", - 16398: "ADDITIONAL_IP6_ADDRESS", - 16399: "NO_ADDITIONAL_ADDRESSES", - 16400: "UPDATE_SA_ADDRESSES", - 16401: "COOKIE2", - 16402: "NO_NATS_ALLOWED", - 16403: "AUTH_LIFETIME", - 16404: "MULTIPLE_AUTH_SUPPORTED", - 16405: "ANOTHER_AUTH_FOLLOWS", - 16406: "REDIRECT_SUPPORTED", - 16407: "REDIRECT", - 16408: "REDIRECTED_FROM", - 16409: "TICKET_LT_OPAQUE", - 16410: "TICKET_REQUEST", - 16411: "TICKET_ACK", - 16412: "TICKET_NACK", - 16413: "TICKET_OPAQUE", - 16414: "LINK_ID", - 16415: "USE_WESP_MODE", - 16416: "ROHC_SUPPORTED", - 16417: "EAP_ONLY_AUTHENTICATION", - 16418: "CHILDLESS_IKEV2_SUPPORTED", - 16419: "QUICK_CRASH_DETECTION", - 16420: "IKEV2_MESSAGE_ID_SYNC_SUPPORTED", - 16421: "IPSEC_REPLAY_COUNTER_SYNC_SUPPORTED", - 16422: "IKEV2_MESSAGE_ID_SYNC", - 16423: "IPSEC_REPLAY_COUNTER_SYNC", - 16424: "SECURE_PASSWORD_METHODS", - 16425: "PSK_PERSIST", - 16426: "PSK_CONFIRM", - 16427: "ERX_SUPPORTED", - 16428: "IFOM_CAPABILITY", - 16429: "SENDER_REQUEST_ID", - 16430: "IKEV2_FRAGMENTATION_SUPPORTED", - 16431: "SIGNATURE_HASH_ALGORITHMS", - 16432: "CLONE_IKE_SA_SUPPORTED", - 16433: "CLONE_IKE_SA" -} - -IKEv2CertificateEncodings = { - 1: "PKCS #7 wrapped X.509 certificate", - 2: "PGP Certificate", - 3: "DNS Signed Key", - 4: "X.509 Certificate - Signature", - 6: "Kerberos Token", - 7: "Certificate Revocation List (CRL)", - 8: "Authority Revocation List (ARL)", - 9: "SPKI Certificate", - 10: "X.509 Certificate - Attribute", - 11: "Raw RSA Key", - 12: "Hash and URL of X.509 certificate", - 13: "Hash and URL of X.509 bundle" -} - -IKEv2TrafficSelectorTypes = { - 7: "TS_IPV4_ADDR_RANGE", - 8: "TS_IPV6_ADDR_RANGE", - 9: "TS_FC_ADDR_RANGE" -} - -IPProtocolIDs = { - 0: "All protocols", - 1: "Internet Control Message Protocol", - 2: "Internet Group Management Protocol", - 3: "Gateway-to-Gateway Protocol", - 4: "IP in IP (encapsulation)", - 5: "Internet Stream Protocol", - 6: "Transmission Control Protocol", - 7: "Core-based trees", - 8: "Exterior Gateway Protocol", - 9: "Interior Gateway Protocol (any private interior gateway (used by Cisco for their IGRP))", # noqa: E501 - 10: "BBN RCC Monitoring", - 11: "Network Voice Protocol", - 12: "Xerox PUP", - 13: "ARGUS", - 14: "EMCON", - 15: "Cross Net Debugger", - 16: "Chaos", - 17: "User Datagram Protocol", - 18: "Multiplexing", - 19: "DCN Measurement Subsystems", - 20: "Host Monitoring Protocol", - 21: "Packet Radio Measurement", - 22: "XEROX NS IDP", - 23: "Trunk-1", - 24: "Trunk-2", - 25: "Leaf-1", - 26: "Leaf-2", - 27: "Reliable Datagram Protocol", - 28: "Internet Reliable Transaction Protocol", - 29: "ISO Transport Protocol Class 4", - 30: "Bulk Data Transfer Protocol", - 31: "MFE Network Services Protocol", - 32: "MERIT Internodal Protocol", - 33: "Datagram Congestion Control Protocol", - 34: "Third Party Connect Protocol", - 35: "Inter-Domain Policy Routing Protocol", - 36: "Xpress Transport Protocol", - 37: "Datagram Delivery Protocol", - 38: "IDPR Control Message Transport Protocol", - 39: "TP++ Transport Protocol", - 40: "IL Transport Protocol", - 41: "IPv6 Encapsulation", - 42: "Source Demand Routing Protocol", - 43: "Routing Header for IPv6", - 44: "Fragment Header for IPv6", - 45: "Inter-Domain Routing Protocol", - 46: "Resource Reservation Protocol", - 47: "Generic Routing Encapsulation", - 48: "Mobile Host Routing Protocol", - 49: "BNA", - 50: "Encapsulating Security Payload", - 51: "Authentication Header", - 52: "Integrated Net Layer Security Protocol", - 53: "SwIPe", - 54: "NBMA Address Resolution Protocol", - 55: "IP Mobility (Min Encap)", - 56: "Transport Layer Security Protocol (using Kryptonet key management)", - 57: "Simple Key-Management for Internet Protocol", - 58: "ICMP for IPv6", - 59: "No Next Header for IPv6", - 60: "Destination Options for IPv6", - 61: "Any host internal protocol", - 62: "CFTP", - 63: "Any local network", - 64: "SATNET and Backroom EXPAK", - 65: "Kryptolan", - 66: "MIT Remote Virtual Disk Protocol", - 67: "Internet Pluribus Packet Core", - 68: "Any distributed file system", - 69: "SATNET Monitoring", - 70: "VISA Protocol", - 71: "Internet Packet Core Utility", - 72: "Computer Protocol Network Executive", - 73: "Computer Protocol Heart Beat", - 74: "Wang Span Network", - 75: "Packet Video Protocol", - 76: "Backroom SATNET Monitoring", - 77: "SUN ND PROTOCOL-Temporary", - 78: "WIDEBAND Monitoring", - 79: "WIDEBAND EXPAK", - 80: "International Organization for Standardization Internet Protocol", - 81: "Versatile Message Transaction Protocol", - 82: "Secure Versatile Message Transaction Protocol", - 83: "VINES", - 84: "Internet Protocol Traffic Manager", - 85: "NSFNET-IGP", - 86: "Dissimilar Gateway Protocol", - 87: "TCF", - 88: "EIGRP", - 89: "Open Shortest Path First", - 90: "Sprite RPC Protocol", - 91: "Locus Address Resolution Protocol", - 92: "Multicast Transport Protocol", - 93: "AX.25", - 94: "IP-within-IP Encapsulation Protocol", - 95: "Mobile Internetworking Control Protocol", - 96: "Semaphore Communications Sec. Pro", - 97: "Ethernet-within-IP Encapsulation", - 98: "Encapsulation Header", - 99: "Any private encryption scheme", - 100: "GMTP", - 101: "Ipsilon Flow Management Protocol", - 102: "PNNI over IP", - 103: "Protocol Independent Multicast", - 104: "IBM's ARIS (Aggregate Route IP Switching) Protocol", - 105: "SCPS (Space Communications Protocol Standards)", - 106: "QNX", - 107: "Active Networks", - 108: "IP Payload Compression Protocol", - 109: "Sitara Networks Protocol", - 110: "Compaq Peer Protocol", - 111: "IPX in IP", - 112: "Virtual Router Redundancy Protocol, Common Address Redundancy Protocol (not IANA assigned)", # noqa: E501 - 113: "PGM Reliable Transport Protocol", - 114: "Any 0-hop protocol", - 115: "Layer Two Tunneling Protocol Version 3", - 116: "D-II Data Exchange (DDX)", - 117: "Interactive Agent Transfer Protocol", - 118: "Schedule Transfer Protocol", - 119: "SpectraLink Radio Protocol", - 120: "Universal Transport Interface Protocol", - 121: "Simple Message Protocol", - 122: "Simple Multicast Protocol", - 123: "Performance Transparency Protocol", - 124: "Intermediate System to Intermediate System (IS-IS) Protocol over IPv4", # noqa: E501 - 125: "Flexible Intra-AS Routing Environment", - 126: "Combat Radio Transport Protocol", - 127: "Combat Radio User Datagram", - 128: "Service-Specific Connection-Oriented Protocol in a Multilink and Connectionless Environment", # noqa: E501 - 129: "IPLT", - 130: "Secure Packet Shield", - 131: "Private IP Encapsulation within IP", - 132: "Stream Control Transmission Protocol", - 133: "Fibre Channel", - 134: "Reservation Protocol (RSVP) End-to-End Ignore", - 135: "Mobility Extension Header for IPv6", - 136: "Lightweight User Datagram Protocol", - 137: "Multiprotocol Label Switching Encapsulated in IP", - 138: "MANET Protocols", - 139: "Host Identity Protocol", - 140: "Site Multihoming by IPv6 Intermediation", - 141: "Wrapped Encapsulating Security Payload", - 142: "Robust Header Compression", -} - -# the name 'IKEv2TransformTypes' is actually a misnomer (since the table -# holds info for all IKEv2 Attribute types, not just transforms, but we'll -# keep it for backwards compatibility... for now at least -IKEv2TransformTypes = IKEv2AttributeTypes - -IKEv2TransformNum = {} -for n in IKEv2TransformTypes: - val = IKEv2TransformTypes[n] - tmp = {} - for e in val[1]: - tmp[val[1][e]] = e - IKEv2TransformNum[val[0]] = tmp - -IKEv2Transforms = {} -for n in IKEv2TransformTypes: - IKEv2Transforms[IKEv2TransformTypes[n][0]] = n - -del(n) -del(e) -del(tmp) -del(val) - -# Note: Transform and Proposal can only be used inside the SA payload -IKEv2_payload_type = ["None", "", "Proposal", "Transform"] - -IKEv2_payload_type.extend([""] * 29) -IKEv2_payload_type.extend(["SA", "KE", "IDi", "IDr", "CERT", "CERTREQ", "AUTH", "Nonce", "Notify", "Delete", # noqa: E501 - "VendorID", "TSi", "TSr", "Encrypted", "CP", "EAP", "", "", "", "", "Encrypted Fragment"]) # noqa: E501 - -IKEv2_exchange_type = [""] * 34 -IKEv2_exchange_type.extend(["IKE_SA_INIT", "IKE_AUTH", "CREATE_CHILD_SA", - "INFORMATIONAL", "IKE_SESSION_RESUME"]) - - -class IKEv2_class(Packet): - def guess_payload_class(self, payload): - np = self.next_payload - logging.debug("For IKEv2_class np=%d" % np) - if np == 0: - return conf.raw_layer - elif np < len(IKEv2_payload_type): - pt = IKEv2_payload_type[np] - logging.debug(globals().get("IKEv2_payload_%s" % pt, IKEv2_payload)) # noqa: E501 - return globals().get("IKEv2_payload_%s" % pt, IKEv2_payload) - else: - return IKEv2_payload - - -class IKEv2(IKEv2_class): # rfc4306 - name = "IKEv2" - fields_desc = [ - StrFixedLenField("init_SPI", "", 8), - StrFixedLenField("resp_SPI", "", 8), - ByteEnumField("next_payload", 0, IKEv2_payload_type), - XByteField("version", 0x20), - ByteEnumField("exch_type", 0, IKEv2_exchange_type), - FlagsField("flags", 0, 8, ["res0", "res1", "res2", "Initiator", "Version", "Response", "res6", "res7"]), # noqa: E501 - IntField("id", 0), - IntField("length", None) # Length of total message: packets + all payloads # noqa: E501 - ] - - def guess_payload_class(self, payload): - if self.flags & 1: - return conf.raw_layer - return IKEv2_class.guess_payload_class(self, payload) - - def answers(self, other): - if isinstance(other, IKEv2): - if other.init_SPI == self.init_SPI: - 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 IKEv2_Key_Length_Attribute(IntField): - # We only support the fixed-length Key Length attribute (the only one currently defined) # noqa: E501 - def __init__(self, name): - IntField.__init__(self, name, 0x800E0000) - - def i2h(self, pkt, x): - return IntField.i2h(self, pkt, x & 0xFFFF) - - def h2i(self, pkt, x): - return IntField.h2i(self, pkt, (x if x is not None else 0) | 0x800E0000) # noqa: E501 - - -class IKEv2_payload_Transform(IKEv2_class): - name = "IKE Transform" - fields_desc = [ - ByteEnumField("next_payload", None, {0: "last", 3: "Transform"}), - ByteField("res", 0), - ShortField("length", 8), - ByteEnumField("transform_type", None, IKEv2Transforms), - ByteField("res2", 0), - MultiEnumField("transform_id", None, IKEv2TransformNum, depends_on=lambda pkt: pkt.transform_type, fmt="H"), # noqa: E501 - ConditionalField(IKEv2_Key_Length_Attribute("key_length"), lambda pkt: pkt.length > 8), # noqa: E501 - ] - - -class IKEv2_payload_Proposal(IKEv2_class): - name = "IKEv2 Proposal" - fields_desc = [ - ByteEnumField("next_payload", None, {0: "last", 2: "Proposal"}), - ByteField("res", 0), - FieldLenField("length", None, "trans", "H", adjust=lambda pkt, x: x + 8 + (pkt.SPIsize if pkt.SPIsize else 0)), # noqa: E501 - ByteField("proposal", 1), - ByteEnumField("proto", 1, {1: "IKEv2", 2: "AH", 3: "ESP"}), - FieldLenField("SPIsize", None, "SPI", "B"), - ByteField("trans_nb", None), - StrLenField("SPI", "", length_from=lambda pkt: pkt.SPIsize), - PacketLenField("trans", conf.raw_layer(), IKEv2_payload_Transform, length_from=lambda pkt: pkt.length - 8 - pkt.SPIsize), # noqa: E501 - ] - - -class IKEv2_payload(IKEv2_class): - name = "IKEv2 Payload" - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - FlagsField("flags", 0, 8, ["critical", "res1", "res2", "res3", "res4", "res5", "res6", "res7"]), # noqa: E501 - FieldLenField("length", None, "load", "H", adjust=lambda pkt, x:x + 4), - StrLenField("load", "", length_from=lambda x:x.length - 4), - ] - - -class IKEv2_payload_AUTH(IKEv2_class): - name = "IKEv2 Authentication" - overload_fields = {IKEv2: {"next_payload": 39}} - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "load", "H", adjust=lambda pkt, x:x + 8), - ByteEnumField("auth_type", None, IKEv2AuthenticationTypes), - X3BytesField("res2", 0), - StrLenField("load", "", length_from=lambda x:x.length - 8), - ] - - -class IKEv2_payload_VendorID(IKEv2_class): - name = "IKEv2 Vendor ID" - overload_fields = {IKEv2: {"next_payload": 43}} - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "vendorID", "H", adjust=lambda pkt, x:x + 4), # noqa: E501 - StrLenField("vendorID", "", length_from=lambda x:x.length - 4), - ] - - -class TrafficSelector(Packet): - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 16: - ts_type = struct.unpack("!B", _pkt[0:1])[0] - if ts_type == 7: - return IPv4TrafficSelector - elif ts_type == 8: - return IPv6TrafficSelector - elif ts_type == 9: - return EncryptedTrafficSelector - else: - return RawTrafficSelector - return IPv4TrafficSelector - - -class IPv4TrafficSelector(TrafficSelector): - name = "IKEv2 IPv4 Traffic Selector" - fields_desc = [ - ByteEnumField("TS_type", 7, IKEv2TrafficSelectorTypes), - ByteEnumField("IP_protocol_ID", None, IPProtocolIDs), - ShortField("length", 16), - ShortField("start_port", 0), - ShortField("end_port", 65535), - IPField("starting_address_v4", "192.168.0.1"), - IPField("ending_address_v4", "192.168.0.255"), - ] - - -class IPv6TrafficSelector(TrafficSelector): - name = "IKEv2 IPv6 Traffic Selector" - fields_desc = [ - ByteEnumField("TS_type", 8, IKEv2TrafficSelectorTypes), - ByteEnumField("IP_protocol_ID", None, IPProtocolIDs), - ShortField("length", 20), - ShortField("start_port", 0), - ShortField("end_port", 65535), - IP6Field("starting_address_v6", "2001::"), - IP6Field("ending_address_v6", "2001::"), - ] - - -class EncryptedTrafficSelector(TrafficSelector): - name = "IKEv2 Encrypted Traffic Selector" - fields_desc = [ - ByteEnumField("TS_type", 9, IKEv2TrafficSelectorTypes), - ByteEnumField("IP_protocol_ID", None, IPProtocolIDs), - ShortField("length", 16), - ByteField("res", 0), - X3BytesField("starting_address_FC", 0), - ByteField("res2", 0), - X3BytesField("ending_address_FC", 0), - ByteField("starting_R_CTL", 0), - ByteField("ending_R_CTL", 0), - ByteField("starting_type", 0), - ByteField("ending_type", 0), - ] - - -class RawTrafficSelector(TrafficSelector): - name = "IKEv2 Encrypted Traffic Selector" - fields_desc = [ - ByteEnumField("TS_type", None, IKEv2TrafficSelectorTypes), - ByteEnumField("IP_protocol_ID", None, IPProtocolIDs), - FieldLenField("length", None, "load", "H", adjust=lambda pkt, x:x + 4), - PacketField("load", "", Raw) - ] - - -class IKEv2_payload_TSi(IKEv2_class): - name = "IKEv2 Traffic Selector - Initiator" - overload_fields = {IKEv2: {"next_payload": 44}} - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "traffic_selector", "H", adjust=lambda pkt, x:x + 8), # noqa: E501 - ByteField("number_of_TSs", 0), - X3BytesField("res2", 0), - PacketListField("traffic_selector", None, TrafficSelector, length_from=lambda x:x.length - 8, count_from=lambda x:x.number_of_TSs), # noqa: E501 - ] - - -class IKEv2_payload_TSr(IKEv2_class): - name = "IKEv2 Traffic Selector - Responder" - overload_fields = {IKEv2: {"next_payload": 45}} - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "traffic_selector", "H", adjust=lambda pkt, x:x + 8), # noqa: E501 - ByteField("number_of_TSs", 0), - X3BytesField("res2", 0), - PacketListField("traffic_selector", None, TrafficSelector, length_from=lambda x:x.length - 8, count_from=lambda x:x.number_of_TSs), # noqa: E501 - ] - - -class IKEv2_payload_Delete(IKEv2_class): - name = "IKEv2 Vendor ID" - overload_fields = {IKEv2: {"next_payload": 42}} - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "vendorID", "H", adjust=lambda pkt, x:x + 4), # noqa: E501 - StrLenField("vendorID", "", length_from=lambda x:x.length - 4), - ] - - -class IKEv2_payload_SA(IKEv2_class): - name = "IKEv2 SA" - overload_fields = {IKEv2: {"next_payload": 33}} - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "prop", "H", adjust=lambda pkt, x:x + 4), - PacketLenField("prop", conf.raw_layer(), IKEv2_payload_Proposal, length_from=lambda x:x.length - 4), # noqa: E501 - ] - - -class IKEv2_payload_Nonce(IKEv2_class): - name = "IKEv2 Nonce" - overload_fields = {IKEv2: {"next_payload": 40}} - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_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 IKEv2_payload_Notify(IKEv2_class): - name = "IKEv2 Notify" - overload_fields = {IKEv2: {"next_payload": 41}} - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "load", "H", adjust=lambda pkt, x:x + 8), - ByteEnumField("proto", None, {0: "Reserved", 1: "IKE", 2: "AH", 3: "ESP"}), # noqa: E501 - FieldLenField("SPIsize", None, "SPI", "B"), - ShortEnumField("type", 0, IKEv2NotifyMessageTypes), - StrLenField("SPI", "", length_from=lambda x: x.SPIsize), - StrLenField("load", "", length_from=lambda x: x.length - 8), - ] - - -class IKEv2_payload_KE(IKEv2_class): - name = "IKEv2 Key Exchange" - overload_fields = {IKEv2: {"next_payload": 34}} - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "load", "H", adjust=lambda pkt, x:x + 8), - ShortEnumField("group", 0, IKEv2TransformTypes['GroupDesc'][1]), - ShortField("res2", 0), - StrLenField("load", "", length_from=lambda x:x.length - 8), - ] - - -class IKEv2_payload_IDi(IKEv2_class): - name = "IKEv2 Identification - Initiator" - overload_fields = {IKEv2: {"next_payload": 35}} - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "load", "H", adjust=lambda pkt, x:x + 8), - ByteEnumField("IDtype", 1, {1: "IPv4_addr", 2: "FQDN", 3: "Email_addr", 5: "IPv6_addr", 11: "Key"}), # noqa: E501 - 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 IKEv2_payload_IDr(IKEv2_class): - name = "IKEv2 Identification - Responder" - overload_fields = {IKEv2: {"next_payload": 36}} - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "load", "H", adjust=lambda pkt, x:x + 8), - ByteEnumField("IDtype", 1, {1: "IPv4_addr", 2: "FQDN", 3: "Email_addr", 5: "IPv6_addr", 11: "Key"}), # noqa: E501 - 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 IKEv2_payload_Encrypted(IKEv2_class): - name = "IKEv2 Encrypted and Authenticated" - overload_fields = {IKEv2: {"next_payload": 46}} - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_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 IKEv2_payload_Encrypted_Fragment(IKEv2_class): - name = "IKEv2 Encrypted Fragment" - overload_fields = {IKEv2: {"next_payload": 53}} - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "load", "H", adjust=lambda pkt, x: x + 8), # noqa: E501 - ShortField("frag_number", 1), - ShortField("frag_total", 1), - StrLenField("load", "", length_from=lambda x: x.length - 8), - ] - - -class IKEv2_payload_CERTREQ(IKEv2_class): - name = "IKEv2 Certificate Request" - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "cert_data", "H", adjust=lambda pkt, x:x + 5), # noqa: E501 - ByteEnumField("cert_type", 0, IKEv2CertificateEncodings), - StrLenField("cert_data", "", length_from=lambda x:x.length - 5), - ] - - -class IKEv2_payload_CERT(IKEv2_class): - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 16: - ts_type = struct.unpack("!B", _pkt[4:5])[0] - if ts_type == 4: - return IKEv2_payload_CERT_CRT - elif ts_type == 7: - return IKEv2_payload_CERT_CRL - else: - return IKEv2_payload_CERT_STR - return IKEv2_payload_CERT_STR - - -class IKEv2_payload_CERT_CRT(IKEv2_payload_CERT): - name = "IKEv2 Certificate" - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "x509Cert", "H", adjust=lambda pkt, x: x + len(pkt.x509Cert) + 5), # noqa: E501 - ByteEnumField("cert_type", 4, IKEv2CertificateEncodings), - PacketLenField("x509Cert", X509_Cert(''), X509_Cert, length_from=lambda x:x.length - 5), # noqa: E501 - ] - - -class IKEv2_payload_CERT_CRL(IKEv2_payload_CERT): - name = "IKEv2 Certificate" - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "x509CRL", "H", adjust=lambda pkt, x: x + len(pkt.x509CRL) + 5), # noqa: E501 - ByteEnumField("cert_type", 7, IKEv2CertificateEncodings), - PacketLenField("x509CRL", X509_CRL(''), X509_CRL, length_from=lambda x:x.length - 5), # noqa: E501 - ] - - -class IKEv2_payload_CERT_STR(IKEv2_payload_CERT): - name = "IKEv2 Certificate" - fields_desc = [ - ByteEnumField("next_payload", None, IKEv2_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "cert_data", "H", adjust=lambda pkt, x: x + 5), # noqa: E501 - ByteEnumField("cert_type", 0, IKEv2CertificateEncodings), - StrLenField("cert_data", "", length_from=lambda x:x.length - 5), - ] - - -IKEv2_payload_type_overload = {} -for i, payloadname in enumerate(IKEv2_payload_type): - name = "IKEv2_payload_%s" % payloadname - if name in globals(): - IKEv2_payload_type_overload[globals()[name]] = {"next_payload": i} - -del i, payloadname, name -IKEv2_class._overload_fields = IKEv2_payload_type_overload.copy() - -split_layers(UDP, ISAKMP, sport=500) -split_layers(UDP, ISAKMP, dport=500) - -bind_layers(UDP, IKEv2, dport=500, sport=500) # TODO: distinguish IKEv1/IKEv2 -bind_layers(UDP, IKEv2, dport=4500, sport=4500) - - -def ikev2scan(ip, **kwargs): - """Send a IKEv2 SA to an IP and wait for answers.""" - return sr(IP(dst=ip) / UDP() / IKEv2(init_SPI=RandString(8), - exch_type=34) / IKEv2_payload_SA(prop=IKEv2_payload_Proposal()), **kwargs) # noqa: E501 diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ipfix.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/ipfix.py deleted file mode 100755 index 7310c9a8bb..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ipfix.py +++ /dev/null @@ -1,237 +0,0 @@ -""" -IPFIX protocol a.k.a. NetFlow Version 10 - -References: -https://tools.ietf.org/html/rfc5101 -https://tools.ietf.org/html/rfc6759 -https://www.iana.org/assignments/ipfix/ipfix.xhtml -https://www.cisco.com/c/en/us/td/docs/routers/access/ISRG2/AVC/api/guide/AVC_Metric_Definition_Guide/5_AVC_Metric_Def.html -https://www.cisco.com/c/en/us/td/docs/routers/access/ISRG2/AVC/api/guide/AVC_Metric_Definition_Guide/avc_app_exported_fields.html - -Not implemented: -Lengths auto-fill at "crafting" -""" - -# TRex Change - -from scapy.layers.netflow import * -import os -import csv - -tmpl_sets = {} -ietf_csv = 'ipfix-ietf-information-elements.csv' -cisco_csv = 'ipfix-cisco-information-elements.csv' - -def _fill_from_csv(filename): - d = {} - file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, filename)) - assert os.path.isfile(file_path), 'CSV path does not exist: %s' % file_path - with open(file_path, 'r') as csvfile: - for i, row in enumerate(csv.reader(csvfile)): - assert type(row) is list and len(row) == 2 and row[1] and row[0].isdigit(), 'Bad CSV %s, row number %s' % (filename, i) - d[int(row[0]) % 0x8000] = row[1] - return d - -ietf_field_type_names = _fill_from_csv(ietf_csv) -cisco_field_type_names = _fill_from_csv(cisco_csv) - - -class IPFIXSet(Raw): - _set_types = {} - @classmethod - def register_variant(cls): - if cls.__name__ == 'IPFIXSet': - return - cls._set_types[cls.set_id.default] = cls - - - @classmethod - def dispatch_hook(cls, pkt=None, *a, **k): - if pkt and len(pkt) >= 4: - set_id = str2int(pkt[:2]) - if set_id > 255: - return generate_data_record(set_id, pkt, *a, **k) - return cls._set_types.get(set_id, cls) - return cls - - -class _IPFIXTemplateRecordHeader(Packet): - fields_desc = [ - ShortField('template_id', 255), - FieldLenField('field_count', None, count_of='field_specifiers') ] - - -class _IPFIXOptionRecordHeader(Packet): - fields_desc = [ - ShortField('template_id', 1), - FieldLenField('total_field_count', None, count_of='field_specifiers'), - ShortField('scope_field_count', 0) ] - - -class FieldNameByType(BitField): - def i2repr(self, pkt, x): - return _get_type_name(pkt.enterprise_bit, x, pkt.enterprise_number) - - -class IPFIXFieldSpecifier(Packet): - name = 'IPFIX Field Specifier' - fields_desc = [ - BitField('enterprise_bit', 0, 1), - FieldNameByType('information_element_identifier', 0, 15), - ShortField('field_length', 0), - ConditionalField(IntField('enterprise_number', None), lambda pkt:pkt.enterprise_bit) ] - - def extract_padding(self, s): - return '', s - - -class IPFIXTemplateRecord(Packet): - fields_desc = [ - _IPFIXTemplateRecordHeader, - PacketListField('field_specifiers', [], IPFIXFieldSpecifier, count_from = lambda p:p.field_count) ] - - def extract_padding(self, s): - return '', s - - def post_dissect(self, *a, **k): - tmpl_sets[self.template_id] = [field_desc.fields for field_desc in self.field_specifiers] - return Packet.post_dissect(self, *a, **k) - - def post_build(self, *a, **k): - assert self.template_id is not None - tmpl_sets[self.template_id] = [field_desc.fields for field_desc in self.field_specifiers] - return Packet.post_build(self, *a, **k) - - -class _IPFIXSetHeader(Packet): - fields_desc = [ - ShortField('set_id', None), - FieldLenField('length', None, length_of = 'records', adjust = lambda pkt,x:x+4) ] - - -class IPFIXSetTemplate(IPFIXSet): - name = 'IPFIX Template set' - set_id = 2 - fields_desc = [ - _IPFIXSetHeader, - PacketListField('records', [], IPFIXTemplateRecord, length_from = lambda pkt: pkt.length-4) ] - - def extract_padding(self, s): - return '', s - - -class IPFIXOptionRecord(Packet): - fields_desc = [ - _IPFIXOptionRecordHeader, - PacketListField('field_specifiers', [], IPFIXFieldSpecifier, count_from = lambda p:p.total_field_count) ] - - def extract_padding(self, s): - return '', s - - def post_dissect(self, *a, **k): - tmpl_sets[self.template_id] = [field_desc.fields for field_desc in self.field_specifiers] - return Packet.post_dissect(self, *a, **k) - - def post_build(self, *a, **k): - assert self.template_id is not None - tmpl_sets[self.template_id] = [field_desc.fields for field_desc in self.field_specifiers] - return Packet.post_build(self, *a, **k) - - -class IPFIXSetOption(IPFIXSet): - name = 'IPFIX Option template set' - set_id = 3 - fields_desc = [ - _IPFIXSetHeader, - PacketListField('records', [], IPFIXOptionRecord, length_from = lambda pkt: pkt.length-4) ] - - def extract_padding(self, s): - return '', s - - -class IPFIXSetDataRaw(IPFIXSet): - name = 'IPFIX Data set (no template)' - fields_desc = [ - _IPFIXSetHeader, - StrField('records', '') ] - - def extract_padding(self, s): - return '', s - - -class VariableLengthField(StrField): - def getfield(self, pkt, s): - if len(s) < 1: - raise Exception('Variable length field does not have enough bytes! Must contain at least 1') - length = str2int(s[:1]) # common case - if length < 255: - return s[1+length:], s[1:1+length] - - if len(s) < 4: - raise Exception('Variable length field does not have enough bytes! Must contain at least 4') - length = str2int(s[1:4]) # rare case - return s[4+length:], s[4:4+length] - - -def _get_type_name(enter_bit, field_type, enter_num): - if enter_bit: - if enter_num == 9: # Cisco - field_name = cisco_field_type_names.get(field_type) - assert field_name, 'Missing field type %s in %s' % (field_type, cisco_csv) - return field_name - raise Exception('No support for enterprise number %s' % enter_num) - field_name = ietf_field_type_names.get(field_type) - assert field_name, 'Missing field type %s in %s' % (field_type, ietf_csv) - return field_name - - -def _get_field_desc(tmpl_set): - _fields_desc = [] - for index, desc in enumerate(tmpl_set): - type_name = _get_type_name(desc['enterprise_bit'], desc['information_element_identifier'], desc.get('enterprise_number')) - length = desc['field_length'] - if length == 65535: # Variable length field - field = VariableLengthField(type_name, '') - else: - field = StrFixedLenField(type_name, '', length) - _fields_desc.append(field) - return _fields_desc - - -def generate_data_record(set_id, pkt, *a, **k): - tmpl_set = tmpl_sets.get(set_id) - if not tmpl_set: # we did not see template - return IPFIXSetDataRaw - - _fields_desc = _get_field_desc(tmpl_set) - class IPFIXDataRecord(Packet): - fields_desc = _fields_desc - - def extract_padding(self, s): - if len(self.fields_desc) > len(s): - return s, None - return '', s - - class IPFIXSetData(IPFIXSetDataRaw): - name = 'IPFIX Data set (ID %s)' % set_id - fields_desc = [ - _IPFIXSetHeader, - PacketListField('records', [], IPFIXDataRecord, length_from = lambda pkt: pkt.length-4) ] - - return IPFIXSetData - - -class IPFIX(Packet): - name = 'IPFIX' - fields_desc = [ - ShortField('version', 10), - FieldLenField('length', None, length_of = 'sets', adjust = lambda pkt,x: x+16), - IntField('export_time', 0), - IntField('sequence_number',0), - IntField('domain_id', 0), - PacketListField('sets', [], IPFIXSet, length_from = lambda pkt: pkt.length-16) ] - - - -bind_layers( UDP, IPFIX, dport=4739 ) - diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/isis.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/isis.py deleted file mode 100644 index d2e1128735..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/isis.py +++ /dev/null @@ -1,936 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = Intermediate System to Intermediate System (ISIS) -# scapy.contrib.status = loads - -""" - IS-IS Scapy Extension - ~~~~~~~~~~~~~~~~~~~~~ - - :copyright: 2014-2016 BENOCS GmbH, Berlin (Germany) - :author: Marcel Patzlaff, mpatzlaff@benocs.com - Michal Kaliszan, mkaliszan@benocs.com - :license: GPLv2 - - This module is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This module 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. - - :description: - - This module provides Scapy layers for the Intermediate System - to Intermediate System routing protocol as defined in RFC 1195. - - Currently it (partially) supports the packaging/encoding - requirements of the following RFCs: - * RFC 1195 (only the TCP/IP related part) - * RFC 3358 (optional checksums) - * RFC 5301 (dynamic hostname extension) - * RFC 5302 (domain-wide prefix distribution) - * RFC 5303 (three-way handshake) - * RFC 5304 (cryptographic authentication) - * RFC 5308 (routing IPv6 with IS-IS) - - :TODO: - - - packet relations (requests, responses) - - support for recent RFCs: - * RFC 5305 (traffic engineering) - * RFC 5307 (support for G-MPLS) - * RFC 5310 (generic cryptographic authentication) - * RFC 5316 (inter-AS MPLS and G-MPLS TE) - -""" - -from __future__ import absolute_import -import struct -import random - -from scapy.config import conf -from scapy.fields import BitField, BitFieldLenField, BoundStrLenField, \ - ByteEnumField, ByteField, ConditionalField, Field, FieldLenField, \ - FieldListField, FlagsField, IEEEFloatField, IP6PrefixField, IPField, \ - IPPrefixField, IntField, LongField, MACField, PacketListField, \ - ShortField, ThreeBytesField, XIntField, XShortField -from scapy.packet import bind_layers, Packet -from scapy.layers.clns import network_layer_protocol_ids, register_cln_protocol -from scapy.layers.inet6 import IP6ListField, IP6Field -from scapy.utils import fletcher16_checkbytes -from scapy.volatile import RandString, RandByte -from scapy.modules.six.moves import range -from scapy.compat import orb, hex_bytes - -EXT_VERSION = "v0.0.2" - - -####################################################################### -# ISIS Utilities + Fields # -####################################################################### -def isis_area2str(area): - return b"".join(hex_bytes(x) for x in area.split(".")) - - -def isis_str2area(s): - if len(s) == 0: - return "" - - numbytes = len(s[1:]) - fmt = "%02X" + (".%02X%02X" * (numbytes // 2)) + ("" if (numbytes % 2) == 0 else ".%02X") # noqa: E501 - return fmt % tuple(orb(x) for x in s) - - -def isis_sysid2str(sysid): - return b"".join(hex_bytes(x) for x in sysid.split(".")) - - -def isis_str2sysid(s): - return ("%02X%02X." * 3)[:-1] % tuple(orb(x) for x in s) - - -def isis_nodeid2str(nodeid): - return isis_sysid2str(nodeid[:-3]) + hex_bytes(nodeid[-2:]) - - -def isis_str2nodeid(s): - return "%s.%02X" % (isis_str2sysid(s[:-1]), orb(s[-1])) - - -def isis_lspid2str(lspid): - return isis_nodeid2str(lspid[:-3]) + hex_bytes(lspid[-2:]) - - -def isis_str2lspid(s): - return "%s-%02X" % (isis_str2nodeid(s[:-1]), orb(s[-1])) - - -class _ISIS_IdFieldBase(Field): - __slots__ = ["to_str", "to_id", "length"] - - def __init__(self, name, default, length, to_str, to_id): - self.to_str = to_str - self.to_id = to_id - self.length = length - Field.__init__(self, name, default, "%is" % length) - - def i2m(self, pkt, x): - if x is None: - return b"\0" * self.length - - return self.to_str(x) - - def m2i(self, pkt, x): - return self.to_id(x) - - def any2i(self, pkt, x): - if isinstance(x, str) and len(x) == self.length: - return self.m2i(pkt, x) - - return x - - -class _ISIS_RandId(RandString): - def __init__(self, template): - self.bytecount = template.count("*") - self.format = template.replace("*", "%02X") - - def _fix(self): - if self.bytecount == 0: - return "" - - val = () - - for _ in range(self.bytecount): - val += (RandByte(),) - - return self.format % val - - -class _ISIS_RandAreaId(_ISIS_RandId): - def __init__(self, bytecount=None): - self.bytecount = random.randint(1, 13) if bytecount is None else bytecount # noqa: E501 - self.format = "%02X" + (".%02X%02X" * ((self.bytecount - 1) // 2)) + ("" if ((self.bytecount - 1) % 2) == 0 else ".%02X") # noqa: E501 - - -class ISIS_AreaIdField(Field): - __slots__ = ["length_from"] - - def __init__(self, name, default, length_from): - Field.__init__(self, name, default) - self.length_from = length_from - - def i2m(self, pkt, x): - return isis_area2str(x) - - def m2i(self, pkt, x): - return isis_str2area(x) - - def i2len(self, pkt, x): - if x is None: - return 0 - tmp_len = len(x) - # l/5 is the number of dots in the Area ID - return (tmp_len - (tmp_len // 5)) // 2 - - def addfield(self, pkt, s, val): - sval = self.i2m(pkt, val) - return s + struct.pack("!%is" % len(sval), sval) - - def getfield(self, pkt, s): - numbytes = self.length_from(pkt) - return s[numbytes:], self.m2i(pkt, struct.unpack("!%is" % numbytes, s[:numbytes])[0]) # noqa: E501 - - def randval(self): - return _ISIS_RandAreaId() - - -class ISIS_SystemIdField(_ISIS_IdFieldBase): - def __init__(self, name, default): - _ISIS_IdFieldBase.__init__(self, name, default, 6, isis_sysid2str, isis_str2sysid) # noqa: E501 - - def randval(self): - return _ISIS_RandId("**.**.**") - - -class ISIS_NodeIdField(_ISIS_IdFieldBase): - def __init__(self, name, default): - _ISIS_IdFieldBase.__init__(self, name, default, 7, isis_nodeid2str, isis_str2nodeid) # noqa: E501 - - def randval(self): - return _ISIS_RandId("**.**.**.*") - - -class ISIS_LspIdField(_ISIS_IdFieldBase): - def __init__(self, name, default): - _ISIS_IdFieldBase.__init__(self, name, default, 8, isis_lspid2str, isis_str2lspid) # noqa: E501 - - def randval(self): - return _ISIS_RandId("**.**.**.*-*") - - -class ISIS_CircuitTypeField(FlagsField): - def __init__(self, name="circuittype", default=2, size=8, - names=None): - if names is None: - names = ["L1", "L2", "r0", "r1", "r2", "r3", "r4", "r5"] - FlagsField.__init__(self, name, default, size, names) - - -def _ISIS_GuessTlvClass_Helper(tlv_classes, defaultname, p, **kargs): - cls = conf.raw_layer - if len(p) >= 2: - tlvtype = orb(p[0]) - clsname = tlv_classes.get(tlvtype, defaultname) - cls = globals()[clsname] - - return cls(p, **kargs) - - -class _ISIS_GenericTlv_Base(Packet): - fields_desc = [ByteField("type", 0), - FieldLenField("len", None, length_of="val", fmt="B"), - BoundStrLenField("val", "", length_from=lambda pkt: pkt.len)] # noqa: E501 - - def guess_payload_class(self, p): - return conf.padding_layer - - -class ISIS_GenericTlv(_ISIS_GenericTlv_Base): - name = "ISIS Generic TLV" - - -class ISIS_GenericSubTlv(_ISIS_GenericTlv_Base): - name = "ISIS Generic Sub-TLV" - - -####################################################################### -# ISIS Sub-TLVs for TLVs 22, 23, 141, 222, 223 # -####################################################################### -_isis_subtlv_classes_1 = { - 3: "ISIS_AdministrativeGroupSubTlv", - 4: "ISIS_LinkLocalRemoteIdentifiersSubTlv", - 6: "ISIS_IPv4InterfaceAddressSubTlv", - 8: "ISIS_IPv4NeighborAddressSubTlv", - 9: "ISIS_MaximumLinkBandwidthSubTlv", - 10: "ISIS_MaximumReservableLinkBandwidthSubTlv", - 11: "ISIS_UnreservedBandwidthSubTlv", - 12: "ISIS_IPv6InterfaceAddressSubTlv", - 13: "ISIS_IPv6NeighborAddressSubTlv", - 18: "ISIS_TEDefaultMetricSubTlv" -} - -_isis_subtlv_names_1 = { - 3: "Administrative Group (Color)", - 4: "Link Local/Remote Identifiers", - 6: "IPv4 Interface Address", - 8: "IPv4 Neighbor Address", - 9: "Maximum Link Bandwidth", - 10: "Maximum Reservable Link Bandwidth", - 11: "Unreserved Bandwidth", - 12: "IPv6 Interface Address", - 13: "IPv6 Neighbor Address", - 18: "TE Default Metric" -} - - -def _ISIS_GuessSubTlvClass_1(p, **kargs): - return _ISIS_GuessTlvClass_Helper(_isis_subtlv_classes_1, "ISIS_GenericSubTlv", p, **kargs) # noqa: E501 - - -class ISIS_IPv4InterfaceAddressSubTlv(ISIS_GenericSubTlv): - name = "ISIS IPv4 Interface Address (S)" - fields_desc = [ByteEnumField("type", 6, _isis_subtlv_names_1), - FieldLenField("len", None, length_of="address", fmt="B"), - IPField("address", "0.0.0.0")] - - -class ISIS_IPv4NeighborAddressSubTlv(ISIS_GenericSubTlv): - name = "ISIS IPv4 Neighbor Address (S)" - fields_desc = [ByteEnumField("type", 8, _isis_subtlv_names_1), - FieldLenField("len", None, length_of="address", fmt="B"), - IPField("address", "0.0.0.0")] - - -class ISIS_LinkLocalRemoteIdentifiersSubTlv(ISIS_GenericSubTlv): - name = "ISIS Link Local/Remote Identifiers (S)" - fields_desc = [ByteEnumField("type", 4, _isis_subtlv_names_1), - FieldLenField("len", 8, fmt="B"), - IntField("localid", "0"), - IntField("remoteid", "0")] - - -class ISIS_IPv6InterfaceAddressSubTlv(ISIS_GenericSubTlv): - name = "ISIS IPv6 Interface Address (S)" - fields_desc = [ByteEnumField("type", 12, _isis_subtlv_names_1), - FieldLenField("len", None, length_of="address", fmt="B"), - IP6Field("address", "::")] - - -class ISIS_IPv6NeighborAddressSubTlv(ISIS_GenericSubTlv): - name = "ISIS IPv6 Neighbor Address (S)" - fields_desc = [ByteEnumField("type", 13, _isis_subtlv_names_1), - FieldLenField("len", None, length_of="address", fmt="B"), - IP6Field("address", "::")] - - -class ISIS_AdministrativeGroupSubTlv(ISIS_GenericSubTlv): - name = "Administrative Group SubTLV (Color)" - fields_desc = [ByteEnumField("code", 3, _isis_subtlv_names_1), - FieldLenField("len", None, length_of="admingroup", fmt="B"), - IPField("admingroup", "0.0.0.1")] - - -class ISIS_MaximumLinkBandwidthSubTlv(ISIS_GenericSubTlv): - name = "Maximum Link Bandwidth SubTLV" - fields_desc = [ByteEnumField("type", 9, _isis_subtlv_names_1), - FieldLenField("len", None, length_of="maxbw", fmt="B"), - IEEEFloatField("maxbw", 1000)] # in B/s - - -class ISIS_MaximumReservableLinkBandwidthSubTlv(ISIS_GenericSubTlv): - name = "Maximum Reservable Link Bandwidth SubTLV" - fields_desc = [ByteEnumField("type", 10, _isis_subtlv_names_1), - FieldLenField("len", None, length_of="maxrsvbw", fmt="B"), - IEEEFloatField("maxrsvbw", 1000)] # in B/s - - -class ISIS_UnreservedBandwidthSubTlv(ISIS_GenericSubTlv): - name = "Unreserved Bandwidth SubTLV" - fields_desc = [ByteEnumField("type", 11, _isis_subtlv_names_1), - FieldLenField("len", None, length_of="unrsvbw", fmt="B"), - FieldListField("unrsvbw", [1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000], IEEEFloatField("", 1000), count_from=lambda pkt: pkt.len / 4)] # in B/s # noqa: E501 - - -class ISIS_TEDefaultMetricSubTlv(ISIS_GenericSubTlv): - name = "TE Default Metric SubTLV" - fields_desc = [ByteEnumField("type", 18, _isis_subtlv_names_1), - FieldLenField("len", None, length_of="temetric", adjust=lambda pkt, x:x - 1, fmt="B"), # noqa: E501 - ThreeBytesField("temetric", 1000)] - - -####################################################################### -# ISIS Sub-TLVs for TLVs 135, 235, 236, and 237 # -####################################################################### -_isis_subtlv_classes_2 = { - 1: "ISIS_32bitAdministrativeTagSubTlv", - 2: "ISIS_64bitAdministrativeTagSubTlv" -} - -_isis_subtlv_names_2 = { - 1: "32-bit Administrative Tag", - 2: "64-bit Administrative Tag" -} - - -def _ISIS_GuessSubTlvClass_2(p, **kargs): - return _ISIS_GuessTlvClass_Helper(_isis_subtlv_classes_2, "ISIS_GenericSubTlv", p, **kargs) # noqa: E501 - - -class ISIS_32bitAdministrativeTagSubTlv(ISIS_GenericSubTlv): - name = "ISIS 32-bit Administrative Tag (S)" - fields_desc = [ByteEnumField("type", 1, _isis_subtlv_names_2), - FieldLenField("len", None, length_of="tags", fmt="B"), - FieldListField("tags", [], IntField("", 0), count_from=lambda pkt: pkt.len // 4)] # noqa: E501 - - -class ISIS_64bitAdministrativeTagSubTlv(ISIS_GenericSubTlv): - name = "ISIS 64-bit Administrative Tag (S)" - fields_desc = [ByteEnumField("type", 2, _isis_subtlv_names_2), - FieldLenField("len", None, length_of="tags", fmt="B"), - FieldListField("tags", [], LongField("", 0), count_from=lambda pkt: pkt.len // 8)] # noqa: E501 - - -####################################################################### -# ISIS TLVs # -####################################################################### -_isis_tlv_classes = { - 1: "ISIS_AreaTlv", - 2: "ISIS_IsReachabilityTlv", - 6: "ISIS_IsNeighbourTlv", - 8: "ISIS_PaddingTlv", - 9: "ISIS_LspEntryTlv", - 10: "ISIS_AuthenticationTlv", - 12: "ISIS_ChecksumTlv", - 14: "ISIS_BufferSizeTlv", - 22: "ISIS_ExtendedIsReachabilityTlv", - 128: "ISIS_InternalIpReachabilityTlv", - 129: "ISIS_ProtocolsSupportedTlv", - 130: "ISIS_ExternalIpReachabilityTlv", - 132: "ISIS_IpInterfaceAddressTlv", - 135: "ISIS_ExtendedIpReachabilityTlv", - 137: "ISIS_DynamicHostnameTlv", - 232: "ISIS_Ipv6InterfaceAddressTlv", - 236: "ISIS_Ipv6ReachabilityTlv", - 240: "ISIS_P2PAdjacencyStateTlv" -} - -_isis_tlv_names = { - 1: "Area TLV", - 2: "IS Reachability TLV", - 6: "IS Neighbour TLV", - 7: "Instance Identifier TLV", - 8: "Padding TLV", - 9: "LSP Entries TLV", - 10: "Authentication TLV", - 12: "Optional Checksum TLV", - 13: "Purge Originator Identification TLV", - 14: "LSP Buffer Size TLV", - 22: "Extended IS-Reachability TLV", - 23: "IS Neighbour Attribute TLV", - 24: "IS Alias ID", - 128: "IP Internal Reachability TLV", - 129: "Protocols Supported TLV", - 130: "IP External Reachability TLV", - 131: "Inter-Domain Routing Protocol Information TLV", - 132: "IP Interface Address TLV", - 134: "Traffic Engineering Router ID TLV", - 135: "Extended IP Reachability TLV", - 137: "Dynamic Hostname TLV", - 138: "GMPLS Shared Risk Link Group TLV", - 139: "IPv6 Shared Risk Link Group TLV", - 140: "IPv6 Traffic Engineering Router ID TLV", - 141: "Inter-AS Reachability Information TLV", - 142: "Group Address TLV", - 143: "Multi-Topology-Aware Port Capability TLV", - 144: "Multi-Topology Capability TLV", - 145: "TRILL Neighbour TLV", - 147: "MAC-Reachability TLV", - 148: "BFD-Enabled TLV", - 211: "Restart TLV", - 222: "Multi-Topology Intermediate Systems TLV", - 223: "Multi-Topology IS Neighbour Attributes TLV", - 229: "Multi-Topology TLV", - 232: "IPv6 Interface Address TLV", - 233: "IPv6 Global Interface Address TLV", - 235: "Multi-Topology IPv4 Reachability TLV", - 236: "IPv6 Reachability TLV", - 237: "Multi-Topology IPv6 Reachability TLV", - 240: "Point-to-Point Three-Way Adjacency TLV", - 242: "IS-IS Router Capability TLV", - 251: "Generic Information TLV" -} - - -def _ISIS_GuessTlvClass(p, **kargs): - return _ISIS_GuessTlvClass_Helper(_isis_tlv_classes, "ISIS_GenericTlv", p, **kargs) # noqa: E501 - - -class ISIS_AreaEntry(Packet): - name = "ISIS Area Entry" - fields_desc = [FieldLenField("arealen", None, length_of="areaid", fmt="B"), - ISIS_AreaIdField("areaid", "49", length_from=lambda pkt: pkt.arealen)] # noqa: E501 - - def extract_padding(self, s): - return "", s - - -class ISIS_AreaTlv(ISIS_GenericTlv): - name = "ISIS Area TLV" - fields_desc = [ByteEnumField("type", 1, _isis_tlv_names), - FieldLenField("len", None, length_of="areas", fmt="B"), - PacketListField("areas", [], ISIS_AreaEntry, length_from=lambda x: x.len)] # noqa: E501 - - -class ISIS_AuthenticationTlv(ISIS_GenericTlv): - name = "ISIS Authentication TLV" - fields_desc = [ByteEnumField("type", 10, _isis_tlv_names), - FieldLenField("len", None, length_of="password", adjust=lambda pkt, x: x + 1, fmt="B"), # noqa: E501 - ByteEnumField("authtype", 1, {1: "Plain", 17: "HMAC-MD5"}), - BoundStrLenField("password", "", maxlen=254, length_from=lambda pkt: pkt.len - 1)] # noqa: E501 - - -class ISIS_BufferSizeTlv(ISIS_GenericTlv): - name = "ISIS Buffer Size TLV" - fields_desc = [ByteEnumField("type", 14, _isis_tlv_names), - ByteField("len", 2), - ShortField("lspbuffersize", 1497)] - - -class ISIS_ChecksumTlv(ISIS_GenericTlv): - name = "ISIS Optional Checksum TLV" - fields_desc = [ByteEnumField("type", 12, _isis_tlv_names), - ByteField("len", 2), - XShortField("checksum", None)] - - -class ISIS_DynamicHostnameTlv(ISIS_GenericTlv): - name = "ISIS Dynamic Hostname TLV" - fields_desc = [ByteEnumField("type", 137, _isis_tlv_names), - FieldLenField("len", None, length_of="hostname", fmt="B"), - BoundStrLenField("hostname", "", length_from=lambda pkt: pkt.len)] # noqa: E501 - - -class ISIS_ExtendedIpPrefix(Packet): - name = "ISIS Extended IP Prefix" - fields_desc = [ - IntField("metric", 1), - BitField("updown", 0, 1), - BitField("subtlvindicator", 0, 1), - BitFieldLenField("pfxlen", None, 6, length_of="pfx"), - IPPrefixField("pfx", None, wordbytes=1, length_from=lambda x: x.pfxlen), # noqa: E501 - ConditionalField(FieldLenField("subtlvslen", None, length_of="subtlvs", fmt="B"), lambda pkt: pkt.subtlvindicator == 1), # noqa: E501 - ConditionalField(PacketListField("subtlvs", [], _ISIS_GuessSubTlvClass_2, length_from=lambda x: x.subtlvslen), lambda pkt: pkt.subtlvindicator == 1) # noqa: E501 - ] - - def extract_padding(self, s): - return "", s - - -class ISIS_TERouterIDTlv(ISIS_GenericTlv): - name = "ISIS TE Router ID TLV" - fields_desc = [ByteEnumField("type", 134, _isis_tlv_names), - FieldLenField("len", None, length_of="routerid", fmt="B"), - IPField("routerid", "0.0.0.0")] - - -class ISIS_ExtendedIpReachabilityTlv(ISIS_GenericTlv): - name = "ISIS Extended IP Reachability TLV" - fields_desc = [ByteEnumField("type", 135, _isis_tlv_names), - FieldLenField("len", None, length_of="pfxs", fmt="B"), - PacketListField("pfxs", [], ISIS_ExtendedIpPrefix, length_from=lambda pkt: pkt.len)] # noqa: E501 - - -class ISIS_ExtendedIsNeighbourEntry(Packet): - name = "ISIS Extended IS Neighbour Entry" - fields_desc = [ - ISIS_NodeIdField("neighbourid", "0102.0304.0506.07"), - ThreeBytesField("metric", 1), - FieldLenField("subtlvslen", None, length_of="subtlvs", fmt="B"), - PacketListField("subtlvs", [], _ISIS_GuessSubTlvClass_1, length_from=lambda x: x.subtlvslen) # noqa: E501 - ] - - def extract_padding(self, s): - return "", s - - -class ISIS_ExtendedIsReachabilityTlv(ISIS_GenericTlv): - name = "ISIS Extended IS Reachability TLV" - fields_desc = [ByteEnumField("type", 22, _isis_tlv_names), - FieldLenField("len", None, length_of="neighbours", fmt="B"), - PacketListField("neighbours", [], ISIS_ExtendedIsNeighbourEntry, length_from=lambda x: x.len)] # noqa: E501 - - -class ISIS_IpInterfaceAddressTlv(ISIS_GenericTlv): - name = "ISIS IP Interface Address TLV" - fields_desc = [ByteEnumField("type", 132, _isis_tlv_names), - FieldLenField("len", None, length_of="addresses", fmt="B"), - FieldListField("addresses", [], IPField("", "0.0.0.0"), count_from=lambda pkt: pkt.len // 4)] # noqa: E501 - - -class ISIS_Ipv6InterfaceAddressTlv(ISIS_GenericTlv): - name = "ISIS IPv6 Interface Address TLV" - fields_desc = [ - ByteEnumField("type", 232, _isis_tlv_names), - FieldLenField("len", None, length_of="addresses", fmt="B"), - IP6ListField("addresses", [], count_from=lambda pkt: pkt.len // 16) - ] - - -class ISIS_Ipv6Prefix(Packet): - name = "ISIS IPv6 Prefix" - fields_desc = [ - IntField("metric", 1), - BitField("updown", 0, 1), - BitField("external", 0, 1), - BitField("subtlvindicator", 0, 1), - BitField("reserved", 0, 5), - FieldLenField("pfxlen", None, length_of="pfx", fmt="B"), - IP6PrefixField("pfx", None, wordbytes=1, length_from=lambda x: x.pfxlen), # noqa: E501 - ConditionalField(FieldLenField("subtlvslen", None, length_of="subtlvs", fmt="B"), lambda pkt: pkt.subtlvindicator == 1), # noqa: E501 - ConditionalField(PacketListField("subtlvs", [], _ISIS_GuessSubTlvClass_2, length_from=lambda x: x.subtlvslen), lambda pkt: pkt.subtlvindicator == 1) # noqa: E501 - ] - - def extract_padding(self, s): - return "", s - - -class ISIS_Ipv6ReachabilityTlv(ISIS_GenericTlv): - name = "ISIS IPv6 Reachability TLV" - fields_desc = [ByteEnumField("type", 236, _isis_tlv_names), - FieldLenField("len", None, length_of="pfxs", fmt="B"), - PacketListField("pfxs", [], ISIS_Ipv6Prefix, length_from=lambda pkt: pkt.len)] # noqa: E501 - - -class ISIS_IsNeighbourTlv(ISIS_GenericTlv): - name = "ISIS IS Neighbour TLV" - fields_desc = [ByteEnumField("type", 6, _isis_tlv_names), - FieldLenField("len", None, length_of="neighbours", fmt="B"), - FieldListField("neighbours", [], MACField("", "00.00.00.00.00.00"), count_from=lambda pkt: pkt.len // 6)] # noqa: E501 - - -class ISIS_LspEntry(Packet): - name = "ISIS LSP Entry" - fields_desc = [ShortField("lifetime", 1200), - ISIS_LspIdField("lspid", "0102.0304.0506.07-08"), - XIntField("seqnum", 0x00000001), - XShortField("checksum", None)] - - def extract_padding(self, s): - return "", s - - -class ISIS_LspEntryTlv(ISIS_GenericTlv): - name = "ISIS LSP Entry TLV" - fields_desc = [ - ByteEnumField("type", 9, _isis_tlv_names), - FieldLenField("len", None, length_of="entries", fmt="B"), - PacketListField("entries", [], ISIS_LspEntry, count_from=lambda pkt: pkt.len // 16) # noqa: E501 - ] - - -class _AdjacencyStateTlvLenField(Field): - def i2m(self, pkt, x): - if pkt.neighbourextlocalcircuitid is not None: - return 15 - - if pkt.neighboursystemid is not None: - return 11 - - if pkt.extlocalcircuitid is not None: - return 5 - - return 1 - - -class ISIS_P2PAdjacencyStateTlv(ISIS_GenericTlv): - name = "ISIS P2P Adjacency State TLV" - fields_desc = [ByteEnumField("type", 240, _isis_tlv_names), - _AdjacencyStateTlvLenField("len", None, fmt="B"), - ByteEnumField("state", "Down", {0x2: "Down", 0x1: "Initialising", 0x0: "Up"}), # noqa: E501 - ConditionalField(IntField("extlocalcircuitid", None), lambda pkt: pkt.len >= 5), # noqa: E501 - ConditionalField(ISIS_SystemIdField("neighboursystemid", None), lambda pkt: pkt.len >= 11), # noqa: E501 - ConditionalField(IntField("neighbourextlocalcircuitid", None), lambda pkt: pkt.len == 15)] # noqa: E501 - - -# TODO dynamically allocate sufficient size -class ISIS_PaddingTlv(ISIS_GenericTlv): - name = "ISIS Padding TLV" - fields_desc = [ - ByteEnumField("type", 8, _isis_tlv_names), - FieldLenField("len", None, length_of="padding", fmt="B"), - BoundStrLenField("padding", "", length_from=lambda pkt: pkt.len) - ] - - -class ISIS_ProtocolsSupportedTlv(ISIS_GenericTlv): - name = "ISIS Protocols Supported TLV" - fields_desc = [ - ByteEnumField("type", 129, _isis_tlv_names), - FieldLenField("len", None, count_of="nlpids", fmt="B"), - FieldListField("nlpids", [], ByteEnumField("", "IPv4", network_layer_protocol_ids), count_from=lambda pkt: pkt.len) # noqa: E501 - ] - - -####################################################################### -# ISIS Old-Style TLVs # -####################################################################### - -class ISIS_IpReachabilityEntry(Packet): - name = "ISIS IP Reachability" - fields_desc = [ByteField("defmetric", 1), - ByteField("delmetric", 0x80), - ByteField("expmetric", 0x80), - ByteField("errmetric", 0x80), - IPField("ipaddress", "0.0.0.0"), - IPField("subnetmask", "255.255.255.255")] - - def extract_padding(self, s): - return "", s - - -class ISIS_InternalIpReachabilityTlv(ISIS_GenericTlv): - name = "ISIS Internal IP Reachability TLV" - fields_desc = [ - ByteEnumField("type", 128, _isis_tlv_names), - FieldLenField("len", None, length_of="entries", fmt="B"), - PacketListField("entries", [], ISIS_IpReachabilityEntry, count_from=lambda x: x.len // 12) # noqa: E501 - ] - - -class ISIS_ExternalIpReachabilityTlv(ISIS_GenericTlv): - name = "ISIS External IP Reachability TLV" - fields_desc = [ - ByteEnumField("type", 130, _isis_tlv_names), - FieldLenField("len", None, length_of="entries", fmt="B"), - PacketListField("entries", [], ISIS_IpReachabilityEntry, count_from=lambda x: x.len // 12) # noqa: E501 - ] - - -class ISIS_IsReachabilityEntry(Packet): - name = "ISIS IS Reachability" - fields_desc = [ByteField("defmetric", 1), - ByteField("delmetric", 0x80), - ByteField("expmetric", 0x80), - ByteField("errmetric", 0x80), - ISIS_NodeIdField("neighbourid", "0102.0304.0506.07")] - - def extract_padding(self, s): - return "", s - - -class ISIS_IsReachabilityTlv(ISIS_GenericTlv): - name = "ISIS IS Reachability TLV" - fields_desc = [ - ByteEnumField("type", 2, _isis_tlv_names), - FieldLenField("len", None, fmt="B", length_of="neighbours", adjust=lambda pkt, x: x + 1), # noqa: E501 - ByteField("virtual", 0), - PacketListField("neighbours", [], ISIS_IsReachabilityEntry, count_from=lambda x: (x.len - 1) // 11) # noqa: E501 - ] - - -####################################################################### -# ISIS PDU Packets # -####################################################################### -_isis_pdu_names = { - 15: "L1 LAN Hello", - 16: "L2 LAN Hello", - 17: "P2P Hello", - 18: "L1 LSP", - 20: "L2 LSP", - 24: "L1 CSNP", - 25: "L2 CSNP", - 26: "L1 PSNP", - 27: "L2 PSNP" -} - - -class ISIS_CommonHdr(Packet): - name = "ISIS Common Header" - fields_desc = [ - ByteEnumField("nlpid", 0x83, network_layer_protocol_ids), - ByteField("hdrlen", None), - ByteField("version", 1), - ByteField("idlen", 0), - ByteEnumField("pdutype", None, _isis_pdu_names), - ByteField("pduversion", 1), - ByteField("hdrreserved", 0), - ByteField("maxareaaddr", 0) - ] - - def post_build(self, pkt, pay): - # calculating checksum if requested - pdu = pkt + pay - checksumInfo = self[1].checksum_info(self.hdrlen) - - if checksumInfo is not None: - (cbegin, cpos) = checksumInfo - checkbytes = fletcher16_checkbytes(pdu[cbegin:], (cpos - cbegin)) - pdu = pdu[:cpos] + checkbytes + pdu[cpos + 2:] - - return pdu - - -class _ISIS_PduBase(Packet): - def checksum_info(self, hdrlen): - checksumPosition = hdrlen - for tlv in self.tlvs: - if isinstance(tlv, ISIS_ChecksumTlv): - checksumPosition += 2 - return (0, checksumPosition) - else: - checksumPosition += len(tlv) - - return None - - def guess_payload_class(self, p): - return conf.padding_layer - - -class _ISIS_PduLengthField(FieldLenField): - def __init__(self): - FieldLenField.__init__(self, "pdulength", None, length_of="tlvs", adjust=lambda pkt, x: x + pkt.underlayer.hdrlen) # noqa: E501 - - -class _ISIS_TlvListField(PacketListField): - def __init__(self): - PacketListField.__init__(self, "tlvs", [], _ISIS_GuessTlvClass, length_from=lambda pkt: pkt.pdulength - pkt.underlayer.hdrlen) # noqa: E501 - - -class _ISIS_LAN_HelloBase(_ISIS_PduBase): - fields_desc = [ - ISIS_CircuitTypeField(), - ISIS_SystemIdField("sourceid", "0102.0304.0506"), - ShortField("holdingtime", 30), - _ISIS_PduLengthField(), - ByteField("priority", 1), - ISIS_NodeIdField("lanid", "0000.0000.0000.00"), - _ISIS_TlvListField() - ] - - -class ISIS_L1_LAN_Hello(_ISIS_LAN_HelloBase): - name = "ISIS L1 LAN Hello PDU" - - -class ISIS_L2_LAN_Hello(_ISIS_LAN_HelloBase): - name = "ISIS L2 LAN Hello PDU" - - -class ISIS_P2P_Hello(_ISIS_PduBase): - name = "ISIS Point-to-Point Hello PDU" - - fields_desc = [ - ISIS_CircuitTypeField(), - ISIS_SystemIdField("sourceid", "0102.0304.0506"), - ShortField("holdingtime", 30), - _ISIS_PduLengthField(), - ByteField("localcircuitid", 0), - _ISIS_TlvListField() - ] - - -class _ISIS_LSP_Base(_ISIS_PduBase): - fields_desc = [ - _ISIS_PduLengthField(), - ShortField("lifetime", 1199), - ISIS_LspIdField("lspid", "0102.0304.0506.00-00"), - XIntField("seqnum", 0x00000001), - XShortField("checksum", None), - FlagsField("typeblock", 0x03, 8, ["L1", "L2", "OL", "ADef", "ADel", "AExp", "AErr", "P"]), # noqa: E501 - _ISIS_TlvListField() - ] - - def checksum_info(self, hdrlen): - if self.checksum is not None: - return None - - return (12, 24) - - -def _lsp_answers(lsp, other, clsname): - # TODO - return 0 - - -class ISIS_L1_LSP(_ISIS_LSP_Base): - name = "ISIS L1 Link State PDU" - - def answers(self, other): - return _lsp_answers(self, other, "ISIS_L1_PSNP") - - -class ISIS_L2_LSP(_ISIS_LSP_Base): - name = "ISIS L2 Link State PDU" - - def answers(self, other): - return _lsp_answers(self, other, "ISIS_L2_PSNP") - - -class _ISIS_CSNP_Base(_ISIS_PduBase): - fields_desc = [ - _ISIS_PduLengthField(), - ISIS_NodeIdField("sourceid", "0102.0304.0506.00"), - ISIS_LspIdField("startlspid", "0000.0000.0000.00-00"), - ISIS_LspIdField("endlspid", "FFFF.FFFF.FFFF.FF-FF"), - _ISIS_TlvListField() - ] - - -def _snp_answers(snp, other, clsname): - # TODO - return 0 - - -class ISIS_L1_CSNP(_ISIS_CSNP_Base): - name = "ISIS L1 Complete Sequence Number Packet" - - def answers(self, other): - return _snp_answers(self, other, "ISIS_L1_LSP") - - -class ISIS_L2_CSNP(_ISIS_CSNP_Base): - name = "ISIS L2 Complete Sequence Number Packet" - - def answers(self, other): - return _snp_answers(self, other, "ISIS_L2_LSP") - - -class _ISIS_PSNP_Base(_ISIS_PduBase): - fields_desc = [ - _ISIS_PduLengthField(), - ISIS_NodeIdField("sourceid", "0102.0304.0506.00"), - _ISIS_TlvListField() - ] - - -class ISIS_L1_PSNP(_ISIS_PSNP_Base): - name = "ISIS L1 Partial Sequence Number Packet" - - def answers(self, other): - return _snp_answers(self, other, "ISIS_L1_LSP") - - -class ISIS_L2_PSNP(_ISIS_PSNP_Base): - name = "ISIS L2 Partial Sequence Number Packet" - - def answers(self, other): - return _snp_answers(self, other, "ISIS_L2_LSP") - - -register_cln_protocol(0x83, ISIS_CommonHdr) -bind_layers(ISIS_CommonHdr, ISIS_L1_LAN_Hello, hdrlen=27, pdutype=15) -bind_layers(ISIS_CommonHdr, ISIS_L2_LAN_Hello, hdrlen=27, pdutype=16) -bind_layers(ISIS_CommonHdr, ISIS_P2P_Hello, hdrlen=20, pdutype=17) -bind_layers(ISIS_CommonHdr, ISIS_L1_LSP, hdrlen=27, pdutype=18) -bind_layers(ISIS_CommonHdr, ISIS_L2_LSP, hdrlen=27, pdutype=20) -bind_layers(ISIS_CommonHdr, ISIS_L1_CSNP, hdrlen=33, pdutype=24) -bind_layers(ISIS_CommonHdr, ISIS_L2_CSNP, hdrlen=33, pdutype=25) -bind_layers(ISIS_CommonHdr, ISIS_L1_PSNP, hdrlen=17, pdutype=26) -bind_layers(ISIS_CommonHdr, ISIS_L2_PSNP, hdrlen=17, pdutype=27) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/isotp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/isotp.py deleted file mode 100644 index afe4344b6d..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/isotp.py +++ /dev/null @@ -1,1999 +0,0 @@ -#! /usr/bin/env python - -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Nils Weiss -# Copyright (C) Enrico Pozzobon -# Copyright (C) Alexander Schroeder -# This program is published under a GPLv2 license - -# scapy.contrib.description = ISO-TP (ISO 15765-2) -# scapy.contrib.status = loads - -""" -ISOTPSocket. -""" - - -import ctypes -from ctypes.util import find_library -import struct -import socket -import time -from threading import Thread, Event, Lock, Semaphore - -from scapy.packet import Packet -from scapy.fields import BitField, FlagsField, StrLenField, \ - ThreeBytesField, XBitField, ConditionalField, \ - BitEnumField, ByteField, XByteField, BitFieldLenField, StrField -from scapy.compat import chb, orb -from scapy.layers.can import CAN -import scapy.modules.six as six -import scapy.automaton as automaton -import six.moves.queue as queue -from scapy.error import Scapy_Exception, warning, log_loading -from scapy.supersocket import SuperSocket -from scapy.config import conf -from scapy.consts import LINUX -from scapy.contrib.cansocket import PYTHON_CAN -from scapy.sendrecv import sniff -from scapy.sessions import DefaultSession - -__all__ = ["ISOTP", "ISOTPHeader", "ISOTPHeaderEA", "ISOTP_SF", "ISOTP_FF", - "ISOTP_CF", "ISOTP_FC", "ISOTPSoftSocket", "ISOTPSession", - "ISOTPSocket", "ISOTPSocketImplementation", "ISOTPMessageBuilder", - "ISOTPScan"] - -USE_CAN_ISOTP_KERNEL_MODULE = False -if six.PY3 and LINUX: - LIBC = ctypes.cdll.LoadLibrary(find_library("c")) - try: - if conf.contribs['ISOTP']['use-can-isotp-kernel-module']: - USE_CAN_ISOTP_KERNEL_MODULE = True - except KeyError: - log_loading.info("Specify 'conf.contribs['ISOTP'] = " - "{'use-can-isotp-kernel-module': True}' to enable " - "usage of can-isotp kernel module.") - -CAN_MAX_IDENTIFIER = (1 << 29) - 1 # Maximum 29-bit identifier -CAN_MTU = 16 -CAN_MAX_DLEN = 8 -ISOTP_MAX_DLEN_2015 = (1 << 32) - 1 # Maximum for 32-bit FF_DL -ISOTP_MAX_DLEN = (1 << 12) - 1 # Maximum for 12-bit FF_DL - -N_PCI_SF = 0x00 # /* single frame */ -N_PCI_FF = 0x10 # /* first frame */ -N_PCI_CF = 0x20 # /* consecutive frame */ -N_PCI_FC = 0x30 # /* flow control */ - - -class ISOTP(Packet): - name = 'ISOTP' - fields_desc = [ - StrField('data', B"") - ] - __slots__ = Packet.__slots__ + ["src", "dst", "exsrc", "exdst"] - - def answers(self, other): - if other.__class__ == self.__class__: - return self.payload.answers(other.payload) - return 0 - - def __init__(self, *args, **kwargs): - self.src = None - self.dst = None - self.exsrc = None - self.exdst = None - if "src" in kwargs: - self.src = kwargs["src"] - del kwargs["src"] - if "dst" in kwargs: - self.dst = kwargs["dst"] - del kwargs["dst"] - if "exsrc" in kwargs: - self.exsrc = kwargs["exsrc"] - del kwargs["exsrc"] - if "exdst" in kwargs: - self.exdst = kwargs["exdst"] - del kwargs["exdst"] - Packet.__init__(self, *args, **kwargs) - self.validate_fields() - - def validate_fields(self): - if self.src is not None: - if not 0 <= self.src <= CAN_MAX_IDENTIFIER: - raise Scapy_Exception("src is not a valid CAN identifier") - if self.dst is not None: - if not 0 <= self.dst <= CAN_MAX_IDENTIFIER: - raise Scapy_Exception("dst is not a valid CAN identifier") - if self.exsrc is not None: - if not 0 <= self.exsrc <= 0xff: - raise Scapy_Exception("exsrc is not a byte") - if self.exdst is not None: - if not 0 <= self.exdst <= 0xff: - raise Scapy_Exception("exdst is not a byte") - - def fragment(self): - data_bytes_in_frame = 7 - if self.exdst is not None: - data_bytes_in_frame = 6 - - if len(self.data) > ISOTP_MAX_DLEN_2015: - raise Scapy_Exception("Too much data in ISOTP message") - - if len(self.data) <= data_bytes_in_frame: - # We can do this in a single frame - frame_data = struct.pack('B', len(self.data)) + self.data - if self.exdst: - frame_data = struct.pack('B', self.exdst) + frame_data - pkt = CAN(identifier=self.dst, data=frame_data) - return [pkt] - - # Construct the first frame - if len(self.data) <= ISOTP_MAX_DLEN: - frame_header = struct.pack(">H", len(self.data) + 0x1000) - else: - frame_header = struct.pack(">HI", 0x1000, len(self.data)) - if self.exdst: - frame_header = struct.pack('B', self.exdst) + frame_header - idx = 8 - len(frame_header) - frame_data = self.data[0:idx] - frame = CAN(identifier=self.dst, data=frame_header + frame_data) - - # Construct consecutive frames - n = 1 - pkts = [frame] - while idx < len(self.data): - frame_data = self.data[idx:idx + data_bytes_in_frame] - frame_header = struct.pack("b", (n % 16) + N_PCI_CF) - - n += 1 - idx += len(frame_data) - - if self.exdst: - frame_header = struct.pack('B', self.exdst) + frame_header - pkt = CAN(identifier=self.dst, data=frame_header + frame_data) - pkts.append(pkt) - return pkts - - @staticmethod - def defragment(can_frames, use_extended_addressing=None): - if len(can_frames) == 0: - raise Scapy_Exception("ISOTP.defragment called with 0 frames") - - dst = can_frames[0].identifier - for frame in can_frames: - if frame.identifier != dst: - warning("Not all CAN frames have the same identifier") - - parser = ISOTPMessageBuilder(use_extended_addressing) - for c in can_frames: - parser.feed(c) - - results = [] - while parser.count > 0: - p = parser.pop() - if (use_extended_addressing is True and p.exdst is not None) \ - or (use_extended_addressing is False and p.exdst is None) \ - or (use_extended_addressing is None): - results.append(p) - - if len(results) == 0: - return None - - if len(results) > 0: - warning("More than one ISOTP frame could be defragmented from the " - "provided CAN frames, returning the first one.") - - return results[0] - - -class ISOTPHeader(CAN): - name = 'ISOTPHeader' - fields_desc = [ - FlagsField('flags', 0, 3, ['error', - 'remote_transmission_request', - 'extended']), - XBitField('identifier', 0, 29), - ByteField('length', None), - ThreeBytesField('reserved', 0), - ] - - def extract_padding(self, p): - return p, None - - def post_build(self, pkt, pay): - """ - This will set the ByteField 'length' to the correct value. - """ - if self.length is None: - pkt = pkt[:4] + chb(len(pay)) + pkt[5:] - return pkt + pay - - def guess_payload_class(self, payload): - """ - ISOTP encodes the frame type in the first nibble of a frame. - """ - t = (orb(payload[0]) & 0xf0) >> 4 - if t == 0: - return ISOTP_SF - elif t == 1: - return ISOTP_FF - elif t == 2: - return ISOTP_CF - else: - return ISOTP_FC - - -class ISOTPHeaderEA(ISOTPHeader): - name = 'ISOTPHeaderExtendedAddress' - fields_desc = ISOTPHeader.fields_desc + [ - XByteField('extended_address', 0), - ] - - def post_build(self, p, pay): - """ - This will set the ByteField 'length' to the correct value. - 'chb(len(pay) + 1)' is required, because the field 'extended_address' - is counted as payload on the CAN layer - """ - if self.length is None: - p = p[:4] + chb(len(pay) + 1) + p[5:] - return p + pay - - -ISOTP_TYPE = {0: 'single', - 1: 'first', - 2: 'consecutive', - 3: 'flow_control'} - - -class ISOTP_SF(Packet): - name = 'ISOTPSingleFrame' - fields_desc = [ - BitEnumField('type', 0, 4, ISOTP_TYPE), - BitFieldLenField('message_size', None, 4, length_of='data'), - StrLenField('data', '', length_from=lambda pkt: pkt.message_size) - ] - - -class ISOTP_FF(Packet): - name = 'ISOTPFirstFrame' - fields_desc = [ - BitEnumField('type', 1, 4, ISOTP_TYPE), - BitField('message_size', 0, 12), - ConditionalField(BitField('extended_message_size', 0, 32), - lambda pkt: pkt.message_size == 0), - StrField('data', '', fmt="B") - ] - - -class ISOTP_CF(Packet): - name = 'ISOTPConsecutiveFrame' - fields_desc = [ - BitEnumField('type', 2, 4, ISOTP_TYPE), - BitField('index', 0, 4), - StrField('data', '', fmt="B") - ] - - -class ISOTP_FC(Packet): - name = 'ISOTPFlowControlFrame' - fields_desc = [ - BitEnumField('type', 3, 4, ISOTP_TYPE), - BitEnumField('fc_flag', 0, 4, {0: 'continue', - 1: 'wait', - 2: 'abort'}), - ByteField('block_size', 0), - ByteField('separation_time', 0), - ] - - -class ISOTPMessageBuilderIter(object): - slots = ["builder"] - - def __init__(self, builder): - self.builder = builder - - def __iter__(self): - return self - - def __next__(self): - while self.builder.count: - return self.builder.pop() - raise StopIteration - - next = __next__ - - -class ISOTPMessageBuilder: - """ - Utility class to build ISOTP messages out of CAN frames, used by both - ISOTP.defragment() and ISOTPSession. - - This class attempts to interpret some CAN frames as ISOTP frames, both with - and without extended addressing at the same time. For example, if an - extended address of 07 is being used, all frames will also be interpreted - as ISOTP single-frame messages. - - CAN frames are fed to an ISOTPMessageBuilder object with the feed() method - and the resulting ISOTP frames can be extracted using the pop() method. - """ - - class Bucket: - def __init__(self, total_len, first_piece): - self.pieces = [first_piece] - self.total_len = total_len - self.current_len = len(first_piece) - self.ready = None - - def push(self, piece): - self.pieces.append(piece) - self.current_len += len(piece) - if self.current_len >= self.total_len: - if six.PY3: - isotp_data = b"".join(self.pieces) - else: - isotp_data = "".join(map(str, self.pieces)) - self.ready = isotp_data[:self.total_len] - - def __init__(self, use_ext_addr=None, basecls=None): - """ - Initialize a ISOTPMessageBuilder object - - :param use_ext_addr: True for only attempting to defragment with - extended addressing, False for only attempting - to defragment without extended addressing, - or None for both - :param basecls: the class of packets that will be returned, - defaults to ISOTP - - """ - self.ready = [] - self.buckets = {} - self.use_ext_addr = use_ext_addr - self.basecls = basecls or ISOTP - - def feed(self, can): - """Attempt to feed an incoming CAN frame into the state machine""" - if not isinstance(can, Packet) and hasattr(can, "__iter__"): - for p in can: - self.feed(p) - return - if not isinstance(can, CAN): - raise Scapy_Exception("argument is not a CAN frame") - identifier = can.identifier - data = bytes(can.data) - - if len(data) > 1 and self.use_ext_addr is not True: - self._try_feed(identifier, None, data) - if len(data) > 2 and self.use_ext_addr is not False: - ea = six.indexbytes(data, 0) - self._try_feed(identifier, ea, data[1:]) - - @property - def count(self): - """Returns the number of ready ISOTP messages built from the provided - can frames""" - return len(self.ready) - - def __len__(self): - return self.count - - def pop(self, identifier=None, ext_addr=None): - """ - Returns a built ISOTP message - :param identifier: if not None, only return isotp messages with this - destination - :param ext_addr: if identifier is not None, only return isotp messages - with this extended address for destination - :return: an ISOTP packet, or None if no message is ready - """ - - if identifier is not None: - for i in range(len(self.ready)): - b = self.ready[i] - iden = b[0] - ea = b[1] - if iden == identifier and ext_addr == ea: - return ISOTPMessageBuilder._build(self.ready.pop(i), - self.basecls) - return None - - if len(self.ready) > 0: - return ISOTPMessageBuilder._build(self.ready.pop(0), self.basecls) - return None - - def __iter__(self): - return ISOTPMessageBuilderIter(self) - - @staticmethod - def _build(t, basecls=ISOTP): - p = basecls(t[2]) - if hasattr(p, "dst"): - p.dst = t[0] - if hasattr(p, "exdst"): - p.exdst = t[1] - return p - - def _feed_first_frame(self, identifier, ea, data): - if len(data) < 3: - # At least 3 bytes are necessary: 2 for length and 1 for data - return False - - header = struct.unpack('>H', bytes(data[:2]))[0] - expected_length = header & 0x0fff - isotp_data = data[2:] - if expected_length == 0 and len(data) >= 6: - expected_length = struct.unpack('>I', bytes(data[2:6]))[0] - isotp_data = data[6:] - - key = (ea, identifier, 1) - self.buckets[key] = self.Bucket(expected_length, isotp_data) - return True - - def _feed_single_frame(self, identifier, ea, data): - if len(data) < 2: - # At least 2 bytes are necessary: 1 for length and 1 for data - return False - - length = six.indexbytes(data, 0) & 0x0f - isotp_data = data[1:length + 1] - - if length > len(isotp_data): - # CAN frame has less data than expected - return False - - self.ready.append((identifier, ea, isotp_data)) - return True - - def _feed_consecutive_frame(self, identifier, ea, data): - if len(data) < 2: - # At least 2 bytes are necessary: 1 for sequence number and - # 1 for data - return False - - first_byte = six.indexbytes(data, 0) - seq_no = first_byte & 0x0f - isotp_data = data[1:] - - key = (ea, identifier, seq_no) - bucket = self.buckets.pop(key, None) - - if bucket is None: - # There is no message constructor waiting for this frame - return False - - bucket.push(isotp_data) - if bucket.ready is None: - # full ISOTP message is not ready yet, put it back in - # buckets list - next_seq = (seq_no + 1) % 16 - key = (ea, identifier, next_seq) - self.buckets[key] = bucket - else: - self.ready.append((identifier, ea, bucket.ready)) - - return True - - def _try_feed(self, identifier, ea, data): - first_byte = six.indexbytes(data, 0) - if len(data) > 1 and first_byte & 0xf0 == N_PCI_SF: - self._feed_single_frame(identifier, ea, data) - if len(data) > 2 and first_byte & 0xf0 == N_PCI_FF: - self._feed_first_frame(identifier, ea, data) - if len(data) > 1 and first_byte & 0xf0 == N_PCI_CF: - self._feed_consecutive_frame(identifier, ea, data) - - -class ISOTPSession(DefaultSession): - """Defragment ISOTP packets 'on-the-flow'. - Usage: - >>> sniff(session=ISOTPSession) - """ - - def __init__(self, *args, **karg): - DefaultSession.__init__(self, *args) - self.m = ISOTPMessageBuilder(**karg) - - def on_packet_received(self, pkt): - self.m.feed(pkt) - while len(self.m) > 0: - rcvd = self.m.pop() - DefaultSession.on_packet_received(self, rcvd) - - -class ISOTPSoftSocket(SuperSocket): - """ - This class is a wrapper around the ISOTPSocketImplementation, for the - reasons described below. - - The ISOTPSoftSocket aims to be fully compatible with the Linux ISOTP - sockets provided by the can-isotp kernel module, while being usable on any - operating system. - Therefore, this socket needs to be able to respond to an incoming FF frame - with a FC frame even before the recv() method is called. - A thread is needed for receiving CAN frames in the background, and since - the lower layer CAN implementation is not guaranteed to have a functioning - POSIX select(), each ISOTP socket needs its own CAN receiver thread. - Additionally, 2 timers are necessary to keep track of the timeouts and - frame separation times, and each timer is implemented in its own thread. - In total, each ISOTPSoftSocket spawns 3 background threads when - constructed, which must be terminated afterwards by calling the close() - method. - SuperSocket automatically calls the close() method when the GC destroys an - ISOTPSoftSocket. However, note that if any thread holds a reference to - an ISOTPSoftSocket object, it will not be collected by the GC. - - The implementation of the ISOTP protocol, along with the necessary - threads, are stored in the ISOTPSocketImplementation class, and therefore: - - * There no reference from ISOTPSocketImplementation to ISOTPSoftSocket - * ISOTPSoftSocket can be normally garbage collected - * Upon destruction, ISOTPSoftSocket.close() will be called - * ISOTPSoftSocket.close() will call ISOTPSocketImplementation.close() - * All background threads can be stopped by the garbage collector - """ - - nonblocking_socket = True - - def __init__(self, - can_socket=None, - sid=0, - did=0, - extended_addr=None, - extended_rx_addr=None, - rx_block_size=0, - rx_separation_time_min=0, - padding=False, - listen_only=False, - basecls=ISOTP): - """ - Initialize an ISOTPSoftSocket using the provided underlying can socket - - :param can_socket: a CANSocket instance, preferably filtering only can - frames with identifier equal to did - :param sid: the CAN identifier of the sent CAN frames - :param did: the CAN identifier of the received CAN frames - :param extended_addr: the extended address of the sent ISOTP frames - (can be None) - :param extended_rx_addr: the extended address of the received ISOTP - frames (can be None) - :param rx_block_size: block size sent in Flow Control ISOTP frames - :param rx_separation_time_min: minimum desired separation time sent in - Flow Control ISOTP frames - :param padding: If True, pads sending packets with 0x00 which not - count to the payload. - Does not affect receiving packets. - :param basecls: base class of the packets emitted by this socket - """ - - if six.PY3 and LINUX and isinstance(can_socket, six.string_types): - from scapy.contrib.cansocket import CANSocket - can_socket = CANSocket(can_socket) - elif isinstance(can_socket, six.string_types): - raise Scapy_Exception("Provide a CANSocket object instead") - - self.exsrc = extended_addr - self.exdst = extended_rx_addr - self.src = sid - self.dst = did - - impl = ISOTPSocketImplementation( - can_socket, - src_id=sid, - dst_id=did, - padding=padding, - extended_addr=extended_addr, - extended_rx_addr=extended_rx_addr, - rx_block_size=rx_block_size, - rx_separation_time_min=rx_separation_time_min, - listen_only=listen_only - ) - - self.ins = impl - self.outs = impl - self.impl = impl - - if basecls is None: - warning('Provide a basecls ') - self.basecls = basecls - - def close(self): - self.impl.close() - self.outs = None - self.ins = None - SuperSocket.close(self) - - def begin_send(self, p): - """Begin the transmission of message p. This method returns after - sending the first frame. If multiple frames are necessary to send the - message, this socket will unable to send other messages until either - the transmission of this frame succeeds or it fails.""" - if hasattr(p, "sent_time"): - p.sent_time = time.time() - - return self.outs.begin_send(bytes(p)) - - def recv_raw(self, x=0xffff): - """Receive a complete ISOTP message, blocking until a message is - received or the specified timeout is reached. - If self.timeout is 0, then this function doesn't block and returns the - first frame in the receive buffer or None if there isn't any.""" - msg = self.ins.recv() - t = time.time() - return self.basecls, msg, t - - def recv(self, x=0xffff): - msg = SuperSocket.recv(self, x) - - if hasattr(msg, "src"): - msg.src = self.src - if hasattr(msg, "dst"): - msg.dst = self.dst - if hasattr(msg, "exsrc"): - msg.exsrc = self.exsrc - if hasattr(msg, "exdst"): - msg.exdst = self.exdst - return msg - - @staticmethod - def select(sockets, remain=None): - """This function is called during sendrecv() routine to wait for - sockets to be ready to receive - """ - blocking = remain is None or remain > 0 - - def find_ready_sockets(): - return list(filter(lambda x: not x.ins.rx_queue.empty(), sockets)) - - ready_sockets = find_ready_sockets() - if len(ready_sockets) > 0 or not blocking: - return ready_sockets, None - - exit_select = Event() - - def my_cb(msg): - exit_select.set() - - try: - for s in sockets: - s.ins.rx_callbacks.append(my_cb) - - exit_select.wait(remain) - - finally: - for s in sockets: - try: - s.ins.rx_callbacks.remove(my_cb) - except ValueError: - pass - - ready_sockets = find_ready_sockets() - return ready_sockets, None - - -ISOTPSocket = ISOTPSoftSocket - - -class CANReceiverThread(Thread): - """ - Helper class that receives CAN frames and feeds them to the provided - callback. It relies on CAN frames being enqueued in the CANSocket object - and not being lost if they come before the sniff method is called. This is - true in general since sniff is usually implemented as repeated recv(), but - might be false in some implementation of CANSocket - """ - - def __init__(self, can_socket, callback): - """ - Initialize the thread. In order for this thread to be able to be - stopped by the destructor of another object, it is important to not - keep a reference to the object in the callback function. - - :param socket: the CANSocket upon which this class will call the - sniff() method - :param callback: function to call whenever a CAN frame is received - """ - self.socket = can_socket - self.callback = callback - self.exiting = False - self._thread_started = Event() - self.exception = None - - Thread.__init__(self) - self.name = "CANReceiver" + self.name - - def start(self): - Thread.start(self) - self._thread_started.wait() - - def run(self): - self._thread_started.set() - try: - def prn(msg): - if not self.exiting: - self.callback(msg) - - while 1: - try: - sniff(store=False, timeout=1, count=1, - stop_filter=lambda x: self.exiting, - prn=prn, opened_socket=self.socket) - except ValueError as ex: - if not self.exiting: - raise ex - if self.exiting: - return - except Exception as ex: - self.exception = ex - - def stop(self): - self.exiting = True - - -class TimeoutThread(Thread): - """ - Utility class implementing a timer, useful for both timeouts and - waiting between sent CAN frames. - Contrary to the threading.Timer implementation, this timer thread can be - reused for multiple timeouts. This avoids the overhead of creating a new - pthread every time a timeout is planned. - """ - - def __init__(self): - Thread.__init__(self) - - self._thread_started = Event() - self._cancelled = Event() - self._ready_sem = Semaphore(1) - self._busy_sem = Semaphore(0) - self._timeout = 1 - self._callback = None - self._exception = None - self._killed = False - self._dead = False - - self.name = "ISOTP Timer " + self.name - - def run(self): - self._thread_started.set() - - try: - while not self._killed: - self._busy_sem.acquire() - f = self._cancelled.wait(self._timeout) - self._ready_sem.release() - if f is False: - if self._callback is not None: - self._callback() - - except Exception as ex: - self._exception = ex - warning(self.name + " is now stopped") - raise ex - - finally: - self._dead = True - - def start(self): - """Start the thread, and make sure it is running""" - Thread.start(self) - self._thread_started.wait() - - def set_timeout(self, timeout, callback): - """Call 'callback' in 'timeout' seconds, unless cancelled.""" - if not self._ready_sem.acquire(False): - raise Scapy_Exception("Timer was already started") - - self._callback = callback - self._timeout = timeout - self._cancelled.clear() - self._busy_sem.release() - - def cancel(self): - """Stop the timer without executing the callback.""" - self._cancelled.set() - if not self._dead: - self._ready_sem.acquire() - self._ready_sem.release() - - def stop(self): - """Stop the thread, making this object unusable.""" - if not self._dead: - self._killed = True - self._cancelled.set() - self._busy_sem.release() - self.join() - if not self._ready_sem.acquire(False): - warning("ISOTP Timer thread may not have stopped " - "correctly") - - -"""ISOTPSoftSocket definitions.""" - -# Enum states -ISOTP_IDLE = 0 -ISOTP_WAIT_FIRST_FC = 1 -ISOTP_WAIT_FC = 2 -ISOTP_WAIT_DATA = 3 -ISOTP_SENDING = 4 - -# /* Flow Status given in FC frame */ -ISOTP_FC_CTS = 0 # /* clear to send */ -ISOTP_FC_WT = 1 # /* wait */ -ISOTP_FC_OVFLW = 2 # /* overflow */ - - -class ISOTPSocketImplementation(automaton.SelectableObject): - """ - Implementation of an ISOTP "state machine". - - Most of the ISOTP logic was taken from - https://github.com/hartkopp/can-isotp/blob/master/net/can/isotp.c - - This class is separated from ISOTPSoftSocket to make sure the background - threads can't hold a reference to ISOTPSoftSocket, allowing it to be - collected by the GC. - """ - - def __init__(self, - can_socket, - src_id, - dst_id, - padding=False, - extended_addr=None, - extended_rx_addr=None, - rx_block_size=0, - rx_separation_time_min=0, - listen_only=False): - """ - :param can_socket: a CANSocket instance, preferably filtering only can - frames with identifier equal to did - :param src_id: the CAN identifier of the sent CAN frames - :param dst_id: the CAN identifier of the received CAN frames - :param padding: If True, pads sending packets with 0x00 which not - count to the payload. - Does not affect receiving packets. - :param extended_addr: Extended Address byte to be added at the - beginning of every CAN frame _sent_ by this object. Can be None - in order to disable extended addressing on sent frames. - :param extended_rx_addr: Extended Address byte expected to be found at - the beginning of every CAN frame _received_ by this object. Can - be None in order to disable extended addressing on received - frames. - :param rx_block_size: Block Size byte to be included in every Control - Flow Frame sent by this object. The default value of 0 means - that all the data will be received in a single block. - :param rx_separation_time_min: Time Minimum Separation byte to be - included in every Control Flow Frame sent by this object. The - default value of 0 indicates that the peer will not wait any - time between sending frames. - :param listen_only: Disables send of flow control frames - """ - - automaton.SelectableObject.__init__(self) - - self.can_socket = can_socket - self.dst_id = dst_id - self.src_id = src_id - self.padding = padding - self.fc_timeout = 1 - self.cf_timeout = 1 - - self.filter_warning_emitted = False - - self.extended_rx_addr = extended_rx_addr - self.ea_hdr = b"" - if extended_addr is not None: - self.ea_hdr = struct.pack("B", extended_addr) - self.listen_only = listen_only - - self.rxfc_bs = rx_block_size - self.rxfc_stmin = rx_separation_time_min - - self.rx_queue = queue.Queue() - self.rx_len = -1 - self.rx_buf = None - self.rx_sn = 0 - self.rx_bs = 0 - self.rx_idx = 0 - self.rx_state = ISOTP_IDLE - - self.txfc_bs = 0 - self.txfc_stmin = 0 - self.tx_gap = 0 - - self.tx_buf = None - self.tx_sn = 0 - self.tx_bs = 0 - self.tx_idx = 0 - self.rx_ll_dl = 0 - self.tx_state = ISOTP_IDLE - - self.tx_timer = TimeoutThread() - self.rx_timer = TimeoutThread() - self.rx_thread = CANReceiverThread(can_socket, self.on_can_recv) - - self.tx_mutex = Lock() - self.rx_mutex = Lock() - self.send_mutex = Lock() - - self.tx_done = Event() - self.tx_exception = None - - self.tx_callbacks = [] - self.rx_callbacks = [] - - self.tx_timer.start() - self.rx_timer.start() - self.rx_thread.start() - - def __del__(self): - self.close() - - def can_send(self, load): - if self.padding: - load += bytearray(CAN_MAX_DLEN - len(load)) - self.can_socket.send(CAN(identifier=self.src_id, data=load)) - - def on_can_recv(self, p): - if not isinstance(p, CAN): - raise Scapy_Exception("argument is not a CAN frame") - if p.identifier != self.dst_id: - if not self.filter_warning_emitted: - warning("You should put a filter for identifier=%x on your" - "CAN socket" % self.dst_id) - self.filter_warning_emitted = True - else: - self.on_recv(p) - - def close(self): - self.rx_timer.stop() - self.tx_timer.stop() - self.rx_thread.stop() - - def _rx_timer_handler(self): - """Method called every time the rx_timer times out, due to the peer not - sending a consecutive frame within the expected time window""" - - with self.rx_mutex: - if self.rx_state == ISOTP_WAIT_DATA: - # we did not get new data frames in time. - # reset rx state - self.rx_state = ISOTP_IDLE - warning("RX state was reset due to timeout") - - def _tx_timer_handler(self): - """Method called every time the tx_timer times out, which can happen in - two situations: either a Flow Control frame was not received in time, - or the Separation Time Min is expired and a new frame must be sent.""" - - with self.tx_mutex: - if (self.tx_state == ISOTP_WAIT_FC or - self.tx_state == ISOTP_WAIT_FIRST_FC): - # we did not get any flow control frame in time - # reset tx state - self.tx_state = ISOTP_IDLE - self.tx_exception = "TX state was reset due to timeout" - self.tx_done.set() - raise Scapy_Exception(self.tx_exception) - elif self.tx_state == ISOTP_SENDING: - # push out the next segmented pdu - src_off = len(self.ea_hdr) - max_bytes = 7 - src_off - - while 1: - load = self.ea_hdr - load += struct.pack("B", N_PCI_CF + self.tx_sn) - load += self.tx_buf[self.tx_idx:self.tx_idx + max_bytes] - self.can_send(load) - - self.tx_sn = (self.tx_sn + 1) % 16 - self.tx_bs += 1 - self.tx_idx += max_bytes - - if len(self.tx_buf) <= self.tx_idx: - # we are done - self.tx_state = ISOTP_IDLE - self.tx_done.set() - for cb in self.tx_callbacks: - cb() - return - - if self.txfc_bs != 0 and self.tx_bs >= self.txfc_bs: - # stop and wait for FC - self.tx_state = ISOTP_WAIT_FC - self.tx_timer.set_timeout(self.fc_timeout, - self._tx_timer_handler) - return - - if self.tx_gap == 0: - continue - else: - self.tx_timer.set_timeout(self.tx_gap, - self._tx_timer_handler) - - def on_recv(self, cf): - """Function that must be called every time a CAN frame is received, to - advance the state machine.""" - - data = bytes(cf.data) - - if len(data) < 2: - return - - ae = 0 - if self.extended_rx_addr is not None: - ae = 1 - if len(data) < 3: - return - if six.indexbytes(data, 0) != self.extended_rx_addr: - return - - n_pci = six.indexbytes(data, ae) & 0xf0 - - if n_pci == N_PCI_FC: - with self.tx_mutex: - self._recv_fc(data[ae:]) - elif n_pci == N_PCI_SF: - with self.rx_mutex: - self._recv_sf(data[ae:]) - elif n_pci == N_PCI_FF: - with self.rx_mutex: - self._recv_ff(data[ae:]) - elif n_pci == N_PCI_CF: - with self.rx_mutex: - self._recv_cf(data[ae:]) - - def _recv_fc(self, data): - """Process a received 'Flow Control' frame""" - if (self.tx_state != ISOTP_WAIT_FC and - self.tx_state != ISOTP_WAIT_FIRST_FC): - return 0 - - self.tx_timer.cancel() - - if len(data) < 3: - self.tx_state = ISOTP_IDLE - self.tx_exception = "CF frame discarded because it was too short" - self.tx_done.set() - raise Scapy_Exception(self.tx_exception) - - # get communication parameters only from the first FC frame - if self.tx_state == ISOTP_WAIT_FIRST_FC: - self.txfc_bs = six.indexbytes(data, 1) - self.txfc_stmin = six.indexbytes(data, 2) - - if ((self.txfc_stmin > 0x7F) and - ((self.txfc_stmin < 0xF1) or (self.txfc_stmin > 0xF9))): - self.txfc_stmin = 0x7F - - if six.indexbytes(data, 2) <= 127: - tx_gap = six.indexbytes(data, 2) / 1000.0 - elif 0xf1 <= six.indexbytes(data, 2) <= 0xf9: - tx_gap = (six.indexbytes(data, 2) & 0x0f) / 10000.0 - else: - tx_gap = 0 - self.tx_gap = tx_gap - - self.tx_state = ISOTP_WAIT_FC - - isotp_fc = six.indexbytes(data, 0) & 0x0f - - if isotp_fc == ISOTP_FC_CTS: - self.tx_bs = 0 - self.tx_state = ISOTP_SENDING - # start cyclic timer for sending CF frame - self.tx_timer.set_timeout(self.tx_gap, self._tx_timer_handler) - elif isotp_fc == ISOTP_FC_WT: - # start timer to wait for next FC frame - self.tx_state = ISOTP_WAIT_FC - self.tx_timer.set_timeout(self.fc_timeout, self._tx_timer_handler) - elif isotp_fc == ISOTP_FC_OVFLW: - # overflow in receiver side - self.tx_state = ISOTP_IDLE - self.tx_exception = "Overflow happened at the receiver side" - self.tx_done.set() - raise Scapy_Exception(self.tx_exception) - else: - self.tx_state = ISOTP_IDLE - self.tx_exception = "Unknown FC frame type" - self.tx_done.set() - raise Scapy_Exception(self.tx_exception) - - return 0 - - def _recv_sf(self, data): - """Process a received 'Single Frame' frame""" - self.rx_timer.cancel() - if self.rx_state != ISOTP_IDLE: - warning("RX state was reset because single frame was received") - self.rx_state = ISOTP_IDLE - - length = six.indexbytes(data, 0) & 0xf - if len(data) - 1 < length: - return 1 - - msg = data[1:1 + length] - self.rx_queue.put(msg) - for cb in self.rx_callbacks: - cb(msg) - self.call_release() - return 0 - - def _recv_ff(self, data): - """Process a received 'First Frame' frame""" - self.rx_timer.cancel() - if self.rx_state != ISOTP_IDLE: - warning("RX state was reset because first frame was received") - self.rx_state = ISOTP_IDLE - - if len(data) < 7: - return 1 - self.rx_ll_dl = len(data) - - # get the FF_DL - self.rx_len = (six.indexbytes(data, 0) & 0x0f) * 256 + six.indexbytes( - data, 1) - ff_pci_sz = 2 - - # Check for FF_DL escape sequence supporting 32 bit PDU length - if self.rx_len == 0: - # FF_DL = 0 => get real length from next 4 bytes - self.rx_len = six.indexbytes(data, 2) << 24 - self.rx_len += six.indexbytes(data, 3) << 16 - self.rx_len += six.indexbytes(data, 4) << 8 - self.rx_len += six.indexbytes(data, 5) - ff_pci_sz = 6 - - # copy the first received data bytes - data_bytes = data[ff_pci_sz:] - self.rx_idx = len(data_bytes) - self.rx_buf = data_bytes - - # initial setup for this pdu reception - self.rx_sn = 1 - self.rx_state = ISOTP_WAIT_DATA - - # no creation of flow control frames - if not self.listen_only: - # send our first FC frame - load = self.ea_hdr - load += struct.pack("BBB", N_PCI_FC, self.rxfc_bs, self.rxfc_stmin) - self.can_send(load) - - # wait for a CF - self.rx_bs = 0 - self.rx_timer.set_timeout(self.cf_timeout, self._rx_timer_handler) - - return 0 - - def _recv_cf(self, data): - """Process a received 'Consecutive Frame' frame""" - if self.rx_state != ISOTP_WAIT_DATA: - return 0 - - self.rx_timer.cancel() - - # CFs are never longer than the FF - if len(data) > self.rx_ll_dl: - return 1 - - # CFs have usually the LL_DL length - if len(data) < self.rx_ll_dl: - # this is only allowed for the last CF - if self.rx_len - self.rx_idx > self.rx_ll_dl: - warning("Received a CF with insuffifient length") - return 1 - - if six.indexbytes(data, 0) & 0x0f != self.rx_sn: - # Wrong sequence number - warning("RX state was reset because wrong sequence number was " - "received") - self.rx_state = ISOTP_IDLE - return 1 - - self.rx_sn = (self.rx_sn + 1) % 16 - self.rx_buf += data[1:] - self.rx_idx = len(self.rx_buf) - - if self.rx_idx >= self.rx_len: - # we are done - self.rx_buf = self.rx_buf[0:self.rx_len] - self.rx_state = ISOTP_IDLE - self.rx_queue.put(self.rx_buf) - for cb in self.rx_callbacks: - cb(self.rx_buf) - self.call_release() - self.rx_buf = None - return 0 - - # perform blocksize handling, if enabled - if self.rxfc_bs != 0: - self.rx_bs += 1 - - # check if we reached the end of the block - if self.rx_bs >= self.rxfc_bs and not self.listen_only: - # send our FC frame - load = self.ea_hdr - load += struct.pack("BBB", N_PCI_FC, self.rxfc_bs, - self.rxfc_stmin) - self.can_send(load) - - # wait for another CF - self.rx_timer.set_timeout(self.cf_timeout, self._rx_timer_handler) - return 0 - - def begin_send(self, x): - """Begins sending an ISOTP message. This method does not block.""" - with self.tx_mutex: - if self.tx_state != ISOTP_IDLE: - raise Scapy_Exception("Socket is already sending, retry later") - - self.tx_done.clear() - self.tx_exception = None - self.tx_state = ISOTP_SENDING - - length = len(x) - if length > ISOTP_MAX_DLEN_2015: - raise Scapy_Exception("Too much data for ISOTP message") - - if len(self.ea_hdr) + length <= 7: - # send a single frame - data = self.ea_hdr - data += struct.pack("B", length) - data += x - self.tx_state = ISOTP_IDLE - self.can_send(data) - self.tx_done.set() - for cb in self.tx_callbacks: - cb() - return - - # send the first frame - data = self.ea_hdr - if length > ISOTP_MAX_DLEN: - data += struct.pack(">HI", 0x1000, length) - else: - data += struct.pack(">H", 0x1000 | length) - load = x[0:8 - len(data)] - data += load - self.can_send(data) - - self.tx_buf = x - self.tx_sn = 1 - self.tx_bs = 0 - self.tx_idx = len(load) - - self.tx_state = ISOTP_WAIT_FIRST_FC - self.tx_timer.set_timeout(self.fc_timeout, self._tx_timer_handler) - - def send(self, p): - """Send an ISOTP frame and block until the message is sent or an error - happens.""" - with self.send_mutex: - self.begin_send(p) - - # Wait until the tx callback is called - self.tx_done.wait() - if self.tx_exception is not None: - raise Scapy_Exception(self.tx_exception) - return - - def recv(self, timeout=None): - """Receive an ISOTP frame, blocking if none is available in the buffer - for at most 'timeout' seconds.""" - - try: - return self.rx_queue.get(timeout is None or timeout > 0, timeout) - except queue.Empty: - return None - - def check_recv(self): - """Implementation for SelectableObject""" - return not self.rx_queue.empty() - - -if six.PY3 and LINUX: - - from scapy.arch.linux import get_last_packet_timestamp, SIOCGIFINDEX - - """ISOTPNativeSocket definitions:""" - - CAN_ISOTP = 6 # ISO 15765-2 Transport Protocol - - SOL_CAN_BASE = 100 # from can.h - SOL_CAN_ISOTP = SOL_CAN_BASE + CAN_ISOTP - # /* for socket options affecting the socket (not the global system) */ - CAN_ISOTP_OPTS = 1 # /* pass struct can_isotp_options */ - CAN_ISOTP_RECV_FC = 2 # /* pass struct can_isotp_fc_options */ - - # /* sockopts to force stmin timer values for protocol regression tests */ - CAN_ISOTP_TX_STMIN = 3 # /* pass __u32 value in nano secs */ - CAN_ISOTP_RX_STMIN = 4 # /* pass __u32 value in nano secs */ - CAN_ISOTP_LL_OPTS = 5 # /* pass struct can_isotp_ll_options */ - - CAN_ISOTP_LISTEN_MODE = 0x001 # /* listen only (do not send FC) */ - CAN_ISOTP_EXTEND_ADDR = 0x002 # /* enable extended addressing */ - CAN_ISOTP_TX_PADDING = 0x004 # /* enable CAN frame padding tx path */ - CAN_ISOTP_RX_PADDING = 0x008 # /* enable CAN frame padding rx path */ - CAN_ISOTP_CHK_PAD_LEN = 0x010 # /* check received CAN frame padding */ - CAN_ISOTP_CHK_PAD_DATA = 0x020 # /* check received CAN frame padding */ - CAN_ISOTP_HALF_DUPLEX = 0x040 # /* half duplex error state handling */ - CAN_ISOTP_FORCE_TXSTMIN = 0x080 # /* ignore stmin from received FC */ - CAN_ISOTP_FORCE_RXSTMIN = 0x100 # /* ignore CFs depending on rx stmin */ - CAN_ISOTP_RX_EXT_ADDR = 0x200 # /* different rx extended addressing */ - - # /* default values */ - CAN_ISOTP_DEFAULT_FLAGS = 0 - CAN_ISOTP_DEFAULT_EXT_ADDRESS = 0x00 - CAN_ISOTP_DEFAULT_PAD_CONTENT = 0xCC # /* prevent bit-stuffing */ - CAN_ISOTP_DEFAULT_FRAME_TXTIME = 0 - CAN_ISOTP_DEFAULT_RECV_BS = 0 - CAN_ISOTP_DEFAULT_RECV_STMIN = 0x00 - CAN_ISOTP_DEFAULT_RECV_WFTMAX = 0 - CAN_ISOTP_DEFAULT_LL_MTU = CAN_MTU - CAN_ISOTP_DEFAULT_LL_TX_DL = CAN_MAX_DLEN - CAN_ISOTP_DEFAULT_LL_TX_FLAGS = 0 - - class SOCKADDR(ctypes.Structure): - # See /usr/include/i386-linux-gnu/bits/socket.h for original struct - _fields_ = [("sa_family", ctypes.c_uint16), - ("sa_data", ctypes.c_char * 14)] - - class TP(ctypes.Structure): - # This struct is only used within the SOCKADDR_CAN struct - _fields_ = [("rx_id", ctypes.c_uint32), - ("tx_id", ctypes.c_uint32)] - - class ADDR_INFO(ctypes.Union): - # This struct is only used within the SOCKADDR_CAN struct - # This union is to future proof for future can address information - _fields_ = [("tp", TP)] - - class SOCKADDR_CAN(ctypes.Structure): - # See /usr/include/linux/can.h for original struct - _fields_ = [("can_family", ctypes.c_uint16), - ("can_ifindex", ctypes.c_int), - ("can_addr", ADDR_INFO)] - - class IFREQ(ctypes.Structure): - # The two fields in this struct were originally unions. - # See /usr/include/net/if.h for original struct - _fields_ = [("ifr_name", ctypes.c_char * 16), - ("ifr_ifindex", ctypes.c_int)] - - class ISOTPNativeSocket(SuperSocket): - desc = "read/write packets at a given CAN interface using CAN_ISOTP " \ - "socket " - can_isotp_options_fmt = "@2I4B" - can_isotp_fc_options_fmt = "@3B" - can_isotp_ll_options_fmt = "@3B" - sockaddr_can_fmt = "@H3I" - - def __build_can_isotp_options( - self, - flags=CAN_ISOTP_DEFAULT_FLAGS, - frame_txtime=0, - ext_address=CAN_ISOTP_DEFAULT_EXT_ADDRESS, - txpad_content=0, - rxpad_content=0, - rx_ext_address=CAN_ISOTP_DEFAULT_EXT_ADDRESS): - return struct.pack(self.can_isotp_options_fmt, - flags, - frame_txtime, - ext_address, - txpad_content, - rxpad_content, - rx_ext_address) - - # == Must use native not standard types for packing == - # struct can_isotp_options { - # __u32 flags; /* set flags for isotp behaviour. */ - # /* __u32 value : flags see below */ - # - # __u32 frame_txtime; /* frame transmission time (N_As/N_Ar) */ - # /* __u32 value : time in nano secs */ - # - # __u8 ext_address; /* set address for extended addressing */ - # /* __u8 value : extended address */ - # - # __u8 txpad_content; /* set content of padding byte (tx) */ - # /* __u8 value : content on tx path */ - # - # __u8 rxpad_content; /* set content of padding byte (rx) */ - # /* __u8 value : content on rx path */ - # - # __u8 rx_ext_address; /* set address for extended addressing */ - # /* __u8 value : extended address (rx) */ - # }; - - def __build_can_isotp_fc_options(self, - bs=CAN_ISOTP_DEFAULT_RECV_BS, - stmin=CAN_ISOTP_DEFAULT_RECV_STMIN, - wftmax=CAN_ISOTP_DEFAULT_RECV_WFTMAX): - return struct.pack(self.can_isotp_fc_options_fmt, - bs, - stmin, - wftmax) - - # == Must use native not standard types for packing == - # struct can_isotp_fc_options { - # - # __u8 bs; /* blocksize provided in FC frame */ - # /* __u8 value : blocksize. 0 = off */ - # - # __u8 stmin; /* separation time provided in FC frame */ - # /* __u8 value : */ - # /* 0x00 - 0x7F : 0 - 127 ms */ - # /* 0x80 - 0xF0 : reserved */ - # /* 0xF1 - 0xF9 : 100 us - 900 us */ - # /* 0xFA - 0xFF : reserved */ - # - # __u8 wftmax; /* max. number of wait frame transmiss. */ - # /* __u8 value : 0 = omit FC N_PDU WT */ - # }; - - def __build_can_isotp_ll_options(self, - mtu=CAN_ISOTP_DEFAULT_LL_MTU, - tx_dl=CAN_ISOTP_DEFAULT_LL_TX_DL, - tx_flags=CAN_ISOTP_DEFAULT_LL_TX_FLAGS - ): - return struct.pack(self.can_isotp_ll_options_fmt, - mtu, - tx_dl, - tx_flags) - - # == Must use native not standard types for packing == - # struct can_isotp_ll_options { - # - # __u8 mtu; /* generated & accepted CAN frame type */ - # /* __u8 value : */ - # /* CAN_MTU (16) -> standard CAN 2.0 */ - # /* CANFD_MTU (72) -> CAN FD frame */ - # - # __u8 tx_dl; /* tx link layer data length in bytes */ - # /* (configured maximum payload length) */ - # /* __u8 value : 8,12,16,20,24,32,48,64 */ - # /* => rx path supports all LL_DL values */ - # - # __u8 tx_flags; /* set into struct canfd_frame.flags */ - # /* at frame creation: e.g. CANFD_BRS */ - # /* Obsolete when the BRS flag is fixed */ - # /* by the CAN netdriver configuration */ - # }; - - def __get_sock_ifreq(self, sock, iface): - socket_id = ctypes.c_int(sock.fileno()) - ifr = IFREQ() - ifr.ifr_name = iface.encode('ascii') - ret = LIBC.ioctl(socket_id, SIOCGIFINDEX, ctypes.byref(ifr)) - - if ret < 0: - m = u'Failure while getting "{}" interface index.'.format( - iface) - raise Scapy_Exception(m) - return ifr - - def __bind_socket(self, sock, iface, sid, did): - socket_id = ctypes.c_int(sock.fileno()) - ifr = self.__get_sock_ifreq(sock, iface) - - if sid > 0x7ff: - sid = sid | socket.CAN_EFF_FLAG - if did > 0x7ff: - did = did | socket.CAN_EFF_FLAG - - # select the CAN interface and bind the socket to it - addr = SOCKADDR_CAN(ctypes.c_uint16(socket.PF_CAN), - ifr.ifr_ifindex, - ADDR_INFO(TP(ctypes.c_uint32(did), - ctypes.c_uint32(sid)))) - - error = LIBC.bind(socket_id, ctypes.byref(addr), - ctypes.sizeof(addr)) - - if error < 0: - warning("Couldn't bind socket") - - def __set_option_flags(self, sock, extended_addr=None, - extended_rx_addr=None, - listen_only=False, - padding=False, - transmit_time=100): - option_flags = CAN_ISOTP_DEFAULT_FLAGS - if extended_addr is not None: - option_flags = option_flags | CAN_ISOTP_EXTEND_ADDR - else: - extended_addr = CAN_ISOTP_DEFAULT_EXT_ADDRESS - - if extended_rx_addr is not None: - option_flags = option_flags | CAN_ISOTP_RX_EXT_ADDR - else: - extended_rx_addr = CAN_ISOTP_DEFAULT_EXT_ADDRESS - - if listen_only: - option_flags = option_flags | CAN_ISOTP_LISTEN_MODE - - if padding: - option_flags = option_flags | CAN_ISOTP_TX_PADDING \ - | CAN_ISOTP_RX_PADDING - - sock.setsockopt(SOL_CAN_ISOTP, - CAN_ISOTP_OPTS, - self.__build_can_isotp_options( - frame_txtime=transmit_time, - flags=option_flags, - ext_address=extended_addr, - rx_ext_address=extended_rx_addr)) - - def __init__(self, - iface=None, - sid=0, - did=0, - extended_addr=None, - extended_rx_addr=None, - listen_only=False, - padding=False, - transmit_time=100, - basecls=ISOTP): - self.iface = conf.contribs['NativeCANSocket']['iface'] \ - if iface is None else iface - self.can_socket = socket.socket(socket.PF_CAN, socket.SOCK_DGRAM, - CAN_ISOTP) - self.__set_option_flags(self.can_socket, - extended_addr, - extended_rx_addr, - listen_only, - padding, - transmit_time) - - self.src = sid - self.dst = did - self.exsrc = extended_addr - self.exdst = extended_rx_addr - - self.can_socket.setsockopt(SOL_CAN_ISOTP, - CAN_ISOTP_RECV_FC, - self.__build_can_isotp_fc_options()) - self.can_socket.setsockopt(SOL_CAN_ISOTP, - CAN_ISOTP_LL_OPTS, - self.__build_can_isotp_ll_options()) - - self.__bind_socket(self.can_socket, iface, sid, did) - self.ins = self.can_socket - self.outs = self.can_socket - if basecls is None: - warning('Provide a basecls ') - self.basecls = basecls - - def recv_raw(self, x=0xffff): - """ - Receives a packet, then returns a tuple containing - (cls, pkt_data, time) - """ # noqa: E501 - try: - pkt = self.can_socket.recvfrom(x)[0] - except BlockingIOError: # noqa: F821 - warning('Captured no data, socket in non-blocking mode.') - return None - except socket.timeout: - warning('Captured no data, socket read timed out.') - return None - except OSError: - # something bad happened (e.g. the interface went down) - warning("Captured no data.") - return None - - ts = get_last_packet_timestamp(self.can_socket) - return self.basecls, pkt, ts - - def recv(self, x=0xffff): - msg = SuperSocket.recv(self, x) - - if hasattr(msg, "src"): - msg.src = self.src - if hasattr(msg, "dst"): - msg.dst = self.dst - if hasattr(msg, "exsrc"): - msg.exsrc = self.exsrc - if hasattr(msg, "exdst"): - msg.exdst = self.exdst - return msg - - __all__.append("ISOTPNativeSocket") - -if USE_CAN_ISOTP_KERNEL_MODULE: - ISOTPSocket = ISOTPNativeSocket - - -# ################################################################### -# #################### ISOTPSCAN #################################### -# ################################################################### -def send_multiple_ext(sock, ext_id, packet, number_of_packets): - """ Send multiple packets with extended addresses at once - - Args: - sock: socket for can interface - ext_id: extended id. First id to send. - packet: packet to send - number_of_packets: number of packets send - - This function is used for scanning with extended addresses. - It sends multiple packets at once. The number of packets - is defined in the number_of_packets variable. - It only iterates the extended ID, NOT the actual ID of the packet. - This method is used in extended scan function. - """ - end_id = min(ext_id + number_of_packets, 255) - for i in range(ext_id, end_id + 1): - packet.extended_address = i - sock.send(packet) - - -def get_isotp_packet(identifier=0x0, extended=False): - """ Craft ISO TP packet - Args: - identifier: identifier of crafted packet - extended: boolean if packet uses extended address - """ - - if extended: - pkt = ISOTPHeaderEA() / ISOTP_FF() - pkt.extended_address = 0 - pkt.data = b'\x00\x00\x00\x00\x00' - else: - pkt = ISOTPHeader() / ISOTP_FF() - pkt.data = b'\x00\x00\x00\x00\x00\x00' - - pkt.identifier = identifier - pkt.message_size = 100 - return pkt - - -def filter_periodic_packets(packet_dict, verbose=False): - """ Filter for periodic packets - - Args: - packet_dict: Dictionary with Send-to-ID as key and a tuple - (received packet, Recv_ID) - verbose: Displays further information - - ISOTP-Filter for periodic packets (same ID, always same timegap) - Deletes periodic packets in packet_dict - """ - filter_dict = {} - - for key, value in packet_dict.items(): - pkt = value[0] - idn = value[1] - if idn not in filter_dict: - filter_dict[idn] = ([key], [pkt]) - else: - key_lst, pkt_lst = filter_dict[idn] - filter_dict[idn] = (key_lst + [key], pkt_lst + [pkt]) - - for idn in filter_dict: - key_lst = filter_dict[idn][0] - pkt_lst = filter_dict[idn][1] - if len(pkt_lst) < 3: - continue - - tg = [p1.time - p2.time for p1, p2 in zip(pkt_lst[1:], pkt_lst[:-1])] - if all(abs(t1 - t2) < 0.001 for t1, t2 in zip(tg[1:], tg[:-1])): - if verbose: - print("[i] Identifier 0x%03x seems to be periodic. " - "Filtered.") - for k in key_lst: - del packet_dict[k] - - -def get_isotp_fc(id_value, id_list, noise_ids, extended, packet, - verbose=False): - """Callback for sniff function when packet received - - Args: - id_value: packet id of send packet - id_list: list of received IDs - noise_ids: list of packet IDs which will not be considered when - received during scan - extended: boolean if extended scan - packet: received packet - verbose: displays information during scan - - If received packet is a FlowControl - and not in noise_ids - append it to id_list - """ - if packet.flags: - return - - if noise_ids is not None and packet.identifier in noise_ids: - return - - try: - index = 1 if extended else 0 - isotp_pci = orb(packet.data[index]) >> 4 - isotp_fc = orb(packet.data[index]) & 0x0f - if isotp_pci == 3 and 0 <= isotp_fc <= 2: - if verbose: - print("[+] Found flow-control frame from identifier 0x%03x" - " when testing identifier 0x%03x" % - (packet.identifier, id_value)) - if isinstance(id_list, dict): - id_list[id_value] = (packet, packet.identifier) - elif isinstance(id_list, list): - id_list.append(id_value) - else: - raise TypeError("Unknown type of id_list") - else: - noise_ids.append(packet.identifier) - except Exception as e: - print("[!] Unknown message Exception: %s on packet: %s" % - (e, repr(packet))) - - -def scan(sock, scan_range=range(0x800), noise_ids=None, sniff_time=0.1, - verbose=False): - """Scan and return dictionary of detections - - Args: - sock: socket for can interface - scan_range: hexadecimal range of IDs to scan. - Default is 0x0 - 0x7ff - noise_ids: list of packet IDs which will not be considered when - received during scan - sniff_time: time the scan waits for isotp flow control responses - after sending a first frame - verbose: displays information during scan - - ISOTP-Scan - NO extended IDs - found_packets = Dictionary with Send-to-ID as - key and a tuple (received packet, Recv_ID) - """ - return_values = dict() - for value in scan_range: - sock.sniff(prn=lambda pkt: get_isotp_fc(value, return_values, - noise_ids, False, pkt, - verbose), - timeout=sniff_time, - started_callback=lambda: sock.send( - get_isotp_packet(value))) - return return_values - - -def scan_extended(sock, scan_range=range(0x800), scan_block_size=100, - noise_ids=None, sniff_time=0.1, verbose=False): - """Scan with extended addresses and return dictionary of detections - - Args: - sock: socket for can interface - scan_range: hexadecimal range of IDs to scan. - Default is 0x0 - 0x7ff - scan_block_size: count of packets send at once - noise_ids: list of packet IDs which will not be considered when - received during scan - sniff_time: time the scan waits for isotp flow control responses - after sending a first frame - verbose: displays information during scan - - If an answer-packet found -> slow scan with - single packages with extended ID 0 - 255 - found_packets = Dictionary with Send-to-ID - as key and a tuple (received packet, Recv_ID) - """ - - return_values = dict() - scan_block_size = scan_block_size or 1 - - for value in scan_range: - pkt = get_isotp_packet(value, extended=True) - id_list = [] - - for extended_id in range(0, 256, scan_block_size): - sock.sniff(prn=lambda p: get_isotp_fc(extended_id, id_list, - noise_ids, True, p, - verbose), - timeout=sniff_time * 3, - started_callback=send_multiple_ext(sock, extended_id, - pkt, - scan_block_size)) - # sleep to prevent flooding - time.sleep(1) - - # remove duplicate IDs - id_list = list(set(id_list)) - for extended_id in id_list: - for ext_id in range(extended_id, min(extended_id + - scan_block_size, 256)): - pkt.extended_address = ext_id - full_id = (value << 8) + ext_id - sock.sniff(prn=lambda pkt: get_isotp_fc(full_id, - return_values, - noise_ids, True, - pkt, verbose), - timeout=sniff_time, - started_callback=lambda: sock.send(pkt)) - return return_values - - -def ISOTPScan(sock, scan_range=range(0x7ff + 1), extended_addressing=False, - noise_listen_time=2, - sniff_time=0.1, - output_format=None, - can_interface="can0", - verbose=False): - - """Scan for ISOTP Sockets on a bus and return findings - - Args: - sock: CANSocket object to communicate with the bus under scan - scan_range: hexadecimal range of CAN-Identifiers to scan. - Default is 0x0 - 0x7ff - extended_addressing: scan with ISOTP extended addressing - noise_listen_time: seconds to listen for default - communication on the bus - sniff_time: time the scan waits for isotp flow control responses - after sending a first frame - output_format: defines the format of the returned - results (text, code or sockets). Provide a string - e.g. "text". Default is "socket". - can_interface: interface used to create the returned code/sockets - verbose: displays information during scan - - Scan for ISOTP Sockets in the defined range and returns found sockets - in a specified format. The format can be: - text: human readable output - code: python code for copy&paste - sockets: if output format is not specified, ISOTPSockets will be - created and returned in a list - """ - - if verbose: - print("Filtering background noise...") - - # Send dummy packet. In most cases, this triggers activity on the bus. - dummy_pkt = CAN(identifier=0x123, - data=b'\xaa\xbb\xcc\xdd\xee\xff\xaa\xbb') - - background_pkts = sock.sniff(timeout=noise_listen_time, - started_callback=lambda: - sock.send(dummy_pkt)) - - noise_ids = list(set(pkt.identifier for pkt in background_pkts)) - - if extended_addressing: - found_packets = scan_extended(sock, scan_range, noise_ids=noise_ids, - sniff_time=sniff_time, verbose=verbose) - else: - found_packets = scan(sock, scan_range, noise_ids=noise_ids, - sniff_time=sniff_time, verbose=verbose) - - filter_periodic_packets(found_packets, verbose) - - if output_format == "text": - return generate_text_output(found_packets) - if output_format == "code": - return generate_code_output(found_packets, can_interface) - return generate_isotp_list(found_packets, can_interface) - - -def generate_text_output(found_packets): - """Generate a human readable output from the result of the `scan` or - the `scan_extended` function. - - Args: - found_packets: result of the `scan` or `scan_extended` function - """ - if not found_packets: - return "No packets found." - - text = "\nFound %s ISOTP-FlowControl Packet(s):" % len(found_packets) - for pack in found_packets: - extended_id = pack > 0x7ff - if extended_id: - send_id = pack // 256 - send_ext = pack - (send_id * 256) - ext_id = hex(orb(found_packets[pack][0].data[0])) - text += "\nSend to ID: %s" \ - "\nSend to extended ID: %s" \ - "\nReceived ID: %s" \ - "\nReceived extended ID: %s" \ - "\nMessage: %s" % \ - (hex(send_id), hex(send_ext), - hex(found_packets[pack][0].identifier), ext_id, - repr(found_packets[pack][0])) - else: - text += "\nSend to ID: %s" \ - "\nReceived ID: %s" \ - "\nMessage: %s" % \ - (hex(pack), - hex(found_packets[pack][0].identifier), - repr(found_packets[pack][0])) - - padding = found_packets[pack][0].length == 8 - if padding: - text += "\nPadding enabled" - else: - text += "\nNo Padding" - - text += "\n" - return text - - -def generate_code_output(found_packets, can_interface): - """Generate a copy&past-able output from the result of the `scan` or - the `scan_extended` function. - - Args: - found_packets: result of the `scan` or `scan_extended` function - can_interface: description string for a CAN interface to be - used for the creation of the output. - """ - result = "" - if not found_packets: - return result - - header = "\n\nimport can\n" \ - "conf.contribs['CANSocket'] = {'use-python-can': %s}\n" \ - "load_contrib('cansocket')\n" \ - "load_contrib('isotp')\n\n" % PYTHON_CAN - - for pack in found_packets: - extended_id = pack > 0x7ff - if extended_id: - send_id = pack // 256 - send_ext = pack - (send_id * 256) - ext_id = orb(found_packets[pack][0].data[0]) - result += "ISOTPSocket(%s, sid=%s, did=%s, padding=%s, " \ - "extended_addr=%s, extended_rx_addr=%s, " \ - "basecls=ISOTP)\n" % \ - (can_interface, hex(send_id), - hex(int(found_packets[pack][0].identifier)), - found_packets[pack][0].length == 8, - hex(send_ext), - hex(ext_id)) - - else: - result += "ISOTPSocket(%s, sid=%s, did=%s, padding=%s, " \ - "basecls=ISOTP)\n" % \ - (can_interface, hex(pack), - hex(int(found_packets[pack][0].identifier)), - found_packets[pack][0].length == 8) - return header + result - - -def generate_isotp_list(found_packets, can_interface): - """Generate a list of ISOTPSocket objects from the result of the `scan` or - the `scan_extended` function. - - Args: - found_packets: result of the `scan` or `scan_extended` function - can_interface: description string for a CAN interface to be - used for the creation of the output. - """ - socket_list = [] - for pack in found_packets: - extended_id = pack > 0x7ff - pkt = found_packets[pack][0] - - dest_id = pkt.identifier - pad = True if pkt.length == 8 else False - - if extended_id: - source_id = pack >> 8 - source_ext = int(pack - (source_id * 256)) - dest_ext = orb(pkt.data[0]) - socket_list.append(ISOTPSocket(can_interface, sid=source_id, - extended_addr=source_ext, - did=dest_id, - extended_rx_addr=dest_ext, - padding=pad, - basecls=ISOTP)) - else: - source_id = pack - socket_list.append(ISOTPSocket(can_interface, sid=source_id, - did=dest_id, padding=pad, - basecls=ISOTP)) - return socket_list diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/lacp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/lacp.py deleted file mode 100644 index 2a69d6a93e..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/lacp.py +++ /dev/null @@ -1,96 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = Link Aggregation Control Protocol (LACP) -# scapy.contrib.status = loads - -from scapy.packet import Packet, bind_layers -from scapy.fields import ByteField, MACField, ShortField, ByteEnumField, IntField, XStrFixedLenField # noqa: E501 -from scapy.layers.l2 import Ether -from scapy.data import ETHER_TYPES - - -ETHER_TYPES['SlowProtocol'] = 0x8809 -SLOW_SUB_TYPES = { - 'Unused': 0, - 'LACP': 1, - 'Marker Protocol': 2, -} - - -class SlowProtocol(Packet): - name = "SlowProtocol" - fields_desc = [ByteEnumField("subtype", 0, SLOW_SUB_TYPES)] - - -bind_layers(Ether, SlowProtocol, type=0x8809, dst='01:80:c2:00:00:02') - - -class LACP(Packet): - name = "LACP" - fields_desc = [ - ByteField("version", 1), - ByteField("actor_type", 1), - ByteField("actor_length", 20), - ShortField("actor_system_priority", 0), - MACField("actor_system", None), - ShortField("actor_key", 0), - ShortField("actor_port_priority", 0), - ShortField("actor_port_numer", 0), - ByteField("actor_state", 0), - XStrFixedLenField("actor_reserved", "", 3), - ByteField("partner_type", 2), - ByteField("partner_length", 20), - ShortField("partner_system_priority", 0), - MACField("partner_system", None), - ShortField("partner_key", 0), - ShortField("partner_port_priority", 0), - ShortField("partner_port_numer", 0), - ByteField("partner_state", 0), - XStrFixedLenField("partner_reserved", "", 3), - ByteField("collector_type", 3), - ByteField("collector_length", 16), - ShortField("collector_max_delay", 0), - XStrFixedLenField("colletctor_reserved", "", 12), - ByteField("terminator_type", 0), - ByteField("terminator_length", 0), - XStrFixedLenField("reserved", "", 50), - ] - - -bind_layers(SlowProtocol, LACP, subtype=1) - -MARKER_TYPES = { - 'Marker Request': 1, - 'Marker Response': 2, -} - - -class MarkerProtocol(Packet): - name = "MarkerProtocol" - fields_desc = [ - ByteField("version", 1), - ByteEnumField("marker_type", 1, MARKER_TYPES), - ByteField("marker_length", 16), - ShortField("requester_port", 0), - MACField("requester_system", None), - IntField("requester_transaction_id", 0), - XStrFixedLenField("marker_reserved", "", 2), - ByteField("terminator_type", 0), - ByteField("terminator_length", 0), - XStrFixedLenField("reserved", 0, 90), - ] - - -bind_layers(SlowProtocol, MarkerProtocol, subtype=2) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ldp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/ldp.py deleted file mode 100644 index 25152ab769..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ldp.py +++ /dev/null @@ -1,441 +0,0 @@ -# scapy.contrib.description = Label Distribution Protocol (LDP) -# scapy.contrib.status = loads - -# http://git.savannah.gnu.org/cgit/ldpscapy.git/snapshot/ldpscapy-5285b81d6e628043df2a83301b292f24a95f0ba1.tar.gz - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# 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. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Copyright (C) 2010 Florian Duraffourg - -from __future__ import absolute_import -import struct - -from scapy.compat import orb -from scapy.packet import Packet, bind_layers, bind_bottom_up -from scapy.fields import BitField, IPField, IntField, ShortField, StrField, \ - XBitField -from scapy.layers.inet import UDP -from scapy.layers.inet import TCP -from scapy.modules.six.moves import range -from scapy.config import conf -from scapy.utils import inet_aton, inet_ntoa - - -class _LDP_Packet(Packet): - # Guess payload - def guess_payload_class(self, p): - LDPTypes = { - 0x0001: LDPNotification, - 0x0100: LDPHello, - 0x0200: LDPInit, - 0x0201: LDPKeepAlive, - 0x0300: LDPAddress, - 0x0301: LDPAddressWM, - 0x0400: LDPLabelMM, - 0x0401: LDPLabelReqM, - 0x0404: LDPLabelARM, - 0x0402: LDPLabelWM, - 0x0403: LDPLabelRelM, - } - type = struct.unpack("!H", p[0:2])[0] - type = type & 0x7fff - if type == 0x0001 and struct.unpack("!H", p[2:4])[0] > 20: - return LDP - if type in LDPTypes: - return LDPTypes[type] - else: - return conf.raw_layer - - def post_build(self, p, pay): - if self.len is None: - tmp_len = len(p) - 4 - p = p[:2] + struct.pack("!H", tmp_len) + p[4:] - return p + pay - -# Fields # - -# 3.4.1. FEC TLV - - -class FecTLVField(StrField): - islist = 1 - - def m2i(self, pkt, x): - used = 0 - x = x[4:] - list = [] - while x: - # if x[0] == 1: - # list.append('Wildcard') - # else: - # mask=orb(x[8*i+3]) - # add=inet_ntoa(x[8*i+4:8*i+8]) - mask = orb(x[3]) - nbroctets = mask // 8 - if mask % 8: - nbroctets += 1 - add = inet_ntoa(x[4:4 + nbroctets] + b"\x00" * (4 - nbroctets)) - list.append((add, mask)) - used += 4 + nbroctets - x = x[4 + nbroctets:] - return list - - def i2m(self, pkt, x): - if not x: - return b"" - if isinstance(x, bytes): - return x - s = b"\x01\x00" - tmp_len = 0 - fec = b"" - for o in x: - fec += b"\x02\x00\x01" - # mask length - fec += struct.pack("!B", o[1]) - # Prefix - fec += inet_aton(o[0]) - tmp_len += 8 - s += struct.pack("!H", tmp_len) - s += fec - return s - - def size(self, s): - """Get the size of this field""" - tmp_len = 4 + struct.unpack("!H", s[2:4])[0] - return tmp_len - - def getfield(self, pkt, s): - tmp_len = self.size(s) - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - - -# 3.4.2.1. Generic Label TLV - -class LabelTLVField(StrField): - def m2i(self, pkt, x): - return struct.unpack("!I", x[4:8])[0] - - def i2m(self, pkt, x): - if isinstance(x, bytes): - return x - s = b"\x02\x00\x00\x04" - s += struct.pack("!I", x) - return s - - def size(self, s): - """Get the size of this field""" - tmp_len = 4 + struct.unpack("!H", s[2:4])[0] - return tmp_len - - def getfield(self, pkt, s): - tmp_len = self.size(s) - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - - -# 3.4.3. Address List TLV - -class AddressTLVField(StrField): - islist = 1 - - def m2i(self, pkt, x): - nbr = struct.unpack("!H", x[2:4])[0] - 2 - nbr //= 4 - x = x[6:] - list = [] - for i in range(0, nbr): - add = x[4 * i:4 * i + 4] - list.append(inet_ntoa(add)) - return list - - def i2m(self, pkt, x): - if not x: - return b"" - if isinstance(x, bytes): - return x - tmp_len = 2 + len(x) * 4 - s = b"\x01\x01" + struct.pack("!H", tmp_len) + b"\x00\x01" - for o in x: - s += inet_aton(o) - return s - - def size(self, s): - """Get the size of this field""" - tmp_len = 4 + struct.unpack("!H", s[2:4])[0] - return tmp_len - - def getfield(self, pkt, s): - tmp_len = self.size(s) - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - - -# 3.4.6. Status TLV - -class StatusTLVField(StrField): - islist = 1 - - def m2i(self, pkt, x): - lst = [] - statuscode = struct.unpack("!I", x[4:8])[0] - lst.append((statuscode & 2**31) >> 31) - lst.append((statuscode & 2**30) >> 30) - lst.append(statuscode & 0x3FFFFFFF) - lst.append(struct.unpack("!I", x[8:12])[0]) - lst.append(struct.unpack("!H", x[12:14])[0]) - return lst - - def i2m(self, pkt, x): - if isinstance(x, bytes): - return x - s = b"\x03\x00" + struct.pack("!H", 10) - statuscode = 0 - if x[0] != 0: - statuscode += 2**31 - if x[1] != 0: - statuscode += 2**30 - statuscode += x[2] - s += struct.pack("!I", statuscode) - if len(x) > 3: - s += struct.pack("!I", x[3]) - else: - s += b"\x00\x00\x00\x00" - if len(x) > 4: - s += struct.pack("!H", x[4]) - else: - s += b"\x00\x00" - return s - - def getfield(self, pkt, s): - tmp_len = 14 - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - - -# 3.5.2 Common Hello Parameters TLV -class CommonHelloTLVField(StrField): - islist = 1 - - def m2i(self, pkt, x): - list = [] - v = struct.unpack("!H", x[4:6])[0] - list.append(v) - flags = orb(x[6]) - v = (flags & 0x80) >> 7 - list.append(v) - v = (flags & 0x40) >> 6 - list.append(v) - return list - - def i2m(self, pkt, x): - if isinstance(x, bytes): - return x - s = b"\x04\x00\x00\x04" - s += struct.pack("!H", x[0]) - byte = 0 - if x[1] == 1: - byte += 0x80 - if x[2] == 1: - byte += 0x40 - s += struct.pack("!B", byte) - s += b"\x00" - return s - - def getfield(self, pkt, s): - tmp_len = 8 - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - - -# 3.5.3 Common Session Parameters TLV -class CommonSessionTLVField(StrField): - islist = 1 - - def m2i(self, pkt, x): - lst = [struct.unpack("!H", x[6:8])[0]] - octet = struct.unpack("B", x[8:9])[0] - lst.append((octet & 2**7) >> 7) - lst.append((octet & 2**6) >> 6) - lst.append(struct.unpack("B", x[9:10])[0]) - lst.append(struct.unpack("!H", x[10:12])[0]) - lst.append(inet_ntoa(x[12:16])) - lst.append(struct.unpack("!H", x[16:18])[0]) - return lst - - def i2m(self, pkt, x): - if isinstance(x, bytes): - return x - s = b"\x05\x00\x00\x0E\x00\x01" - s += struct.pack("!H", x[0]) - octet = 0 - if x[1] != 0: - octet += 2**7 - if x[2] != 0: - octet += 2**6 - s += struct.pack("!B", octet) - s += struct.pack("!B", x[3]) - s += struct.pack("!H", x[4]) - s += inet_aton(x[5]) - s += struct.pack("!H", x[6]) - return s - - def getfield(self, pkt, s): - tmp_len = 18 - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - - -# Messages # - -# 3.5.1. Notification Message -class LDPNotification(_LDP_Packet): - name = "LDPNotification" - fields_desc = [BitField("u", 0, 1), - BitField("type", 0x0001, 15), - ShortField("len", None), - IntField("id", 0), - StatusTLVField("status", (0, 0, 0, 0, 0))] - -# 3.5.2. Hello Message - - -class LDPHello(_LDP_Packet): - name = "LDPHello" - fields_desc = [BitField("u", 0, 1), - BitField("type", 0x0100, 15), - ShortField("len", None), - IntField("id", 0), - CommonHelloTLVField("params", [180, 0, 0])] - -# 3.5.3. Initialization Message - - -class LDPInit(_LDP_Packet): - name = "LDPInit" - fields_desc = [BitField("u", 0, 1), - XBitField("type", 0x0200, 15), - ShortField("len", None), - IntField("id", 0), - CommonSessionTLVField("params", None)] - -# 3.5.4. KeepAlive Message - - -class LDPKeepAlive(_LDP_Packet): - name = "LDPKeepAlive" - fields_desc = [BitField("u", 0, 1), - XBitField("type", 0x0201, 15), - ShortField("len", None), - IntField("id", 0)] - -# 3.5.5. Address Message - - -class LDPAddress(_LDP_Packet): - name = "LDPAddress" - fields_desc = [BitField("u", 0, 1), - XBitField("type", 0x0300, 15), - ShortField("len", None), - IntField("id", 0), - AddressTLVField("address", None)] - -# 3.5.6. Address Withdraw Message - - -class LDPAddressWM(_LDP_Packet): - name = "LDPAddressWM" - fields_desc = [BitField("u", 0, 1), - XBitField("type", 0x0301, 15), - ShortField("len", None), - IntField("id", 0), - AddressTLVField("address", None)] - -# 3.5.7. Label Mapping Message - - -class LDPLabelMM(_LDP_Packet): - name = "LDPLabelMM" - fields_desc = [BitField("u", 0, 1), - XBitField("type", 0x0400, 15), - ShortField("len", None), - IntField("id", 0), - FecTLVField("fec", None), - LabelTLVField("label", 0)] - -# 3.5.8. Label Request Message - - -class LDPLabelReqM(_LDP_Packet): - name = "LDPLabelReqM" - fields_desc = [BitField("u", 0, 1), - XBitField("type", 0x0401, 15), - ShortField("len", None), - IntField("id", 0), - FecTLVField("fec", None)] - -# 3.5.9. Label Abort Request Message - - -class LDPLabelARM(_LDP_Packet): - name = "LDPLabelARM" - fields_desc = [BitField("u", 0, 1), - XBitField("type", 0x0404, 15), - ShortField("len", None), - IntField("id", 0), - FecTLVField("fec", None), - IntField("labelRMid", 0)] - -# 3.5.10. Label Withdraw Message - - -class LDPLabelWM(_LDP_Packet): - name = "LDPLabelWM" - fields_desc = [BitField("u", 0, 1), - XBitField("type", 0x0402, 15), - ShortField("len", None), - IntField("id", 0), - FecTLVField("fec", None), - LabelTLVField("label", 0)] - -# 3.5.11. Label Release Message - - -class LDPLabelRelM(_LDP_Packet): - name = "LDPLabelRelM" - fields_desc = [BitField("u", 0, 1), - XBitField("type", 0x0403, 15), - ShortField("len", None), - IntField("id", 0), - FecTLVField("fec", None), - LabelTLVField("label", 0)] - -# 3.1. LDP PDUs - - -class LDP(_LDP_Packet): - name = "LDP" - fields_desc = [ShortField("version", 1), - ShortField("len", None), - IPField("id", "127.0.0.1"), - ShortField("space", 0)] - - def post_build(self, p, pay): - pay = pay or b"" - if self.len is None: - tmp_len = len(p) + len(pay) - 4 - p = p[:2] + struct.pack("!H", tmp_len) + p[4:] - return p + pay - - -bind_bottom_up(TCP, LDP, sport=646) -bind_bottom_up(TCP, LDP, dport=646) -bind_bottom_up(TCP, UDP, sport=646) -bind_bottom_up(TCP, UDP, dport=646) -bind_layers(TCP, LDP, sport=646, dport=646) -bind_layers(UDP, LDP, sport=646, dport=646) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/lldp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/lldp.py deleted file mode 100644 index 87868728e0..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/lldp.py +++ /dev/null @@ -1,754 +0,0 @@ -#! /usr/bin/env python -# -# scapy.contrib.description = Link Layer Discovery Protocol (LLDP) -# scapy.contrib.status = loads - -""" - LLDP - Link Layer Discovery Protocol - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - :author: Thomas Tannhaeuser, hecke@naberius.de - :license: GPLv2 - - This module is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This module 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. - - :description: - - This module provides Scapy layers for the LLDP protocol. - - normative references: - - IEEE 802.1AB 2016 - LLDP protocol, topology and MIB description - - :TODO: - - organization specific TLV e.g. ProfiNet (see LLDPDUGenericOrganisationSpecific for a starting point) # noqa: E501 - - :NOTES: - - you can find the layer configuration options at the end of this file - - default configuration enforces standard conform - - frame structure - (ChassisIDTLV/PortIDTLV/TimeToLiveTLV/.../EndofLLDPDUTLV) - - multiplicity of TLVs (if given by the standard) - - min sizes of strings used by the TLVs - - conf.contribs['LLDP'].strict_mode_disable() -> disable strict mode - -""" -from scapy.config import conf -from scapy.error import Scapy_Exception -from scapy.layers.l2 import Ether, Dot1Q -from scapy.fields import MACField, IPField, BitField, \ - StrLenField, ByteEnumField, BitEnumField, \ - EnumField, ThreeBytesField, BitFieldLenField, \ - ShortField, XStrLenField, ByteField, ConditionalField, \ - MultipleTypeField -from scapy.packet import Packet, bind_layers -from scapy.modules.six.moves import range -from scapy.data import ETHER_TYPES -from scapy.compat import orb - -LLDP_NEAREST_BRIDGE_MAC = '01:80:c2:00:00:0e' -LLDP_NEAREST_NON_TPMR_BRIDGE_MAC = '01:80:c2:00:00:03' -LLDP_NEAREST_CUSTOMER_BRIDGE_MAC = '01:80:c2:00:00:00' - -LLDP_ETHER_TYPE = 0x88cc -ETHER_TYPES['LLDP'] = LLDP_ETHER_TYPE - - -class LLDPInvalidFrameStructure(Scapy_Exception): - """ - basic frame structure not standard conform - (missing TLV, invalid order or multiplicity) - """ - pass - - -class LLDPInvalidLastLayerException(Scapy_Exception): - """ - in strict mode, last layer in frame must be of type LLDPDUEndOfLLDPDU - """ - pass - - -class LLDPMissingLowerLayer(Scapy_Exception): - """ - first layer below first LLDPDU must be Ethernet or Dot1q - """ - pass - - -class LLDPInvalidTLVCount(Scapy_Exception): - """ - invalid number of entries for a specific TLV type - """ - pass - - -class LLDPInvalidLengthField(Scapy_Exception): - """ - invalid value of length field - """ - pass - - -class LLDPDU(Packet): - """ - base class for all LLDP data units - """ - TYPES = { - 0x00: 'end of LLDPDU', - 0x01: 'chassis id', - 0x02: 'port id', - 0x03: 'time to live', - 0x04: 'port description', - 0x05: 'system name', - 0x06: 'system description', - 0x07: 'system capabilities', - 0x08: 'management address', - range(0x09, 0x7e): 'reserved - future standardization', - 127: 'organisation specific TLV' - } - - DOT1Q_HEADER_LEN = 4 - ETHER_HEADER_LEN = 14 - ETHER_FSC_LEN = 4 - ETHER_FRAME_MIN_LEN = 64 - - LAYER_STACK = [] - LAYER_MULTIPLICITIES = {} - - def guess_payload_class(self, payload): - # type is a 7-bit bitfield spanning bits 1..7 -> div 2 - try: - lldpdu_tlv_type = orb(payload[0]) // 2 - return LLDPDU_CLASS_TYPES.get(lldpdu_tlv_type, conf.raw_layer) - except IndexError: - return conf.raw_layer - - @staticmethod - def _dot1q_headers_size(layer): - """ - calculate size of lower dot1q layers (if present) - :param layer: the layer to start at - :return: size of vlan headers, layer below lowest vlan header - """ - - vlan_headers_size = 0 - under_layer = layer - - while under_layer and isinstance(under_layer, Dot1Q): - vlan_headers_size += LLDPDU.DOT1Q_HEADER_LEN - under_layer = under_layer.underlayer - - return vlan_headers_size, under_layer - - def post_build(self, pkt, pay): - - last_layer = not pay - if last_layer and conf.contribs['LLDP'].strict_mode() and \ - type(self).__name__ != LLDPDUEndOfLLDPDU.__name__: - raise LLDPInvalidLastLayerException('Last layer must be instance ' - 'of LLDPDUEndOfLLDPDU - ' - 'got {}'. - format(type(self).__name__)) - - under_layer = self.underlayer - - if under_layer is None: - if conf.contribs['LLDP'].strict_mode(): - raise LLDPMissingLowerLayer('No lower layer (Ethernet ' - 'or Dot1Q) provided.') - else: - return pkt + pay - - if isinstance(under_layer, LLDPDU): - return pkt + pay - - frame_size, under_layer = LLDPDU._dot1q_headers_size(under_layer) - - if not under_layer or not isinstance(under_layer, Ether): - if conf.contribs['LLDP'].strict_mode(): - raise LLDPMissingLowerLayer('No Ethernet layer provided.') - else: - return pkt + pay - - frame_size += LLDPDU.ETHER_HEADER_LEN - frame_size += len(pkt) + len(pay) + LLDPDU.ETHER_FSC_LEN - if frame_size < LLDPDU.ETHER_FRAME_MIN_LEN: - return pkt + pay + b'\x00' * (LLDPDU.ETHER_FRAME_MIN_LEN - frame_size) # noqa: E501 - return pkt + pay - - @staticmethod - def _frame_structure_check(structure_description): - """ - check if the structure of the frame is conform to the basic - frame structure defined by the standard - :param structure_description: string-list reflecting LLDP-msg structure - """ - - standard_frame_structure = [LLDPDUChassisID.__name__, - LLDPDUPortID.__name__, - LLDPDUTimeToLive.__name__, - '<...>', - LLDPDUEndOfLLDPDU.__name__] - - if len(structure_description) < 4: - raise LLDPInvalidFrameStructure( - 'Invalid frame structure.\ngot: {}\nexpected: ' - '{}'.format(' '.join(structure_description), - ' '.join(standard_frame_structure))) - - for idx, layer_name in enumerate(standard_frame_structure): - - if layer_name == '<...>': - break - if layer_name != structure_description[idx]: - raise LLDPInvalidFrameStructure( - 'Invalid frame structure.\ngot: {}\nexpected: ' - '{}'.format(' '.join(structure_description), - ' '.join(standard_frame_structure))) - - if structure_description[-1] != standard_frame_structure[-1]: - raise LLDPInvalidFrameStructure( - 'Invalid frame structure.\ngot: {}\nexpected: ' - '{}'.format(' '.join(structure_description), - ' '.join(standard_frame_structure))) - - @staticmethod - def _tlv_multiplicities_check(tlv_type_count): - """ - check if multiplicity of present TLVs conforms to the standard - :param tlv_type_count: dict containing counte-per-TLV - """ - - # * : 0..n, 1 : one and only one. - standard_multiplicities = { - LLDPDUEndOfLLDPDU.__name__: 1, - LLDPDUChassisID.__name__: 1, - LLDPDUPortID.__name__: 1, - LLDPDUTimeToLive.__name__: 1, - LLDPDUPortDescription: '*', - LLDPDUSystemName: '*', - LLDPDUSystemDescription: '*', - LLDPDUSystemCapabilities: '*', - LLDPDUManagementAddress: '*' - } - - for tlv_type_name in standard_multiplicities: - - standard_tlv_multiplicity = \ - standard_multiplicities[tlv_type_name] - if standard_tlv_multiplicity == '*': - continue - - try: - if tlv_type_count[tlv_type_name] != standard_tlv_multiplicity: - raise LLDPInvalidTLVCount( - 'Invalid number of entries for TLV type ' - '{} - expected {} entries, got ' - '{}'.format(tlv_type_name, - standard_tlv_multiplicity, - tlv_type_count[tlv_type_name])) - - except KeyError: - raise LLDPInvalidTLVCount('Missing TLV layer of type ' - '{}.'.format(tlv_type_name)) - - def pre_dissect(self, s): - - if conf.contribs['LLDP'].strict_mode(): - if self.__class__.__name__ == 'LLDPDU': - LLDPDU.LAYER_STACK = [] - LLDPDU.LAYER_MULTIPLICITIES = {} - else: - LLDPDU.LAYER_STACK.append(self.__class__.__name__) - try: - LLDPDU.LAYER_MULTIPLICITIES[self.__class__.__name__] += 1 - except KeyError: - LLDPDU.LAYER_MULTIPLICITIES[self.__class__.__name__] = 1 - - return s - - def dissection_done(self, pkt): - - if self.__class__.__name__ == 'LLDPDU' and \ - conf.contribs['LLDP'].strict_mode(): - LLDPDU._frame_structure_check(LLDPDU.LAYER_STACK) - LLDPDU._tlv_multiplicities_check(LLDPDU.LAYER_MULTIPLICITIES) - - super(LLDPDU, self).dissection_done(pkt) - - def _check(self): - """Overwrited by LLDPU objects""" - pass - - def post_dissect(self, s): - self._check() - return super(LLDPDU, self).post_dissect(s) - - def do_build(self): - self._check() - return super(LLDPDU, self).do_build() - - -def _ldp_id_adjustlen(pkt, x): - """Return the length of the `id` field, - according to its real encoded type""" - f, v = pkt.getfield_and_val('id') - length = f.i2len(pkt, v) + 1 - if (isinstance(pkt, LLDPDUPortID) and pkt.subtype == 0x4) or \ - (isinstance(pkt, LLDPDUChassisID) and pkt.subtype == 0x5): - # Take the ConditionalField into account - length += 1 - return length - - -class LLDPDUChassisID(LLDPDU): - """ - ieee 802.1ab-2016 - sec. 8.5.2 / p. 26 - """ - LLDP_CHASSIS_ID_TLV_SUBTYPES = { - 0x00: 'reserved', - 0x01: 'chassis component', - 0x02: 'interface alias', - 0x03: 'port component', - 0x04: 'MAC address', - 0x05: 'network address', - 0x06: 'interface name', - 0x07: 'locally assigned', - range(0x08, 0xff): 'reserved' - } - - SUBTYPE_RESERVED = 0x00 - SUBTYPE_CHASSIS_COMPONENT = 0x01 - SUBTYPE_INTERFACE_ALIAS = 0x02 - SUBTYPE_PORT_COMPONENT = 0x03 - SUBTYPE_MAC_ADDRESS = 0x04 - SUBTYPE_NETWORK_ADDRESS = 0x05 - SUBTYPE_INTERFACE_NAME = 0x06 - SUBTYPE_LOCALLY_ASSIGNED = 0x07 - - fields_desc = [ - BitEnumField('_type', 0x01, 7, LLDPDU.TYPES), - BitFieldLenField('_length', None, 9, length_of='id', - adjust=lambda pkt, x: _ldp_id_adjustlen(pkt, x)), - ByteEnumField('subtype', 0x00, LLDP_CHASSIS_ID_TLV_SUBTYPES), - ConditionalField( - ByteField('family', 0), - lambda pkt: pkt.subtype == 0x05 - ), - MultipleTypeField([ - ( - MACField('id', None), - lambda pkt: pkt.subtype == 0x04 - ), - ( - IPField('id', None), - lambda pkt: pkt.subtype == 0x05 - ), - ], StrLenField('id', '', length_from=lambda pkt: pkt._length - 1) - ) - ] - - def _check(self): - """ - run layer specific checks - """ - if conf.contribs['LLDP'].strict_mode() and not self.id: - raise LLDPInvalidLengthField('id must be >= 1 characters long') - - -class LLDPDUPortID(LLDPDU): - """ - ieee 802.1ab-2016 - sec. 8.5.3 / p. 26 - """ - LLDP_PORT_ID_TLV_SUBTYPES = { - 0x00: 'reserved', - 0x01: 'interface alias', - 0x02: 'port component', - 0x03: 'MAC address', - 0x04: 'network address', - 0x05: 'interface name', - 0x06: 'agent circuit ID', - 0x07: 'locally assigned', - range(0x08, 0xff): 'reserved' - } - - SUBTYPE_RESERVED = 0x00 - SUBTYPE_INTERFACE_ALIAS = 0x01 - SUBTYPE_PORT_COMPONENT = 0x02 - SUBTYPE_MAC_ADDRESS = 0x03 - SUBTYPE_NETWORK_ADDRESS = 0x04 - SUBTYPE_INTERFACE_NAME = 0x05 - SUBTYPE_AGENT_CIRCUIT_ID = 0x06 - SUBTYPE_LOCALLY_ASSIGNED = 0x07 - - fields_desc = [ - BitEnumField('_type', 0x02, 7, LLDPDU.TYPES), - BitFieldLenField('_length', None, 9, length_of='id', - adjust=lambda pkt, x: _ldp_id_adjustlen(pkt, x)), - ByteEnumField('subtype', 0x00, LLDP_PORT_ID_TLV_SUBTYPES), - ConditionalField( - ByteField('family', 0), - lambda pkt: pkt.subtype == 0x04 - ), - MultipleTypeField([ - ( - MACField('id', None), - lambda pkt: pkt.subtype == 0x03 - ), - ( - IPField('id', None), - lambda pkt: pkt.subtype == 0x04 - ), - ], StrLenField('id', '', length_from=lambda pkt: pkt._length - 1) - ) - ] - - def _check(self): - """ - run layer specific checks - """ - if conf.contribs['LLDP'].strict_mode() and not self.id: - raise LLDPInvalidLengthField('id must be >= 1 characters long') - - -class LLDPDUTimeToLive(LLDPDU): - """ - ieee 802.1ab-2016 - sec. 8.5.4 / p. 29 - """ - fields_desc = [ - BitEnumField('_type', 0x03, 7, LLDPDU.TYPES), - BitField('_length', 0x02, 9), - ShortField('ttl', 20) - ] - - def _check(self): - """ - run layer specific checks - """ - if conf.contribs['LLDP'].strict_mode() and self._length != 2: - raise LLDPInvalidLengthField('length must be 2 - got ' - '{}'.format(self._length)) - - -class LLDPDUEndOfLLDPDU(LLDPDU): - """ - ieee 802.1ab-2016 - sec. 8.5.1 / p. 26 - """ - fields_desc = [ - BitEnumField('_type', 0x00, 7, LLDPDU.TYPES), - BitField('_length', 0x00, 9), - ] - - def extract_padding(self, s): - return '', s - - def _check(self): - """ - run layer specific checks - """ - if conf.contribs['LLDP'].strict_mode() and self._length != 0: - raise LLDPInvalidLengthField('length must be 0 - got ' - '{}'.format(self._length)) - - -class LLDPDUPortDescription(LLDPDU): - """ - ieee 802.1ab-2016 - sec. 8.5.5 / p. 29 - """ - fields_desc = [ - BitEnumField('_type', 0x04, 7, LLDPDU.TYPES), - BitFieldLenField('_length', None, 9, length_of='description'), - StrLenField('description', '', length_from=lambda pkt: pkt._length) - ] - - -class LLDPDUSystemName(LLDPDU): - """ - ieee 802.1ab-2016 - sec. 8.5.6 / p. 30 - """ - fields_desc = [ - BitEnumField('_type', 0x05, 7, LLDPDU.TYPES), - BitFieldLenField('_length', None, 9, length_of='system_name'), - StrLenField('system_name', '', length_from=lambda pkt: pkt._length) - ] - - -class LLDPDUSystemDescription(LLDPDU): - """ - ieee 802.1ab-2016 - sec. 8.5.7 / p. 31 - """ - fields_desc = [ - BitEnumField('_type', 0x06, 7, LLDPDU.TYPES), - BitFieldLenField('_length', None, 9, length_of='description'), - StrLenField('description', '', length_from=lambda pkt: pkt._length) - ] - - -class LLDPDUSystemCapabilities(LLDPDU): - """ - ieee 802.1ab-2016 - sec. 8.5.8 / p. 31 - """ - fields_desc = [ - BitEnumField('_type', 0x07, 7, LLDPDU.TYPES), - BitFieldLenField('_length', 4, 9), - BitField('reserved_5_available', 0, 1), - BitField('reserved_4_available', 0, 1), - BitField('reserved_3_available', 0, 1), - BitField('reserved_2_available', 0, 1), - BitField('reserved_1_available', 0, 1), - BitField('two_port_mac_relay_available', 0, 1), - BitField('s_vlan_component_available', 0, 1), - BitField('c_vlan_component_available', 0, 1), - BitField('station_only_available', 0, 1), - BitField('docsis_cable_device_available', 0, 1), - BitField('telephone_available', 0, 1), - BitField('router_available', 0, 1), - BitField('wlan_access_point_available', 0, 1), - BitField('mac_bridge_available', 0, 1), - BitField('repeater_available', 0, 1), - BitField('other_available', 0, 1), - BitField('reserved_5_enabled', 0, 1), - BitField('reserved_4_enabled', 0, 1), - BitField('reserved_3_enabled', 0, 1), - BitField('reserved_2_enabled', 0, 1), - BitField('reserved_1_enabled', 0, 1), - BitField('two_port_mac_relay_enabled', 0, 1), - BitField('s_vlan_component_enabled', 0, 1), - BitField('c_vlan_component_enabled', 0, 1), - BitField('station_only_enabled', 0, 1), - BitField('docsis_cable_device_enabled', 0, 1), - BitField('telephone_enabled', 0, 1), - BitField('router_enabled', 0, 1), - BitField('wlan_access_point_enabled', 0, 1), - BitField('mac_bridge_enabled', 0, 1), - BitField('repeater_enabled', 0, 1), - BitField('other_enabled', 0, 1), - ] - - def _check(self): - """ - run layer specific checks - """ - if conf.contribs['LLDP'].strict_mode() and self._length != 4: - raise LLDPInvalidLengthField('length must be 4 - got ' - '{}'.format(self._length)) - - -class LLDPDUManagementAddress(LLDPDU): - """ - ieee 802.1ab-2016 - sec. 8.5.9 / p. 32 - - currently only 0x00..0x1e are used by standards, no way to - use anything > 0xff as management address subtype is only - one octet wide - - see https://www.iana.org/assignments/ - address-family-numbers/address-family-numbers.xhtml - """ - IANA_ADDRESS_FAMILY_NUMBERS = { - 0x00: 'other', - 0x01: 'IPv4', - 0x02: 'IPv6', - 0x03: 'NSAP', - 0x04: 'HDLC', - 0x05: 'BBN', - 0x06: '802', - 0x07: 'E.163', - 0x08: 'E.164', - 0x09: 'F.69', - 0x0a: 'X.121', - 0x0b: 'IPX', - 0x0c: 'Appletalk', - 0x0d: 'Decnet IV', - 0x0e: 'Banyan Vines', - 0x0f: 'E.164 with NSAP', - 0x10: 'DNS', - 0x11: 'Distinguished Name', - 0x12: 'AS Number', - 0x13: 'XTP over IPv4', - 0x14: 'XTP over IPv6', - 0x15: 'XTP native mode XTP', - 0x16: 'Fiber Channel World-Wide Port Name', - 0x17: 'Fiber Channel World-Wide Node Name', - 0x18: 'GWID', - 0x19: 'AFI for L2VPN', - 0x1a: 'MPLS-TP Section Endpoint ID', - 0x1b: 'MPLS-TP LSP Endpoint ID', - 0x1c: 'MPLS-TP Pseudowire Endpoint ID', - 0x1d: 'MT IP Multi-Topology IPv4', - 0x1e: 'MT IP Multi-Topology IPv6' - } - - SUBTYPE_MANAGEMENT_ADDRESS_OTHER = 0x00 - SUBTYPE_MANAGEMENT_ADDRESS_IPV4 = 0x01 - SUBTYPE_MANAGEMENT_ADDRESS_IPV6 = 0x02 - SUBTYPE_MANAGEMENT_ADDRESS_NSAP = 0x03 - SUBTYPE_MANAGEMENT_ADDRESS_HDLC = 0x04 - SUBTYPE_MANAGEMENT_ADDRESS_BBN = 0x05 - SUBTYPE_MANAGEMENT_ADDRESS_802 = 0x06 - SUBTYPE_MANAGEMENT_ADDRESS_E_163 = 0x07 - SUBTYPE_MANAGEMENT_ADDRESS_E_164 = 0x08 - SUBTYPE_MANAGEMENT_ADDRESS_F_69 = 0x09 - SUBTYPE_MANAGEMENT_ADDRESS_X_121 = 0x0A - SUBTYPE_MANAGEMENT_ADDRESS_IPX = 0x0B - SUBTYPE_MANAGEMENT_ADDRESS_APPLETALK = 0x0C - SUBTYPE_MANAGEMENT_ADDRESS_DECNET_IV = 0x0D - SUBTYPE_MANAGEMENT_ADDRESS_BANYAN_VINES = 0x0E - SUBTYPE_MANAGEMENT_ADDRESS_E_164_WITH_NSAP = 0x0F - SUBTYPE_MANAGEMENT_ADDRESS_DNS = 0x10 - SUBTYPE_MANAGEMENT_ADDRESS_DISTINGUISHED_NAME = 0x11 - SUBTYPE_MANAGEMENT_ADDRESS_AS_NUMBER = 0x12 - SUBTYPE_MANAGEMENT_ADDRESS_XTP_OVER_IPV4 = 0x13 - SUBTYPE_MANAGEMENT_ADDRESS_XTP_OVER_IPV6 = 0x14 - SUBTYPE_MANAGEMENT_ADDRESS_XTP_NATIVE_MODE_XTP = 0x15 - SUBTYPE_MANAGEMENT_ADDRESS_FIBER_CHANNEL_WORLD_WIDE_PORT_NAME = 0x16 - SUBTYPE_MANAGEMENT_ADDRESS_FIBER_CHANNEL_WORLD_WIDE_NODE_NAME = 0x17 - SUBTYPE_MANAGEMENT_ADDRESS_GWID = 0x18 - SUBTYPE_MANAGEMENT_ADDRESS_AFI_FOR_L2VPN = 0x19 - SUBTYPE_MANAGEMENT_ADDRESS_MPLS_TP_SECTION_ENDPOINT_ID = 0x1A - SUBTYPE_MANAGEMENT_ADDRESS_MPLS_TP_LSP_ENDPOINT_ID = 0x1B - SUBTYPE_MANAGEMENT_ADDRESS_MPLS_TP_PSEUDOWIRE_ENDPOINT_ID = 0x1C - SUBTYPE_MANAGEMENT_ADDRESS_MT_IP_MULTI_TOPOLOGY_IPV4 = 0x1D - SUBTYPE_MANAGEMENT_ADDRESS_MT_IP_MULTI_TOPOLOGY_IPV6 = 0x1E - - INTERFACE_NUMBERING_SUBTYPES = { - 0x01: 'unknown', - 0x02: 'ifIndex', - 0x03: 'system port number' - } - - SUBTYPE_INTERFACE_NUMBER_UNKNOWN = 0x01 - SUBTYPE_INTERFACE_NUMBER_IF_INDEX = 0x02 - SUBTYPE_INTERFACE_NUMBER_SYSTEM_PORT_NUMBER = 0x03 - - ''' - Note - calculation of _length field: - _length = 1@_management_address_string_length + - 1@management_address_subtype + - management_address.len + - 1@interface_numbering_subtype + - 4@interface_number + - 1@_oid_string_length + - object_id.len - ''' - - fields_desc = [ - BitEnumField('_type', 0x08, 7, LLDPDU.TYPES), - BitFieldLenField('_length', None, 9, length_of='management_address', - adjust=lambda pkt, x: - 8 + len(pkt.management_address) + len(pkt.object_id)), - BitFieldLenField('_management_address_string_length', None, 8, - length_of='management_address', - adjust=lambda pkt, x: len(pkt.management_address) + 1), # noqa: E501 - ByteEnumField('management_address_subtype', 0x00, - IANA_ADDRESS_FAMILY_NUMBERS), - XStrLenField('management_address', '', - length_from=lambda pkt: - pkt._management_address_string_length - 1), - ByteEnumField('interface_numbering_subtype', - SUBTYPE_INTERFACE_NUMBER_UNKNOWN, - INTERFACE_NUMBERING_SUBTYPES), - BitField('interface_number', 0, 32), - BitFieldLenField('_oid_string_length', None, 8, length_of='object_id'), - XStrLenField('object_id', '', - length_from=lambda pkt: pkt._oid_string_length), - ] - - def _check(self): - """ - run layer specific checks - """ - if conf.contribs['LLDP'].strict_mode(): - management_address_len = len(self.management_address) - if management_address_len == 0 or management_address_len > 31: - raise LLDPInvalidLengthField( - 'management address must be 1..31 characters long - ' - 'got string of size {}'.format(management_address_len)) - - -class ThreeBytesEnumField(EnumField, ThreeBytesField): - - def __init__(self, name, default, enum): - EnumField.__init__(self, name, default, enum, "!I") - - -class LLDPDUGenericOrganisationSpecific(LLDPDU): - - ORG_UNIQUE_CODE_PNO = 0x000ecf - ORG_UNIQUE_CODE_IEEE_802_1 = 0x0080c2 - ORG_UNIQUE_CODE_IEEE_802_3 = 0x00120f - ORG_UNIQUE_CODE_TIA_TR_41_MED = 0x0012bb - ORG_UNIQUE_CODE_HYTEC = 0x30b216 - - ORG_UNIQUE_CODES = { - ORG_UNIQUE_CODE_PNO: "PROFIBUS International (PNO)", - ORG_UNIQUE_CODE_IEEE_802_1: "IEEE 802.1", - ORG_UNIQUE_CODE_IEEE_802_3: "IEEE 802.3", - ORG_UNIQUE_CODE_TIA_TR_41_MED: "TIA TR-41 Committee . Media Endpoint Discovery", # noqa: E501 - ORG_UNIQUE_CODE_HYTEC: "Hytec Geraetebau GmbH" - } - - fields_desc = [ - BitEnumField('_type', 127, 7, LLDPDU.TYPES), - BitFieldLenField('_length', None, 9, length_of='data', adjust=lambda pkt, x: len(pkt.data) + 4), # noqa: E501 - ThreeBytesEnumField('org_code', 0, ORG_UNIQUE_CODES), - ByteField('subtype', 0x00), - XStrLenField('data', '', length_from=lambda pkt: pkt._length - 4) - ] - - -# 0x09 .. 0x7e is reserved for future standardization and for now treated as Raw() data # noqa: E501 -LLDPDU_CLASS_TYPES = { - 0x00: LLDPDUEndOfLLDPDU, - 0x01: LLDPDUChassisID, - 0x02: LLDPDUPortID, - 0x03: LLDPDUTimeToLive, - 0x04: LLDPDUPortDescription, - 0x05: LLDPDUSystemName, - 0x06: LLDPDUSystemDescription, - 0x07: LLDPDUSystemCapabilities, - 0x08: LLDPDUManagementAddress, - 127: LLDPDUGenericOrganisationSpecific -} - - -class LLDPConfiguration(object): - """ - basic configuration for LLDP layer - """ - - def __init__(self): - self._strict_mode = True - self.strict_mode_enable() - - def strict_mode_enable(self): - """ - enable strict mode and dissector debugging - """ - self._strict_mode = True - - def strict_mode_disable(self): - """ - disable strict mode and dissector debugging - """ - self._strict_mode = False - - def strict_mode(self): - """ - get current strict mode state - """ - return self._strict_mode - - -conf.contribs['LLDP'] = LLDPConfiguration() - -bind_layers(Ether, LLDPDU, type=LLDP_ETHER_TYPE) -bind_layers(Dot1Q, LLDPDU, type=LLDP_ETHER_TYPE) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ltp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/ltp.py deleted file mode 100755 index 0009bfbab0..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ltp.py +++ /dev/null @@ -1,205 +0,0 @@ -#!/usr/bin/env python - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -""" - Copyright 2012, The MITRE Corporation - - NOTICE - This software/technical data was produced for the U.S. Government - under Prime Contract No. NASA-03001 and JPL Contract No. 1295026 - and is subject to FAR 52.227-14 (6/87) Rights in Data General, - and Article GP-51, Rights in Data General, respectively. - This software is publicly released under MITRE case #12-3054 -""" - -# scapy.contrib.description = Licklider Transmission Protocol (LTP) -# scapy.contrib.status = loads - -import scapy.modules.six as six -from scapy.packet import Packet, bind_layers, bind_top_down -from scapy.fields import BitEnumField, BitField, BitFieldLenField, \ - ByteEnumField, ConditionalField, PacketListField, StrLenField -from scapy.layers.inet import UDP -from scapy.config import conf -from scapy.contrib.sdnv import SDNV2, SDNV2FieldLenField - -# LTP https://tools.ietf.org/html/rfc5326 - -_ltp_flag_vals = { - 0: '0x0 Red data, NOT (Checkpoint, EORP or EOB)', - 1: '0x1 Red data, Checkpoint, NOT (EORP or EOB)', - 2: '0x2 Red data, Checkpoint, EORP, NOT EOB', - 3: '0x3 Red data, Checkpoint, EORP, EOB', - 4: '0x4 Green data, NOT EOB', - 5: '0x5 Green data, undefined', - 6: '0x6 Green data, undefined', - 7: '0x7 Green data, EOB', - 8: '0x8 Report segment', - 9: '0x9 Report-acknowledgment segmen', - 10: '0xA Control segment, undefined', - 11: '0xB Control segment, undefined', - 12: '0xC Cancel segment from block sender', - 13: '0xD Cancel-acknowledgment segment to block sender', - 14: '0xE Cancel segment from block receiver', - 15: '0xF Cancel-acknowledgment segment to block receiver'} - -_ltp_cancel_reasons = { - 0: 'USR_CNCLD - Client service canceled session.', - 1: 'UNREACH - Unreachable client service.', - 2: 'RLEXC - Retransmission limit exceeded.', - 3: 'MISCOLORED - Received miscolored segment.', - 4: 'SYS_CNCLD - System error condition.', - 5: 'RXMTCYCEXC - Exceeded the retransmission cycles limit.', - 6: 'RESERVED'} # Reserved 0x06-0xFF - -# LTP Extensions https://tools.ietf.org/html/rfc5327 - -_ltp_extension_tag = { - 0: 'LTP authentication extension', - 1: 'LTP cookie extension' -} - -_ltp_data_segment = [0, 1, 2, 3, 4, 5, 6, 7] -_ltp_checkpoint_segment = [1, 2, 3] - -_ltp_payload_conditions = {} - - -def ltp_bind_payload(cls, lambd): - """Bind payload class to the LTP packets. - params: - - cls: the class to bind - - lambd: lambda that will be called to check - whether or not the cls should be used - - lambda pkt: ... - """ - _ltp_payload_conditions[cls] = lambd - - -class LTPex(Packet): - name = "LTP Extension" - fields_desc = [ - ByteEnumField("ExTag", 0, _ltp_extension_tag), - SDNV2FieldLenField("ExLength", None, length_of="ExData"), - # SDNV2FieldLenField - StrLenField("ExData", "", length_from=lambda x: x.ExLength) - ] - - def default_payload_class(self, pay): - return conf.padding_layer - - -class LTPReceptionClaim(Packet): - name = "LTP Reception Claim" - fields_desc = [SDNV2("ReceptionClaimOffset", 0), - SDNV2("ReceptionClaimLength", 0)] - - def default_payload_class(self, pay): - return conf.padding_layer - - -def _ltp_guess_payload(pkt, *args): - for k, v in six.iteritems(_ltp_payload_conditions): - if v(pkt): - return k - return conf.raw_layer - - -class LTP(Packet): - name = "LTP" - fields_desc = [ - BitField('version', 0, 4), - BitEnumField('flags', 0, 4, _ltp_flag_vals), - SDNV2("SessionOriginator", 0), - SDNV2("SessionNumber", 0), - BitFieldLenField("HeaderExtensionCount", None, 4, count_of="HeaderExtensions"), # noqa: E501 - BitFieldLenField("TrailerExtensionCount", None, 4, count_of="TrailerExtensions"), # noqa: E501 - PacketListField("HeaderExtensions", [], LTPex, count_from=lambda x: x.HeaderExtensionCount), # noqa: E501 - # - # LTP segments containing data have a DATA header - # - ConditionalField(SDNV2("DATA_ClientServiceID", 0), - lambda x: x.flags in _ltp_data_segment), - ConditionalField(SDNV2("DATA_PayloadOffset", 0), - lambda x: x.flags in _ltp_data_segment), - ConditionalField(SDNV2FieldLenField("DATA_PayloadLength", None, length_of="LTP_Payload"), # noqa: E501 - lambda x: x.flags in _ltp_data_segment), - # - # LTP segments that are checkpoints will have a checkpoint serial number and report serial number. # noqa: E501 - # - ConditionalField(SDNV2("CheckpointSerialNo", 0), - lambda x: x.flags in _ltp_checkpoint_segment), - ConditionalField(SDNV2("ReportSerialNo", 0), - lambda x: x.flags in _ltp_checkpoint_segment), - # - # Then comes the actual payload for data carrying segments. - # - ConditionalField(PacketListField("LTP_Payload", None, next_cls_cb=_ltp_guess_payload, # noqa: E501 - length_from=lambda x: x.DATA_PayloadLength), # noqa: E501 - lambda x: x.flags in _ltp_data_segment), - # - # Report ACKS acknowledge a particular report serial number. - # - ConditionalField(SDNV2("RA_ReportSerialNo", 0), - lambda x: x.flags == 9), - # - # Reception reports have the following fields. - # - ConditionalField(SDNV2("ReportSerialNo", 0), - lambda x: x.flags == 8), - ConditionalField(SDNV2("ReportCheckpointSerialNo", 0), - lambda x: x.flags == 8), - ConditionalField(SDNV2("ReportUpperBound", 0), - lambda x: x.flags == 8), - ConditionalField(SDNV2("ReportLowerBound", 0), - lambda x: x.flags == 8), - ConditionalField(SDNV2FieldLenField("ReportReceptionClaimCount", None, count_of="ReportReceptionClaims"), # noqa: E501 - lambda x: x.flags == 8), - ConditionalField(PacketListField("ReportReceptionClaims", [], LTPReceptionClaim, # noqa: E501 - count_from=lambda x: x.ReportReceptionClaimCount), # noqa: E501 - lambda x: x.flags == 8 and (not x.ReportReceptionClaimCount or x.ReportReceptionClaimCount > 0)), # noqa: E501 - # - # Cancellation Requests - # - ConditionalField(ByteEnumField("CancelFromSenderReason", - 15, _ltp_cancel_reasons), - lambda x: x.flags == 12), - ConditionalField(ByteEnumField("CancelFromReceiverReason", - 15, _ltp_cancel_reasons), - lambda x: x.flags == 14), - # - # Cancellation Acknowldgements - # - ConditionalField(SDNV2("CancelAckToBlockSender", 0), - lambda x: x.flags == 13), - ConditionalField(SDNV2("CancelAckToBlockReceiver", 0), - lambda x: x.flags == 15), - # - # Finally, trailing extensions - # - PacketListField("TrailerExtensions", [], LTPex, count_from=lambda x: x.TrailerExtensionCount) # noqa: E501 - ] - - def mysummary(self): - return self.sprintf("LTP %SessionNumber%"), [UDP] - - -bind_top_down(UDP, LTP, sport=1113) -bind_top_down(UDP, LTP, dport=1113) -bind_top_down(UDP, LTP, sport=2113) -bind_top_down(UDP, LTP, dport=2113) -bind_layers(UDP, LTP, sport=1113, dport=1113) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/mac_control.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/mac_control.py deleted file mode 100644 index b340590a51..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/mac_control.py +++ /dev/null @@ -1,253 +0,0 @@ -#! /usr/bin/env python -# -# scapy.contrib.description = MACControl -# scapy.contrib.status = loads - -""" - MACControl - ~~~~~~~~~~ - - :author: Thomas Tannhaeuser, hecke@naberius.de - :license: GPLv2 - - This module is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This module 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. - - :description: - - This module provides Scapy layers for the MACControl protocol messages: - - Pause - - Gate - - Report - - Register/REQ/ACK - - Class Based Flow Control - - normative references: - - IEEE 802.3x - - - :NOTES: - - this is based on the MACControl dissector used by Wireshark - (https://github.com/wireshark/wireshark/blob/master/epan/dissectors/packet-maccontrol.c) - -""" - -from scapy.compat import orb -from scapy.data import ETHER_TYPES -from scapy.error import Scapy_Exception -from scapy.fields import IntField, ByteField, ByteEnumField, ShortField, BitField # noqa: E501 -from scapy.layers.dot11 import Packet -from scapy.layers.l2 import Ether, Dot1Q, bind_layers - -MAC_CONTROL_ETHER_TYPE = 0x8808 -ETHER_TYPES['MAC_CONTROL'] = MAC_CONTROL_ETHER_TYPE - -ETHER_SPEED_MBIT_10 = 0x01 -ETHER_SPEED_MBIT_100 = 0x02 -ETHER_SPEED_MBIT_1000 = 0x04 - - -class MACControl(Packet): - DEFAULT_DST_MAC = "01:80:c2:00:00:01" - - OP_CODE_PAUSE = 0x0001 - OP_CODE_GATE = 0x0002 - OP_CODE_REPORT = 0x0003 - OP_CODE_REGISTER_REQ = 0x0004 - OP_CODE_REGISTER = 0x0005 - OP_CODE_REGISTER_ACK = 0x0006 - OP_CODE_CLASS_BASED_FLOW_CONTROL = 0x0101 - - OP_CODES = { - OP_CODE_PAUSE: 'pause', - OP_CODE_GATE: 'gate', - OP_CODE_REPORT: 'report', - OP_CODE_REGISTER_REQ: 'register req', - OP_CODE_REGISTER: 'register', - OP_CODE_REGISTER_ACK: 'register_ack', - OP_CODE_CLASS_BASED_FLOW_CONTROL: 'class based flow control' - } - - ''' - flags used by Register* messages - ''' - FLAG_REGISTER = 0x01 - FLAG_DEREGISTER = 0x02 - FLAG_ACK = 0x03 - FLAG_NACK = 0x04 - - REGISTER_FLAGS = { - FLAG_REGISTER: 'register', - FLAG_DEREGISTER: 'deregister', - FLAG_ACK: 'ack', - FLAG_NACK: 'nack' - } - - def guess_payload_class(self, payload): - - try: - op_code = (orb(payload[0]) << 8) + orb(payload[1]) - return MAC_CTRL_CLASSES[op_code] - except KeyError: - pass - - return Packet.guess_payload_class(self, payload) - - def _get_underlayers_size(self): - """ - get the total size of all under layers - :return: number of bytes - """ - - under_layer = self.underlayer - - under_layers_size = 0 - - while under_layer and isinstance(under_layer, Dot1Q): - under_layers_size += 4 - under_layer = under_layer.underlayer - - if under_layer and isinstance(under_layer, Ether): - # ether header len + FCS len - under_layers_size += 14 + 4 - - return under_layers_size - - def post_build(self, pkt, pay): - """ - add padding to the frame if required. - - note that padding is only added if pay is None/empty. this allows us to add # noqa: E501 - any payload after the MACControl* PDU if needed (piggybacking). - """ - - if not pay: - under_layers_size = self._get_underlayers_size() - - frame_size = (len(pkt) + under_layers_size) - - if frame_size < 64: - return pkt + b'\x00' * (64 - frame_size) - - return pkt + pay - - -class MACControlInvalidSpeedException(Scapy_Exception): - pass - - -class MACControlPause(MACControl): - fields_desc = [ - ShortField("_op_code", MACControl.OP_CODE_PAUSE), - ShortField("pause_time", 0), - ] - - def get_pause_time(self, speed=ETHER_SPEED_MBIT_1000): - """ - get pause time for given link speed in seconds - - :param speed: select link speed to get the pause time for, must be ETHER_SPEED_MBIT_[10,100,1000] # noqa: E501 - :return: pause time in seconds - :raises MACControlInvalidSpeedException: on invalid speed selector - """ - - try: - return self.pause_time * { - ETHER_SPEED_MBIT_10: (0.0000001 * 512), - ETHER_SPEED_MBIT_100: (0.00000001 * 512), - ETHER_SPEED_MBIT_1000: (0.000000001 * 512 * 2) - }[speed] - except KeyError: - raise MACControlInvalidSpeedException('Invalid speed selector given. ' # noqa: E501 - 'Must be one of ETHER_SPEED_MBIT_[10,100,1000]') # noqa: E501 - - -class MACControlGate(MACControl): - fields_desc = [ - ShortField("_op_code", MACControl.OP_CODE_GATE), - IntField("timestamp", 0) - ] - - -class MACControlReport(MACControl): - fields_desc = [ - ShortField("_op_code", MACControl.OP_CODE_REPORT), - IntField("timestamp", 0), - ByteEnumField('flags', 0, MACControl.REGISTER_FLAGS), - ByteField('pending_grants', 0) - ] - - -class MACControlRegisterReq(MACControl): - fields_desc = [ - ShortField("_op_code", MACControl.OP_CODE_REGISTER_REQ), - IntField("timestamp", 0), - ShortField('assigned_port', 0), - ByteEnumField('flags', 0, MACControl.REGISTER_FLAGS), - ShortField('sync_time', 0), - ByteField('echoed_pending_grants', 0) - ] - - -class MACControlRegister(MACControl): - fields_desc = [ - ShortField("_op_code", MACControl.OP_CODE_REGISTER), - IntField("timestamp", 0), - ByteEnumField('flags', 0, MACControl.REGISTER_FLAGS), - ShortField('echoed_assigned_port', 0), - ShortField('echoed_sync_time', 0) - ] - - -class MACControlRegisterAck(MACControl): - fields_desc = [ - ShortField("_op_code", MACControl.OP_CODE_REGISTER_ACK), - IntField("timestamp", 0), - ByteEnumField('flags', 0, MACControl.REGISTER_FLAGS), - ShortField('echoed_assigned_port', 0), - ShortField('echoed_sync_time', 0) - ] - - -class MACControlClassBasedFlowControl(MACControl): - fields_desc = [ - ShortField("_op_code", MACControl.OP_CODE_CLASS_BASED_FLOW_CONTROL), - ByteField("_reserved", 0), - BitField('c7_enabled', 0, 1), - BitField('c6_enabled', 0, 1), - BitField('c5_enabled', 0, 1), - BitField('c4_enabled', 0, 1), - BitField('c3_enabled', 0, 1), - BitField('c2_enabled', 0, 1), - BitField('c1_enabled', 0, 1), - BitField('c0_enabled', 0, 1), - ShortField('c0_pause_time', 0), - ShortField('c1_pause_time', 0), - ShortField('c2_pause_time', 0), - ShortField('c3_pause_time', 0), - ShortField('c4_pause_time', 0), - ShortField('c5_pause_time', 0), - ShortField('c6_pause_time', 0), - ShortField('c7_pause_time', 0) - ] - - -MAC_CTRL_CLASSES = { - MACControl.OP_CODE_PAUSE: MACControlPause, - MACControl.OP_CODE_GATE: MACControlGate, - MACControl.OP_CODE_REPORT: MACControlReport, - MACControl.OP_CODE_REGISTER_REQ: MACControlRegisterReq, - MACControl.OP_CODE_REGISTER: MACControlRegister, - MACControl.OP_CODE_REGISTER_ACK: MACControlRegisterAck, - MACControl.OP_CODE_CLASS_BASED_FLOW_CONTROL: MACControlClassBasedFlowControl # noqa: E501 -} - -bind_layers(Ether, MACControl, type=MAC_CONTROL_ETHER_TYPE) -bind_layers(Dot1Q, MACControl, type=MAC_CONTROL_ETHER_TYPE) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/macsec.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/macsec.py deleted file mode 100755 index 64ae04542a..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/macsec.py +++ /dev/null @@ -1,241 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Sabrina Dubroca -# This program is published under a GPLv2 license - -# scapy.contrib.description = 802.1AE - IEEE MAC Security standard (MACsec) -# scapy.contrib.status = loads - -""" -Classes and functions for MACsec. -""" - -from __future__ import absolute_import -from __future__ import print_function -import struct -import copy - -from scapy.config import conf -from scapy.fields import BitField, ConditionalField, IntField, PacketField, \ - XShortEnumField -from scapy.packet import Packet, Raw, bind_layers -from scapy.layers.l2 import Ether, Dot1AD, Dot1Q -from scapy.layers.eap import MACsecSCI -from scapy.layers.inet import IP -from scapy.layers.inet6 import IPv6 -from scapy.compat import raw -from scapy.data import ETH_P_MACSEC, ETHER_TYPES, ETH_P_IP, ETH_P_IPV6 -from scapy.error import log_loading -import scapy.modules.six as six - -if conf.crypto_valid: - from cryptography.hazmat.backends import default_backend - from cryptography.hazmat.primitives.ciphers import ( - Cipher, - algorithms, - modes, - ) -else: - log_loading.info("Can't import python-cryptography v1.7+. " - "Disabled MACsec encryption/authentication.") - - -NOSCI_LEN = 14 + 6 -SCI_LEN = 8 -DEFAULT_ICV_LEN = 16 - - -class MACsecSA(object): - """Representation of a MACsec Secure Association - - Provides encapsulation, decapsulation, encryption, and decryption - of MACsec frames - """ - def __init__(self, sci, an, pn, key, icvlen, encrypt, send_sci, xpn_en=False, ssci=None, salt=None): # noqa: E501 - if isinstance(sci, six.integer_types): - self.sci = struct.pack('!Q', sci) - elif isinstance(sci, bytes): - self.sci = sci - else: - raise TypeError("SCI must be either bytes or int") - self.an = an - self.pn = pn - self.key = key - self.icvlen = icvlen - self.do_encrypt = encrypt - self.send_sci = send_sci - self.xpn_en = xpn_en - if self.xpn_en: - # Get SSCI (32 bits) - if isinstance(ssci, six.integer_types): - self.ssci = struct.pack('!L', ssci) - elif isinstance(ssci, bytes): - self.ssci = ssci - else: - raise TypeError("SSCI must be either bytes or int") - # Get Salt (96 bits, only bytes allowed) - if isinstance(salt, bytes): - self.salt = salt - else: - raise TypeError("Salt must be bytes") - - def make_iv(self, pkt): - """generate an IV for the packet""" - if self.xpn_en: - tmp_pn = (self.pn & 0xFFFFFFFF00000000) | (pkt[MACsec].pn & 0xFFFFFFFF) # noqa: E501 - tmp_iv = self.ssci + struct.pack('!Q', tmp_pn) - return bytes(bytearray([a ^ b for a, b in zip(bytearray(tmp_iv), bytearray(self.salt))])) # noqa: E501 - else: - return self.sci + struct.pack('!I', pkt[MACsec].pn) - - @staticmethod - def split_pkt(pkt, assoclen, icvlen=0): - """ - split the packet into associated data, plaintext or ciphertext, and - optional ICV - """ - data = raw(pkt) - assoc = data[:assoclen] - if icvlen: - icv = data[-icvlen:] - enc = data[assoclen:-icvlen] - else: - icv = b'' - enc = data[assoclen:] - return assoc, enc, icv - - def e_bit(self): - """returns the value of the E bit for packets sent through this SA""" - return self.do_encrypt - - def c_bit(self): - """returns the value of the C bit for packets sent through this SA""" - return self.do_encrypt or self.icvlen != DEFAULT_ICV_LEN - - @staticmethod - def shortlen(pkt): - """determine shortlen for a raw packet (not encapsulated yet)""" - datalen = len(pkt) - 2 * 6 - if datalen < 48: - return datalen - return 0 - - def encap(self, pkt): - """encapsulate a frame using this Secure Association""" - if pkt.name != Ether().name: - raise TypeError('cannot encapsulate packet in MACsec, must be Ethernet') # noqa: E501 - hdr = copy.deepcopy(pkt) - payload = hdr.payload - del hdr.payload - tag = MACsec(sci=self.sci, an=self.an, - SC=self.send_sci, - E=self.e_bit(), C=self.c_bit(), - shortlen=MACsecSA.shortlen(pkt), - pn=(self.pn & 0xFFFFFFFF), type=pkt.type) - hdr.type = ETH_P_MACSEC - return hdr / tag / payload - - # this doesn't really need to be a method, but for symmetry with - # encap(), it is - def decap(self, orig_pkt): - """decapsulate a MACsec frame""" - if orig_pkt.name != Ether().name or orig_pkt.payload.name != MACsec().name: # noqa: E501 - raise TypeError('cannot decapsulate MACsec packet, must be Ethernet/MACsec') # noqa: E501 - packet = copy.deepcopy(orig_pkt) - prev_layer = packet[MACsec].underlayer - prev_layer.type = packet[MACsec].type - next_layer = packet[MACsec].payload - del prev_layer.payload - if prev_layer.name == Ether().name: - return Ether(raw(prev_layer / next_layer)) - return prev_layer / next_layer - - def encrypt(self, orig_pkt, assoclen=None): - """encrypt a MACsec frame for this Secure Association""" - hdr = copy.deepcopy(orig_pkt) - del hdr[MACsec].payload - del hdr[MACsec].type - pktlen = len(orig_pkt) - if self.send_sci: - hdrlen = NOSCI_LEN + SCI_LEN - else: - hdrlen = NOSCI_LEN - if assoclen is None or not self.do_encrypt: - if self.do_encrypt: - assoclen = hdrlen - else: - assoclen = pktlen - iv = self.make_iv(orig_pkt) - assoc, pt, _ = MACsecSA.split_pkt(orig_pkt, assoclen) - encryptor = Cipher( - algorithms.AES(self.key), - modes.GCM(iv), - backend=default_backend() - ).encryptor() - encryptor.authenticate_additional_data(assoc) - ct = encryptor.update(pt) + encryptor.finalize() - hdr[MACsec].payload = Raw(assoc[hdrlen:assoclen] + ct + encryptor.tag) - return hdr - - def decrypt(self, orig_pkt, assoclen=None): - """decrypt a MACsec frame for this Secure Association""" - hdr = copy.deepcopy(orig_pkt) - del hdr[MACsec].payload - pktlen = len(orig_pkt) - if self.send_sci: - hdrlen = NOSCI_LEN + SCI_LEN - else: - hdrlen = NOSCI_LEN - if assoclen is None or not self.do_encrypt: - if self.do_encrypt: - assoclen = hdrlen - else: - assoclen = pktlen - self.icvlen - iv = self.make_iv(hdr) - assoc, ct, icv = MACsecSA.split_pkt(orig_pkt, assoclen, self.icvlen) - decryptor = Cipher( - algorithms.AES(self.key), - modes.GCM(iv, icv), - backend=default_backend() - ).decryptor() - decryptor.authenticate_additional_data(assoc) - pt = assoc[hdrlen:assoclen] - pt += decryptor.update(ct) - pt += decryptor.finalize() - hdr[MACsec].type = struct.unpack('!H', pt[0:2])[0] - hdr[MACsec].payload = Raw(pt[2:]) - return hdr - - -class MACsec(Packet): - """representation of one MACsec frame""" - name = '802.1AE' - fields_desc = [BitField('Ver', 0, 1), - BitField('ES', 0, 1), - BitField('SC', 0, 1), - BitField('SCB', 0, 1), - BitField('E', 0, 1), - BitField('C', 0, 1), - BitField('an', 0, 2), - BitField('reserved', 0, 2), - BitField('shortlen', 0, 6), - IntField("pn", 1), - ConditionalField(PacketField("sci", None, MACsecSCI), lambda pkt: pkt.SC), # noqa: E501 - ConditionalField(XShortEnumField("type", None, ETHER_TYPES), - lambda pkt: pkt.type is not None)] - - def mysummary(self): - summary = self.sprintf("an=%MACsec.an%, pn=%MACsec.pn%") - if self.SC: - summary += self.sprintf(", sci=%MACsec.sci%") - if self.type is not None: - summary += self.sprintf(", %MACsec.type%") - return summary - - -bind_layers(MACsec, IP, type=ETH_P_IP) -bind_layers(MACsec, IPv6, type=ETH_P_IPV6) - -bind_layers(Dot1AD, MACsec, type=ETH_P_MACSEC) -bind_layers(Dot1Q, MACsec, type=ETH_P_MACSEC) -bind_layers(Ether, MACsec, type=ETH_P_MACSEC) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/modbus.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/modbus.py deleted file mode 100644 index 3e270833c0..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/modbus.py +++ /dev/null @@ -1,846 +0,0 @@ -# coding: utf8 - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = ModBus Protocol -# scapy.contrib.status = loads - -# Copyright (C) 2017 Arthur Gervais, Ken LE PRADO, Sébastien Mainand, Thomas Aurel # noqa: E501 - -import struct - -from scapy.packet import Packet, bind_layers -from scapy.fields import XByteField, XShortField, StrLenField, ByteEnumField, \ - BitFieldLenField, ByteField, ConditionalField, EnumField, FieldListField, \ - ShortField, StrFixedLenField -from scapy.layers.inet import TCP -from scapy.utils import orb -from scapy.config import conf -from scapy.volatile import VolatileValue - -# TODO: implement serial specific function codes - -_modbus_exceptions = {1: "Illegal Function Code", - 2: "Illegal Data Address", - 3: "Illegal Data Value", - 4: "Server Device Failure", - 5: "Acknowledge", - 6: "Server Device Busy", - 8: "Memory Parity Error", - 10: "Gateway Path Unavailable", - 11: "Gateway Target Device Failed to Respond"} - - -class ModbusPDU01ReadCoilsRequest(Packet): - name = "Read Coils Request" - fields_desc = [XByteField("funcCode", 0x01), - XShortField("startAddr", 0x0000), # 0x0000 to 0xFFFF - XShortField("quantity", 0x0001)] - - def extract_padding(self, s): - return b"", None - - -class ModbusPDU01ReadCoilsResponse(Packet): - name = "Read Coils Response" - fields_desc = [XByteField("funcCode", 0x01), - BitFieldLenField("byteCount", None, 8, count_of="coilStatus"), # noqa: E501 - FieldListField("coilStatus", [0x00], ByteField("", 0x00), count_from=lambda pkt: pkt.byteCount)] # noqa: E501 - - def extract_padding(self, s): - return b"", None - - -class ModbusPDU01ReadCoilsError(Packet): - name = "Read Coils Exception" - fields_desc = [XByteField("funcCode", 0x81), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - def extract_padding(self, s): - return b"", None - - -class ModbusPDU02ReadDiscreteInputsRequest(Packet): - name = "Read Discrete Inputs" - fields_desc = [XByteField("funcCode", 0x02), - XShortField("startAddr", 0x0000), - XShortField("quantity", 0x0001)] - - def extract_padding(self, s): - return b"", None - - -class ModbusPDU02ReadDiscreteInputsResponse(Packet): - """ inputStatus: result is represented as bytes, padded with 0 to have a - integer number of bytes. The field does not parse this result and - present the bytes directly - """ - name = "Read Discrete Inputs Response" - fields_desc = [XByteField("funcCode", 0x02), - BitFieldLenField("byteCount", None, 8, count_of="inputStatus"), # noqa: E501 - FieldListField("inputStatus", [0x00], ByteField("", 0x00), count_from=lambda pkt: pkt.byteCount)] # noqa: E501 - - -class ModbusPDU02ReadDiscreteInputsError(Packet): - name = "Read Discrete Inputs Exception" - fields_desc = [XByteField("funcCode", 0x82), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -class ModbusPDU03ReadHoldingRegistersRequest(Packet): - name = "Read Holding Registers" - fields_desc = [XByteField("funcCode", 0x03), - XShortField("startAddr", 0x0000), - XShortField("quantity", 0x0001)] - - def extract_padding(self, s): - return b"", None - - -class ModbusPDU03ReadHoldingRegistersResponse(Packet): - name = "Read Holding Registers Response" - fields_desc = [XByteField("funcCode", 0x03), - BitFieldLenField("byteCount", None, 8, count_of="registerVal", adjust=lambda pkt, x: x * 2), # noqa: E501 - FieldListField("registerVal", [0x0000], ShortField("", 0x0000), # noqa: E501 - count_from=lambda pkt: pkt.byteCount)] - - -class ModbusPDU03ReadHoldingRegistersError(Packet): - name = "Read Holding Registers Exception" - fields_desc = [XByteField("funcCode", 0x83), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -class ModbusPDU04ReadInputRegistersRequest(Packet): - name = "Read Input Registers" - fields_desc = [XByteField("funcCode", 0x04), - XShortField("startAddr", 0x0000), - XShortField("quantity", 0x0001)] - - def extract_padding(self, s): - return b"", None - - -class ModbusPDU04ReadInputRegistersResponse(Packet): - name = "Read Input Registers Response" - fields_desc = [XByteField("funcCode", 0x04), - BitFieldLenField("byteCount", None, 8, count_of="registerVal", adjust=lambda pkt, x: x * 2), # noqa: E501 - FieldListField("registerVal", [0x0000], ShortField("", 0x0000), # noqa: E501 - count_from=lambda pkt: pkt.byteCount)] - - -class ModbusPDU04ReadInputRegistersError(Packet): - name = "Read Input Registers Exception" - fields_desc = [XByteField("funcCode", 0x84), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -class ModbusPDU05WriteSingleCoilRequest(Packet): - name = "Write Single Coil" - fields_desc = [XByteField("funcCode", 0x05), - XShortField("outputAddr", 0x0000), # from 0x0000 to 0xFFFF - XShortField("outputValue", 0x0000)] # 0x0000 == Off, 0xFF00 == On # noqa: E501 - - -class ModbusPDU05WriteSingleCoilResponse(Packet): # The answer is the same as the request if successful # noqa: E501 - name = "Write Single Coil" - fields_desc = [XByteField("funcCode", 0x05), - XShortField("outputAddr", 0x0000), # from 0x0000 to 0xFFFF - XShortField("outputValue", 0x0000)] # 0x0000 == Off, 0xFF00 == On # noqa: E501 - - -class ModbusPDU05WriteSingleCoilError(Packet): - name = "Write Single Coil Exception" - fields_desc = [XByteField("funcCode", 0x85), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -class ModbusPDU06WriteSingleRegisterRequest(Packet): - name = "Write Single Register" - fields_desc = [XByteField("funcCode", 0x06), - XShortField("registerAddr", 0x0000), - XShortField("registerValue", 0x0000)] - - def extract_padding(self, s): - return b"", None - - -class ModbusPDU06WriteSingleRegisterResponse(Packet): - name = "Write Single Register Response" - fields_desc = [XByteField("funcCode", 0x06), - XShortField("registerAddr", 0x0000), - XShortField("registerValue", 0x0000)] - - -class ModbusPDU06WriteSingleRegisterError(Packet): - name = "Write Single Register Exception" - fields_desc = [XByteField("funcCode", 0x86), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -class ModbusPDU07ReadExceptionStatusRequest(Packet): - name = "Read Exception Status" - fields_desc = [XByteField("funcCode", 0x07)] - - def extract_padding(self, s): - return b"", None - - -class ModbusPDU07ReadExceptionStatusResponse(Packet): - name = "Read Exception Status Response" - fields_desc = [XByteField("funcCode", 0x07), - XByteField("startAddr", 0x00)] - - -class ModbusPDU07ReadExceptionStatusError(Packet): - name = "Read Exception Status Exception" - fields_desc = [XByteField("funcCode", 0x87), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -class ModbusPDU0FWriteMultipleCoilsRequest(Packet): - name = "Write Multiple Coils" - fields_desc = [XByteField("funcCode", 0x0F), - XShortField("startAddr", 0x0000), - XShortField("quantityOutput", 0x0001), - BitFieldLenField("byteCount", None, 8, count_of="outputsValue"), # noqa: E501 - FieldListField("outputsValue", [0x00], XByteField("", 0x00), count_from=lambda pkt: pkt.byteCount)] # noqa: E501 - - def extract_padding(self, s): - return b"", None - - -class ModbusPDU0FWriteMultipleCoilsResponse(Packet): - name = "Write Multiple Coils Response" - fields_desc = [XByteField("funcCode", 0x0F), - XShortField("startAddr", 0x0000), - XShortField("quantityOutput", 0x0001)] - - -class ModbusPDU0FWriteMultipleCoilsError(Packet): - name = "Write Multiple Coils Exception" - fields_desc = [XByteField("funcCode", 0x8F), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -class ModbusPDU10WriteMultipleRegistersRequest(Packet): - name = "Write Multiple Registers" - fields_desc = [XByteField("funcCode", 0x10), - XShortField("startAddr", 0x0000), - BitFieldLenField("quantityRegisters", None, 16, count_of="outputsValue",), # noqa: E501 - BitFieldLenField("byteCount", None, 8, count_of="outputsValue", adjust=lambda pkt, x: x * 2), # noqa: E501 - FieldListField("outputsValue", [0x0000], XShortField("", 0x0000), # noqa: E501 - count_from=lambda pkt: pkt.byteCount)] - - -class ModbusPDU10WriteMultipleRegistersResponse(Packet): - name = "Write Multiple Registers Response" - fields_desc = [XByteField("funcCode", 0x10), - XShortField("startAddr", 0x0000), - XShortField("quantityRegisters", 0x0001)] - - -class ModbusPDU10WriteMultipleRegistersError(Packet): - name = "Write Multiple Registers Exception" - fields_desc = [XByteField("funcCode", 0x90), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -class ModbusPDU11ReportSlaveIdRequest(Packet): - name = "Report Slave Id" - fields_desc = [XByteField("funcCode", 0x11)] - - def extract_padding(self, s): - return b"", None - - -class ModbusPDU11ReportSlaveIdResponse(Packet): - name = "Report Slave Id Response" - fields_desc = [XByteField("funcCode", 0x11), - BitFieldLenField("byteCount", None, 8, length_of="slaveId"), - ConditionalField(StrLenField("slaveId", "", length_from=lambda pkt: pkt.byteCount), # noqa: E501 - lambda pkt: pkt.byteCount > 0), - ConditionalField(XByteField("runIdicatorStatus", 0x00), lambda pkt: pkt.byteCount > 0)] # noqa: E501 - - -class ModbusPDU11ReportSlaveIdError(Packet): - name = "Report Slave Id Exception" - fields_desc = [XByteField("funcCode", 0x91), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -class ModbusReadFileSubRequest(Packet): - name = "Sub-request of Read File Record" - fields_desc = [ByteField("refType", 0x06), - ShortField("fileNumber", 0x0001), - ShortField("recordNumber", 0x0000), - ShortField("recordLength", 0x0001)] - - def guess_payload_class(self, payload): - return ModbusReadFileSubRequest - - -class ModbusPDU14ReadFileRecordRequest(Packet): - name = "Read File Record" - fields_desc = [XByteField("funcCode", 0x14), - ByteField("byteCount", None)] - - def guess_payload_class(self, payload): - if self.byteCount > 0: - return ModbusReadFileSubRequest - else: - return Packet.guess_payload_class(self, payload) - - def post_build(self, p, pay): - if self.byteCount is None: - tmp_len = len(pay) - p = p[:1] + struct.pack("!B", tmp_len) + p[3:] - return p + pay - - -class ModbusReadFileSubResponse(Packet): - name = "Sub-response" - fields_desc = [BitFieldLenField("respLength", None, 8, count_of="recData", adjust=lambda pkt, p: p * 2 + 1), # noqa: E501 - ByteField("refType", 0x06), - FieldListField("recData", [0x0000], XShortField("", 0x0000), - count_from=lambda pkt: (pkt.respLength - 1) // 2)] # noqa: E501 - - def guess_payload_class(self, payload): - return ModbusReadFileSubResponse - - -class ModbusPDU14ReadFileRecordResponse(Packet): - name = "Read File Record Response" - fields_desc = [XByteField("funcCode", 0x14), - ByteField("dataLength", None)] - - def post_build(self, p, pay): - if self.dataLength is None: - tmp_len = len(pay) - p = p[:1] + struct.pack("!B", tmp_len) + p[3:] - return p + pay - - def guess_payload_class(self, payload): - if self.dataLength > 0: - return ModbusReadFileSubResponse - else: - return Packet.guess_payload_class(self, payload) - - -class ModbusPDU14ReadFileRecordError(Packet): - name = "Read File Record Exception" - fields_desc = [XByteField("funcCode", 0x94), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -# 0x15 : Write File Record -class ModbusWriteFileSubRequest(Packet): - name = "Sub request of Write File Record" - fields_desc = [ByteField("refType", 0x06), - ShortField("fileNumber", 0x0001), - ShortField("recordNumber", 0x0000), - BitFieldLenField("recordLength", None, 16, length_of="recordData", adjust=lambda pkt, p: p // 2), # noqa: E501 - FieldListField("recordData", [0x0000], ShortField("", 0x0000), # noqa: E501 - length_from=lambda pkt: pkt.recordLength * 2)] # noqa: E501 - - def guess_payload_class(self, payload): - if payload: - return ModbusWriteFileSubRequest - - -class ModbusPDU15WriteFileRecordRequest(Packet): - name = "Write File Record" - fields_desc = [XByteField("funcCode", 0x15), - ByteField("dataLength", None)] - - def post_build(self, p, pay): - if self.dataLength is None: - tmp_len = len(pay) - p = p[:1] + struct.pack("!B", tmp_len) + p[3:] - return p + pay - - def guess_payload_class(self, payload): - if self.dataLength > 0: - return ModbusWriteFileSubRequest - else: - return Packet.guess_payload_class(self, payload) - - -class ModbusWriteFileSubResponse(ModbusWriteFileSubRequest): - name = "Sub response of Write File Record" - - def guess_payload_class(self, payload): - if payload: - return ModbusWriteFileSubResponse - - -class ModbusPDU15WriteFileRecordResponse(ModbusPDU15WriteFileRecordRequest): - name = "Write File Record Response" - - def guess_payload_class(self, payload): - if self.dataLength > 0: - return ModbusWriteFileSubResponse - else: - return Packet.guess_payload_class(self, payload) - - -class ModbusPDU15WriteFileRecordError(Packet): - name = "Write File Record Exception" - fields_desc = [XByteField("funcCode", 0x95), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -class ModbusPDU16MaskWriteRegisterRequest(Packet): - # and/or to 0xFFFF/0x0000 so that nothing is changed in memory - name = "Mask Write Register" - fields_desc = [XByteField("funcCode", 0x16), - XShortField("refAddr", 0x0000), - XShortField("andMask", 0xffff), - XShortField("orMask", 0x0000)] - - -class ModbusPDU16MaskWriteRegisterResponse(Packet): - name = "Mask Write Register Response" - fields_desc = [XByteField("funcCode", 0x16), - XShortField("refAddr", 0x0000), - XShortField("andMask", 0xffff), - XShortField("orMask", 0x0000)] - - -class ModbusPDU16MaskWriteRegisterError(Packet): - name = "Mask Write Register Exception" - fields_desc = [XByteField("funcCode", 0x96), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -class ModbusPDU17ReadWriteMultipleRegistersRequest(Packet): - name = "Read Write Multiple Registers" - fields_desc = [XByteField("funcCode", 0x17), - XShortField("readStartingAddr", 0x0000), - XShortField("readQuantityRegisters", 0x0001), - XShortField("writeStartingAddr", 0x0000), - BitFieldLenField("writeQuantityRegisters", None, 16, count_of="writeRegistersValue"), # noqa: E501 - BitFieldLenField("byteCount", None, 8, count_of="writeRegistersValue", adjust=lambda pkt, x: x * 2), # noqa: E501 - FieldListField("writeRegistersValue", [0x0000], XShortField("", 0x0000), # noqa: E501 - count_from=lambda pkt: pkt.byteCount)] - - -class ModbusPDU17ReadWriteMultipleRegistersResponse(Packet): - name = "Read Write Multiple Registers Response" - fields_desc = [XByteField("funcCode", 0x17), - BitFieldLenField("byteCount", None, 8, count_of="registerVal", adjust=lambda pkt, x: x * 2), # noqa: E501 - FieldListField("registerVal", [0x0000], ShortField("", 0x0000), # noqa: E501 - count_from=lambda pkt: pkt.byteCount)] - - -class ModbusPDU17ReadWriteMultipleRegistersError(Packet): - name = "Read Write Multiple Exception" - fields_desc = [XByteField("funcCode", 0x97), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -class ModbusPDU18ReadFIFOQueueRequest(Packet): - name = "Read FIFO Queue" - fields_desc = [XByteField("funcCode", 0x18), - XShortField("FIFOPointerAddr", 0x0000)] - - -class ModbusPDU18ReadFIFOQueueResponse(Packet): - name = "Read FIFO Queue Response" - fields_desc = [XByteField("funcCode", 0x18), - # TODO: ByteCount must includes size of FIFOCount - BitFieldLenField("byteCount", None, 16, count_of="FIFOVal", adjust=lambda pkt, p: p * 2 + 2), # noqa: E501 - BitFieldLenField("FIFOCount", None, 16, count_of="FIFOVal"), - FieldListField("FIFOVal", [], ShortField("", 0x0000), count_from=lambda pkt: pkt.byteCount)] # noqa: E501 - - -class ModbusPDU18ReadFIFOQueueError(Packet): - name = "Read FIFO Queue Exception" - fields_desc = [XByteField("funcCode", 0x98), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -# TODO: not implemented, out of the main specification -# class ModbusPDU2B0DCANOpenGeneralReferenceRequest(Packet): -# name = "CANopen General Reference Request" -# fields_desc = [] -# -# -# class ModbusPDU2B0DCANOpenGeneralReferenceResponse(Packet): -# name = "CANopen General Reference Response" -# fields_desc = [] -# -# -# class ModbusPDU2B0DCANOpenGeneralReferenceError(Packet): -# name = "CANopen General Reference Error" -# fields_desc = [] - - -# 0x2B/0x0E - Read Device Identification values -_read_device_id_codes = {1: "Basic", - 2: "Regular", - 3: "Extended", - 4: "Specific"} -# 0x00->0x02: mandatory -# 0x03->0x06: optional -# 0x07->0x7F: Reserved (optional) -# 0x80->0xFF: product dependent private objects (optional) -_read_device_id_object_id = {0x00: "VendorName", - 0x01: "ProductCode", - 0x02: "MajorMinorRevision", - 0x03: "VendorUrl", - 0x04: "ProductName", - 0x05: "ModelName", - 0x06: "UserApplicationName"} -_read_device_id_conformity_lvl = {0x01: "Basic Identification (stream only)", - 0x02: "Regular Identification (stream only)", - 0x03: "Extended Identification (stream only)", # noqa: E501 - 0x81: "Basic Identification (stream and individual access)", # noqa: E501 - 0x82: "Regular Identification (stream and individual access)", # noqa: E501 - 0x83: "Extended Identification (stream and individual access)"} # noqa: E501 -_read_device_id_more_follow = {0x00: "No", - 0x01: "Yes"} - - -class ModbusPDU2B0EReadDeviceIdentificationRequest(Packet): - name = "Read Device Identification" - fields_desc = [XByteField("funcCode", 0x2B), - XByteField("MEIType", 0x0E), - ByteEnumField("readCode", 1, _read_device_id_codes), - ByteEnumField("objectId", 0x00, _read_device_id_object_id)] - - -class ModbusPDU2B0EReadDeviceIdentificationResponse(Packet): - name = "Read Device Identification" - fields_desc = [XByteField("funcCode", 0x2B), - XByteField("MEIType", 0x0E), - ByteEnumField("readCode", 4, _read_device_id_codes), - ByteEnumField("conformityLevel", 0x01, _read_device_id_conformity_lvl), # noqa: E501 - ByteEnumField("more", 0x00, _read_device_id_more_follow), - ByteEnumField("nextObjId", 0x00, _read_device_id_object_id), - ByteField("objCount", 0x00)] - - def guess_payload_class(self, payload): - if self.objCount > 0: - return ModbusObjectId - else: - return Packet.guess_payload_class(self, payload) - - -class ModbusPDU2B0EReadDeviceIdentificationError(Packet): - name = "Read Exception Status Exception" - fields_desc = [XByteField("funcCode", 0xAB), - ByteEnumField("exceptCode", 1, _modbus_exceptions)] - - -_reserved_funccode_request = { - 0x08: '0x08 Unknown Reserved Request', - 0x09: '0x09 Unknown Reserved Request', - 0x0A: '0x0a Unknown Reserved Request', - 0x0D: '0x0d Unknown Reserved Request', - 0x0E: '0x0e Unknown Reserved Request', - 0x29: '0x29 Unknown Reserved Request', - 0x2A: '0x2a Unknown Reserved Request', - 0x5A: 'Specific Schneider Electric Request', - 0x5B: '0x5b Unknown Reserved Request', - 0x7D: '0x7d Unknown Reserved Request', - 0x7E: '0x7e Unknown Reserved Request', - 0x7F: '0x7f Unknown Reserved Request', -} - -_reserved_funccode_response = { - 0x08: '0x08 Unknown Reserved Response', - 0x09: '0x09 Unknown Reserved Response', - 0x0A: '0x0a Unknown Reserved Response', - 0x0D: '0x0d Unknown Reserved Response', - 0x0E: '0x0e Unknown Reserved Response', - 0x29: '0x29 Unknown Reserved Response', - 0x2A: '0x2a Unknown Reserved Response', - 0x5A: 'Specific Schneider Electric Response', - 0x5B: '0x5b Unknown Reserved Response', - 0x7D: '0x7d Unknown Reserved Response', - 0x7E: '0x7e Unknown Reserved Response', - 0x7F: '0x7f Unknown Reserved Response', -} - -_reserved_funccode_error = { - 0x88: '0x88 Unknown Reserved Error', - 0x89: '0x89 Unknown Reserved Error', - 0x8A: '0x8a Unknown Reserved Error', - 0x8D: '0x8d Unknown Reserved Error', - 0x8E: '0x8e Unknown Reserved Error', - 0xA9: '0x88 Unknown Reserved Error', - 0xAA: '0x88 Unknown Reserved Error', - 0xDA: 'Specific Schneider Electric Error', - 0xDB: '0xdb Unknown Reserved Error', - 0xDC: '0xdc Unknown Reserved Error', - 0xFD: '0xfd Unknown Reserved Error', - 0xFE: '0xfe Unknown Reserved Error', - 0xFF: '0xff Unknown Reserved Error', -} - - -class ModbusPDUReservedFunctionCodeRequest(Packet): - name = "Reserved Function Code Request" - fields_desc = [ - ByteEnumField("funcCode", 0x00, _reserved_funccode_request), - StrFixedLenField('payload', '', 255), ] - - def extract_padding(self, s): - return b"", None - - def mysummary(self): - return self.sprintf("Modbus Reserved Request %funcCode%") - - -class ModbusPDUReservedFunctionCodeResponse(Packet): - name = "Reserved Function Code Response" - fields_desc = [ - ByteEnumField("funcCode", 0x00, _reserved_funccode_response), - StrFixedLenField('payload', '', 255), ] - - def extract_padding(self, s): - return b"", None - - def mysummary(self): - return self.sprintf("Modbus Reserved Response %funcCode%") - - -class ModbusPDUReservedFunctionCodeError(Packet): - name = "Reserved Function Code Error" - fields_desc = [ - ByteEnumField("funcCode", 0x00, _reserved_funccode_error), - StrFixedLenField('payload', '', 255), ] - - def extract_padding(self, s): - return b"", None - - def mysummary(self): - return self.sprintf("Modbus Reserved Error %funcCode%") - - -_userdefined_funccode_request = { -} -_userdefined_funccode_response = { -} -_userdefined_funccode_error = { -} - - -class ModbusByteEnumField(EnumField): - __slots__ = "defEnum" - - def __init__(self, name, default, enum, defEnum): - EnumField.__init__(self, name, default, enum, "B") - defEnum = self.defEnum = defEnum - - def i2repr_one(self, pkt, x): - if self not in conf.noenum and not isinstance(x, VolatileValue) \ - and x in self.i2s: - return self.i2s[x] - if self.defEnum: - return self.defEnum - return repr(x) - - -class ModbusPDUUserDefinedFunctionCodeRequest(Packet): - name = "User-Defined Function Code Request" - fields_desc = [ - ModbusByteEnumField( - "funcCode", 0x00, _userdefined_funccode_request, - "Unknown user-defined request function Code"), - StrFixedLenField('payload', '', 255), ] - - def extract_padding(self, s): - return b"", None - - def mysummary(self): - return self.sprintf("Modbus User-Defined Request %funcCode%") - - -class ModbusPDUUserDefinedFunctionCodeResponse(Packet): - name = "User-Defined Function Code Response" - fields_desc = [ - ModbusByteEnumField( - "funcCode", 0x00, _userdefined_funccode_response, - "Unknown user-defined response function Code"), - StrFixedLenField('payload', '', 255), ] - - def extract_padding(self, s): - return b"", None - - def mysummary(self): - return self.sprintf("Modbus User-Defined Response %funcCode%") - - -class ModbusPDUUserDefinedFunctionCodeError(Packet): - name = "User-Defined Function Code Error" - fields_desc = [ - ModbusByteEnumField( - "funcCode", 0x00, _userdefined_funccode_error, - "Unknown user-defined error function Code"), - StrFixedLenField('payload', '', 255), ] - - def extract_padding(self, s): - return b"", None - - def mysummary(self): - return self.sprintf("Modbus User-Defined Error %funcCode%") - - -class ModbusObjectId(Packet): - name = "Object" - fields_desc = [ByteEnumField("id", 0x00, _read_device_id_object_id), - BitFieldLenField("length", None, 8, length_of="value"), - StrLenField("value", "", length_from=lambda pkt: pkt.length)] # noqa: E501 - - def guess_payload_class(self, payload): - return ModbusObjectId - - -_modbus_request_classes = { - 0x01: ModbusPDU01ReadCoilsRequest, - 0x02: ModbusPDU02ReadDiscreteInputsRequest, - 0x03: ModbusPDU03ReadHoldingRegistersRequest, - 0x04: ModbusPDU04ReadInputRegistersRequest, - 0x05: ModbusPDU05WriteSingleCoilRequest, - 0x06: ModbusPDU06WriteSingleRegisterRequest, - 0x07: ModbusPDU07ReadExceptionStatusRequest, - 0x0F: ModbusPDU0FWriteMultipleCoilsRequest, - 0x10: ModbusPDU10WriteMultipleRegistersRequest, - 0x11: ModbusPDU11ReportSlaveIdRequest, - 0x14: ModbusPDU14ReadFileRecordRequest, - 0x15: ModbusPDU15WriteFileRecordRequest, - 0x16: ModbusPDU16MaskWriteRegisterRequest, - 0x17: ModbusPDU17ReadWriteMultipleRegistersRequest, - 0x18: ModbusPDU18ReadFIFOQueueRequest, -} -_modbus_error_classes = { - 0x81: ModbusPDU01ReadCoilsError, - 0x82: ModbusPDU02ReadDiscreteInputsError, - 0x83: ModbusPDU03ReadHoldingRegistersError, - 0x84: ModbusPDU04ReadInputRegistersError, - 0x85: ModbusPDU05WriteSingleCoilError, - 0x86: ModbusPDU06WriteSingleRegisterError, - 0x87: ModbusPDU07ReadExceptionStatusError, - 0x8F: ModbusPDU0FWriteMultipleCoilsError, - 0x90: ModbusPDU10WriteMultipleRegistersError, - 0x91: ModbusPDU11ReportSlaveIdError, - 0x94: ModbusPDU14ReadFileRecordError, - 0x95: ModbusPDU15WriteFileRecordError, - 0x96: ModbusPDU16MaskWriteRegisterError, - 0x97: ModbusPDU17ReadWriteMultipleRegistersError, - 0x98: ModbusPDU18ReadFIFOQueueError, - 0xAB: ModbusPDU2B0EReadDeviceIdentificationError, -} -_modbus_response_classes = { - 0x01: ModbusPDU01ReadCoilsResponse, - 0x02: ModbusPDU02ReadDiscreteInputsResponse, - 0x03: ModbusPDU03ReadHoldingRegistersResponse, - 0x04: ModbusPDU04ReadInputRegistersResponse, - 0x05: ModbusPDU05WriteSingleCoilResponse, - 0x06: ModbusPDU06WriteSingleRegisterResponse, - 0x07: ModbusPDU07ReadExceptionStatusResponse, - 0x0F: ModbusPDU0FWriteMultipleCoilsResponse, - 0x10: ModbusPDU10WriteMultipleRegistersResponse, - 0x11: ModbusPDU11ReportSlaveIdResponse, - 0x14: ModbusPDU14ReadFileRecordResponse, - 0x15: ModbusPDU15WriteFileRecordResponse, - 0x16: ModbusPDU16MaskWriteRegisterResponse, - 0x17: ModbusPDU17ReadWriteMultipleRegistersResponse, - 0x18: ModbusPDU18ReadFIFOQueueResponse, -} -_mei_types_request = { - 0x0E: ModbusPDU2B0EReadDeviceIdentificationRequest, - # 0x0D: ModbusPDU2B0DCANOpenGeneralReferenceRequest, -} -_mei_types_response = { - 0x0E: ModbusPDU2B0EReadDeviceIdentificationResponse, - # 0x0D: ModbusPDU2B0DCANOpenGeneralReferenceResponse, -} - - -class ModbusADURequest(Packet): - name = "ModbusADU" - fields_desc = [XShortField("transId", 0x0000), # needs to be unique - XShortField("protoId", 0x0000), # needs to be zero (Modbus) - ShortField("len", None), # is calculated with payload - XByteField("unitId", 0xff)] # 0xFF (recommended as non-significant value) or 0x00 # noqa: E501 - - def guess_payload_class(self, payload): - function_code = orb(payload[0]) - - if function_code == 0x2B: - sub_code = orb(payload[1]) - try: - return _mei_types_request[sub_code] - except KeyError: - pass - try: - return _modbus_request_classes[function_code] - except KeyError: - pass - if function_code in _reserved_funccode_request: - return ModbusPDUReservedFunctionCodeRequest - return ModbusPDUUserDefinedFunctionCodeRequest - - def post_build(self, p, pay): - if self.len is None: - tmp_len = len(pay) + 1 # +len(p) - p = p[:4] + struct.pack("!H", tmp_len) + p[6:] - return p + pay - - -class ModbusADUResponse(Packet): - name = "ModbusADU" - fields_desc = [XShortField("transId", 0x0000), # needs to be unique - XShortField("protoId", 0x0000), # needs to be zero (Modbus) - ShortField("len", None), # is calculated with payload - XByteField("unitId", 0xff)] # 0xFF or 0x00 should be used for Modbus over TCP/IP # noqa: E501 - - def guess_payload_class(self, payload): - function_code = orb(payload[0]) - - if function_code == 0x2B: - sub_code = orb(payload[1]) - try: - return _mei_types_response[sub_code] - except KeyError: - pass - try: - return _modbus_response_classes[function_code] - except KeyError: - pass - try: - return _modbus_error_classes[function_code] - except KeyError: - pass - if function_code in _reserved_funccode_response: - return ModbusPDUReservedFunctionCodeResponse - elif function_code in _reserved_funccode_error: - return ModbusPDUReservedFunctionCodeError - if function_code < 0x80: - return ModbusPDUUserDefinedFunctionCodeResponse - return ModbusPDUUserDefinedFunctionCodeError - - def post_build(self, p, pay): - if self.len is None: - tmp_len = len(pay) + 1 # +len(p) - p = p[:4] + struct.pack("!H", tmp_len) + p[6:] - return p + pay - - -bind_layers(TCP, ModbusADURequest, dport=502) -bind_layers(TCP, ModbusADUResponse, sport=502) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/mpls.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/mpls.py deleted file mode 100644 index e5235b4bee..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/mpls.py +++ /dev/null @@ -1,74 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = Multiprotocol Label Switching (MPLS) -# scapy.contrib.status = loads - -from scapy.packet import Packet, bind_layers, Padding -from scapy.fields import BitField, ByteField, ShortField -from scapy.layers.inet import IP, UDP -from scapy.contrib.bier import BIER -from scapy.layers.inet6 import IPv6 -from scapy.layers.l2 import Ether, GRE -from scapy.compat import orb - - -class EoMCW(Packet): - name = "EoMCW" - fields_desc = [BitField("zero", 0, 4), - BitField("reserved", 0, 12), - ShortField("seq", 0)] - - def guess_payload_class(self, payload): - if len(payload) >= 1: - return Ether - return Padding - - -class MPLS(Packet): - name = "MPLS" - fields_desc = [BitField("label", 3, 20), - BitField("cos", 0, 3), - BitField("s", 1, 1), - ByteField("ttl", 0)] - - def guess_payload_class(self, payload): - if len(payload) >= 1: - if not self.s: - return MPLS - ip_version = (orb(payload[0]) >> 4) & 0xF - if ip_version == 4: - return IP - elif ip_version == 5: - return BIER - elif ip_version == 6: - return IPv6 - else: - if orb(payload[0]) == 0 and orb(payload[1]) == 0: - return EoMCW - else: - return Ether - return Padding - - -bind_layers(Ether, MPLS, type=0x8847) -bind_layers(IP, MPLS, proto=137) -bind_layers(IPv6, MPLS, nh=137) -bind_layers(UDP, MPLS, dport=6635) -bind_layers(GRE, MPLS, proto=0x8847) -bind_layers(MPLS, MPLS, s=0) -bind_layers(MPLS, IP, label=0) # IPv4 Explicit NULL -bind_layers(MPLS, IPv6, label=2) # IPv6 Explicit NULL -bind_layers(MPLS, EoMCW) -bind_layers(EoMCW, Ether, zero=0, reserved=0) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/mqtt.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/mqtt.py deleted file mode 100644 index 01cc111c2c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/mqtt.py +++ /dev/null @@ -1,273 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Santiago Hernandez Ramos -# This program is published under GPLv2 license - -# scapy.contrib.description = Message Queuing Telemetry Transport (MQTT) -# scapy.contrib.status = loads - -from scapy.packet import Packet, bind_layers -from scapy.fields import FieldLenField, BitEnumField, StrLenField, \ - ShortField, ConditionalField, ByteEnumField, ByteField, StrNullField -from scapy.layers.inet import TCP -from scapy.error import Scapy_Exception -from scapy.compat import orb, chb -from scapy.volatile import RandNum - - -# CUSTOM FIELDS -# source: http://stackoverflow.com/a/43717630 -class VariableFieldLenField(FieldLenField): - def addfield(self, pkt, s, val): - val = self.i2m(pkt, val) - data = [] - while val: - if val > 127: - data.append(val & 127) - val //= 128 - else: - data.append(val) - lastoffset = len(data) - 1 - data = b"".join(chb(val | (0 if i == lastoffset else 128)) - for i, val in enumerate(data)) - return s + data - if len(data) > 3: - raise Scapy_Exception("%s: malformed length field" % - self.__class__.__name__) - # If val is None / 0 - return s + b"\x00" - - def getfield(self, pkt, s): - value = 0 - for offset, curbyte in enumerate(s): - curbyte = orb(curbyte) - value += (curbyte & 127) * (128 ** offset) - if curbyte & 128 == 0: - return s[offset + 1:], value - if offset > 2: - raise Scapy_Exception("%s: malformed length field" % - self.__class__.__name__) - - def randval(self): - return RandVariableFieldLen() - - -class RandVariableFieldLen(RandNum): - def __init__(self): - RandNum.__init__(self, 0, 268435455) - - -# LAYERS -CONTROL_PACKET_TYPE = {1: 'CONNECT', - 2: 'CONNACK', - 3: 'PUBLISH', - 4: 'PUBACK', - 5: 'PUBREC', - 6: 'PUBREL', - 7: 'PUBCOMP', - 8: 'SUBSCRIBE', - 9: 'SUBACK', - 10: 'UNSUBSCRIBE', - 11: 'UNSUBACK', - 12: 'PINGREQ', - 13: 'PINGRESP', - 14: 'DISCONNECT'} - - -QOS_LEVEL = {0: 'At most once delivery', - 1: 'At least once delivery', - 2: 'Exactly once delivery'} - - -# source: http://stackoverflow.com/a/43722441 -class MQTT(Packet): - name = "MQTT fixed header" - fields_desc = [ - BitEnumField("type", 1, 4, CONTROL_PACKET_TYPE), - BitEnumField("DUP", 0, 1, {0: 'Disabled', - 1: 'Enabled'}), - BitEnumField("QOS", 0, 2, QOS_LEVEL), - BitEnumField("RETAIN", 0, 1, {0: 'Disabled', - 1: 'Enabled'}), - # Since the size of the len field depends on the next layer, we need - # to "cheat" with the length_of parameter and use adjust parameter to - # calculate the value. - VariableFieldLenField("len", None, length_of="len", - adjust=lambda pkt, x: len(pkt.payload),), - ] - - -class MQTTConnect(Packet): - name = "MQTT connect" - fields_desc = [ - FieldLenField("length", None, length_of="protoname"), - StrLenField("protoname", "", - length_from=lambda pkt: pkt.length), - ByteField("protolevel", 0), - BitEnumField("usernameflag", 0, 1, {0: 'Disabled', - 1: 'Enabled'}), - BitEnumField("passwordflag", 0, 1, {0: 'Disabled', - 1: 'Enabled'}), - BitEnumField("willretainflag", 0, 1, {0: 'Disabled', - 1: 'Enabled'}), - BitEnumField("willQOSflag", 0, 2, QOS_LEVEL), - BitEnumField("willflag", 0, 1, {0: 'Disabled', - 1: 'Enabled'}), - BitEnumField("cleansess", 0, 1, {0: 'Disabled', - 1: 'Enabled'}), - BitEnumField("reserved", 0, 1, {0: 'Disabled', - 1: 'Enabled'}), - ShortField("klive", 0), - FieldLenField("clientIdlen", None, length_of="clientId"), - StrLenField("clientId", "", - length_from=lambda pkt: pkt.clientIdlen), - # Payload with optional fields depending on the flags - ConditionalField(FieldLenField("wtoplen", None, length_of="willtopic"), - lambda pkt: pkt.willflag == 1), - ConditionalField(StrLenField("willtopic", "", - length_from=lambda pkt: pkt.wtoplen), - lambda pkt: pkt.willflag == 1), - ConditionalField(FieldLenField("wmsglen", None, length_of="willmsg"), - lambda pkt: pkt.willflag == 1), - ConditionalField(StrLenField("willmsg", "", - length_from=lambda pkt: pkt.wmsglen), - lambda pkt: pkt.willflag == 1), - ConditionalField(FieldLenField("userlen", None, length_of="username"), - lambda pkt: pkt.usernameflag == 1), - ConditionalField(StrLenField("username", "", - length_from=lambda pkt: pkt.userlen), - lambda pkt: pkt.usernameflag == 1), - ConditionalField(FieldLenField("passlen", None, length_of="password"), - lambda pkt: pkt.passwordflag == 1), - ConditionalField(StrLenField("password", "", - length_from=lambda pkt: pkt.passlen), - lambda pkt: pkt.passwordflag == 1), - ] - - -RETURN_CODE = {0: 'Connection Accepted', - 1: 'Unacceptable protocol version', - 2: 'Identifier rejected', - 3: 'Server unavailable', - 4: 'Bad username/password', - 5: 'Not authorized'} - - -class MQTTConnack(Packet): - name = "MQTT connack" - fields_desc = [ - ByteField("sessPresentFlag", 0), - ByteEnumField("retcode", 0, RETURN_CODE), - # this package has not payload - ] - - -class MQTTPublish(Packet): - name = "MQTT publish" - fields_desc = [ - FieldLenField("length", None, length_of="topic"), - StrLenField("topic", "", - length_from=lambda pkt: pkt.length), - ConditionalField(ShortField("msgid", None), - lambda pkt: (pkt.underlayer.QOS == 1 or - pkt.underlayer.QOS == 2)), - StrLenField("value", "", - length_from=lambda pkt: (pkt.underlayer.len - - pkt.length - 2)), - ] - - -class MQTTPuback(Packet): - name = "MQTT puback" - fields_desc = [ - ShortField("msgid", None), - ] - - -class MQTTPubrec(Packet): - name = "MQTT pubrec" - fields_desc = [ - ShortField("msgid", None), - ] - - -class MQTTPubrel(Packet): - name = "MQTT pubrel" - fields_desc = [ - ShortField("msgid", None), - ] - - -class MQTTPubcomp(Packet): - name = "MQTT pubcomp" - fields_desc = [ - ShortField("msgid", None), - ] - - -class MQTTSubscribe(Packet): - name = "MQTT subscribe" - fields_desc = [ - ShortField("msgid", None), - FieldLenField("length", None, length_of="topic"), - StrLenField("topic", "", - length_from=lambda pkt: pkt.length), - ByteEnumField("QOS", 0, QOS_LEVEL), - ] - - -ALLOWED_RETURN_CODE = {0: 'Success', - 1: 'Success', - 2: 'Success', - 128: 'Failure'} - - -class MQTTSuback(Packet): - name = "MQTT suback" - fields_desc = [ - ShortField("msgid", None), - ByteEnumField("retcode", None, ALLOWED_RETURN_CODE) - ] - - -class MQTTUnsubscribe(Packet): - name = "MQTT unsubscribe" - fields_desc = [ - ShortField("msgid", None), - StrNullField("payload", "") - ] - - -class MQTTUnsuback(Packet): - name = "MQTT unsuback" - fields_desc = [ - ShortField("msgid", None) - ] - - -# LAYERS BINDINGS - -bind_layers(TCP, MQTT, sport=1883) -bind_layers(TCP, MQTT, dport=1883) -bind_layers(MQTT, MQTTConnect, type=1) -bind_layers(MQTT, MQTTConnack, type=2) -bind_layers(MQTT, MQTTPublish, type=3) -bind_layers(MQTT, MQTTPuback, type=4) -bind_layers(MQTT, MQTTPubrec, type=5) -bind_layers(MQTT, MQTTPubrel, type=6) -bind_layers(MQTT, MQTTPubcomp, type=7) -bind_layers(MQTT, MQTTSubscribe, type=8) -bind_layers(MQTT, MQTTSuback, type=9) -bind_layers(MQTT, MQTTUnsubscribe, type=10) -bind_layers(MQTT, MQTTUnsuback, type=11) -bind_layers(MQTTConnect, MQTT) -bind_layers(MQTTConnack, MQTT) -bind_layers(MQTTPublish, MQTT) -bind_layers(MQTTPuback, MQTT) -bind_layers(MQTTPubrec, MQTT) -bind_layers(MQTTPubrel, MQTT) -bind_layers(MQTTPubcomp, MQTT) -bind_layers(MQTTSubscribe, MQTT) -bind_layers(MQTTSuback, MQTT) -bind_layers(MQTTUnsubscribe, MQTT) -bind_layers(MQTTUnsuback, MQTT) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/mqttsn.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/mqttsn.py deleted file mode 100644 index df74805e03..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/mqttsn.py +++ /dev/null @@ -1,469 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) 2019 Freie Universitaet Berlin -# This program is published under GPLv2 license -# -# Specification: -# http://www.mqtt.org/new/wp-content/uploads/2009/06/MQTT-SN_spec_v1.2.pdf - -# scapy.contrib.description = MQTT for Sensor Networks (MQTT-SN) -# scapy.contrib.status = loads - -from scapy.packet import Packet, bind_layers, bind_bottom_up -from scapy.fields import BitField, BitEnumField, ByteField, ByteEnumField, \ - ConditionalField, FieldLenField, ShortField, StrFixedLenField, \ - StrLenField, XByteEnumField -from scapy.layers.inet import UDP -from scapy.error import Scapy_Exception -from scapy.compat import chb, orb -from scapy.volatile import RandNum -import struct - - -# Constants -ADVERTISE = 0x00 -SEARCHGW = 0x01 -GWINFO = 0x02 -CONNECT = 0x04 -CONNACK = 0x05 -WILLTOPICREQ = 0x06 -WILLTOPIC = 0x07 -WILLMSGREQ = 0x08 -WILLMSG = 0x09 -REGISTER = 0x0a -REGACK = 0x0b -PUBLISH = 0x0c -PUBACK = 0x0d -PUBCOMP = 0x0e -PUBREC = 0x0f -PUBREL = 0x10 -SUBSCRIBE = 0x12 -SUBACK = 0x13 -UNSUBSCRIBE = 0x14 -UNSUBACK = 0x15 -PINGREQ = 0x16 -PINGRESP = 0x17 -DISCONNECT = 0x18 -WILLTOPICUPD = 0x1a -WILLTOPICRESP = 0x1b -WILLMSGUPD = 0x1c -WILLMSGRESP = 0x1d -ENCAPS_MSG = 0xfe - -QOS_0 = 0b00 -QOS_1 = 0b01 -QOS_2 = 0b10 -QOS_NEG1 = 0b11 - -TID_NORMAL = 0b00 -TID_PREDEF = 0b01 -TID_SHORT = 0b10 -TID_RESVD = 0b11 - - -ACCEPTED = 0x00 -REJ_CONJ = 0x01 -REJ_TID = 0x02 -REJ_NOTSUP = 0x03 - - -# Custom fields -class VariableFieldLenField(FieldLenField): - """ - MQTT-SN length field either has 1 byte for values [0x02, 0xff] or 3 bytes - for values [0x0100, 0xffff]. If the first byte is 0x01 the length value - comes in network byte-order in the next 2 bytes. MQTT-SN packets are at - least 2 bytes long (length field + type field). - """ - def addfield(self, pkt, s, val): - val = self.i2m(pkt, val) - if (val < 2) or (val > 0xffff): - raise Scapy_Exception("%s: invalid length field value" % - self.__class__.__name__) - elif val > 0xff: - return s + b"\x01" + struct.pack("!H", val) - else: - return s + chb(val) - - def getfield(self, pkt, s): - if orb(s[0]) == 0x01: - if len(s) < 3: - raise Scapy_Exception("%s: malformed length field" % - self.__class__.__name__) - return s[3:], (orb(s[1]) << 8) | orb(s[2]) - else: - return s[1:], orb(s[0]) - - def randval(self): - return RandVariableFieldLen() - - def __init__(self, *args, **kwargs): - super(VariableFieldLenField, self).__init__(*args, **kwargs) - - -class RandVariableFieldLen(RandNum): - def __init__(self): - super(RandVariableFieldLen, self).__init__(0, 0xffff) - - -# Layers -PACKET_TYPE = { - ADVERTISE: "ADVERTISE", - SEARCHGW: "SEARCHGW", - GWINFO: "GWINFO", - CONNECT: "CONNECT", - CONNACK: "CONNACK", - WILLTOPICREQ: "WILLTOPICREQ", - WILLTOPIC: "WILLTOPIC", - WILLMSGREQ: "WILLMSGREQ", - WILLMSG: "WILLMSG", - REGISTER: "REGISTER", - REGACK: "REGACK", - PUBLISH: "PUBLISH", - PUBACK: "PUBACK", - PUBCOMP: "PUBCOMP", - PUBREC: "PUBREC", - PUBREL: "PUBREL", - SUBSCRIBE: "SUBSCRIBE", - SUBACK: "SUBACK", - UNSUBSCRIBE: "UNSUBSCRIBE", - UNSUBACK: "UNSUBACK", - PINGREQ: "PINGREQ", - PINGRESP: "PINGRESP", - DISCONNECT: "DISCONNECT", - WILLTOPICUPD: "WILLTOPICUPD", - WILLTOPICRESP: "WILLTOPICRESP", - WILLMSGUPD: "WILLMSGUPD", - WILLMSGRESP: "WILLMSGRESP", - ENCAPS_MSG: "Encapsulated message", -} - - -QOS_LEVELS = { - QOS_0: 'Fire and Forget', - QOS_1: 'Acknowledged deliver', - QOS_2: 'Assured Delivery', - QOS_NEG1: 'No Connection required', -} - - -TOPIC_ID_TYPES = { - TID_NORMAL: 'Normal ID', - TID_PREDEF: 'Pre-defined ID', - TID_SHORT: 'Short Topic Name', - TID_RESVD: 'Reserved', -} - - -RETURN_CODES = { - ACCEPTED: "Accepted", - REJ_CONJ: "Rejected: congestion", - REJ_TID: "Rejected: invalid topic ID", - REJ_NOTSUP: "Rejected: not supported", -} - - -FLAG_FIELDS = [ - BitField("dup", 0, 1), - BitEnumField("qos", QOS_0, 2, QOS_LEVELS), - BitField("retain", 0, 1), - BitField("will", 0, 1), - BitField("cleansess", 0, 1), - BitEnumField("tid_type", TID_NORMAL, 2, TOPIC_ID_TYPES), -] - - -def _mqttsn_length_from(size_until): - def fun(pkt): - if (hasattr(pkt.underlayer, "len")): - if pkt.underlayer.len > 0xff: - return pkt.underlayer.len - size_until - 4 - elif (pkt.underlayer.len > 1) and (pkt.underlayer.len < 0xffff): - return pkt.underlayer.len - size_until - 2 - # assume string to be of length 0 - return len(pkt.payload) - size_until + 1 - return fun - - -def _mqttsn_len_adjust(pkt, x): - res = x + len(pkt.payload) - if (pkt.type == DISCONNECT) and \ - (getattr(pkt.payload, "duration", None) is None): - res -= 2 # duration is optional with DISCONNECT - elif (pkt.type == ENCAPS_MSG) and \ - (getattr(pkt.payload, "w_node_id", None) is not None): - res = x + len(pkt.payload.w_node_id) + 1 - if res > 0xff: - res += 2 - return res - - -class MQTTSN(Packet): - name = "MQTT-SN header" - fields_desc = [ - # Since the size of the len field depends on the next layer, we - # need to "cheat" with the length_of parameter and use adjust - # parameter to calculate the value. - VariableFieldLenField("len", None, length_of="len", - adjust=_mqttsn_len_adjust), - XByteEnumField("type", 0, PACKET_TYPE), - ] - - -class MQTTSNAdvertise(Packet): - name = "MQTT-SN advertise gateway" - fields_desc = [ - ByteField("gw_id", 0), - ShortField("duration", 0), - ] - - -class MQTTSNSearchGW(Packet): - name = "MQTT-SN search gateway" - fields_desc = [ - ByteField("radius", 0), - ] - - -class MQTTSNGwInfo(Packet): - name = "MQTT-SN gateway info" - fields_desc = [ - ByteField("gw_id", 0), - StrLenField("gw_addr", "", length_from=_mqttsn_length_from(1)), - ] - - -class MQTTSNConnect(Packet): - name = "MQTT-SN connect command" - fields_desc = FLAG_FIELDS + [ - ByteField("prot_id", 1), - ShortField("duration", 0), - StrLenField("client_id", "", length_from=_mqttsn_length_from(4)), - ] - - -class MQTTSNConnack(Packet): - name = "MQTT-SN connect ACK" - fields_desc = [ - ByteEnumField("return_code", ACCEPTED, RETURN_CODES), - ] - - -class MQTTSNWillTopicReq(Packet): - name = "MQTT-SN will topic request" - - -class MQTTSNWillTopic(Packet): - name = "MQTT-SN will topic" - fields_desc = FLAG_FIELDS + [ - StrLenField("will_topic", "", length_from=_mqttsn_length_from(1)), - ] - - -class MQTTSNWillMsgReq(Packet): - name = "MQTT-SN will message request" - - -class MQTTSNWillMsg(Packet): - name = "MQTT-SN will message" - fields_desc = [ - StrLenField("will_msg", "", length_from=_mqttsn_length_from(0)) - ] - - -class MQTTSNRegister(Packet): - name = "MQTT-SN register" - fields_desc = [ - ShortField("tid", 0), - ShortField("mid", 0), - StrLenField("topic_name", "", length_from=_mqttsn_length_from(4)), - ] - - -class MQTTSNRegack(Packet): - name = "MQTT-SN register ACK" - fields_desc = [ - ShortField("tid", 0), - ShortField("mid", 0), - ByteEnumField("return_code", ACCEPTED, RETURN_CODES), - ] - - -class MQTTSNPublish(Packet): - name = "MQTT-SN publish message" - fields_desc = FLAG_FIELDS + [ - ShortField("tid", 0), - ShortField("mid", 0), - StrLenField("data", "", length_from=_mqttsn_length_from(5)), - ] - - -class MQTTSNPuback(Packet): - name = "MQTT-SN publish ACK" - fields_desc = [ - ShortField("tid", 0), - ShortField("mid", 0), - ByteEnumField("return_code", ACCEPTED, RETURN_CODES), - ] - - -class MQTTSNPubcomp(Packet): - name = "MQTT-SN publish complete" - fields_desc = [ - ShortField("mid", 0), - ] - - -class MQTTSNPubrec(Packet): - name = "MQTT-SN publish received" - fields_desc = [ - ShortField("mid", 0), - ] - - -class MQTTSNPubrel(Packet): - name = "MQTT-SN publish release" - fields_desc = [ - ShortField("mid", 0), - ] - - -class MQTTSNSubscribe(Packet): - name = "MQTT-SN subscribe request" - fields_desc = FLAG_FIELDS + [ - ShortField("mid", 0), - ConditionalField(ShortField("tid", None), - lambda pkt: pkt.tid_type == 0b01), - ConditionalField(StrFixedLenField("short_topic", None, length=2), - lambda pkt: pkt.tid_type == 0b10), - ConditionalField(StrLenField("topic_name", None, - length_from=_mqttsn_length_from(3)), - lambda pkt: pkt.tid_type not in [0b01, 0b10]), - ] - - -class MQTTSNSuback(Packet): - name = "MQTT-SN subscribe ACK" - fields_desc = FLAG_FIELDS + [ - ShortField("tid", 0), - ShortField("mid", 0), - ByteEnumField("return_code", ACCEPTED, RETURN_CODES), - ] - - -class MQTTSNUnsubscribe(Packet): - name = "MQTT-SN unsubscribe request" - fields_desc = FLAG_FIELDS + [ - ShortField("mid", 0), - ConditionalField(ShortField("tid", None), - lambda pkt: pkt.tid_type == 0b01), - ConditionalField(StrFixedLenField("short_topic", None, length=2), - lambda pkt: pkt.tid_type == 0b10), - ConditionalField(StrLenField("topic_name", None, - length_from=_mqttsn_length_from(3)), - lambda pkt: pkt.tid_type not in [0b01, 0b10]), - ] - - -class MQTTSNUnsuback(Packet): - name = "MQTT-SN unsubscribe ACK" - fields_desc = [ - ShortField("mid", 0), - ] - - -class MQTTSNPingReq(Packet): - name = "MQTT-SN ping request" - fields_desc = [ - StrLenField("client_id", "", length_from=_mqttsn_length_from(0)), - ] - - -class MQTTSNPingResp(Packet): - name = "MQTT-SN ping response" - - -class MQTTSNDisconnect(Packet): - name = "MQTT-SN disconnect request" - fields_desc = [ - ConditionalField( - ShortField("duration", None), - lambda pkt: hasattr(pkt.underlayer, "len") and - ((pkt.underlayer.len is None) or (pkt.underlayer.len > 2)) - ), - ] - - -class MQTTSNWillTopicUpd(Packet): - name = "MQTT-SN will topic update" - fields_desc = FLAG_FIELDS + [ - StrLenField("will_topic", "", length_from=_mqttsn_length_from(1)), - ] - - -class MQTTSNWillTopicResp(Packet): - name = "MQTT-SN will topic response" - fields_desc = [ - ByteEnumField("return_code", ACCEPTED, RETURN_CODES), - ] - - -class MQTTSNWillMsgUpd(Packet): - name = "MQTT-SN will message update" - fields_desc = [ - StrLenField("will_msg", "", length_from=_mqttsn_length_from(0)) - ] - - -class MQTTSNWillMsgResp(Packet): - name = "MQTT-SN will message response" - fields_desc = [ - ByteEnumField("return_code", ACCEPTED, RETURN_CODES), - ] - - -class MQTTSNEncaps(Packet): - name = "MQTT-SN encapsulated message" - fields_desc = [ - BitField("resvd", 0, 6), - BitField("radius", 0, 2), - StrLenField( - "w_node_id", "", - length_from=_mqttsn_length_from(1) - ), - ] - - -# Layer bindings -bind_bottom_up(UDP, MQTTSN, sport=1883) -bind_bottom_up(UDP, MQTTSN, dport=1883) -bind_layers(UDP, MQTTSN, dport=1883, sport=1883) -bind_layers(MQTTSN, MQTTSNAdvertise, type=ADVERTISE) -bind_layers(MQTTSN, MQTTSNSearchGW, type=SEARCHGW) -bind_layers(MQTTSN, MQTTSNGwInfo, type=GWINFO) -bind_layers(MQTTSN, MQTTSNConnect, type=CONNECT) -bind_layers(MQTTSN, MQTTSNConnack, type=CONNACK) -bind_layers(MQTTSN, MQTTSNWillTopicReq, type=WILLTOPICREQ) -bind_layers(MQTTSN, MQTTSNWillTopic, type=WILLTOPIC) -bind_layers(MQTTSN, MQTTSNWillMsgReq, type=WILLMSGREQ) -bind_layers(MQTTSN, MQTTSNWillMsg, type=WILLMSG) -bind_layers(MQTTSN, MQTTSNRegister, type=REGISTER) -bind_layers(MQTTSN, MQTTSNRegack, type=REGACK) -bind_layers(MQTTSN, MQTTSNPublish, type=PUBLISH) -bind_layers(MQTTSN, MQTTSNPuback, type=PUBACK) -bind_layers(MQTTSN, MQTTSNPubcomp, type=PUBCOMP) -bind_layers(MQTTSN, MQTTSNPubrec, type=PUBREC) -bind_layers(MQTTSN, MQTTSNPubrel, type=PUBREL) -bind_layers(MQTTSN, MQTTSNSubscribe, type=SUBSCRIBE) -bind_layers(MQTTSN, MQTTSNSuback, type=SUBACK) -bind_layers(MQTTSN, MQTTSNUnsubscribe, type=UNSUBSCRIBE) -bind_layers(MQTTSN, MQTTSNUnsuback, type=UNSUBACK) -bind_layers(MQTTSN, MQTTSNPingReq, type=PINGREQ) -bind_layers(MQTTSN, MQTTSNPingResp, type=PINGRESP) -bind_layers(MQTTSN, MQTTSNDisconnect, type=DISCONNECT) -bind_layers(MQTTSN, MQTTSNWillTopicUpd, type=WILLTOPICUPD) -bind_layers(MQTTSN, MQTTSNWillTopicResp, type=WILLTOPICRESP) -bind_layers(MQTTSN, MQTTSNWillMsgUpd, type=WILLMSGUPD) -bind_layers(MQTTSN, MQTTSNWillMsgResp, type=WILLMSGRESP) -bind_layers(MQTTSN, MQTTSNEncaps, type=ENCAPS_MSG) -bind_layers(MQTTSNEncaps, MQTTSN) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/nsh.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/nsh.py deleted file mode 100644 index 57ca029036..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/nsh.py +++ /dev/null @@ -1,97 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = Network Services Headers (NSH) -# scapy.contrib.status = loads - -from scapy.all import bind_layers -from scapy.fields import BitField, ByteField, ByteEnumField -from scapy.fields import ShortField, X3BytesField, XIntField -from scapy.fields import ConditionalField, PacketListField, BitFieldLenField -from scapy.layers.inet import Ether, IP -from scapy.layers.inet6 import IPv6 -from scapy.layers.vxlan import VXLAN -from scapy.packet import Packet -from scapy.layers.l2 import GRE - -from scapy.contrib.mpls import MPLS - -# -# NSH Support -# https://www.ietf.org/id/draft-ietf-sfc-nsh-05.txt -# - - -class Metadata(Packet): - name = 'NSH metadata' - fields_desc = [XIntField('value', 0)] - - -class NSHTLV(Packet): - "NSH MD-type 2 - Variable Length Context Headers" - name = "NSHTLV" - fields_desc = [ - ShortField('Class', 0), - BitField('Critical', 0, 1), - BitField('Type', 0, 7), - BitField('Reserved', 0, 3), - BitField('Len', 0, 5), - PacketListField('Metadata', None, XIntField, count_from='Len') - ] - - -class NSH(Packet): - """Network Service Header. - NSH MD-type 1 if there is no ContextHeaders""" - name = "NSH" - - fields_desc = [ - BitField('Ver', 0, 2), - BitField('OAM', 0, 1), - BitField('Critical', 0, 1), - BitField('Reserved', 0, 6), - BitFieldLenField('Len', None, 6, - count_of='ContextHeaders', - adjust=lambda pkt, x: 6 if pkt.MDType == 1 else x + 2), # noqa: E501 - ByteEnumField('MDType', 1, {1: 'Fixed Length', - 2: 'Variable Length'}), - ByteEnumField('NextProto', 3, {1: 'IPv4', - 2: 'IPv6', - 3: 'Ethernet', - 4: 'NSH', - 5: 'MPLS'}), - X3BytesField('NSP', 0), - ByteField('NSI', 1), - ConditionalField(XIntField('NPC', 0), lambda pkt: pkt.MDType == 1), - ConditionalField(XIntField('NSC', 0), lambda pkt: pkt.MDType == 1), - ConditionalField(XIntField('SPC', 0), lambda pkt: pkt.MDType == 1), - ConditionalField(XIntField('SSC', 0), lambda pkt: pkt.MDType == 1), - ConditionalField(PacketListField("ContextHeaders", None, - NSHTLV, count_from="Length"), - lambda pkt: pkt.MDType == 2) - ] - - def mysummary(self): - return self.sprintf("NSP: %NSP% - NSI: %NSI%") - - -bind_layers(Ether, NSH, {'type': 0x894F}, type=0x894F) -bind_layers(VXLAN, NSH, {'flags': 0xC, 'NextProtocol': 4}, NextProtocol=4) -bind_layers(GRE, NSH, {'proto': 0x894F}, proto=0x894F) - -bind_layers(NSH, IP, {'NextProto': 1}, NextProto=1) -bind_layers(NSH, IPv6, {'NextProto': 2}, NextProto=2) -bind_layers(NSH, Ether, {'NextProto': 3}, NextProto=3) -bind_layers(NSH, NSH, {'NextProto': 4}, NextProto=4) -bind_layers(NSH, MPLS, {'NextProto': 5}, NextProto=5) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/opc_da.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/opc_da.py deleted file mode 100644 index 887d0d99a2..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/opc_da.py +++ /dev/null @@ -1,1492 +0,0 @@ -# coding: utf8 - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software FounDation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# Copyright (C) -# @Author: GuillaumeF -# @Email: guillaume4favre@gmail.com -# @Date: 2016-10-18 -# @Last modified by: GuillaumeF -# @Last modified by: Sebastien Mainand -# @Last modified time: 2016-12-08 11:16:27 -# @Last modified time: 2017-07-05 - -# scapy.contrib.description = OPC Data Access -# scapy.contrib.status = loads - -""" -Opc Data Access. -References: Data Access Custom Interface StanDard -Using the website: http://pubs.opengroup.org/onlinepubs/9629399/chap12.htm - -DCOM Remote Protocol. -References: Specifies Distributed Component Object Model (DCOM) Remote Protocol -Using the website: https://msdn.microsoft.com/en-us/library/cc226801.aspx -""" - -from scapy.config import conf -from scapy.fields import Field, ByteField, ShortField, LEShortField, \ - IntField, LEIntField, LongField, LELongField, StrField, StrLenField, \ - StrFixedLenField, BitEnumField, ByteEnumField, ShortEnumField, \ - LEShortEnumField, IntEnumField, LEIntEnumField, FieldLenField, \ - LEFieldLenField, PacketField, PacketListField, PacketLenField, \ - ConditionalField, FlagsField, UUIDField -from scapy.packet import Packet - -# Defined values -_tagOPCDataSource = { - 1: "OPC_DS_CACHE", - 2: "OPC_DS_DEVICE" -} - -_tagOPCBrowseType = { - 1: "OPC_BRANCH", - 2: "OPC_LEAF", - 3: "OPC_FLAT" -} - -_tagOPCNameSpaceType = { - 1: "OPC_NS_HIERARCHIAL", - 2: "OPC_NS_FLAT" -} - -_tagOPCBrowseDirection = { - 1: "OPC_BROWSE_UP", - 2: "OPC_BROWSE_DOWN", - 3: "OPC_BROWSE_TO" -} - -_tagOPCEuType = { - 0: "OPC_NOENUM", - 1: "OPC_ANALOG", - 2: "OPC_ENUMERATED" -} - -_tagOPCServerState = { - 1: "OPC_STATUS_RUNNING", - 2: "OPC_STATUS_FAILED", - 3: "OPC_STATUS_NOCONFIG", - 4: "OPC_STATUS_SUSPENDED", - 5: "OPC_STATUS_TEST", - 6: "OPC_STATUS_COMM_FAULT" -} - -_tagOPCEnumScope = { - 1: "OPC_ENUM_PRIVATE_CONNECTIONS", - 2: "OPC_ENUM_PUBLIC_CONNECTIONS", - 3: "OPC_ENUM_ALL_CONNECTIONS", - 4: "OPC_ENUM_PRIVATE", - 5: "OPC_ENUM_PUBLIC", - 6: "OPC_ENUM_ALL" -} - -_pfc_flags = [ - "firstFragment", # First fragment - "lastFragment", # Last fragment - "pendingCancel", # Cancel was pending at sender - "reserved", # - "concurrentMultiplexing", # supports concurrent multiplexing - # of a single connection - "didNotExecute", # only meaningful on `fault' packet if true, - # guaranteed call did not execute - "maybe", # `maybe' call semantics requested - "objectUuid" # if true, a non-nil object UUID was specified - # in the handle, and is present in the optional - # object field. If false, the object field - # is omitted -] - -_faultStatus = { - 382312475: 'rpc_s_fault_object_not_found', - 382312497: 'rpc_s_call_cancelled', - 382312564: 'rpc_s_fault_addr_error', - 382312565: 'rpc_s_fault_context_mismatch', - 382312566: 'rpc_s_fault_fp_div_by_zero', - 382312567: 'rpc_s_fault_fp_error', - 382312568: 'rpc_s_fault_fp_overflow', - 382312569: 'rpc_s_fault_fp_underflow', - 382312570: 'rpc_s_fault_ill_inst', - 382312571: 'rpc_s_fault_int_div_by_zero', - 382312572: 'rpc_s_fault_int_overflow', - 382312573: 'rpc_s_fault_invalid_bound', - 382312574: 'rpc_s_fault_invalid_tag', - 382312575: 'rpc_s_fault_pipe_closed', - 382312576: 'rpc_s_fault_pipe_comm_error', - 382312577: 'rpc_s_fault_pipe_discipline', - 382312578: 'rpc_s_fault_pipe_empty', - 382312579: 'rpc_s_fault_pipe_memory', - 382312580: 'rpc_s_fault_pipe_order', - 382312582: 'rpc_s_fault_remote_no_memory', - 382312583: 'rpc_s_fault_unspec', - 382312723: 'rpc_s_fault_user_defined', - 382312726: 'rpc_s_fault_tx_open_failed', - 382312814: 'rpc_s_fault_codeset_conv_error', - 382312816: 'rpc_s_fault_no_client_stub', - 469762049: 'nca_s_fault_int_div_by_zero', - 469762050: 'nca_s_fault_addr_error', - 469762051: 'nca_s_fault_fp_div_zero', - 469762052: 'nca_s_fault_fp_underflow', - 469762053: 'nca_s_fault_fp_overflow', - 469762054: 'nca_s_fault_invalid_tag', - 469762055: 'nca_s_fault_invalid_bound', - 469762061: 'nca_s_fault_cancel', - 469762062: 'nca_s_fault_ill_inst', - 469762063: 'nca_s_fault_fp_error', - 469762064: 'nca_s_fault_int_overflow', - 469762068: 'nca_s_fault_pipe_empty', - 469762069: 'nca_s_fault_pipe_closed', - 469762070: 'nca_s_fault_pipe_order', - 469762071: 'nca_s_fault_pipe_discipline', - 469762072: 'nca_s_fault_pipe_comm_error', - 469762073: 'nca_s_fault_pipe_memory', - 469762074: 'nca_s_fault_context_mismatch', - 469762075: 'nca_s_fault_remote_no_memory', - 469762081: 'ncs_s_fault_user_defined', - 469762082: 'nca_s_fault_tx_open_failed', - 469762083: 'nca_s_fault_codeset_conv_error', - 469762084: 'nca_s_fault_object_not_found', - 469762085: 'nca_s_fault_no_client_stub', -} - -_defResult = { - 0: 'ACCEPTANCE', - 1: 'USER_REJECTION', - 2: 'PROVIDER_REJECTION', -} - -_defReason = { - 0: 'REASON_NOT_SPECIFIED', - 1: 'ABSTRACT_SYNTAX_NOT_SUPPORTED', - 2: 'PROPOSED_TRANSFER_SYNTAXES_NOT_SUPPORTED', - 3: 'LOCAL_LIMIT_EXCEEDED', -} - -_rejectBindNack = { - 0: 'REASON_NOT_SPECIFIED', - 1: 'TEMPORARY_CONGESTION', - 2: 'LOCAL_LIMIT_EXCEEDED', - 3: 'CALLED_PADDR_UNKNOWN', - 4: 'PROTOCOL_VERSION_NOT_SUPPORTED', - 5: 'DEFAULT_CONTEXT_NOT_SUPPORTED', - 6: 'USER_DATA_NOT_READABLE', - 7: 'NO_PSAP_AVAILABLE' -} - -_rejectStatus = { - 469762056: 'nca_rpc_version_mismatch', - 469762057: 'nca_unspec_reject', - 469762058: 'nca_s_bad_actid', - 469762059: 'nca_who_are_you_failed', - 469762060: 'nca_manager_not_entered', - 469827586: 'nca_op_rng_error', - 469827587: 'nca_unk_if', - 469827590: 'nca_wrong_boot_time', - 469827593: 'nca_s_you_crashed', - 469827595: 'nca_proto_error', - 469827603: 'nca_out_args_too_big', - 469827604: 'nca_server_too_busy', - 469827607: 'nca_unsupported_type', - 469762076: 'nca_invalid_pres_context_id', - 469762077: 'nca_unsupported_authn_level', - 469762079: 'nca_invalid_checksum', - 469762080: 'nca_invalid_crc' -} - -_pduType = { - 0: "REQUEST", - 1: "PING", - 2: "RESPONSE", - 3: "FAULT", - 4: "WORKING", - 5: "NOCALL", - 6: "REJECT", - 7: "ACK", - 8: "CI_CANCEL", - 9: "FACK", - 10: "CANCEL_ACK", - 11: "BIND", - 12: "BIND_ACK", - 13: "BIND_NACK", - 14: "ALTER_CONTEXT", - 15: "ALTER_CONTEXT_RESP", - 17: "SHUTDOWN", - 18: "CO_CANCEL", - 19: "ORPHANED", - # Not documented - 16: "Auth3", -} - -_authentification_protocol = { - 0: 'None', - 1: 'OsfDcePrivateKeyAuthentication', -} - - -# Sub class for dissection -class AuthentificationProtocol(Packet): - name = 'authentificationProtocol' - - def extract_padding(self, p): - return b"", p - - def guess_payload_class(self, payload): - if self.underlayer and hasattr(self.underlayer, "auth_length"): - auth_length = self.underlayer.auth_length - if auth_length != 0: - try: - return _authentification_protocol[auth_length] - except Exception: - pass - return conf.raw_layer - - -class OsfDcePrivateKeyAuthentification(Packet): - name = "OsfDcePrivateKeyAuthentication" - # TODO - - def extract_padding(self, p): - return b"", p - - -class OPCHandle(Packet): - def __init__(self, name, default): - Field.__init__(self, name, default, "16s") - - def extract_padding(self, p): - return b"", p - - -class LenStringPacket(Packet): - name = "len string packet" - fields_desc = [ - FieldLenField('length', 0, length_of='data', fmt="H"), - ConditionalField(StrLenField('data', None, - length_from=lambda pkt:pkt.length + 2), - lambda pkt:pkt.length == 0), - ConditionalField(StrLenField('data', '', - length_from=lambda pkt:pkt.length), - lambda pkt:pkt.length != 0), - ] - - def extract_padding(self, p): - return b"", p - - -class LenStringPacketLE(Packet): - name = "len string packet" - fields_desc = [ - LEFieldLenField('length', 0, length_of='data', fmt=" -# This program is published under a GPLv2 license - -# Copyright (C) 2014 Maxence Tury -# OpenFlow is an open standard used in SDN deployments. -# Based on OpenFlow v1.0.1 -# Specifications can be retrieved from https://www.opennetworking.org/ - -# scapy.contrib.description = Openflow v1.0 -# scapy.contrib.status = loads - -from __future__ import absolute_import -import struct - - -from scapy.compat import chb, orb, raw -from scapy.config import conf -from scapy.error import warning -from scapy.fields import BitEnumField, BitField, ByteEnumField, ByteField, FieldLenField, FlagsField, IntEnumField, IntField, IPField, LongField, MACField, PacketField, PacketListField, ShortEnumField, ShortField, StrFixedLenField, X3BytesField, XBitField, XByteField, XIntField, XShortField # noqa: E501 -from scapy.layers.l2 import Ether -from scapy.layers.inet import TCP -from scapy.packet import Packet, Raw, bind_bottom_up, bind_top_down -from scapy.utils import binrepr -from scapy.modules import six - - -# If prereq_autocomplete is True then match prerequisites will be -# automatically handled. See OFPMatch class. -conf.contribs['OPENFLOW'] = {'prereq_autocomplete': True} - -##################################################### -# Predefined values # -##################################################### - -ofp_port_no = {0xfff8: "IN_PORT", - 0xfff9: "TABLE", - 0xfffa: "NORMAL", - 0xfffb: "FLOOD", - 0xfffc: "ALL", - 0xfffd: "CONTROLLER", - 0xfffe: "LOCAL", - 0xffff: "NONE"} - -ofp_table = {0xff: "ALL"} - -ofp_queue = {0xffffffff: "ALL"} - -ofp_buffer = {0xffffffff: "NO_BUFFER"} - -ofp_max_len = {0xffff: "NO_BUFFER"} - -##################################################### -# Common structures # -##################################################### - -# The following structures will be used in different types -# of OpenFlow messages: ports, matches, actions, queues. - - -# Ports # - -ofp_port_config = ["PORT_DOWN", - "NO_STP", - "NO_RECV", - "NO_RECV_STP", - "NO_FLOOD", - "NO_FWD", - "NO_PACKET_IN"] - -ofp_port_state = ["LINK_DOWN"] - -ofp_port_state_stp = {0: "OFPPS_STP_LISTEN", - 1: "OFPPS_STP_LEARN", - 2: "OFPPS_STP_FORWARD", - 3: "OFPPS_STP_BLOCK"} - -ofp_port_features = ["10MB_HD", - "10MB_FD", - "100MB_HD", - "100MB_FD", - "1GB_HD", - "1GB_FD", - "10GB_FD", - "COPPER", - "FIBER", - "AUTONEG", - "PAUSE", - "PAUSE_ASYM"] - - -class OFPPhyPort(Packet): - name = "OFP_PHY_PORT" - fields_desc = [ShortEnumField("port_no", 0, ofp_port_no), - MACField("hw_addr", "0"), - StrFixedLenField("port_name", "", 16), - FlagsField("config", 0, 32, ofp_port_config), - BitEnumField("stp_state", 0, 24, ofp_port_state), - FlagsField("state", 0, 8, ofp_port_state), - FlagsField("curr", 0, 32, ofp_port_features), - FlagsField("advertised", 0, 32, ofp_port_features), - FlagsField("supported", 0, 32, ofp_port_features), - FlagsField("peer", 0, 32, ofp_port_features)] - - def extract_padding(self, s): - return b"", s - - -class OFPMatch(Packet): - name = "OFP_MATCH" - fields_desc = [FlagsField("wildcards1", None, 12, ["DL_VLAN_PCP", - "NW_TOS"]), - BitField("nw_dst_mask", None, 6), - BitField("nw_src_mask", None, 6), - FlagsField("wildcards2", None, 8, ["IN_PORT", - "DL_VLAN", - "DL_SRC", - "DL_DST", - "DL_TYPE", - "NW_PROTO", - "TP_SRC", - "TP_DST"]), - ShortEnumField("in_port", None, ofp_port_no), - MACField("dl_src", None), - MACField("dl_dst", None), - ShortField("dl_vlan", None), - ByteField("dl_vlan_pcp", None), - XByteField("pad1", None), - ShortField("dl_type", None), - ByteField("nw_tos", None), - ByteField("nw_proto", None), - XShortField("pad2", None), - IPField("nw_src", "0"), - IPField("nw_dst", "0"), - ShortField("tp_src", None), - ShortField("tp_dst", None)] - - def extract_padding(self, s): - return b"", s - - # with post_build we create the wildcards field bit by bit - def post_build(self, p, pay): - # first 10 bits of an ofp_match are always set to 0 - lst_bits = "0" * 10 - - # when one field has not been declared, it is assumed to be wildcarded - if self.wildcards1 is None: - if self.nw_tos is None: - lst_bits += "1" - else: - lst_bits += "0" - if self.dl_vlan_pcp is None: - lst_bits += "1" - else: - lst_bits += "0" - else: - w1 = binrepr(self.wildcards1) - lst_bits += "0" * (2 - len(w1)) - lst_bits += w1 - - # ip masks use 6 bits each - if self.nw_dst_mask is None: - if self.nw_dst == "0": - lst_bits += "111111" - # 0x100000 would be ok too (32-bit IP mask) - else: - lst_bits += "0" * 6 - else: - m1 = binrepr(self.nw_dst_mask) - lst_bits += "0" * (6 - len(m1)) - lst_bits += m1 - if self.nw_src_mask is None: - if self.nw_src == "0": - lst_bits += "111111" - else: - lst_bits += "0" * 6 - else: - m2 = binrepr(self.nw_src_mask) - lst_bits += "0" * (6 - len(m2)) - lst_bits += m2 - - # wildcards2 works the same way as wildcards1 - if self.wildcards2 is None: - if self.tp_dst is None: - lst_bits += "1" - else: - lst_bits += "0" - if self.tp_src is None: - lst_bits += "1" - else: - lst_bits += "0" - if self.nw_proto is None: - lst_bits += "1" - else: - lst_bits += "0" - if self.dl_type is None: - lst_bits += "1" - else: - lst_bits += "0" - if self.dl_dst is None: - lst_bits += "1" - else: - lst_bits += "0" - if self.dl_src is None: - lst_bits += "1" - else: - lst_bits += "0" - if self.dl_vlan is None: - lst_bits += "1" - else: - lst_bits += "0" - if self.in_port is None: - lst_bits += "1" - else: - lst_bits += "0" - else: - w2 = binrepr(self.wildcards2) - lst_bits += "0" * (8 - len(w2)) - lst_bits += w2 - - # In order to write OFPMatch compliant with the specifications, - # if prereq_autocomplete has been set to True - # we assume ethertype=IP or nwproto=TCP when appropriate subfields are provided. # noqa: E501 - if conf.contribs['OPENFLOW']['prereq_autocomplete']: - if self.dl_type is None: - if self.nw_src != "0" or self.nw_dst != "0" or \ - self.nw_proto is not None or self.nw_tos is not None: - p = p[:22] + struct.pack("!H", 0x0800) + p[24:] - lst_bits = lst_bits[:-5] + "0" + lst_bits[-4:] - if self.nw_proto is None: - if self.tp_src is not None or self.tp_dst is not None: - p = p[:22] + struct.pack("!H", 0x0800) + p[24:] - lst_bits = lst_bits[:-5] + "0" + lst_bits[-4:] - p = p[:25] + struct.pack("!B", 0x06) + p[26:] - lst_bits = lst_bits[:-6] + "0" + lst_bits[-5:] - - ins = b"".join(chb(int("".join(x), 2)) for x in zip(*[iter(lst_bits)] * 8)) # noqa: E501 - p = ins + p[4:] - return p + pay - - -class _ofp_header(Packet): - name = "Dummy OpenFlow Header for some lower layers" - - def post_build(self, p, pay): - if self.len is None: - tmp_len = len(p) + len(pay) - p = p[:2] + struct.pack("!H", tmp_len) + p[4:] - return p + pay - - -class _ofp_header_item(Packet): - name = "Dummy OpenFlow Header for items layers" - - def post_build(self, p, pay): - if self.len is None: - tmp_len = len(p) + len(pay) - p = struct.pack("!H", tmp_len) + p[2:] - return p + pay - - -# Actions # - - -class _UnknownOpenFlow(Raw): - name = "Unknown OpenFlow packet" - - -class OpenFlow(_ofp_header): - name = "OpenFlow dissector" - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 2: - version = orb(_pkt[0]) - if version == 0x04: # OpenFlow 1.3 - from scapy.contrib.openflow3 import OpenFlow3 - return OpenFlow3.dispatch_hook(_pkt, *args, **kargs) - elif version == 0x01: # OpenFlow 1.0 - # port 6653 has been allocated by IANA, port 6633 should no - # longer be used - # OpenFlow function may be called with a None - # self in OFPPacketField - of_type = orb(_pkt[1]) - if of_type == 1: - err_type = orb(_pkt[9]) - # err_type is a short int, but last byte is enough - if err_type == 255: - err_type = 65535 - return ofp_error_cls[err_type] - elif of_type == 16: - mp_type = orb(_pkt[9]) - if mp_type == 255: - mp_type = 65535 - return ofp_stats_request_cls[mp_type] - elif of_type == 17: - mp_type = orb(_pkt[9]) - if mp_type == 255: - mp_type = 65535 - return ofp_stats_reply_cls[mp_type] - else: - return ofpt_cls[of_type] - else: - warning("Unknown OpenFlow packet") - return _UnknownOpenFlow - - -ofp_action_types = {0: "OFPAT_OUTPUT", - 1: "OFPAT_SET_VLAN_VID", - 2: "OFPAT_SET_VLAN_PCP", - 3: "OFPAT_STRIP_VLAN", - 4: "OFPAT_SET_DL_SRC", - 5: "OFPAT_SET_DL_DST", - 6: "OFPAT_SET_NW_SRC", - 7: "OFPAT_SET_NW_DST", - 8: "OFPAT_SET_NW_TOS", - 9: "OFPAT_SET_TP_SRC", - 10: "OFPAT_SET_TP_DST", - 11: "OFPAT_ENQUEUE", - 65535: "OFPAT_VENDOR"} - - -class OFPATOutput(OpenFlow): - name = "OFPAT_OUTPUT" - fields_desc = [ShortEnumField("type", 0, ofp_action_types), - ShortField("len", 8), - ShortEnumField("port", 0, ofp_port_no), - ShortEnumField("max_len", "NO_BUFFER", ofp_max_len)] - - -class OFPATSetVLANVID(OpenFlow): - name = "OFPAT_SET_VLAN_VID" - fields_desc = [ShortEnumField("type", 1, ofp_action_types), - ShortField("len", 8), - ShortField("vlan_vid", 0), - XShortField("pad", 0)] - - -class OFPATSetVLANPCP(OpenFlow): - name = "OFPAT_SET_VLAN_PCP" - fields_desc = [ShortEnumField("type", 2, ofp_action_types), - ShortField("len", 8), - ByteField("vlan_pcp", 0), - X3BytesField("pad", 0)] - - -class OFPATStripVLAN(OpenFlow): - name = "OFPAT_STRIP_VLAN" - fields_desc = [ShortEnumField("type", 3, ofp_action_types), - ShortField("len", 8), - XIntField("pad", 0)] - - -class OFPATSetDlSrc(OpenFlow): - name = "OFPAT_SET_DL_SRC" - fields_desc = [ShortEnumField("type", 4, ofp_action_types), - ShortField("len", 16), - MACField("dl_addr", "0"), - XBitField("pad", 0, 48)] - - -class OFPATSetDlDst(OpenFlow): - name = "OFPAT_SET_DL_DST" - fields_desc = [ShortEnumField("type", 5, ofp_action_types), - ShortField("len", 16), - MACField("dl_addr", "0"), - XBitField("pad", 0, 48)] - - -class OFPATSetNwSrc(OpenFlow): - name = "OFPAT_SET_NW_SRC" - fields_desc = [ShortEnumField("type", 6, ofp_action_types), - ShortField("len", 8), - IPField("nw_addr", "0")] - - -class OFPATSetNwDst(OpenFlow): - name = "OFPAT_SET_NW_DST" - fields_desc = [ShortEnumField("type", 7, ofp_action_types), - ShortField("len", 8), - IPField("nw_addr", "0")] - - -class OFPATSetNwToS(OpenFlow): - name = "OFPAT_SET_TP_TOS" - fields_desc = [ShortEnumField("type", 8, ofp_action_types), - ShortField("len", 8), - ByteField("nw_tos", 0), - X3BytesField("pad", 0)] - - -class OFPATSetTpSrc(OpenFlow): - name = "OFPAT_SET_TP_SRC" - fields_desc = [ShortEnumField("type", 9, ofp_action_types), - ShortField("len", 8), - ShortField("tp_port", 0), - XShortField("pad", 0)] - - -class OFPATSetTpDst(OpenFlow): - name = "OFPAT_SET_TP_DST" - fields_desc = [ShortEnumField("type", 10, ofp_action_types), - ShortField("len", 8), - ShortField("tp_port", 0), - XShortField("pad", 0)] - - -class OFPATEnqueue(OpenFlow): - name = "OFPAT_ENQUEUE" - fields_desc = [ShortEnumField("type", 11, ofp_action_types), - ShortField("len", 16), - ShortEnumField("port", 0, ofp_port_no), - XBitField("pad", 0, 48), - IntField("queue_id", 0)] - - -class OFPATVendor(OpenFlow): - name = "OFPAT_VENDOR" - fields_desc = [ShortEnumField("type", 65535, ofp_action_types), - ShortField("len", 8), - IntField("vendor", 0)] - - -ofp_action_cls = {0: OFPATOutput, - 1: OFPATSetVLANVID, - 2: OFPATSetVLANPCP, - 3: OFPATStripVLAN, - 4: OFPATSetDlSrc, - 5: OFPATSetDlDst, - 6: OFPATSetNwSrc, - 7: OFPATSetNwDst, - 8: OFPATSetNwToS, - 9: OFPATSetTpSrc, - 10: OFPATSetTpDst, - 11: OFPATEnqueue, - 65535: OFPATVendor} - - -class OFPAT(Packet): - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 2: - t = struct.unpack("!H", _pkt[:2])[0] - return ofp_action_cls.get(t, Raw) - return Raw - - def extract_padding(self, s): - return b"", s - - -# Queues # - - -ofp_queue_property_types = {0: "OFPQT_NONE", - 1: "OFPQT_MIN_RATE"} - - -class OFPQTNone(_ofp_header): - name = "OFPQT_NONE" - fields_desc = [ShortEnumField("type", 0, ofp_queue_property_types), - ShortField("len", 8), - XIntField("pad", 0)] - - -class OFPQTMinRate(_ofp_header): - name = "OFPQT_MIN_RATE" - fields_desc = [ShortEnumField("type", 1, ofp_queue_property_types), - ShortField("len", 16), - XIntField("pad", 0), - ShortField("rate", 0), - XBitField("pad2", 0, 48)] - - -ofp_queue_property_cls = {0: OFPQTNone, - 1: OFPQTMinRate} - - -class OFPQT(Packet): - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 2: - t = struct.unpack("!H", _pkt[:2])[0] - return ofp_queue_property_cls.get(t, Raw) - return Raw - - def extract_padding(self, s): - return b"", s - - -class OFPPacketQueue(Packet): - name = "OFP_PACKET_QUEUE" - fields_desc = [IntField("queue_id", 0), - ShortField("len", None), - XShortField("pad", 0), - PacketListField("properties", [], OFPQT, - length_from=lambda pkt:pkt.len - 8)] # noqa: E501 - - def extract_padding(self, s): - return b"", s - - def post_build(self, p, pay): - if self.properties == []: - p += raw(OFPQTNone()) - if self.len is None: - tmp_len = len(p) + len(pay) - p = p[:4] + struct.pack("!H", tmp_len) + p[6:] - return p + pay - - -##################################################### -# OpenFlow 1.0 Messages # -##################################################### - - -ofp_version = {0x01: "OpenFlow 1.0", - 0x02: "OpenFlow 1.1", - 0x03: "OpenFlow 1.2", - 0x04: "OpenFlow 1.3", - 0x05: "OpenFlow 1.4"} - -ofp_type = {0: "OFPT_HELLO", - 1: "OFPT_ERROR", - 2: "OFPT_ECHO_REQUEST", - 3: "OFPT_ECHO_REPLY", - 4: "OFPT_VENDOR", - 5: "OFPT_FEATURES_REQUEST", - 6: "OFPT_FEATURES_REPLY", - 7: "OFPT_GET_CONFIG_REQUEST", - 8: "OFPT_GET_CONFIG_REPLY", - 9: "OFPT_SET_CONFIG", - 10: "OFPT_PACKET_IN", - 11: "OFPT_FLOW_REMOVED", - 12: "OFPT_PORT_STATUS", - 13: "OFPT_PACKET_OUT", - 14: "OFPT_FLOW_MOD", - 15: "OFPT_PORT_MOD", - 16: "OFPT_STATS_REQUEST", - 17: "OFPT_STATS_REPLY", - 18: "OFPT_BARRIER_REQUEST", - 19: "OFPT_BARRIER_REPLY", - 20: "OFPT_QUEUE_GET_CONFIG_REQUEST", - 21: "OFPT_QUEUE_GET_CONFIG_REPLY"} - - -class OFPTHello(_ofp_header): - name = "OFPT_HELLO" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 0, ofp_type), - ShortField("len", None), - IntField("xid", 0)] - - -##################################################### -# OFPT_ERROR # -##################################################### - -# this class will be used to display some messages -# sent back by the switch after an error - - -class OFPacketField(PacketField): - def getfield(self, pkt, s): - try: - tmp_len = s[2:4] - tmp_len = struct.unpack("!H", tmp_len)[0] - ofload = s[:tmp_len] - remain = s[tmp_len:] - return remain, OpenFlow(ofload) - except Exception: - return "", Raw(s) - - -ofp_error_type = {0: "OFPET_HELLO_FAILED", - 1: "OFPET_BAD_REQUEST", - 2: "OFPET_BAD_ACTION", - 3: "OFPET_FLOW_MOD_FAILED", - 4: "OFPET_PORT_MOD_FAILED", - 5: "OFPET_QUEUE_OP_FAILED"} - - -class OFPETHelloFailed(_ofp_header): - name = "OFPET_HELLO_FAILED" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 0, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPHFC_INCOMPATIBLE", - 1: "OFPHFC_EPERM"}), - OFPacketField("data", "", Raw)] - - -class OFPETBadRequest(_ofp_header): - name = "OFPET_BAD_REQUEST" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 1, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPBRC_BAD_VERSION", - 1: "OFPBRC_BAD_TYPE", - 2: "OFPBRC_BAD_STAT", - 3: "OFPBRC_BAD_VENDOR", - 4: "OFPBRC_BAD_SUBTYPE", - 5: "OFPBRC_EPERM", - 6: "OFPBRC_BAD_LEN", - 7: "OFPBRC_BUFFER_EMPTY", - 8: "OFPBRC_BUFFER_UNKNOWN"}), - OFPacketField("data", "", Raw)] - - -class OFPETBadAction(_ofp_header): - name = "OFPET_BAD_ACTION" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 2, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPBAC_BAD_TYPE", - 1: "OFPBAC_BAD_LEN", - 2: "OFPBAC_BAD_VENDOR", - 3: "OFPBAC_BAD_VENDOR_TYPE", - 4: "OFPBAC_BAD_OUT_PORT", - 5: "OFPBAC_BAD_ARGUMENT", - 6: "OFPBAC_EPERM", - 7: "OFPBAC_TOO_MANY", - 8: "OFPBAC_BAD_QUEUE"}), - OFPacketField("data", "", Raw)] - - -class OFPETFlowModFailed(_ofp_header): - name = "OFPET_FLOW_MOD_FAILED" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 3, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPFMFC_ALL_TABLES_FULL", - 1: "OFPFMFC_OVERLAP", - 2: "OFPFMFC_EPERM", - 3: "OFPFMFC_BAD_EMERG_TIMEOUT", # noqa: E501 - 4: "OFPFMFC_BAD_COMMAND", - 5: "OFPFMFC_UNSUPPORTED"}), - OFPacketField("data", "", Raw)] - - -class OFPETPortModFailed(_ofp_header): - name = "OFPET_PORT_MOD_FAILED" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 4, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPPMFC_BAD_PORT", - 1: "OFPPMFC_BAD_HW_ADDR"}), - OFPacketField("data", "", Raw)] - - -class OFPETQueueOpFailed(_ofp_header): - name = "OFPET_QUEUE_OP_FAILED" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 5, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPQOFC_BAD_PORT", - 1: "OFPQOFC_BAD_QUEUE", - 2: "OFPQOFC_EPERM"}), - OFPacketField("data", "", Raw)] - - -# ofp_error_cls allows generic method OpenFlow() to choose the right class for dissection # noqa: E501 -ofp_error_cls = {0: OFPETHelloFailed, - 1: OFPETBadRequest, - 2: OFPETBadAction, - 3: OFPETFlowModFailed, - 4: OFPETPortModFailed, - 5: OFPETQueueOpFailed} - -# end of OFPT_ERRORS # - - -class OFPTEchoRequest(_ofp_header): - name = "OFPT_ECHO_REQUEST" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 2, ofp_type), - ShortField("len", None), - IntField("xid", 0)] - - -class OFPTEchoReply(_ofp_header): - name = "OFPT_ECHO_REPLY" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 3, ofp_type), - ShortField("len", None), - IntField("xid", 0)] - - -class OFPTVendor(_ofp_header): - name = "OFPT_VENDOR" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 4, ofp_type), - ShortField("len", None), - IntField("xid", 0), - IntField("vendor", 0)] - - -class OFPTFeaturesRequest(_ofp_header): - name = "OFPT_FEATURES_REQUEST" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 5, ofp_type), - ShortField("len", None), - IntField("xid", 0)] - - -ofp_action_types_flags = [v for v in six.itervalues(ofp_action_types) - if v != 'OFPAT_VENDOR'] - - -class OFPTFeaturesReply(_ofp_header): - name = "OFPT_FEATURES_REPLY" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 6, ofp_type), - ShortField("len", None), - IntField("xid", 0), - LongField("datapath_id", 0), - IntField("n_buffers", 0), - ByteField("n_tables", 1), - X3BytesField("pad", 0), - FlagsField("capabilities", 0, 32, ["FLOW_STATS", - "TABLE_STATS", - "PORT_STATS", - "STP", - "RESERVED", - "IP_REASM", - "QUEUE_STATS", - "ARP_MATCH_IP"]), - FlagsField("actions", 0, 32, ofp_action_types_flags), - PacketListField("ports", [], OFPPhyPort, - length_from=lambda pkt:pkt.len - 32)] - - -class OFPTGetConfigRequest(_ofp_header): - name = "OFPT_GET_CONFIG_REQUEST" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 7, ofp_type), - ShortField("len", None), - IntField("xid", 0)] - - -class OFPTGetConfigReply(_ofp_header): - name = "OFPT_GET_CONFIG_REPLY" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 8, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("flags", 0, {0: "FRAG_NORMAL", - 1: "FRAG_DROP", - 2: "FRAG_REASM", - 3: "FRAG_MASK"}), - ShortField("miss_send_len", 0)] - - -class OFPTSetConfig(_ofp_header): - name = "OFPT_SET_CONFIG" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 9, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("flags", 0, {0: "FRAG_NORMAL", - 1: "FRAG_DROP", - 2: "FRAG_REASM", - 3: "FRAG_MASK"}), - ShortField("miss_send_len", 128)] - - -class OFPTPacketIn(_ofp_header): - name = "OFPT_PACKET_IN" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 10, ofp_type), - ShortField("len", None), - IntField("xid", 0), - IntEnumField("buffer_id", "NO_BUFFER", ofp_buffer), - ShortField("total_len", 0), - ShortEnumField("in_port", 0, ofp_port_no), - ByteEnumField("reason", 0, {0: "OFPR_NO_MATCH", - 1: "OFPR_ACTION"}), - XByteField("pad", 0), - PacketField("data", None, Ether)] - - -class OFPTFlowRemoved(_ofp_header): - name = "OFPT_FLOW_REMOVED" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 11, ofp_type), - ShortField("len", None), - IntField("xid", 0), - PacketField("match", OFPMatch(), OFPMatch), - LongField("cookie", 0), - ShortField("priority", 0), - ByteEnumField("reason", 0, {0: "OFPRR_IDLE_TIMEOUT", - 1: "OFPRR_HARD_TIMEOUT", - 2: "OFPRR_DELETE"}), - XByteField("pad1", 0), - IntField("duration_sec", 0), - IntField("duration_nsec", 0), - ShortField("idle_timeout", 0), - XShortField("pad2", 0), - LongField("packet_count", 0), - LongField("byte_count", 0)] - - -class OFPTPortStatus(_ofp_header): - name = "OFPT_PORT_STATUS" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 12, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ByteEnumField("reason", 0, {0: "OFPPR_ADD", - 1: "OFPPR_DELETE", - 2: "OFPPR_MODIFY"}), - XBitField("pad", 0, 56), - PacketField("desc", OFPPhyPort(), OFPPhyPort)] - - -class OFPTPacketOut(_ofp_header): - name = "OFPT_PACKET_OUT" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 13, ofp_type), - ShortField("len", None), - IntField("xid", 0), - IntEnumField("buffer_id", "NO_BUFFER", ofp_buffer), - ShortEnumField("in_port", "NONE", ofp_port_no), - FieldLenField("actions_len", None, fmt="H", length_of="actions"), # noqa: E501 - PacketListField("actions", [], OFPAT, - ofp_action_cls, - length_from=lambda pkt:pkt.actions_len), # noqa: E501 - PacketField("data", None, Ether)] - - -class OFPTFlowMod(_ofp_header): - name = "OFPT_FLOW_MOD" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 14, ofp_type), - ShortField("len", None), - IntField("xid", 0), - PacketField("match", OFPMatch(), OFPMatch), - LongField("cookie", 0), - ShortEnumField("cmd", 0, {0: "OFPFC_ADD", - 1: "OFPFC_MODIFY", - 2: "OFPFC_MODIFY_STRICT", - 3: "OFPFC_DELETE", - 4: "OFPFC_DELETE_STRICT"}), - ShortField("idle_timeout", 0), - ShortField("hard_timeout", 0), - ShortField("priority", 0), - IntEnumField("buffer_id", "NO_BUFFER", ofp_buffer), - ShortEnumField("out_port", "NONE", ofp_port_no), - FlagsField("flags", 0, 16, ["SEND_FLOW_REM", - "CHECK_OVERLAP", - "EMERG"]), - PacketListField("actions", [], OFPAT, - ofp_action_cls, - length_from=lambda pkt:pkt.len - 72)] - - -class OFPTPortMod(_ofp_header): - name = "OFPT_PORT_MOD" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 15, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("port_no", 0, ofp_port_no), - MACField("hw_addr", "0"), - FlagsField("config", 0, 32, ofp_port_config), - FlagsField("mask", 0, 32, ofp_port_config), - FlagsField("advertise", 0, 32, ofp_port_features), - IntField("pad", 0)] - - -##################################################### -# OFPT_STATS # -##################################################### - - -ofp_stats_types = {0: "OFPST_DESC", - 1: "OFPST_FLOW", - 2: "OFPST_AGGREGATE", - 3: "OFPST_TABLE", - 4: "OFPST_PORT", - 5: "OFPST_QUEUE", - 65535: "OFPST_VENDOR"} - - -class OFPTStatsRequestDesc(_ofp_header): - name = "OFPST_STATS_REQUEST_DESC" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 16, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("stats_type", 0, ofp_stats_types), - FlagsField("flags", 0, 16, [])] - - -class OFPTStatsReplyDesc(_ofp_header): - name = "OFPST_STATS_REPLY_DESC" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 17, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("stats_type", 0, ofp_stats_types), - FlagsField("flags", 0, 16, []), - StrFixedLenField("mfr_desc", "", 256), - StrFixedLenField("hw_desc", "", 256), - StrFixedLenField("sw_desc", "", 256), - StrFixedLenField("serial_num", "", 32), - StrFixedLenField("dp_desc", "", 256)] - - -class OFPTStatsRequestFlow(_ofp_header): - name = "OFPST_STATS_REQUEST_FLOW" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 16, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("stats_type", 1, ofp_stats_types), - FlagsField("flags", 0, 16, []), - PacketField("match", OFPMatch(), OFPMatch), - ByteEnumField("table_id", "ALL", ofp_table), - ByteField("pad", 0), - ShortEnumField("out_port", "NONE", ofp_port_no)] - - -class OFPFlowStats(Packet): - name = "OFP_FLOW_STATS" - fields_desc = [ShortField("length", None), - ByteField("table_id", 0), - XByteField("pad1", 0), - PacketField("match", OFPMatch(), OFPMatch), - IntField("duration_sec", 0), - IntField("duration_nsec", 0), - ShortField("priority", 0), - ShortField("idle_timeout", 0), - ShortField("hard_timeout", 0), - XBitField("pad2", 0, 48), - LongField("cookie", 0), - LongField("packet_count", 0), - LongField("byte_count", 0), - PacketListField("actions", [], OFPAT, - ofp_action_cls, - length_from=lambda pkt:pkt.length - 88)] - - def post_build(self, p, pay): - if self.length is None: - tmp_len = len(p) + len(pay) - p = struct.pack("!H", tmp_len) + p[2:] - return p + pay - - def extract_padding(self, s): - return b"", s - - -class OFPTStatsReplyFlow(_ofp_header): - name = "OFPST_STATS_REPLY_FLOW" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 17, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("stats_type", 1, ofp_stats_types), - FlagsField("flags", 0, 16, []), - PacketListField("flow_stats", [], OFPFlowStats, - length_from=lambda pkt:pkt.len - 12)] # noqa: E501 - - -class OFPTStatsRequestAggregate(OFPTStatsRequestFlow): - name = "OFPST_STATS_REQUEST_AGGREGATE" - stats_type = 2 - - -class OFPTStatsReplyAggregate(_ofp_header): - name = "OFPST_STATS_REPLY_AGGREGATE" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 17, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("stats_type", 2, ofp_stats_types), - FlagsField("flags", 0, 16, []), - LongField("packet_count", 0), - LongField("byte_count", 0), - IntField("flow_count", 0), - XIntField("pad", 0)] - - -class OFPTStatsRequestTable(_ofp_header): - name = "OFPST_STATS_REQUEST_TABLE" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 16, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("stats_type", 3, ofp_stats_types), - FlagsField("flags", 0, 16, [])] - - -class OFPTableStats(Packet): - - def extract_padding(self, s): - return b"", s - - name = "OFP_TABLE_STATS" - fields_desc = [ByteField("table_id", 0), - X3BytesField("pad", 0), - StrFixedLenField("name", "", 32), - FlagsField("wildcards1", 0x003, 12, ["DL_VLAN_PCP", - "NW_TOS"]), - BitField("nw_dst_mask", 63, 6), # 32 would be enough - BitField("nw_src_mask", 63, 6), - FlagsField("wildcards2", 0xff, 8, ["IN_PORT", - "DL_VLAN", - "DL_SRC", - "DL_DST", - "DL_TYPE", - "NW_PROTO", - "TP_SRC", - "TP_DST"]), - IntField("max_entries", 0), - IntField("active_count", 0), - LongField("lookup_count", 0), - LongField("matched_count", 0)] - - -class OFPTStatsReplyTable(_ofp_header): - name = "OFPST_STATS_REPLY_TABLE" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 17, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("stats_type", 3, ofp_stats_types), - FlagsField("flags", 0, 16, []), - PacketListField("table_stats", [], OFPTableStats, - length_from=lambda pkt:pkt.len - 12)] - - -class OFPTStatsRequestPort(_ofp_header): - name = "OFPST_STATS_REQUEST_PORT" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 16, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("stats_type", 4, ofp_stats_types), - FlagsField("flags", 0, 16, []), - ShortEnumField("port_no", "NONE", ofp_port_no), - XBitField("pad", 0, 48)] - - -class OFPPortStats(Packet): - - def extract_padding(self, s): - return b"", s - - name = "OFP_PORT_STATS" - fields_desc = [ShortEnumField("port_no", 0, ofp_port_no), - XBitField("pad", 0, 48), - LongField("rx_packets", 0), - LongField("tx_packets", 0), - LongField("rx_bytes", 0), - LongField("tx_bytes", 0), - LongField("rx_dropped", 0), - LongField("tx_dropped", 0), - LongField("rx_errors", 0), - LongField("tx_errors", 0), - LongField("rx_frame_err", 0), - LongField("rx_over_err", 0), - LongField("rx_crc_err", 0), - LongField("collisions", 0)] - - -class OFPTStatsReplyPort(_ofp_header): - name = "OFPST_STATS_REPLY_TABLE" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 17, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("stats_type", 4, ofp_stats_types), - FlagsField("flags", 0, 16, []), - PacketListField("port_stats", [], OFPPortStats, - length_from=lambda pkt:pkt.len - 12)] - - -class OFPTStatsRequestQueue(_ofp_header): - name = "OFPST_STATS_REQUEST_QUEUE" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 16, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("stats_type", 5, ofp_stats_types), - FlagsField("flags", 0, 16, []), - ShortEnumField("port_no", "NONE", ofp_port_no), - XShortField("pad", 0), - IntEnumField("queue_id", "ALL", ofp_queue)] - - -class OFPTStatsReplyQueue(_ofp_header): - name = "OFPST_STATS_REPLY_QUEUE" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 17, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("stats_type", 5, ofp_stats_types), - FlagsField("flags", 0, 16, []), - ShortEnumField("port_no", "NONE", ofp_port_no), - XShortField("pad", 0), - IntEnumField("queue_id", "ALL", ofp_queue), - LongField("tx_bytes", 0), - LongField("tx_packets", 0), - LongField("tx_errors", 0)] - - -class OFPTStatsRequestVendor(_ofp_header): - name = "OFPST_STATS_REQUEST_VENDOR" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 16, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("stats_type", 6, ofp_stats_types), - FlagsField("flags", 0, 16, []), - IntField("vendor", 0)] - - -class OFPTStatsReplyVendor(_ofp_header): - name = "OFPST_STATS_REPLY_VENDOR" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 17, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("stats_type", 6, ofp_stats_types), - FlagsField("flags", 0, 16, []), - IntField("vendor", 0)] - - -# ofp_stats_request/reply_cls allows generic method OpenFlow() (end of script) -# to choose the right class for dissection -ofp_stats_request_cls = {0: OFPTStatsRequestDesc, - 1: OFPTStatsRequestFlow, - 2: OFPTStatsRequestAggregate, - 3: OFPTStatsRequestTable, - 4: OFPTStatsRequestPort, - 5: OFPTStatsRequestQueue, - 65535: OFPTStatsRequestVendor} - -ofp_stats_reply_cls = {0: OFPTStatsReplyDesc, - 1: OFPTStatsReplyFlow, - 2: OFPTStatsReplyAggregate, - 3: OFPTStatsReplyTable, - 4: OFPTStatsReplyPort, - 5: OFPTStatsReplyQueue, - 65535: OFPTStatsReplyVendor} - -# end of OFPT_STATS # - - -class OFPTBarrierRequest(_ofp_header): - name = "OFPT_BARRIER_REQUEST" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0)] - - -class OFPTBarrierReply(_ofp_header): - name = "OFPT_BARRIER_REPLY" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0)] - - -class OFPTQueueGetConfigRequest(_ofp_header): - name = "OFPT_QUEUE_GET_CONFIG_REQUEST" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 20, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("port", 0, ofp_port_no), - XShortField("pad", 0)] - - -class OFPTQueueGetConfigReply(_ofp_header): - name = "OFPT_QUEUE_GET_CONFIG_REPLY" - fields_desc = [ByteEnumField("version", 0x01, ofp_version), - ByteEnumField("type", 21, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("port", 0, ofp_port_no), - XBitField("pad", 0, 48), - PacketListField("queues", [], OFPPacketQueue, - length_from=lambda pkt:pkt.len - 16)] - - -# ofpt_cls allows generic method OpenFlow() to choose the right class for dissection # noqa: E501 -ofpt_cls = {0: OFPTHello, - # 1: OFPTError, - 2: OFPTEchoRequest, - 3: OFPTEchoReply, - 4: OFPTVendor, - 5: OFPTFeaturesRequest, - 6: OFPTFeaturesReply, - 7: OFPTGetConfigRequest, - 8: OFPTGetConfigReply, - 9: OFPTSetConfig, - 10: OFPTPacketIn, - 11: OFPTFlowRemoved, - 12: OFPTPortStatus, - 13: OFPTPacketOut, - 14: OFPTFlowMod, - 15: OFPTPortMod, - # 16: OFPTStatsRequest, - # 17: OFPTStatsReply, - 18: OFPTBarrierRequest, - 19: OFPTBarrierReply, - 20: OFPTQueueGetConfigRequest, - 21: OFPTQueueGetConfigReply} - - -bind_bottom_up(TCP, OpenFlow, dport=6653) -bind_bottom_up(TCP, OpenFlow, sport=6653) -bind_bottom_up(TCP, OpenFlow, dport=6633) -bind_bottom_up(TCP, OpenFlow, sport=6633) - -bind_top_down(TCP, _ofp_header, sport=6653, dport=6653) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/openflow3.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/openflow3.py deleted file mode 100755 index c7307045bf..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/openflow3.py +++ /dev/null @@ -1,3165 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -# Copyright (C) 2014 Maxence Tury -# OpenFlow is an open standard used in SDN deployments. -# Based on OpenFlow v1.3.4 -# Specifications can be retrieved from https://www.opennetworking.org/ - -# scapy.contrib.description = OpenFlow v1.3 -# scapy.contrib.status = loads - -from __future__ import absolute_import -import copy -import struct - - -from scapy.compat import orb, raw -from scapy.config import conf -from scapy.fields import BitEnumField, BitField, ByteEnumField, ByteField, \ - FieldLenField, FlagsField, IntEnumField, IntField, IPField, \ - LongField, MACField, PacketField, PacketListField, ShortEnumField, \ - ShortField, StrFixedLenField, X3BytesField, XBitField, XByteField, \ - XIntField, XShortField, PacketLenField -from scapy.layers.l2 import Ether -from scapy.packet import Packet, Padding, Raw -from scapy.modules import six - -from scapy.contrib.openflow import _ofp_header, _ofp_header_item, \ - OFPacketField, OpenFlow, _UnknownOpenFlow - -##################################################### -# Predefined values # -##################################################### - -ofp_port_no = {0xfffffff8: "IN_PORT", - 0xfffffff9: "TABLE", - 0xfffffffa: "NORMAL", - 0xfffffffb: "FLOOD", - 0xfffffffc: "ALL", - 0xfffffffd: "CONTROLLER", - 0xfffffffe: "LOCAL", - 0xffffffff: "ANY"} - -ofp_group = {0xffffff00: "MAX", - 0xfffffffc: "ALL", - 0xffffffff: "ANY"} - -ofp_table = {0xfe: "MAX", - 0xff: "ALL"} - -ofp_queue = {0xffffffff: "ALL"} - -ofp_meter = {0xffff0000: "MAX", - 0xfffffffd: "SLOWPATH", - 0xfffffffe: "CONTROLLER", - 0xffffffff: "ALL"} - -ofp_buffer = {0xffffffff: "NO_BUFFER"} - -ofp_max_len = {0xffff: "NO_BUFFER"} - - -##################################################### -# Common structures # -##################################################### - -# The following structures will be used in different types -# of OpenFlow messages: ports, matches/OXMs, actions, -# instructions, buckets, queues, meter bands. - - -# Hello elements # - - -ofp_hello_elem_types = {1: "OFPHET_VERSIONBITMAP"} - - -class OFPHET(_ofp_header): - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 2: - t = struct.unpack("!H", _pkt[:2])[0] - return ofp_hello_elem_cls.get(t, Raw) - return Raw - - def extract_padding(self, s): - return b"", s - - -class OFPHETVersionBitmap(_ofp_header): - name = "OFPHET_VERSIONBITMAP" - fields_desc = [ShortEnumField("type", 1, ofp_hello_elem_types), - ShortField("len", 8), - FlagsField("bitmap", 0, 32, ["Type 0", - "OFv1.0", - "OFv1.1", - "OFv1.2", - "OFv1.3", - "OFv1.4", - "OFv1.5"])] - - -ofp_hello_elem_cls = {1: OFPHETVersionBitmap} - - -# Ports # - -ofp_port_config = ["PORT_DOWN", - "NO_STP", # undefined in v1.3 - "NO_RECV", - "NO_RECV_STP", # undefined in v1.3 - "NO_FLOOD", # undefined in v1.3 - "NO_FWD", - "NO_PACKET_IN"] - -ofp_port_state = ["LINK_DOWN", - "BLOCKED", - "LIVE"] - -ofp_port_features = ["10MB_HD", - "10MB_FD", - "100MB_HD", - "100MB_FD", - "1GB_HD", - "1GB_FD", - "10GB_FD", - "40GB_FD", - "100GB_FD", - "1TB_FD", - "OTHER", - "COPPER", - "FIBER", - "AUTONEG", - "PAUSE", - "PAUSE_ASYM"] - - -class OFPPort(Packet): - name = "OFP_PHY_PORT" - fields_desc = [IntEnumField("port_no", 0, ofp_port_no), - XIntField("pad1", 0), - MACField("hw_addr", "0"), - XShortField("pad2", 0), - StrFixedLenField("port_name", "", 16), - FlagsField("config", 0, 32, ofp_port_config), - FlagsField("state", 0, 32, ofp_port_state), - FlagsField("curr", 0, 32, ofp_port_features), - FlagsField("advertised", 0, 32, ofp_port_features), - FlagsField("supported", 0, 32, ofp_port_features), - FlagsField("peer", 0, 32, ofp_port_features), - IntField("curr_speed", 0), - IntField("max_speed", 0)] - - def extract_padding(self, s): - return b"", s - - -# Matches & OXMs # - -ofp_oxm_classes = {0: "OFPXMC_NXM_0", - 1: "OFPXMC_NXM_1", - 0x8000: "OFPXMC_OPENFLOW_BASIC", - 0xffff: "OFPXMC_EXPERIMENTER"} - -ofp_oxm_names = {0: "OFB_IN_PORT", - 1: "OFB_IN_PHY_PORT", - 2: "OFB_METADATA", - 3: "OFB_ETH_DST", - 4: "OFB_ETH_SRC", - 5: "OFB_ETH_TYPE", - 6: "OFB_VLAN_VID", - 7: "OFB_VLAN_PCP", - 8: "OFB_IP_DSCP", - 9: "OFB_IP_ECN", - 10: "OFB_IP_PROTO", - 11: "OFB_IPV4_SRC", - 12: "OFB_IPV4_DST", - 13: "OFB_TCP_SRC", - 14: "OFB_TCP_DST", - 15: "OFB_UDP_SRC", - 16: "OFB_UDP_DST", - 17: "OFB_SCTP_SRC", - 18: "OFB_SCTP_DST", - 19: "OFB_ICMPV4_TYPE", - 20: "OFB_ICMPV4_CODE", - 21: "OFB_ARP_OP", - 22: "OFB_ARP_SPA", - 23: "OFB_ARP_TPA", - 24: "OFB_ARP_SHA", - 25: "OFB_ARP_THA", - 26: "OFB_IPV6_SRC", - 27: "OFB_IPV6_DST", - 28: "OFB_IPV6_FLABEL", - 29: "OFB_ICMPV6_TYPE", - 30: "OFB_ICMPV6_CODE", - 31: "OFB_IPV6_ND_TARGET", - 32: "OFB_IPV6_ND_SLL", - 33: "OFB_IPV6_ND_TLL", - 34: "OFB_MPLS_LABEL", - 35: "OFB_MPLS_TC", - 36: "OFB_MPLS_BOS", - 37: "OFB_PBB_ISID", - 38: "OFB_TUNNEL_ID", - 39: "OFB_IPV6_EXTHDR"} - -ofp_oxm_constr = {0: ["OFBInPort", "in_port", 4], - 1: ["OFBInPhyPort", "in_phy_port", 4], - 2: ["OFBMetadata", "metadata", 8], - 3: ["OFBEthDst", "eth_dst", 6], - 4: ["OFBEthSrc", "eth_src", 6], - 5: ["OFBEthType", "eth_type", 2], - 6: ["OFBVLANVID", "vlan_vid", 2], - 7: ["OFBVLANPCP", "vlan_pcp", 1], - 8: ["OFBIPDSCP", "ip_dscp", 1], - 9: ["OFBIPECN", "ip_ecn", 1], - 10: ["OFBIPProto", "ip_proto", 1], - 11: ["OFBIPv4Src", "ipv4_src", 4], - 12: ["OFBIPv4Dst", "ipv4_dst", 4], - 13: ["OFBTCPSrc", "tcp_src", 2], - 14: ["OFBTCPDst", "tcp_dst", 2], - 15: ["OFBUDPSrc", "udp_src", 2], - 16: ["OFBUDPDst", "udp_dst", 2], - 17: ["OFBSCTPSrc", "sctp_src", 2], - 18: ["OFBSCTPDst", "sctp_dst", 2], - 19: ["OFBICMPv4Type", "icmpv4_type", 1], - 20: ["OFBICMPv4Code", "icmpv4_code", 1], - 21: ["OFBARPOP", "arp_op", 2], - 22: ["OFBARPSPA", "arp_spa", 4], - 23: ["OFBARPTPA", "arp_tpa", 4], - 24: ["OFBARPSHA", "arp_sha", 6], - 25: ["OFBARPTHA", "arp_tha", 6], - 26: ["OFBIPv6Src", "ipv6_src", 16], - 27: ["OFBIPv6Dst", "ipv6_dst", 16], - 28: ["OFBIPv6FLabel", "ipv6_flabel", 4], - 29: ["OFBICMPv6Type", "icmpv6_type", 1], - 30: ["OFBICMPv6Code", "icmpv6_code", 1], - 31: ["OFBIPv6NDTarget", "ipv6_nd_target", 16], - 32: ["OFBIPv6NDSLL", "ipv6_sll", 6], - 33: ["OFBIPv6NDTLL", "ipv6_tll", 6], - 34: ["OFBMPLSLabel", "mpls_label", 4], - 35: ["OFBMPLSTC", "mpls_tc", 1], - 36: ["OFBMPLSBoS", "mpls_bos", 1], - 37: ["OFBPBBISID", "pbb_isid", 3], - 38: ["OFBTunnelID", "tunnel_id", 8], - 39: ["OFBIPv6ExtHdr", "ipv6_ext_hdr_flags", 2]} - -# the ipv6flags array is useful only to the OFBIPv6ExtHdr class -ipv6flags = ["NONEXT", - "ESP", - "AUTH", - "DEST", - "FRAG", - "ROUTER", - "HOP", - "UNREP", - "UNSEQ"] - -# here we fill ofp_oxm_fields with the fields that will be used -# to generate the various OXM classes -# e.g. the call to add_ofp_oxm_fields(0, ["OFBInPort", "in_port", 4]) -# will add {0: [ShortEnumField("class",..), BitEnumField("field",..),..]} -ofp_oxm_fields = {} - - -def add_ofp_oxm_fields(i, org): - ofp_oxm_fields[i] = [ShortEnumField("class", "OFPXMC_OPENFLOW_BASIC", ofp_oxm_classes), # noqa: E501 - BitEnumField("field", i // 2, 7, ofp_oxm_names), - BitField("hasmask", i % 2, 1)] - ofp_oxm_fields[i].append(ByteField("len", org[2] + org[2] * (i % 2))) - if i // 2 == 0: # OFBInPort - ofp_oxm_fields[i].append(IntEnumField(org[1], 0, ofp_port_no)) - elif i // 2 == 3 or i // 2 == 4: # OFBEthSrc & OFBEthDst - ofp_oxm_fields[i].append(MACField(org[1], None)) - elif i // 2 == 11 or i // 2 == 12: # OFBIPv4Src & OFBIPv4Dst - ofp_oxm_fields[i].append(IPField(org[1], "0")) - elif i // 2 == 39: # OFBIPv6ExtHdr - ofp_oxm_fields[i].append(FlagsField(org[1], 0, 8 * org[2], ipv6flags)) - else: - ofp_oxm_fields[i].append(BitField(org[1], 0, 8 * org[2])) - if i % 2: - ofp_oxm_fields[i].append(BitField(org[1] + "_mask", 0, 8 * org[2])) - - -# some HM classes are not supported par OFv1.3 but we will create them anyway -for i, cls in ofp_oxm_constr.items(): - add_ofp_oxm_fields(2 * i, cls) - add_ofp_oxm_fields(2 * i + 1, cls) - -# now we create every OXM class with the same call, -# (except that static variable create_oxm_class.i is each time different) -# and we fill ofp_oxm_cls with them -ofp_oxm_cls = {} -ofp_oxm_id_cls = {} - - -def _create_oxm_cls(): - # static variable initialization - if not hasattr(_create_oxm_cls, "i"): - _create_oxm_cls.i = 0 - - index = _create_oxm_cls.i - cls_name = ofp_oxm_constr[index // 4][0] - # we create standard OXM then OXM ID then OXM with mask then OXM-hasmask ID - if index % 4 == 2: - cls_name += "HM" - if index % 2: - cls_name += "ID" - - oxm_name = ofp_oxm_names[index // 4] - oxm_fields = ofp_oxm_fields[index // 2] - # for ID classes we just want the first 4 fields (no payload) - if index % 2: - oxm_fields = oxm_fields[:4] - - cls = type(cls_name, (Packet,), {"name": oxm_name, "fields_desc": oxm_fields}) # noqa: E501 - # the first call to special function type will create the same class as in - # class OFBInPort(Packet): - # def __init__(self): - # self.name = "OFB_IN_PORT" - # self.fields_desc = [ ShortEnumField("class", 0x8000, ofp_oxm_classes), - # BitEnumField("field", 0, 7, ofp_oxm_names), - # BitField("hasmask", 0, 1), - # ByteField("len", 4), - # IntEnumField("in_port", 0, ofp_port_no) ] - - if index % 2 == 0: - ofp_oxm_cls[index // 2] = cls - else: - ofp_oxm_id_cls[index // 2] = cls - _create_oxm_cls.i += 1 - cls.extract_padding = lambda self, s: (b"", s) - return cls - - -OFBInPort = _create_oxm_cls() -OFBInPortID = _create_oxm_cls() -OFBInPortHM = _create_oxm_cls() -OFBInPortHMID = _create_oxm_cls() -OFBInPhyPort = _create_oxm_cls() -OFBInPhyPortID = _create_oxm_cls() -OFBInPhyPortHM = _create_oxm_cls() -OFBInPhyPortHMID = _create_oxm_cls() -OFBMetadata = _create_oxm_cls() -OFBMetadataID = _create_oxm_cls() -OFBMetadataHM = _create_oxm_cls() -OFBMetadataHMID = _create_oxm_cls() -OFBEthDst = _create_oxm_cls() -OFBEthDstID = _create_oxm_cls() -OFBEthDstHM = _create_oxm_cls() -OFBEthDstHMID = _create_oxm_cls() -OFBEthSrc = _create_oxm_cls() -OFBEthSrcID = _create_oxm_cls() -OFBEthSrcHM = _create_oxm_cls() -OFBEthSrcHMID = _create_oxm_cls() -OFBEthType = _create_oxm_cls() -OFBEthTypeID = _create_oxm_cls() -OFBEthTypeHM = _create_oxm_cls() -OFBEthTypeHMID = _create_oxm_cls() -OFBVLANVID = _create_oxm_cls() -OFBVLANVIDID = _create_oxm_cls() -OFBVLANVIDHM = _create_oxm_cls() -OFBVLANVIDHMID = _create_oxm_cls() -OFBVLANPCP = _create_oxm_cls() -OFBVLANPCPID = _create_oxm_cls() -OFBVLANPCPHM = _create_oxm_cls() -OFBVLANPCPHMID = _create_oxm_cls() -OFBIPDSCP = _create_oxm_cls() -OFBIPDSCPID = _create_oxm_cls() -OFBIPDSCPHM = _create_oxm_cls() -OFBIPDSCPHMID = _create_oxm_cls() -OFBIPECN = _create_oxm_cls() -OFBIPECNID = _create_oxm_cls() -OFBIPECNHM = _create_oxm_cls() -OFBIPECNHMID = _create_oxm_cls() -OFBIPProto = _create_oxm_cls() -OFBIPProtoID = _create_oxm_cls() -OFBIPProtoHM = _create_oxm_cls() -OFBIPProtoHMID = _create_oxm_cls() -OFBIPv4Src = _create_oxm_cls() -OFBIPv4SrcID = _create_oxm_cls() -OFBIPv4SrcHM = _create_oxm_cls() -OFBIPv4SrcHMID = _create_oxm_cls() -OFBIPv4Dst = _create_oxm_cls() -OFBIPv4DstID = _create_oxm_cls() -OFBIPv4DstHM = _create_oxm_cls() -OFBIPv4DstHMID = _create_oxm_cls() -OFBTCPSrc = _create_oxm_cls() -OFBTCPSrcID = _create_oxm_cls() -OFBTCPSrcHM = _create_oxm_cls() -OFBTCPSrcHMID = _create_oxm_cls() -OFBTCPDst = _create_oxm_cls() -OFBTCPDstID = _create_oxm_cls() -OFBTCPDstHM = _create_oxm_cls() -OFBTCPDstHMID = _create_oxm_cls() -OFBUDPSrc = _create_oxm_cls() -OFBUDPSrcID = _create_oxm_cls() -OFBUDPSrcHM = _create_oxm_cls() -OFBUDPSrcHMID = _create_oxm_cls() -OFBUDPDst = _create_oxm_cls() -OFBUDPDstID = _create_oxm_cls() -OFBUDPDstHM = _create_oxm_cls() -OFBUDPDstHMID = _create_oxm_cls() -OFBSCTPSrc = _create_oxm_cls() -OFBSCTPSrcID = _create_oxm_cls() -OFBSCTPSrcHM = _create_oxm_cls() -OFBSCTPSrcHMID = _create_oxm_cls() -OFBSCTPDst = _create_oxm_cls() -OFBSCTPDstID = _create_oxm_cls() -OFBSCTPDstHM = _create_oxm_cls() -OFBSCTPDstHMID = _create_oxm_cls() -OFBICMPv4Type = _create_oxm_cls() -OFBICMPv4TypeID = _create_oxm_cls() -OFBICMPv4TypeHM = _create_oxm_cls() -OFBICMPv4TypeHMID = _create_oxm_cls() -OFBICMPv4Code = _create_oxm_cls() -OFBICMPv4CodeID = _create_oxm_cls() -OFBICMPv4CodeHM = _create_oxm_cls() -OFBICMPv4CodeHMID = _create_oxm_cls() -OFBARPOP = _create_oxm_cls() -OFBARPOPID = _create_oxm_cls() -OFBARPOPHM = _create_oxm_cls() -OFBARPOPHMID = _create_oxm_cls() -OFBARPSPA = _create_oxm_cls() -OFBARPSPAID = _create_oxm_cls() -OFBARPSPAHM = _create_oxm_cls() -OFBARPSPAHMID = _create_oxm_cls() -OFBARPTPA = _create_oxm_cls() -OFBARPTPAID = _create_oxm_cls() -OFBARPTPAHM = _create_oxm_cls() -OFBARPTPAHMID = _create_oxm_cls() -OFBARPSHA = _create_oxm_cls() -OFBARPSHAID = _create_oxm_cls() -OFBARPSHAHM = _create_oxm_cls() -OFBARPSHAHMID = _create_oxm_cls() -OFBARPTHA = _create_oxm_cls() -OFBARPTHAID = _create_oxm_cls() -OFBARPTHAHM = _create_oxm_cls() -OFBARPTHAHMID = _create_oxm_cls() -OFBIPv6Src = _create_oxm_cls() -OFBIPv6SrcID = _create_oxm_cls() -OFBIPv6SrcHM = _create_oxm_cls() -OFBIPv6SrcHMID = _create_oxm_cls() -OFBIPv6Dst = _create_oxm_cls() -OFBIPv6DstID = _create_oxm_cls() -OFBIPv6DstHM = _create_oxm_cls() -OFBIPv6DstHMID = _create_oxm_cls() -OFBIPv6FLabel = _create_oxm_cls() -OFBIPv6FLabelID = _create_oxm_cls() -OFBIPv6FLabelHM = _create_oxm_cls() -OFBIPv6FLabelHMID = _create_oxm_cls() -OFBICMPv6Type = _create_oxm_cls() -OFBICMPv6TypeID = _create_oxm_cls() -OFBICMPv6TypeHM = _create_oxm_cls() -OFBICMPv6TypeHMID = _create_oxm_cls() -OFBICMPv6Code = _create_oxm_cls() -OFBICMPv6CodeID = _create_oxm_cls() -OFBICMPv6CodeHM = _create_oxm_cls() -OFBICMPv6CodeHMID = _create_oxm_cls() -OFBIPv6NDTarget = _create_oxm_cls() -OFBIPv6NDTargetID = _create_oxm_cls() -OFBIPv6NDTargetHM = _create_oxm_cls() -OFBIPv6NDTargetHMID = _create_oxm_cls() -OFBIPv6NDSLL = _create_oxm_cls() -OFBIPv6NDSLLID = _create_oxm_cls() -OFBIPv6NDSLLHM = _create_oxm_cls() -OFBIPv6NDSLLHMID = _create_oxm_cls() -OFBIPv6NDTLL = _create_oxm_cls() -OFBIPv6NDTLLID = _create_oxm_cls() -OFBIPv6NDTLLHM = _create_oxm_cls() -OFBIPv6NDTLLHMID = _create_oxm_cls() -OFBMPLSLabel = _create_oxm_cls() -OFBMPLSLabelID = _create_oxm_cls() -OFBMPLSLabelHM = _create_oxm_cls() -OFBMPLSLabelHMID = _create_oxm_cls() -OFBMPLSTC = _create_oxm_cls() -OFBMPLSTCID = _create_oxm_cls() -OFBMPLSTCHM = _create_oxm_cls() -OFBMPLSTCHMID = _create_oxm_cls() -OFBMPLSBoS = _create_oxm_cls() -OFBMPLSBoSID = _create_oxm_cls() -OFBMPLSBoSHM = _create_oxm_cls() -OFBMPLSBoSHMID = _create_oxm_cls() -OFBPBBISID = _create_oxm_cls() -OFBPBBISIDID = _create_oxm_cls() -OFBPBBISIDHM = _create_oxm_cls() -OFBPBBISIDHMID = _create_oxm_cls() -OFBTunnelID = _create_oxm_cls() -OFBTunnelIDID = _create_oxm_cls() -OFBTunnelIDHM = _create_oxm_cls() -OFBTunnelIDHMID = _create_oxm_cls() -OFBIPv6ExtHdr = _create_oxm_cls() -OFBIPv6ExtHdrID = _create_oxm_cls() -OFBIPv6ExtHdrHM = _create_oxm_cls() -OFBIPv6ExtHdrHMID = _create_oxm_cls() - -# need_prereq holds a list of prerequisites defined in 7.2.3.8 of the specifications # noqa: E501 -# e.g. if you want to use an OFBTCPSrc instance (code 26) -# you first need to declare an OFBIPProto instance (code 20) with value 6, -# and if you want to use an OFBIPProto instance (still code 20) -# you first need to declare an OFBEthType instance (code 10) with value 0x0800 -# (0x0800 means IPv4 by default, but you might want to use 0x86dd with IPv6) -# need_prereq codes are two times higher than previous oxm classes codes, -# except for 21 which is sort of a proxy for IPv6 (see below) -need_prereq = {14: [12, 0x1000], - 16: [10, 0x0800], # could be 0x86dd - 18: [10, 0x0800], # could be 0x86dd - 20: [10, 0x0800], # could be 0x86dd - 21: [10, 0x86dd], - 22: [10, 0x0800], - 24: [10, 0x0800], - 26: [20, 6], - 28: [20, 6], - 30: [20, 17], - 32: [20, 17], - 34: [20, 132], - 36: [20, 132], - 38: [20, 1], - 40: [20, 1], - 42: [10, 0x0806], - 44: [10, 0x0806], - 46: [10, 0x0806], - 48: [10, 0x0806], - 50: [10, 0x0806], - 52: [10, 0x86dd], - 54: [10, 0x86dd], - 56: [10, 0x86dd], - 58: [21, 58], # small trick here, we refer to normally non- - 60: [21, 58], # existent field 21 to distinguish ipv6 - 62: [58, 135], # could be 136 - 64: [58, 135], - 66: [58, 136], - 68: [10, 0x8847], # could be 0x8848 - 70: [10, 0x8847], # could be 0x8848 - 72: [10, 0x8847], # could be 0x8848 - 74: [10, 0x88e7], - 78: [10, 0x86dd]} - - -class OXMPacketListField(PacketListField): - - __slots__ = ["autocomplete", "index"] - - def __init__(self, name, default, cls, length_from=None, autocomplete=False): # noqa: E501 - PacketListField.__init__(self, name, default, cls, length_from=length_from) # noqa: E501 - self.autocomplete = autocomplete - self.index = [] - - def i2m(self, pkt, val): - # this part makes for a faster writing of specs-compliant matches - # expect some unwanted behaviour if you try incoherent associations - # you might want to set autocomplete=False in __init__ method - if self.autocomplete or conf.contribs['OPENFLOW']['prereq_autocomplete']: # noqa: E501 - # val might be modified during the loop so we need a fixed copy - fix_val = copy.deepcopy(val) - for oxm in fix_val: - f = 2 * oxm.field - fix_index = list(self.index) - while f in need_prereq: - # this loop enables a small recursion - # e.g. ipv6_nd<--icmpv6<--ip_proto<--eth_type - prereq = need_prereq[f] - f = prereq[0] - f2 = 20 if f == 21 else f # ipv6 trick... - if f2 not in fix_index: - self.index.insert(0, f2) - prrq = ofp_oxm_cls[f2]() # never HM - setattr(prrq, ofp_oxm_constr[f2 // 2][1], prereq[1]) - val.insert(0, prrq) - # we could do more complicated stuff to - # make sure prerequisite order is correct - # but it works well when presented with any coherent input - # e.g. you should not mix OFBTCPSrc with OFBICMPv6Code - # and expect to get coherent results... - # you can still go manual by setting prereq_autocomplete=False # noqa: E501 - return val - - def m2i(self, pkt, s): - t = orb(s[2]) - nrm_t = t - t % 2 - if nrm_t not in self.index: - self.index.append(nrm_t) - return ofp_oxm_cls.get(t, Raw)(s) - - @staticmethod - def _get_oxm_length(s): - return orb(s[3]) - - def addfield(self, pkt, s, val): - return s + b"".join(raw(x) for x in self.i2m(pkt, val)) - - def getfield(self, pkt, s): - lst = [] - lim = self.length_from(pkt) - ret = s[lim:] - remain = s[:lim] - - while remain and len(remain) > 4: - tmp_len = OXMPacketListField._get_oxm_length(remain) + 4 - # this could also be done by parsing oxm_fields (fixed lengths) - if tmp_len <= 4 or len(remain) < tmp_len: - # no incoherent length - break - current = remain[:tmp_len] - remain = remain[tmp_len:] - p = self.m2i(pkt, current) - lst.append(p) - - self.index = [] - # since OXMPacketListField is called only twice (when OFPMatch and OFPSetField # noqa: E501 - # classes are created) and not when you want to instantiate an OFPMatch, # noqa: E501 - # index needs to be reinitialized, otherwise there will be some conflicts # noqa: E501 - # e.g. if you create OFPMatch with OFBTCPSrc and then change to OFBTCPDst, # noqa: E501 - # index will already be filled with ethertype and nwproto codes, - # thus the corresponding fields will not be added to the packet - return remain + ret, lst - - -class OXMID(Packet): - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 2: - t = orb(_pkt[2]) - return ofp_oxm_id_cls.get(t, Raw) - return Raw - - def extract_padding(self, s): - return b"", s - - -class OFPMatch(Packet): - name = "OFP_MATCH" - fields_desc = [ShortEnumField("type", 1, {0: "OFPMT_STANDARD", - 1: "OFPMT_OXM"}), - ShortField("len", None), - OXMPacketListField("oxm_fields", [], Packet, - length_from=lambda pkt:pkt.len - 4)] - - def post_build(self, p, pay): - tmp_len = self.len - if tmp_len is None: - tmp_len = len(p) + len(pay) - p = p[:2] + struct.pack("!H", tmp_len) + p[4:] - zero_bytes = (8 - tmp_len % 8) % 8 - p += b"\x00" * zero_bytes - # message with user-defined length will not be automatically padded - return p + pay - - def extract_padding(self, s): - tmp_len = self.len - zero_bytes = (8 - tmp_len % 8) % 8 - return s[zero_bytes:], s[:zero_bytes] - -# ofp_match is no longer a fixed-length structure in v1.3 -# furthermore it may include variable padding -# we introduce to that end a subclass of PacketField - - -class MatchField(PacketField): - def __init__(self, name): - PacketField.__init__(self, name, OFPMatch(), OFPMatch) - - def getfield(self, pkt, s): - i = self.m2i(pkt, s) - # i can be or > - # or > or >> - # and we want to return "", or "", > - # or raw(), or raw(), > - if Raw in i: - r = i[Raw] - if Padding in r: - p = r[Padding] - i.payload = p - del(r.payload) - return r.load, i - else: - return b"", i - - -# Actions # - - -class OpenFlow3(OpenFlow): - name = "OpenFlow v1.3 dissector" - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 2: - # port 6653 has been allocated by IANA, port 6633 should no - # longer be used - # OpenFlow3 function may be called with None self in OFPPacketField - of_type = orb(_pkt[1]) - if of_type == 1: - err_type = orb(_pkt[9]) - # err_type is a short int, but last byte is enough - if err_type == 255: - err_type = 65535 - return ofp_error_cls[err_type] - elif of_type == 18: - mp_type = orb(_pkt[9]) - if mp_type == 255: - mp_type = 65535 - return ofp_multipart_request_cls[mp_type] - elif of_type == 19: - mp_type = orb(_pkt[9]) - if mp_type == 255: - mp_type = 65535 - return ofp_multipart_reply_cls[mp_type] - else: - return ofpt_cls[of_type] - return _UnknownOpenFlow - - -ofp_action_types = {0: "OFPAT_OUTPUT", - 1: "OFPAT_SET_VLAN_VID", - 2: "OFPAT_SET_VLAN_PCP", - 3: "OFPAT_STRIP_VLAN", - 4: "OFPAT_SET_DL_SRC", - 5: "OFPAT_SET_DL_DST", - 6: "OFPAT_SET_NW_SRC", - 7: "OFPAT_SET_NW_DST", - 8: "OFPAT_SET_NW_TOS", - 9: "OFPAT_SET_TP_SRC", - 10: "OFPAT_SET_TP_DST", - # 11: "OFPAT_ENQUEUE", - 11: "OFPAT_COPY_TTL_OUT", - 12: "OFPAT_COPY_TTL_IN", - 13: "OFPAT_SET_MPLS_LABEL", - 14: "OFPAT_DEC_MPLS_TC", - 15: "OFPAT_SET_MPLS_TTL", - 16: "OFPAT_DEC_MPLS_TTL", - 17: "OFPAT_PUSH_VLAN", - 18: "OFPAT_POP_VLAN", - 19: "OFPAT_PUSH_MPLS", - 20: "OFPAT_POP_MPLS", - 21: "OFPAT_SET_QUEUE", - 22: "OFPAT_GROUP", - 23: "OFPAT_SET_NW_TTL", - 24: "OFPAT_DEC_NW_TTL", - 25: "OFPAT_SET_FIELD", - 26: "OFPAT_PUSH_PBB", - 27: "OFPAT_POP_PBB", - 65535: "OFPAT_EXPERIMENTER"} - - -class OFPAT(_ofp_header): - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 2: - t = struct.unpack("!H", _pkt[:2])[0] - return ofp_action_cls.get(t, Raw) - return Raw - - def extract_padding(self, s): - return b"", s - - -class OFPATOutput(OFPAT): - name = "OFPAT_OUTPUT" - fields_desc = [ShortEnumField("type", 0, ofp_action_types), - ShortField("len", 16), - IntEnumField("port", 0, ofp_port_no), - ShortEnumField("max_len", "NO_BUFFER", ofp_max_len), - XBitField("pad", 0, 48)] - - -# the following actions are not supported by OFv1.3 - - -class OFPATSetVLANVID(OFPAT): - name = "OFPAT_SET_VLAN_VID" - fields_desc = [ShortEnumField("type", 1, ofp_action_types), - ShortField("len", 8), - ShortField("vlan_vid", 0), - XShortField("pad", 0)] - - -class OFPATSetVLANPCP(OFPAT): - name = "OFPAT_SET_VLAN_PCP" - fields_desc = [ShortEnumField("type", 2, ofp_action_types), - ShortField("len", 8), - ByteField("vlan_pcp", 0), - X3BytesField("pad", 0)] - - -class OFPATStripVLAN(OFPAT): - name = "OFPAT_STRIP_VLAN" - fields_desc = [ShortEnumField("type", 3, ofp_action_types), - ShortField("len", 8), - XIntField("pad", 0)] - - -class OFPATSetDlSrc(OFPAT): - name = "OFPAT_SET_DL_SRC" - fields_desc = [ShortEnumField("type", 4, ofp_action_types), - ShortField("len", 16), - MACField("dl_addr", "0"), - XBitField("pad", 0, 48)] - - -class OFPATSetDlDst(OFPAT): - name = "OFPAT_SET_DL_DST" - fields_desc = [ShortEnumField("type", 5, ofp_action_types), - ShortField("len", 16), - MACField("dl_addr", "0"), - XBitField("pad", 0, 48)] - - -class OFPATSetNwSrc(OFPAT): - name = "OFPAT_SET_NW_SRC" - fields_desc = [ShortEnumField("type", 6, ofp_action_types), - ShortField("len", 8), - IPField("nw_addr", "0")] - - -class OFPATSetNwDst(OFPAT): - name = "OFPAT_SET_NW_DST" - fields_desc = [ShortEnumField("type", 7, ofp_action_types), - ShortField("len", 8), - IPField("nw_addr", "0")] - - -class OFPATSetNwToS(OFPAT): - name = "OFPAT_SET_TP_TOS" - fields_desc = [ShortEnumField("type", 8, ofp_action_types), - ShortField("len", 8), - ByteField("nw_tos", 0), - X3BytesField("pad", 0)] - - -class OFPATSetTpSrc(OFPAT): - name = "OFPAT_SET_TP_SRC" - fields_desc = [ShortEnumField("type", 9, ofp_action_types), - ShortField("len", 8), - ShortField("tp_port", 0), - XShortField("pad", 0)] - - -class OFPATSetTpDst(OFPAT): - name = "OFPAT_SET_TP_DST" - fields_desc = [ShortEnumField("type", 10, ofp_action_types), - ShortField("len", 8), - ShortField("tp_port", 0), - XShortField("pad", 0)] - -# class OFPATEnqueue(OFPAT): -# name = "OFPAT_ENQUEUE" -# fields_desc = [ ShortEnumField("type", 11, ofp_action_types), -# ShortField("len", 16), -# ShortField("port", 0), -# XBitField("pad", 0, 48), -# IntEnumField("queue_id", 0, ofp_queue) ] - - -class OFPATSetMPLSLabel(OFPAT): - name = "OFPAT_SET_MPLS_LABEL" - fields_desc = [ShortEnumField("type", 13, ofp_action_types), - ShortField("len", 8), - IntField("mpls_label", 0)] - - -class OFPATSetMPLSTC(OFPAT): - name = "OFPAT_SET_MPLS_TC" - fields_desc = [ShortEnumField("type", 14, ofp_action_types), - ShortField("len", 8), - ByteField("mpls_tc", 0), - X3BytesField("pad", 0)] - -# end of unsupported actions - - -class OFPATCopyTTLOut(OFPAT): - name = "OFPAT_COPY_TTL_OUT" - fields_desc = [ShortEnumField("type", 11, ofp_action_types), - ShortField("len", 8), - XIntField("pad", 0)] - - -class OFPATCopyTTLIn(OFPAT): - name = "OFPAT_COPY_TTL_IN" - fields_desc = [ShortEnumField("type", 12, ofp_action_types), - ShortField("len", 8), - XIntField("pad", 0)] - - -class OFPATSetMPLSTTL(OFPAT): - name = "OFPAT_SET_MPLS_TTL" - fields_desc = [ShortEnumField("type", 15, ofp_action_types), - ShortField("len", 8), - ByteField("mpls_ttl", 0), - X3BytesField("pad", 0)] - - -class OFPATDecMPLSTTL(OFPAT): - name = "OFPAT_DEC_MPLS_TTL" - fields_desc = [ShortEnumField("type", 16, ofp_action_types), - ShortField("len", 8), - XIntField("pad", 0)] - - -class OFPATPushVLAN(OFPAT): - name = "OFPAT_PUSH_VLAN" - fields_desc = [ShortEnumField("type", 17, ofp_action_types), - ShortField("len", 8), - ShortField("ethertype", 0x8100), # or 0x88a8 - XShortField("pad", 0)] - - -class OFPATPopVLAN(OFPAT): - name = "OFPAT_POP_VLAN" - fields_desc = [ShortEnumField("type", 18, ofp_action_types), - ShortField("len", 8), - XIntField("pad", 0)] - - -class OFPATPushMPLS(OFPAT): - name = "OFPAT_PUSH_MPLS" - fields_desc = [ShortEnumField("type", 19, ofp_action_types), - ShortField("len", 8), - ShortField("ethertype", 0x8847), # or 0x8848 - XShortField("pad", 0)] - - -class OFPATPopMPLS(OFPAT): - name = "OFPAT_POP_MPLS" - fields_desc = [ShortEnumField("type", 20, ofp_action_types), - ShortField("len", 8), - ShortField("ethertype", 0x8847), # or 0x8848 - XShortField("pad", 0)] - - -class OFPATSetQueue(OFPAT): - name = "OFPAT_SET_QUEUE" - fields_desc = [ShortEnumField("type", 21, ofp_action_types), - ShortField("len", 8), - IntEnumField("queue_id", 0, ofp_queue)] - - -class OFPATGroup(OFPAT): - name = "OFPAT_GROUP" - fields_desc = [ShortEnumField("type", 22, ofp_action_types), - ShortField("len", 8), - IntEnumField("group_id", 0, ofp_group)] - - -class OFPATSetNwTTL(OFPAT): - name = "OFPAT_SET_NW_TTL" - fields_desc = [ShortEnumField("type", 23, ofp_action_types), - ShortField("len", 8), - ByteField("nw_ttl", 0), - X3BytesField("pad", 0)] - - -class OFPATDecNwTTL(OFPAT): - name = "OFPAT_DEC_NW_TTL" - fields_desc = [ShortEnumField("type", 24, ofp_action_types), - ShortField("len", 8), - XIntField("pad", 0)] - - -class OFPATSetField(OFPAT): - name = "OFPAT_SET_FIELD" - fields_desc = [ShortEnumField("type", 25, ofp_action_types), - ShortField("len", None), - # there should not be more than one oxm tlv - OXMPacketListField("field", [], Packet, - length_from=lambda pkt:pkt.len - 4, - # /!\ contains padding! - autocomplete=False)] - - def post_build(self, p, pay): - tmp_len = self.len - zero_bytes = 0 - if tmp_len is None: - tmp_len = len(p) + len(pay) - zero_bytes = (8 - tmp_len % 8) % 8 - tmp_len = tmp_len + zero_bytes # add padding length - p = p[:2] + struct.pack("!H", tmp_len) + p[4:] - else: - zero_bytes = (8 - tmp_len % 8) % 8 - # every message will be padded correctly - p += b"\x00" * zero_bytes - return p + pay - - def extract_padding(self, s): - return b"", s - - -class OFPATPushPBB(OFPAT): - name = "OFPAT_PUSH_PBB" - fields_desc = [ShortEnumField("type", 26, ofp_action_types), - ShortField("len", 8), - ShortField("ethertype", 0x88e7), - XShortField("pad", 0)] - - -class OFPATPopPBB(OFPAT): - name = "OFPAT_POP_PBB" - fields_desc = [ShortEnumField("type", 27, ofp_action_types), - ShortField("len", 8), - XIntField("pad", 0)] - - -class OFPATExperimenter(OFPAT): - name = "OFPAT_EXPERIMENTER" - fields_desc = [ShortEnumField("type", 65535, ofp_action_types), - ShortField("len", 8), - IntField("experimenter", 0)] - - -ofp_action_cls = {0: OFPATOutput, - 1: OFPATSetVLANVID, - 2: OFPATSetVLANPCP, - 3: OFPATStripVLAN, - 4: OFPATSetDlSrc, - 5: OFPATSetDlDst, - 6: OFPATSetNwSrc, - 7: OFPATSetNwDst, - 8: OFPATSetNwToS, - 9: OFPATSetTpSrc, - 10: OFPATSetTpDst, - # 11: OFPATEnqueue, - 11: OFPATCopyTTLOut, - 12: OFPATCopyTTLIn, - 13: OFPATSetMPLSLabel, - 14: OFPATSetMPLSTC, - 15: OFPATSetMPLSTTL, - 16: OFPATDecMPLSTTL, - 17: OFPATPushVLAN, - 18: OFPATPopVLAN, - 19: OFPATPushMPLS, - 20: OFPATPopMPLS, - 21: OFPATSetQueue, - 22: OFPATGroup, - 23: OFPATSetNwTTL, - 24: OFPATDecNwTTL, - 25: OFPATSetField, - 26: OFPATPushPBB, - 27: OFPATPopPBB, - 65535: OFPATExperimenter} - - -# Action IDs # - -class OFPATID(_ofp_header): - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 2: - t = struct.unpack("!H", _pkt[:2])[0] - return ofp_action_id_cls.get(t, Raw) - return Raw - - def extract_padding(self, s): - return b"", s - -# length is computed as in instruction structures, -# so we reuse _ofp_header - - -class OFPATOutputID(OFPATID): - name = "OFPAT_OUTPUT" - fields_desc = [ShortEnumField("type", 0, ofp_action_types), - ShortField("len", 4)] - -# the following actions are not supported by OFv1.3 - - -class OFPATSetVLANVIDID(OFPATID): - name = "OFPAT_SET_VLAN_VID" - fields_desc = [ShortEnumField("type", 1, ofp_action_types), - ShortField("len", 4)] - - -class OFPATSetVLANPCPID(OFPATID): - name = "OFPAT_SET_VLAN_PCP" - fields_desc = [ShortEnumField("type", 2, ofp_action_types), - ShortField("len", 4)] - - -class OFPATStripVLANID(OFPATID): - name = "OFPAT_STRIP_VLAN" - fields_desc = [ShortEnumField("type", 3, ofp_action_types), - ShortField("len", 4)] - - -class OFPATSetDlSrcID(OFPATID): - name = "OFPAT_SET_DL_SRC" - fields_desc = [ShortEnumField("type", 4, ofp_action_types), - ShortField("len", 4)] - - -class OFPATSetDlDstID(OFPATID): - name = "OFPAT_SET_DL_DST" - fields_desc = [ShortEnumField("type", 5, ofp_action_types), - ShortField("len", 4)] - - -class OFPATSetNwSrcID(OFPATID): - name = "OFPAT_SET_NW_SRC" - fields_desc = [ShortEnumField("type", 6, ofp_action_types), - ShortField("len", 4)] - - -class OFPATSetNwDstID(OFPATID): - name = "OFPAT_SET_NW_DST" - fields_desc = [ShortEnumField("type", 7, ofp_action_types), - ShortField("len", 4)] - - -class OFPATSetNwToSID(OFPATID): - name = "OFPAT_SET_TP_TOS" - fields_desc = [ShortEnumField("type", 8, ofp_action_types), - ShortField("len", 4)] - - -class OFPATSetTpSrcID(OFPATID): - name = "OFPAT_SET_TP_SRC" - fields_desc = [ShortEnumField("type", 9, ofp_action_types), - ShortField("len", 4)] - - -class OFPATSetTpDstID(OFPATID): - name = "OFPAT_SET_TP_DST" - fields_desc = [ShortEnumField("type", 10, ofp_action_types), - ShortField("len", 4)] - -# class OFPATEnqueueID(OFPAT): -# name = "OFPAT_ENQUEUE" -# fields_desc = [ ShortEnumField("type", 11, ofp_action_types), -# ShortField("len", 4) ] - - -class OFPATSetMPLSLabelID(OFPATID): - name = "OFPAT_SET_MPLS_LABEL" - fields_desc = [ShortEnumField("type", 13, ofp_action_types), - ShortField("len", 4)] - - -class OFPATSetMPLSTCID(OFPATID): - name = "OFPAT_SET_MPLS_TC" - fields_desc = [ShortEnumField("type", 14, ofp_action_types), - ShortField("len", 4)] - -# end of unsupported actions - - -class OFPATCopyTTLOutID(OFPATID): - name = "OFPAT_COPY_TTL_OUT" - fields_desc = [ShortEnumField("type", 11, ofp_action_types), - ShortField("len", 4)] - - -class OFPATCopyTTLInID(OFPATID): - name = "OFPAT_COPY_TTL_IN" - fields_desc = [ShortEnumField("type", 12, ofp_action_types), - ShortField("len", 4)] - - -class OFPATSetMPLSTTLID(OFPATID): - name = "OFPAT_SET_MPLS_TTL" - fields_desc = [ShortEnumField("type", 15, ofp_action_types), - ShortField("len", 4)] - - -class OFPATDecMPLSTTLID(OFPATID): - name = "OFPAT_DEC_MPLS_TTL" - fields_desc = [ShortEnumField("type", 16, ofp_action_types), - ShortField("len", 4)] - - -class OFPATPushVLANID(OFPATID): - name = "OFPAT_PUSH_VLAN" - fields_desc = [ShortEnumField("type", 17, ofp_action_types), - ShortField("len", 4)] - - -class OFPATPopVLANID(OFPATID): - name = "OFPAT_POP_VLAN" - fields_desc = [ShortEnumField("type", 18, ofp_action_types), - ShortField("len", 4)] - - -class OFPATPushMPLSID(OFPATID): - name = "OFPAT_PUSH_MPLS" - fields_desc = [ShortEnumField("type", 19, ofp_action_types), - ShortField("len", 4)] - - -class OFPATPopMPLSID(OFPATID): - name = "OFPAT_POP_MPLS" - fields_desc = [ShortEnumField("type", 20, ofp_action_types), - ShortField("len", 4)] - - -class OFPATSetQueueID(OFPATID): - name = "OFPAT_SET_QUEUE" - fields_desc = [ShortEnumField("type", 21, ofp_action_types), - ShortField("len", 4)] - - -class OFPATGroupID(OFPATID): - name = "OFPAT_GROUP" - fields_desc = [ShortEnumField("type", 22, ofp_action_types), - ShortField("len", 4)] - - -class OFPATSetNwTTLID(OFPATID): - name = "OFPAT_SET_NW_TTL" - fields_desc = [ShortEnumField("type", 23, ofp_action_types), - ShortField("len", 4)] - - -class OFPATDecNwTTLID(OFPATID): - name = "OFPAT_DEC_NW_TTL" - fields_desc = [ShortEnumField("type", 24, ofp_action_types), - ShortField("len", 4)] - - -class OFPATSetFieldID(OFPATID): - name = "OFPAT_SET_FIELD" - fields_desc = [ShortEnumField("type", 25, ofp_action_types), - ShortField("len", 4)] - - -class OFPATPushPBBID(OFPATID): - name = "OFPAT_PUSH_PBB" - fields_desc = [ShortEnumField("type", 26, ofp_action_types), - ShortField("len", 4)] - - -class OFPATPopPBBID(OFPATID): - name = "OFPAT_POP_PBB" - fields_desc = [ShortEnumField("type", 27, ofp_action_types), - ShortField("len", 4)] - - -class OFPATExperimenterID(OFPATID): - name = "OFPAT_EXPERIMENTER" - fields_desc = [ShortEnumField("type", 65535, ofp_action_types), - ShortField("len", None)] - - -ofp_action_id_cls = {0: OFPATOutputID, - 1: OFPATSetVLANVIDID, - 2: OFPATSetVLANPCPID, - 3: OFPATStripVLANID, - 4: OFPATSetDlSrcID, - 5: OFPATSetDlDstID, - 6: OFPATSetNwSrcID, - 7: OFPATSetNwDstID, - 8: OFPATSetNwToSID, - 9: OFPATSetTpSrcID, - 10: OFPATSetTpDstID, - # 11: OFPATEnqueueID, - 11: OFPATCopyTTLOutID, - 12: OFPATCopyTTLInID, - 13: OFPATSetMPLSLabelID, - 14: OFPATSetMPLSTCID, - 15: OFPATSetMPLSTTLID, - 16: OFPATDecMPLSTTLID, - 17: OFPATPushVLANID, - 18: OFPATPopVLANID, - 19: OFPATPushMPLSID, - 20: OFPATPopMPLSID, - 21: OFPATSetQueueID, - 22: OFPATGroupID, - 23: OFPATSetNwTTLID, - 24: OFPATDecNwTTLID, - 25: OFPATSetFieldID, - 26: OFPATPushPBBID, - 27: OFPATPopPBBID, - 65535: OFPATExperimenterID} - - -# Instructions # - - -ofp_instruction_types = {1: "OFPIT_GOTO_TABLE", - 2: "OFPIT_WRITE_METADATA", - 3: "OFPIT_WRITE_ACTIONS", - 4: "OFPIT_APPLY_ACTIONS", - 5: "OFPIT_CLEAR_ACTIONS", - 6: "OFPIT_METER", - 65535: "OFPIT_EXPERIMENTER"} - - -class OFPIT(_ofp_header): - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 2: - t = struct.unpack("!H", _pkt[:2])[0] - return ofp_instruction_cls.get(t, Raw) - return Raw - - def extract_padding(self, s): - return b"", s - - -class OFPITGotoTable(OFPIT): - name = "OFPIT_GOTO_TABLE" - fields_desc = [ShortEnumField("type", 1, ofp_instruction_types), - ShortField("len", 8), - ByteEnumField("table_id", 0, ofp_table), - X3BytesField("pad", 0)] - - -class OFPITWriteMetadata(OFPIT): - name = "OFPIT_WRITE_METADATA" - fields_desc = [ShortEnumField("type", 2, ofp_instruction_types), - ShortField("len", 24), - XIntField("pad", 0), - LongField("metadata", 0), - LongField("metadata_mask", 0)] - - -class OFPITWriteActions(OFPIT): - name = "OFPIT_WRITE_ACTIONS" - fields_desc = [ShortEnumField("type", 3, ofp_instruction_types), - ShortField("len", None), - XIntField("pad", 0), - PacketListField("actions", [], OFPAT, - length_from=lambda pkt:pkt.len - 8)] - - -class OFPITApplyActions(OFPIT): - name = "OFPIT_APPLY_ACTIONS" - fields_desc = [ShortEnumField("type", 4, ofp_instruction_types), - ShortField("len", None), - XIntField("pad", 0), - PacketListField("actions", [], OFPAT, - length_from=lambda pkt:pkt.len - 8)] - - -class OFPITClearActions(OFPIT): - name = "OFPIT_CLEAR_ACTIONS" - fields_desc = [ShortEnumField("type", 5, ofp_instruction_types), - ShortField("len", 8), - XIntField("pad", 0)] - - -class OFPITMeter(OFPIT): - name = "OFPIT_METER" - fields_desc = [ShortEnumField("type", 6, ofp_instruction_types), - ShortField("len", 8), - IntEnumField("meter_id", 1, ofp_meter)] - - -class OFPITExperimenter(OFPIT): - name = "OFPIT_EXPERIMENTER" - fields_desc = [ShortEnumField("type", 65535, ofp_instruction_types), - ShortField("len", None), - IntField("experimenter", 0)] - - -ofp_instruction_cls = {1: OFPITGotoTable, - 2: OFPITWriteMetadata, - 3: OFPITWriteActions, - 4: OFPITApplyActions, - 5: OFPITClearActions, - 6: OFPITMeter, - 65535: OFPITExperimenter} - - -# Instruction IDs # - -# length is computed as in instruction structures, -# so we reuse _ofp_header - -class OFPITID(_ofp_header): - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 2: - t = struct.unpack("!H", _pkt[:2])[0] - return ofp_instruction_id_cls.get(t, Raw) - return Raw - - def extract_padding(self, s): - return b"", s - - -class OFPITGotoTableID(OFPITID): - name = "OFPIT_GOTO_TABLE" - fields_desc = [ShortEnumField("type", 1, ofp_instruction_types), - ShortField("len", 4)] - - -class OFPITWriteMetadataID(OFPITID): - name = "OFPIT_WRITE_METADATA" - fields_desc = [ShortEnumField("type", 2, ofp_instruction_types), - ShortField("len", 4)] - - -class OFPITWriteActionsID(OFPITID): - name = "OFPIT_WRITE_ACTIONS" - fields_desc = [ShortEnumField("type", 3, ofp_instruction_types), - ShortField("len", 4)] - - -class OFPITApplyActionsID(OFPITID): - name = "OFPIT_APPLY_ACTIONS" - fields_desc = [ShortEnumField("type", 4, ofp_instruction_types), - ShortField("len", 4)] - - -class OFPITClearActionsID(OFPITID): - name = "OFPIT_CLEAR_ACTIONS" - fields_desc = [ShortEnumField("type", 5, ofp_instruction_types), - ShortField("len", 4)] - - -class OFPITMeterID(OFPITID): - name = "OFPIT_METER" - fields_desc = [ShortEnumField("type", 6, ofp_instruction_types), - ShortField("len", 4)] - - -class OFPITExperimenterID(OFPITID): - name = "OFPIT_EXPERIMENTER" - fields_desc = [ShortEnumField("type", 65535, ofp_instruction_types), - ShortField("len", None)] - - -ofp_instruction_id_cls = {1: OFPITGotoTableID, - 2: OFPITWriteMetadataID, - 3: OFPITWriteActionsID, - 4: OFPITApplyActionsID, - 5: OFPITClearActionsID, - 6: OFPITMeterID, - 65535: OFPITExperimenterID} - - -# Buckets # - -class OFPBucket(_ofp_header_item): - name = "OFP_BUCKET" - fields_desc = [ShortField("len", None), - ShortField("weight", 0), - IntEnumField("watch_port", 0, ofp_port_no), - IntEnumField("watch_group", 0, ofp_group), - XIntField("pad", 0), - PacketListField("actions", [], OFPAT, - length_from=lambda pkt:pkt.len - 16)] - - def extract_padding(self, s): - return b"", s - - -# Queues # - - -ofp_queue_property_types = {0: "OFPQT_NONE", - 1: "OFPQT_MIN_RATE"} - - -class OFPQT(_ofp_header): - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 2: - t = struct.unpack("!H", _pkt[:2])[0] - return ofp_queue_property_cls.get(t, Raw) - return Raw - - def extract_padding(self, s): - return b"", s - - -class OFPQTNone(OFPQT): - name = "OFPQT_NONE" - fields_desc = [ShortEnumField("type", 0, ofp_queue_property_types), - ShortField("len", 8), - XIntField("pad", 0)] - - -class OFPQTMinRate(OFPQT): - name = "OFPQT_MIN_RATE" - fields_desc = [ShortEnumField("type", 1, ofp_queue_property_types), - ShortField("len", 16), - XIntField("pad1", 0), - ShortField("rate", 0), - XBitField("pad2", 0, 48)] - - -ofp_queue_property_cls = {0: OFPQTNone, - 1: OFPQTMinRate} - - -class OFPPacketQueue(Packet): - name = "OFP_PACKET_QUEUE" - fields_desc = [IntEnumField("queue_id", 0, ofp_queue), - ShortField("len", None), - XShortField("pad", 0), - PacketListField("properties", [], OFPQT, - length_from=lambda pkt:pkt.len - 8)] # noqa: E501 - - def extract_padding(self, s): - return b"", s - - def post_build(self, p, pay): - if self.properties == []: - p += raw(OFPQTNone()) - if self.len is None: - tmp_len = len(p) + len(pay) - p = p[:4] + struct.pack("!H", tmp_len) + p[6:] - return p + pay - - -# Meter bands # - -ofp_meter_band_types = {0: "OFPMBT_DROP", - 1: "OFPMBT_DSCP_REMARK", - 65535: "OFPMBT_EXPERIMENTER"} - - -class OFPMBT(_ofp_header): - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 2: - t = struct.unpack("!H", _pkt[:2])[0] - return ofp_meter_band_cls.get(t, Raw) - return Raw - - def extract_padding(self, s): - return b"", s - - -class OFPMBTDrop(OFPMBT): - name = "OFPMBT_DROP" - fields_desc = [ShortEnumField("type", 0, ofp_queue_property_types), - ShortField("len", 16), - IntField("rate", 0), - IntField("burst_size", 0), - XIntField("pad", 0)] - - -class OFPMBTDSCPRemark(OFPMBT): - name = "OFPMBT_DSCP_REMARK" - fields_desc = [ShortEnumField("type", 1, ofp_queue_property_types), - ShortField("len", 16), - IntField("rate", 0), - IntField("burst_size", 0), - ByteField("prec_level", 0), - X3BytesField("pad", 0)] - - -class OFPMBTExperimenter(OFPMBT): - name = "OFPMBT_EXPERIMENTER" - fields_desc = [ShortEnumField("type", 65535, ofp_queue_property_types), - ShortField("len", 16), - IntField("rate", 0), - IntField("burst_size", 0), - IntField("experimenter", 0)] - - -ofp_meter_band_cls = {0: OFPMBTDrop, - 1: OFPMBTDSCPRemark, - 2: OFPMBTExperimenter} - - -##################################################### -# OpenFlow 1.3 Messages # -##################################################### - -ofp_version = {0x01: "OpenFlow 1.0", - 0x02: "OpenFlow 1.1", - 0x03: "OpenFlow 1.2", - 0x04: "OpenFlow 1.3", - 0x05: "OpenFlow 1.4"} - -ofp_type = {0: "OFPT_HELLO", - 1: "OFPT_ERROR", - 2: "OFPT_ECHO_REQUEST", - 3: "OFPT_ECHO_REPLY", - 4: "OFPT_EXPERIMENTER", - 5: "OFPT_FEATURES_REQUEST", - 6: "OFPT_FEATURES_REPLY", - 7: "OFPT_GET_CONFIG_REQUEST", - 8: "OFPT_GET_CONFIG_REPLY", - 9: "OFPT_SET_CONFIG", - 10: "OFPT_PACKET_IN", - 11: "OFPT_FLOW_REMOVED", - 12: "OFPT_PORT_STATUS", - 13: "OFPT_PACKET_OUT", - 14: "OFPT_FLOW_MOD", - 15: "OFPT_GROUP_MOD", - 16: "OFPT_PORT_MOD", - 17: "OFPT_TABLE_MOD", - 18: "OFPT_MULTIPART_REQUEST", - 19: "OFPT_MULTIPART_REPLY", - 20: "OFPT_BARRIER_REQUEST", - 21: "OFPT_BARRIER_REPLY", - 22: "OFPT_QUEUE_GET_CONFIG_REQUEST", - 23: "OFPT_QUEUE_GET_CONFIG_REPLY", - 24: "OFPT_ROLE_REQUEST", - 25: "OFPT_ROLE_REPLY", - 26: "OFPT_GET_ASYNC_REQUEST", - 27: "OFPT_GET_ASYNC_REPLY", - 28: "OFPT_SET_ASYNC", - 29: "OFPT_METER_MOD"} - - -class OFPTHello(_ofp_header): - name = "OFPT_HELLO" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 0, ofp_type), - ShortField("len", None), - IntField("xid", 0), - PacketListField("elements", [], OFPHET, - length_from=lambda pkt: pkt.len - 8)] - - -##################################################### -# OFPT_ERROR # -##################################################### - - -ofp_error_type = {0: "OFPET_HELLO_FAILED", - 1: "OFPET_BAD_REQUEST", - 2: "OFPET_BAD_ACTION", - 3: "OFPET_BAD_INSTRUCTION", - 4: "OFPET_BAD_MATCH", - 5: "OFPET_FLOW_MOD_FAILED", - 6: "OFPET_GROUP_MOD_FAILED", - 7: "OFPET_PORT_MOD_FAILED", - 8: "OFPET_TABLE_MOD_FAILED", - 9: "OFPET_QUEUE_OP_FAILED", - 10: "OFPET_SWITCH_CONFIG_FAILED", - 11: "OFPET_ROLE_REQUEST_FAILED", - 12: "OFPET_METER_MOD_FAILED", - 13: "OFPET_TABLE_FEATURES_FAILED", - 65535: "OFPET_EXPERIMENTER"} - - -class OFPETHelloFailed(_ofp_header): - name = "OFPET_HELLO_FAILED" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 0, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPHFC_INCOMPATIBLE", - 1: "OFPHFC_EPERM"}), - OFPacketField("data", "", Raw)] - - -class OFPETBadRequest(_ofp_header): - name = "OFPET_BAD_REQUEST" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 1, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPBRC_BAD_VERSION", - 1: "OFPBRC_BAD_TYPE", - 2: "OFPBRC_BAD_MULTIPART", - 3: "OFPBRC_BAD_EXPERIMENTER", - 4: "OFPBRC_BAD_EXP_TYPE", - 5: "OFPBRC_EPERM", - 6: "OFPBRC_BAD_LEN", - 7: "OFPBRC_BUFFER_EMPTY", - 8: "OFPBRC_BUFFER_UNKNOWN", - 9: "OFPBRC_BAD_TABLE_ID", - 10: "OFPBRC_IS_SLAVE", - 11: "OFPBRC_BAD_PORT", - 12: "OFPBRC_BAD_PACKET", - 13: "OFPBRC_MULTIPART_BUFFER_OVERFLOW"}), # noqa: E501 - OFPacketField("data", "", Raw)] - - -class OFPETBadAction(_ofp_header): - name = "OFPET_BAD_ACTION" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 2, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPBAC_BAD_TYPE", - 1: "OFPBAC_BAD_LEN", - 2: "OFPBAC_BAD_EXPERIMENTER", - 3: "OFPBAC_BAD_EXP_TYPE", - 4: "OFPBAC_BAD_OUT_PORT", - 5: "OFPBAC_BAD_ARGUMENT", - 6: "OFPBAC_EPERM", - 7: "OFPBAC_TOO_MANY", - 8: "OFPBAC_BAD_QUEUE", - 9: "OFPBAC_BAD_OUT_GROUP", - 10: "OFPBAC_MATCH_INCONSISTENT", # noqa: E501 - 11: "OFPBAC_UNSUPPORTED_ORDER", # noqa: E501 - 12: "OFPBAC_BAD_TAG", - 13: "OFPBAC_BAD_SET_TYPE", - 14: "OFPBAC_BAD_SET_LEN", - 15: "OFPBAC_BAD_SET_ARGUMENT"}), # noqa: E501 - OFPacketField("data", "", Raw)] - - -class OFPETBadInstruction(_ofp_header): - name = "OFPET_BAD_INSTRUCTION" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 3, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPBIC_UNKNOWN_INST", - 1: "OFPBIC_UNSUP_INST", - 2: "OFPBIC_BAD_TABLE_ID", - 3: "OFPBIC_UNSUP_METADATA", - 4: "OFPBIC_UNSUP_METADATA_MASK", # noqa: E501 - 5: "OFPBIC_BAD_EXPERIMENTER", - 6: "OFPBIC_BAD_EXP_TYPE", - 7: "OFPBIC_BAD_LEN", - 8: "OFPBIC_EPERM"}), - OFPacketField("data", "", Raw)] - - -class OFPETBadMatch(_ofp_header): - name = "OFPET_BAD_MATCH" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 4, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPBMC_BAD_TYPE", - 1: "OFPBMC_BAD_LEN", - 2: "OFPBMC_BAD_TAG", - 3: "OFPBMC_BAD_DL_ADDR_MASK", - 4: "OFPBMC_BAD_NW_ADDR_MASK", - 5: "OFPBMC_BAD_WILDCARDS", - 6: "OFPBMC_BAD_FIELD", - 7: "OFPBMC_BAD_VALUE", - 8: "OFPBMC_BAD_MASK", - 9: "OFPBMC_BAD_PREREQ", - 10: "OFPBMC_DUP_FIELD", - 11: "OFPBMC_EPERM"}), - OFPacketField("data", "", Raw)] - - -class OFPETFlowModFailed(_ofp_header): - name = "OFPET_FLOW_MOD_FAILED" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 5, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPFMFC_UNKNOWN", - 1: "OFPFMFC_TABLE_FULL", - 2: "OFPFMFC_BAD_TABLE_ID", - 3: "OFPFMFC_OVERLAP", - 4: "OFPFMFC_EPERM", - 5: "OFPFMFC_BAD_TIMEOUT", - 6: "OFPFMFC_BAD_COMMAND", - 7: "OFPFMFC_BAD_FLAGS"}), - OFPacketField("data", "", Raw)] - - -class OFPETGroupModFailed(_ofp_header): - name = "OFPET_GROUP_MOD_FAILED" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 6, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPGMFC_GROUP_EXISTS", - 1: "OFPGMFC_INVALID_GROUP", - 2: "OFPGMFC_WEIGHT_UNSUPPORTED", # noqa: E501 - 3: "OFPGMFC_OUT_OF_GROUPS", - 4: "OFPGMFC_OUT_OF_BUCKETS", - 5: "OFPGMFC_CHAINING_UNSUPPORTED", # noqa: E501 - 6: "OFPGMFC_WATCH_UNSUPPORTED", # noqa: E501 - 7: "OFPGMFC_LOOP", - 8: "OFPGMFC_UNKNOWN_GROUP", - 9: "OFPGMFC_CHAINED_GROUP", - 10: "OFPGMFC_BAD_TYPE", - 11: "OFPGMFC_BAD_COMMAND", - 12: "OFPGMFC_BAD_BUCKET", - 13: "OFPGMFC_BAD_WATCH", - 14: "OFPFMFC_EPERM"}), - OFPacketField("data", "", Raw)] - - -class OFPETPortModFailed(_ofp_header): - name = "OFPET_PORT_MOD_FAILED" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 7, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPPMFC_BAD_PORT", - 1: "OFPPMFC_BAD_HW_ADDR", - 2: "OFPPMFC_BAD_CONFIG", - 3: "OFPPMFC_BAD_ADVERTISE", - 4: "OFPPMFC_EPERM"}), - OFPacketField("data", "", Raw)] - - -class OFPETTableModFailed(_ofp_header): - name = "OFPET_TABLE_MOD_FAILED" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 8, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPTMFC_BAD_TABLE", - 1: "OFPTMFC_BAD_CONFIG", - 2: "OFPTMFC_EPERM"}), - OFPacketField("data", "", Raw)] - - -class OFPETQueueOpFailed(_ofp_header): - name = "OFPET_QUEUE_OP_FAILED" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 9, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPQOFC_BAD_PORT", - 1: "OFPQOFC_BAD_QUEUE", - 2: "OFPQOFC_EPERM"}), - OFPacketField("data", "", Raw)] - - -class OFPETSwitchConfigFailed(_ofp_header): - name = "OFPET_SWITCH_CONFIG_FAILED" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 10, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPSCFC_BAD_FLAGS", - 1: "OFPSCFC_BAD_LEN", - 2: "OFPSCFC_EPERM"}), - OFPacketField("data", "", Raw)] - - -class OFPETRoleRequestFailed(_ofp_header): - name = "OFPET_ROLE_REQUEST_FAILED" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 11, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPRRFC_STALE", - 1: "OFPRRFC_UNSUP", - 2: "OFPRRFC_BAD_ROLE"}), - OFPacketField("data", "", Raw)] - - -class OFPETMeterModFailed(_ofp_header): - name = "OFPET_METER_MOD_FAILED" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 12, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPMMFC_UNKNOWN", - 1: "OFPMMFC_METER_EXISTS", - 2: "OFPMMFC_INVALID_METER", - 3: "OFPMMFC_UNKNOWN_METER", - 4: "OFPMMFC_BAD_COMMAND", - 5: "OFPMMFC_BAD_FLAGS", - 6: "OFPMMFC_BAD_RATE", - 7: "OFPMMFC_BAD_BURST", - 8: "OFPMMFC_BAD_BAND", - 9: "OFPMMFC_BAD_BAND_VALUE", - 10: "OFPMMFC_OUT_OF_METERS", - 11: "OFPMMFC_OUT_OF_BANDS"}), - OFPacketField("data", "", Raw)] - - -class OFPETTableFeaturesFailed(_ofp_header): - name = "OFPET_TABLE_FEATURES_FAILED" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", 13, ofp_error_type), - ShortEnumField("errcode", 0, {0: "OFPTFFC_BAD_TABLE", - 1: "OFPTFFC_BAD_METADATA", - 2: "OFPTFFC_BAD_TYPE", - 3: "OFPTFFC_BAD_LEN", - 4: "OFPTFFC_BAD_ARGUMENT", - 5: "OFPTFFC_EPERM"}), - OFPacketField("data", "", Raw)] - - -class OFPETExperimenter(_ofp_header): - name = "OFPET_EXPERIMENTER" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 1, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("errtype", "OFPET_EXPERIMENTER", ofp_error_type), # noqa: E501 - ShortField("exp_type", None), - IntField("experimenter", None), - OFPacketField("data", "", Raw)] - - -# ofp_error_cls allows generic method OpenFlow3() -# to choose the right class for dissection -ofp_error_cls = {0: OFPETHelloFailed, - 1: OFPETBadRequest, - 2: OFPETBadAction, - 3: OFPETBadInstruction, - 4: OFPETBadMatch, - 5: OFPETFlowModFailed, - 6: OFPETGroupModFailed, - 7: OFPETPortModFailed, - 8: OFPETTableModFailed, - 9: OFPETQueueOpFailed, - 10: OFPETSwitchConfigFailed, - 11: OFPETRoleRequestFailed, - 12: OFPETMeterModFailed, - 13: OFPETTableFeaturesFailed, - 65535: OFPETExperimenter} - -# end of OFPT_ERRORS # - - -class OFPTEchoRequest(_ofp_header): - name = "OFPT_ECHO_REQUEST" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 2, ofp_type), - ShortField("len", None), - IntField("xid", 0)] - - -class OFPTEchoReply(_ofp_header): - name = "OFPT_ECHO_REPLY" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 3, ofp_type), - ShortField("len", None), - IntField("xid", 0)] - - -class OFPTExperimenter(_ofp_header): - name = "OFPT_EXPERIMENTER" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 4, ofp_type), - ShortField("len", None), - IntField("xid", 0), - IntField("experimenter", 0), - IntField("exp_type", 0)] - - -class OFPTFeaturesRequest(_ofp_header): - name = "OFPT_FEATURES_REQUEST" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 5, ofp_type), - ShortField("len", None), - IntField("xid", 0)] - - -class OFPTFeaturesReply(_ofp_header): - name = "OFPT_FEATURES_REPLY" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 6, ofp_type), - ShortField("len", None), - IntField("xid", 0), - LongField("datapath_id", 0), - IntField("n_buffers", 0), - ByteField("n_tables", 1), - ByteField("auxiliary_id", 0), - XShortField("pad", 0), - FlagsField("capabilities", 0, 32, ["FLOW_STATS", - "TABLE_STATS", - "PORT_STATS", - "GROUP_STATS", - "RESERVED", # undefined - "IP_REASM", - "QUEUE_STATS", - "ARP_MATCH_IP", # undefined # noqa: E501 - "PORT_BLOCKED"]), - IntField("reserved", 0)] - - -class OFPTGetConfigRequest(_ofp_header): - name = "OFPT_GET_CONFIG_REQUEST" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 7, ofp_type), - ShortField("len", None), - IntField("xid", 0)] - - -class OFPTGetConfigReply(_ofp_header): - name = "OFPT_GET_CONFIG_REPLY" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 8, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("flags", 0, {0: "FRAG_NORMAL", - 1: "FRAG_DROP", - 2: "FRAG_REASM", - 3: "FRAG_MASK"}), - ShortField("miss_send_len", 0)] - - -class OFPTSetConfig(_ofp_header): - name = "OFPT_SET_CONFIG" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 9, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("flags", 0, {0: "FRAG_NORMAL", - 1: "FRAG_DROP", - 2: "FRAG_REASM", - 3: "FRAG_MASK"}), - ShortField("miss_send_len", 128)] - - -class OFPTPacketIn(_ofp_header): - name = "OFPT_PACKET_IN" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 10, ofp_type), - ShortField("len", None), - IntField("xid", 0), - IntEnumField("buffer_id", "NO_BUFFER", ofp_buffer), - ShortField("total_len", 0), - ByteEnumField("reason", 0, {0: "OFPR_NO_MATCH", - 1: "OFPR_ACTION", - 2: "OFPR_INVALID_TTL"}), - ByteEnumField("table_id", 0, ofp_table), - LongField("cookie", 0), - MatchField("match"), - XShortField("pad", 0), - PacketField("data", "", Ether)] - - -class OFPTFlowRemoved(_ofp_header): - name = "OFPT_FLOW_REMOVED" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 11, ofp_type), - ShortField("len", None), - IntField("xid", 0), - LongField("cookie", 0), - ShortField("priority", 0), - ByteEnumField("reason", 0, {0: "OFPRR_IDLE_TIMEOUT", - 1: "OFPRR_HARD_TIMEOUT", - 2: "OFPRR_DELETE", - 3: "OFPRR_GROUP_DELETE"}), - ByteEnumField("table_id", 0, ofp_table), - IntField("duration_sec", 0), - IntField("duration_nsec", 0), - ShortField("idle_timeout", 0), - ShortField("hard_timeout", 0), - LongField("packet_count", 0), - LongField("byte_count", 0), - MatchField("match")] - - -class OFPTPortStatus(_ofp_header): - name = "OFPT_PORT_STATUS" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 12, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ByteEnumField("reason", 0, {0: "OFPPR_ADD", - 1: "OFPPR_DELETE", - 2: "OFPPR_MODIFY"}), - XBitField("pad", 0, 56), - PacketField("desc", OFPPort(), OFPPort)] - - -class OFPTPacketOut(_ofp_header): - name = "OFPT_PACKET_OUT" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 13, ofp_type), - ShortField("len", None), - IntField("xid", 0), - IntEnumField("buffer_id", "NO_BUFFER", ofp_buffer), - IntEnumField("in_port", "CONTROLLER", ofp_port_no), - FieldLenField("actions_len", None, fmt="H", length_of="actions"), # noqa: E501 - XBitField("pad", 0, 48), - PacketListField("actions", [], OFPAT, - OFPAT, - length_from=lambda pkt:pkt.actions_len), - PacketField("data", "", Ether)] - - -class OFPTFlowMod(_ofp_header): - name = "OFPT_FLOW_MOD" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 14, ofp_type), - ShortField("len", None), - IntField("xid", 0), - LongField("cookie", 0), - LongField("cookie_mask", 0), - ByteEnumField("table_id", 0, ofp_table), - ByteEnumField("cmd", 0, {0: "OFPFC_ADD", - 1: "OFPFC_MODIFY", - 2: "OFPFC_MODIFY_STRICT", - 3: "OFPFC_DELETE", - 4: "OFPFC_DELETE_STRICT"}), - ShortField("idle_timeout", 0), - ShortField("hard_timeout", 0), - ShortField("priority", 0), - IntEnumField("buffer_id", "NO_BUFFER", ofp_buffer), - IntEnumField("out_port", "ANY", ofp_port_no), - IntEnumField("out_group", "ANY", ofp_group), - FlagsField("flags", 0, 16, ["SEND_FLOW_REM", - "CHECK_OVERLAP", - "RESET_COUNTS", - "NO_PKT_COUNTS", - "NO_BYT_COUNTS"]), - XShortField("pad", 0), - MatchField("match"), - PacketListField("instructions", [], OFPIT, - length_from=lambda pkt:pkt.len - 48 - (pkt.match.len + (8 - pkt.match.len % 8) % 8))] # noqa: E501 - # include match padding to match.len - - -class OFPTGroupMod(_ofp_header): - name = "OFPT_GROUP_MOD" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 15, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("cmd", 0, {0: "OFPGC_ADD", - 1: "OFPGC_MODIFY", - 2: "OFPGC_DELETE"}), - ByteEnumField("group_type", 0, {0: "OFPGT_ALL", - 1: "OFPGT_SELECT", - 2: "OFPGT_INDIRECT", - 3: "OFPGT_FF"}), - XByteField("pad", 0), - IntEnumField("group_id", 0, ofp_group), - PacketListField("buckets", [], OFPBucket, - length_from=lambda pkt:pkt.len - 16)] - - -class OFPTPortMod(_ofp_header): - name = "OFPT_PORT_MOD" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 16, ofp_type), - ShortField("len", None), - IntField("xid", 0), - IntEnumField("port_no", 0, ofp_port_no), - XIntField("pad1", 0), - MACField("hw_addr", "0"), - XShortField("pad2", 0), - FlagsField("config", 0, 32, ofp_port_config), - FlagsField("mask", 0, 32, ofp_port_config), - FlagsField("advertise", 0, 32, ofp_port_features), - XIntField("pad3", 0)] - - -class OFPTTableMod(_ofp_header): - name = "OFPT_TABLE_MOD" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 17, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ByteEnumField("table_id", 0, ofp_table), - X3BytesField("pad", 0), - IntEnumField("config", 0, {3: "OFPTC_DEPRECATED_MASK"})] - - -##################################################### -# OFPT_MULTIPART # -##################################################### - - -ofp_multipart_types = {0: "OFPMP_DESC", - 1: "OFPMP_FLOW", - 2: "OFPMP_AGGREGATE", - 3: "OFPMP_TABLE", - 4: "OFPMP_PORT_STATS", - 5: "OFPMP_QUEUE", - 6: "OFPMP_GROUP", - 7: "OFPMP_GROUP_DESC", - 8: "OFPMP_GROUP_FEATURES", - 9: "OFPMP_METER", - 10: "OFPMP_METER_CONFIG", - 11: "OFPMP_METER_FEATURES", - 12: "OFPMP_TABLE_FEATURES", - 13: "OFPMP_PORT_DESC", - 65535: "OFPST_VENDOR"} - -ofpmp_request_flags = ["REQ_MORE"] - -ofpmp_reply_flags = ["REPLY_MORE"] - - -class OFPMPRequestDesc(_ofp_header): - name = "OFPMP_REQUEST_DESC" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 0, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_request_flags), - XIntField("pad", 0)] - - -class OFPMPReplyDesc(_ofp_header): - name = "OFPMP_REPLY_DESC" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 0, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad", 0), - StrFixedLenField("mfr_desc", "", 256), - StrFixedLenField("hw_desc", "", 256), - StrFixedLenField("sw_desc", "", 256), - StrFixedLenField("serial_num", "", 32), - StrFixedLenField("dp_desc", "", 256)] - - -class OFPMPRequestFlow(_ofp_header): - name = "OFPMP_REQUEST_FLOW" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 1, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_request_flags), - XIntField("pad1", 0), - ByteEnumField("table_id", "ALL", ofp_table), - X3BytesField("pad2", 0), - IntEnumField("out_port", "ANY", ofp_port_no), - IntEnumField("out_group", "ANY", ofp_group), - IntField("pad3", 0), - LongField("cookie", 0), - LongField("cookie_mask", 0), - MatchField("match")] - - -class OFPFlowStats(_ofp_header_item): - name = "OFP_FLOW_STATS" - fields_desc = [ShortField("len", None), - ByteEnumField("table_id", 0, ofp_table), - XByteField("pad1", 0), - IntField("duration_sec", 0), - IntField("duration_nsec", 0), - ShortField("priority", 0), - ShortField("idle_timeout", 0), - ShortField("hard_timeout", 0), - FlagsField("flags", 0, 16, ["SEND_FLOW_REM", - "CHECK_OVERLAP", - "RESET_COUNTS", - "NO_PKT_COUNTS", - "NO_BYT_COUNTS"]), - IntField("pad2", 0), - LongField("cookie", 0), - LongField("packet_count", 0), - LongField("byte_count", 0), - MatchField("match"), - PacketListField("instructions", [], OFPIT, - length_from=lambda pkt:pkt.len - 56 - pkt.match.len)] # noqa: E501 - - def extract_padding(self, s): - return b"", s - - -class OFPMPReplyFlow(_ofp_header): - name = "OFPMP_REPLY_FLOW" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 1, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad1", 0), - PacketListField("flow_stats", [], OFPFlowStats, - length_from=lambda pkt:pkt.len - 16)] - - -class OFPMPRequestAggregate(OFPMPRequestFlow): - name = "OFPMP_REQUEST_AGGREGATE" - mp_type = 2 - - -class OFPMPReplyAggregate(_ofp_header): - name = "OFPMP_REPLY_AGGREGATE" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 2, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad1", 0), - LongField("packet_count", 0), - LongField("byte_count", 0), - IntField("flow_count", 0), - XIntField("pad2", 0)] - - -class OFPMPRequestTable(_ofp_header): - name = "OFPMP_REQUEST_TABLE" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 3, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_request_flags), - XIntField("pad1", 0)] - - -class OFPTableStats(Packet): - name = "OFP_TABLE_STATS" - fields_desc = [ByteEnumField("table_id", 0, ofp_table), - X3BytesField("pad1", 0), - IntField("active_count", 0), - LongField("lookup_count", 0), - LongField("matched_count", 0)] - - def extract_padding(self, s): - return b"", s - - -class OFPMPReplyTable(_ofp_header): - name = "OFPMP_REPLY_TABLE" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 3, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad1", 0), - PacketListField("table_stats", None, OFPTableStats, - length_from=lambda pkt:pkt.len - 16)] - - -class OFPMPRequestPortStats(_ofp_header): - name = "OFPMP_REQUEST_PORT_STATS" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 4, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_request_flags), - XIntField("pad1", 0), - IntEnumField("port_no", "ANY", ofp_port_no), - XIntField("pad", 0)] - - -class OFPPortStats(Packet): - def extract_padding(self, s): - return b"", s - name = "OFP_PORT_STATS" - fields_desc = [IntEnumField("port_no", 0, ofp_port_no), - XIntField("pad", 0), - LongField("rx_packets", 0), - LongField("tx_packets", 0), - LongField("rx_bytes", 0), - LongField("tx_bytes", 0), - LongField("rx_dropped", 0), - LongField("tx_dropped", 0), - LongField("rx_errors", 0), - LongField("tx_errors", 0), - LongField("rx_frame_err", 0), - LongField("rx_over_err", 0), - LongField("rx_crc_err", 0), - LongField("collisions", 0), - IntField("duration_sec", 0), - IntField("duration_nsec", 0)] - - -class OFPMPReplyPortStats(_ofp_header): - name = "OFPMP_REPLY_PORT_STATS" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 4, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad1", 0), - PacketListField("port_stats", None, OFPPortStats, - length_from=lambda pkt:pkt.len - 16)] - - -class OFPMPRequestQueue(_ofp_header): - name = "OFPMP_REQUEST_QUEUE" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 5, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_request_flags), - XIntField("pad1", 0), - IntEnumField("port_no", "ANY", ofp_port_no), - IntEnumField("queue_id", "ALL", ofp_queue)] - - -class OFPQueueStats(Packet): - name = "OFP_QUEUE_STATS" - fields_desc = [IntEnumField("port_no", 0, ofp_port_no), - IntEnumField("queue_id", 0, ofp_queue), - LongField("tx_bytes", 0), - LongField("tx_packets", 0), - LongField("tx_errors", 0), - IntField("duration_sec", 0), - IntField("duration_nsec", 0)] - - def extract_padding(self, s): - return b"", s - - -class OFPMPReplyQueue(_ofp_header): - name = "OFPMP_REPLY_QUEUE" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 5, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad1", 0), - PacketListField("queue_stats", None, OFPQueueStats, - length_from=lambda pkt:pkt.len - 16)] - - -class OFPMPRequestGroup(_ofp_header): - name = "OFPMP_REQUEST_GROUP" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 6, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_request_flags), - XIntField("pad1", 0), - IntEnumField("group_id", "ANY", ofp_group), - XIntField("pad2", 0)] - - -class OFPBucketStats(Packet): - name = "OFP_BUCKET_STATS" - fields_desc = [LongField("packet_count", 0), - LongField("byte_count", 0)] - - def extract_padding(self, s): - return b"", s - - -class OFPGroupStats(_ofp_header_item): - name = "OFP_GROUP_STATS" - fields_desc = [ShortField("len", None), - XShortField("pad1", 0), - IntEnumField("group_id", 0, ofp_group), - IntField("ref_count", 0), - IntField("pad2", 0), - LongField("packet_count", 0), - LongField("byte_count", 0), - IntField("duration_sec", 0), - IntField("duration_nsec", 0), - PacketListField("bucket_stats", None, OFPBucketStats, - length_from=lambda pkt:pkt.len - 40)] - - def extract_padding(self, s): - return b"", s - - -class OFPMPReplyGroup(_ofp_header): - name = "OFPMP_REPLY_GROUP" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 6, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad1", 0), - PacketListField("group_stats", [], OFPGroupStats, - length_from=lambda pkt:pkt.len - 16)] - - -class OFPMPRequestGroupDesc(_ofp_header): - name = "OFPMP_REQUEST_GROUP_DESC" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 7, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_request_flags), - XIntField("pad1", 0)] - - -class OFPGroupDesc(_ofp_header_item): - name = "OFP_GROUP_DESC" - fields_desc = [ShortField("len", None), - ByteEnumField("type", 0, {0: "OFPGT_ALL", - 1: "OFPGT_SELECT", - 2: "OFPGT_INDIRECT", - 3: "OFPGT_FF"}), - XByteField("pad", 0), - IntEnumField("group_id", 0, ofp_group), - PacketListField("buckets", None, OFPBucket, - length_from=lambda pkt: pkt.len - 8)] - - def extract_padding(self, s): - return b"", s - - -class OFPMPReplyGroupDesc(_ofp_header): - name = "OFPMP_REPLY_GROUP_DESC" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 7, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad1", 0), - PacketListField("group_descs", [], OFPGroupDesc, - length_from=lambda pkt:pkt.len - 16)] - - -class OFPMPRequestGroupFeatures(_ofp_header): - name = "OFPMP_REQUEST_GROUP_FEATURES" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 8, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_request_flags), - XIntField("pad1", 0)] - - -ofp_action_types_flags = [v for v in six.itervalues(ofp_action_types) - if v != 'OFPAT_EXPERIMENTER'] - - -class OFPMPReplyGroupFeatures(_ofp_header): - name = "OFPMP_REPLY_GROUP_FEATURES" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 8, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad1", 0), - FlagsField("types", 0, 32, ["ALL", - "SELECT", - "INDIRECT", - "FF"]), - FlagsField("capabilities", 0, 32, ["SELECT_WEIGHT", - "SELECT_LIVENESS", - "CHAINING", - "CHAINING_CHECKS"]), - IntField("max_group_all", 0), - IntField("max_group_select", 0), - IntField("max_group_indirect", 0), - IntField("max_group_ff", 0), - # no ofpat_experimenter flag - FlagsField("actions_all", 0, 32, ofp_action_types_flags), - FlagsField("actions_select", 0, 32, ofp_action_types_flags), - FlagsField("actions_indirect", 0, 32, ofp_action_types_flags), # noqa: E501 - FlagsField("actions_ff", 0, 32, ofp_action_types_flags)] - - -class OFPMPRequestMeter(_ofp_header): - name = "OFPMP_REQUEST_METER" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 9, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_request_flags), - XIntField("pad1", 0), - IntEnumField("meter_id", "ALL", ofp_meter), - XIntField("pad2", 0)] - - -class OFPMeterBandStats(Packet): - name = "OFP_METER_BAND_STATS" - fields_desc = [LongField("packet_band_count", 0), - LongField("byte_band_count", 0)] - - def extract_padding(self, s): - return b"", s - - -class OFPMeterStats(Packet): - name = "OFP_GROUP_STATS" - fields_desc = [IntEnumField("meter_id", 1, ofp_meter), - ShortField("len", None), - XBitField("pad", 0, 48), - IntField("flow_count", 0), - LongField("packet_in_count", 0), - LongField("byte_in_count", 0), - IntField("duration_sec", 0), - IntField("duration_nsec", 0), - PacketListField("band_stats", None, OFPMeterBandStats, - length_from=lambda pkt:pkt.len - 40)] - - def post_build(self, p, pay): - if self.len is None: - tmp_len = len(p) + len(pay) - p = p[:4] + struct.pack("!H", tmp_len) + p[6:] - return p + pay - - def extract_padding(self, s): - return b"", s - - -class OFPMPReplyMeter(_ofp_header): - name = "OFPMP_REPLY_METER" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 9, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad1", 0), - PacketListField("meter_stats", [], OFPMeterStats, - length_from=lambda pkt:pkt.len - 16)] - - -class OFPMPRequestMeterConfig(_ofp_header): - name = "OFPMP_REQUEST_METER_CONFIG" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 10, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_request_flags), - XIntField("pad1", 0), - IntEnumField("meter_id", "ALL", ofp_meter), - XIntField("pad2", 0)] - - -class OFPMeterConfig(_ofp_header_item): - name = "OFP_METER_CONFIG" - fields_desc = [ShortField("len", None), - FlagsField("flags", 0, 16, ["KBPS", - "PKTPS", - "BURST", - "STATS"]), - IntEnumField("meter_id", 1, ofp_meter), - PacketListField("bands", [], OFPMBT, - length_from=lambda pkt:pkt.len - 8)] - - def extract_padding(self, s): - return b"", s - - -class OFPMPReplyMeterConfig(_ofp_header): - name = "OFPMP_REPLY_METER_CONFIG" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 10, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad1", 0), - PacketListField("meter_configs", [], OFPMeterConfig, - length_from=lambda pkt:pkt.len - 16)] - - -class OFPMPRequestMeterFeatures(_ofp_header): - name = "OFPMP_REQUEST_METER_FEATURES" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 11, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_request_flags), - XIntField("pad1", 0)] - - -class OFPMPReplyMeterFeatures(_ofp_header): - name = "OFPMP_REPLY_METER_FEATURES" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 11, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad1", 0), - IntField("max_meter", 0), - FlagsField("band_types", 0, 32, ["DROP", - "DSCP_REMARK", - "EXPERIMENTER"]), - FlagsField("capabilities", 0, 32, ["KPBS", - "PKTPS", - "BURST", - "STATS"]), - ByteField("max_bands", 0), - ByteField("max_color", 0), - XShortField("pad2", 0)] - - -# table features for multipart messages # - - -class OFPTFPT(Packet): - name = "Dummy OpenFlow3 Table Features Properties Header" - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 2: - t = struct.unpack("!H", _pkt[:2])[0] - return ofp_table_features_prop_cls.get(t, Raw) - return Raw - - def post_build(self, p, pay): - tmp_len = self.len - if tmp_len is None: - tmp_len = len(p) + len(pay) - p = p[:2] + struct.pack("!H", tmp_len) + p[4:] - # every message will be padded correctly - zero_bytes = (8 - tmp_len % 8) % 8 - p += b"\x00" * zero_bytes - return p + pay - - def extract_padding(self, s): - return b"", s - - -ofp_table_features_prop_types = {0: "OFPTFPT_INSTRUCTIONS", - 1: "OFPTFPT_INSTRUCTIONS_MISS", - 2: "OFPTFPT_NEXT_TABLES", - 3: "OFPTFPT_NEXT_TABLES_MISS", - 4: "OFPTFPT_WRITE_ACTIONS", - 5: "OFPTFPT_WRITE_ACTIONS_MISS", - 6: "OFPTFPT_APPLY_ACTIONS", - 7: "OFPTFPT_APPLY_ACTIONS_MISS", - 8: "OFPTFPT_MATCH", - 10: "OFPTFPT_WILDCARDS", - 12: "OFPTFPT_WRITE_SETFIELD", - 13: "OFPTFPT_WRITE_SETFIELD_MISS", - 14: "OFPTFPT_APPLY_SETFIELD", - 15: "OFPTFPT_APPLY_SETFIELD_MISS", - 65534: "OFPTFPT_EXPERIMENTER", - 65535: "OFPTFPT_EXPERIMENTER_MISS"} - - -class OFPTFPTInstructions(OFPTFPT): - name = "OFPTFPT_INSTRUCTIONS" - fields_desc = [ShortField("type", 0), - ShortField("len", None), - PacketListField("instruction_ids", [], OFPITID, - length_from=lambda pkt:pkt.len - 4)] - - -class OFPTFPTInstructionsMiss(OFPTFPT): - name = "OFPTFPT_INSTRUCTIONS_MISS" - fields_desc = [ShortField("type", 1), - ShortField("len", None), - PacketListField("instruction_ids", [], OFPITID, - length_from=lambda pkt:pkt.len - 4)] - - -class OFPTableID(Packet): - name = "OFP_TABLE_ID" - fields_desc = [ByteEnumField("table_id", 0, ofp_table)] - - def extract_padding(self, s): - return b"", s - - -class OFPTFPTNextTables(OFPTFPT): - name = "OFPTFPT_NEXT_TABLES" - fields_desc = [ShortField("type", 2), - ShortField("len", None), - PacketListField("next_table_ids", None, OFPTableID, - length_from=lambda pkt:pkt.len - 4)] - - -class OFPTFPTNextTablesMiss(OFPTFPT): - name = "OFPTFPT_NEXT_TABLES_MISS" - fields_desc = [ShortField("type", 3), - ShortField("len", None), - PacketListField("next_table_ids", None, OFPTableID, - length_from=lambda pkt:pkt.len - 4)] - - -class OFPTFPTWriteActions(OFPTFPT): - name = "OFPTFPT_WRITE_ACTIONS" - fields_desc = [ShortField("type", 4), - ShortField("len", None), - PacketListField("action_ids", [], OFPATID, - length_from=lambda pkt:pkt.len - 4)] - - -class OFPTFPTWriteActionsMiss(OFPTFPT): - name = "OFPTFPT_WRITE_ACTIONS_MISS" - fields_desc = [ShortField("type", 5), - ShortField("len", None), - PacketListField("action_ids", [], OFPATID, - length_from=lambda pkt:pkt.len - 4)] - - -class OFPTFPTApplyActions(OFPTFPT): - name = "OFPTFPT_APPLY_ACTIONS" - fields_desc = [ShortField("type", 6), - ShortField("len", None), - PacketListField("action_ids", [], OFPATID, - length_from=lambda pkt:pkt.len - 4)] - - -class OFPTFPTApplyActionsMiss(OFPTFPT): - name = "OFPTFPT_APPLY_ACTIONS_MISS" - fields_desc = [ShortField("type", 7), - ShortField("len", None), - PacketListField("action_ids", [], OFPATID, - length_from=lambda pkt:pkt.len - 4)] - - -class OFPTFPTMatch(OFPTFPT): - name = "OFPTFPT_MATCH" - fields_desc = [ShortField("type", 8), - ShortField("len", None), - PacketListField("oxm_ids", [], OXMID, - length_from=lambda pkt:pkt.len - 4)] - - -class OFPTFPTWildcards(OFPTFPT): - name = "OFPTFPT_WILDCARDS" - fields_desc = [ShortField("type", 10), - ShortField("len", None), - PacketListField("oxm_ids", [], OXMID, - length_from=lambda pkt:pkt.len - 4)] - - -class OFPTFPTWriteSetField(OFPTFPT): - name = "OFPTFPT_WRITE_SETFIELD" - fields_desc = [ShortField("type", 12), - ShortField("len", None), - PacketListField("oxm_ids", [], OXMID, - length_from=lambda pkt:pkt.len - 4)] - - -class OFPTFPTWriteSetFieldMiss(OFPTFPT): - name = "OFPTFPT_WRITE_SETFIELD_MISS" - fields_desc = [ShortField("type", 13), - ShortField("len", None), - PacketListField("oxm_ids", [], OXMID, - length_from=lambda pkt:pkt.len - 4)] - - -class OFPTFPTApplySetField(OFPTFPT): - name = "OFPTFPT_APPLY_SETFIELD" - fields_desc = [ShortField("type", 14), - ShortField("len", None), - PacketListField("oxm_ids", [], OXMID, - length_from=lambda pkt:pkt.len - 4)] - - -class OFPTFPTApplySetFieldMiss(OFPTFPT): - name = "OFPTFPT_APPLY_SETFIELD_MISS" - fields_desc = [ShortField("type", 15), - ShortField("len", None), - PacketListField("oxm_ids", [], OXMID, - length_from=lambda pkt:pkt.len - 4)] - - -class OFPTFPTExperimenter(OFPTFPT): - name = "OFPTFPT_EXPERIMENTER" - fields_desc = [ShortField("type", 65534), - ShortField("len", None), - IntField("experimenter", 0), - IntField("exp_type", 0), - PacketLenField("experimenter_data", None, Raw, - length_from=lambda pkt: pkt.len - 12)] - - -class OFPTFPTExperimenterMiss(OFPTFPT): - name = "OFPTFPT_EXPERIMENTER_MISS" - fields_desc = [ShortField("type", 65535), - ShortField("len", None), - IntField("experimenter", 0), - IntField("exp_type", 0), - PacketLenField("experimenter_data", None, Raw, - length_from=lambda pkt: pkt.len - 12)] - - -ofp_table_features_prop_cls = {0: OFPTFPTInstructions, - 1: OFPTFPTInstructionsMiss, - 2: OFPTFPTNextTables, - 3: OFPTFPTNextTablesMiss, - 4: OFPTFPTWriteActions, - 5: OFPTFPTWriteActionsMiss, - 6: OFPTFPTApplyActions, - 7: OFPTFPTApplyActionsMiss, - 8: OFPTFPTMatch, - 10: OFPTFPTWildcards, - 12: OFPTFPTWriteSetField, - 13: OFPTFPTWriteSetFieldMiss, - 14: OFPTFPTApplySetField, - 15: OFPTFPTApplySetFieldMiss, - 65534: OFPTFPTExperimenter, - 65535: OFPTFPTExperimenterMiss} - - -class OFPTableFeatures(_ofp_header_item): - name = "OFP_TABLE_FEATURES" - fields_desc = [ShortField("len", None), - ByteEnumField("table_id", 0, ofp_table), - XBitField("pad", 0, 40), - StrFixedLenField("table_name", "", 32), - LongField("metadata_match", 0), - LongField("metadata_write", 0), - IntEnumField("config", 0, {0: "OFPTC_NO_MASK", - 3: "OFPTC_DEPRECATED_MASK"}), - IntField("max_entries", 0), - PacketListField("properties", [], OFPTFPT, - length_from=lambda pkt:pkt.len - 64)] - - def extract_padding(self, s): - return b"", s - - -class OFPMPRequestTableFeatures(_ofp_header): - name = "OFPMP_REQUEST_TABLE_FEATURES" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 12, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_request_flags), - XIntField("pad1", 0), - PacketListField("table_features", [], OFPTableFeatures, - length_from=lambda pkt:pkt.len - 16)] - - -class OFPMPReplyTableFeatures(_ofp_header): - name = "OFPMP_REPLY_TABLE_FEATURES" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 12, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad1", 0), - PacketListField("table_features", [], OFPTableFeatures, - length_from=lambda pkt:pkt.len - 16)] - - -# end of table features # - - -class OFPMPRequestPortDesc(_ofp_header): - name = "OFPMP_REQUEST_PORT_DESC" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 13, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_request_flags), - XIntField("pad1", 0), - IntEnumField("port_no", 0, ofp_port_no), - XIntField("pad", 0)] - - -class OFPMPReplyPortDesc(_ofp_header): - name = "OFPMP_REPLY_PORT_DESC" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 13, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad1", 0), - PacketListField("ports", None, OFPPort, - length_from=lambda pkt:pkt.len - 16)] - - -class OFPMPRequestExperimenter(_ofp_header): - name = "OFPST_REQUEST_EXPERIMENTER" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 18, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 65535, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_request_flags), - XIntField("pad1", 0), - IntField("experimenter", 0), - IntField("exp_type", 0)] - - -class OFPMPReplyExperimenter(_ofp_header): - name = "OFPST_REPLY_EXPERIMENTER" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 19, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("mp_type", 65535, ofp_multipart_types), - FlagsField("flags", 0, 16, ofpmp_reply_flags), - XIntField("pad1", 0), - IntField("experimenter", 0), - IntField("exp_type", 0)] - - -# ofp_multipart_request/reply_cls allows generic method OpenFlow3() -# to choose the right class for dissection -ofp_multipart_request_cls = {0: OFPMPRequestDesc, - 1: OFPMPRequestFlow, - 2: OFPMPRequestAggregate, - 3: OFPMPRequestTable, - 4: OFPMPRequestPortStats, - 5: OFPMPRequestQueue, - 6: OFPMPRequestGroup, - 7: OFPMPRequestGroupDesc, - 8: OFPMPRequestGroupFeatures, - 9: OFPMPRequestMeter, - 10: OFPMPRequestMeterConfig, - 11: OFPMPRequestMeterFeatures, - 12: OFPMPRequestTableFeatures, - 13: OFPMPRequestPortDesc, - 65535: OFPMPRequestExperimenter} - -ofp_multipart_reply_cls = {0: OFPMPReplyDesc, - 1: OFPMPReplyFlow, - 2: OFPMPReplyAggregate, - 3: OFPMPReplyTable, - 4: OFPMPReplyPortStats, - 5: OFPMPReplyQueue, - 6: OFPMPReplyGroup, - 7: OFPMPReplyGroupDesc, - 8: OFPMPReplyGroupFeatures, - 9: OFPMPReplyMeter, - 10: OFPMPReplyMeterConfig, - 11: OFPMPReplyMeterFeatures, - 12: OFPMPReplyTableFeatures, - 13: OFPMPReplyPortDesc, - 65535: OFPMPReplyExperimenter} - -# end of OFPT_MULTIPART # - - -class OFPTBarrierRequest(_ofp_header): - name = "OFPT_BARRIER_REQUEST" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 20, ofp_type), - ShortField("len", None), - IntField("xid", 0)] - - -class OFPTBarrierReply(_ofp_header): - name = "OFPT_BARRIER_REPLY" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 21, ofp_type), - ShortField("len", None), - IntField("xid", 0)] - - -class OFPTQueueGetConfigRequest(_ofp_header): - name = "OFPT_QUEUE_GET_CONFIG_REQUEST" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 22, ofp_type), - ShortField("len", None), - IntField("xid", 0), - IntEnumField("port_no", "ANY", ofp_port_no), - XIntField("pad", 0)] - - -class OFPTQueueGetConfigReply(_ofp_header): - name = "OFPT_QUEUE_GET_CONFIG_REPLY" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 23, ofp_type), - ShortField("len", None), - IntField("xid", 0), - IntEnumField("port", 0, ofp_port_no), - XIntField("pad", 0), - PacketListField("queues", [], OFPPacketQueue, - length_from=lambda pkt:pkt.len - 16)] - - -class OFPTRoleRequest(_ofp_header): - name = "OFPT_ROLE_REQUEST" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 24, ofp_type), - ShortField("len", None), - IntField("xid", 0), - IntEnumField("role", 0, {0: "OFPCR_ROLE_NOCHANGE", - 1: "OFPCR_ROLE_EQUAL", - 2: "OFPCR_ROLE_MASTER", - 3: "OFPCR_ROLE_SLAVE"}), - XIntField("pad", 0), - LongField("generation_id", 0)] - - -class OFPTRoleReply(OFPTRoleRequest): - name = "OFPT_ROLE_REPLY" - type = 25 - - -class OFPTGetAsyncRequest(_ofp_header): - name = "OFPT_GET_ASYNC_REQUEST" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 26, ofp_type), - ShortField("len", 8), - IntField("xid", 0)] - - -ofp_packet_in_reason = ["NO_MATCH", - "ACTION", - "INVALID_TTL"] - -ofp_port_reason = ["ADD", - "DELETE", - "MODIFY"] - -ofp_flow_removed_reason = ["IDLE_TIMEOUT", - "HARD_TIMEOUT", - "DELETE", - "GROUP_DELETE"] - - -class OFPTGetAsyncReply(_ofp_header): - name = "OFPT_GET_ASYNC_REPLY" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 27, ofp_type), - ShortField("len", 32), - IntField("xid", 0), - FlagsField("packet_in_mask_master", 0, 32, ofp_packet_in_reason), # noqa: E501 - FlagsField("packet_in_mask_slave", 0, 32, ofp_packet_in_reason), # noqa: E501 - FlagsField("port_status_mask_master", 0, 32, ofp_port_reason), # noqa: E501 - FlagsField("port_status_mask_slave", 0, 32, ofp_port_reason), # noqa: E501 - FlagsField("flow_removed_mask_master", 0, 32, ofp_flow_removed_reason), # noqa: E501 - FlagsField("flow_removed_mask_slave", 0, 32, ofp_flow_removed_reason)] # noqa: E501 - - -class OFPTSetAsync(OFPTGetAsyncReply): - name = "OFPT_SET_ASYNC" - type = 28 - - -class OFPTMeterMod(_ofp_header): - name = "OFPT_METER_MOD" - fields_desc = [ByteEnumField("version", 0x04, ofp_version), - ByteEnumField("type", 29, ofp_type), - ShortField("len", None), - IntField("xid", 0), - ShortEnumField("cmd", 0, {0: "OFPMC_ADD", - 1: "OFPMC_MODIFY", - 2: "OFPMC_DELETE"}), - FlagsField("flags", 0, 16, ["KBPS", - "PKTPS", - "BURST", - "STATS"]), - IntEnumField("meter_id", 1, ofp_meter), - PacketListField("bands", [], OFPMBT, - length_from=lambda pkt:pkt.len - 16)] - - -# ofpt_cls allows generic method OpenFlow3() to choose the right class for dissection # noqa: E501 -ofpt_cls = {0: OFPTHello, - # 1: OFPTError, - 2: OFPTEchoRequest, - 3: OFPTEchoReply, - 4: OFPTExperimenter, - 5: OFPTFeaturesRequest, - 6: OFPTFeaturesReply, - 7: OFPTGetConfigRequest, - 8: OFPTGetConfigReply, - 9: OFPTSetConfig, - 10: OFPTPacketIn, - 11: OFPTFlowRemoved, - 12: OFPTPortStatus, - 13: OFPTPacketOut, - 14: OFPTFlowMod, - 15: OFPTGroupMod, - 16: OFPTPortMod, - 17: OFPTTableMod, - # 18: OFPTMultipartRequest, - # 19: OFPTMultipartReply, - 20: OFPTBarrierRequest, - 21: OFPTBarrierReply, - 22: OFPTQueueGetConfigRequest, - 23: OFPTQueueGetConfigReply, - 24: OFPTRoleRequest, - 25: OFPTRoleReply, - 26: OFPTGetAsyncRequest, - 27: OFPTGetAsyncReply, - 28: OFPTSetAsync, - 29: OFPTMeterMod} diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ospf.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/ospf.py deleted file mode 100644 index 8cbe9a3ed5..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ospf.py +++ /dev/null @@ -1,754 +0,0 @@ -#!/usr/bin/env python - -# scapy.contrib.description = Open Shortest Path First (OSPF) -# scapy.contrib.status = loads - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -""" -OSPF extension for Scapy - -This module provides Scapy layers for the Open Shortest Path First -routing protocol as defined in RFC 2328 and RFC 5340. - -Copyright (c) 2008 Dirk Loss : mail dirk-loss de -Copyright (c) 2010 Jochen Bartl : jochen.bartl gmail com -""" - - -import struct - -from scapy.packet import bind_layers, Packet -from scapy.fields import BitField, ByteEnumField, ByteField, \ - ConditionalField, DestIP6Field, FieldLenField, \ - FieldListField, FlagsField, IP6Field, IP6PrefixField, IPField, \ - IntEnumField, IntField, LenField, PacketListField, ShortEnumField, \ - ShortField, StrLenField, X3BytesField, XIntField, XLongField, XShortField -from scapy.layers.inet import IP, DestIPField -from scapy.layers.inet6 import IPv6, in6_chksum -from scapy.utils import fletcher16_checkbytes, checksum -from scapy.compat import orb -from scapy.config import conf - -EXT_VERSION = "v0.9.2" - - -class OSPFOptionsField(FlagsField): - - def __init__(self, name="options", default=0, size=8, - names=None): - if names is None: - names = ["MT", "E", "MC", "NP", "L", "DC", "O", "DN"] - FlagsField.__init__(self, name, default, size, names) - - -_OSPF_types = {1: "Hello", - 2: "DBDesc", - 3: "LSReq", - 4: "LSUpd", - 5: "LSAck"} - - -class _NoLLSLenField(LenField): - """ - LenField that will ignore the size of OSPF_LLS_Hdr if it exists - in the payload - """ - - def i2m(self, pkt, x): - if x is None: - x = self.adjust(len(pkt.payload)) - if OSPF_LLS_Hdr in pkt: - x -= len(pkt[OSPF_LLS_Hdr]) - return x - - -class OSPF_Hdr(Packet): - name = "OSPF Header" - fields_desc = [ - ByteField("version", 2), - ByteEnumField("type", 1, _OSPF_types), - _NoLLSLenField("len", None, adjust=lambda x: x + 24), - IPField("src", "1.1.1.1"), - IPField("area", "0.0.0.0"), # default: backbone - XShortField("chksum", None), - ShortEnumField("authtype", 0, {0: "Null", 1: "Simple", 2: "Crypto"}), - # Null or Simple Authentication - ConditionalField(XLongField("authdata", 0), lambda pkt: pkt.authtype != 2), # noqa: E501 - # Crypto Authentication - ConditionalField(XShortField("reserved", 0), lambda pkt: pkt.authtype == 2), # noqa: E501 - ConditionalField(ByteField("keyid", 1), lambda pkt: pkt.authtype == 2), - ConditionalField(ByteField("authdatalen", 0), lambda pkt: pkt.authtype == 2), # noqa: E501 - ConditionalField(XIntField("seq", 0), lambda pkt: pkt.authtype == 2), - # TODO: Support authdata (which is appended to the packets as if it were padding) # noqa: E501 - ] - - def post_build(self, p, pay): - # See - p += pay - if self.chksum is None: - if self.authtype == 2: - ck = 0 # Crypto, see RFC 2328, D.4.3 - else: - # Checksum is calculated without authentication data - # Algorithm is the same as in IP() - ck = checksum(p[:16] + p[24:]) - p = p[:12] + struct.pack("!H", ck) + p[14:] - # TODO: Handle Crypto: Add message digest (RFC 2328, D.4.3) - return p - - def hashret(self): - return struct.pack("H", self.area) + self.payload.hashret() - - def answers(self, other): - if (isinstance(other, OSPF_Hdr) and - self.area == other.area and - self.type == 5): # Only acknowledgements answer other packets - return self.payload.answers(other.payload) - return 0 - - -class OSPF_Hello(Packet): - name = "OSPF Hello" - fields_desc = [IPField("mask", "255.255.255.0"), - ShortField("hellointerval", 10), - OSPFOptionsField(), - ByteField("prio", 1), - IntField("deadinterval", 40), - IPField("router", "0.0.0.0"), - IPField("backup", "0.0.0.0"), - FieldListField("neighbors", [], IPField("", "0.0.0.0"), length_from=lambda pkt: (pkt.underlayer.len - 44) if pkt.underlayer else None)] # noqa: E501 - - def guess_payload_class(self, payload): - # check presence of LLS data block flag - if self.options & 0x10 == 0x10: - return OSPF_LLS_Hdr - else: - return Packet.guess_payload_class(self, payload) - - -class LLS_Generic_TLV(Packet): - name = "LLS Generic" - fields_desc = [ShortField("type", 0), - FieldLenField("len", None, length_of="val"), - StrLenField("val", "", length_from=lambda x: x.len)] - - def guess_payload_class(self, p): - return conf.padding_layer - - -class LLS_Extended_Options(LLS_Generic_TLV): - name = "LLS Extended Options and Flags" - fields_desc = [ShortField("type", 1), - FieldLenField("len", None, fmt="!H", length_of="options"), - StrLenField("options", "", length_from=lambda x: x.len)] - # TODO: FlagsField("options", 0, names=["LR", "RS"], size) with dynamic size # noqa: E501 - - -class LLS_Crypto_Auth(LLS_Generic_TLV): - name = "LLS Cryptographic Authentication" - fields_desc = [ShortField("type", 2), - FieldLenField("len", 20, fmt="B", length_of=lambda x: x.authdata + 4), # noqa: E501 - XIntField("sequence", 0), - StrLenField("authdata", b"\x00" * 16, length_from=lambda x: x.len - 4)] # noqa: E501 - - -_OSPF_LLSclasses = {1: "LLS_Extended_Options", - 2: "LLS_Crypto_Auth"} - - -def _LLSGuessPayloadClass(p, **kargs): - """ Guess the correct LLS class for a given payload """ - - cls = conf.raw_layer - if len(p) >= 3: - typ = struct.unpack("!H", p[0:2])[0] - clsname = _OSPF_LLSclasses.get(typ, "LLS_Generic_TLV") - cls = globals()[clsname] - return cls(p, **kargs) - - -class FieldLenField32Bits(FieldLenField): - def i2repr(self, pkt, x): - return repr(x) if not x else str(FieldLenField.i2h(self, pkt, x) << 2) + " bytes" # noqa: E501 - - -class OSPF_LLS_Hdr(Packet): - name = "OSPF Link-local signaling" - fields_desc = [XShortField("chksum", None), - FieldLenField32Bits("len", None, length_of="llstlv", adjust=lambda pkt, x: (x + 4) >> 2), # noqa: E501 - PacketListField("llstlv", [], _LLSGuessPayloadClass, length_from=lambda x: (x.len << 2) - 4)] # noqa: E501 - - def post_build(self, p, pay): - p += pay - if self.chksum is None: - c = checksum(p) - p = struct.pack("!H", c) + p[2:] - return p - - -_OSPF_LStypes = {1: "router", - 2: "network", - 3: "summaryIP", - 4: "summaryASBR", - 5: "external", - 7: "NSSAexternal"} - -_OSPF_LSclasses = {1: "OSPF_Router_LSA", - 2: "OSPF_Network_LSA", - 3: "OSPF_SummaryIP_LSA", - 4: "OSPF_SummaryASBR_LSA", - 5: "OSPF_External_LSA", - 7: "OSPF_NSSA_External_LSA"} - - -def ospf_lsa_checksum(lsa): - return fletcher16_checkbytes(b"\x00\x00" + lsa[2:], 16) # leave out age - - -class OSPF_LSA_Hdr(Packet): - name = "OSPF LSA Header" - fields_desc = [ShortField("age", 1), - OSPFOptionsField(), - ByteEnumField("type", 1, _OSPF_LStypes), - IPField("id", "192.168.0.0"), - IPField("adrouter", "1.1.1.1"), - XIntField("seq", 0x80000001), - XShortField("chksum", 0), - ShortField("len", 36)] - - def extract_padding(self, s): - return "", s - - -_OSPF_Router_LSA_types = {1: "p2p", - 2: "transit", - 3: "stub", - 4: "virtual"} - - -class OSPF_Link(Packet): - name = "OSPF Link" - fields_desc = [IPField("id", "192.168.0.0"), - IPField("data", "255.255.255.0"), - ByteEnumField("type", 3, _OSPF_Router_LSA_types), - ByteField("toscount", 0), - ShortField("metric", 10), - # TODO: define correct conditions - ConditionalField(ByteField("tos", 0), lambda pkt: False), - ConditionalField(ByteField("reserved", 0), lambda pkt: False), # noqa: E501 - ConditionalField(ShortField("tosmetric", 0), lambda pkt: False)] # noqa: E501 - - def extract_padding(self, s): - return "", s - - -def _LSAGuessPayloadClass(p, **kargs): - """ Guess the correct LSA class for a given payload """ - # This is heavily based on scapy-cdp.py by Nicolas Bareil and Arnaud Ebalard # noqa: E501 - - cls = conf.raw_layer - if len(p) >= 4: - typ = orb(p[3]) - clsname = _OSPF_LSclasses.get(typ, "Raw") - cls = globals()[clsname] - return cls(p, **kargs) - - -class OSPF_BaseLSA(Packet): - """ An abstract base class for Link State Advertisements """ - - def post_build(self, p, pay): - length = self.len - if length is None: - length = len(p) - p = p[:18] + struct.pack("!H", length) + p[20:] - if self.chksum is None: - chksum = ospf_lsa_checksum(p) - p = p[:16] + chksum + p[18:] - return p # p+pay? - - def extract_padding(self, s): - return "", s - - -class OSPF_Router_LSA(OSPF_BaseLSA): - name = "OSPF Router LSA" - fields_desc = [ShortField("age", 1), - OSPFOptionsField(), - ByteField("type", 1), - IPField("id", "1.1.1.1"), - IPField("adrouter", "1.1.1.1"), - XIntField("seq", 0x80000001), - XShortField("chksum", None), - ShortField("len", None), - FlagsField("flags", 0, 8, ["B", "E", "V", "W", "Nt"]), - ByteField("reserved", 0), - FieldLenField("linkcount", None, count_of="linklist"), - PacketListField("linklist", [], OSPF_Link, - count_from=lambda pkt: pkt.linkcount, - length_from=lambda pkt: pkt.linkcount * 12)] - - -class OSPF_Network_LSA(OSPF_BaseLSA): - name = "OSPF Network LSA" - fields_desc = [ShortField("age", 1), - OSPFOptionsField(), - ByteField("type", 2), - IPField("id", "192.168.0.0"), - IPField("adrouter", "1.1.1.1"), - XIntField("seq", 0x80000001), - XShortField("chksum", None), - ShortField("len", None), - IPField("mask", "255.255.255.0"), - FieldListField("routerlist", [], IPField("", "1.1.1.1"), - length_from=lambda pkt: pkt.len - 24)] - - -class OSPF_SummaryIP_LSA(OSPF_BaseLSA): - name = "OSPF Summary LSA (IP Network)" - fields_desc = [ShortField("age", 1), - OSPFOptionsField(), - ByteField("type", 3), - IPField("id", "192.168.0.0"), - IPField("adrouter", "1.1.1.1"), - XIntField("seq", 0x80000001), - XShortField("chksum", None), - ShortField("len", None), - IPField("mask", "255.255.255.0"), - ByteField("reserved", 0), - X3BytesField("metric", 10), - # TODO: Define correct conditions - ConditionalField(ByteField("tos", 0), lambda pkt:False), - ConditionalField(X3BytesField("tosmetric", 0), lambda pkt:False)] # noqa: E501 - - -class OSPF_SummaryASBR_LSA(OSPF_SummaryIP_LSA): - name = "OSPF Summary LSA (AS Boundary Router)" - type = 4 - id = "2.2.2.2" - mask = "0.0.0.0" - metric = 20 - - -class OSPF_External_LSA(OSPF_BaseLSA): - name = "OSPF External LSA (ASBR)" - fields_desc = [ShortField("age", 1), - OSPFOptionsField(), - ByteField("type", 5), - IPField("id", "192.168.0.0"), - IPField("adrouter", "2.2.2.2"), - XIntField("seq", 0x80000001), - XShortField("chksum", None), - ShortField("len", None), - IPField("mask", "255.255.255.0"), - FlagsField("ebit", 0, 1, ["E"]), - BitField("reserved", 0, 7), - X3BytesField("metric", 20), - IPField("fwdaddr", "0.0.0.0"), - XIntField("tag", 0), - # TODO: Define correct conditions - ConditionalField(ByteField("tos", 0), lambda pkt:False), - ConditionalField(X3BytesField("tosmetric", 0), lambda pkt:False)] # noqa: E501 - - -class OSPF_NSSA_External_LSA(OSPF_External_LSA): - name = "OSPF NSSA External LSA" - type = 7 - - -class OSPF_DBDesc(Packet): - name = "OSPF Database Description" - fields_desc = [ShortField("mtu", 1500), - OSPFOptionsField(), - FlagsField("dbdescr", 0, 8, ["MS", "M", "I", "R", "4", "3", "2", "1"]), # noqa: E501 - IntField("ddseq", 1), - PacketListField("lsaheaders", None, OSPF_LSA_Hdr, - count_from=lambda pkt: None, - length_from=lambda pkt: pkt.underlayer.len - 24 - 8)] # noqa: E501 - - def guess_payload_class(self, payload): - # check presence of LLS data block flag - if self.options & 0x10 == 0x10: - return OSPF_LLS_Hdr - else: - return Packet.guess_payload_class(self, payload) - - -class OSPF_LSReq_Item(Packet): - name = "OSPF Link State Request (item)" - fields_desc = [IntEnumField("type", 1, _OSPF_LStypes), - IPField("id", "1.1.1.1"), - IPField("adrouter", "1.1.1.1")] - - def extract_padding(self, s): - return "", s - - -class OSPF_LSReq(Packet): - name = "OSPF Link State Request (container)" - fields_desc = [PacketListField("requests", None, OSPF_LSReq_Item, - count_from=lambda pkt:None, - length_from=lambda pkt:pkt.underlayer.len - 24)] # noqa: E501 - - -class OSPF_LSUpd(Packet): - name = "OSPF Link State Update" - fields_desc = [FieldLenField("lsacount", None, fmt="!I", count_of="lsalist"), # noqa: E501 - PacketListField("lsalist", None, _LSAGuessPayloadClass, - count_from=lambda pkt: pkt.lsacount, - length_from=lambda pkt: pkt.underlayer.len - 24)] # noqa: E501 - - -class OSPF_LSAck(Packet): - name = "OSPF Link State Acknowledgement" - fields_desc = [PacketListField("lsaheaders", None, OSPF_LSA_Hdr, - count_from=lambda pkt: None, - length_from=lambda pkt: pkt.underlayer.len - 24)] # noqa: E501 - - def answers(self, other): - if isinstance(other, OSPF_LSUpd): - for reqLSA in other.lsalist: - for ackLSA in self.lsaheaders: - if (reqLSA.type == ackLSA.type and - reqLSA.seq == ackLSA.seq): - return 1 - return 0 - - -############################################################################### -# OSPFv3 -############################################################################### -class OSPFv3_Hdr(Packet): - name = "OSPFv3 Header" - fields_desc = [ByteField("version", 3), - ByteEnumField("type", 1, _OSPF_types), - ShortField("len", None), - IPField("src", "1.1.1.1"), - IPField("area", "0.0.0.0"), - XShortField("chksum", None), - ByteField("instance", 0), - ByteField("reserved", 0)] - - def post_build(self, p, pay): - p += pay - tmp_len = self.len - - if tmp_len is None: - tmp_len = len(p) - p = p[:2] + struct.pack("!H", tmp_len) + p[4:] - - if self.chksum is None: - chksum = in6_chksum(89, self.underlayer, p) - p = p[:12] + struct.pack("!H", chksum) + p[14:] - - return p - - -class OSPFv3OptionsField(FlagsField): - - def __init__(self, name="options", default=0, size=24, - names=None): - if names is None: - names = ["V6", "E", "MC", "N", "R", "DC", "AF", "L", "I", "F"] - FlagsField.__init__(self, name, default, size, names) - - -class OSPFv3_Hello(Packet): - name = "OSPFv3 Hello" - fields_desc = [IntField("intid", 0), - ByteField("prio", 1), - OSPFv3OptionsField(), - ShortField("hellointerval", 10), - ShortField("deadinterval", 40), - IPField("router", "0.0.0.0"), - IPField("backup", "0.0.0.0"), - FieldListField("neighbors", [], IPField("", "0.0.0.0"), - length_from=lambda pkt: (pkt.underlayer.len - 36))] # noqa: E501 - - -_OSPFv3_LStypes = {0x2001: "router", - 0x2002: "network", - 0x2003: "interAreaPrefix", - 0x2004: "interAreaRouter", - 0x4005: "asExternal", - 0x2007: "type7", - 0x0008: "link", - 0x2009: "intraAreaPrefix"} - -_OSPFv3_LSclasses = {0x2001: "OSPFv3_Router_LSA", - 0x2002: "OSPFv3_Network_LSA", - 0x2003: "OSPFv3_Inter_Area_Prefix_LSA", - 0x2004: "OSPFv3_Inter_Area_Router_LSA", - 0x4005: "OSPFv3_AS_External_LSA", - 0x2007: "OSPFv3_Type_7_LSA", - 0x0008: "OSPFv3_Link_LSA", - 0x2009: "OSPFv3_Intra_Area_Prefix_LSA"} - - -class OSPFv3_LSA_Hdr(Packet): - name = "OSPFv3 LSA Header" - fields_desc = [ShortField("age", 1), - ShortEnumField("type", 0x2001, _OSPFv3_LStypes), - IPField("id", "0.0.0.0"), - IPField("adrouter", "1.1.1.1"), - XIntField("seq", 0x80000001), - XShortField("chksum", 0), - ShortField("len", 36)] - - def extract_padding(self, s): - return "", s - - -def _OSPFv3_LSAGuessPayloadClass(p, **kargs): - """ Guess the correct OSPFv3 LSA class for a given payload """ - - cls = conf.raw_layer - - if len(p) >= 6: - typ = struct.unpack("!H", p[2:4])[0] - clsname = _OSPFv3_LSclasses.get(typ, "Raw") - cls = globals()[clsname] - - return cls(p, **kargs) - - -_OSPFv3_Router_LSA_types = {1: "p2p", - 2: "transit", - 3: "reserved", - 4: "virtual"} - - -class OSPFv3_Link(Packet): - name = "OSPFv3 Link" - fields_desc = [ByteEnumField("type", 1, _OSPFv3_Router_LSA_types), - ByteField("reserved", 0), - ShortField("metric", 10), - IntField("intid", 0), - IntField("neighintid", 0), - IPField("neighbor", "2.2.2.2")] - - def extract_padding(self, s): - return "", s - - -class OSPFv3_Router_LSA(OSPF_BaseLSA): - name = "OSPFv3 Router LSA" - fields_desc = [ShortField("age", 1), - ShortEnumField("type", 0x2001, _OSPFv3_LStypes), - IPField("id", "0.0.0.0"), - IPField("adrouter", "1.1.1.1"), - XIntField("seq", 0x80000001), - XShortField("chksum", None), - ShortField("len", None), - FlagsField("flags", 0, 8, ["B", "E", "V", "W"]), - OSPFv3OptionsField(), - PacketListField("linklist", [], OSPFv3_Link, - length_from=lambda pkt:pkt.len - 24)] - - -class OSPFv3_Network_LSA(OSPF_BaseLSA): - name = "OSPFv3 Network LSA" - fields_desc = [ShortField("age", 1), - ShortEnumField("type", 0x2002, _OSPFv3_LStypes), - IPField("id", "0.0.0.0"), - IPField("adrouter", "1.1.1.1"), - XIntField("seq", 0x80000001), - XShortField("chksum", None), - ShortField("len", None), - ByteField("reserved", 0), - OSPFv3OptionsField(), - FieldListField("routerlist", [], IPField("", "0.0.0.1"), - length_from=lambda pkt: pkt.len - 24)] - - -class OSPFv3PrefixOptionsField(FlagsField): - - def __init__(self, name="prefixoptions", default=0, size=8, - names=None): - if names is None: - names = ["NU", "LA", "MC", "P"] - FlagsField.__init__(self, name, default, size, names) - - -class OSPFv3_Inter_Area_Prefix_LSA(OSPF_BaseLSA): - name = "OSPFv3 Inter Area Prefix LSA" - fields_desc = [ShortField("age", 1), - ShortEnumField("type", 0x2003, _OSPFv3_LStypes), - IPField("id", "0.0.0.0"), - IPField("adrouter", "1.1.1.1"), - XIntField("seq", 0x80000001), - XShortField("chksum", None), - ShortField("len", None), - ByteField("reserved", 0), - X3BytesField("metric", 10), - FieldLenField("prefixlen", None, length_of="prefix", fmt="B"), # noqa: E501 - OSPFv3PrefixOptionsField(), - ShortField("reserved2", 0), - IP6PrefixField("prefix", "2001:db8:0:42::/64", wordbytes=4, length_from=lambda pkt: pkt.prefixlen)] # noqa: E501 - - -class OSPFv3_Inter_Area_Router_LSA(OSPF_BaseLSA): - name = "OSPFv3 Inter Area Router LSA" - fields_desc = [ShortField("age", 1), - ShortEnumField("type", 0x2004, _OSPFv3_LStypes), - IPField("id", "0.0.0.0"), - IPField("adrouter", "1.1.1.1"), - XIntField("seq", 0x80000001), - XShortField("chksum", None), - ShortField("len", None), - ByteField("reserved", 0), - OSPFv3OptionsField(), - ByteField("reserved2", 0), - X3BytesField("metric", 1), - IPField("router", "2.2.2.2")] - - -class OSPFv3_AS_External_LSA(OSPF_BaseLSA): - name = "OSPFv3 AS External LSA" - fields_desc = [ShortField("age", 1), - ShortEnumField("type", 0x4005, _OSPFv3_LStypes), - IPField("id", "0.0.0.0"), - IPField("adrouter", "1.1.1.1"), - XIntField("seq", 0x80000001), - XShortField("chksum", None), - ShortField("len", None), - FlagsField("flags", 0, 8, ["T", "F", "E"]), - X3BytesField("metric", 20), - FieldLenField("prefixlen", None, length_of="prefix", fmt="B"), # noqa: E501 - OSPFv3PrefixOptionsField(), - ShortEnumField("reflstype", 0, _OSPFv3_LStypes), - IP6PrefixField("prefix", "2001:db8:0:42::/64", wordbytes=4, length_from=lambda pkt: pkt.prefixlen), # noqa: E501 - ConditionalField(IP6Field("fwaddr", "::"), lambda pkt: pkt.flags & 0x02 == 0x02), # noqa: E501 - ConditionalField(IntField("tag", 0), lambda pkt: pkt.flags & 0x01 == 0x01), # noqa: E501 - ConditionalField(IPField("reflsid", 0), lambda pkt: pkt.reflstype != 0)] # noqa: E501 - - -class OSPFv3_Type_7_LSA(OSPFv3_AS_External_LSA): - name = "OSPFv3 Type 7 LSA" - type = 0x2007 - - -class OSPFv3_Prefix_Item(Packet): - name = "OSPFv3 Link Prefix Item" - fields_desc = [FieldLenField("prefixlen", None, length_of="prefix", fmt="B"), # noqa: E501 - OSPFv3PrefixOptionsField(), - ShortField("metric", 10), - IP6PrefixField("prefix", "2001:db8:0:42::/64", wordbytes=4, length_from=lambda pkt: pkt.prefixlen)] # noqa: E501 - - def extract_padding(self, s): - return "", s - - -class OSPFv3_Link_LSA(OSPF_BaseLSA): - name = "OSPFv3 Link LSA" - fields_desc = [ShortField("age", 1), - ShortEnumField("type", 0x0008, _OSPFv3_LStypes), - IPField("id", "0.0.0.0"), - IPField("adrouter", "1.1.1.1"), - XIntField("seq", 0x80000001), - XShortField("chksum", None), - ShortField("len", None), - ByteField("prio", 1), - OSPFv3OptionsField(), - IP6Field("lladdr", "fe80::"), - FieldLenField("prefixes", None, count_of="prefixlist", fmt="I"), # noqa: E501 - PacketListField("prefixlist", None, OSPFv3_Prefix_Item, - count_from=lambda pkt: pkt.prefixes)] - - -class OSPFv3_Intra_Area_Prefix_LSA(OSPF_BaseLSA): - name = "OSPFv3 Intra Area Prefix LSA" - fields_desc = [ShortField("age", 1), - ShortEnumField("type", 0x2009, _OSPFv3_LStypes), - IPField("id", "0.0.0.0"), - IPField("adrouter", "1.1.1.1"), - XIntField("seq", 0x80000001), - XShortField("chksum", None), - ShortField("len", None), - FieldLenField("prefixes", None, count_of="prefixlist", fmt="H"), # noqa: E501 - ShortEnumField("reflstype", 0, _OSPFv3_LStypes), - IPField("reflsid", "0.0.0.0"), - IPField("refadrouter", "0.0.0.0"), - PacketListField("prefixlist", None, OSPFv3_Prefix_Item, - count_from=lambda pkt: pkt.prefixes)] - - -class OSPFv3_DBDesc(Packet): - name = "OSPFv3 Database Description" - fields_desc = [ByteField("reserved", 0), - OSPFv3OptionsField(), - ShortField("mtu", 1500), - ByteField("reserved2", 0), - FlagsField("dbdescr", 0, 8, ["MS", "M", "I", "R"]), - IntField("ddseq", 1), - PacketListField("lsaheaders", None, OSPFv3_LSA_Hdr, - count_from=lambda pkt:None, - length_from=lambda pkt:pkt.underlayer.len - 28)] # noqa: E501 - - -class OSPFv3_LSReq_Item(Packet): - name = "OSPFv3 Link State Request (item)" - fields_desc = [ShortField("reserved", 0), - ShortEnumField("type", 0x2001, _OSPFv3_LStypes), - IPField("id", "1.1.1.1"), - IPField("adrouter", "1.1.1.1")] - - def extract_padding(self, s): - return "", s - - -class OSPFv3_LSReq(Packet): - name = "OSPFv3 Link State Request (container)" - fields_desc = [PacketListField("requests", None, OSPFv3_LSReq_Item, - count_from=lambda pkt:None, - length_from=lambda pkt:pkt.underlayer.len - 16)] # noqa: E501 - - -class OSPFv3_LSUpd(Packet): - name = "OSPFv3 Link State Update" - fields_desc = [FieldLenField("lsacount", None, fmt="!I", count_of="lsalist"), # noqa: E501 - PacketListField("lsalist", [], _OSPFv3_LSAGuessPayloadClass, - count_from=lambda pkt:pkt.lsacount, - length_from=lambda pkt:pkt.underlayer.len - 16)] # noqa: E501 - - -class OSPFv3_LSAck(Packet): - name = "OSPFv3 Link State Acknowledgement" - fields_desc = [PacketListField("lsaheaders", None, OSPFv3_LSA_Hdr, - count_from=lambda pkt:None, - length_from=lambda pkt:pkt.underlayer.len - 16)] # noqa: E501 - - -bind_layers(IP, OSPF_Hdr, proto=89) -bind_layers(OSPF_Hdr, OSPF_Hello, type=1) -bind_layers(OSPF_Hdr, OSPF_DBDesc, type=2) -bind_layers(OSPF_Hdr, OSPF_LSReq, type=3) -bind_layers(OSPF_Hdr, OSPF_LSUpd, type=4) -bind_layers(OSPF_Hdr, OSPF_LSAck, type=5) -DestIPField.bind_addr(OSPF_Hdr, "224.0.0.5") - -bind_layers(IPv6, OSPFv3_Hdr, nh=89) -bind_layers(OSPFv3_Hdr, OSPFv3_Hello, type=1) -bind_layers(OSPFv3_Hdr, OSPFv3_DBDesc, type=2) -bind_layers(OSPFv3_Hdr, OSPFv3_LSReq, type=3) -bind_layers(OSPFv3_Hdr, OSPFv3_LSUpd, type=4) -bind_layers(OSPFv3_Hdr, OSPFv3_LSAck, type=5) -DestIP6Field.bind_addr(OSPFv3_Hdr, "ff02::5") - - -if __name__ == "__main__": - from scapy.main import interact - interact(mydict=globals(), mybanner="OSPF extension %s" % EXT_VERSION) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/pnio.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/pnio.py deleted file mode 100644 index 72afcd6e4b..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/pnio.py +++ /dev/null @@ -1,392 +0,0 @@ -# coding: utf8 -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# Copyright (C) 2016 Gauthier Sebaux - -# scapy.contrib.description = ProfinetIO RTC (+Profisafe) layer -# scapy.contrib.status = loads -import copy -from scapy.compat import raw -from scapy.error import Scapy_Exception -from scapy.config import conf -from scapy.packet import Packet, bind_layers -from scapy.layers.l2 import Ether -from scapy.layers.inet import UDP -from scapy.fields import ( - XShortEnumField, BitEnumField, XBitField, - BitField, StrField, PacketListField, - StrFixedLenField, ShortField, - FlagsField, ByteField, XIntField, X3BytesField -) -from scapy.modules import six - -PNIO_FRAME_IDS = { - 0x0020: "PTCP-RTSyncPDU-followup", - 0x0080: "PTCP-RTSyncPDU", - 0xFC01: "Alarm High", - 0xFE01: "Alarm Low", - 0xFEFC: "DCP-Hello-Req", - 0xFEFD: "DCP-Get-Set", - 0xFEFE: "DCP-Identify-ReqPDU", - 0xFEFF: "DCP-Identify-ResPDU", - 0xFF00: "PTCP-AnnouncePDU", - 0xFF20: "PTCP-FollowUpPDU", - 0xFF40: "PTCP-DelayReqPDU", - 0xFF41: "PTCP-DelayResPDU-followup", - 0xFF42: "PTCP-DelayFuResPDU", - 0xFF43: "PTCP-DelayResPDU", -} - - -def i2s_frameid(x): - """ Get representation name of a pnio frame ID - - :param x: a key of the PNIO_FRAME_IDS dictionary - :returns: str - """ - try: - return PNIO_FRAME_IDS[x] - except KeyError: - pass - if 0x0100 <= x < 0x1000: - return "RT_CLASS_3 (%4x)" % x - if 0x8000 <= x < 0xC000: - return "RT_CLASS_1 (%4x)" % x - if 0xC000 <= x < 0xFC00: - return "RT_CLASS_UDP (%4x)" % x - if 0xFF80 <= x < 0xFF90: - return "FragmentationFrameID (%4x)" % x - return x - - -def s2i_frameid(x): - """ Get pnio frame ID from a representation name - - Performs a reverse look-up in PNIO_FRAME_IDS dictionary - - :param x: a value of PNIO_FRAME_IDS dict - :returns: integer - """ - try: - return { - "RT_CLASS_3": 0x0100, - "RT_CLASS_1": 0x8000, - "RT_CLASS_UDP": 0xC000, - "FragmentationFrameID": 0xFF80, - }[x] - except KeyError: - pass - try: - return next(key for key, value in six.iteritems(PNIO_FRAME_IDS) - if value == x) - except StopIteration: - pass - return x - - -################# -# PROFINET IO # -################# - -class ProfinetIO(Packet): - """ Basic PROFINET IO dispatcher """ - fields_desc = [ - XShortEnumField("frameID", 0, (i2s_frameid, s2i_frameid)) - ] - - def guess_payload_class(self, payload): - # For frameID in the RT_CLASS_* range, use the RTC packet as payload - if self.frameID in [0xfefe, 0xfeff, 0xfefd]: - from scapy.contrib.pnio_dcp import ProfinetDCP - return ProfinetDCP - elif ( - (0x0100 <= self.frameID < 0x1000) or - (0x8000 <= self.frameID < 0xFC00) - - - ): - return PNIORealTimeCyclicPDU - return super(ProfinetIO, self).guess_payload_class(payload) - - -bind_layers(Ether, ProfinetIO, type=0x8892) -bind_layers(UDP, ProfinetIO, dport=0x8892) - - -##################################### -# PROFINET Real-Time Data Packets # -##################################### - -conf.contribs["PNIO_RTC"] = {} - - -class PNIORealTime_IOxS(Packet): - """ IOCS and IOPS packets for PROFINET Real-Time payload """ - name = "PNIO RTC IOxS" - fields_desc = [ - # IOxS.DataState -- IEC-61158 - 6 - 10 / FDIS ED 3, Table 181 - BitEnumField("dataState", 1, 1, ["bad", "good"]), - # IOxS.Instance -- IEC-61158 - 6 - 10 / FDIS ED 3, Table 180 - BitEnumField("instance", 0, 2, - ["subslot", "slot", "device", "controller"]), - # IOxS.reserved -- IEC-61158 - 6 - 10 / FDIS ED 3, line 2649 - XBitField("reserved", 0, 4), - # IOxS.Extension -- IEC-61158-6-10/FDIS ED 3, Table 179 - BitField("extension", 0, 1), - ] - - @classmethod - def is_extension_set(cls, _pkt, _lst, p, _remain): - ret = cls if isinstance(p, type(None)) or p.extension != 0 else None - return ret - - @classmethod - def get_len(cls): - return sum(type(fld).i2len(None, 0) for fld in cls.fields_desc) - - def guess_payload_class(self, p): - return conf.padding_layer - - -class PNIORealTimeCyclicDefaultRawData(Packet): - name = "PROFINET IO Real Time Cyclic Default Raw Data" - fields_desc = [ - # 4 is the sum of the size of the CycleCounter + DataStatus - # + TransferStatus trailing from PNIORealTimeCyclicPDU - StrField("data", '', remain=4) - ] - - def guess_payload_class(self, payload): - return conf.padding_layer - - -class PNIORealTimeCyclicPDU(Packet): - """ PROFINET cyclic real-time """ - __slots__ = ["_len", "_layout"] - name = "PROFINET Real-Time" - - fields_desc = [ - # C_SDU ^ CSF_SDU -- IEC-61158-6-10/FDIS ED 3, Table 163 - PacketListField( - "data", [], - next_cls_cb=lambda pkt, lst, p, remain: pkt.next_cls_cb( - lst, p, remain) - ), - # RTCPadding -- IEC - 61158 - 6 - 10 / FDIS ED 3, Table 163 - StrFixedLenField("padding", '', - length_from=lambda p: p.get_padding_length()), - # APDU_Status -- IEC-61158-6-10/FDIS ED 3, Table 164 - ShortField("cycleCounter", 0), - FlagsField("dataStatus", 0x35, 8, [ - "primary", - "redundancy", - "validData", - "reserved_1", - "run", - "no_problem", - "reserved_2", - "ignore", - ]), - ByteField("transferStatus", 0) - ] - - def pre_dissect(self, s): - # Constraint from IEC-61158-6-10/FDIS ED 3, line 690 - self._len = min(1440, len(s)) - return s - - def get_padding_length(self): - if hasattr(self, "_len"): - pad_len = ( - self._len - - sum(len(raw(pkt)) for pkt in self.getfieldval("data")) - - 2 - # Cycle Counter size (ShortField) - 1 - # DataStatus size (FlagsField over 8 bits) - 1 # TransferStatus (ByteField) - ) - else: - pad_len = len(self.getfieldval("padding")) - - # Constraints from IEC-61158-6-10/FDIS ED 3, Table 163 - assert(0 <= pad_len <= 40) - q = self - while not isinstance(q, UDP) and hasattr(q, "underlayer"): - q = q.underlayer - if isinstance(q, UDP): - assert(0 <= pad_len <= 12) - return pad_len - - def next_cls_cb(self, _lst, _p, _remain): - if hasattr(self, "_layout") and isinstance(self._layout, list): - try: - return self._layout.pop(0) - except IndexError: - self._layout = None - return None - - ether_layer = None - q = self - while not isinstance(q, Ether) and hasattr(q, "underlayer"): - q = q.underlayer - if isinstance(q, Ether): - ether_layer = q - - pnio_layer = None - q = self - while not isinstance(q, ProfinetIO) and hasattr(q, "underlayer"): - q = q.underlayer - if isinstance(q, ProfinetIO): - pnio_layer = q - - self._layout = [PNIORealTimeCyclicDefaultRawData] - if not (ether_layer is None and pnio_layer is None): - # Get from config the layout for these hosts and frameid - layout = type(self).get_layout_from_config( - ether_layer.src, - ether_layer.dst, - pnio_layer.frameID) - if not isinstance(layout, type(None)): - self._layout = layout - - return self._layout.pop(0) - - @staticmethod - def get_layout_from_config(ether_src, ether_dst, frame_id): - try: - return copy.deepcopy( - conf.contribs["PNIO_RTC"][(ether_src, ether_dst, frame_id)] - ) - except KeyError: - return None - - @staticmethod - def build_fixed_len_raw_type(length): - return type( - "FixedLenRawPacketLen{}".format(length), - (conf.raw_layer,), - { - "name": "FixedLenRawPacketLen{}".format(length), - "fields_desc": [StrFixedLenField("data", '', length=length)], - "get_data_length": lambda _: length, - "guess_payload_class": lambda self, p: conf.padding_layer, - } - ) - - -# From IEC 61784-3-3 Ed. 3 PROFIsafe v.2.6, Figure 20 -profisafe_control_flags = [ - "iPar_EN", "OA_Req", "R_cons_nr", "Use_TO2", - "activate_FV", "Toggle_h", "ChF_Ack", "Loopcheck" -] -# From IEC 61784-3-3 Ed. 3 PROFIsafe v.2.6, Figure 19 -profisafe_status_flags = [ - "iPar_OK", "Device_Fault/ChF_Ack_Req", "CE_CRC", - "WD_timeout", "FV_activated", "Toggle_d", "cons_nr_R", "reserved" -] - - -class PROFIsafeCRCSeed(Packet): - __slots__ = ["_len"] + Packet.__slots__ - - def guess_payload_class(self, p): - return conf.padding_layer - - def get_data_length(self): - """ Must be overridden in a subclass to return the correct value """ - raise Scapy_Exception( - "This method must be overridden in a specific subclass" - ) - - def get_mandatory_fields_len(self): - # 5 is the len of the control/status byte + the CRC length - return 5 - - @staticmethod - def get_max_data_length(): - # Constraints from IEC-61784-3-3 ED 3, Figure 18 - return 13 - - -class PROFIsafeControlCRCSeed(PROFIsafeCRCSeed): - name = "PROFISafe Control Message with F_CRC_Seed=1" - fields_desc = [ - StrFixedLenField("data", '', - length_from=lambda p: p.get_data_length()), - FlagsField("control", 0, 8, profisafe_control_flags), - XIntField("crc", 0) - ] - - -class PROFIsafeStatusCRCSeed(PROFIsafeCRCSeed): - name = "PROFISafe Status Message with F_CRC_Seed=1" - fields_desc = [ - StrFixedLenField("data", '', - length_from=lambda p: p.get_data_length()), - FlagsField("status", 0, 8, profisafe_status_flags), - XIntField("crc", 0) - ] - - -class PROFIsafe(Packet): - __slots__ = ["_len"] + Packet.__slots__ - - def guess_payload_class(self, p): - return conf.padding_layer - - def get_data_length(self): - """ Must be overridden in a subclass to return the correct value """ - raise Scapy_Exception( - "This method must be overridden in a specific subclass" - ) - - def get_mandatory_fields_len(self): - # 4 is the len of the control/status byte + the CRC length - return 4 - - @staticmethod - def get_max_data_length(): - # Constraints from IEC-61784-3-3 ED 3, Figure 18 - return 12 - - @staticmethod - def build_PROFIsafe_class(cls, data_length): - assert(cls.get_max_data_length() >= data_length) - return type( - "{}Len{}".format(cls.__name__, data_length), - (cls,), - { - "get_data_length": lambda _: data_length, - } - ) - - -class PROFIsafeControl(PROFIsafe): - name = "PROFISafe Control Message with F_CRC_Seed=0" - fields_desc = [ - StrFixedLenField("data", '', - length_from=lambda p: p.get_data_length()), - FlagsField("control", 0, 8, profisafe_control_flags), - X3BytesField("crc", 0) - ] - - -class PROFIsafeStatus(PROFIsafe): - name = "PROFISafe Status Message with F_CRC_Seed=0" - fields_desc = [ - StrFixedLenField("data", '', - length_from=lambda p: p.get_data_length()), - FlagsField("status", 0, 8, profisafe_status_flags), - X3BytesField("crc", 0) - ] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/pnio_dcp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/pnio_dcp.py deleted file mode 100644 index 6a04b65da3..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/pnio_dcp.py +++ /dev/null @@ -1,596 +0,0 @@ -# coding: utf8 - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# Copyright (C) 2019 Stefan Mehner (stefan.mehner@b-tu.de) - -# scapy.contrib.description = Profinet DCP layer -# scapy.contrib.status = loads - -from scapy.compat import orb -from scapy.all import Packet, bind_layers, Padding -from scapy.fields import ByteEnumField, ShortField, XShortField, \ - ShortEnumField, FieldLenField, XByteField, XIntField, MultiEnumField, \ - IPField, MACField, StrLenField, PacketListField, PadField, \ - ConditionalField, LenField - -# minimum packet is 60 bytes.. 14 bytes are Ether() -MIN_PACKET_LENGTH = 44 - -##################################################### -# Constants # -##################################################### - -DCP_GET_SET_FRAME_ID = 0xFEFD -DCP_IDENTIFY_REQUEST_FRAME_ID = 0xFEFE -DCP_IDENTIFY_RESPONSE_FRAME_ID = 0xFEFF - -DCP_REQUEST = 0x00 -DCP_RESPONSE = 0x01 - -DCP_SERVICE_ID_GET = 0x03 -DCP_SERVICE_ID_SET = 0x04 -DCP_SERVICE_ID_IDENTIFY = 0x05 - -DCP_SERVICE_ID = { - 0x00: "reserved", - 0x01: "Manufacturer specific", - 0x02: "Manufacturer specific", - 0x03: "Get", - 0x04: "Set", - 0x05: "Identify", - 0x06: "Hello", -} - -DCP_SERVICE_TYPE = { - 0x00: "Request", - 0x01: "Response Success", - 0x05: "Response - Request not supported", -} - -DCP_DEVICE_ROLES = { - 0x00: "IO Supervisor", - 0x01: "IO Device", - 0x02: "IO Controller", - -} - -DCP_OPTIONS = { - 0x00: "reserved", - 0x01: "IP", - 0x02: "Device properties", - 0x03: "DHCP", - 0x04: "Reserved", - 0x05: "Control", - 0x06: "Device Initiative", - 0xff: "All Selector" -} -DCP_OPTIONS.update({i: "reserved" for i in range(0x07, 0x7f)}) -DCP_OPTIONS.update({i: "Manufacturer specific" for i in range(0x80, 0xfe)}) - -DCP_SUBOPTIONS = { - # ip - 0x01: { - 0x00: "Reserved", - 0x01: "MAC Address", - 0x02: "IP Parameter" - }, - # device properties - 0x02: { - 0x00: "Reserved", - 0x01: "Manufacturer specific (Type of Station)", - 0x02: "Name of Station", - 0x03: "Device ID", - 0x04: "Device Role", - 0x05: "Device Options", - 0x06: "Alias Name", - 0x07: "Device Instance", - 0x08: "OEM Device ID", - }, - # dhcp - 0x03: { - 0x0c: "Host name", - 0x2b: "Vendor specific", - 0x36: "Server identifier", - 0x37: "Parameter request list", - 0x3c: "Class identifier", - 0x3d: "DHCP client identifier", - 0x51: "FQDN, Fully Qualified Domain Name", - 0x61: "UUID/GUID-based Client", - 0xff: "Control DHCP for address resolution" - }, - # control - 0x05: { - 0x00: "Reserved", - 0x01: "Start Transaction", - 0x02: "End Transaction", - 0x03: "Signal", - 0x04: "Response", - 0x05: "Reset Factory Settings", - 0x06: "Reset to Factory" - }, - # device initiative - 0x06: { - 0x00: "Reserved", - 0x01: "Device Initiative" - }, - 0xff: { - 0xff: "ALL Selector" - } -} - -BLOCK_INFOS = { - 0x00: "Reserved", -} -BLOCK_INFOS.update({i: "reserved" for i in range(0x01, 0xff)}) - - -IP_BLOCK_INFOS = { - 0x0000: "IP not set", - 0x0001: "IP set", - 0x0002: "IP set by DHCP", - 0x0080: "IP not set (address conflict detected)", - 0x0081: "IP set (address conflict detected)", - 0x0082: "IP set by DHCP (address conflict detected)", -} -IP_BLOCK_INFOS.update({i: "reserved" for i in range(0x0003, 0x007f)}) - -BLOCK_ERRORS = { - 0x00: "Ok", - 0x01: "Option unsupp.", - 0x02: "Suboption unsupp. or no DataSet avail.", - 0x03: "Suboption not set", - 0x04: "Resource Error", - 0x05: "SET not possible by local reasons", - 0x06: "In operation, SET not possible", -} - -BLOCK_QUALIFIERS = { - 0x0000: "Use the value temporary", - 0x0001: "Save the value permanent", -} -BLOCK_QUALIFIERS.update({i: "reserved" for i in range(0x0002, 0x00ff)}) - - -##################################################### -# DCP Blocks # -##################################################### - -# GENERIC DCP BLOCK - -# DCP RESPONSE BLOCKS - -class DCPBaseBlock(Packet): - """ - base class for all DCP Blocks - """ - fields_desc = [ - ByteEnumField("option", 1, DCP_OPTIONS), - MultiEnumField("sub_option", 2, DCP_SUBOPTIONS, fmt='B', - depends_on=lambda p: p.option), - FieldLenField("dcp_block_length", None, length_of="data"), - ShortEnumField("block_info", 0, BLOCK_INFOS), - StrLenField("data", "", length_from=lambda x: x.dcp_block_length), - ] - - def extract_padding(self, s): - return '', s - - -# OPTION: IP - -class DCPIPBlock(Packet): - fields_desc = [ - ByteEnumField("option", 1, DCP_OPTIONS), - MultiEnumField("sub_option", 2, DCP_SUBOPTIONS, fmt='B', - depends_on=lambda p: p.option), - LenField("dcp_block_length", None), - ShortEnumField("block_info", 1, IP_BLOCK_INFOS), - IPField("ip", "192.168.0.2"), - IPField("netmask", "255.255.255.0"), - IPField("gateway", "192.168.0.1"), - PadField(StrLenField("padding", b"\x00", - length_from=lambda p: p.dcp_block_length % 2), 1, - padwith=b"\x00") - ] - - def extract_padding(self, s): - return '', s - - -class DCPMACBlock(Packet): - fields_desc = [ - ByteEnumField("option", 1, DCP_OPTIONS), - MultiEnumField("sub_option", 1, DCP_SUBOPTIONS, fmt='B', - depends_on=lambda p: p.option), - FieldLenField("dcp_block_length", None), - ShortEnumField("block_info", 0, BLOCK_INFOS), - MACField("mac", "00:00:00:00:00:00"), - PadField(StrLenField("padding", b"\x00", - length_from=lambda p: p.dcp_block_length % 2), 1, - padwith=b"\x00") - ] - - def extract_padding(self, s): - return '', s - - -# OPTION: Device Properties - -class DCPManufacturerSpecificBlock(Packet): - fields_desc = [ - ByteEnumField("option", 2, DCP_OPTIONS), - MultiEnumField("sub_option", 1, DCP_SUBOPTIONS, fmt='B', - depends_on=lambda p: p.option), - FieldLenField("dcp_block_length", None), - ShortEnumField("block_info", 0, BLOCK_INFOS), - StrLenField("device_vendor_value", "et200sp", - length_from=lambda x: x.dcp_block_length - 2), - PadField(StrLenField("padding", b"\x00", - length_from=lambda p: p.dcp_block_length % 2), 1, - padwith=b"\x00") - ] - - def extract_padding(self, s): - return '', s - - -class DCPNameOfStationBlock(Packet): - fields_desc = [ - ByteEnumField("option", 2, DCP_OPTIONS), - MultiEnumField("sub_option", 2, DCP_SUBOPTIONS, fmt='B', - depends_on=lambda p: p.option), - FieldLenField("dcp_block_length", None, length_of="name_of_station", - adjust=lambda p, x: x + 2), - - ShortEnumField("block_info", 0, BLOCK_INFOS), - StrLenField("name_of_station", "et200sp", - length_from=lambda x: x.dcp_block_length - 2), - PadField(StrLenField("padding", b"\x00", - length_from=lambda p: p.dcp_block_length % 2), 1, - padwith=b"\x00") - ] - - def extract_padding(self, s): - return '', s - - -class DCPDeviceIDBlock(Packet): - fields_desc = [ - ByteEnumField("option", 2, DCP_OPTIONS), - MultiEnumField("sub_option", 3, DCP_SUBOPTIONS, fmt='B', - depends_on=lambda p: p.option), - LenField("dcp_block_length", None), - ShortEnumField("block_info", 0, BLOCK_INFOS), - XShortField("vendor_id", 0x002a), - XShortField("device_id", 0x0313), - PadField(StrLenField("padding", b"\x00", - length_from=lambda p: p.dcp_block_length % 2), 1, - padwith=b"\x00") - ] - - def extract_padding(self, s): - return '', s - - -class DCPDeviceRoleBlock(Packet): - fields_desc = [ - ByteEnumField("option", 2, DCP_OPTIONS), - MultiEnumField("sub_option", 4, DCP_SUBOPTIONS, fmt='B', - depends_on=lambda p: p.option), - LenField("dcp_block_length", 4), - ShortEnumField("block_info", 0, BLOCK_INFOS), - ByteEnumField("device_role_details", 1, DCP_DEVICE_ROLES), - XByteField("reserved", 0x00), - PadField(StrLenField("padding", b"\x00", - length_from=lambda p: p.dcp_block_length % 2), 1, - padwith=b"\x00") - ] - - def extract_padding(self, s): - return '', s - - -# one DeviceOptionsBlock can contain 1..n different options -class DeviceOption(Packet): - fields_desc = [ - ByteEnumField("option", 2, DCP_OPTIONS), - MultiEnumField("sub_option", 5, DCP_SUBOPTIONS, fmt='B', - depends_on=lambda p: p.option), - ] - - def extract_padding(self, s): - return '', s - - -class DCPDeviceOptionsBlock(Packet): - fields_desc = [ - ByteEnumField("option", 2, DCP_OPTIONS), - MultiEnumField("sub_option", 5, DCP_SUBOPTIONS, fmt='B', - depends_on=lambda p: p.option), - LenField("dcp_block_length", None), - ShortEnumField("block_info", 0, BLOCK_INFOS), - - PacketListField("device_options", [], DeviceOption, - length_from=lambda p: p.dcp_block_length - 2), - - PadField(StrLenField("padding", b"\x00", - length_from=lambda p: p.dcp_block_length % 2), 1, - padwith=b"\x00") - ] - - def extract_padding(self, s): - return '', s - - -class DCPAliasNameBlock(Packet): - fields_desc = [ - ByteEnumField("option", 2, DCP_OPTIONS), - MultiEnumField("sub_option", 6, DCP_SUBOPTIONS, fmt='B', - depends_on=lambda p: p.option), - FieldLenField("dcp_block_length", None, length_of="alias_name", - adjust=lambda p, x: x + 2), - ShortEnumField("block_info", 0, BLOCK_INFOS), - StrLenField("alias_name", "et200sp", - length_from=lambda x: x.dcp_block_length - 2), - PadField(StrLenField("padding", b"\x00", - length_from=lambda p: p.dcp_block_length % 2), 1, - padwith=b"\x00") - ] - - def extract_padding(self, s): - return '', s - - -class DCPDeviceInstanceBlock(Packet): - fields_desc = [ - ByteEnumField("option", 2, DCP_OPTIONS), - MultiEnumField("sub_option", 7, DCP_SUBOPTIONS, fmt='B', - depends_on=lambda p: p.option), - LenField("dcp_block_length", 4), - ShortEnumField("block_info", 0, BLOCK_INFOS), - XByteField("device_instance_high", 0x00), - XByteField("device_instance_low", 0x01), - PadField(StrLenField("padding", b"\x00", - length_from=lambda p: p.dcp_block_length % 2), 1, - padwith=b"\x00") - ] - - def extract_padding(self, s): - return '', s - - -class DCPControlBlock(Packet): - fields_desc = [ - ByteEnumField("option", 5, DCP_OPTIONS), - MultiEnumField("sub_option", 4, DCP_SUBOPTIONS, fmt='B', - depends_on=lambda p: p.option), - LenField("dcp_block_length", 3), - ByteEnumField("response", 2, DCP_OPTIONS), - MultiEnumField("response_sub_option", 2, DCP_SUBOPTIONS, fmt='B', - depends_on=lambda p: p.option), - ByteEnumField("block_error", 0, BLOCK_ERRORS), - PadField(StrLenField("padding", b"\x00", - length_from=lambda p: p.dcp_block_length % 2), 1, - padwith=b"\x00") - ] - - def extract_padding(self, s): - return '', s - - -def guess_dcp_block_class(packet, **kargs): - """ - returns the correct dcp block class needed to dissect the current tag - if nothing can be found -> dcp base block will be used - - :param packet: the current packet - :return: dcp block class - """ - # packet = unicode(packet, "utf-8") - option = orb(packet[0]) - suboption = orb(packet[1]) - - # NOTE implement the other functions if needed - - class_switch_case = { - # IP - 0x01: - { - 0x01: "DCPMACBlock", - 0x02: "DCPIPBlock" - }, - # Device Properties - 0x02: - { - 0x01: "DCPManufacturerSpecificBlock", - 0x02: "DCPNameOfStationBlock", - 0x03: "DCPDeviceIDBlock", - 0x04: "DCPDeviceRoleBlock", - 0x05: "DCPDeviceOptionsBlock", - 0x06: "DCPAliasNameBlock", - 0x07: "DCPDeviceInstanceBlock", - 0x08: "OEM Device ID" - }, - # DHCP - 0x03: - { - 0x0c: "Host name", - 0x2b: "Vendor specific", - 0x36: "Server identifier", - 0x37: "Parameter request list", - 0x3c: "Class identifier", - 0x3d: "DHCP client identifier", - 0x51: "FQDN, Fully Qualified Domain Name", - 0x61: "UUID/GUID-based Client", - 0xff: "Control DHCP for address resolution" - }, - # Control - 0x05: - { - 0x00: "Reserved (0x00)", - 0x01: "Start Transaction (0x01)", - 0x02: "End Transaction (0x02)", - 0x03: "Signal (0x03)", - 0x04: "DCPControlBlock", - 0x05: "Reset Factory Settings (0x05)", - 0x06: "Reset to Factory (0x06)" - }, - # Device Inactive - 0x06: - { - 0x00: "Reserved (0x00)", - 0x01: "Device Initiative (0x01)" - }, - # ALL Selector - 0xff: - { - 0xff: "ALL Selector (0xff)" - } - } - - try: - c = class_switch_case[option][suboption] - except KeyError: - c = "DCPBaseBlock" - - cls = globals()[c] - return cls(packet, **kargs) - - -# GENERIC DCP PACKET - -class ProfinetDCP(Packet): - """ - Profinet DCP Packet - - Requests are handled via ConditionalField because here only 1 Block is used - qevery time - Ŕesoinse can contain 1..n Blocks, for that you have to use one ProfinetDCP - Layer with one or multiple DCP*Block Layers - ProfinetDCP / DCPNameOfStationBlock / DCPDeviceIDBlock ... - - Example for a DCP Identify All Request: - Ether(dst="01:0e:cf:00:00:00") / - ProfinetIO(frameID=DCP_IDENTIFY_REQUEST_FRAME_ID) / - ProfinetDCP(service_id=DCP_SERVICE_ID_IDENTIFY, - service_type=DCP_REQUEST, option=255, sub_option=255, - dcp_data_length=4) - - Example for a DCP Identify Response: - Ether(dst=dst_mac) / - ProfinetIO(frameID=DCP_IDENTIFY_RESPONSE_FRAME_ID) / - ProfinetDCP( - service_id=DCP_SERVICE_ID_IDENTIFY, - service_type=DCP_RESPONSE) / - DCPNameOfStationBlock(name_of_station="device1") - - Example for a DCP Set Request: - Ether(dst=mac) / - ProfinetIO(frameID=DCP_GET_SET_FRAME_ID) / - ProfinetDCP(service_id=DCP_SERVICE_ID_SET, service_type=DCP_REQUEST, - option=2, sub_option=2, dcp_data_length=14, dcp_block_length=10, - name_of_station=name, reserved=0) - - """ - - name = "Profinet DCP" - # a DCP PDU consists of some fields and 1..n DCP Blocks - fields_desc = [ - ByteEnumField("service_id", 5, DCP_SERVICE_ID), - ByteEnumField("service_type", 0, DCP_SERVICE_TYPE), - XIntField("xid", 0x01000001), - # XShortField('reserved', 0), - - ShortField('reserved', 0), - LenField("dcp_data_length", None), - - # DCP REQUEST specific - ConditionalField(ByteEnumField("option", 2, DCP_OPTIONS), - lambda pkt: pkt.service_type == 0), - ConditionalField( - MultiEnumField("sub_option", 3, DCP_SUBOPTIONS, fmt='B', - depends_on=lambda p: p.option), - lambda pkt: pkt.service_type == 0), - - # calculate the len fields - workaround - ConditionalField(LenField("dcp_block_length", 0), - lambda pkt: pkt.service_type == 0), - - # DCP SET REQUEST # - ConditionalField(ShortEnumField("block_qualifier", 1, - BLOCK_QUALIFIERS), - lambda pkt: pkt.service_id == 4 and - pkt.service_type == 0), - # Name Of Station - ConditionalField(StrLenField("name_of_station", "et200sp", - length_from=lambda x: x.dcp_block_length - 2), - lambda pkt: pkt.service_id == 4 and - pkt.service_type == 0 and pkt.option == 2 and - pkt.sub_option == 2), - - # MAC - ConditionalField(MACField("mac", "00:00:00:00:00:00"), - lambda pkt: pkt.service_id == 4 and - pkt.service_type == 0 and pkt.option == 1 and - pkt.sub_option == 1), - # IP - ConditionalField(IPField("ip", "192.168.0.2"), - lambda pkt: pkt.service_id == 4 and - pkt.service_type == 0 and pkt.option == 1 and - pkt.sub_option == 2), - ConditionalField(IPField("netmask", "255.255.255.0"), - lambda pkt: pkt.service_id == 4 and - pkt.service_type == 0 and pkt.option == 1 and - pkt.sub_option == 2), - ConditionalField(IPField("gateway", "192.168.0.1"), - lambda pkt: pkt.service_id == 4 and - pkt.service_type == 0 and pkt.option == 1 and - pkt.sub_option == 2), - - # DCP IDENTIFY REQUEST # - # Name of station - ConditionalField(StrLenField("name_of_station", "et200sp", - length_from=lambda x: x.dcp_block_length), - lambda pkt: pkt.service_id == 5 and - pkt.service_type == 0 and pkt.option == 2 and - pkt.sub_option == 2), - - # Alias name - ConditionalField(StrLenField("alias_name", "et200sp", - length_from=lambda x: x.dcp_block_length), - lambda pkt: pkt.service_id == 5 and - pkt.service_type == 0 and pkt.option == 2 and - pkt.sub_option == 6), - - # implement further REQUEST fields if needed .... - - # DCP RESPONSE BLOCKS # - ConditionalField( - PacketListField("dcp_blocks", [], guess_dcp_block_class, - length_from=lambda p: p.dcp_data_length), - lambda pkt: pkt.service_type == 1), - ] - - def post_build(self, pkt, pay): - # add padding to ensure min packet length - - padding = MIN_PACKET_LENGTH - (len(pkt + pay)) - pay += b"\0" * padding - - return Packet.post_build(self, pkt, pay) - - -bind_layers(ProfinetDCP, Padding) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/pnio_rpc.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/pnio_rpc.py deleted file mode 100644 index f835473298..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/pnio_rpc.py +++ /dev/null @@ -1,1010 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# Copyright (C) 2016 Gauthier Sebaux - -# scapy.contrib.description = ProfinetIO Remote Procedure Call (RPC) -# scapy.contrib.status = loads - -""" -PNIO RPC endpoints -""" - -import struct -from uuid import UUID - -from scapy.packet import Packet, bind_layers -from scapy.config import conf -from scapy.fields import BitField, ByteField, BitEnumField, ConditionalField, \ - FieldLenField, FieldListField, IntField, IntEnumField, \ - LenField, MACField, PadField, PacketField, PacketListField, \ - ShortEnumField, ShortField, StrFixedLenField, StrLenField, \ - UUIDField, XByteField, XIntField, XShortEnumField, XShortField -from scapy.contrib.dce_rpc import DceRpc, EndiannessField, DceRpcPayload -from scapy.compat import bytes_hex -from scapy.volatile import RandUUID - -# Block Packet -BLOCK_TYPES_ENUM = { - 0x0000: "AlarmNotification_High", - 0x0001: "AlarmNotification_Low", - 0x0008: "IODWriteReqHeader", - 0x0009: "IODReadReqHeader", - 0x0010: "DiagnosisData", - 0x0012: "ExpectedIdentificationData", - 0x0013: "RealIdentificationData", - 0x0014: "SubsituteValue", - 0x0015: "RecordInputDataObjectElement", - 0x0016: "RecordOutputDataObjectElement", - 0x0018: "ARData", - 0x0019: "LogBookData", - 0x001a: "APIData", - 0x001b: "SRLData", - 0x0020: "I&M0", - 0x0021: "I&M1", - 0x0022: "I&M2", - 0x0023: "I&M3", - 0x0024: "I&M4", - 0x0030: "I&M0FilterDataSubmodule", - 0x0031: "I&M0FilterDataModule", - 0x0032: "I&M0FilterDataDevice", - 0x0101: "ARBlockReq", - 0x0102: "IOCRBlockReq", - 0x0103: "AlarmCRBlockReq", - 0x0104: "ExpectedSubmoduleBlockReq", - 0x0105: "PrmServerBlockReq", - 0x0106: "MCRBlockReq", - 0x0107: "ARRPCBlockReq", - 0x0108: "ARVendorBlockReq", - 0x0109: "IRInfoBlock", - 0x010a: "SRInfoBlock", - 0x010b: "ARFSUBlock", - 0x0110: "IODBlockReq_connect_end", - 0x0111: "IODBlockReq_plug", - 0x0112: "IOXBlockReq_connect", - 0x0113: "IOXBlockReq_plug", - 0x0114: "ReleaseBlockReq", - 0x0116: "IOXBlockReq_companion", - 0x0117: "IOXBlockReq_rt_class_3", - 0x0118: "IODBlockReq_connect_begin", - 0x0119: "SubmoduleListBlock", - 0x0200: "PDPortDataCheck", - 0x0201: "PdevData", - 0x0202: "PDPortDataAdjust", - 0x0203: "PDSyncData", - 0x0204: "IsochronousModeData", - 0x0205: "PDIRData", - 0x0206: "PDIRGlobalData", - 0x0207: "PDIRFrameData", - 0x0208: "PDIRBeginEndData", - 0x0209: "AdjustDomainBoundary", - 0x020a: "SubBlock_check_Peers", - 0x020b: "SubBlock_check_LineDelay", - 0x020c: "SubBlock_check_MAUType", - 0x020e: "AdjustMAUType", - 0x020f: "PDPortDataReal", - 0x0210: "AdjustMulticastBoundary", - 0x0211: "PDInterfaceMrpDataAdjust", - 0x0212: "PDInterfaceMrpDataReal", - 0x0213: "PDInterfaceMrpDataCheck", - 0x0214: "PDPortMrpDataAdjust", - 0x0215: "PDPortMrpDataReal", - 0x0216: "MrpManagerParams", - 0x0217: "MrpClientParams", - 0x0219: "MrpRingStateData", - 0x021b: "AdjustLinkState", - 0x021c: "CheckLinkState", - 0x021e: "CheckSyncDifference", - 0x021f: "CheckMAUTypeDifference", - 0x0220: "PDPortFODataReal", - 0x0221: "FiberOpticManufacturerSpecific", - 0x0222: "PDPortFODataAdjust", - 0x0223: "PDPortFODataCheck", - 0x0224: "AdjustPeerToPeerBoundary", - 0x0225: "AdjustDCPBoundary", - 0x0226: "AdjustPreambleLength", - 0x0228: "FiberOpticDiagnosisInfo", - 0x022a: "PDIRSubframeData", - 0x022b: "SubframeBlock", - 0x022d: "PDTimeData", - 0x0230: "PDNCDataCheck", - 0x0231: "MrpInstanceDataAdjustBlock", - 0x0232: "MrpInstanceDataRealBlock", - 0x0233: "MrpInstanceDataCheckBlock", - 0x0240: "PDInterfaceDataReal", - 0x0250: "PDInterfaceAdjust", - 0x0251: "PDPortStatistic", - 0x0400: "MultipleBlockHeader", - 0x0401: "COContainerContent", - 0x0500: "RecordDataReadQuery", - 0x0600: "FSHelloBlock", - 0x0601: "FSParameterBlock", - 0x0608: "PDInterfaceFSUDataAdjust", - 0x0609: "ARFSUDataAdjust", - 0x0700: "AutoConfiguration", - 0x0701: "AutoConfigurationCommunication", - 0x0702: "AutoConfigurationConfiguration", - 0x0703: "AutoConfigurationIsochronous", - 0x0A00: "UploadBLOBQuery", - 0x0A01: "UploadBLOB", - 0x0A02: "NestedDiagnosisInfo", - 0x0F00: "MaintenanceItem", - 0x0F01: "UploadRecord", - 0x0F02: "iParameterItem", - 0x0F03: "RetrieveRecord", - 0x0F04: "RetrieveAllRecord", - 0x8001: "AlarmAckHigh", - 0x8002: "AlarmAckLow", - 0x8008: "IODWriteResHeader", - 0x8009: "IODReadResHeader", - 0x8101: "ARBlockRes", - 0x8102: "IOCRBlockRes", - 0x8103: "AlarmCRBlockRes", - 0x8104: "ModuleDiffBlock", - 0x8105: "PrmServerBlockRes", - 0x8106: "ARServerBlockRes", - 0x8107: "ARRPCBlockRes", - 0x8108: "ARVendorBlockRes", - 0x8110: "IODBlockRes_connect_end", - 0x8111: "IODBlockRes_plug", - 0x8112: "IOXBlockRes_connect", - 0x8113: "IOXBlockRes_plug", - 0x8114: "ReleaseBlockRes", - 0x8116: "IOXBlockRes_companion", - 0x8117: "IOXBlockRes_rt_class_3", - 0x8118: "IODBlockRes_connect_begin", -} - -# IODWriteReq & IODWriteMultipleReq Packets -IOD_WRITE_REQ_INDEX = { - 0x8000: "ExpectedIdentificationData_subslot", - 0x8001: "RealIdentificationData_subslot", - 0x800a: "Diagnosis_channel_subslot", - 0x800b: "Diagnosis_all_subslot", - 0x800c: "Diagnosis_Maintenance_subslot", - 0x8010: "Maintenance_required_in_channel_subslot", - 0x8011: "Maintenance_demanded_in_channel_subslot", - 0x8012: "Maintenance_required_in_all_channels_subslot", - 0x8013: "Maintenance_demanded_in_all_channels_subslot", - 0x801e: "SubstitueValue_subslot", - 0x8020: "PDIRSubframeData_subslot", - 0x8028: "RecordInputDataObjectElement_subslot", - 0x8029: "RecordOutputDataObjectElement_subslot", - 0x802a: "PDPortDataReal_subslot", - 0x802b: "PDPortDataCheck_subslot", - 0x802c: "PDIRData_subslot", - 0x802d: "Expected_PDSyncData_subslot", - 0x802f: "PDPortDataAdjust_subslot", - 0x8030: "IsochronousModeData_subslot", - 0x8031: "Expected_PDTimeData_subslot", - 0x8050: "PDInterfaceMrpDataReal_subslot", - 0x8051: "PDInterfaceMrpDataCheck_subslot", - 0x8052: "PDInterfaceMrpDataAdjust_subslot", - 0x8053: "PDPortMrpDataAdjust_subslot", - 0x8054: "PDPortMrpDataReal_subslot", - 0x8060: "PDPortFODataReal_subslot", - 0x8061: "PDPortFODataCheck_subslot", - 0x8062: "PDPortFODataAdjust_subslot", - 0x8070: "PdNCDataCheck_subslot", - 0x8071: "PDInterfaceAdjust_subslot", - 0x8072: "PDPortStatistic_subslot", - 0x8080: "PDInterfaceDataReal_subslot", - 0x8090: "Expected_PDInterfaceFSUDataAdjust", - 0x80a0: "Energy_saving_profile_record_0", - 0x80b0: "CombinedObjectContainer", - 0x80c0: "Sequence_events_profile_record_0", - 0xaff0: "I&M0", - 0xaff1: "I&M1", - 0xaff2: "I&M2", - 0xaff3: "I&M3", - 0xaff4: "I&M4", - 0xc000: "Expect edIdentificationData_slot", - 0xc001: "RealId entificationData_slot", - 0xc00a: "Diagno sis_channel_slot", - 0xc00b: "Diagnosis_all_slot", - 0xc00c: "Diagnosis_Maintenance_slot", - 0xc010: "Maintenance_required_in_channel_slot", - 0xc011: "Maintenance_demanded_in_channel_slot", - 0xc012: "Maintenance_required_in_all_channels_slot", - 0xc013: "Maintenance_demanded_in_all_channels_slot", - 0xe000: "ExpectedIdentificationData_AR", - 0xe001: "RealIdentificationData_AR", - 0xe002: "ModuleDiffBlock_AR", - 0xe00a: "Diagnosis_channel_AR", - 0xe00b: "Diagnosis_all_AR", - 0xe00c: "Diagnosis_Maintenance_AR", - 0xe010: "Maintenance_required_in_channel_AR", - 0xe011: "Maintenance_demanded_in_channel_AR", - 0xe012: "Maintenance_required_in_all_channels_AR", - 0xe013: "Maintenance_demanded_in_all_channels_AR", - 0xe040: "WriteMultiple", - 0xe050: "ARFSUDataAdjust_AR", - 0xf000: "RealIdentificationData_API", - 0xf00a: "Diagnosis_channel_API", - 0xf00b: "Diagnosis_all_API", - 0xf00c: "Diagnosis_Maintenance_API", - 0xf010: "Maintenance_required_in_channel_API", - 0xf011: "Maintenance_demanded_in_channel_API", - 0xf012: "Maintenance_required_in_all_channels_API", - 0xf013: "Maintenance_demanded_in_all_channels_API", - 0xf020: "ARData_API", - 0xf80c: "Diagnosis_Maintenance_device", - 0xf820: "ARData", - 0xf821: "APIData", - 0xf830: "LogBookData", - 0xf831: "PdevData", - 0xf840: "I&M0FilterData", - 0xf841: "PDRealData", - 0xf842: "PDExpectedData", - 0xf850: "AutoConfiguration", - 0xf860: "GSD_upload", - 0xf861: "Nested_Diagnosis_info", - 0xfbff: "Trigger_index_CMSM", -} - -# ARBlockReq Packets -AR_TYPE = { - 0x0001: "IOCARSingle", - 0x0006: "IOSAR", - 0x0010: "IOCARSingle_RT_CLASS_3", - 0x0020: "IOCARSR", -} - -# IOCRBlockReq Packets -IOCR_TYPE = { - 0x0001: "InputCR", - 0x0002: "OutputCR", - 0x0003: "MulticastProviderCR", - 0x0004: "MulticastConsumerCR", -} - -IOCR_BLOCK_REQ_IOCR_PROPERTIES = { - 0x1: "RT_CLASS_1", - 0x2: "RT_CLASS_2", - 0x3: "RT_CLASS_3", - 0x4: "RT_CLASS_UDP", -} - - -# List of all valid activity UUIDs for the DceRpc layer with PROFINET RPC -# endpoint. -# -# Because these are used in overloaded_fields, it must be a ``UUID``, not a -# string. -RPC_INTERFACE_UUID = { - "UUID_IO_DeviceInterface": UUID("dea00001-6c97-11d1-8271-00a02442df7d"), - "UUID_IO_ControllerInterface": - UUID("dea00002-6c97-11d1-8271-00a02442df7d"), - "UUID_IO_SupervisorInterface": - UUID("dea00003-6c97-11d1-8271-00a02442df7d"), - "UUID_IO_ParameterServerInterface": - UUID("dea00004-6c97-11d1-8271-00a02442df7d"), -} - - -# Generic Block Packet -class BlockHeader(Packet): - """Abstract packet to centralize block headers fields""" - fields_desc = [ - ShortEnumField("block_type", None, BLOCK_TYPES_ENUM), - ShortField("block_length", None), - ByteField("block_version_high", 1), - ByteField("block_version_low", 0), - ] - - def __new__(cls, name, bases, dct): - raise NotImplementedError() - - -class Block(Packet): - """A generic block packet for PNIO RPC""" - fields_desc = [ - BlockHeader, - StrLenField("load", "", length_from=lambda pkt: pkt.block_length - 2), - ] - # default block_type - block_type = 0 - - def post_build(self, p, pay): - # update the block_length if needed - if self.block_length is None: - # block_length and block_type are not part of the length count - length = len(p) - 4 - p = p[:2] + struct.pack("!H", length) + p[4:] - - return Packet.post_build(self, p, pay) - - def extract_padding(self, s): - # all fields after block_length are included in the length and must be - # subtracted from the pdu length l - length = self.payload_length() - return s[:length], s[length:] - - def payload_length(self): - """ A function for each block, to determine the length of - the payload """ - return 0 # default, no payload - - -# Specific Block Packets -# IODControlRe{q,s} -class IODControlReq(Block): - """IODControl request block""" - fields_desc = [ - BlockHeader, - StrFixedLenField("padding", "", length=2), - UUIDField("ARUUID", None), - ShortField("SessionKey", 0), - XShortField("AlarmSequenceNumber", 0), - # ControlCommand - BitField("ControlCommand_reserved", 0, 9), - BitField("ControlCommand_PrmBegin", 0, 1), - BitField("ControlCommand_ReadyForRT_CLASS_3", 0, 1), - BitField("ControlCommand_ReadyForCompanion", 0, 1), - BitField("ControlCommand_Done", 0, 1), - BitField("ControlCommand_Release", 0, 1), - BitField("ControlCommand_ApplicationReady", 0, 1), - BitField("ControlCommand_PrmEnd", 0, 1), - XShortField("ControlBlockProperties", 0) - ] - - def post_build(self, p, pay): - # Try to find the right block type - if self.block_type is None: - if self.ControlCommand_PrmBegin: - p = struct.pack("!H", 0x0118) + p[2:] - elif self.ControlCommand_ReadyForRT_CLASS_3: - p = struct.pack("!H", 0x0117) + p[2:] - elif self.ControlCommand_ReadyForCompanion: - p = struct.pack("!H", 0x0116) + p[2:] - elif self.ControlCommand_Release: - p = struct.pack("!H", 0x0114) + p[2:] - elif self.ControlCommand_ApplicationReady: - if self.AlarmSequenceNumber > 0: - p = struct.pack("!H", 0x0113) + p[2:] - else: - p = struct.pack("!H", 0x0112) + p[2:] - elif self.ControlCommand_PrmEnd: - if self.AlarmSequenceNumber > 0: - p = struct.pack("!H", 0x0111) + p[2:] - else: - p = struct.pack("!H", 0x0110) + p[2:] - return Block.post_build(self, p, pay) - - def get_response(self): - """Generate the response block of this request. - Careful: it only sets the fields which can be set from the request - """ - res = IODControlRes() - for field in ["ARUUID", "SessionKey", "AlarmSequenceNumber"]: - res.setfieldval(field, self.getfieldval(field)) - - res.block_type = self.block_type + 0x8000 - return res - - -class IODControlRes(Block): - """IODControl response block""" - fields_desc = [ - BlockHeader, - StrFixedLenField("padding", "", length=2), - UUIDField("ARUUID", None), - ShortField("SessionKey", 0), - XShortField("AlarmSequenceNumber", 0), - # ControlCommand - BitField("ControlCommand_reserved", 0, 9), - BitField("ControlCommand_PrmBegin", 0, 1), - BitField("ControlCommand_ReadyForRT_CLASS_3", 0, 1), - BitField("ControlCommand_ReadyForCompanion", 0, 1), - BitField("ControlCommand_Done", 1, 1), - BitField("ControlCommand_Release", 0, 1), - BitField("ControlCommand_ApplicationReady", 0, 1), - BitField("ControlCommand_PrmEnd", 0, 1), - XShortField("ControlBlockProperties", 0) - ] - - # default block_type value - block_type = 0x8110 - # The block_type can be among 0x8110 to 0x8118 except 0x8115 - # The right type is however determine by the type of the request - # (same type as the request + 0x8000) - - -# IODWriteRe{q,s} -class IODWriteReq(Block): - """IODWrite request block""" - fields_desc = [ - BlockHeader, - ShortField("seqNum", 0), - UUIDField("ARUUID", None), - XIntField("API", 0), - XShortField("slotNumber", 0), - XShortField("subslotNumber", 0), - StrFixedLenField("padding", "", length=2), - XShortEnumField("index", 0, IOD_WRITE_REQ_INDEX), - LenField("recordDataLength", None, fmt="I"), - StrFixedLenField("RWPadding", "", length=24), - ] - # default block_type value - block_type = 0x0008 - - def payload_length(self): - return self.recordDataLength - - def get_response(self): - """Generate the response block of this request. - Careful: it only sets the fields which can be set from the request - """ - res = IODWriteRes() - for field in ["seqNum", "ARUUID", "API", "slotNumber", - "subslotNumber", "index"]: - res.setfieldval(field, self.getfieldval(field)) - return res - - -class IODWriteRes(Block): - """IODWrite response block""" - fields_desc = [ - BlockHeader, - ShortField("seqNum", 0), - UUIDField("ARUUID", None), - XIntField("API", 0), - XShortField("slotNumber", 0), - XShortField("subslotNumber", 0), - StrFixedLenField("padding", "", length=2), - XShortEnumField("index", 0, IOD_WRITE_REQ_INDEX), - LenField("recordDataLength", None, fmt="I"), - XShortField("additionalValue1", 0), - XShortField("additionalValue2", 0), - IntEnumField("status", 0, ["OK"]), - StrFixedLenField("RWPadding", "", length=16), - ] - # default block_type value - block_type = 0x8008 - - -F_PARAMETERS_BLOCK_ID = [ - "No_F_WD_Time2_No_F_iPar_CRC", "No_F_WD_Time2_F_iPar_CRC", - "F_WD_Time2_No_F_iPar_CRC", "F_WD_Time2_F_iPar_CRC", - "reserved_4", "reserved_5", "reserved_6", "reserved_7" -] - - -class FParametersBlock(Packet): - """F-Parameters configuration block""" - name = "F-Parameters Block" - fields_desc = [ - # F_Prm_Flag1 - BitField("F_Prm_Flag1_Reserved_7", 0, 1), - BitField("F_CRC_Seed", 0, 1), - BitEnumField("F_CRC_Length", 0, 2, - ["CRC-24", "depreciated", "CRC-32", "reserved"]), - BitEnumField("F_SIL", 2, 2, ["SIL_1", "SIL_2", "SIL_3", "No_SIL"]), - BitField("F_Check_iPar", 0, 1), - BitField("F_Check_SeqNr", 0, 1), - - # F_Prm_Flag2 - BitEnumField("F_Par_Version", 1, 2, - ["V1", "V2", "reserved_2", "reserved_3"]), - BitEnumField("F_Block_ID", 0, 3, F_PARAMETERS_BLOCK_ID), - BitField("F_Prm_Flag2_Reserved", 0, 2), - BitField("F_Passivation", 0, 1), - - XShortField("F_Source_Add", 0), - XShortField("F_Dest_Add", 0), - ShortField("F_WD_Time", 0), - ConditionalField( - cond=lambda p: p.getfieldval("F_Block_ID") & 0b110 == 0b010, - fld=ShortField("F_WD_Time_2", 0)), - ConditionalField( - cond=lambda p: p.getfieldval("F_Block_ID") & 0b101 == 0b001, - fld=XIntField("F_iPar_CRC", 0)), - XShortField("F_Par_CRC", 0) - ] - overload_fields = { - IODWriteReq: { - "index": 0x100, # commonly used index for F-Parameters block - } - } - - -bind_layers(IODWriteReq, FParametersBlock, index=0x0100) -bind_layers(FParametersBlock, conf.padding_layer) - - -# IODWriteMultipleRe{q,s} -class PadFieldWithLen(PadField): - """PadField which handles the i2len function to include padding""" - def i2len(self, pkt, val): - """get the length of the field, including the padding length""" - fld_len = self._fld.i2len(pkt, val) - return fld_len + self.padlen(fld_len) - - -class IODWriteMultipleReq(Block): - """IODWriteMultiple request""" - fields_desc = [ - BlockHeader, - ShortField("seqNum", 0), - UUIDField("ARUUID", None), - XIntField("API", 0xffffffff), - XShortField("slotNumber", 0xffff), - XShortField("subslotNumber", 0xffff), - StrFixedLenField("padding", "", length=2), - XShortEnumField("index", 0, IOD_WRITE_REQ_INDEX), - FieldLenField("recordDataLength", None, fmt="I", length_of="blocks"), - StrFixedLenField("RWPadding", "", length=24), - FieldListField("blocks", [], - PadFieldWithLen(PacketField("", None, IODWriteReq), 4), - length_from=lambda pkt: pkt.recordDataLength) - ] - # default values - block_type = 0x0008 - index = 0xe040 - API = 0xffffffff - slotNumber = 0xffff - subslotNumber = 0xffff - - def post_build(self, p, pay): - # patch the update of block_length, as requests field must not be - # included. block_length is always 60 - if self.block_length is None: - p = p[:2] + struct.pack("!H", 60) + p[4:] - - # Remove the final padding added in requests - fld, val = self.getfield_and_val("blocks") - if fld.i2count(self, val) > 0: - length = len(val[-1]) - pad = fld.field.padlen(length) - if pad > 0: - p = p[:-pad] - # also reduce the recordDataLength accordingly - if self.recordDataLength is None: - val = struct.unpack("!I", p[36:40])[0] - val -= pad - p = p[:36] + struct.pack("!I", val) + p[40:] - - return Packet.post_build(self, p, pay) - - def get_response(self): - """Generate the response block of this request. - Careful: it only sets the fields which can be set from the request - """ - res = IODWriteMultipleRes() - for field in ["seqNum", "ARUUID", "API", "slotNumber", - "subslotNumber", "index"]: - res.setfieldval(field, self.getfieldval(field)) - - # append all block response - res_blocks = [] - for block in self.getfieldval("blocks"): - res_blocks.append(block.get_response()) - res.setfieldval("blocks", res_blocks) - return res - - -class IODWriteMultipleRes(Block): - """IODWriteMultiple response""" - fields_desc = [ - BlockHeader, - ShortField("seqNum", 0), - UUIDField("ARUUID", None), - XIntField("API", 0xffffffff), - XShortField("slotNumber", 0xffff), - XShortField("subslotNumber", 0xffff), - StrFixedLenField("padding", "", length=2), - XShortEnumField("index", 0, IOD_WRITE_REQ_INDEX), - FieldLenField("recordDataLength", None, fmt="I", length_of="blocks"), - XShortField("additionalValue1", 0), - XShortField("additionalValue2", 0), - IntEnumField("status", 0, ["OK"]), - StrFixedLenField("RWPadding", "", length=16), - FieldListField("blocks", [], PacketField("", None, IODWriteRes), - length_from=lambda pkt: pkt.recordDataLength) - ] - # default values - block_type = 0x8008 - index = 0xe040 - - def post_build(self, p, pay): - # patch the update of block_length, as requests field must not be - # included. block_length is always 60 - if self.block_length is None: - p = p[:2] + struct.pack("!H", 60) + p[4:] - - return Packet.post_build(self, p, pay) - - -# ARBlockRe{q,s} -class ARBlockReq(Block): - """Application relationship block request""" - fields_desc = [ - BlockHeader, - XShortEnumField("ARType", 1, AR_TYPE), - UUIDField("ARUUID", None), - ShortField("SessionKey", 0), - MACField("CMInitiatorMacAdd", None), - UUIDField("CMInitiatorObjectUUID", None), - # ARProperties - BitField("ARProperties_PullModuleAlarmAllowed", 0, 1), - BitEnumField("ARProperties_StartupMode", 0, 1, - ["Legacy", "Advanced"]), - BitField("ARProperties_reserved_3", 0, 6), - BitField("ARProperties_reserved_2", 0, 12), - BitField("ARProperties_AcknowledgeCompanionAR", 0, 1), - BitEnumField("ARProperties_CompanionAR", 0, 2, - ["Single_AR", "First_AR", "Companion_AR", "reserved"]), - BitEnumField("ARProperties_DeviceAccess", 0, 1, - ["ExpectedSubmodule", "Controlled_by_IO_device_app"]), - BitField("ARProperties_reserved_1", 0, 3), - BitEnumField("ARProperties_ParametrizationServer", 0, 1, - ["External_PrmServer", "CM_Initator"]), - BitField("ARProperties_SupervisorTakeoverAllowed", 0, 1), - BitEnumField("ARProperties_State", 1, 3, {1: "Active"}), - ShortField("CMInitiatorActivityTimeoutFactor", 1000), - ShortField("CMInitiatorUDPRTPort", 0x8892), - FieldLenField("StationNameLength", None, fmt="H", - length_of="CMInitiatorStationName"), - StrLenField("CMInitiatorStationName", "", - length_from=lambda pkt: pkt.StationNameLength), - ] - # default block_type value - block_type = 0x0101 - - def get_response(self): - """Generate the response block of this request. - Careful: it only sets the fields which can be set from the request - """ - res = ARBlockRes() - for field in ["ARType", "ARUUID", "SessionKey"]: - res.setfieldval(field, self.getfieldval(field)) - return res - - -class ARBlockRes(Block): - """Application relationship block response""" - fields_desc = [ - BlockHeader, - XShortEnumField("ARType", 1, AR_TYPE), - UUIDField("ARUUID", None), - ShortField("SessionKey", 0), - MACField("CMResponderMacAdd", None), - ShortField("CMResponderUDPRTPort", 0x8892), - ] - # default block_type value - block_type = 0x8101 - - -# IOCRBlockRe{q,s} -class IOCRAPIObject(Packet): - """API item descriptor used in API description of IOCR blocks""" - name = "API item" - fields_desc = [ - XShortField("SlotNumber", 0), - XShortField("SubslotNumber", 0), - ShortField("FrameOffset", 0), - ] - - def extract_padding(self, s): - return None, s # No extra payload - - -class IOCRAPI(Packet): - """API description used in IOCR block""" - name = "API" - fields_desc = [ - XIntField("API", 0), - FieldLenField("NumberOfIODataObjects", None, - count_of="IODataObjects"), - PacketListField("IODataObjects", [], IOCRAPIObject, - count_from=lambda p: p.NumberOfIODataObjects), - FieldLenField("NumberOfIOCS", None, - count_of="IOCSs"), - PacketListField("IOCSs", [], IOCRAPIObject, - count_from=lambda p: p.NumberOfIOCS), - ] - - def extract_padding(self, s): - return None, s # No extra payload - - -class IOCRBlockReq(Block): - """IO Connection Relationship block request""" - fields_desc = [ - BlockHeader, - XShortEnumField("IOCRType", 1, IOCR_TYPE), - XShortField("IOCRReference", 1), - XShortField("LT", 0x8892), - # IOCRProperties - BitField("IOCRProperties_reserved3", 0, 8), - BitField("IOCRProperties_reserved2", 0, 11), - BitField("IOCRProperties_reserved1", 0, 9), - BitEnumField("IOCRProperties_RTClass", 0, 4, - IOCR_BLOCK_REQ_IOCR_PROPERTIES), - ShortField("DataLength", 40), - XShortField("FrameID", 0x8000), - ShortField("SendClockFactor", 32), - ShortField("ReductionRatio", 32), - ShortField("Phase", 1), - ShortField("Sequence", 0), - XIntField("FrameSendOffset", 0xffffffff), - ShortField("WatchdogFactor", 10), - ShortField("DataHoldFactor", 10), - # IOCRTagHeader - BitEnumField("IOCRTagHeader_IOUserPriority", 6, 3, - {6: "IOCRPriority"}), - BitField("IOCRTagHeader_reserved", 0, 1), - BitField("IOCRTagHeader_IOCRVLANID", 0, 12), - MACField("IOCRMulticastMACAdd", None), - FieldLenField("NumberOfAPIs", None, fmt="H", count_of="APIs"), - PacketListField("APIs", [], IOCRAPI, - count_from=lambda p: p.NumberOfAPIs) - ] - # default block_type value - block_type = 0x0102 - - def get_response(self): - """Generate the response block of this request. - Careful: it only sets the fields which can be set from the request - """ - res = IOCRBlockRes() - for field in ["IOCRType", "IOCRReference", "FrameID"]: - res.setfieldval(field, self.getfieldval(field)) - return res - - -class IOCRBlockRes(Block): - """IO Connection Relationship block response""" - fields_desc = [ - BlockHeader, - XShortEnumField("IOCRType", 1, IOCR_TYPE), - XShortField("IOCRReference", 1), - XShortField("FrameID", 0x8000), - ] - # default block_type value - block_type = 0x8102 - - -# ExpectedSubmoduleBlockReq -class ExpectedSubmoduleDataDescription(Packet): - """Description of the data of a submodule""" - name = "Data Description" - fields_desc = [ - XShortEnumField("DataDescription", 0, {1: "Input", 2: "Output"}), - ShortField("SubmoduleDataLength", 0), - ByteField("LengthIOCS", 0), - ByteField("LengthIOPS", 0), - ] - - def extract_padding(self, s): - return None, s # No extra payload - - -class ExpectedSubmodule(Packet): - """Description of a submodule in an API of an expected submodule""" - name = "Submodule" - fields_desc = [ - XShortField("SubslotNumber", 0), - XIntField("SubmoduleIdentNumber", 0), - # Submodule Properties - XByteField("SubmoduleProperties_reserved_2", 0), - BitField("SubmoduleProperties_reserved_1", 0, 2), - BitField("SubmoduleProperties_DiscardIOXS", 0, 1), - BitField("SubmoduleProperties_ReduceOutputSubmoduleDataLength", 0, 1), - BitField("SubmoduleProperties_ReduceInputSubmoduleDataLength", 0, 1), - BitField("SubmoduleProperties_SharedInput", 0, 1), - BitEnumField("SubmoduleProperties_Type", 0, 2, - ["NO_IO", "INPUT", "OUTPUT", "INPUT_OUTPUT"]), - PacketListField( - "DataDescription", [], ExpectedSubmoduleDataDescription, - count_from=lambda p: 2 if p.SubmoduleProperties_Type == 3 else 1 - ), - ] - - def extract_padding(self, s): - return None, s # No extra payload - - -class ExpectedSubmoduleAPI(Packet): - """Description of an API in the expected submodules blocks""" - name = "API" - fields_desc = [ - XIntField("API", 0), - XShortField("SlotNumber", 0), - XIntField("ModuleIdentNumber", 0), - XShortField("ModuleProperties", 0), - FieldLenField("NumberOfSubmodules", None, fmt="H", - count_of="Submodules"), - PacketListField("Submodules", [], ExpectedSubmodule, - count_from=lambda p: p.NumberOfSubmodules), - ] - - def extract_padding(self, s): - return None, s # No extra payload - - -class ExpectedSubmoduleBlockReq(Block): - """Expected submodule block request""" - fields_desc = [ - BlockHeader, - FieldLenField("NumberOfAPIs", None, fmt="H", count_of="APIs"), - PacketListField("APIs", [], ExpectedSubmoduleAPI, - count_from=lambda p: p.NumberOfAPIs) - ] - # default block_type value - block_type = 0x0104 - - def get_response(self): - """Generate the response block of this request. - Careful: it only sets the fields which can be set from the request - """ - return None # no response associated (should be modulediffblock) - - -# PROFINET IO DCE/RPC PDU -PNIO_RPC_BLOCK_ASSOCIATION = { - # requests - "0101": ARBlockReq, - "0102": IOCRBlockReq, - "0104": ExpectedSubmoduleBlockReq, - "0110": IODControlReq, - "0111": IODControlReq, - "0112": IODControlReq, - "0113": IODControlReq, - "0114": IODControlReq, - "0116": IODControlReq, - "0117": IODControlReq, - "0118": IODControlReq, - - # responses - "8101": ARBlockRes, - "8102": IOCRBlockRes, - "8110": IODControlRes, - "8111": IODControlRes, - "8112": IODControlRes, - "8113": IODControlRes, - "8114": IODControlRes, - "8116": IODControlRes, - "8117": IODControlRes, - "8118": IODControlRes, -} - - -def _guess_block_class(_pkt, *args, **kargs): - cls = Block # Default block type - - # Special cases - if _pkt[:2] == b'\x00\x08': # IODWriteReq - if _pkt[34:36] == b'\xe0@': # IODWriteMultipleReq - cls = IODWriteMultipleReq - else: - cls = IODWriteReq - - elif _pkt[:2] == b'\x80\x08': # IODWriteRes - if _pkt[34:36] == b'\xe0@': # IODWriteMultipleRes - cls = IODWriteMultipleRes - else: - cls = IODWriteRes - - # Common cases - else: - btype = bytes_hex(_pkt[:2]).decode("utf8") - if btype in PNIO_RPC_BLOCK_ASSOCIATION: - cls = PNIO_RPC_BLOCK_ASSOCIATION[btype] - - return cls(_pkt, *args, **kargs) - - -def dce_rpc_endianess(pkt): - """determine the symbol for the endianness of a the DCE/RPC""" - try: - endianness = pkt.underlayer.endianness - except AttributeError: - # handle the case where a PNIO class is - # built without its DCE-RPC under-layer - # i.e there is no endianness indication - return "!" - if endianness == 0: # big endian - return ">" - elif endianness == 1: # little endian - return "<" - else: - return "!" - - -class NDRData(Packet): - """Base NDRData to centralize some fields. It can't be instantiated""" - fields_desc = [ - EndiannessField( - FieldLenField("args_length", None, fmt="I", length_of="blocks"), - endianess_from=dce_rpc_endianess), - EndiannessField( - FieldLenField("max_count", None, fmt="I", length_of="blocks"), - endianess_from=dce_rpc_endianess), - EndiannessField( - IntField("offset", 0), - endianess_from=dce_rpc_endianess), - EndiannessField( - FieldLenField("actual_count", None, fmt="I", length_of="blocks"), - endianess_from=dce_rpc_endianess), - PacketListField("blocks", [], _guess_block_class, - length_from=lambda p: p.args_length) - ] - - def __new__(cls, name, bases, dct): - raise NotImplementedError() - - -class PNIOServiceReqPDU(Packet): - """PNIO PDU for RPC Request""" - fields_desc = [ - EndiannessField( - FieldLenField("args_max", None, fmt="I", length_of="blocks"), - endianess_from=dce_rpc_endianess), - NDRData, - ] - overload_fields = { - DceRpc: { - # random object_uuid in the appropriate range - "object_uuid": RandUUID("dea00000-6c97-11d1-8271-******"), - # interface uuid to send to a device - "interface_uuid": RPC_INTERFACE_UUID["UUID_IO_DeviceInterface"], - # Request DCE/RPC type - "type": 0, - }, - } - - @classmethod - def can_handle(cls, pkt, rpc): - """heuristic guess_payload_class""" - # type = 0 => request - if rpc.getfieldval("type") == 0 and \ - str(rpc.object_uuid).startswith("dea00000-6c97-11d1-8271-"): - return True - return False - - -DceRpcPayload.register_possible_payload(PNIOServiceReqPDU) - - -class PNIOServiceResPDU(Packet): - """PNIO PDU for RPC Response""" - fields_desc = [ - EndiannessField(IntEnumField("status", 0, ["OK"]), - endianess_from=dce_rpc_endianess), - NDRData, - ] - overload_fields = { - DceRpc: { - # random object_uuid in the appropriate range - "object_uuid": RandUUID("dea00000-6c97-11d1-8271-******"), - # interface uuid to send to a host - "interface_uuid": RPC_INTERFACE_UUID[ - "UUID_IO_ControllerInterface"], - # Request DCE/RPC type - "type": 2, - }, - } - - @classmethod - def can_handle(cls, pkt, rpc): - """heuristic guess_payload_class""" - # type = 2 => response - if rpc.getfieldval("type") == 2 and \ - str(rpc.object_uuid).startswith("dea00000-6c97-11d1-8271-"): - return True - return False - - -DceRpcPayload.register_possible_payload(PNIOServiceResPDU) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ppi.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/ppi.py deleted file mode 100644 index f43640961c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ppi.py +++ /dev/null @@ -1,86 +0,0 @@ -## This file is (hopefully) part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## -## This program is published under a GPLv2 license - -# scapy.contrib.description = PPI -# scapy.contrib.status = loads - - -""" -PPI (Per-Packet Information). -""" -import logging,struct -from scapy.config import conf -from scapy.packet import * -from scapy.fields import * -from scapy.layers.l2 import Ether -from scapy.layers.dot11 import Dot11 - -# Dictionary to map the TLV type to the class name of a sub-packet -_ppi_types = {} -def addPPIType(id, value): - _ppi_types[id] = value -def getPPIType(id, default="default"): - return _ppi_types.get(id, _ppi_types.get(default, None)) - - -# Default PPI Field Header -class PPIGenericFldHdr(Packet): - name = "PPI Field Header" - fields_desc = [ LEShortField('pfh_type', 0), - FieldLenField('pfh_length', None, length_of="value", fmt='= 4: - t,pfh_len = struct.unpack(" pfh_len): - out.payload.payload = conf.padding_layer(p[pfh_len:]) - elif (len(p) > pfh_len): - out.payload = conf.padding_layer(p[pfh_len:]) - - else: - out = conf.raw_layer(p, **kargs) - return out - - - - -class PPI(Packet): - name = "PPI Packet Header" - fields_desc = [ ByteField('pph_version', 0), - ByteField('pph_flags', 0), - FieldLenField('pph_len', None, length_of="PPIFieldHeaders", fmt=". - -# author: - -# scapy.contrib.description = CACE Per-Packet Information (PPI) -# scapy.contrib.status = loads - -""" -CACE PPI types -""" - -from scapy.data import PPI_DOT11COMMON -from scapy.packet import bind_layers -from scapy.fields import ByteField, Field, FlagsField, LELongField, \ - LEShortField -from scapy.layers.ppi import PPI_Hdr, PPI_Element - - -# PPI 802.11 Common Field Header Fields -class dBmByteField(Field): - def __init__(self, name, default): - Field.__init__(self, name, default, "b") - - def i2repr(self, pkt, x): - if x is not None: - x = "%4d dBm" % x - return x - - -class PPITSFTField(LELongField): - def i2h(self, pkt, x): - flags = 0 - if pkt: - flags = pkt.getfieldval("Pkt_Flags") - if not flags: - flags = 0 - if flags & 0x02: - scale = 1e-3 - else: - scale = 1e-6 - tout = scale * float(x) - return tout - - def h2i(self, pkt, x): - scale = 1e6 - if pkt: - flags = pkt.getfieldval("Pkt_Flags") - if flags and (flags & 0x02): - scale = 1e3 - tout = int((scale * x) + 0.5) - return tout - - -_PPIDot11CommonChFlags = [ - '', '', '', '', 'Turbo', 'CCK', 'OFDM', '2GHz', '5GHz', - 'PassiveOnly', 'Dynamic CCK-OFDM', 'GSFK'] - -_PPIDot11CommonPktFlags = ['FCS', 'TSFT_ms', 'FCS_Invalid', 'PHY_Error'] - - -# PPI 802.11 Common Field Header -class PPI_Dot11Common(PPI_Element): - name = "PPI 802.11-Common" - fields_desc = [PPITSFTField('TSF_Timer', 0), - FlagsField('Pkt_Flags', 0, -16, _PPIDot11CommonPktFlags), - LEShortField('Rate', 0), - LEShortField('Ch_Freq', 0), - FlagsField('Ch_Flags', 0, -16, _PPIDot11CommonChFlags), - ByteField('FHSS_Hop', 0), - ByteField('FHSS_Pat', 0), - dBmByteField('Antsignal', -128), - dBmByteField('Antnoise', -128)] - - def extract_padding(self, s): - return b'', s - - -# Hopefully other CACE defined types will be added here. - - -# Add the dot11common layer to the PPI array -bind_layers(PPI_Hdr, PPI_Dot11Common, pfh_type=PPI_DOT11COMMON) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ppi_geotag.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/ppi_geotag.py deleted file mode 100644 index a7cc634546..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ppi_geotag.py +++ /dev/null @@ -1,467 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# author: - -# scapy.contrib.description = CACE Per-Packet Information (PPI) Geolocation -# scapy.contrib.status = loads - - -""" -PPI-GEOLOCATION tags -""" - -from __future__ import absolute_import -import functools -import struct - -from scapy.base_classes import Packet_metaclass -from scapy.data import PPI_GPS, PPI_VECTOR, PPI_SENSOR, PPI_ANTENNA -from scapy.packet import bind_layers -from scapy.fields import ByteField, ConditionalField, Field, FlagsField, \ - LEIntField, LEShortEnumField, LEShortField, StrFixedLenField, \ - UTCTimeField, XLEIntField, SignedByteField, XLEShortField -from scapy.layers.ppi import PPI_Hdr, PPI_Element -from scapy.error import warning -import scapy.modules.six as six -from scapy.modules.six.moves import range - -CURR_GEOTAG_VER = 2 # Major revision of specification - - -# The FixedX_Y Fields are used to store fixed point numbers in a variety of -# fields in the GEOLOCATION-TAGS specification - - -class _RMMLEIntField(LEIntField): - __slots__ = ["min_i2h", "max_i2h", "lambda_i2h", - "min_h2i", "max_h2i", "lambda_h2i", - "rname", "ffmt"] - - def __init__(self, name, default, _min, _max, _min2, _max2, _lmb, _lmb2, - fmt, *args, **kargs): - LEIntField.__init__(self, name, default, *args, **kargs) - self.min_i2h = _min - self.max_i2h = _max - self.lambda_i2h = _lmb - self.min_h2i = _min2 - self.max_h2i = _max2 - self.lambda_h2i = _lmb2 - self.rname = self.__class__.__name__ - self.ffmt = fmt - - def i2h(self, pkt, x): - if x is not None: - if (x < self.min_i2h): - warning("%s: Internal value too negative: %d", self.rname, x) - x = int(round(self.min_i2h)) - elif (x > self.max_i2h): - warning("%s: Internal value too positive: %d", self.rname, x) - x = self.max_i2h - x = self.lambda_i2h(x) - return x - - def h2i(self, pkt, x): - if x is not None: - if (x < self.min_h2i): - warning("%s: Input value too negative: %.10f", self.rname, x) - x = int(round(self.min_h2i)) - elif (x >= self.max_h2i): - warning("%s: Input value too positive: %.10f", self.rname, x) - x = int(round(self.max_h2i)) - x = self.lambda_h2i(x) - return x - - def i2m(self, pkt, x): - """Convert internal value to machine value""" - if x is None: - # Try to return zero if undefined - x = self.h2i(pkt, 0) - return x - - def i2repr(self, pkt, x): - if x is None: - y = 0 - else: - y = self.i2h(pkt, x) - return ("%" + self.ffmt) % (y) - - -class Fixed3_6Field(_RMMLEIntField): - def __init__(self, name, default, *args, **kargs): - _RMMLEIntField.__init__(self, - name, default, - 0, - 999999999, - -0.5e-6, - 999.9999995, - lambda x: x * 1e-6, - lambda x: int(round(x * 1e6)), - "3.6f") - - -class Fixed3_7Field(_RMMLEIntField): - def __init__(self, name, default, *args, **kargs): - _RMMLEIntField.__init__(self, - name, default, - 0, - 3600000000, - -180.00000005, - 180.00000005, - lambda x: (x - 1800000000) * 1e-7, - lambda x: int(round((x + 180.0) * 1e7)), - "3.7f") - - -class Fixed6_4Field(_RMMLEIntField): - def __init__(self, name, default, *args, **kargs): - _RMMLEIntField.__init__(self, - name, default, - 0, - 3600000000, - -180000.00005, - 180000.00005, - lambda x: (x - 1800000000) * 1e-4, - lambda x: int(round((x + 180000.0) * 1e4)), - "6.4f") - -# The GPS timestamps fractional time counter is stored in a 32-bit unsigned ns -# counter. -# The ept field is as well, - - -class NSCounter_Field(_RMMLEIntField): - def __init__(self, name, default): - _RMMLEIntField.__init__(self, - name, default, - 0, - 2**32, - 0, - (2**32 - 1) / 1e9, - lambda x: (x / 1e9), - lambda x: int(round(x * 1e9)), - "1.9f") - - -class LETimeField(UTCTimeField, LEIntField): - __slots__ = ["epoch", "delta", "strf"] - - def __init__(self, name, default, epoch=None, - strf="%a, %d %b %Y %H:%M:%S %z"): - LEIntField.__init__(self, name, default) - UTCTimeField.__init__(self, name, default, epoch=epoch, strf=strf) - - -class GPSTime_Field(LETimeField): - def __init__(self, name, default): - LETimeField.__init__(self, name, default, - strf="%a, %d %b %Y %H:%M:%S UTC") - - -class VectorFlags_Field(XLEIntField): - """Represents the VectorFlags field. Handles the RelativeTo:sub-field""" - _fwdstr = "DefinesForward" - _resmask = 0xfffffff8 - _relmask = 0x6 - _relnames = [ - "RelativeToForward", - "RelativeToEarth", - "RelativeToCurrent", - "RelativeToReserved", - ] - _relvals = [0x00, 0x02, 0x04, 0x06] - - def i2repr(self, pkt, x): - if x is None: - return str(x) - r = [] - if (x & 0x1): - r.append(self._fwdstr) - i = (x & self._relmask) >> 1 - r.append(self._relnames[i]) - i = x & self._resmask - if (i): - r.append("ReservedBits:%08X" % i) - sout = "+".join(r) - return sout - - def any2i(self, pkt, x): - if isinstance(x, str): - r = x.split("+") - y = 0 - for value in r: - if (value == self._fwdstr): - y |= 0x1 - elif (value in self._relnames): - i = self._relnames.index(value) - y &= (~self._relmask) - y |= self._relvals[i] - else: - # logging.warning("Unknown VectorFlags Arg: %s", value) - pass - else: - y = x - # print "any2i: %s --> %s" % (str(x), str(y)) - return y - - -class HCSIFlagsField(FlagsField): - """A FlagsField where each bit/flag turns a conditional field on or off. - - If the value is None when building a packet, i2m() will check the value of - every field in self.names. If the field's value is not None, the - corresponding flag will be set. - """ - - def i2m(self, pkt, val): - if val is None: - val = 0 - if (pkt): - for i, name in enumerate(self.names): - value = pkt.getfieldval(name) - if value is not None: - val |= 1 << i - return val - - -class HCSINullField(Field): - def __init__(self, name): - Field.__init__(self, name, None, '!') - - -def _hcsi_null_range(*args, **kwargs): - """Builds a list of _HCSINullField with numbered "Reserved" names. - - Takes the same arguments as the ``range`` built-in. - - :returns: list[HCSINullField] - """ - return [ - HCSINullField('Reserved{:02d}'.format(x)) - for x in range(*args, **kwargs) - ] - - -class HCSIDescField(StrFixedLenField): - def __init__(self, name, default): - StrFixedLenField.__init__(self, name, default, length=32) - - -class HCSIAppField(StrFixedLenField): - def __init__(self, name, default): - StrFixedLenField.__init__(self, name, default, length=60) - - -def _FlagsList(myfields): - flags = ["Reserved%02d" % i for i in range(32)] - for i, value in six.iteritems(myfields): - flags[i] = value - return flags - - -# Define all geolocation-tag flags lists -_hcsi_gps_flags = _FlagsList({ - 0: "No Fix Available", - 1: "GPS", - 2: "Differential GPS", - 3: "Pulse Per Second", - 4: "Real Time Kinematic", - 5: "Float Real Time Kinematic", - 6: "Estimated (Dead Reckoning)", - 7: "Manual Input", - 8: "Simulation", -}) - -_hcsi_vector_char_flags = _FlagsList({ - 0: "Antenna", - 1: "Direction of Travel", - 2: "Front of Vehicle", - 3: "Angle of Arrival", - 4: "Transmitter Position", - 8: "GPS Derived", - 9: "INS Derived", - 10: "Compass Derived", - 11: "Acclerometer Derived", - 12: "Human Derived", -}) - -_hcsi_antenna_flags = _FlagsList({ - 1: "Horizontal Polarization", - 2: "Vertical Polarization", - 3: "Circular Polarization Left", - 4: "Circular Polarization Right", - 16: "Electronically Steerable", - 17: "Mechanically Steerable", -}) - -# HCSI PPI Fields are similar to RadioTap. A mask field called "present" -# specifies if each field is present. All other fields are conditional. When -# dissecting a packet, each field is present if "present" has the corresponding -# bit set. -# -# When building a packet, if "present" is None, the mask is set to include -# every field that does not have a value of None. Otherwise, if the mask field -# is not None, only the fields specified by "present" will be added to the -# packet. -# -# To build each Packet type, build a list of the fields normally, excluding -# the present bitmask field. The code will then construct conditional -# versions of each field and add the present field. -# -# See GPS_Fields as an example. - -_COMMON_GEOTAG_HEADERS = [ - ByteField('geotag_ver', CURR_GEOTAG_VER), - ByteField('geotag_pad', 0), - LEShortField('geotag_len', None), -] - -_COMMON_GEOTAG_FOOTER = [ - HCSIDescField("DescString", None), - XLEIntField("AppId", None), - HCSIAppField("AppData", None), - HCSINullField("Extended"), -] - - -# Conditional test for all HCSI Fields -def _HCSITest(fname, fbit, pkt): - if pkt.present is None: - return pkt.getfieldval(fname) is not None - return pkt.present & fbit - - -class _Geotag_metaclass(Packet_metaclass): - def __new__(cls, name, bases, dct): - hcsi_fields = dct.get('hcsi_fields', []) - - if len(hcsi_fields) != 0: - hcsi_fields += _COMMON_GEOTAG_FOOTER - if len(hcsi_fields) not in (8, 16, 32): - raise TypeError( - 'hcsi_fields in {} was {} elements long, expected 8, 16 ' - 'or 32'.format(name, len(hcsi_fields))) - - names = [f.name for f in hcsi_fields] - - # Add the base fields - fields_desc = _COMMON_GEOTAG_HEADERS + [ - HCSIFlagsField('present', None, -len(names), names), - ] - - # Add conditional fields - for i, field in enumerate(hcsi_fields): - fields_desc.append(ConditionalField( - field, functools.partial( - _HCSITest, field.name, 1 << i))) - - dct['fields_desc'] = fields_desc - - x = super(_Geotag_metaclass, cls).__new__(cls, name, bases, dct) - return x - - -class HCSIPacket(six.with_metaclass(_Geotag_metaclass, PPI_Element)): - def post_build(self, p, pay): - if self.geotag_len is None: - sl_g = struct.pack('. - -# scapy.contrib.description = Routing Information Protocol next gen (RIPng) -# scapy.contrib.status = loads - -from scapy.packet import Packet, bind_layers -from scapy.fields import ByteEnumField, ByteField, IP6Field, ShortField -from scapy.layers.inet import UDP - - -class RIPng(Packet): - name = "RIPng header" - fields_desc = [ - ByteEnumField("cmd", 1, {1: "req", 2: "resp"}), - ByteField("ver", 1), - ShortField("null", 0) - ] - - -class RIPngEntry(Packet): - name = "RIPng entry" - fields_desc = [ - IP6Field("prefix_or_nh", "::"), - ShortField("routetag", 0), - ByteField("prefixlen", 0), - ByteEnumField("metric", 1, {16: "Unreach", - 255: "next-hop entry"}) - ] - - -bind_layers(UDP, RIPng, sport=521, dport=521) -bind_layers(RIPng, RIPngEntry) -bind_layers(RIPngEntry, RIPngEntry) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/rsvp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/rsvp.py deleted file mode 100644 index a720826bde..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/rsvp.py +++ /dev/null @@ -1,225 +0,0 @@ -# RSVP layer - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = Resource Reservation Protocol (RSVP) -# scapy.contrib.status = loads - -from scapy.compat import chb -from scapy.packet import Packet, bind_layers -from scapy.fields import BitField, ByteEnumField, ByteField, FieldLenField, \ - IPField, ShortField, StrLenField, XByteField, XShortField -from scapy.layers.inet import IP, checksum - -rsvpmsgtypes = {0x01: "Path", - 0x02: "Reservation request", - 0x03: "Path error", - 0x04: "Reservation request error", - 0x05: "Path teardown", - 0x06: "Reservation teardown", - 0x07: "Reservation request acknowledgment" - } - - -class RSVP(Packet): - name = "RSVP" - fields_desc = [BitField("Version", 1, 4), - BitField("Flags", 1, 4), - ByteEnumField("Class", 0x01, rsvpmsgtypes), - XShortField("chksum", None), - ByteField("TTL", 1), - XByteField("dataofs", 0), - ShortField("Length", None)] - - def post_build(self, p, pay): - p += pay - if self.Length is None: - tmp_len = len(p) - tmp_p = p[:6] + chb((tmp_len >> 8) & 0xff) + chb(tmp_len & 0xff) - p = tmp_p + p[8:] - if self.chksum is None: - ck = checksum(p) - p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:] - return p - - -rsvptypes = {0x01: "Session", - 0x03: "HOP", - 0x04: "INTEGRITY", - 0x05: "TIME_VALUES", - 0x06: "ERROR_SPEC", - 0x07: "SCOPE", - 0x08: "STYLE", - 0x09: "FLOWSPEC", - 0x0A: "FILTER_SPEC", - 0x0B: "SENDER_TEMPLATE", - 0x0C: "SENDER_TSPEC", - 0x0D: "ADSPEC", - 0x0E: "POLICY_DATA", - 0x0F: "RESV_CONFIRM", - 0x10: "RSVP_LABEL", - 0x11: "HOP_COUNT", - 0x12: "STRICT_SOURCE_ROUTE", - 0x13: "LABEL_REQUEST", - 0x14: "EXPLICIT_ROUTE", - 0x15: "ROUTE_RECORD", - 0x16: "HELLO", - 0x17: "MESSAGE_ID", - 0x18: "MESSAGE_ID_ACK", - 0x19: "MESSAGE_ID_LIST", - 0x1E: "DIAGNOSTIC", - 0x1F: "ROUTE", - 0x20: "DIAG_RESPONSE", - 0x21: "DIAG_SELECT", - 0x22: "RECOVERY_LABEL", - 0x23: "UPSTREAM_LABEL", - 0x24: "LABEL_SET", - 0x25: "PROTECTION", - 0x26: "PRIMARY PATH ROUTE", - 0x2A: "DSBM IP ADDRESS", - 0x2B: "SBM_PRIORITY", - 0x2C: "DSBM TIMER INTERVALS", - 0x2D: "SBM_INFO", - 0x32: "S2L_SUB_LSP", - 0x3F: "DETOUR", - 0x40: "CHALLENGE", - 0x41: "DIFF-SERV", - 0x42: "CLASSTYPE", - 0x43: "LSP_REQUIRED_ATTRIBUTES", - 0x80: "NODE_CHAR", - 0x81: "SUGGESTED_LABEL", - 0x82: "ACCEPTABLE_LABEL_SET", - 0x83: "RESTART_CA", - 0x84: "SESSION-OF-INTEREST", - 0x85: "LINK_CAPABILITY", - 0x86: "Capability Object", - 0xA1: "RSVP_HOP_L2", - 0xA2: "LAN_NHOP_L2", - 0xA3: "LAN_NHOP_L3", - 0xA4: "LAN_LOOPBACK", - 0xA5: "TCLASS", - 0xC0: "TUNNEL", - 0xC1: "LSP_TUNNEL_INTERFACE_ID", - 0xC2: "USER_ERROR_SPEC", - 0xC3: "NOTIFY_REQUEST", - 0xC4: "ADMIN-STATUS", - 0xC5: "LSP_ATTRIBUTES", - 0xC6: "ALARM_SPEC", - 0xC7: "ASSOCIATION", - 0xC8: "SECONDARY_EXPLICIT_ROUTE", - 0xC9: "SECONDARY_RECORD_ROUTE", - 0xCD: "FAST_REROUTE", - 0xCF: "SESSION_ATTRIBUTE", - 0xE1: "DCLASS", - 0xE2: "PACKETCABLE EXTENSIONS", - 0xE3: "ATM_SERVICECLASS", - 0xE4: "CALL_OPS (ASON)", - 0xE5: "GENERALIZED_UNI", - 0xE6: "CALL_ID", - 0xE7: "3GPP2_Object", - 0xE8: "EXCLUDE_ROUTE" - } - - -class RSVP_Object(Packet): - name = "RSVP_Object" - fields_desc = [ShortField("Length", 4), - ByteEnumField("Class", 0x01, rsvptypes), - ByteField("C-Type", 1)] - - def guess_payload_class(self, payload): - if self.Class == 0x03: - return RSVP_HOP - elif self.Class == 0x05: - return RSVP_Time - elif self.Class == 0x0c: - return RSVP_SenderTSPEC - elif self.Class == 0x13: - return RSVP_LabelReq - elif self.Class == 0xCF: - return RSVP_SessionAttrb - else: - return RSVP_Data - - -class RSVP_Data(Packet): - name = "Data" - overload_fields = {RSVP_Object: {"Class": 0x01}} - fields_desc = [StrLenField("Data", "", length_from=lambda pkt:pkt.underlayer.Length - 4)] # noqa: E501 - - def default_payload_class(self, payload): - return RSVP_Object - - -class RSVP_HOP(Packet): - name = "HOP" - overload_fields = {RSVP_Object: {"Class": 0x03}} - fields_desc = [IPField("neighbor", "0.0.0.0"), - BitField("inface", 1, 32)] - - def default_payload_class(self, payload): - return RSVP_Object - - -class RSVP_Time(Packet): - name = "Time Val" - overload_fields = {RSVP_Object: {"Class": 0x05}} - fields_desc = [BitField("refresh", 1, 32)] - - def default_payload_class(self, payload): - return RSVP_Object - - -class RSVP_SenderTSPEC(Packet): - name = "Sender_TSPEC" - overload_fields = {RSVP_Object: {"Class": 0x0c}} - fields_desc = [ByteField("Msg_Format", 0), - ByteField("reserve", 0), - ShortField("Data_Length", 4), - ByteField("Srv_hdr", 1), - ByteField("reserve2", 0), - ShortField("Srv_Length", 4), - StrLenField("Tokens", "", length_from=lambda pkt:pkt.underlayer.Length - 12)] # noqa: E501 - - def default_payload_class(self, payload): - return RSVP_Object - - -class RSVP_LabelReq(Packet): - name = "Label Req" - overload_fields = {RSVP_Object: {"Class": 0x13}} - fields_desc = [ShortField("reserve", 1), - ShortField("L3PID", 1)] - - def default_payload_class(self, payload): - return RSVP_Object - - -class RSVP_SessionAttrb(Packet): - name = "Session_Attribute" - overload_fields = {RSVP_Object: {"Class": 0xCF}} - fields_desc = [ByteField("Setup_priority", 1), - ByteField("Hold_priority", 1), - ByteField("flags", 1), - FieldLenField("Name_length", None, length_of="Name"), - StrLenField("Name", "", length_from=lambda pkt:pkt.Name_length), # noqa: E501 - ] - - def default_payload_class(self, payload): - return RSVP_Object - - -bind_layers(IP, RSVP, {"proto": 46}) -bind_layers(RSVP, RSVP_Object) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/rtr.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/rtr.py deleted file mode 100755 index 425e4926f8..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/rtr.py +++ /dev/null @@ -1,345 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# Copyright (C) 2018 Francois Contat - -# Based on RTR RFC 6810 https://tools.ietf.org/html/rfc6810 for version 0 -# Based on RTR RFC 8210 https://tools.ietf.org/html/rfc8210 for version 1 - -# scapy.contrib.description = The RPKI to Router Protocol -# scapy.contrib.status = loads - -# Start dev - -import struct - -from scapy.packet import Packet, bind_layers, Raw -from scapy.fields import ByteEnumField, ByteField, IntField, ShortField -from scapy.fields import IPField, IP6Field, StrLenField -from scapy.fields import FieldLenField -from scapy.fields import StrFixedLenField, ShortEnumField -from scapy.layers.inet import TCP -from scapy.compat import orb - -STATIC_SERIAL_NOTIFY_LENGTH = 12 -STATIC_SERIAL_QUERY_LENGTH = 12 -STATIC_RESET_QUERY_LENGTH = 8 -STATIC_CACHE_RESET_LENGTH = 8 -STATIC_CACHE_RESPONSE_LENGTH = 8 -STATIC_IPV4_PREFIX_LENGTH = 20 -STATIC_IPV6_PREFIX_LENGTH = 32 -STATIC_END_OF_DATA_V0_LENGTH = 12 -STATIC_END_OF_DATA_V1_LENGTH = 24 - -RTR_VERSION = {0: '0', - 1: '1'} - -PDU_TYPE = {0: 'Serial Notify', - 1: 'Serial Query', - 2: 'Reset Query', - 3: 'Cache Response', - 4: 'IPv4 Prefix', - 6: 'IPv6 Prefix', - 7: 'End of Data', - 8: 'Cache Reset', - 9: 'Router Key', - 10: 'Error Report', - 255: 'Reserved'} - -ERROR_LIST = {0: 'Corrupt Data', - 1: 'Internal Error', - 2: 'No data Available', - 3: 'Invalid Request', - 4: 'Unsupported Protocol Version', - 5: 'Unsupported PDU Type', - 6: 'Withdrawal of Unknown Record', - 7: 'Duplicate Announcement Received', - 8: 'Unexpected Protocol Version'} - - -class RTRSerialNotify(Packet): - - ''' - - Serial Notify packet from section 5.2 - https://tools.ietf.org/html/rfc6810#section-5.2 - - ''' - - name = 'Serial Notify' - fields_desc = [ByteEnumField('rtr_version', 0, RTR_VERSION), - ByteEnumField('pdu_type', 0, PDU_TYPE), - ShortField('session_id', 0), - IntField('length', STATIC_SERIAL_NOTIFY_LENGTH), - IntField('serial_number', 0)] - - -class RTRSerialQuery(Packet): - - ''' - - Serial Query packet from section 5.3 - https://tools.ietf.org/html/rfc6810#section-5.3 - - ''' - name = 'Serial Query' - fields_desc = [ByteEnumField('rtr_version', 0, RTR_VERSION), - ByteEnumField('pdu_type', 1, PDU_TYPE), - ShortField('session_id', 0), - IntField('length', STATIC_SERIAL_QUERY_LENGTH), - IntField('serial_number', 0)] - - -class RTRResetQuery(Packet): - - ''' - - Reset Query packet from section 5.4 - https://tools.ietf.org/html/rfc6810#section-5.4 - - ''' - name = 'Reset Query' - fields_desc = [ByteEnumField('rtr_version', 0, RTR_VERSION), - ByteEnumField('pdu_type', 2, PDU_TYPE), - ShortField('reserved', 0), - IntField('length', STATIC_RESET_QUERY_LENGTH)] - - -class RTRCacheResponse(Packet): - - ''' - - Cache Response packet from section 5.5 - https://tools.ietf.org/html/rfc6810#section-5.5 - - ''' - name = 'Cache Response' - fields_desc = [ByteEnumField('rtr_version', 0, RTR_VERSION), - ByteEnumField('pdu_type', 3, PDU_TYPE), - ShortField('session_id', 0), - IntField('length', STATIC_CACHE_RESPONSE_LENGTH)] - - def guess_payload_class(self, payload): - return RTR - - -class RTRIPv4Prefix(Packet): - - ''' - - IPv4 Prefix packet from section 5.6 - https://tools.ietf.org/html/rfc6810#section-5.6 - - ''' - name = 'IPv4 Prefix' - fields_desc = [ByteEnumField('rtr_version', 0, RTR_VERSION), - ByteEnumField('pdu_type', 4, PDU_TYPE), - ShortField('reserved', 0), - IntField('length', STATIC_IPV4_PREFIX_LENGTH), - ByteField('flags', 0), - ByteField('shortest_length', 0), - ByteField('longest_length', 0), - ByteField('zeros', 0), - IPField('prefix', '0.0.0.0'), - IntField('asn', 0)] - - def guess_payload_class(self, payload): - return RTR - - -class RTRIPv6Prefix(Packet): - - ''' - - IPv6 Prefix packet from section 5.7 - https://tools.ietf.org/html/rfc6810#section-5.7 - - ''' - name = 'IPv6 Prefix' - fields_desc = [ByteEnumField('rtr_version', 0, RTR_VERSION), - ByteEnumField('pdu_type', 6, PDU_TYPE), - ShortField('reserved', 0), - IntField('length', STATIC_IPV6_PREFIX_LENGTH), - ByteField('flags', 0), - ByteField('shortest_length', 0), - ByteField('longest_length', 0), - ByteField('zeros', 0), - IP6Field("prefix", "::"), - IntField('asn', 0)] - - def guess_payload_class(self, payload): - return RTR - - -class RTREndofDatav0(Packet): - - ''' - - End of Data packet from version 0 standard section 5.8 - https://tools.ietf.org/html/rfc6810#section-5.8 - - ''' - name = 'End of Data - version 0' - fields_desc = [ByteEnumField('rtr_version', 0, RTR_VERSION), - ByteEnumField('pdu_type', 7, PDU_TYPE), - ShortField('session_id', 0), - IntField('length', STATIC_END_OF_DATA_V0_LENGTH), - IntField('serial_number', 0)] - - -class RTREndofDatav1(Packet): - - ''' - - End of Data packet from version 1 standard section 5.8 - https://tools.ietf.org/html/rfc8210#section-5.8 - - ''' - name = 'End of Data - version 1' - fields_desc = [ByteEnumField('rtr_version', 1, RTR_VERSION), - ByteEnumField('pdu_type', 7, PDU_TYPE), - ShortField('session_id', 0), - IntField('length', STATIC_END_OF_DATA_V1_LENGTH), - IntField('serial_number', 0), - IntField('refresh_interval', 0), - IntField('retry_interval', 0), - IntField('expire_interval', 0)] - - -class RTRCacheReset(Packet): - - ''' - - Cache Reset packet from section 5.9 - https://tools.ietf.org/html/rfc6810#section-5.9 - - ''' - name = 'Reset Query' - fields_desc = [ByteEnumField('rtr_version', 0, RTR_VERSION), - ByteEnumField('pdu_type', 8, PDU_TYPE), - ShortField('reserved', 0), - IntField('length', STATIC_CACHE_RESET_LENGTH)] - - -class RTRRouterKey(Packet): - - ''' - - Router Key packet from version 1 standard section 5.10 - https://tools.ietf.org/html/rfc8210#section-5.10 - - ''' - name = 'Router Key' - fields_desc = [ByteEnumField('rtr_version', 1, RTR_VERSION), - ByteEnumField('pdu_type', 9, PDU_TYPE), - ByteField('flags', 0), - ByteField('zeros', 0), - IntField('length', None), - StrFixedLenField('subject_key_identifier', '', 20), - IntField('asn', 0), - StrLenField('subject_PKI', '', - length_from=lambda x: x.length - 32)] - - def post_build(self, pkt, pay): - temp_len = len(pkt) + 2 - if not self.length: - pkt = pkt[:2] + struct.pack('!I', temp_len) + pkt[6:] - return pkt + pay - - -class RTRErrorReport(Packet): - - ''' - - Error Report packet from section 5.10 - https://tools.ietf.org/html/rfc6810#section-5.10 - - ''' - name = 'Error Report' - fields_desc = [ByteEnumField('rtr_version', 0, RTR_VERSION), - ByteEnumField('pdu_type', 10, PDU_TYPE), - ShortEnumField('error_code', 0, ERROR_LIST), - IntField('length', None), - FieldLenField('length_of_encaps_PDU', - None, fmt='!I', length_of='erroneous_PDU'), - StrLenField('erroneous_PDU', '', - length_from=lambda x: x.length_of_encaps_PDU), - FieldLenField('length_of_error_text', None, fmt='!I', - length_of='error_text'), - StrLenField('error_text', '', - length_from=lambda x: x.length_of_error_text)] - - def post_build(self, pkt, pay): - temp_len = len(pkt) + 2 - if not self.length: - pkt = pkt[:2] + struct.pack('!I', temp_len) + pkt[6:] - return pkt + pay - - -PDU_CLASS_VERSION_0 = {0: RTRSerialNotify, - 1: RTRSerialQuery, - 2: RTRResetQuery, - 3: RTRCacheResponse, - 4: RTRIPv4Prefix, - 6: RTRIPv6Prefix, - 7: RTREndofDatav0, - 8: RTRCacheReset, - 10: RTRErrorReport} - -PDU_CLASS_VERSION_1 = {0: RTRSerialNotify, - 1: RTRSerialQuery, - 2: RTRResetQuery, - 3: RTRCacheResponse, - 4: RTRIPv4Prefix, - 6: RTRIPv6Prefix, - 7: RTREndofDatav1, - 8: RTRCacheReset, - 9: RTRRouterKey, - 10: RTRErrorReport} - - -class RTR(Packet): - - ''' - Dummy RPKI to Router generic packet for pre-sorting the packet type - eg. https://tools.ietf.org/html/rfc6810#section-5.2 - - ''' - name = 'RTR dissector' - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - ''' - Attribution of correct type depending on version and pdu_type - ''' - if _pkt and len(_pkt) >= 2: - version = orb(_pkt[0]) - pdu_type = orb(_pkt[1]) - if version == 0: - return PDU_CLASS_VERSION_0[pdu_type] - elif version == 1: - return PDU_CLASS_VERSION_1[pdu_type] - return Raw - - -bind_layers(TCP, RTR, dport=323) # real reserved port -bind_layers(TCP, RTR, sport=323) # real reserved port -bind_layers(TCP, RTR, dport=8282) # RIPE implementation default port -bind_layers(TCP, RTR, sport=8282) # RIPE implementation default port -bind_layers(TCP, RTR, dport=2222) # gortr implementation default port -bind_layers(TCP, RTR, sport=2222) # gortr implementation default port - -if __name__ == '__main__': - from scapy.main import interact - interact(mydict=globals(), mybanner='RPKI to Router') diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/__init__.py deleted file mode 100644 index 815b2daefb..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -"""contains packages related to SCADA protocol layers.""" - -from scapy.contrib.scada.iec104 import * # noqa F403,F401 - -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Thomas Tannhaeuser -# This program is published under a GPLv2 license -# -# scapy.contrib.description = SCADA related layers -# scapy.contrib.status = loads - - -# Package of contrib SCADA modules. diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/__init__.py deleted file mode 100644 index 22272c6963..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -"""contains the IEC 60870-5-104 package.""" - -from scapy.contrib.scada.iec104.iec104_fields import * # noqa F403,F401 -from scapy.contrib.scada.iec104.iec104_information_elements import * # noqa F403,F401 -from scapy.contrib.scada.iec104.iec104_information_objects import * # noqa F403,F401 -from scapy.contrib.scada.iec104.iec104 import * # noqa F403,F401 - -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Thomas Tannhaeuser -# This program is published under a GPLv2 license -# -# scapy.contrib.description = IEC-60870-5-104 APCI / APDU layer definitions -# scapy.contrib.status = loads - - -# Package of contrib SCADA IEC-60870-5-104 specific modules diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/iec104.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/iec104.py deleted file mode 100644 index b1d17abc70..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/iec104.py +++ /dev/null @@ -1,645 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Thomas Tannhaeuser -# This program is published under a GPLv2 license -# -# scapy.contrib.description = IEC-60870-5-104 APCI / APDU layer definitions -# scapy.contrib.status = loads - -""" - IEC 60870-5-104 - ~~~~~~~~~~~~~~~ - - :description: - - This module provides the IEC 60870-5-104 (common short name: iec104) - layer, the information objects and related information element - definitions. - - normative references: - - IEC 60870-5-4:1994 (atomic base types / data format) - - IEC 60870-5-101:2003 (information elements (sec. 7.2.6) and - ASDU definition (sec. 7.3)) - - IEC 60870-5-104:2006 (information element TSC (sec. 8.8, p. 44)) - - :TODO: - - add allowed direction to IO attributes - (but this could be derived from the name easily <--> ) - - information elements / objects need more testing - (e.g. on live traffic w comparison against tshark) - - :NOTES: - - bit and octet numbering is used as in the related standards - (they usually start with index one instead of zero) - - some of the information objects are only valid for IEC 60870-5-101 - - so usually they should never appear on the network as iec101 uses - serial connections. I added them if decoding of those messages is - needed cause one goes to implement a iec101<-->iec104 gateway or - hits such a gateway that acts not standard conform (e.g. by - forwarding 101 messages to a 104 network) -""" - -from scapy.compat import orb - -from scapy.contrib.scada.iec104.iec104_fields import LEThreeBytesField, \ - IEC104SequenceNumber -from scapy.contrib.scada.iec104.iec104_information_objects import \ - IEC104_IO_NAMES, IEC104_IO_WITH_IOA_CLASSES, \ - IEC104_IO_CLASSES, IEC104_IO_ID_C_RD_NA_1, IEC104_IO_C_RD_NA_1 - -from scapy.config import conf -from scapy.contrib.scada.iec104.iec104_information_objects import \ - IEC104_IO_Packet -from scapy.error import warning, Scapy_Exception -from scapy.fields import ByteField, BitField, ByteEnumField, PacketListField, \ - BitEnumField, XByteField, FieldLenField, LEShortField, BitFieldLenField - -from scapy.layers.inet import TCP -from scapy.packet import Raw -from scapy.packet import Packet, bind_layers - -IEC_104_IANA_PORT = 2404 - -# direction - from the central station to the substation -IEC104_CONTROL_DIRECTION = 0 -IEC104_CENTRAL_2_SUB_DIR = IEC104_CONTROL_DIRECTION - -# direction - from the substation to the central station -IEC104_MONITOR_DIRECTION = 1 -IEC104_SUB_2_CENTRAL_DIR = IEC104_MONITOR_DIRECTION - -IEC104_DIRECTIONS = { - IEC104_MONITOR_DIRECTION: 'monitor direction (sub -> central)', - IEC104_CONTROL_DIRECTION: 'control direction (central -> sub)', -} - -# COT - cause of transmission -IEC104_COT_UNDEFINED = 0 -IEC104_COT_CYC = 1 -IEC104_COT_BACK = 2 -IEC104_COT_SPONT = 3 -IEC104_COT_INIT = 4 -IEC104_COT_REQ = 5 -IEC104_COT_ACT = 6 -IEC104_COT_ACTCON = 7 -IEC104_COT_DEACT = 8 -IEC104_COT_DEACTCON = 9 -IEC104_COT_ACTTERM = 10 -IEC104_COT_RETREM = 11 -IEC104_COT_RETLOC = 12 -IEC104_COT_FILE = 13 -IEC104_COT_RESERVED_14 = 14 -IEC104_COT_RESERVED_15 = 15 -IEC104_COT_RESERVED_16 = 16 -IEC104_COT_RESERVED_17 = 17 -IEC104_COT_RESERVED_18 = 18 -IEC104_COT_RESERVED_19 = 19 -IEC104_COT_INROGEN = 20 -IEC104_COT_INRO1 = 21 -IEC104_COT_INRO2 = 22 -IEC104_COT_INRO3 = 23 -IEC104_COT_INRO4 = 24 -IEC104_COT_INRO5 = 25 -IEC104_COT_INRO6 = 26 -IEC104_COT_INRO7 = 27 -IEC104_COT_INRO8 = 28 -IEC104_COT_INRO9 = 29 -IEC104_COT_INRO10 = 30 -IEC104_COT_INRO11 = 31 -IEC104_COT_INRO12 = 32 -IEC104_COT_INRO13 = 33 -IEC104_COT_INRO14 = 34 -IEC104_COT_INRO15 = 35 -IEC104_COT_INRO16 = 36 -IEC104_COT_REQCOGEN = 37 -IEC104_COT_REQCO1 = 38 -IEC104_COT_REQCO2 = 39 -IEC104_COT_REQCO3 = 40 -IEC104_COT_REQCO4 = 41 -IEC104_COT_RESERVED_42 = 42 -IEC104_COT_RESERVED_43 = 43 -IEC104_COT_UNKNOWN_TYPE_CODE = 44 -IEC104_COT_UNKNOWN_TRANSMIT_REASON = 45 -IEC104_COT_UNKNOWN_COMMON_ADDRESS_OF_ASDU = 46 -IEC104_COT_UNKNOWN_ADDRESS_OF_INFORMATION_OBJECT = 47 -IEC104_COT_PRIVATE_48 = 48 -IEC104_COT_PRIVATE_49 = 49 -IEC104_COT_PRIVATE_50 = 50 -IEC104_COT_PRIVATE_51 = 51 -IEC104_COT_PRIVATE_52 = 52 -IEC104_COT_PRIVATE_53 = 53 -IEC104_COT_PRIVATE_54 = 54 -IEC104_COT_PRIVATE_55 = 55 -IEC104_COT_PRIVATE_56 = 56 -IEC104_COT_PRIVATE_57 = 57 -IEC104_COT_PRIVATE_58 = 58 -IEC104_COT_PRIVATE_59 = 59 -IEC104_COT_PRIVATE_60 = 60 -IEC104_COT_PRIVATE_61 = 61 -IEC104_COT_PRIVATE_62 = 62 -IEC104_COT_PRIVATE_63 = 63 - -CAUSE_OF_TRANSMISSIONS = { - IEC104_COT_UNDEFINED: 'undefined', - IEC104_COT_CYC: 'cyclic (per/cyc)', - IEC104_COT_BACK: 'background (back)', - IEC104_COT_SPONT: 'spontaneous (spont)', - IEC104_COT_INIT: 'initialized (init)', - IEC104_COT_REQ: 'request (req)', - IEC104_COT_ACT: 'activation (act)', - IEC104_COT_ACTCON: 'activation confirmed (actcon)', - IEC104_COT_DEACT: 'activation canceled (deact)', - IEC104_COT_DEACTCON: 'activation cancellation confirmed (deactcon)', - IEC104_COT_ACTTERM: 'activation finished (actterm)', - IEC104_COT_RETREM: 'feedback caused by remote command (retrem)', - IEC104_COT_RETLOC: 'feedback caused by local command (retloc)', - IEC104_COT_FILE: 'file transfer (file)', - IEC104_COT_RESERVED_14: 'reserved_14', - IEC104_COT_RESERVED_15: 'reserved_15', - IEC104_COT_RESERVED_16: 'reserved_16', - IEC104_COT_RESERVED_17: 'reserved_17', - IEC104_COT_RESERVED_18: 'reserved_18', - IEC104_COT_RESERVED_19: 'reserved_19', - IEC104_COT_INROGEN: 'queried by station (inrogen)', - IEC104_COT_INRO1: 'queried by query to group 1 (inro1)', - IEC104_COT_INRO2: 'queried by query to group 2 (inro2)', - IEC104_COT_INRO3: 'queried by query to group 3 (inro3)', - IEC104_COT_INRO4: 'queried by query to group 4 (inro4)', - IEC104_COT_INRO5: 'queried by query to group 5 (inro5)', - IEC104_COT_INRO6: 'queried by query to group 6 (inro6)', - IEC104_COT_INRO7: 'queried by query to group 7 (inro7)', - IEC104_COT_INRO8: 'queried by query to group 8 (inro8)', - IEC104_COT_INRO9: 'queried by query to group 9 (inro9)', - IEC104_COT_INRO10: 'queried by query to group 10 (inro10)', - IEC104_COT_INRO11: 'queried by query to group 11 (inro11)', - IEC104_COT_INRO12: 'queried by query to group 12 (inro12)', - IEC104_COT_INRO13: 'queried by query to group 13 (inro13)', - IEC104_COT_INRO14: 'queried by query to group 14 (inro14)', - IEC104_COT_INRO15: 'queried by query to group 15 (inro15)', - IEC104_COT_INRO16: 'queried by query to group 16 (inro16)', - IEC104_COT_REQCOGEN: 'queried by counter general interrogation (reqcogen)', - IEC104_COT_REQCO1: 'queried by query to counter group 1 (reqco1)', - IEC104_COT_REQCO2: 'queried by query to counter group 2 (reqco2)', - IEC104_COT_REQCO3: 'queried by query to counter group 3 (reqco3)', - IEC104_COT_REQCO4: 'queried by query to counter group 4 (reqco4)', - IEC104_COT_RESERVED_42: 'reserved_42', - IEC104_COT_RESERVED_43: 'reserved_43', - IEC104_COT_UNKNOWN_TYPE_CODE: 'unknown type code', - IEC104_COT_UNKNOWN_TRANSMIT_REASON: 'unknown transmit reason', - IEC104_COT_UNKNOWN_COMMON_ADDRESS_OF_ASDU: - 'unknown common address of ASDU', - IEC104_COT_UNKNOWN_ADDRESS_OF_INFORMATION_OBJECT: - 'unknown address of information object', - IEC104_COT_PRIVATE_48: 'private_48', - IEC104_COT_PRIVATE_49: 'private_49', - IEC104_COT_PRIVATE_50: 'private_50', - IEC104_COT_PRIVATE_51: 'private_51', - IEC104_COT_PRIVATE_52: 'private_52', - IEC104_COT_PRIVATE_53: 'private_53', - IEC104_COT_PRIVATE_54: 'private_54', - IEC104_COT_PRIVATE_55: 'private_55', - IEC104_COT_PRIVATE_56: 'private_56', - IEC104_COT_PRIVATE_57: 'private_57', - IEC104_COT_PRIVATE_58: 'private_58', - IEC104_COT_PRIVATE_59: 'private_59', - IEC104_COT_PRIVATE_60: 'private_60', - IEC104_COT_PRIVATE_61: 'private_61', - IEC104_COT_PRIVATE_62: 'private_62', - IEC104_COT_PRIVATE_63: 'private_63' -} - -IEC104_APDU_TYPE_UNKNOWN = 0x00 -IEC104_APDU_TYPE_I_SEQ_IOA = 0x01 -IEC104_APDU_TYPE_I_SINGLE_IOA = 0x02 -IEC104_APDU_TYPE_U = 0x03 -IEC104_APDU_TYPE_S = 0x04 - - -def _iec104_apci_type_from_packet(data): - """ - the type of the message is encoded in octet 1..4 - - oct 1, bit 1 2 oct 3, bit 1 - I Message 0 1|0 0 - S Message 1 0 0 - U Message 1 1 0 - - - see EN 60870-5-104:2006, sec. 5 (p. 13, fig. 6,7,8) - """ - - oct_1 = orb(data[2]) - oct_3 = orb(data[4]) - - oct_1_bit_1 = bool(oct_1 & 1) - oct_1_bit_2 = bool(oct_1 & 2) - oct_3_bit_1 = bool(oct_3 & 1) - - if oct_1_bit_1 is False and oct_3_bit_1 is False: - if len(data) < 8: - return IEC104_APDU_TYPE_UNKNOWN - - is_seq_ioa = ((orb(data[7]) & 0x80) == 0x80) - - if is_seq_ioa: - return IEC104_APDU_TYPE_I_SEQ_IOA - else: - return IEC104_APDU_TYPE_I_SINGLE_IOA - - if oct_1_bit_1 and oct_1_bit_2 is False and oct_3_bit_1 is False: - return IEC104_APDU_TYPE_S - - if oct_1_bit_1 and oct_1_bit_2 and oct_3_bit_1 is False: - return IEC104_APDU_TYPE_U - - return IEC104_APDU_TYPE_UNKNOWN - - -class IEC104_APDU(Packet): - """ - basic Application Protocol Data Unit definition used by S/U/I messages - """ - - def guess_payload_class(self, payload): - - payload_len = len(payload) - - if payload_len < 6: - return self.default_payload_class(payload) - - if orb(payload[0]) != 0x68: - self.default_payload_class(payload) - - # the length field contains the number of bytes starting from the - # first control octet - apdu_length = 2 + orb(payload[1]) - - if payload_len < apdu_length: - warning( - 'invalid len of APDU. given len: {} available len: {}'.format( - apdu_length, payload_len)) - return self.default_payload_class(payload) - - apdu_type = _iec104_apci_type_from_packet(payload) - - return IEC104_APDU_CLASSES.get(apdu_type, - self.default_payload_class(payload)) - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - """ - detect type of the message by checking packet data - :param _pkt: raw bytes of the packet layer data to be checked - :param args: unused - :param kargs: unused - :return: class of the detected message type - """ - - if _iec104_is_i_apdu_seq_ioa(_pkt): - return IEC104_I_Message_SeqIOA - - if _iec104_is_i_apdu_single_ioa(_pkt): - return IEC104_I_Message_SingleIOA - - if _iec104_is_u_apdu(_pkt): - return IEC104_U_Message - - if _iec104_is_s_apdu(_pkt): - return IEC104_S_Message - - return Raw - - -class IEC104_S_Message(IEC104_APDU): - """ - message used for ack of received I-messages - """ - name = 'IEC-104 S APDU' - - fields_desc = [ - - XByteField('start', 0x68), - ByteField("apdu_length", 4), - - ByteField('octet_1', 0x01), - ByteField('octet_2', 0), - IEC104SequenceNumber('rx_seq_num', 0), - ] - - -class IEC104_U_Message(IEC104_APDU): - """ - message used for connection tx control (start/stop) and monitoring (test) - """ - name = 'IEC-104 U APDU' - - fields_desc = [ - - XByteField('start', 0x68), - ByteField("apdu_length", 4), - - BitField('testfr_con', 0, 1), - BitField('testfr_act', 0, 1), - BitField('stopdt_con', 0, 1), - BitField('stopdt_act', 0, 1), - BitField('startdt_con', 0, 1), - BitField('startdt_act', 0, 1), - BitField('octet_1_1_2', 3, 2), - - ByteField('octet_2', 0), - ByteField('octet_3', 0), - ByteField('octet_4', 0) - ] - - -def _i_msg_io_dispatcher_sequence(pkt, next_layer_data): - """ - get the type id and return the matching ASDU instance - """ - next_layer_class_type = IEC104_IO_CLASSES.get(pkt.type_id, conf.raw_layer) - - return next_layer_class_type(next_layer_data) - - -def _i_msg_io_dispatcher_single(pkt, next_layer_data): - """ - get the type id and return the matching ASDU instance - (information object address + regular ASDU information object fields) - """ - next_layer_class_type = IEC104_IO_WITH_IOA_CLASSES.get(pkt.type_id, - conf.raw_layer) - - return next_layer_class_type(next_layer_data) - - -class IEC104ASDUPacketListField(PacketListField): - """ - used to add a list of information objects to an I-message - """ - def m2i(self, pkt, m): - """ - add calling layer instance to the cls()-signature - :param pkt: calling layer instance - :param m: raw data forming the next layer - :return: instance of the class representing the next layer - """ - return self.cls(pkt, m) - - -class IEC104_I_Message_StructureException(Scapy_Exception): - """ - Exception raised if payload is not of type Information Object - """ - pass - - -class IEC104_I_Message(IEC104_APDU): - """ - message used for transmitting data (APDU - Application Protocol Data Unit) - - APDU: MAGIC + APCI + ASDU - MAGIC: 0x68 - APCI : Control Information (rx/tx seq/ack numbers) - ASDU : Application Service Data Unit - information object related data - - see EN 60870-5-104:2006, sec. 5 (p. 12) - """ - name = 'IEC-104 I APDU' - - IEC_104_MAGIC = 0x68 # dec -> 104 - - SQ_FLAG_SINGLE = 0 - SQ_FLAG_SEQUENCE = 1 - - SQ_FLAGS = { - SQ_FLAG_SINGLE: 'single', - SQ_FLAG_SEQUENCE: 'sequence' - } - - TEST_DISABLED = 0 - TEST_ENABLED = 1 - - TEST_FLAGS = { - TEST_DISABLED: 'disabled', - TEST_ENABLED: 'enabled' - } - - ACK_POSITIVE = 0 - ACK_NEGATIVE = 1 - - ACK_FLAGS = { - ACK_POSITIVE: 'positive', - ACK_NEGATIVE: 'negative' - } - - fields_desc = [] - - def __init__(self, _pkt=b"", post_transform=None, _internal=0, - _underlayer=None, **fields): - - super(IEC104_I_Message, self).__init__(_pkt=_pkt, - post_transform=post_transform, - _internal=_internal, - _underlayer=_underlayer, - **fields) - - if 'io' in fields and fields['io']: - self._information_object_update(fields['io']) - - def _information_object_update(self, io_instances): - """ - set the type_id in the ASDU header based on the given information - object (io) and check for valid structure - :param io_instances: information object - """ - - if not isinstance(io_instances, list): - io_instances = [io_instances] - - first_io = io_instances[0] - first_io_class = first_io.__class__ - - if not issubclass(first_io_class, IEC104_IO_Packet): - raise IEC104_I_Message_StructureException( - 'information object payload must be a subclass of ' - 'IEC104_IO_Packet') - - self.type_id = first_io.iec104_io_type_id() - - # ensure all io elements within the ASDU share the same class type - for io_inst in io_instances[1:]: - if io_inst.__class__ != first_io_class: - raise IEC104_I_Message_StructureException( - 'each information object within the ASDU must be of ' - 'the same class type (first io: {}, ' - 'current io: {})'.format(first_io_class._name, - io_inst._name)) - - -class IEC104_I_Message_SeqIOA(IEC104_I_Message): - """ - all information objects share a base information object address field - - sq = 1, see EN 60870-5-101:2003, sec. 7.2.2.1 (p. 33) - """ - name = 'IEC-104 I APDU (Seq IOA)' - - fields_desc = [ - # APCI - XByteField('start', IEC104_I_Message.IEC_104_MAGIC), - FieldLenField("apdu_length", None, fmt="!B", length_of='io', - adjust=lambda pkt, x: x + 13), - - IEC104SequenceNumber('tx_seq_num', 0), - IEC104SequenceNumber('rx_seq_num', 0), - - # ASDU - ByteEnumField('type_id', 0, IEC104_IO_NAMES), - - BitEnumField('sq', IEC104_I_Message.SQ_FLAG_SEQUENCE, 1, - IEC104_I_Message.SQ_FLAGS), - BitFieldLenField('num_io', None, 7, count_of='io'), - - BitEnumField('test', 0, 1, IEC104_I_Message.TEST_FLAGS), - BitEnumField('ack', 0, 1, IEC104_I_Message.ACK_FLAGS), - BitEnumField('cot', 0, 6, CAUSE_OF_TRANSMISSIONS), - - ByteField('origin_address', 0), - - LEShortField('common_asdu_address', 0), - - LEThreeBytesField('information_object_address', 0), - - IEC104ASDUPacketListField('io', - conf.raw_layer(), - _i_msg_io_dispatcher_sequence, - length_from=lambda pkt: pkt.apdu_length - 13) - ] - - def post_dissect(self, s): - if self.type_id == IEC104_IO_ID_C_RD_NA_1: - - # IEC104_IO_ID_C_RD_NA_1 has no payload. we will add the layer - # manually to the stack right now. we do this num_io times - # as - even if it makes no sense - someone could decide - # to add more than one read commands in a sequence... - setattr(self, 'io', [IEC104_IO_C_RD_NA_1()] * self.num_io) - - return s - - -class IEC104_I_Message_SingleIOA(IEC104_I_Message): - """ - every information object contains an individual information object - address field - - sq = 0, see EN 60870-5-101:2003, sec. 7.2.2.1 (p. 33) - """ - name = 'IEC-104 I APDU (single IOA)' - - fields_desc = [ - # APCI - XByteField('start', IEC104_I_Message.IEC_104_MAGIC), - FieldLenField("apdu_length", None, fmt="!B", length_of='io', - adjust=lambda pkt, x: x + 10), - - IEC104SequenceNumber('tx_seq_num', 0), - IEC104SequenceNumber('rx_seq_num', 0), - - # ASDU - ByteEnumField('type_id', 0, IEC104_IO_NAMES), - - BitEnumField('sq', IEC104_I_Message.SQ_FLAG_SINGLE, 1, - IEC104_I_Message.SQ_FLAGS), - BitFieldLenField('num_io', None, 7, count_of='io'), - - BitEnumField('test', 0, 1, IEC104_I_Message.TEST_FLAGS), - BitEnumField('ack', 0, 1, IEC104_I_Message.ACK_FLAGS), - BitEnumField('cot', 0, 6, CAUSE_OF_TRANSMISSIONS), - - ByteField('origin_address', 0), - - LEShortField('common_asdu_address', 0), - - IEC104ASDUPacketListField('io', - conf.raw_layer(), - _i_msg_io_dispatcher_single, - length_from=lambda pkt: pkt.apdu_length - 10) - ] - - -IEC104_APDU_CLASSES = { - IEC104_APDU_TYPE_UNKNOWN: conf.raw_layer, - IEC104_APDU_TYPE_I_SEQ_IOA: IEC104_I_Message_SeqIOA, - IEC104_APDU_TYPE_I_SINGLE_IOA: IEC104_I_Message_SingleIOA, - IEC104_APDU_TYPE_U: IEC104_U_Message, - IEC104_APDU_TYPE_S: IEC104_S_Message -} - - -def _iec104_is_i_apdu_seq_ioa(payload): - len_payload = len(payload) - if len_payload < 6: - return False - - if orb(payload[0]) != 0x68 or ( - orb(payload[1]) + 2) > len_payload or len_payload < 8: - return False - - return IEC104_APDU_TYPE_I_SEQ_IOA == _iec104_apci_type_from_packet(payload) - - -def _iec104_is_i_apdu_single_ioa(payload): - len_payload = len(payload) - if len_payload < 6: - return False - - if orb(payload[0]) != 0x68 or ( - orb(payload[1]) + 2) > len_payload or len_payload < 8: - return False - - return IEC104_APDU_TYPE_I_SINGLE_IOA == _iec104_apci_type_from_packet( - payload) - - -def _iec104_is_u_apdu(payload): - if len(payload) < 6: - return False - - if orb(payload[0]) != 0x68 or orb(payload[1]) != 4: - return False - - return IEC104_APDU_TYPE_U == _iec104_apci_type_from_packet(payload) - - -def _iec104_is_s_apdu(payload): - if len(payload) < 6: - return False - - if orb(payload[0]) != 0x68 or orb(payload[1]) != 4: - return False - - return IEC104_APDU_TYPE_S == _iec104_apci_type_from_packet(payload) - - -def iec104_decode(payload): - """ - can be used to dissect payload of a TCP connection - :param payload: the application layer data (IEC104-APDU(s)) - :return: iec104 (I/U/S) message instance, conf.raw_layer() if unknown - """ - - if _iec104_is_i_apdu_seq_ioa(payload): - return IEC104_I_Message_SeqIOA(payload) - elif _iec104_is_i_apdu_single_ioa(payload): - return IEC104_I_Message_SingleIOA(payload) - elif _iec104_is_s_apdu(payload): - return IEC104_S_Message(payload) - elif _iec104_is_u_apdu(payload): - return IEC104_U_Message(payload) - else: - return conf.raw_layer(payload) - - -bind_layers(TCP, IEC104_APDU, sport=IEC_104_IANA_PORT) -bind_layers(TCP, IEC104_APDU, dport=IEC_104_IANA_PORT) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/iec104_fields.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/iec104_fields.py deleted file mode 100644 index bf0247c102..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/iec104_fields.py +++ /dev/null @@ -1,144 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Thomas Tannhaeuser -# This program is published under a GPLv2 license - -# scapy.contrib.description = IEC-60870-5-104 layer specific fields -# scapy.contrib.status = loads - -""" - field type definitions used by iec 60870-5-104 layer (iec104) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - :description: - - This file provides field definitions used by the IEC-60870-5-104 - implementation. Some of those fields are used exclusively by iec104 - (e.g. IEC104SequenceNumber) while others (LESignedShortField) are - more common an may be moved to fields.py. - - normative references: - - EN 60870-5-104:2006 - - EN 60870-5-4:1993 - - EN 60870-5-4:1994 -""" -import struct - -from scapy.compat import orb -from scapy.fields import Field, ThreeBytesField, BitField -from scapy.volatile import RandSShort - - -class LESignedShortField(Field): - """ - little endian signed short field - """ - def __init__(self, name, default): - Field.__init__(self, name, default, "7 6 5 4 3 2 1 0 - +---+---+---+---+---+---+---+---+ - | | | | | | |LSB| 0 | byte 0 - +---+---+---+---+---+---+---+---+ - |MSB| | | | | | | | byte 1 - +---+---+---+---+---+---+---+---+ - - """ - - def __init__(self, name, default): - Field.__init__(self, name, default, "!I") - - def addfield(self, pkt, s, val): - b0 = (val << 1) & 0xfe - b1 = val >> 7 - - return s + bytes(bytearray([b0, b1])) - - def getfield(self, pkt, s): - b0 = (orb(s[0]) & 0xfe) >> 1 - b1 = orb(s[1]) - - seq_num = b0 + (b1 << 7) - - return s[2:], seq_num - - -class IEC104SignedSevenBitValue(BitField): - """ - Typ 2.1, 7 Bit, [-64..63] - - see EN 60870-5-4:1994, Typ 2.1 (p. 13) - """ - - def __init__(self, name, default): - BitField.__init__(self, name, default, 7) - - def m2i(self, pkt, x): - - if x & 64: - x = x - 128 - - return x - - def i2m(self, pkt, x): - - sign = 0 - if x < 0: - sign = 64 - x = x + 64 - - x = x | sign - - return x diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/iec104_information_elements.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/iec104_information_elements.py deleted file mode 100644 index e05977931c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/iec104_information_elements.py +++ /dev/null @@ -1,1438 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Thomas Tannhaeuser -# This program is published under a GPLv2 license - -# scapy.contrib.description = IEC-60870-5-104 information elements -# scapy.contrib.status = loads - -""" - information element definitions used by IEC 60870-5-101/104 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - :description: - - This module provides the information element (IE) definitions used to - compose the ASDUs (Application Service Data Units) used within the - IEC 60870-5-101 and IEC 60870-5-104 protocol. - - normative references: - - IEC 60870-5-4:1993 (atomic base types / data format) - - IEC 60870-5-101:2003 (information elements (sec. 7.2.6) and - ASDU definition (sec. 7.3)) - - IEC 60870-5-104:2006 (information element TSC (sec. 8.8, p. 44)) - - :TODO: - - some definitions should use signed types as outlined in the standard - - normed value element should use a float type - -""" -from scapy.contrib.scada.iec104.iec104_fields import \ - IEC60870_5_4_NormalizedFixPoint, IEC104SignedSevenBitValue, \ - LESignedShortField, LEIEEEFloatField -from scapy.fields import BitEnumField, ByteEnumField, ByteField, \ - ThreeBytesField, \ - BitField, LEShortField, LESignedIntField - - -def _generate_attributes_and_dicts(cls): - """ - create class attributes and dict entries for range-based attributes - - class attributes will take the form: cls._ - - dictionary entries will be generated as: - - the_dict[index] = " ()" - - expects a GENERATED_ATTRIBUTES attribute within the class that contains a - list of the specification for the attributes and dictionary entries to be - generated. each list entry must have this format: - - (attribute_name_prefix, dict_entry_prefix, dictionary, first_index, - last_index) - - with - - the prefix of the attribute name - first_index - index of the first attribute to be generated - last_index - index of the last attribute to be generated - :param cls: the class the attributes should be added to - :return: cls extended by generated attributes - """ - - for attribute_name_prefix, dict_entry_prefix, the_dict, first_index, \ - last_index \ - in cls.GENERATED_ATTRIBUTES: - - for index in range(first_index, last_index + 1): - the_dict[index] = '{} ({})'.format(dict_entry_prefix, index) - - setattr(cls, '{}_{}'.format(attribute_name_prefix, index), index) - - return cls - - -class IEC104_IE_CommonQualityFlags: - """ - common / shared information element quality flags - """ - IV_FLAG_VALID = 0 - IV_FLAG_INVALID = 1 - IV_FLAGS = { - IV_FLAG_VALID: 'valid', - IV_FLAG_INVALID: 'invalid' - } - - NT_FLAG_CURRENT_VALUE = 0 - NT_FLAG_OLD_VALUE = 1 - NT_FLAGS = { - NT_FLAG_CURRENT_VALUE: 'current value', - NT_FLAG_OLD_VALUE: 'old value' - } - - SB_FLAG_NOT_SUBSTITUTED = 0 - SB_FLAG_SUBSTITUTED = 1 - SB_FLAGS = { - SB_FLAG_NOT_SUBSTITUTED: 'not substituted', - SB_FLAG_SUBSTITUTED: 'substituted' - } - - BL_FLAG_NOT_BLOCKED = 0 - BL_FLAG_BLOCKED = 1 - BL_FLAGS = { - BL_FLAG_NOT_BLOCKED: 'not blocked', - BL_FLAG_BLOCKED: 'blocked' - } - - EI_FLAG_ELAPSED_TIME_VALID = 0 - EI_FLAG_ELAPSED_TIME_INVALID = 1 - EI_FLAGS = { - EI_FLAG_ELAPSED_TIME_VALID: 'elapsed time valid', - EI_FLAG_ELAPSED_TIME_INVALID: 'elapsed time invalid' - } - - -class IEC104_IE_SIQ(IEC104_IE_CommonQualityFlags): - """ - SIQ - single point information with quality descriptor - - EN 60870-5-101:2003, sec. 7.2.6.1 (p. 44) - """ - - SPI_FLAG_STATE_OFF = 0 - SPI_FLAG_STATE_ON = 1 - - SPI_FLAGS = { - SPI_FLAG_STATE_OFF: 'off', - SPI_FLAG_STATE_ON: 'on' - } - - informantion_element_fields = [ - BitEnumField('iv', 0, 1, IEC104_IE_CommonQualityFlags.IV_FLAGS), - # invalid - BitEnumField('nt', 0, 1, IEC104_IE_CommonQualityFlags.NT_FLAGS), - # live or cached old value - BitEnumField('sb', 0, 1, IEC104_IE_CommonQualityFlags.SB_FLAGS), - # value substituted - BitEnumField('bl', 0, 1, IEC104_IE_CommonQualityFlags.BL_FLAGS), - # blocked - BitField('reserved', 0, 3), - BitEnumField('spi_value', 0, 1, SPI_FLAGS) - ] - - -class IEC104_IE_DIQ(IEC104_IE_CommonQualityFlags): - """ - DIQ - double-point information with quality descriptor - - EN 60870-5-101:2003, sec. 7.2.6.2 (p. 44) - """ - - DPI_FLAG_STATE_UNDEFINED_OR_TRANSIENT = 0 - DPI_FLAG_STATE_OFF = 1 - DPI_FLAG_STATE_ON = 2 - DPI_FLAG_STATE_UNDEFINED = 3 - - DPI_FLAGS = { - DPI_FLAG_STATE_UNDEFINED_OR_TRANSIENT: 'undefined/transient', - DPI_FLAG_STATE_OFF: 'off', - DPI_FLAG_STATE_ON: 'on', - DPI_FLAG_STATE_UNDEFINED: 'undefined' - } - - informantion_element_fields = [ - BitEnumField('iv', 0, 1, IEC104_IE_CommonQualityFlags.IV_FLAGS), - # invalid - BitEnumField('nt', 0, 1, IEC104_IE_CommonQualityFlags.NT_FLAGS), - # live or cached old value - BitEnumField('sb', 0, 1, IEC104_IE_CommonQualityFlags.SB_FLAGS), - # value substituted - BitEnumField('bl', 0, 1, IEC104_IE_CommonQualityFlags.BL_FLAGS), - # blocked - BitField('reserved', 0, 2), - BitEnumField('dpi_value', 0, 2, DPI_FLAGS) - ] - - -class IEC104_IE_QDS(IEC104_IE_CommonQualityFlags): - """ - QDS - quality descriptor separate object - - EN 60870-5-101:2003, sec. 7.2.6.3 (p. 45) - """ - - OV_FLAG_NO_OVERFLOW = 0 - OV_FLAG_OVERFLOW = 1 - OV_FLAGS = { - OV_FLAG_NO_OVERFLOW: 'no overflow', - OV_FLAG_OVERFLOW: 'overflow' - } - - informantion_element_fields = [ - BitEnumField('iv', 0, 1, IEC104_IE_CommonQualityFlags.IV_FLAGS), - # invalid - BitEnumField('nt', 0, 1, IEC104_IE_CommonQualityFlags.NT_FLAGS), - # live or cached old value - BitEnumField('sb', 0, 1, IEC104_IE_CommonQualityFlags.SB_FLAGS), - # value substituted - BitEnumField('bl', 0, 1, IEC104_IE_CommonQualityFlags.BL_FLAGS), - # blocked - BitField('reserved', 0, 3), - BitEnumField('ov', 0, 1, OV_FLAGS), # overflow - ] - - -class IEC104_IE_QDP(IEC104_IE_CommonQualityFlags): - """ - QDP - quality descriptor protection equipment separate object - - EN 60870-5-101:2003, sec. 7.2.6.4 (p. 46) - """ - - informantion_element_fields = [ - BitEnumField('iv', 0, 1, IEC104_IE_CommonQualityFlags.IV_FLAGS), - # invalid - BitEnumField('nt', 0, 1, IEC104_IE_CommonQualityFlags.NT_FLAGS), - # live or cached old value - BitEnumField('sb', 0, 1, IEC104_IE_CommonQualityFlags.SB_FLAGS), - # value substituted - BitEnumField('bl', 0, 1, IEC104_IE_CommonQualityFlags.BL_FLAGS), - # blocked - BitEnumField('ei', 0, 1, IEC104_IE_CommonQualityFlags.EI_FLAGS), - # blocked - BitField('reserved', 0, 3) - ] - - -class IEC104_IE_VTI: - """ - VTI - value with transient state indication - - EN 60870-5-101:2003, sec. 7.2.6.5 (p. 47) - """ - - TRANSIENT_STATE_DISABLED = 0 - TRANSIENT_STATE_ENABLED = 1 - - TRANSIENT_STATE_FLAGS = { - TRANSIENT_STATE_DISABLED: 'device not in transient state', - TRANSIENT_STATE_ENABLED: 'device in transient state' - } - - informantion_element_fields = [ - BitEnumField('transient_state', 0, 1, TRANSIENT_STATE_FLAGS), - IEC104SignedSevenBitValue('value', 0) - ] - - -class IEC104_IE_NVA: - """ - NVA - normed value - - EN 60870-5-101:2003, sec. 7.2.6.6 (p. 47) - """ - - informantion_element_fields = [ - IEC60870_5_4_NormalizedFixPoint('normed_value', 0) - ] - - -class IEC104_IE_SVA: - """ - SVA - scaled value - - EN 60870-5-101:2003, sec. 7.2.6.7 (p. 47) - """ - - informantion_element_fields = [ - LESignedShortField('scaled_value', 0) - ] - - -class IEC104_IE_R32_IEEE_STD_754: - """ - R32-IEEE STD 754 - short floating point value - - EN 60870-5-101:2003, sec. 7.2.6.8 (p. 47) - """ - - informantion_element_fields = [ - LEIEEEFloatField('scaled_value', 0) - ] - - -class IEC104_IE_BCR: - """ - BCR - binary counter reading - - EN 60870-5-101:2003, sec. 7.2.6.9 (p. 47) - """ - CA_FLAG_COUNTER_NOT_ADJUSTED = 0 - CA_FLAG_COUNTER_ADJUSTED = 1 - CA_FLAGS = { - CA_FLAG_COUNTER_NOT_ADJUSTED: 'counter not adjusted', - CA_FLAG_COUNTER_ADJUSTED: 'counter adjusted' - } - - CY_FLAG_NO_OVERFLOW = 0 - CY_FLAG_OVERFLOW = 1 - CY_FLAGS = { - CY_FLAG_NO_OVERFLOW: 'no overflow', - CY_FLAG_OVERFLOW: 'overflow' - } - - informantion_element_fields = [ - LESignedIntField('counter_value', 0), - BitEnumField('iv', 0, 1, IEC104_IE_CommonQualityFlags.IV_FLAGS), - # invalid - BitEnumField('ca', 0, 1, CA_FLAGS), # counter adjusted - BitEnumField('cy', 0, 1, CY_FLAGS), # carry flag / overflow - BitField('sq', 0, 5) # sequence - ] - - -class IEC104_IE_SEP(IEC104_IE_CommonQualityFlags): - """ - SEP - single event of protection equipment - - EN 60870-5-101:2003, sec. 7.2.6.10 (p. 48) - """ - - ES_FLAG_STATE_UNDEFINED_0 = 0 - ES_FLAG_STATE_OFF = 1 - ES_FLAG_STATE_ON = 2 - ES_FLAG_STATE_UNDEFINED_3 = 3 - ES_FLAGS = { - ES_FLAG_STATE_UNDEFINED_0: 'undefined (0)', - ES_FLAG_STATE_OFF: 'off', - ES_FLAG_STATE_ON: 'on', - ES_FLAG_STATE_UNDEFINED_3: 'undefined (3)', - } - - informantion_element_fields = [ - BitEnumField('iv', 0, 1, IEC104_IE_CommonQualityFlags.IV_FLAGS), - # invalid - BitEnumField('nt', 0, 1, IEC104_IE_CommonQualityFlags.NT_FLAGS), - # live or cached old value - BitEnumField('sb', 0, 1, IEC104_IE_CommonQualityFlags.SB_FLAGS), - # value substituted - BitEnumField('bl', 0, 1, IEC104_IE_CommonQualityFlags.BL_FLAGS), - # blocked - BitEnumField('ei', 0, 1, IEC104_IE_CommonQualityFlags.EI_FLAGS), - # time valid - BitField('reserved', 0, 1), - BitEnumField('es', 0, 2, ES_FLAGS), # event state - ] - - -class IEC104_IE_SPE: - """ - SPE - start events of protection equipment - - EN 60870-5-101:2003, sec. 7.2.6.11 (p. 48) - """ - GS_FLAG_NO_GENERAL_TRIGGER = 0 - GS_FLAG_GENERAL_TRIGGER = 1 - GS_FLAGS = { - GS_FLAG_NO_GENERAL_TRIGGER: 'general trigger', - GS_FLAG_GENERAL_TRIGGER: 'no general trigger' - } - - # protection relays - start of operation - fault detection per phase - SL_FLAG_START_OPR_PHASE_L1_NO_TRIGGER = 0 - SL_FLAG_START_OPR_PHASE_L1_TRIGGER = 1 - SL_FLAG_START_OPR_PHASE_L2_NO_TRIGGER = 0 - SL_FLAG_START_OPR_PHASE_L2_TRIGGER = 1 - SL_FLAG_START_OPR_PHASE_L3_NO_TRIGGER = 0 - SL_FLAG_START_OPR_PHASE_L3_TRIGGER = 1 - SL_FLAGS = { - SL_FLAG_START_OPR_PHASE_L1_NO_TRIGGER: 'no start of operation', - SL_FLAG_START_OPR_PHASE_L1_TRIGGER: 'start of operation' - } - - # protection event start caused by earth current - SIE_FLAG_START_OPR_PHASE_IE_NO_TRIGGER = 0 - SIE_FLAG_START_OPR_PHASE_IE_TRIGGER = 1 - SIE_FLAGS = { - SIE_FLAG_START_OPR_PHASE_IE_NO_TRIGGER: 'no start of operation', - SIE_FLAG_START_OPR_PHASE_IE_TRIGGER: 'start of operation' - } - - # direction of the started protection event - SRD_FLAG_DIRECTION_FORWARD = 0 - SRD_FLAG_DIRECTION_BACKWARD = 1 - SRD_FLAGS = { - SRD_FLAG_DIRECTION_FORWARD: 'forward', - SRD_FLAG_DIRECTION_BACKWARD: 'backward' - } - - informantion_element_fields = [ - BitField('reserved', 0, 2), - BitEnumField('srd', 0, 1, SRD_FLAGS), - BitEnumField('sie', 0, 1, SIE_FLAGS), - BitEnumField('sl3', 0, 1, SL_FLAGS), - BitEnumField('sl2', 0, 1, SL_FLAGS), - BitEnumField('sl1', 0, 1, SL_FLAGS), - BitEnumField('gs', 0, 1, GS_FLAGS) - ] - - -class IEC104_IE_OCI: - """ - OCI - output circuit information of protection equipment - - EN 60870-5-101:2003, sec. 7.2.6.12 (p. 49) - """ - # all 3 phases off command - GC_FLAG_NO_GENERAL_COMMAND_OFF = 0 - GC_FLAG_GENERAL_COMMAND_OFF = 1 - GC_FLAGS = { - GC_FLAG_NO_GENERAL_COMMAND_OFF: 'no general off', - GC_FLAG_GENERAL_COMMAND_OFF: 'general off' - } - # phase based off command - # protection relays - start of operation - fault detection per phase - CL_FLAG_NO_COMMAND_L1_OFF = 0 - CL_FLAG_COMMAND_L1_OFF = 1 - CL_FLAG_NO_COMMAND_L2_OFF = 0 - CL_FLAG_COMMAND_L2_OFF = 1 - CL_FLAG_NO_COMMAND_L3_OFF = 0 - CL_FLAG_COMMAND_L3_OFF = 1 - CL_FLAGS = { - CL_FLAG_NO_COMMAND_L1_OFF: 'no command off', - CL_FLAG_COMMAND_L1_OFF: 'no command off' - } - - informantion_element_fields = [ - BitField('reserved', 0, 4), - BitEnumField('cl3', 0, 1, CL_FLAGS), # command Lx - BitEnumField('cl2', 0, 1, CL_FLAGS), - BitEnumField('cl1', 0, 1, CL_FLAGS), - BitEnumField('gc', 0, 1, GC_FLAGS), # general off - ] - - -class IEC104_IE_BSI: - """ - BSI - binary state information - - EN 60870-5-101:2003, sec. 7.2.6.13 (p. 49) - """ - informantion_element_fields = [ - BitField('bsi', 0, 32) - ] - - -class IEC104_IE_FBP: - """ - FBP - fixed test bit pattern - - EN 60870-5-101:2003, sec. 7.2.6.14 (p. 49) - """ - informantion_element_fields = [ - LEShortField('fbp', 0) - ] - - -@_generate_attributes_and_dicts -class IEC104_IE_QOC: - """ - QOC - qualifier of command - - EN 60870-5-101:2003, sec. 7.2.6.26 (p. 54) - """ - - QU_FLAG_NO_ADDITIONAL_PARAMETERS = 0 - QU_FLAG_SHORT_COMMAND_EXEC_TIME = 1 # e.g. controlling a power switch - QU_FLAG_LONG_COMMAND_EXEC_TIME = 2 - QU_FLAG_PERMANENT_COMMAND = 3 - - QU_FLAGS = { - QU_FLAG_NO_ADDITIONAL_PARAMETERS: 'no additional parameter', - QU_FLAG_SHORT_COMMAND_EXEC_TIME: 'short execution time', - QU_FLAG_LONG_COMMAND_EXEC_TIME: 'long execution time', - QU_FLAG_PERMANENT_COMMAND: 'permanent command', - } - - GENERATED_ATTRIBUTES = [ - ('QU_FLAG_RESERVED_COMPATIBLE', 'reserved - compatible', QU_FLAGS, 4, - 8), - ('QU_FLAG_RESERVED_PREDEFINED_FUNCTION', - 'reserved - predefined function', QU_FLAGS, 9, 15), - ('QU_FLAG_RESERVED_PRIVATE', 'reserved - private', QU_FLAGS, 16, 31) - ] - - SE_FLAG_EXECUTE = 0 - SE_FLAG_SELECT = 1 - SE_FLAGS = { - SE_FLAG_EXECUTE: 'execute', - SE_FLAG_SELECT: 'select' - } - - informantion_element_fields = [ - BitEnumField('s/e', 0, 1, SE_FLAGS), - BitEnumField('qu', 0, 5, QU_FLAGS) - ] - - -class IEC104_IE_SCO(IEC104_IE_QOC): - """ - SCO - single command - - EN 60870-5-101:2003, sec. 7.2.6.15 (p. 50) - """ - SCS_FLAG_STATE_OFF = 0 - SCS_FLAG_STATE_ON = 1 - SCS_FLAGS = { - SCS_FLAG_STATE_OFF: 'off', - SCS_FLAG_STATE_ON: 'on' - } - - informantion_element_fields = IEC104_IE_QOC.informantion_element_fields + [ - BitField('reserved', 0, 1), - BitEnumField('scs', 0, 1, SCS_FLAGS) - ] - - -class IEC104_IE_DCO(IEC104_IE_QOC): - """ - DCO - double command - - EN 60870-5-101:2003, sec. 7.2.6.16 (p. 50) - """ - DCS_FLAG_STATE_INVALID_0 = 0 - DCS_FLAG_STATE_OFF = 1 - DCS_FLAG_STATE_ON = 2 - DCS_FLAG_STATE_INVALID_3 = 3 - DCS_FLAGS = { - DCS_FLAG_STATE_INVALID_0: 'invalid (0)', - DCS_FLAG_STATE_OFF: 'off', - DCS_FLAG_STATE_ON: 'on', - DCS_FLAG_STATE_INVALID_3: 'invalid (3)', - } - - informantion_element_fields = IEC104_IE_QOC.informantion_element_fields + [ - BitEnumField('dcs', 0, 2, DCS_FLAGS) - ] - - -class IEC104_IE_RCO(IEC104_IE_QOC): - """ - RCO - regulating step command - - EN 60870-5-101:2003, sec. 7.2.6.17 (p. 50) - """ - RCO_FLAG_STATE_INVALID_0 = 0 - RCO_FLAG_STATE_STEP_DOWN = 1 - RCO_FLAG_STATE_STEP_UP = 2 - RCO_FLAG_STATE_INVALID_3 = 3 - RCO_FLAGS = { - RCO_FLAG_STATE_INVALID_0: 'invalid (0)', - RCO_FLAG_STATE_STEP_DOWN: 'step down', - RCO_FLAG_STATE_STEP_UP: 'step up', - RCO_FLAG_STATE_INVALID_3: 'invalid (3)', - } - - informantion_element_fields = IEC104_IE_QOC.informantion_element_fields + [ - BitEnumField('rcs', 0, 2, RCO_FLAGS) - ] - - -class IEC104_IE_CP56TIME2A(IEC104_IE_CommonQualityFlags): - """ - CP56Time2a - dual time, 7 octets - (milliseconds, valid flag, minutes, hours, - summer-time-indicator, day of month, weekday, years) - - well, someone should have talked to them about the idea of the - unix timestamp... - - EN 60870-5-101:2003, sec. 7.2.6.18 (p. 50) - - time representation format according IEC 60870-5-4:1993, sec. 6.8, p. 23 - """ - WEEK_DAY_FLAG_UNUSED = 0 - WEEK_DAY_FLAG_MONDAY = 1 - WEEK_DAY_FLAG_TUESDAY = 2 - WEEK_DAY_FLAG_WEDNESDAY = 3 - WEEK_DAY_FLAG_THURSDAY = 4 - WEEK_DAY_FLAG_FRIDAY = 5 - WEEK_DAY_FLAG_SATURDAY = 6 - WEEK_DAY_FLAG_SUNDAY = 7 - WEEK_DAY_FLAGS = { - WEEK_DAY_FLAG_UNUSED: 'unused', - WEEK_DAY_FLAG_MONDAY: 'Monday', - WEEK_DAY_FLAG_TUESDAY: 'Tuesday', - WEEK_DAY_FLAG_WEDNESDAY: 'Wednesday', - WEEK_DAY_FLAG_THURSDAY: 'Thursday', - WEEK_DAY_FLAG_FRIDAY: 'Friday', - WEEK_DAY_FLAG_SATURDAY: 'Saturday', - WEEK_DAY_FLAG_SUNDAY: 'Sunday' - } - - GEN_FLAG_REALTIME = 0 - GEN_FLAG_SUBSTITUTED_TIME = 1 - GEN_FLAGS = { - GEN_FLAG_REALTIME: 'real time', - GEN_FLAG_SUBSTITUTED_TIME: 'substituted time' - } - - SU_FLAG_NORMAL_TIME = 0 - SU_FLAG_SUMMER_TIME = 1 - SU_FLAGS = { - SU_FLAG_NORMAL_TIME: 'normal time', - SU_FLAG_SUMMER_TIME: 'summer time' - } - - informantion_element_fields = [ - LEShortField('sec_milli', 0), - BitEnumField('iv', 0, 1, IEC104_IE_CommonQualityFlags.IV_FLAGS), - BitEnumField('gen', 0, 1, GEN_FLAGS), - # only valid in monitor direction ToDo: special treatment needed? - BitField('minutes', 0, 6), - BitEnumField('su', 0, 1, SU_FLAGS), - BitField('reserved_2', 0, 2), - BitField('hours', 0, 5), - BitEnumField('weekday', 0, 3, WEEK_DAY_FLAGS), - BitField('day-of-month', 0, 5), - BitField('reserved_3', 0, 4), - BitField('month', 0, 4), - BitField('reserved_4', 0, 1), - BitField('year', 0, 7), - ] - - -class IEC104_IE_CP56TIME2A_START_TIME(IEC104_IE_CP56TIME2A): - """ - derived IE, used for ASDU that requires two CP56TIME2A timestamps for - defining a range - """ - _DERIVED_IE = True - informantion_element_fields = [ - LEShortField('start_sec_milli', 0), - BitEnumField('start_iv', 0, 1, IEC104_IE_CommonQualityFlags.IV_FLAGS), - BitEnumField('start_gen', 0, 1, IEC104_IE_CP56TIME2A.GEN_FLAGS), - # only valid in monitor direction ToDo: special treatment needed? - BitField('start_minutes', 0, 6), - BitEnumField('start_su', 0, 1, IEC104_IE_CP56TIME2A.SU_FLAGS), - BitField('start_reserved_2', 0, 2), - BitField('start_hours', 0, 5), - BitEnumField('start_weekday', 0, 3, - IEC104_IE_CP56TIME2A.WEEK_DAY_FLAGS), - BitField('start_day-of-month', 0, 5), - BitField('start_reserved_3', 0, 4), - BitField('start_month', 0, 4), - BitField('start_reserved_4', 0, 1), - BitField('start_year', 0, 7), - ] - - -class IEC104_IE_CP56TIME2A_STOP_TIME(IEC104_IE_CP56TIME2A): - """ - derived IE, used for ASDU that requires two CP56TIME2A timestamps for - defining a range - """ - _DERIVED_IE = True - informantion_element_fields = [ - LEShortField('stop_sec_milli', 0), - BitEnumField('stop_iv', 0, 1, IEC104_IE_CommonQualityFlags.IV_FLAGS), - BitEnumField('stop_gen', 0, 1, IEC104_IE_CP56TIME2A.GEN_FLAGS), - # only valid in monitor direction ToDo: special treatment needed? - BitField('stop_minutes', 0, 6), - BitEnumField('stop_su', 0, 1, IEC104_IE_CP56TIME2A.SU_FLAGS), - BitField('stop_reserved_2', 0, 2), - BitField('stop_hours', 0, 5), - BitEnumField('stop_weekday', 0, 3, - IEC104_IE_CP56TIME2A.WEEK_DAY_FLAGS), - BitField('stop_day-of-month', 0, 5), - BitField('stop_reserved_3', 0, 4), - BitField('stop_month', 0, 4), - BitField('stop_reserved_4', 0, 1), - BitField('stop_year', 0, 7), - ] - - -class IEC104_IE_CP24TIME2A(IEC104_IE_CP56TIME2A): - """ - CP24Time2a - dual time, 3 octets - (milliseconds, valid flag, minutes) - - EN 60870-5-101:2003, sec. 7.2.6.19 (p. 51) - - time representation format according IEC 60870-5-4:1993, sec. 6.8, p. 23, - octet 4..7 discarded - """ - - informantion_element_fields = \ - IEC104_IE_CP56TIME2A.informantion_element_fields[:4] - - -class IEC104_IE_CP16TIME2A: - """ - CP16Time2a - dual time, 2 octets - (milliseconds) - - EN 60870-5-101:2003, sec. 7.2.6.20 (p. 51) - """ - informantion_element_fields = [ - LEShortField('sec_milli', 0) - ] - - -class IEC104_IE_CP16TIME2A_ELAPSED: - """ - derived IE, used in ASDU using more than one CP* field and this one is - used to show an elapsed time - """ - _DERIVED_IE = True - - informantion_element_fields = [ - LEShortField('elapsed_sec_milli', 0) - ] - - -class IEC104_IE_CP16TIME2A_PROTECTION_ACTIVE: - """ - derived IE, used in ASDU using more than one CP* field and this one is - used to show an protection activation time - """ - _DERIVED_IE = True - - informantion_element_fields = [ - LEShortField('prot_act_sec_milli', 0) - ] - - -class IEC104_IE_CP16TIME2A_PROTECTION_COMMAND: - """ - derived IE, used in ASDU using more than one CP* field and this one is - used to show an protection command time - """ - _DERIVED_IE = True - - informantion_element_fields = [ - LEShortField('prot_cmd_sec_milli', 0) - ] - - -@_generate_attributes_and_dicts -class IEC104_IE_COI: - """ - COI - cause of initialization - - EN 60870-5-101:2003, sec. 7.2.6.21 (p. 51) - """ - LPC_FLAG_LOCAL_PARAMETER_UNCHANGED = 0 - LPC_FLAG_LOCAL_PARAMETER_CHANGED = 1 - LPC_FLAGS = { - LPC_FLAG_LOCAL_PARAMETER_UNCHANGED: 'unchanged', - LPC_FLAG_LOCAL_PARAMETER_CHANGED: 'changed' - } - - COI_FLAG_LOCAL_POWER_ON = 0 - COI_FLAG_LOCAL_MANUAL_RESET = 1 - COI_FLAG_REMOTE_RESET = 2 - - COI_FLAGS = { - COI_FLAG_LOCAL_POWER_ON: 'local power on', - COI_FLAG_LOCAL_MANUAL_RESET: 'manual reset', - COI_FLAG_REMOTE_RESET: 'remote reset' - } - - GENERATED_ATTRIBUTES = [ - ('COI_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', COI_FLAGS, 3, - 31), - ('COI_FLAG_PRIVATE_RESERVED', 'private reserved', COI_FLAGS, 32, 127) - ] - - informantion_element_fields = [ - BitEnumField('local_param_state', 0, 1, LPC_FLAGS), - BitEnumField('coi', 0, 7, COI_FLAGS) - ] - - -@_generate_attributes_and_dicts -class IEC104_IE_QOI: - """ - QOI - qualifier of interrogation - - EN 60870-5-101:2003, sec. 7.2.6.22 (p. 52) - """ - QOI_FLAG_UNUSED = 0 - QOI_FLAG_STATION_INTERROGATION = 20 - QOI_FLAG_GROUP_1_INTERROGATION = 21 - QOI_FLAG_GROUP_2_INTERROGATION = 22 - QOI_FLAG_GROUP_3_INTERROGATION = 23 - QOI_FLAG_GROUP_4_INTERROGATION = 24 - QOI_FLAG_GROUP_5_INTERROGATION = 25 - QOI_FLAG_GROUP_6_INTERROGATION = 26 - QOI_FLAG_GROUP_7_INTERROGATION = 27 - QOI_FLAG_GROUP_8_INTERROGATION = 28 - QOI_FLAG_GROUP_9_INTERROGATION = 29 - QOI_FLAG_GROUP_10_INTERROGATION = 30 - QOI_FLAG_GROUP_11_INTERROGATION = 31 - QOI_FLAG_GROUP_12_INTERROGATION = 32 - QOI_FLAG_GROUP_13_INTERROGATION = 33 - QOI_FLAG_GROUP_14_INTERROGATION = 34 - QOI_FLAG_GROUP_15_INTERROGATION = 35 - QOI_FLAG_GROUP_16_INTERROGATION = 36 - - QOI_FLAGS = { - QOI_FLAG_UNUSED: 'unused', - QOI_FLAG_STATION_INTERROGATION: 'station interrogation', - QOI_FLAG_GROUP_1_INTERROGATION: 'group 1 interrogation', - QOI_FLAG_GROUP_2_INTERROGATION: 'group 2 interrogation', - QOI_FLAG_GROUP_3_INTERROGATION: 'group 3 interrogation', - QOI_FLAG_GROUP_4_INTERROGATION: 'group 4 interrogation', - QOI_FLAG_GROUP_5_INTERROGATION: 'group 5 interrogation', - QOI_FLAG_GROUP_6_INTERROGATION: 'group 6 interrogation', - QOI_FLAG_GROUP_7_INTERROGATION: 'group 7 interrogation', - QOI_FLAG_GROUP_8_INTERROGATION: 'group 8 interrogation', - QOI_FLAG_GROUP_9_INTERROGATION: 'group 9 interrogation', - QOI_FLAG_GROUP_10_INTERROGATION: 'group 10 interrogation', - QOI_FLAG_GROUP_11_INTERROGATION: 'group 11 interrogation', - QOI_FLAG_GROUP_12_INTERROGATION: 'group 12 interrogation', - QOI_FLAG_GROUP_13_INTERROGATION: 'group 13 interrogation', - QOI_FLAG_GROUP_14_INTERROGATION: 'group 14 interrogation', - QOI_FLAG_GROUP_15_INTERROGATION: 'group 15 interrogation', - QOI_FLAG_GROUP_16_INTERROGATION: 'group 16 interrogation' - } - - GENERATED_ATTRIBUTES = [ - ('QOI_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', QOI_FLAGS, 1, - 19), - ('QOI_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', QOI_FLAGS, 37, - 63), - ('QOI_FLAG_PRIVATE_RESERVED', 'private reserved', QOI_FLAGS, 64, 255) - ] - - informantion_element_fields = [ - ByteEnumField('qoi', 0, QOI_FLAGS) - ] - - -@_generate_attributes_and_dicts -class IEC104_IE_QCC: - """ - QCC - qualifier of counter interrogation command - - EN 60870-5-101:2003, sec. 7.2.6.23 (p. 52) - """ - - # request flags - RQT_FLAG_UNUSED = 0 - RQT_FLAG_GROUP_1_COUNTER_INTERROGATION = 1 - RQT_FLAG_GROUP_2_COUNTER_INTERROGATION = 2 - RQT_FLAG_GROUP_3_COUNTER_INTERROGATION = 3 - RQT_FLAG_GROUP_4_COUNTER_INTERROGATION = 4 - RQT_FLAG_GENERAL_COUNTER_INTERROGATION = 5 - - RQT_FLAGS = { - RQT_FLAG_UNUSED: 'unused', - RQT_FLAG_GROUP_1_COUNTER_INTERROGATION: 'counter group 1 ' - 'interrogation', - RQT_FLAG_GROUP_2_COUNTER_INTERROGATION: 'counter group 2 ' - 'interrogation', - RQT_FLAG_GROUP_3_COUNTER_INTERROGATION: 'counter group 3 ' - 'interrogation', - RQT_FLAG_GROUP_4_COUNTER_INTERROGATION: 'counter group 4 ' - 'interrogation', - RQT_FLAG_GENERAL_COUNTER_INTERROGATION: 'general counter ' - 'interrogation', - } - - GENERATED_ATTRIBUTES = [ - ('RQT_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', RQT_FLAGS, 6, - 31), - ('RQT_FLAG_PRIVATE_RESERVED', 'private reserved', RQT_FLAGS, 32, 63), - ] - - FRZ_FLAG_QUERY = 0 - FRZ_FLAG_SAVE_COUNTER_WITHOUT_RESET = 1 - FRZ_FLAG_SAVE_COUNTER_AND_RESET = 2 - FRZ_FLAG_COUNTER_RESET = 3 - - FRZ_FLAGS = { - FRZ_FLAG_QUERY: 'query', - FRZ_FLAG_SAVE_COUNTER_WITHOUT_RESET: 'save counter, no counter reset', - FRZ_FLAG_SAVE_COUNTER_AND_RESET: 'save counter and reset counter', - FRZ_FLAG_COUNTER_RESET: 'reset counter' - } - - informantion_element_fields = [ - BitEnumField('frz', 0, 2, FRZ_FLAGS), - BitEnumField('rqt', 0, 6, RQT_FLAGS) - ] - - -@_generate_attributes_and_dicts -class IEC104_IE_QPM: - """ - QPM - qualifier of parameter of measured values - - EN 60870-5-101:2003, sec. 7.2.6.24 (p. 53) - """ - - KPA_FLAG_UNUSED = 0 - KPA_FLAG_THRESHOLD = 1 - KPA_FLAG_SMOOTHING_FACTOR = 2 - KPA_FLAG_LOWER_LIMIT_FOR_MEAS_TX = 3 - KPA_FLAG_UPPER_LIMIT_FOR_MEAS_TX = 4 - GENERATED_ATTRIBUTES = [ - ('KPA_FLAG_COMPATIBLE_RESERVED', 5, 31), - ('KPA_FLAG_PRIVATE_RESERVED', 32, 63) - ] - - KPA_FLAGS = { - KPA_FLAG_UNUSED: 'unused', - KPA_FLAG_THRESHOLD: 'threshold', - KPA_FLAG_SMOOTHING_FACTOR: 'smoothing factor', - KPA_FLAG_LOWER_LIMIT_FOR_MEAS_TX: 'lower limit meas transmit', - KPA_FLAG_UPPER_LIMIT_FOR_MEAS_TX: 'upper limit meas transmit' - } - - GENERATED_ATTRIBUTES = [ - ('KPA_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', KPA_FLAGS, 5, - 31), - ('KPA_FLAG_PRIVATE_RESERVED', 'private reserved', KPA_FLAGS, 32, 63) - ] - - LPC_FLAG_LOCAL_PARAMETER_MOT_CHANGED = 0 - LPC_FLAG_LOCAL_PARAMETER_CHANGED = 1 - LPC_FLAGS = { - LPC_FLAG_LOCAL_PARAMETER_MOT_CHANGED: 'local parameter not changed', - LPC_FLAG_LOCAL_PARAMETER_CHANGED: 'local parameter changed' - } - - POP_FLAG_PARAM_EFFECTIVE = 0 - POP_FLAG_PARAM_INEFFECTIVE = 1 - POP_FLAGS = { - POP_FLAG_PARAM_EFFECTIVE: 'parameter effective', - POP_FLAG_PARAM_INEFFECTIVE: 'parameter ineffective', - } - - informantion_element_fields = [ - BitEnumField('pop', 0, 1, POP_FLAGS), # usually unused, should be zero - BitEnumField('lpc', 0, 1, LPC_FLAGS), # usually unused, should be zero - BitEnumField('kpa', 0, 6, KPA_FLAGS), - ] - - -@_generate_attributes_and_dicts -class IEC104_IE_QPA: - """ - QPA - qualifier of parameter activation - - EN 60870-5-101:2003, sec. 7.2.6.25 (p. 53) - """ - QPA_FLAG_UNUSED = 0 - QPA_FLAG_ACT_DEACT_LOADED_PARAM_OA_0 = 1 - QPA_FLAG_ACT_DEACT_LOADED_PARAM = 2 - QPA_FLAG_ACT_DEACT_CYCLIC_TX = 3 - - QPA_FLAGS = { - QPA_FLAG_UNUSED: 'unused', - QPA_FLAG_ACT_DEACT_LOADED_PARAM_OA_0: 'act/deact loaded parameters ' - 'for object addr 0', - QPA_FLAG_ACT_DEACT_LOADED_PARAM: 'act/deact loaded parameters for ' - 'given object addr', - QPA_FLAG_ACT_DEACT_CYCLIC_TX: 'act/deact cyclic transfer of object ' - 'given by object addr', - } - - GENERATED_ATTRIBUTES = [ - ('QPA_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', QPA_FLAGS, 4, - 127), - ('QPA_FLAG_PRIVATE_RESERVED', 'private reserved', QPA_FLAGS, 128, 255) - ] - - informantion_element_fields = [ - ByteEnumField('qpa', 0, QPA_FLAGS) - ] - - -@_generate_attributes_and_dicts -class IEC104_IE_QRP: - """ - QRP - Qualifier of reset process command - - EN 60870-5-101:2003, sec. 7.2.6.27 (p. 54) - """ - QRP_FLAG_UNUSED = 0 - QRP_FLAG_GENERAL_PROCESS_RESET = 1 - QRP_FLAG_RESET_EVENT_BUFFER = 2 - - QRP_FLAGS = { - QRP_FLAG_UNUSED: 'unsued', - QRP_FLAG_GENERAL_PROCESS_RESET: 'general process reset', - QRP_FLAG_RESET_EVENT_BUFFER: 'reset event buffer' - } - - GENERATED_ATTRIBUTES = [ - ('QRP_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', QRP_FLAGS, 3, - 127), - ('QRP_FLAG_PRIVATE_RESERVED', 'private reserved', QRP_FLAGS, 128, 255), - ] - - informantion_element_fields = [ - ByteEnumField('qrp', 0, QRP_FLAGS) - ] - - -@_generate_attributes_and_dicts -class IEC104_IE_FRQ: - """ - FRQ - file ready qualifier - - EN 60870-5-101:2003, sec. 7.2.6.28 (p. 54) - """ - FR_FLAG_UNUSED = 0 - - FR_FLAGS = { - FR_FLAG_UNUSED: 'unused' - } - - GENERATED_ATTRIBUTES = [ - ('FR_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', - FR_FLAGS, 1, 63), - ('FR_FLAG_PRIVATE_RESERVED', 'private reserved', FR_FLAGS, 64, 127), - ] - - FRACK_FLAG_POSITIVE_ACK = 0 - FRACK_FLAG_NEGATIVE_ACK = 1 - FRACK_FLAGS = { - FRACK_FLAG_POSITIVE_ACK: 'positive ack', - FRACK_FLAG_NEGATIVE_ACK: 'negative ack' - } - - informantion_element_fields = [ - BitEnumField('fr_ack', 0, 1, FRACK_FLAGS), - BitEnumField('fr', 0, 7, FR_FLAGS) - ] - - -@_generate_attributes_and_dicts -class IEC104_IE_SRQ: - """ - SRQ - sequence ready qualifier - - EN 60870-5-101:2003, sec. 7.2.6.29 (p. 54) - """ - SR_FLAG_UNUSED = 0 - - SR_FLAGS = { - SR_FLAG_UNUSED: 'unused' - } - - GENERATED_ATTRIBUTES = [ - ('SR_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', - SR_FLAGS, 1, 63), - ('SR_FLAG_PRIVATE_RESERVED', 'private reserved', SR_FLAGS, 64, 127), - ] - - SLOAD_FLAG_SECTION_READY = 0 - SLOAD_FLAG_SECTION_NOT_READY = 1 - SLAOD_FLAGS = { - SLOAD_FLAG_SECTION_READY: 'section ready', - SLOAD_FLAG_SECTION_NOT_READY: 'section not ready' - } - - informantion_element_fields = [ - BitEnumField('section_load_state', 0, 1, SLAOD_FLAGS), - BitEnumField('sr', 0, 7, SR_FLAGS) - ] - - -@_generate_attributes_and_dicts -class IEC104_IE_SCQ: - """ - SCQ - select and call qualifier - - EN 60870-5-101:2003, sec. 7.2.6.30 (p. 55) - """ - SEL_CALL_FLAG_UNUSED = 0 - SEL_CALL_FLAG_FILE_SELECT = 1 - SEL_CALL_FLAG_FILE_REQUEST = 2 - SEL_CALL_FLAG_FILE_ABORT = 3 - SEL_CALL_FLAG_FILE_DELETE = 4 - SEL_CALL_FLAG_SECTION_SELECTION = 5 - SEL_CALL_FLAG_SECTION_REQUEST = 6 - SEL_CALL_FLAG_SECTION_ABORT = 7 - - SEL_CALL_FLAGS = { - SEL_CALL_FLAG_UNUSED: 'unused', - SEL_CALL_FLAG_FILE_SELECT: 'file select', - SEL_CALL_FLAG_FILE_REQUEST: 'file request', - SEL_CALL_FLAG_FILE_ABORT: 'file abort', - SEL_CALL_FLAG_FILE_DELETE: 'file delete', - SEL_CALL_FLAG_SECTION_SELECTION: 'section selection', - SEL_CALL_FLAG_SECTION_REQUEST: 'section request', - SEL_CALL_FLAG_SECTION_ABORT: 'section abort' - } - - SEL_CALL_ERR_FLAG_UNUSED = 0 - SEL_CALL_ERR_FLAG_REQ_MEM_AREA_NO_AVAIL = 1 - SEL_CALL_ERR_FLAG_INVALID_CHECKSUM = 2 - SEL_CALL_ERR_FLAG_UNEXPECTED_COMMUNICATION_SERVICE = 3 - SEL_CALL_ERR_FLAG_UNEXPECTED_FILENAME = 4 - SEL_CALL_ERR_FLAG_UNEXPECTED_SECTION_NAME = 5 - SEL_CALL_ERR_FLAG_COMPATIBLE_RESERVED_6 = 6 - SEL_CALL_ERR_FLAG_COMPATIBLE_RESERVED_7 = 7 - SEL_CALL_ERR_FLAG_COMPATIBLE_RESERVED_8 = 8 - SEL_CALL_ERR_FLAG_COMPATIBLE_RESERVED_9 = 9 - SEL_CALL_ERR_FLAG_COMPATIBLE_RESERVED_10 = 10 - SEL_CALL_ERR_FLAG_PRIVATE_RESERVED_11 = 11 - SEL_CALL_ERR_FLAG_PRIVATE_RESERVED_12 = 12 - SEL_CALL_ERR_FLAG_PRIVATE_RESERVED_13 = 13 - SEL_CALL_ERR_FLAG_PRIVATE_RESERVED_14 = 14 - SEL_CALL_ERR_FLAG_PRIVATE_RESERVED_15 = 15 - - SEL_CALL_ERR_FLAGS = { - SEL_CALL_ERR_FLAG_UNUSED: 'unused', - SEL_CALL_ERR_FLAG_REQ_MEM_AREA_NO_AVAIL: 'requested memory area ' - 'not available', - SEL_CALL_ERR_FLAG_INVALID_CHECKSUM: 'invalid checksum', - SEL_CALL_ERR_FLAG_UNEXPECTED_COMMUNICATION_SERVICE: 'unexpected ' - 'communication ' - 'service', - SEL_CALL_ERR_FLAG_UNEXPECTED_FILENAME: 'unexpected file name', - SEL_CALL_ERR_FLAG_UNEXPECTED_SECTION_NAME: 'unexpected section name' - } - - GENERATED_ATTRIBUTES = [ - ('SEL_CALL_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', - SEL_CALL_FLAGS, 8, 10), - ('SEL_CALL_FLAG_PRIVATE_RESERVED', 'private reserved', SEL_CALL_FLAGS, - 11, 15), - ('SEL_CALL_ERR_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', - SEL_CALL_ERR_FLAGS, 6, 10), - ('SEL_CALL_ERR_FLAG_PRIVATE_RESERVED', 'private reserved', - SEL_CALL_ERR_FLAGS, 11, 15) - ] - - informantion_element_fields = [ - BitEnumField('errors', 0, 4, SEL_CALL_ERR_FLAGS), - BitEnumField('select_call', 0, 4, SEL_CALL_FLAGS) - ] - - -@_generate_attributes_and_dicts -class IEC104_IE_LSQ: - """ - LSQ - last section or segment qualifier - - EN 60870-5-101:2003, sec. 7.2.6.31 (p. 55) - """ - LSQ_FLAG_UNUSED = 0 - LSQ_FLAG_FILE_TRANSFER_NO_ABORT = 1 - LSQ_FLAG_FILE_TRANSFER_ABORT = 2 - LSQ_FLAG_SECTION_TRANSFER_NO_ABORT = 3 - LSQ_FLAG_SECTION_TRANSFER_ABORT = 4 - - LSQ_FLAGS = { - LSQ_FLAG_UNUSED: 'unused', - LSQ_FLAG_FILE_TRANSFER_NO_ABORT: 'file transfer - no abort', - LSQ_FLAG_FILE_TRANSFER_ABORT: 'file transfer - aborted', - LSQ_FLAG_SECTION_TRANSFER_NO_ABORT: 'section transfer - no abort', - LSQ_FLAG_SECTION_TRANSFER_ABORT: 'section transfer - aborted', - } - - GENERATED_ATTRIBUTES = [ - ('LSQ_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', LSQ_FLAGS, 5, - 127), - ('LSQ_FLAG_PRIVATE_RESERVED', 'private reserved', LSQ_FLAGS, 128, 255), - ] - - informantion_element_fields = [ - ByteEnumField('lsq', 0, LSQ_FLAGS) - ] - - -@_generate_attributes_and_dicts -class IEC104_IE_AFQ: - """ - AFQ - acknowledge file or section qualifier - - EN 60870-5-101:2003, sec. 7.2.6.32 (p. 55) - """ - ACK_FILE_OR_SEC_FLAG_UNUSED = 0 - ACK_FILE_OR_SEC_FLAG_POSITIVE_ACK_FILE_TRANSFER = 1 - ACK_FILE_OR_SEC_FLAG_NEGATIVE_ACK_FILE_TRANSFER = 2 - ACK_FILE_OR_SEC_FLAG_POSITIVE_ACK_SECTION_TRANSFER = 3 - ACK_FILE_OR_SEC_FLAG_NEGATIVE_ACK_SECTION_TRANSFER = 4 - - ACK_FILE_OR_SEC_FLAGS = { - ACK_FILE_OR_SEC_FLAG_UNUSED: 'unused', - ACK_FILE_OR_SEC_FLAG_POSITIVE_ACK_FILE_TRANSFER: 'positive acknowledge' - ' file transfer', - ACK_FILE_OR_SEC_FLAG_NEGATIVE_ACK_FILE_TRANSFER: 'negative acknowledge' - ' file transfer', - ACK_FILE_OR_SEC_FLAG_POSITIVE_ACK_SECTION_TRANSFER: 'positive ' - 'acknowledge ' - 'section transfer', - ACK_FILE_OR_SEC_FLAG_NEGATIVE_ACK_SECTION_TRANSFER: 'negative ' - 'acknowledge ' - 'section transfer' - } - - ACK_FILE_OR_SEC_ERR_FLAG_UNUSED = 0 - ACK_FILE_OR_SEC_ERR_FLAG_REQ_MEM_AREA_NO_AVAIL = 1 - ACK_FILE_OR_SEC_ERR_FLAG_INVALID_CHECKSUM = 2 - ACK_FILE_OR_SEC_ERR_FLAG_UNEXPECTED_COMMUNICATION_SERVICE = 3 - ACK_FILE_OR_SEC_ERR_FLAG_UNEXPECTED_FILENAME = 4 - ACK_FILE_OR_SEC_ERR_FLAG_UNEXPECTED_SECTION_NAME = 5 - - ACK_FILE_OR_SEC_ERR_FLAGS = { - ACK_FILE_OR_SEC_ERR_FLAG_UNUSED: 'unused', - ACK_FILE_OR_SEC_ERR_FLAG_REQ_MEM_AREA_NO_AVAIL: 'requested memory ' - 'area not available', - ACK_FILE_OR_SEC_ERR_FLAG_INVALID_CHECKSUM: 'invalid checksum', - ACK_FILE_OR_SEC_ERR_FLAG_UNEXPECTED_COMMUNICATION_SERVICE: 'unexpected' - ' communica' - 'tion ' - 'service', - ACK_FILE_OR_SEC_ERR_FLAG_UNEXPECTED_FILENAME: 'unexpected file name', - ACK_FILE_OR_SEC_ERR_FLAG_UNEXPECTED_SECTION_NAME: 'unexpected ' - 'section name' - } - - GENERATED_ATTRIBUTES = [ - ('ACK_FILE_OR_SEC_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', - ACK_FILE_OR_SEC_FLAGS, 5, 10), - ('ACK_FILE_OR_SEC_FLAG_PRIVATE_RESERVED', 'private reserved', - ACK_FILE_OR_SEC_FLAGS, 11, 15), - - ('ACK_FILE_OR_SEC_ERR_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', - ACK_FILE_OR_SEC_ERR_FLAGS, 6, 10), - ('ACK_FILE_OR_SEC_ERR_FLAG_PRIVATE_RESERVED', 'private reserved', - ACK_FILE_OR_SEC_ERR_FLAGS, 11, 15) - ] - - informantion_element_fields = [ - BitEnumField('errors', 0, 4, ACK_FILE_OR_SEC_ERR_FLAGS), - BitEnumField('ack_file_or_sec', 0, 4, ACK_FILE_OR_SEC_FLAGS) - ] - - -class IEC104_IE_NOF: - """ - NOF - name of file - - EN 60870-5-101:2003, sec. 7.2.6.33 (p. 56) - """ - informantion_element_fields = [ - LEShortField('file_name', 0) - ] - - -class IEC104_IE_NOS: - """ - NOS - name of section - - EN 60870-5-101:2003, sec. 7.2.6.34 (p. 56) - """ - informantion_element_fields = [ - ByteField('section_name', 0) - ] - - -class IEC104_IE_LOF: - """ - LOF - length of file or section - - EN 60870-5-101:2003, sec. 7.2.6.35 (p. 55) - """ - informantion_element_fields = [ - ThreeBytesField('file_length', 0) - ] - - -class IEC104_IE_LOS: - """ - LOS - length of segment - - EN 60870-5-101:2003, sec. 7.2.6.36 (p. 56) - """ - informantion_element_fields = [ - ByteField('segment_length', 0) - ] - - -class IEC104_IE_CHS: - """ - CHS - checksum - - EN 60870-5-101:2003, sec. 7.2.6.37 (p. 56) - """ - informantion_element_fields = [ - ByteField('checksum', 0) - ] - - -@_generate_attributes_and_dicts -class IEC104_IE_SOF: - """ - SOF - status of file - - EN 60870-5-101:2003, sec. 7.2.6.38 (p. 56) - """ - STATUS_FLAG_UNUSED = 0 - - STATUS_FLAGS = { - STATUS_FLAG_UNUSED: 'unused' - } - - GENERATED_ATTRIBUTES = [ - ('STATUS_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', - STATUS_FLAGS, 1, 15), - ('STATUS_FLAG_PRIVATE_RESERVED', 'private reserved', - STATUS_FLAGS, 16, 32) - ] - - LFD_FLAG_NEXT_FILE_OF_DIR_FOLLOWS = 0 - LFD_FLAG_LAST_FILE_OF_DIR = 1 - LFD_FLAGS = { - LFD_FLAG_NEXT_FILE_OF_DIR_FOLLOWS: 'next file of dir follows', - LFD_FLAG_LAST_FILE_OF_DIR: 'last file of dir' - } - - FOR_FLAG_NAME_DEFINES_FILE = 0 - FOR_FLAG_NAME_DEFINES_SUBDIR = 1 - FOR_FLAGS = { - FOR_FLAG_NAME_DEFINES_FILE: 'name defines file', - FOR_FLAG_NAME_DEFINES_SUBDIR: 'name defines subdirectory' - } - - FA_FLAG_FILE_WAITS_FOR_TRANSFER = 0 - FA_FLAG_FILE_TRANSFER_IS_ACTIVE = 1 - FA_FLAGS = { - FA_FLAG_FILE_WAITS_FOR_TRANSFER: 'file waits for transfer', - FA_FLAG_FILE_TRANSFER_IS_ACTIVE: 'transfer of file active' - } - - informantion_element_fields = [ - BitEnumField('fa', 0, 1, FA_FLAGS), - BitEnumField('for', 0, 1, FOR_FLAGS), - BitEnumField('lfd', 0, 1, LFD_FLAGS), - BitEnumField('status', 0, 5, STATUS_FLAGS) - ] - - -@_generate_attributes_and_dicts -class IEC104_IE_QOS: - """ - QOS - qualifier of set-point command - - EN 60870-5-101:2003, sec. 7.2.6.39 (p. 57) - """ - QL_FLAG_UNUSED = 0 - - QL_FLAGS = { - QL_FLAG_UNUSED: 'unused' - } - - GENERATED_ATTRIBUTES = [ - ('QL_FLAG_COMPATIBLE_RESERVED', 'compatible reserved', - QL_FLAGS, 1, 63), - ('QL_FLAG_PRIVATE_RESERVED', 'private reserved', - QL_FLAGS, 64, 127) - ] - - SE_FLAG_EXECUTE = 0 - SE_FLAG_SELECT = 1 - SE_FLAGS = { - SE_FLAG_EXECUTE: 'execute', - SE_FLAG_SELECT: 'select' - } - - informantion_element_fields = [ - BitEnumField('action', 0, 1, SE_FLAGS), - BitEnumField('ql', 0, 7, QL_FLAGS) - ] - - -class IEC104_IE_SCD: - """ - SCD - status and status change detection - - EN 60870-5-101:2003, sec. 7.2.6.40 (p. 57) - """ - ST_FLAG_STATE_OFF = 0 - ST_FLAG_STATE_ON = 1 - ST_FLAGS = { - ST_FLAG_STATE_OFF: 'off', - ST_FLAG_STATE_ON: 'on' - } - - CD_FLAG_STATE_NOT_CHANGED = 0 - CD_FLAG_STATE_CHANGED = 1 - CD_FLAGS = { - CD_FLAG_STATE_NOT_CHANGED: 'state not changed', - CD_FLAG_STATE_CHANGED: 'state changed' - } - - informantion_element_fields = [ - BitEnumField('cd_16', 0, 1, CD_FLAGS), - BitEnumField('cd_15', 0, 1, CD_FLAGS), - BitEnumField('cd_14', 0, 1, CD_FLAGS), - BitEnumField('cd_13', 0, 1, CD_FLAGS), - BitEnumField('cd_12', 0, 1, CD_FLAGS), - BitEnumField('cd_11', 0, 1, CD_FLAGS), - BitEnumField('cd_10', 0, 1, CD_FLAGS), - BitEnumField('cd_9', 0, 1, CD_FLAGS), - BitEnumField('cd_8', 0, 1, CD_FLAGS), - BitEnumField('cd_7', 0, 1, CD_FLAGS), - BitEnumField('cd_6', 0, 1, CD_FLAGS), - BitEnumField('cd_5', 0, 1, CD_FLAGS), - BitEnumField('cd_4', 0, 1, CD_FLAGS), - BitEnumField('cd_3', 0, 1, CD_FLAGS), - BitEnumField('cd_2', 0, 1, CD_FLAGS), - BitEnumField('cd_1', 0, 1, CD_FLAGS), - BitEnumField('st_16', 0, 1, ST_FLAGS), - BitEnumField('st_15', 0, 1, ST_FLAGS), - BitEnumField('st_14', 0, 1, ST_FLAGS), - BitEnumField('st_13', 0, 1, ST_FLAGS), - BitEnumField('st_12', 0, 1, ST_FLAGS), - BitEnumField('st_11', 0, 1, ST_FLAGS), - BitEnumField('st_10', 0, 1, ST_FLAGS), - BitEnumField('st_9', 0, 1, ST_FLAGS), - BitEnumField('st_8', 0, 1, ST_FLAGS), - BitEnumField('st_7', 0, 1, ST_FLAGS), - BitEnumField('st_6', 0, 1, ST_FLAGS), - BitEnumField('st_5', 0, 1, ST_FLAGS), - BitEnumField('st_4', 0, 1, ST_FLAGS), - BitEnumField('st_3', 0, 1, ST_FLAGS), - BitEnumField('st_2', 0, 1, ST_FLAGS), - BitEnumField('st_1', 0, 1, ST_FLAGS), - ] - - -class IEC104_IE_TSC: - """ - TSC - test sequence counter - - EN 60870-5-104:2006, sec. 8.8 (p. 44) - """ - informantion_element_fields = [ - LEShortField('tsc', 0) - ] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/iec104_information_objects.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/iec104_information_objects.py deleted file mode 100644 index 99b2937cf0..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/scada/iec104/iec104_information_objects.py +++ /dev/null @@ -1,2248 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Thomas Tannhaeuser -# This program is published under a GPLv2 license -# -# scapy.contrib.description = IEC-60870-5-104 ASDU layers / IO definitions -# scapy.contrib.status = loads - -""" - application service data units used by IEC 60870-5-101/104 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - :description: - - This module provides the information object (IO) definitions used - within the IEC 60870-5-101 and IEC 60870-5-104 protocol. - - normative references: - - IEC 60870-5-101:2003 (sec. 7.3) - - IEC 60870-5-104:2006 (sec. 8)) - - - :NOTES: - - this file contains all IO definitions from 101 and 104 - even if an - IO is not used within 104 -""" -from scapy.config import conf -from scapy.contrib.scada.iec104.iec104_fields import LEThreeBytesField -from scapy.contrib.scada.iec104.iec104_information_elements import \ - IEC104_IE_SIQ, IEC104_IE_CP24TIME2A, IEC104_IE_DIQ, IEC104_IE_VTI, \ - IEC104_IE_QDS, IEC104_IE_BSI, IEC104_IE_NVA, IEC104_IE_SVA, \ - IEC104_IE_R32_IEEE_STD_754, IEC104_IE_BCR, IEC104_IE_CP16TIME2A_ELAPSED, \ - IEC104_IE_SEP, IEC104_IE_SPE, IEC104_IE_CP16TIME2A_PROTECTION_ACTIVE, \ - IEC104_IE_QDP, IEC104_IE_CP16TIME2A_PROTECTION_COMMAND, IEC104_IE_OCI, \ - IEC104_IE_SCD, IEC104_IE_CP56TIME2A, IEC104_IE_SCO, IEC104_IE_DCO, \ - IEC104_IE_RCO, IEC104_IE_QOS, IEC104_IE_QOI, IEC104_IE_QCC, \ - IEC104_IE_FBP, IEC104_IE_QRP, IEC104_IE_CP16TIME2A, IEC104_IE_QPM, \ - IEC104_IE_QPA, IEC104_IE_NOF, IEC104_IE_LOF, IEC104_IE_FRQ, \ - IEC104_IE_NOS, IEC104_IE_SRQ, IEC104_IE_SCQ, IEC104_IE_CHS, \ - IEC104_IE_LSQ, IEC104_IE_AFQ, IEC104_IE_SOF, IEC104_IE_COI, \ - IEC104_IE_CP56TIME2A_START_TIME, IEC104_IE_CP56TIME2A_STOP_TIME, \ - IEC104_IE_TSC - -from scapy.fields import XStrLenField, BitFieldLenField -from scapy.packet import Packet - -IEC104_IO_ID_UNDEFINED = 0x00 -IEC104_IO_ID_M_SP_NA_1 = 0x01 -IEC104_IO_ID_M_SP_TA_1 = 0x02 -IEC104_IO_ID_M_DP_NA_1 = 0x03 -IEC104_IO_ID_M_DP_TA_1 = 0x04 -IEC104_IO_ID_M_ST_NA_1 = 0x05 -IEC104_IO_ID_M_ST_TA_1 = 0x06 -IEC104_IO_ID_M_BO_NA_1 = 0x07 -IEC104_IO_ID_M_BO_TA_1 = 0x08 -IEC104_IO_ID_M_ME_NA_1 = 0x09 -IEC104_IO_ID_M_ME_TA_1 = 0x0a -IEC104_IO_ID_M_ME_NB_1 = 0x0b -IEC104_IO_ID_M_ME_TB_1 = 0x0c -IEC104_IO_ID_M_ME_NC_1 = 0x0d -IEC104_IO_ID_M_ME_TC_1 = 0x0e -IEC104_IO_ID_M_IT_NA_1 = 0x0f -IEC104_IO_ID_M_IT_TA_1 = 0x10 -IEC104_IO_ID_M_EP_TA_1 = 0x11 -IEC104_IO_ID_M_EP_TB_1 = 0x12 -IEC104_IO_ID_M_EP_TC_1 = 0x13 -IEC104_IO_ID_M_PS_NA_1 = 0x14 -IEC104_IO_ID_M_ME_ND_1 = 0x15 -IEC104_IO_ID_M_SP_TB_1 = 0x1e -IEC104_IO_ID_M_DP_TB_1 = 0x1f -IEC104_IO_ID_M_ST_TB_1 = 0x20 -IEC104_IO_ID_M_BO_TB_1 = 0x21 -IEC104_IO_ID_M_ME_TD_1 = 0x22 -IEC104_IO_ID_M_ME_TE_1 = 0x23 -IEC104_IO_ID_M_ME_TF_1 = 0x24 -IEC104_IO_ID_M_IT_TB_1 = 0x25 -IEC104_IO_ID_M_EP_TD_1 = 0x26 -IEC104_IO_ID_M_EP_TE_1 = 0x27 -IEC104_IO_ID_M_EP_TF_1 = 0x28 -IEC104_IO_ID_C_SC_NA_1 = 0x2d -IEC104_IO_ID_C_DC_NA_1 = 0x2e -IEC104_IO_ID_C_RC_NA_1 = 0x2f -IEC104_IO_ID_C_SE_NA_1 = 0x30 -IEC104_IO_ID_C_SE_NB_1 = 0x31 -IEC104_IO_ID_C_SE_NC_1 = 0x32 -IEC104_IO_ID_C_BO_NA_1 = 0x33 -IEC104_IO_ID_M_EI_NA_1 = 0x46 -IEC104_IO_ID_C_IC_NA_1 = 0x64 -IEC104_IO_ID_C_CI_NA_1 = 0x65 -IEC104_IO_ID_C_RD_NA_1 = 0x66 -IEC104_IO_ID_C_CS_NA_1 = 0x67 -IEC104_IO_ID_C_TS_NA_1 = 0x68 -IEC104_IO_ID_C_RP_NA_1 = 0x69 -IEC104_IO_ID_C_CD_NA_1 = 0x6a -IEC104_IO_ID_P_ME_NA_1 = 0x6e -IEC104_IO_ID_P_ME_NB_1 = 0x6f -IEC104_IO_ID_P_ME_NC_1 = 0x70 -IEC104_IO_ID_P_AC_NA_1 = 0x71 -IEC104_IO_ID_F_FR_NA_1 = 0x78 -IEC104_IO_ID_F_SR_NA_1 = 0x79 -IEC104_IO_ID_F_SC_NA_1 = 0x7a -IEC104_IO_ID_F_LS_NA_1 = 0x7b -IEC104_IO_ID_F_AF_NA_1 = 0x7c -IEC104_IO_ID_F_SG_NA_1 = 0x7d -IEC104_IO_ID_F_DR_TA_1 = 0x7e -# specific IOs from 60870-5-104:2006, sec. 8 (p. 37 ff) -IEC104_IO_ID_C_SC_TA_1 = 0x3a -IEC104_IO_ID_C_DC_TA_1 = 0x3b -IEC104_IO_ID_C_RC_TA_1 = 0x3c -IEC104_IO_ID_C_SE_TA_1 = 0x3d -IEC104_IO_ID_C_SE_TB_1 = 0x3e -IEC104_IO_ID_C_SE_TC_1 = 0x3f -IEC104_IO_ID_C_BO_TA_1 = 0x40 -IEC104_IO_ID_C_TS_TA_1 = 0x6b -IEC104_IO_ID_F_SC_NB_1 = 0x7f - - -def _dict_add_reserved_range(d, start, end): - for idx in range(start, end + 1): - d[idx] = 'reserved_{}'.format(idx) - - -IEC104_IO_DESCRIPTIONS = { - 0: 'undefined', - IEC104_IO_ID_M_SP_NA_1: 'M_SP_NA_1 (single point report)', - IEC104_IO_ID_M_SP_TA_1: 'M_SP_TA_1 (single point report with timestamp) ' - '# 60870-4-101 only', - IEC104_IO_ID_M_DP_NA_1: 'M_DP_NA_1 (double point report)', - IEC104_IO_ID_M_DP_TA_1: 'M_DP_TA_1 (double point report with timestamp) ' - '# 60870-4-101 only', - IEC104_IO_ID_M_ST_NA_1: 'M_ST_NA_1 (step control report)', - IEC104_IO_ID_M_ST_TA_1: 'M_ST_TA_1 (step control report with timestamp) ' - '# 60870-4-101 only', - IEC104_IO_ID_M_BO_NA_1: 'M_BO_NA_1 (bitmask 32 bit)', - IEC104_IO_ID_M_BO_TA_1: 'M_BO_TA_1 (bitmask 32 bit with timestamp) ' - '# 60870-4-101 only', - IEC104_IO_ID_M_ME_NA_1: 'M_ME_NA_1 (meas, normed value)', - IEC104_IO_ID_M_ME_TA_1: 'M_ME_TA_1 (meas, normed value with timestamp) ' - '# 60870-4-101 only', - IEC104_IO_ID_M_ME_NB_1: 'M_ME_NB_1 (meas, scaled value)', - IEC104_IO_ID_M_ME_TB_1: 'M_ME_TB_1 (meas, scaled value with timestamp) ' - '# 60870-4-101 only', - IEC104_IO_ID_M_ME_NC_1: 'M_ME_NC_1 (meas, shortened floating point value)', - IEC104_IO_ID_M_ME_TC_1: 'M_ME_TC_1 (meas, shortened floating point value ' - 'with timestamp) # 60870-4-101 only', - IEC104_IO_ID_M_IT_NA_1: 'M_IT_NA_1 (counter value)', - IEC104_IO_ID_M_IT_TA_1: 'M_IT_TA_1 (counter value with timestamp) ' - '# 60870-4-101 only', - IEC104_IO_ID_M_EP_TA_1: 'M_EP_TA_1 (protection event with timestamp) ' - '# 60870-4-101 only', - IEC104_IO_ID_M_EP_TB_1: 'M_EP_TB_1 (blocked protection trigger with ' - 'timestamp) # 60870-4-101 only', - IEC104_IO_ID_M_EP_TC_1: 'M_EP_TC_1 (blocked protection action with ' - 'timestamp) # 60870-4-101 only', - IEC104_IO_ID_M_PS_NA_1: 'M_PS_NA_1 (blocked single report with ' - 'change indication)', - IEC104_IO_ID_M_ME_ND_1: 'M_ME_ND_1 (meas, normed value, no quality ' - 'indication)', - IEC104_IO_ID_M_SP_TB_1: 'M_SP_TB_1 (single point report with CP56Time2a ' - 'time field)', - IEC104_IO_ID_M_DP_TB_1: 'M_DP_TB_1 (double point report with CP56Time2a ' - 'time field)', - IEC104_IO_ID_M_ST_TB_1: 'M_ST_TB_1 (step control report with CP56Time2a ' - 'time field)', - IEC104_IO_ID_M_BO_TB_1: 'M_BO_TB_1 (bitmask 32 bit with CP56Time2a time ' - 'field)', - IEC104_IO_ID_M_ME_TD_1: 'M_ME_TD_1 (meas, normed value with CP56Time2a ' - 'time field)', - IEC104_IO_ID_M_ME_TE_1: 'M_ME_TE_1 (meas, scaled value with CP56Time2a ' - 'time field)', - IEC104_IO_ID_M_ME_TF_1: 'M_ME_TF_1 (meas, shortened floating point value ' - 'with CP56Time2a time field)', - IEC104_IO_ID_M_IT_TB_1: 'M_IT_TB_1 (counter with CP56Time2a time field)', - IEC104_IO_ID_M_EP_TD_1: 'M_EP_TD_1 (protection event with CP56Time2a ' - 'time field)', - IEC104_IO_ID_M_EP_TE_1: 'M_EP_TE_1 (blocked protection trigger with ' - 'CP56Time2a time field)', - IEC104_IO_ID_M_EP_TF_1: 'M_EP_TF_1 (blocked protection action with ' - 'CP56Time2a time field)', - IEC104_IO_ID_C_SC_NA_1: 'C_SC_NA_1 (single command)', - IEC104_IO_ID_C_DC_NA_1: 'C_DC_NA_1 (double command)', - IEC104_IO_ID_C_RC_NA_1: 'C_RC_NA_1 (step control command)', - IEC104_IO_ID_C_SE_NA_1: 'C_SE_NA_1 (setpoint control command, ' - 'normed value)', - IEC104_IO_ID_C_SE_NB_1: 'C_SE_NB_1 (setpoint control command, ' - 'scaled value)', - IEC104_IO_ID_C_SE_NC_1: 'C_SE_NC_1 (setpoint control command, ' - 'shortened floating point value)', - IEC104_IO_ID_C_BO_NA_1: 'C_BO_NA_1 (bitmask 32 bit)', - IEC104_IO_ID_C_SC_TA_1: 'C_SC_TA_1 (single point command with ' - 'CP56Time2a time field)', - IEC104_IO_ID_C_DC_TA_1: 'C_DC_TA_1 (double point command with ' - 'CP56Time2a time field)', - IEC104_IO_ID_C_RC_TA_1: 'C_RC_TA_1 (step control command with ' - 'CP56Time2a time field)', - IEC104_IO_ID_C_SE_TA_1: 'C_SE_TA_1 (setpoint command, normed value with ' - 'CP56Time2a time field)', - IEC104_IO_ID_C_SE_TB_1: 'C_SE_TB_1 (setpoint command, scaled value with ' - 'CP56Time2a time field)', - IEC104_IO_ID_C_SE_TC_1: 'C_SE_TC_1 (setpoint command, shortened floating ' - 'point value with CP56Time2a time field)', - IEC104_IO_ID_C_BO_TA_1: 'C_BO_TA_1 (bitmask 32 command bit with ' - 'CP56Time2a time field)', - IEC104_IO_ID_M_EI_NA_1: 'M_EI_NA_1 (init done)', - IEC104_IO_ID_C_IC_NA_1: 'C_IC_NA_1 (general interrogation command)', - IEC104_IO_ID_C_CI_NA_1: 'C_CI_NA_1 (counter interrogation command)', - IEC104_IO_ID_C_RD_NA_1: 'C_RD_NA_1 (interrogation)', - IEC104_IO_ID_C_CS_NA_1: 'C_CS_NA_1 (time synchronisation command)', - IEC104_IO_ID_C_TS_NA_1: 'C_TS_NA_1 (test command) # 60870-4-101 only', - IEC104_IO_ID_C_RP_NA_1: 'C_RP_NA_1 (process reset command)', - IEC104_IO_ID_C_CD_NA_1: 'C_CD_NA_1 (meas telegram transit time command) ' - '# 60870-4-101 only', - IEC104_IO_ID_C_TS_TA_1: 'C_TS_TA_1 (test command with CP56Time2a ' - 'time field)', - IEC104_IO_ID_P_ME_NA_1: 'P_ME_NA_1 (meas parameter, normed value)', - IEC104_IO_ID_P_ME_NB_1: 'P_ME_NB_1 (meas parameter, scaled value)', - IEC104_IO_ID_P_ME_NC_1: 'P_ME_NC_1 (meas parameter, shortened floating ' - 'point value)', - IEC104_IO_ID_P_AC_NA_1: 'P_AC_NA_1 (parameter for activation)', - IEC104_IO_ID_F_FR_NA_1: 'F_FR_NA_1 (file ready)', - IEC104_IO_ID_F_SR_NA_1: 'F_SR_NA_1 (section ready)', - IEC104_IO_ID_F_SC_NA_1: 'F_SC_NA_1 (query directory, selection, section)', - IEC104_IO_ID_F_LS_NA_1: 'F_LS_NA_1 (last part/segment)', - IEC104_IO_ID_F_AF_NA_1: 'F_AF_NA_1 (file/section acknowledgement)', - IEC104_IO_ID_F_SG_NA_1: 'F_SG_NA_1 (segment)', - IEC104_IO_ID_F_DR_TA_1: 'F_DR_TA_1 (directory)', - IEC104_IO_ID_F_SC_NB_1: 'F_SC_NB_1 (query log - request archive file)' -} -_dict_add_reserved_range(IEC104_IO_DESCRIPTIONS, 22, 29) -_dict_add_reserved_range(IEC104_IO_DESCRIPTIONS, 41, 44) -_dict_add_reserved_range(IEC104_IO_DESCRIPTIONS, 52, 57) -_dict_add_reserved_range(IEC104_IO_DESCRIPTIONS, 65, 69) -_dict_add_reserved_range(IEC104_IO_DESCRIPTIONS, 71, 99) -_dict_add_reserved_range(IEC104_IO_DESCRIPTIONS, 108, 109) -_dict_add_reserved_range(IEC104_IO_DESCRIPTIONS, 114, 119) - -IEC104_IO_NAMES = { - 0: 'undefined', - IEC104_IO_ID_M_SP_NA_1: 'M_SP_NA_1', - IEC104_IO_ID_M_SP_TA_1: 'M_SP_TA_1', - IEC104_IO_ID_M_DP_NA_1: 'M_DP_NA_1', - IEC104_IO_ID_M_DP_TA_1: 'M_DP_TA_1', - IEC104_IO_ID_M_ST_NA_1: 'M_ST_NA_1', - IEC104_IO_ID_M_ST_TA_1: 'M_ST_TA_1', - IEC104_IO_ID_M_BO_NA_1: 'M_BO_NA_1', - IEC104_IO_ID_M_BO_TA_1: 'M_BO_TA_1', - IEC104_IO_ID_M_ME_NA_1: 'M_ME_NA_1', - IEC104_IO_ID_M_ME_TA_1: 'M_ME_TA_1', - IEC104_IO_ID_M_ME_NB_1: 'M_ME_NB_1', - IEC104_IO_ID_M_ME_TB_1: 'M_ME_TB_1', - IEC104_IO_ID_M_ME_NC_1: 'M_ME_NC_1', - IEC104_IO_ID_M_ME_TC_1: 'M_ME_TC_1', - IEC104_IO_ID_M_IT_NA_1: 'M_IT_NA_1', - IEC104_IO_ID_M_IT_TA_1: 'M_IT_TA_1', - IEC104_IO_ID_M_EP_TA_1: 'M_EP_TA_1', - IEC104_IO_ID_M_EP_TB_1: 'M_EP_TB_1', - IEC104_IO_ID_M_EP_TC_1: 'M_EP_TC_1', - IEC104_IO_ID_M_PS_NA_1: 'M_PS_NA_1', - IEC104_IO_ID_M_ME_ND_1: 'M_ME_ND_1', - IEC104_IO_ID_M_SP_TB_1: 'M_SP_TB_1', - IEC104_IO_ID_M_DP_TB_1: 'M_DP_TB_1', - IEC104_IO_ID_M_ST_TB_1: 'M_ST_TB_1', - IEC104_IO_ID_M_BO_TB_1: 'M_BO_TB_1', - IEC104_IO_ID_M_ME_TD_1: 'M_ME_TD_1', - IEC104_IO_ID_M_ME_TE_1: 'M_ME_TE_1', - IEC104_IO_ID_M_ME_TF_1: 'M_ME_TF_1', - IEC104_IO_ID_M_IT_TB_1: 'M_IT_TB_1', - IEC104_IO_ID_M_EP_TD_1: 'M_EP_TD_1', - IEC104_IO_ID_M_EP_TE_1: 'M_EP_TE_1', - IEC104_IO_ID_M_EP_TF_1: 'M_EP_TF_1', - IEC104_IO_ID_C_SC_NA_1: 'C_SC_NA_1', - IEC104_IO_ID_C_DC_NA_1: 'C_DC_NA_1', - IEC104_IO_ID_C_RC_NA_1: 'C_RC_NA_1', - IEC104_IO_ID_C_SE_NA_1: 'C_SE_NA_1', - IEC104_IO_ID_C_SE_NB_1: 'C_SE_NB_1', - IEC104_IO_ID_C_SE_NC_1: 'C_SE_NC_1', - IEC104_IO_ID_C_BO_NA_1: 'C_BO_NA_1', - IEC104_IO_ID_C_SC_TA_1: 'C_SC_TA_1', - IEC104_IO_ID_C_DC_TA_1: 'C_DC_TA_1', - IEC104_IO_ID_C_RC_TA_1: 'C_RC_TA_1', - IEC104_IO_ID_C_SE_TA_1: 'C_SE_TA_1', - IEC104_IO_ID_C_SE_TB_1: 'C_SE_TB_1', - IEC104_IO_ID_C_SE_TC_1: 'C_SE_TC_1', - IEC104_IO_ID_C_BO_TA_1: 'C_BO_TA_1', - IEC104_IO_ID_M_EI_NA_1: 'M_EI_NA_1', - IEC104_IO_ID_C_IC_NA_1: 'C_IC_NA_1', - IEC104_IO_ID_C_CI_NA_1: 'C_CI_NA_1', - IEC104_IO_ID_C_RD_NA_1: 'C_RD_NA_1', - IEC104_IO_ID_C_CS_NA_1: 'C_CS_NA_1', - IEC104_IO_ID_C_TS_NA_1: 'C_TS_NA_1', - IEC104_IO_ID_C_RP_NA_1: 'C_RP_NA_1', - IEC104_IO_ID_C_CD_NA_1: 'C_CD_NA_1', - IEC104_IO_ID_C_TS_TA_1: 'C_TS_TA_1', - IEC104_IO_ID_P_ME_NA_1: 'P_ME_NA_1', - IEC104_IO_ID_P_ME_NB_1: 'P_ME_NB_1', - IEC104_IO_ID_P_ME_NC_1: 'P_ME_NC_1', - IEC104_IO_ID_P_AC_NA_1: 'P_AC_NA_1', - IEC104_IO_ID_F_FR_NA_1: 'F_FR_NA_1', - IEC104_IO_ID_F_SR_NA_1: 'F_SR_NA_1', - IEC104_IO_ID_F_SC_NA_1: 'F_SC_NA_1', - IEC104_IO_ID_F_LS_NA_1: 'F_LS_NA_1', - IEC104_IO_ID_F_AF_NA_1: 'F_AF_NA_1', - IEC104_IO_ID_F_SG_NA_1: 'F_SG_NA_1', - IEC104_IO_ID_F_DR_TA_1: 'F_DR_TA_1', - IEC104_IO_ID_F_SC_NB_1: 'F_SC_NB_1' -} -_dict_add_reserved_range(IEC104_IO_NAMES, 22, 29) -_dict_add_reserved_range(IEC104_IO_NAMES, 41, 44) -_dict_add_reserved_range(IEC104_IO_NAMES, 52, 57) -_dict_add_reserved_range(IEC104_IO_NAMES, 65, 69) -_dict_add_reserved_range(IEC104_IO_NAMES, 71, 99) -_dict_add_reserved_range(IEC104_IO_NAMES, 108, 109) -_dict_add_reserved_range(IEC104_IO_NAMES, 114, 119) - - -class IEC104_IO_InvalidPayloadException(Exception): - """ - raised if payload is not of the same type, raw() or a child of IEC104_APDU - """ - pass - - -class IEC104_IO_Packet(Packet): - """ - base class of all information object representations - """ - DEFINED_IN_IEC_101 = 0x01 - DEFINED_IN_IEC_104 = 0x02 - - _DEFINED_IN = [] - - def guess_payload_class(self, payload): - return conf.padding_layer - - _IEC104_IO_TYPE_ID = IEC104_IO_ID_UNDEFINED - - def iec104_io_type_id(self): - """ - get individual type id of the information object instance - :return: information object type id (IEC104_IO_ID_*) - """ - return self._IEC104_IO_TYPE_ID - - def defined_for_iec_101(self): - """ - information object ASDU allowed for IEC 60870-5-101 - :return: True if the information object is defined within - IEC 60870-5-101, else False - """ - return IEC104_IO_Packet.DEFINED_IN_IEC_101 in self._DEFINED_IN - - def defined_for_iec_104(self): - """ - information object ASDU allowed for IEC 60870-5-104 - :return: True if the information object is defined within - IEC 60870-5-104, else False - """ - return IEC104_IO_Packet.DEFINED_IN_IEC_104 in self._DEFINED_IN - - -class IEC104_IO_M_SP_NA_1(IEC104_IO_Packet): - """ - single-point information without time tag] - - EN 60870-5-101:2003, sec. 7.3.1.1 (p. 58) - """ - name = 'M_SP_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_SP_NA_1 - - fields_desc = IEC104_IE_SIQ.informantion_element_fields - - -class IEC104_IO_M_SP_TA_1(IEC104_IO_Packet): - """ - single-point information with time tag - - EN 60870-5-101:2003, sec. 7.3.1.2 (p. 59) - """ - name = 'M_SP_TA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_SP_TA_1 - - fields_desc = IEC104_IE_SIQ.informantion_element_fields + \ - IEC104_IE_CP24TIME2A.informantion_element_fields - - -class IEC104_IO_M_DP_NA_1(IEC104_IO_Packet): - """ - double-point information without time tag - - EN 60870-5-101:2003, sec. 7.3.1.3 (p. 60) - """ - name = 'M_DP_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_DP_NA_1 - - fields_desc = IEC104_IE_DIQ.informantion_element_fields - - -class IEC104_IO_M_DP_TA_1(IEC104_IO_Packet): - """ - double-point information with time tag - - EN 60870-5-101:2003, sec. 7.3.1.4 (p. 61) - """ - name = 'M_DP_TA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_DP_TA_1 - - fields_desc = IEC104_IE_DIQ.informantion_element_fields + \ - IEC104_IE_CP24TIME2A.informantion_element_fields - - -class IEC104_IO_M_ST_NA_1(IEC104_IO_Packet): - """ - step position information - - EN 60870-5-101:2003, sec. 7.3.1.5 (p. 62) - """ - name = 'M_ST_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_ST_NA_1 - - fields_desc = IEC104_IE_VTI.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields - - -class IEC104_IO_M_ST_TA_1(IEC104_IO_Packet): - """ - step position information with time tag - - EN 60870-5-101:2003, sec. 7.3.1.6 (p. 63) - """ - name = 'M_ST_TA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_ST_TA_1 - - fields_desc = IEC104_IE_VTI.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields + \ - IEC104_IE_CP24TIME2A.informantion_element_fields - - -class IEC104_IO_M_BO_NA_1(IEC104_IO_Packet): - """ - bitstring of 32 bit - - EN 60870-5-101:2003, sec. 7.3.1.7 (p. 64) - """ - name = 'M_BO_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_BO_NA_1 - - fields_desc = IEC104_IE_BSI.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields - - -class IEC104_IO_M_BO_TA_1(IEC104_IO_Packet): - """ - bitstring of 32 bit with time tag - - EN 60870-5-101:2003, sec. 7.3.1.8 (p. 66) - """ - name = 'M_BO_TA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_BO_TA_1 - - fields_desc = IEC104_IE_BSI.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields + \ - IEC104_IE_CP24TIME2A.informantion_element_fields - - -class IEC104_IO_M_ME_NA_1(IEC104_IO_Packet): - """ - measured value, normalized value - - EN 60870-5-101:2003, sec. 7.3.1.9 (p. 67) - """ - name = 'M_ME_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_ME_NA_1 - - fields_desc = IEC104_IE_NVA.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields - - -class IEC104_IO_M_ME_TA_1(IEC104_IO_Packet): - """ - measured value, normalized value with time tag - - EN 60870-5-101:2003, sec. 7.3.1.10 (p. 68) - """ - name = 'M_ME_TA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_ME_TA_1 - - fields_desc = IEC104_IE_NVA.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields + \ - IEC104_IE_CP24TIME2A.informantion_element_fields - - -class IEC104_IO_M_ME_NB_1(IEC104_IO_Packet): - """ - measured value, scaled value - - EN 60870-5-101:2003, sec. 7.3.1.11 (p. 69) - """ - name = 'M_ME_NB_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_ME_NB_1 - - fields_desc = IEC104_IE_SVA.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields - - -class IEC104_IO_M_ME_TB_1(IEC104_IO_Packet): - """ - measured value, scaled value with time tag - - EN 60870-5-101:2003, sec. 7.3.1.12 (p. 71) - """ - name = 'M_ME_TB_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_ME_TB_1 - - fields_desc = IEC104_IE_SVA.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields + \ - IEC104_IE_CP24TIME2A.informantion_element_fields - - -class IEC104_IO_M_ME_NC_1(IEC104_IO_Packet): - """ - measured value, short floating point number - - EN 60870-5-101:2003, sec. 7.3.1.13 (p. 72) - """ - name = 'M_ME_NC_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_ME_NC_1 - - fields_desc = IEC104_IE_R32_IEEE_STD_754.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields - - -class IEC104_IO_M_ME_TC_1(IEC104_IO_Packet): - """ - measured value, short floating point number with time tag - - EN 60870-5-101:2003, sec. 7.3.1.14 (p. 74) - """ - name = 'M_ME_TC_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_ME_TC_1 - - fields_desc = IEC104_IE_R32_IEEE_STD_754.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields + \ - IEC104_IE_CP24TIME2A.informantion_element_fields - - -class IEC104_IO_M_IT_NA_1(IEC104_IO_Packet): - """ - integrated totals - - EN 60870-5-101:2003, sec. 7.3.1.15 (p. 75) - """ - name = 'M_IT_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_IT_NA_1 - - fields_desc = IEC104_IE_BCR.informantion_element_fields - - -class IEC104_IO_M_IT_TA_1(IEC104_IO_Packet): - """ - integrated totals with time tag - - EN 60870-5-101:2003, sec. 7.3.1.16 (p. 77) - """ - name = 'M_IT_TA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_IT_TA_1 - - fields_desc = IEC104_IE_BCR.informantion_element_fields + \ - IEC104_IE_CP24TIME2A.informantion_element_fields - - -class IEC104_IO_M_EP_TA_1(IEC104_IO_Packet): - """ - event of protection equipment with time tag - - EN 60870-5-101:2003, sec. 7.3.1.17 (p. 78) - """ - name = 'M_EP_TA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_EP_TA_1 - - fields_desc = IEC104_IE_SEP.informantion_element_fields + \ - IEC104_IE_CP16TIME2A_ELAPSED.informantion_element_fields + \ - IEC104_IE_CP24TIME2A.informantion_element_fields - - -class IEC104_IO_M_EP_TB_1(IEC104_IO_Packet): - """ - packed start events of protection equipment with time tag - - EN 60870-5-101:2003, sec. 7.3.1.18 (p. 79) - """ - name = 'M_EP_TB_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_EP_TB_1 - - fields_desc = IEC104_IE_SPE.informantion_element_fields + \ - IEC104_IE_QDP.informantion_element_fields + \ - IEC104_IE_CP16TIME2A_PROTECTION_ACTIVE.\ - informantion_element_fields + \ - IEC104_IE_CP24TIME2A.informantion_element_fields - - -class IEC104_IO_M_EP_TC_1(IEC104_IO_Packet): - """ - packed output circuit information of protection equipment with time tag - - EN 60870-5-101:2003, sec. 7.3.1.19 (p. 80) - """ - name = 'M_EP_TC_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_EP_TC_1 - - fields_desc = IEC104_IE_OCI.informantion_element_fields + \ - IEC104_IE_QDP.informantion_element_fields + \ - IEC104_IE_CP16TIME2A_PROTECTION_COMMAND.\ - informantion_element_fields + \ - IEC104_IE_CP24TIME2A.informantion_element_fields - - -class IEC104_IO_M_PS_NA_1(IEC104_IO_Packet): - """ - packed single-point information with status change detection - - EN 60870-5-101:2003, sec. 7.3.1.20 (p. 81) - """ - name = 'M_PS_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_PS_NA_1 - - fields_desc = IEC104_IE_SCD.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields - - -class IEC104_IO_M_ME_ND_1(IEC104_IO_Packet): - """ - measured value, normalized value without quality descriptor - - EN 60870-5-101:2003, sec. 7.3.1.21 (p. 83) - """ - name = 'M_ME_ND_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_ME_ND_1 - - fields_desc = IEC104_IE_NVA.informantion_element_fields - - -class IEC104_IO_M_SP_TB_1(IEC104_IO_Packet): - """ - single-point information with time tag cp56time2a - - EN 60870-5-101:2003, sec. 7.3.1.22 (p. 84) - """ - name = 'M_SP_TB_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_SP_TB_1 - - fields_desc = IEC104_IE_SIQ.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_M_DP_TB_1(IEC104_IO_Packet): - """ - double-point information with time tag cp56time2a - - EN 60870-5-101:2003, sec. 7.3.1.23 (p. 85) - """ - name = 'M_DP_TB_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_DP_TB_1 - - fields_desc = IEC104_IE_DIQ.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_M_ST_TB_1(IEC104_IO_Packet): - """ - step position information with time tag cp56time2a - - EN 60870-5-101:2003, sec. 7.3.1.24 (p. 87) - """ - name = 'M_ST_TB_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_ST_TB_1 - - fields_desc = IEC104_IE_VTI.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_M_BO_TB_1(IEC104_IO_Packet): - """ - bitstring of 32 bits with time tag cp56time2a - - EN 60870-5-101:2003, sec. 7.3.1.25 (p. 89) - """ - name = 'M_BO_TB_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_BO_TB_1 - - fields_desc = IEC104_IE_BSI.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_M_ME_TD_1(IEC104_IO_Packet): - """ - measured value, normalized value with time tag cp56time2a - - EN 60870-5-101:2003, sec. 7.3.1.26 (p. 91) - """ - name = 'M_ME_TD_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_ME_TD_1 - - fields_desc = IEC104_IE_NVA.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_M_ME_TE_1(IEC104_IO_Packet): - """ - measured value, scaled value with time tag cp56time2a - - EN 60870-5-101:2003, sec. 7.3.1.27 (p. 93) - """ - name = 'M_ME_TE_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_ME_TE_1 - - fields_desc = IEC104_IE_SVA.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_M_ME_TF_1(IEC104_IO_Packet): - """ - measured value, short floating point number with time tag cp56time2a - - EN 60870-5-101:2003, sec. 7.3.1.28 (p. 95) - """ - name = 'M_ME_TF_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_ME_TF_1 - - fields_desc = IEC104_IE_R32_IEEE_STD_754.informantion_element_fields + \ - IEC104_IE_QDS.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_M_IT_TB_1(IEC104_IO_Packet): - """ - integrated totals with time tag cp56time2a - - EN 60870-5-101:2003, sec. 7.3.1.29 (p. 97) - """ - name = 'M_IT_TB_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_IT_TB_1 - - fields_desc = IEC104_IE_BCR.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_M_EP_TD_1(IEC104_IO_Packet): - """ - event of protection equipment with time tag cp56time2a - - EN 60870-5-101:2003, sec. 7.3.1.30 (p. 99) - """ - name = 'M_EP_TD_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_EP_TD_1 - - fields_desc = IEC104_IE_SEP.informantion_element_fields + \ - IEC104_IE_CP16TIME2A_ELAPSED.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_M_EP_TE_1(IEC104_IO_Packet): - """ - packed start events of protection equipment with time tag cp56time2a - - EN 60870-5-101:2003, sec. 7.3.1.31 (p. 100) - """ - name = 'M_EP_TE_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_EP_TE_1 - - fields_desc = IEC104_IE_SPE.informantion_element_fields + \ - IEC104_IE_QDP.informantion_element_fields + \ - IEC104_IE_CP16TIME2A_PROTECTION_ACTIVE.\ - informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_M_EP_TF_1(IEC104_IO_Packet): - """ - packed output circuit information of protection equipment with - time tag cp56time2a - - EN 60870-5-101:2003, sec. 7.3.1.32 (p. 101) - """ - name = 'M_EP_TF_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_EP_TF_1 - - fields_desc = IEC104_IE_OCI.informantion_element_fields + \ - IEC104_IE_QDP.informantion_element_fields + \ - IEC104_IE_CP16TIME2A_PROTECTION_COMMAND.\ - informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_C_SC_NA_1(IEC104_IO_Packet): - """ - single command - - EN 60870-5-101:2003, sec. 7.3.2.1 (p. 102) - """ - name = 'C_SC_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_SC_NA_1 - - fields_desc = IEC104_IE_SCO.informantion_element_fields - - -class IEC104_IO_C_DC_NA_1(IEC104_IO_Packet): - """ - double command - - EN 60870-5-101:2003, sec. 7.3.2.2 (p. 102) - """ - name = 'C_DC_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_DC_NA_1 - - fields_desc = IEC104_IE_DCO.informantion_element_fields - - -class IEC104_IO_C_RC_NA_1(IEC104_IO_Packet): - """ - regulating step command - - EN 60870-5-101:2003, sec. 7.3.2.3 (p. 103) - """ - name = 'C_RC_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_RC_NA_1 - - fields_desc = IEC104_IE_RCO.informantion_element_fields - - -class IEC104_IO_C_SE_NA_1(IEC104_IO_Packet): - """ - set-point command, normalized value - - EN 60870-5-101:2003, sec. 7.3.2.4 (p. 104) - """ - name = 'C_SE_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_SE_NA_1 - - fields_desc = IEC104_IE_NVA.informantion_element_fields + \ - IEC104_IE_QOS.informantion_element_fields - - -class IEC104_IO_C_SE_NB_1(IEC104_IO_Packet): - """ - set-point command, scaled value - - EN 60870-5-101:2003, sec. 7.3.2.5 (p. 104) - """ - name = 'C_SE_NB_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_SE_NB_1 - - fields_desc = IEC104_IE_SVA.informantion_element_fields + \ - IEC104_IE_QOS.informantion_element_fields - - -class IEC104_IO_C_SE_NC_1(IEC104_IO_Packet): - """ - set-point command, short floating point number - - EN 60870-5-101:2003, sec. 7.3.2.6 (p. 105) - """ - name = 'C_SE_NC_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_SE_NC_1 - - fields_desc = IEC104_IE_R32_IEEE_STD_754.informantion_element_fields + \ - IEC104_IE_QOS.informantion_element_fields - - -class IEC104_IO_C_BO_NA_1(IEC104_IO_Packet): - """ - bitstring of 32 bit - - EN 60870-5-101:2003, sec. 7.3.2.7 (p. 106) - """ - name = 'C_BO_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_BO_NA_1 - - fields_desc = IEC104_IE_BSI.informantion_element_fields - - -class IEC104_IO_M_EI_NA_1(IEC104_IO_Packet): - """ - end of initialization - - EN 60870-5-101:2003, sec. 7.3.3.1 (p. 106) - """ - name = 'M_EI_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_M_EI_NA_1 - - fields_desc = IEC104_IE_COI.informantion_element_fields - - -class IEC104_IO_C_IC_NA_1(IEC104_IO_Packet): - """ - interrogation command - - EN 60870-5-101:2003, sec. 7.3.4.1 (p. 107) - """ - name = 'C_IC_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_IC_NA_1 - - fields_desc = IEC104_IE_QOI.informantion_element_fields - - -class IEC104_IO_C_CI_NA_1(IEC104_IO_Packet): - """ - counter interrogation command - - EN 60870-5-101:2003, sec. 7.3.4.2 (p. 108) - """ - name = 'C_CI_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_CI_NA_1 - - fields_desc = IEC104_IE_QCC.informantion_element_fields - - -class IEC104_IO_C_RD_NA_1(IEC104_IO_Packet): - """ - read command - - EN 60870-5-101:2003, sec. 7.3.4.3 (p. 108) - """ - name = 'C_RD_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_RD_NA_1 - - # this information object contains no data - fields_desc = [] - - -class IEC104_IO_C_CS_NA_1(IEC104_IO_Packet): - """ - clock synchronization command - - EN 60870-5-101:2003, sec. 7.3.4.4 (p. 109) - """ - name = 'C_CS_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_CS_NA_1 - - fields_desc = IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_C_TS_NA_1(IEC104_IO_Packet): - """ - test command - - EN 60870-5-101:2003, sec. 7.3.4.5 (p. 110) - """ - name = 'C_TS_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_TS_NA_1 - - fields_desc = IEC104_IE_FBP.informantion_element_fields - - -class IEC104_IO_C_RP_NA_1(IEC104_IO_Packet): - """ - reset process command - - EN 60870-5-101:2003, sec. 7.3.4.6 (p. 110) - """ - name = 'C_RP_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_RP_NA_1 - - fields_desc = IEC104_IE_QRP.informantion_element_fields - - -class IEC104_IO_C_CD_NA_1(IEC104_IO_Packet): - """ - (telegram) delay acquisition command - - EN 60870-5-101:2003, sec. 7.3.4.7 (p. 111) - """ - name = 'C_CD_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_CD_NA_1 - - fields_desc = IEC104_IE_CP16TIME2A.informantion_element_fields - - -class IEC104_IO_P_ME_NA_1(IEC104_IO_Packet): - """ - parameter of measured values, normalized value - - EN 60870-5-101:2003, sec. 7.3.5.1 (p. 112) - """ - name = 'P_ME_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_P_ME_NA_1 - - fields_desc = IEC104_IE_NVA.informantion_element_fields + \ - IEC104_IE_QPM.informantion_element_fields - - -class IEC104_IO_P_ME_NB_1(IEC104_IO_Packet): - """ - parameter of measured values, scaled value - - EN 60870-5-101:2003, sec. 7.3.5.2 (p. 113) - """ - name = 'P_ME_NB_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_P_ME_NB_1 - - fields_desc = IEC104_IE_SVA.informantion_element_fields + \ - IEC104_IE_QPM.informantion_element_fields - - -class IEC104_IO_P_ME_NC_1(IEC104_IO_Packet): - """ - parameter of measured values, short floating point number - - EN 60870-5-101:2003, sec. 7.3.5.3 (p. 114) - """ - name = 'P_ME_NC_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_P_ME_NC_1 - - fields_desc = IEC104_IE_R32_IEEE_STD_754.informantion_element_fields + \ - IEC104_IE_QPM.informantion_element_fields - - -class IEC104_IO_P_AC_NA_1(IEC104_IO_Packet): - """ - parameter activation - - EN 60870-5-101:2003, sec. 7.3.5.4 (p. 115) - """ - name = 'P_AC_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_P_AC_NA_1 - - fields_desc = IEC104_IE_QPA.informantion_element_fields - - -class IEC104_IO_F_FR_NA_1(IEC104_IO_Packet): - """ - file ready - - EN 60870-5-101:2003, sec. 7.3.6.1 (p. 116) - """ - name = 'F_FR_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_F_FR_NA_1 - - fields_desc = IEC104_IE_NOF.informantion_element_fields + \ - IEC104_IE_LOF.informantion_element_fields + \ - IEC104_IE_FRQ.informantion_element_fields - - -class IEC104_IO_F_SR_NA_1(IEC104_IO_Packet): - """ - section ready - - EN 60870-5-101:2003, sec. 7.3.6.2 (p. 117) - """ - name = 'F_SR_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_F_SR_NA_1 - - fields_desc = IEC104_IE_NOF.informantion_element_fields + \ - IEC104_IE_NOS.informantion_element_fields + \ - IEC104_IE_LOF.informantion_element_fields + \ - IEC104_IE_SRQ.informantion_element_fields - - -class IEC104_IO_F_SC_NA_1(IEC104_IO_Packet): - """ - call directory, select file, call file, call section - - EN 60870-5-101:2003, sec. 7.3.6.3 (p. 118) - """ - name = 'F_SC_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_F_SC_NA_1 - - fields_desc = IEC104_IE_NOF.informantion_element_fields + \ - IEC104_IE_NOS.informantion_element_fields + \ - IEC104_IE_SCQ.informantion_element_fields - - -class IEC104_IO_F_LS_NA_1(IEC104_IO_Packet): - """ - last section, last segment - - EN 60870-5-101:2003, sec. 7.3.6.4 (p. 119) - """ - name = 'F_LS_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_F_LS_NA_1 - - fields_desc = IEC104_IE_NOF.informantion_element_fields + \ - IEC104_IE_NOS.informantion_element_fields + \ - IEC104_IE_LSQ.informantion_element_fields + \ - IEC104_IE_CHS.informantion_element_fields - - -class IEC104_IO_F_AF_NA_1(IEC104_IO_Packet): - """ - ack file, ack section - - EN 60870-5-101:2003, sec. 7.3.6.5 (p. 119) - """ - name = 'F_AF_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_F_AF_NA_1 - - fields_desc = IEC104_IE_NOF.informantion_element_fields + \ - IEC104_IE_NOS.informantion_element_fields + \ - IEC104_IE_AFQ.informantion_element_fields - - -class IEC104_IO_F_SG_NA_1(IEC104_IO_Packet): - """ - file / section data octets - - EN 60870-5-101:2003, sec. 7.3.6.6 (p. 120) - """ - name = 'F_SG_NA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_F_SG_NA_1 - - fields_desc = IEC104_IE_NOF.informantion_element_fields + \ - IEC104_IE_NOS.informantion_element_fields + [ - BitFieldLenField('segment_length', None, 8, - length_of='data'), # repr IEC104_IE_LOS - XStrLenField('data', '', - length_from=lambda pkt: pkt.segment_length) - ] - - -class IEC104_IO_F_DR_TA_1(IEC104_IO_Packet): - """ - directory - - EN 60870-5-101:2003, sec. 7.3.6.7 (p. 121) - """ - name = 'F_DR_TA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_101, - IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_F_DR_TA_1 - - fields_desc = IEC104_IE_NOF.informantion_element_fields + \ - IEC104_IE_LOF.informantion_element_fields + \ - IEC104_IE_SOF.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_C_SC_TA_1(IEC104_IO_Packet): - """ - single command with timestamp CP56Time2a - - EN 60870-5-104:2006, sec. 8.1 (p. 37) - """ - name = 'C_SC_TA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_SC_TA_1 - - fields_desc = IEC104_IE_SCO.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_C_DC_TA_1(IEC104_IO_Packet): - """ - double command with timestamp CP56Time2a - - EN 60870-5-104:2006, sec. 8.2 (p. 38) - """ - name = 'C_DC_TA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_DC_TA_1 - - fields_desc = IEC104_IE_DCO.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_C_RC_TA_1(IEC104_IO_Packet): - """ - step control command with timestamp CP56Time2a - - EN 60870-5-104:2006, sec. 8.3 (p. 39) - """ - name = 'C_RC_TA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_RC_TA_1 - - fields_desc = IEC104_IE_RCO.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_C_SE_TA_1(IEC104_IO_Packet): - """ - set point command, normed value with timestamp CP56Time2a - - EN 60870-5-104:2006, sec. 8.4 (p. 40) - """ - name = 'C_SE_TA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_SE_TA_1 - - fields_desc = IEC104_IE_NVA.informantion_element_fields + \ - IEC104_IE_QOS.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_C_SE_TB_1(IEC104_IO_Packet): - """ - set point command, scaled value with timestamp CP56Time2a - - EN 60870-5-104:2006, sec. 8.5 (p. 41) - """ - name = 'C_SE_TB_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_SE_TB_1 - - fields_desc = IEC104_IE_SVA.informantion_element_fields + \ - IEC104_IE_QOS.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_C_SE_TC_1(IEC104_IO_Packet): - """ - set point command, shortened floating point value with timestamp CP56Time2a - - EN 60870-5-104:2006, sec. 8.6 (p. 42) - """ - name = 'C_SE_TC_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_SE_TC_1 - - fields_desc = IEC104_IE_R32_IEEE_STD_754.informantion_element_fields + \ - IEC104_IE_QOS.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_C_BO_TA_1(IEC104_IO_Packet): - """ - bitmask 32 bit with timestamp CP56Time2a - - EN 60870-5-104:2006, sec. 8.7 (p. 43) - """ - name = 'C_BO_TA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_BO_TA_1 - - fields_desc = IEC104_IE_BSI.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_C_TS_TA_1(IEC104_IO_Packet): - """ - test command with timestamp CP56Time2a - - EN 60870-5-104:2006, sec. 8.8 (p. 44) - """ - name = 'C_TS_TA_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_C_TS_TA_1 - - fields_desc = IEC104_IE_TSC.informantion_element_fields + \ - IEC104_IE_CP56TIME2A.informantion_element_fields - - -class IEC104_IO_F_SC_NB_1(IEC104_IO_Packet): - """ - request archive file - - EN 60870-5-104:2006, sec. 8.9 (p. 45) - """ - name = 'F_SC_NB_1' - - _DEFINED_IN = [IEC104_IO_Packet.DEFINED_IN_IEC_104] - _IEC104_IO_TYPE_ID = IEC104_IO_ID_F_SC_NB_1 - - fields_desc = IEC104_IE_NOF.informantion_element_fields + \ - IEC104_IE_CP56TIME2A_START_TIME.\ - informantion_element_fields + \ - IEC104_IE_CP56TIME2A_STOP_TIME.informantion_element_fields - - -IEC104_IO_CLASSES = { - IEC104_IO_ID_M_SP_NA_1: IEC104_IO_M_SP_NA_1, - IEC104_IO_ID_M_SP_TA_1: IEC104_IO_M_SP_TA_1, - IEC104_IO_ID_M_DP_NA_1: IEC104_IO_M_DP_NA_1, - IEC104_IO_ID_M_DP_TA_1: IEC104_IO_M_DP_TA_1, - IEC104_IO_ID_M_ST_NA_1: IEC104_IO_M_ST_NA_1, - IEC104_IO_ID_M_ST_TA_1: IEC104_IO_M_ST_TA_1, - IEC104_IO_ID_M_BO_NA_1: IEC104_IO_M_BO_NA_1, - IEC104_IO_ID_M_BO_TA_1: IEC104_IO_M_BO_TA_1, - IEC104_IO_ID_M_ME_NA_1: IEC104_IO_M_ME_NA_1, - IEC104_IO_ID_M_ME_TA_1: IEC104_IO_M_ME_TA_1, - IEC104_IO_ID_M_ME_NB_1: IEC104_IO_M_ME_NB_1, - IEC104_IO_ID_M_ME_TB_1: IEC104_IO_M_ME_TB_1, - IEC104_IO_ID_M_ME_NC_1: IEC104_IO_M_ME_NC_1, - IEC104_IO_ID_M_ME_TC_1: IEC104_IO_M_ME_TC_1, - IEC104_IO_ID_M_IT_NA_1: IEC104_IO_M_IT_NA_1, - IEC104_IO_ID_M_IT_TA_1: IEC104_IO_M_IT_TA_1, - IEC104_IO_ID_M_EP_TA_1: IEC104_IO_M_EP_TA_1, - IEC104_IO_ID_M_EP_TB_1: IEC104_IO_M_EP_TB_1, - IEC104_IO_ID_M_EP_TC_1: IEC104_IO_M_EP_TC_1, - IEC104_IO_ID_M_PS_NA_1: IEC104_IO_M_PS_NA_1, - IEC104_IO_ID_M_ME_ND_1: IEC104_IO_M_ME_ND_1, - IEC104_IO_ID_M_SP_TB_1: IEC104_IO_M_SP_TB_1, - IEC104_IO_ID_M_DP_TB_1: IEC104_IO_M_DP_TB_1, - IEC104_IO_ID_M_ST_TB_1: IEC104_IO_M_ST_TB_1, - IEC104_IO_ID_M_BO_TB_1: IEC104_IO_M_BO_TB_1, - IEC104_IO_ID_M_ME_TD_1: IEC104_IO_M_ME_TD_1, - IEC104_IO_ID_M_ME_TE_1: IEC104_IO_M_ME_TE_1, - IEC104_IO_ID_M_ME_TF_1: IEC104_IO_M_ME_TF_1, - IEC104_IO_ID_M_IT_TB_1: IEC104_IO_M_IT_TB_1, - IEC104_IO_ID_M_EP_TD_1: IEC104_IO_M_EP_TD_1, - IEC104_IO_ID_M_EP_TE_1: IEC104_IO_M_EP_TE_1, - IEC104_IO_ID_M_EP_TF_1: IEC104_IO_M_EP_TF_1, - IEC104_IO_ID_C_SC_NA_1: IEC104_IO_C_SC_NA_1, - IEC104_IO_ID_C_DC_NA_1: IEC104_IO_C_DC_NA_1, - IEC104_IO_ID_C_RC_NA_1: IEC104_IO_C_RC_NA_1, - IEC104_IO_ID_C_SE_NA_1: IEC104_IO_C_SE_NA_1, - IEC104_IO_ID_C_SE_NB_1: IEC104_IO_C_SE_NB_1, - IEC104_IO_ID_C_SE_NC_1: IEC104_IO_C_SE_NC_1, - IEC104_IO_ID_C_BO_NA_1: IEC104_IO_C_BO_NA_1, - IEC104_IO_ID_C_SC_TA_1: IEC104_IO_C_SC_TA_1, - IEC104_IO_ID_C_DC_TA_1: IEC104_IO_C_DC_TA_1, - IEC104_IO_ID_C_RC_TA_1: IEC104_IO_C_RC_TA_1, - IEC104_IO_ID_C_SE_TA_1: IEC104_IO_C_SE_TA_1, - IEC104_IO_ID_C_SE_TB_1: IEC104_IO_C_SE_TB_1, - IEC104_IO_ID_C_SE_TC_1: IEC104_IO_C_SE_TC_1, - IEC104_IO_ID_C_BO_TA_1: IEC104_IO_C_BO_TA_1, - IEC104_IO_ID_M_EI_NA_1: IEC104_IO_M_EI_NA_1, - IEC104_IO_ID_C_IC_NA_1: IEC104_IO_C_IC_NA_1, - IEC104_IO_ID_C_CI_NA_1: IEC104_IO_C_CI_NA_1, - IEC104_IO_ID_C_RD_NA_1: IEC104_IO_C_RD_NA_1, - IEC104_IO_ID_C_CS_NA_1: IEC104_IO_C_CS_NA_1, - IEC104_IO_ID_C_TS_NA_1: IEC104_IO_C_TS_NA_1, - IEC104_IO_ID_C_RP_NA_1: IEC104_IO_C_RP_NA_1, - IEC104_IO_ID_C_CD_NA_1: IEC104_IO_C_CD_NA_1, - IEC104_IO_ID_C_TS_TA_1: IEC104_IO_C_TS_TA_1, - IEC104_IO_ID_P_ME_NA_1: IEC104_IO_P_ME_NA_1, - IEC104_IO_ID_P_ME_NB_1: IEC104_IO_P_ME_NB_1, - IEC104_IO_ID_P_ME_NC_1: IEC104_IO_P_ME_NC_1, - IEC104_IO_ID_P_AC_NA_1: IEC104_IO_P_AC_NA_1, - IEC104_IO_ID_F_FR_NA_1: IEC104_IO_F_FR_NA_1, - IEC104_IO_ID_F_SR_NA_1: IEC104_IO_F_SR_NA_1, - IEC104_IO_ID_F_SC_NA_1: IEC104_IO_F_SC_NA_1, - IEC104_IO_ID_F_LS_NA_1: IEC104_IO_F_LS_NA_1, - IEC104_IO_ID_F_AF_NA_1: IEC104_IO_F_AF_NA_1, - IEC104_IO_ID_F_SG_NA_1: IEC104_IO_F_SG_NA_1, - IEC104_IO_ID_F_DR_TA_1: IEC104_IO_F_DR_TA_1, - IEC104_IO_ID_F_SC_NB_1: IEC104_IO_F_SC_NB_1 -} - - -class IEC104_IO_M_SP_NA_1_IOA(IEC104_IO_M_SP_NA_1): - """ - extended version of IEC104_IO_M_SP_NA_1 containing an individual - information object address - """ - name = 'M_SP_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_SP_NA_1.fields_desc - - -class IEC104_IO_M_SP_TA_1_IOA(IEC104_IO_M_SP_TA_1): - """ - extended version of IEC104_IO_M_SP_TA_1 containing an individual - information object address - """ - name = 'M_SP_TA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_SP_TA_1.fields_desc - - -class IEC104_IO_M_DP_NA_1_IOA(IEC104_IO_M_DP_NA_1): - """ - extended version of IEC104_IO_M_DP_NA_1 containing an individual - information object address - """ - name = 'M_DP_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_DP_NA_1.fields_desc - - -class IEC104_IO_M_DP_TA_1_IOA(IEC104_IO_M_DP_TA_1): - """ - extended version of IEC104_IO_M_DP_TA_1 containing an individual - information object address - """ - name = 'M_DP_TA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_DP_TA_1.fields_desc - - -class IEC104_IO_M_ST_NA_1_IOA(IEC104_IO_M_ST_NA_1): - """ - extended version of IEC104_IO_M_ST_NA_1 containing an individual - information object address - """ - name = 'M_ST_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_ST_NA_1.fields_desc - - -class IEC104_IO_M_ST_TA_1_IOA(IEC104_IO_M_ST_TA_1): - """ - extended version of IEC104_IO_M_ST_TA_1 containing an individual - information object address - """ - name = 'M_ST_TA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_ST_TA_1.fields_desc - - -class IEC104_IO_M_BO_NA_1_IOA(IEC104_IO_M_BO_NA_1): - """ - extended version of IEC104_IO_M_BO_NA_1 containing an individual - information object address - """ - name = 'M_BO_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_BO_NA_1.fields_desc - - -class IEC104_IO_M_BO_TA_1_IOA(IEC104_IO_M_BO_TA_1): - """ - extended version of IEC104_IO_M_BO_TA_1 containing an individual - information object address - """ - name = 'M_BO_TA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_BO_TA_1.fields_desc - - -class IEC104_IO_M_ME_NA_1_IOA(IEC104_IO_M_ME_NA_1): - """ - extended version of IEC104_IO_M_ME_NA_1 containing an individual - information object address - """ - name = 'M_ME_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_ME_NA_1.fields_desc - - -class IEC104_IO_M_ME_TA_1_IOA(IEC104_IO_M_ME_TA_1): - """ - extended version of IEC104_IO_M_ME_TA_1 containing an individual - information object address - """ - name = 'M_ME_TA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_ME_TA_1.fields_desc - - -class IEC104_IO_M_ME_NB_1_IOA(IEC104_IO_M_ME_NB_1): - """ - extended version of IEC104_IO_M_ME_NB_1 containing an individual - information object address - """ - name = 'M_ME_NB_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_ME_NB_1.fields_desc - - -class IEC104_IO_M_ME_TB_1_IOA(IEC104_IO_M_ME_TB_1): - """ - extended version of IEC104_IO_M_ME_TB_1 containing an individual - information object address - """ - name = 'M_ME_TB_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_ME_TB_1.fields_desc - - -class IEC104_IO_M_ME_NC_1_IOA(IEC104_IO_M_ME_NC_1): - """ - extended version of IEC104_IO_M_ME_NC_1 containing an individual - information object address - """ - name = 'M_ME_NC_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_ME_NC_1.fields_desc - - -class IEC104_IO_M_ME_TC_1_IOA(IEC104_IO_M_ME_TC_1): - """ - extended version of IEC104_IO_M_ME_TC_1 containing an individual - information object address - """ - name = 'M_ME_TC_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_ME_TC_1.fields_desc - - -class IEC104_IO_M_IT_NA_1_IOA(IEC104_IO_M_IT_NA_1): - """ - extended version of IEC104_IO_M_IT_NA_1 containing an individual - information object address - """ - name = 'M_IT_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_IT_NA_1.fields_desc - - -class IEC104_IO_M_IT_TA_1_IOA(IEC104_IO_M_IT_TA_1): - """ - extended version of IEC104_IO_M_IT_TA_1 containing an individual - information object address - """ - name = 'M_IT_TA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_IT_TA_1.fields_desc - - -class IEC104_IO_M_EP_TA_1_IOA(IEC104_IO_M_EP_TA_1): - """ - extended version of IEC104_IO_M_EP_TA_1 containing an individual - information object address - """ - name = 'M_EP_TA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_EP_TA_1.fields_desc - - -class IEC104_IO_M_EP_TB_1_IOA(IEC104_IO_M_EP_TB_1): - """ - extended version of IEC104_IO_M_EP_TB_1 containing an individual - information object address - """ - name = 'M_EP_TB_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_EP_TB_1.fields_desc - - -class IEC104_IO_M_EP_TC_1_IOA(IEC104_IO_M_EP_TC_1): - """ - extended version of IEC104_IO_M_EP_TC_1 containing an individual - information object address - """ - name = 'M_EP_TC_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_EP_TC_1.fields_desc - - -class IEC104_IO_M_PS_NA_1_IOA(IEC104_IO_M_PS_NA_1): - """ - extended version of IEC104_IO_M_PS_NA_1 containing an individual - information object address - """ - name = 'M_PS_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_PS_NA_1.fields_desc - - -class IEC104_IO_M_ME_ND_1_IOA(IEC104_IO_M_ME_ND_1): - """ - extended version of IEC104_IO_M_ME_ND_1 containing an individual - information object address - """ - name = 'M_ME_ND_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_ME_ND_1.fields_desc - - -class IEC104_IO_M_SP_TB_1_IOA(IEC104_IO_M_SP_TB_1): - """ - extended version of IEC104_IO_M_SP_TB_1 containing an individual - information object address - """ - name = 'M_SP_TB_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_SP_TB_1.fields_desc - - -class IEC104_IO_M_DP_TB_1_IOA(IEC104_IO_M_DP_TB_1): - """ - extended version of IEC104_IO_M_DP_TB_1 containing an individual - information object address - """ - name = 'M_DP_TB_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_DP_TB_1.fields_desc - - -class IEC104_IO_M_ST_TB_1_IOA(IEC104_IO_M_ST_TB_1): - """ - extended version of IEC104_IO_M_ST_TB_1 containing an individual - information object address - """ - name = 'M_ST_TB_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_ST_TB_1.fields_desc - - -class IEC104_IO_M_BO_TB_1_IOA(IEC104_IO_M_BO_TB_1): - """ - extended version of IEC104_IO_M_BO_TB_1 containing an individual - information object address - """ - name = 'M_BO_TB_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_BO_TB_1.fields_desc - - -class IEC104_IO_M_ME_TD_1_IOA(IEC104_IO_M_ME_TD_1): - """ - extended version of IEC104_IO_M_ME_TD_1 containing an individual - information object address - """ - name = 'M_ME_TD_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_ME_TD_1.fields_desc - - -class IEC104_IO_M_ME_TE_1_IOA(IEC104_IO_M_ME_TE_1): - """ - extended version of IEC104_IO_M_ME_TE_1 containing an individual - information object address - """ - name = 'M_ME_TE_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_ME_TE_1.fields_desc - - -class IEC104_IO_M_ME_TF_1_IOA(IEC104_IO_M_ME_TF_1): - """ - extended version of IEC104_IO_M_ME_TF_1 containing an individual - information object address - """ - name = 'M_ME_TF_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_ME_TF_1.fields_desc - - -class IEC104_IO_M_IT_TB_1_IOA(IEC104_IO_M_IT_TB_1): - """ - extended version of IEC104_IO_M_IT_TB_1 containing an individual - information object address - """ - name = 'M_IT_TB_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_IT_TB_1.fields_desc - - -class IEC104_IO_M_EP_TD_1_IOA(IEC104_IO_M_EP_TD_1): - """ - extended version of IEC104_IO_M_EP_TD_1 containing an individual - information object address - """ - name = 'M_EP_TD_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_EP_TD_1.fields_desc - - -class IEC104_IO_M_EP_TE_1_IOA(IEC104_IO_M_EP_TE_1): - """ - extended version of IEC104_IO_M_EP_TE_1 containing an individual - information object address - """ - name = 'M_EP_TE_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_EP_TE_1.fields_desc - - -class IEC104_IO_M_EP_TF_1_IOA(IEC104_IO_M_EP_TF_1): - """ - extended version of IEC104_IO_M_EP_TF_1 containing an individual - information object address - """ - name = 'M_EP_TF_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_EP_TF_1.fields_desc - - -class IEC104_IO_C_SC_NA_1_IOA(IEC104_IO_C_SC_NA_1): - """ - extended version of IEC104_IO_C_SC_NA_1 containing an individual - information object address - """ - name = 'C_SC_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_SC_NA_1.fields_desc - - -class IEC104_IO_C_DC_NA_1_IOA(IEC104_IO_C_DC_NA_1): - """ - extended version of IEC104_IO_C_DC_NA_1 containing an individual - information object address - """ - name = 'C_DC_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_DC_NA_1.fields_desc - - -class IEC104_IO_C_RC_NA_1_IOA(IEC104_IO_C_RC_NA_1): - """ - extended version of IEC104_IO_C_RC_NA_1 containing an individual - information object address - """ - name = 'C_RC_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_RC_NA_1.fields_desc - - -class IEC104_IO_C_SE_NA_1_IOA(IEC104_IO_C_SE_NA_1): - """ - extended version of IEC104_IO_C_SE_NA_1 containing an individual - information object address - """ - name = 'C_SE_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_SE_NA_1.fields_desc - - -class IEC104_IO_C_SE_NB_1_IOA(IEC104_IO_C_SE_NB_1): - """ - extended version of IEC104_IO_C_SE_NB_1 containing an individual - information object address - """ - name = 'C_SE_NB_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_SE_NB_1.fields_desc - - -class IEC104_IO_C_SE_NC_1_IOA(IEC104_IO_C_SE_NC_1): - """ - extended version of IEC104_IO_C_SE_NC_1 containing an individual - information object address - """ - name = 'C_SE_NC_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_SE_NC_1.fields_desc - - -class IEC104_IO_C_BO_NA_1_IOA(IEC104_IO_C_BO_NA_1): - """ - extended version of IEC104_IO_C_BO_NA_1 containing an individual - information object address - """ - name = 'C_BO_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_BO_NA_1.fields_desc - - -class IEC104_IO_C_SC_TA_1_IOA(IEC104_IO_C_SC_TA_1): - """ - extended version of IEC104_IO_C_SC_TA_1 containing an individual - information object address - """ - name = 'C_SC_TA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_SC_TA_1.fields_desc - - -class IEC104_IO_C_DC_TA_1_IOA(IEC104_IO_C_DC_TA_1): - """ - extended version of IEC104_IO_C_DC_TA_1 containing an individual - information object address - """ - name = 'C_DC_TA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_DC_TA_1.fields_desc - - -class IEC104_IO_C_RC_TA_1_IOA(IEC104_IO_C_RC_TA_1): - """ - extended version of IEC104_IO_C_RC_TA_1 containing an individual - information object address - """ - name = 'C_RC_TA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_RC_TA_1.fields_desc - - -class IEC104_IO_C_SE_TA_1_IOA(IEC104_IO_C_SE_TA_1): - """ - extended version of IEC104_IO_C_SE_TA_1 containing an individual - information object address - """ - name = 'C_SE_TA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_SE_TA_1.fields_desc - - -class IEC104_IO_C_SE_TB_1_IOA(IEC104_IO_C_SE_TB_1): - """ - extended version of IEC104_IO_C_SE_TB_1 containing an individual - information object address - """ - name = 'C_SE_TB_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_SE_TB_1.fields_desc - - -class IEC104_IO_C_SE_TC_1_IOA(IEC104_IO_C_SE_TC_1): - """ - extended version of IEC104_IO_C_SE_TC_1 containing an individual - information object address - """ - name = 'C_SE_TC_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_SE_TC_1.fields_desc - - -class IEC104_IO_C_BO_TA_1_IOA(IEC104_IO_C_BO_TA_1): - """ - extended version of IEC104_IO_C_BO_TA_1 containing an individual - information object address - """ - name = 'C_BO_TA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_BO_TA_1.fields_desc - - -class IEC104_IO_M_EI_NA_1_IOA(IEC104_IO_M_EI_NA_1): - """ - extended version of IEC104_IO_M_EI_NA_1 containing an individual - information object address - """ - name = 'M_EI_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_M_EI_NA_1.fields_desc - - -class IEC104_IO_C_IC_NA_1_IOA(IEC104_IO_C_IC_NA_1): - """ - extended version of IEC104_IO_C_IC_NA_1 containing an individual - information object address - """ - name = 'C_IC_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_IC_NA_1.fields_desc - - -class IEC104_IO_C_CI_NA_1_IOA(IEC104_IO_C_CI_NA_1): - """ - extended version of IEC104_IO_C_CI_NA_1 containing an individual - information object address - """ - name = 'C_CI_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_CI_NA_1.fields_desc - - -class IEC104_IO_C_RD_NA_1_IOA(IEC104_IO_C_RD_NA_1): - """ - extended version of IEC104_IO_C_RD_NA_1 containing an individual - information object address - """ - name = 'C_RD_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_RD_NA_1.fields_desc - - -class IEC104_IO_C_CS_NA_1_IOA(IEC104_IO_C_CS_NA_1): - """ - extended version of IEC104_IO_C_CS_NA_1 containing an individual - information object address - """ - name = 'C_CS_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_CS_NA_1.fields_desc - - -class IEC104_IO_C_TS_NA_1_IOA(IEC104_IO_C_TS_NA_1): - """ - extended version of IEC104_IO_C_TS_NA_1 containing an individual - information object address - """ - name = 'C_TS_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_TS_NA_1.fields_desc - - -class IEC104_IO_C_RP_NA_1_IOA(IEC104_IO_C_RP_NA_1): - """ - extended version of IEC104_IO_C_RP_NA_1 containing an individual - information object address - """ - name = 'C_RP_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_RP_NA_1.fields_desc - - -class IEC104_IO_C_CD_NA_1_IOA(IEC104_IO_C_CD_NA_1): - """ - extended version of IEC104_IO_C_CD_NA_1 containing an individual - information object address - """ - name = 'C_CD_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_CD_NA_1.fields_desc - - -class IEC104_IO_C_TS_TA_1_IOA(IEC104_IO_C_TS_TA_1): - """ - extended version of IEC104_IO_C_TS_TA_1 containing an individual - information object address - """ - name = 'C_TS_TA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_C_TS_TA_1.fields_desc - - -class IEC104_IO_P_ME_NA_1_IOA(IEC104_IO_P_ME_NA_1): - """ - extended version of IEC104_IO_P_ME_NA_1 containing an individual - information object address - """ - name = 'P_ME_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_P_ME_NA_1.fields_desc - - -class IEC104_IO_P_ME_NB_1_IOA(IEC104_IO_P_ME_NB_1): - """ - extended version of IEC104_IO_P_ME_NB_1 containing an individual - information object address - """ - name = 'P_ME_NB_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_P_ME_NB_1.fields_desc - - -class IEC104_IO_P_ME_NC_1_IOA(IEC104_IO_P_ME_NC_1): - """ - extended version of IEC104_IO_P_ME_NC_1 containing an individual - information object address - """ - name = 'P_ME_NC_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_P_ME_NC_1.fields_desc - - -class IEC104_IO_P_AC_NA_1_IOA(IEC104_IO_P_AC_NA_1): - """ - extended version of IEC104_IO_P_AC_NA_1 containing an individual - information object address - """ - name = 'P_AC_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_P_AC_NA_1.fields_desc - - -class IEC104_IO_F_FR_NA_1_IOA(IEC104_IO_F_FR_NA_1): - """ - extended version of IEC104_IO_F_FR_NA_1 containing an individual - information object address - """ - name = 'F_FR_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_F_FR_NA_1.fields_desc - - -class IEC104_IO_F_SR_NA_1_IOA(IEC104_IO_F_SR_NA_1): - """ - extended version of IEC104_IO_F_SR_NA_1 containing an individual - information object address - """ - name = 'F_SR_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_F_SR_NA_1.fields_desc - - -class IEC104_IO_F_SC_NA_1_IOA(IEC104_IO_F_SC_NA_1): - """ - extended version of IEC104_IO_F_SC_NA_1 containing an individual - information object address - """ - name = 'F_SC_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_F_SC_NA_1.fields_desc - - -class IEC104_IO_F_LS_NA_1_IOA(IEC104_IO_F_LS_NA_1): - """ - extended version of IEC104_IO_F_LS_NA_1 containing an individual - information object address - """ - name = 'F_LS_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_F_LS_NA_1.fields_desc - - -class IEC104_IO_F_AF_NA_1_IOA(IEC104_IO_F_AF_NA_1): - """ - extended version of IEC104_IO_F_AF_NA_1 containing an individual - information object address - """ - name = 'F_AF_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_F_AF_NA_1.fields_desc - - -class IEC104_IO_F_SG_NA_1_IOA(IEC104_IO_F_SG_NA_1): - """ - extended version of IEC104_IO_F_SG_NA_1 containing an individual - information object address - """ - name = 'F_SG_NA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_F_SG_NA_1.fields_desc - - -class IEC104_IO_F_DR_TA_1_IOA(IEC104_IO_F_DR_TA_1): - """ - extended version of IEC104_IO_F_DR_TA_1 containing an individual - information object address - """ - name = 'F_DR_TA_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_F_DR_TA_1.fields_desc - - -class IEC104_IO_F_SC_NB_1_IOA(IEC104_IO_F_SC_NB_1): - """ - extended version of IEC104_IO_F_SC_NB_1 containing an individual - information object address - """ - name = 'F_SC_NB_1 (+ioa)' - fields_desc = [LEThreeBytesField('information_object_address', 0)] + \ - IEC104_IO_F_SC_NB_1.fields_desc - - -IEC104_IO_WITH_IOA_CLASSES = { - IEC104_IO_ID_M_SP_NA_1: IEC104_IO_M_SP_NA_1_IOA, - IEC104_IO_ID_M_SP_TA_1: IEC104_IO_M_SP_TA_1_IOA, - IEC104_IO_ID_M_DP_NA_1: IEC104_IO_M_DP_NA_1_IOA, - IEC104_IO_ID_M_DP_TA_1: IEC104_IO_M_DP_TA_1_IOA, - IEC104_IO_ID_M_ST_NA_1: IEC104_IO_M_ST_NA_1_IOA, - IEC104_IO_ID_M_ST_TA_1: IEC104_IO_M_ST_TA_1_IOA, - IEC104_IO_ID_M_BO_NA_1: IEC104_IO_M_BO_NA_1_IOA, - IEC104_IO_ID_M_BO_TA_1: IEC104_IO_M_BO_TA_1_IOA, - IEC104_IO_ID_M_ME_NA_1: IEC104_IO_M_ME_NA_1_IOA, - IEC104_IO_ID_M_ME_TA_1: IEC104_IO_M_ME_TA_1_IOA, - IEC104_IO_ID_M_ME_NB_1: IEC104_IO_M_ME_NB_1_IOA, - IEC104_IO_ID_M_ME_TB_1: IEC104_IO_M_ME_TB_1_IOA, - IEC104_IO_ID_M_ME_NC_1: IEC104_IO_M_ME_NC_1_IOA, - IEC104_IO_ID_M_ME_TC_1: IEC104_IO_M_ME_TC_1_IOA, - IEC104_IO_ID_M_IT_NA_1: IEC104_IO_M_IT_NA_1_IOA, - IEC104_IO_ID_M_IT_TA_1: IEC104_IO_M_IT_TA_1_IOA, - IEC104_IO_ID_M_EP_TA_1: IEC104_IO_M_EP_TA_1_IOA, - IEC104_IO_ID_M_EP_TB_1: IEC104_IO_M_EP_TB_1_IOA, - IEC104_IO_ID_M_EP_TC_1: IEC104_IO_M_EP_TC_1_IOA, - IEC104_IO_ID_M_PS_NA_1: IEC104_IO_M_PS_NA_1_IOA, - IEC104_IO_ID_M_ME_ND_1: IEC104_IO_M_ME_ND_1_IOA, - IEC104_IO_ID_M_SP_TB_1: IEC104_IO_M_SP_TB_1_IOA, - IEC104_IO_ID_M_DP_TB_1: IEC104_IO_M_DP_TB_1_IOA, - IEC104_IO_ID_M_ST_TB_1: IEC104_IO_M_ST_TB_1_IOA, - IEC104_IO_ID_M_BO_TB_1: IEC104_IO_M_BO_TB_1_IOA, - IEC104_IO_ID_M_ME_TD_1: IEC104_IO_M_ME_TD_1_IOA, - IEC104_IO_ID_M_ME_TE_1: IEC104_IO_M_ME_TE_1_IOA, - IEC104_IO_ID_M_ME_TF_1: IEC104_IO_M_ME_TF_1_IOA, - IEC104_IO_ID_M_IT_TB_1: IEC104_IO_M_IT_TB_1_IOA, - IEC104_IO_ID_M_EP_TD_1: IEC104_IO_M_EP_TD_1_IOA, - IEC104_IO_ID_M_EP_TE_1: IEC104_IO_M_EP_TE_1_IOA, - IEC104_IO_ID_M_EP_TF_1: IEC104_IO_M_EP_TF_1_IOA, - IEC104_IO_ID_C_SC_NA_1: IEC104_IO_C_SC_NA_1_IOA, - IEC104_IO_ID_C_DC_NA_1: IEC104_IO_C_DC_NA_1_IOA, - IEC104_IO_ID_C_RC_NA_1: IEC104_IO_C_RC_NA_1_IOA, - IEC104_IO_ID_C_SE_NA_1: IEC104_IO_C_SE_NA_1_IOA, - IEC104_IO_ID_C_SE_NB_1: IEC104_IO_C_SE_NB_1_IOA, - IEC104_IO_ID_C_SE_NC_1: IEC104_IO_C_SE_NC_1_IOA, - IEC104_IO_ID_C_BO_NA_1: IEC104_IO_C_BO_NA_1_IOA, - IEC104_IO_ID_C_SC_TA_1: IEC104_IO_C_SC_TA_1_IOA, - IEC104_IO_ID_C_DC_TA_1: IEC104_IO_C_DC_TA_1_IOA, - IEC104_IO_ID_C_RC_TA_1: IEC104_IO_C_RC_TA_1_IOA, - IEC104_IO_ID_C_SE_TA_1: IEC104_IO_C_SE_TA_1_IOA, - IEC104_IO_ID_C_SE_TB_1: IEC104_IO_C_SE_TB_1_IOA, - IEC104_IO_ID_C_SE_TC_1: IEC104_IO_C_SE_TC_1_IOA, - IEC104_IO_ID_C_BO_TA_1: IEC104_IO_C_BO_TA_1_IOA, - IEC104_IO_ID_M_EI_NA_1: IEC104_IO_M_EI_NA_1_IOA, - IEC104_IO_ID_C_IC_NA_1: IEC104_IO_C_IC_NA_1_IOA, - IEC104_IO_ID_C_CI_NA_1: IEC104_IO_C_CI_NA_1_IOA, - IEC104_IO_ID_C_RD_NA_1: IEC104_IO_C_RD_NA_1_IOA, - IEC104_IO_ID_C_CS_NA_1: IEC104_IO_C_CS_NA_1_IOA, - IEC104_IO_ID_C_TS_NA_1: IEC104_IO_C_TS_NA_1_IOA, - IEC104_IO_ID_C_RP_NA_1: IEC104_IO_C_RP_NA_1_IOA, - IEC104_IO_ID_C_CD_NA_1: IEC104_IO_C_CD_NA_1_IOA, - IEC104_IO_ID_C_TS_TA_1: IEC104_IO_C_TS_TA_1_IOA, - IEC104_IO_ID_P_ME_NA_1: IEC104_IO_P_ME_NA_1_IOA, - IEC104_IO_ID_P_ME_NB_1: IEC104_IO_P_ME_NB_1_IOA, - IEC104_IO_ID_P_ME_NC_1: IEC104_IO_P_ME_NC_1_IOA, - IEC104_IO_ID_P_AC_NA_1: IEC104_IO_P_AC_NA_1_IOA, - IEC104_IO_ID_F_FR_NA_1: IEC104_IO_F_FR_NA_1_IOA, - IEC104_IO_ID_F_SR_NA_1: IEC104_IO_F_SR_NA_1_IOA, - IEC104_IO_ID_F_SC_NA_1: IEC104_IO_F_SC_NA_1_IOA, - IEC104_IO_ID_F_LS_NA_1: IEC104_IO_F_LS_NA_1_IOA, - IEC104_IO_ID_F_AF_NA_1: IEC104_IO_F_AF_NA_1_IOA, - IEC104_IO_ID_F_SG_NA_1: IEC104_IO_F_SG_NA_1_IOA, - IEC104_IO_ID_F_DR_TA_1: IEC104_IO_F_DR_TA_1_IOA, - IEC104_IO_ID_F_SC_NB_1: IEC104_IO_F_SC_NB_1_IOA -} diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/sdnv.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/sdnv.py deleted file mode 100644 index cfb5e3c4b4..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/sdnv.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env python - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -""" - Copyright 2012, The MITRE Corporation - - NOTICE - This software/technical data was produced for the U.S. Government - under Prime Contract No. NASA-03001 and JPL Contract No. 1295026 - and is subject to FAR 52.227-14 (6/87) Rights in Data General, - and Article GP-51, Rights in Data General, respectively. - This software is publicly released under MITRE case #12-3054 -""" - -# scapy.contrib.description = Self-Delimiting Numeric Values (SDNV) -# scapy.contrib.status = library - -from scapy.fields import Field, FieldLenField, LenField -from scapy.compat import raw - -# SDNV definitions - - -class SDNVValueError(Exception): - def __init__(self, maxValue): - self.maxValue = maxValue - - -class SDNV: - def __init__(self, maxValue=2**32 - 1): - self.maxValue = maxValue - return - - def setMax(self, maxValue): - self.maxValue = maxValue - - def getMax(self): - return self.maxValue - - def encode(self, number): - if number > self.maxValue: - raise SDNVValueError(self.maxValue) - - foo = bytearray() - foo.append(number & 0x7F) - number = number >> 7 - - while (number > 0): - thisByte = number & 0x7F - thisByte |= 0x80 - number = number >> 7 - temp = bytearray() - temp.append(thisByte) - foo = temp + foo - - return(foo) - - def decode(self, ba, offset): - number = 0 - numBytes = 1 - - b = ba[offset] - number = (b & 0x7F) - while (b & 0x80 == 0x80): - number = number << 7 - if (number > self.maxValue): - raise SDNVValueError(self.maxValue) - b = ba[offset + numBytes] - number += (b & 0x7F) - numBytes += 1 - if (number > self.maxValue): - raise SDNVValueError(self.maxValue) - return(number, numBytes) - - -SDNVUtil = SDNV() - - -class SDNV2(Field): - """ SDNV2 field """ - - def addfield(self, pkt, s, val): - return s + raw(SDNVUtil.encode(val)) - - def getfield(self, pkt, s): - b = bytearray(s) - val, len = SDNVUtil.decode(b, 0) - return s[len:], val - - -class SDNV2FieldLenField(FieldLenField, SDNV2): - def addfield(self, pkt, s, val): - return s + raw(SDNVUtil.encode(FieldLenField.i2m(self, pkt, val))) - - -class SDNV2LenField(LenField, SDNV2): - def addfield(self, pkt, s, val): - return s + raw(SDNVUtil.encode(LenField.i2m(self, pkt, val))) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/sebek.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/sebek.py deleted file mode 100644 index 65543c3c39..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/sebek.py +++ /dev/null @@ -1,124 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Sebek: kernel module for data collection on honeypots. -""" - -# scapy.contrib.description = Sebek -# scapy.contrib.status = loads - -from scapy.fields import FieldLenField, IPField, IntField, ShortEnumField, \ - ShortField, StrFixedLenField, StrLenField, XIntField, ByteEnumField -from scapy.packet import Packet, bind_layers -from scapy.layers.inet import UDP -from scapy.data import IP_PROTOS - - -# 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%") # noqa: E501 - -# 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("cmd", "", 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.cmd%)") # noqa: E501 - else: - return self.sprintf("Sebek v1 (%SebekV1.cmd%)") - - -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("cmd", "", 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.cmd%)") # noqa: E501 - else: - return self.sprintf("Sebek v3 (%SebekV3.cmd%)") - - -class SebekV2(SebekV3): - def mysummary(self): - if isinstance(self.underlayer, SebekHead): - return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2.cmd%)") # noqa: E501 - else: - return self.sprintf("Sebek v2 (%SebekV2.cmd%)") - - -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("cmd", "", 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.cmd%)") # noqa: E501 - else: - return self.sprintf("Sebek v3 socket (%SebekV3Sock.cmd%)") - - -class SebekV2Sock(SebekV3Sock): - def mysummary(self): - if isinstance(self.underlayer, SebekHead): - return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2Sock.cmd%)") # noqa: E501 - else: - return self.sprintf("Sebek v2 socket (%SebekV2Sock.cmd%)") - - -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-2.4.3/scapy/contrib/send.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/send.py deleted file mode 100644 index 17bc08dd8a..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/send.py +++ /dev/null @@ -1,90 +0,0 @@ -#! /usr/bin/env python - -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# Copyright (C) 2009 Adline Stephane -# Copyright 2018 Gabriel Potter - -# Partial support of RFC3971 -# scapy.contrib.description = Secure Neighbor Discovery (SEND) (ICMPv6) -# scapy.contrib.status = loads - -from __future__ import absolute_import - -from scapy.packet import Packet -from scapy.fields import BitField, ByteField, FieldLenField, PacketField, \ - PacketLenField, ShortField, StrFixedLenField, StrLenField, UTCTimeField -from scapy.layers.x509 import X509_SubjectPublicKeyInfo -from scapy.layers.inet6 import icmp6ndoptscls, _ICMPv6NDGuessPayload -from scapy.compat import chb -from scapy.volatile import RandBin - - -class ICMPv6NDOptNonce(_ICMPv6NDGuessPayload, Packet): - name = "ICMPv6NDOptNonce" - fields_desc = [ByteField("type", 14), - FieldLenField("len", None, length_of="nonce", fmt="B", adjust=lambda pkt, x: int(round((x + 2) / 8.))), # noqa: E501 - StrLenField("nonce", "", length_from=lambda pkt: pkt.len * 8 - 2)] # noqa: E501 - - -class ICMPv6NDOptTmstp(_ICMPv6NDGuessPayload, Packet): - name = "ICMPv6NDOptTmstp" - fields_desc = [ByteField("type", 13), - ByteField("len", 2), - BitField("reserved", 0, 48), - UTCTimeField("timestamp", None)] - - -class ICMPv6NDOptRsaSig(_ICMPv6NDGuessPayload, Packet): - name = "ICMPv6NDOptRsaSig" - fields_desc = [ByteField("type", 12), - FieldLenField("len", None, length_of="signature_pad", fmt="B", adjust=lambda pkt, x: (x + 20) // 8), # noqa: E501 - ShortField("reserved", 0), - StrFixedLenField("key_hash", "", length=16), - StrLenField("signature_pad", "", length_from=lambda pkt: pkt.len * 8 - 20)] # noqa: E501 - - -class CGA_Params(Packet): - name = "CGA Parameters data structure" - fields_desc = [StrFixedLenField("modifier", RandBin(size=16), length=16), - StrFixedLenField("subprefix", "", length=8), - ByteField("cc", 0), - PacketField("pubkey", X509_SubjectPublicKeyInfo(), - X509_SubjectPublicKeyInfo)] - - -class ICMPv6NDOptCGA(_ICMPv6NDGuessPayload, Packet): - name = "ICMPv6NDOptCGA" - fields_desc = [ByteField("type", 11), - FieldLenField("len", None, length_of="CGA_PARAMS", fmt="B", adjust=lambda pkt, x: (x + pkt.padlength + 4) // 8), # noqa: E501 - FieldLenField("padlength", 0, length_of="padding", fmt="B"), - ByteField("reserved", 0), - PacketLenField("CGA_PARAMS", "", CGA_Params, length_from=lambda pkt: pkt.len * 8 - pkt.padlength - 4), # noqa: E501 - StrLenField("padding", "", length_from=lambda pkt: pkt.padlength)] # noqa: E501 - - def post_build(self, p, pay): - l_ = len(self.CGA_PARAMS) - tmp_len = -(4 + l_) % 8 # Pad to 8 bytes - p = p[:1] + chb((4 + l_ + tmp_len) // 8) + chb(tmp_len) + p[3:4 + l_] - p += b"\x00" * tmp_len + pay - return p - - -send_icmp6ndoptscls = {11: ICMPv6NDOptCGA, - 12: ICMPv6NDOptRsaSig, - 13: ICMPv6NDOptTmstp, - 14: ICMPv6NDOptNonce - } -icmp6ndoptscls.update(send_icmp6ndoptscls) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/skinny.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/skinny.py deleted file mode 100644 index a5f4269d44..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/skinny.py +++ /dev/null @@ -1,537 +0,0 @@ -#! /usr/bin/env python - -# scapy.contrib.description = Skinny Call Control Protocol (SCCP) -# scapy.contrib.status = loads - - -############################################################################# -# # -# scapy-skinny.py --- Skinny Call Control Protocol (SCCP) extension # -# # -# Copyright (C) 2006 Nicolas Bareil # -# EADS/CRC security team # -# # -# This file is part of Scapy # -# Scapy is free software: you can redistribute it and/or modify # -# 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. # -# # -############################################################################# - -from __future__ import absolute_import -import time -import struct - -from scapy.packet import Packet, bind_layers -from scapy.fields import FlagsField, IPField, LEIntEnumField, LEIntField, \ - StrFixedLenField -from scapy.layers.inet import TCP -from scapy.modules.six.moves import range -from scapy.volatile import RandShort -from scapy.config import conf - -##################################################################### -# Helpers and constants -##################################################################### - -skinny_messages_cls = { - # Station -> Callmanager - 0x0000: "SkinnyMessageKeepAlive", - 0x0001: "SkinnyMessageRegister", - 0x0002: "SkinnyMessageIpPort", - 0x0003: "SkinnyMessageKeypadButton", - 0x0004: "SkinnyMessageEnblocCall", - 0x0005: "SkinnyMessageStimulus", - 0x0006: "SkinnyMessageOffHook", - 0x0007: "SkinnyMessageOnHook", - 0x0008: "SkinnyMessageHookFlash", - 0x0009: "SkinnyMessageForwardStatReq", - 0x000A: "SkinnyMessageSpeedDialStatReq", - 0x000B: "SkinnyMessageLineStatReq", - 0x000C: "SkinnyMessageConfigStatReq", - 0x000D: "SkinnyMessageTimeDateReq", - 0x000E: "SkinnyMessageButtonTemplateReq", - 0x000F: "SkinnyMessageVersionReq", - 0x0010: "SkinnyMessageCapabilitiesRes", - 0x0011: "SkinnyMessageMediaPortList", - 0x0012: "SkinnyMessageServerReq", - 0x0020: "SkinnyMessageAlarm", - 0x0021: "SkinnyMessageMulticastMediaReceptionAck", - 0x0022: "SkinnyMessageOpenReceiveChannelAck", - 0x0023: "SkinnyMessageConnectionStatisticsRes", - 0x0024: "SkinnyMessageOffHookWithCgpn", - 0x0025: "SkinnyMessageSoftKeySetReq", - 0x0026: "SkinnyMessageSoftKeyEvent", - 0x0027: "SkinnyMessageUnregister", - 0x0028: "SkinnyMessageSoftKeyTemplateReq", - 0x0029: "SkinnyMessageRegisterTokenReq", - 0x002A: "SkinnyMessageMediaTransmissionFailure", - 0x002B: "SkinnyMessageHeadsetStatus", - 0x002C: "SkinnyMessageMediaResourceNotification", - 0x002D: "SkinnyMessageRegisterAvailableLines", - 0x002E: "SkinnyMessageDeviceToUserData", - 0x002F: "SkinnyMessageDeviceToUserDataResponse", - 0x0030: "SkinnyMessageUpdateCapabilities", - 0x0031: "SkinnyMessageOpenMultiMediaReceiveChannelAck", - 0x0032: "SkinnyMessageClearConference", - 0x0033: "SkinnyMessageServiceURLStatReq", - 0x0034: "SkinnyMessageFeatureStatReq", - 0x0035: "SkinnyMessageCreateConferenceRes", - 0x0036: "SkinnyMessageDeleteConferenceRes", - 0x0037: "SkinnyMessageModifyConferenceRes", - 0x0038: "SkinnyMessageAddParticipantRes", - 0x0039: "SkinnyMessageAuditConferenceRes", - 0x0040: "SkinnyMessageAuditParticipantRes", - 0x0041: "SkinnyMessageDeviceToUserDataVersion1", - # Callmanager -> Station */ - 0x0081: "SkinnyMessageRegisterAck", - 0x0082: "SkinnyMessageStartTone", - 0x0083: "SkinnyMessageStopTone", - 0x0085: "SkinnyMessageSetRinger", - 0x0086: "SkinnyMessageSetLamp", - 0x0087: "SkinnyMessageSetHkFDetect", - 0x0088: "SkinnyMessageSpeakerMode", - 0x0089: "SkinnyMessageSetMicroMode", - 0x008A: "SkinnyMessageStartMediaTransmission", - 0x008B: "SkinnyMessageStopMediaTransmission", - 0x008C: "SkinnyMessageStartMediaReception", - 0x008D: "SkinnyMessageStopMediaReception", - 0x008F: "SkinnyMessageCallInfo", - 0x0090: "SkinnyMessageForwardStat", - 0x0091: "SkinnyMessageSpeedDialStat", - 0x0092: "SkinnyMessageLineStat", - 0x0093: "SkinnyMessageConfigStat", - 0x0094: "SkinnyMessageTimeDate", - 0x0095: "SkinnyMessageStartSessionTransmission", - 0x0096: "SkinnyMessageStopSessionTransmission", - 0x0097: "SkinnyMessageButtonTemplate", - 0x0098: "SkinnyMessageVersion", - 0x0099: "SkinnyMessageDisplayText", - 0x009A: "SkinnyMessageClearDisplay", - 0x009B: "SkinnyMessageCapabilitiesReq", - 0x009C: "SkinnyMessageEnunciatorCommand", - 0x009D: "SkinnyMessageRegisterReject", - 0x009E: "SkinnyMessageServerRes", - 0x009F: "SkinnyMessageReset", - 0x0100: "SkinnyMessageKeepAliveAck", - 0x0101: "SkinnyMessageStartMulticastMediaReception", - 0x0102: "SkinnyMessageStartMulticastMediaTransmission", - 0x0103: "SkinnyMessageStopMulticastMediaReception", - 0x0104: "SkinnyMessageStopMulticastMediaTransmission", - 0x0105: "SkinnyMessageOpenReceiveChannel", - 0x0106: "SkinnyMessageCloseReceiveChannel", - 0x0107: "SkinnyMessageConnectionStatisticsReq", - 0x0108: "SkinnyMessageSoftKeyTemplateRes", - 0x0109: "SkinnyMessageSoftKeySetRes", - 0x0110: "SkinnyMessageStationSelectSoftKeysMessage", - 0x0111: "SkinnyMessageCallState", - 0x0112: "SkinnyMessagePromptStatus", - 0x0113: "SkinnyMessageClearPromptStatus", - 0x0114: "SkinnyMessageDisplayNotify", - 0x0115: "SkinnyMessageClearNotify", - 0x0116: "SkinnyMessageCallPlane", - 0x0117: "SkinnyMessageCallPlane", - 0x0118: "SkinnyMessageUnregisterAck", - 0x0119: "SkinnyMessageBackSpaceReq", - 0x011A: "SkinnyMessageRegisterTokenAck", - 0x011B: "SkinnyMessageRegisterTokenReject", - 0x0042: "SkinnyMessageDeviceToUserDataResponseVersion1", - 0x011C: "SkinnyMessageStartMediaFailureDetection", - 0x011D: "SkinnyMessageDialedNumber", - 0x011E: "SkinnyMessageUserToDeviceData", - 0x011F: "SkinnyMessageFeatureStat", - 0x0120: "SkinnyMessageDisplayPriNotify", - 0x0121: "SkinnyMessageClearPriNotify", - 0x0122: "SkinnyMessageStartAnnouncement", - 0x0123: "SkinnyMessageStopAnnouncement", - 0x0124: "SkinnyMessageAnnouncementFinish", - 0x0127: "SkinnyMessageNotifyDtmfTone", - 0x0128: "SkinnyMessageSendDtmfTone", - 0x0129: "SkinnyMessageSubscribeDtmfPayloadReq", - 0x012A: "SkinnyMessageSubscribeDtmfPayloadRes", - 0x012B: "SkinnyMessageSubscribeDtmfPayloadErr", - 0x012C: "SkinnyMessageUnSubscribeDtmfPayloadReq", - 0x012D: "SkinnyMessageUnSubscribeDtmfPayloadRes", - 0x012E: "SkinnyMessageUnSubscribeDtmfPayloadErr", - 0x012F: "SkinnyMessageServiceURLStat", - 0x0130: "SkinnyMessageCallSelectStat", - 0x0131: "SkinnyMessageOpenMultiMediaChannel", - 0x0132: "SkinnyMessageStartMultiMediaTransmission", - 0x0133: "SkinnyMessageStopMultiMediaTransmission", - 0x0134: "SkinnyMessageMiscellaneousCommand", - 0x0135: "SkinnyMessageFlowControlCommand", - 0x0136: "SkinnyMessageCloseMultiMediaReceiveChannel", - 0x0137: "SkinnyMessageCreateConferenceReq", - 0x0138: "SkinnyMessageDeleteConferenceReq", - 0x0139: "SkinnyMessageModifyConferenceReq", - 0x013A: "SkinnyMessageAddParticipantReq", - 0x013B: "SkinnyMessageDropParticipantReq", - 0x013C: "SkinnyMessageAuditConferenceReq", - 0x013D: "SkinnyMessageAuditParticipantReq", - 0x013F: "SkinnyMessageUserToDeviceDataVersion1", -} - -skinny_callstates = { - 0x1: "Off Hook", - 0x2: "On Hook", - 0x3: "Ring out", - 0xc: "Proceeding", -} - - -skinny_ring_type = { - 0x1: "Ring off" -} - -skinny_speaker_modes = { - 0x1: "Speaker on", - 0x2: "Speaker off" -} - -skinny_lamp_mode = { - 0x1: "Off (?)", - 0x2: "On", -} - -skinny_stimulus = { - 0x9: "Line" -} - - -############ -# Fields # -############ - -class SkinnyDateTimeField(StrFixedLenField): - def __init__(self, name, default): - StrFixedLenField.__init__(self, name, default, 32) - - def m2i(self, pkt, s): - year, month, dow, day, hour, min, sec, millisecond = struct.unpack('<8I', s) # noqa: E501 - return (year, month, day, hour, min, sec) - - def i2m(self, pkt, val): - if isinstance(val, str): - val = self.h2i(pkt, val) - tmp_lst = val[:2] + (0,) + val[2:7] + (0,) - return struct.pack('<8I', *tmp_lst) - - def i2h(self, pkt, x): - if isinstance(x, str): - return x - else: - return time.ctime(time.mktime(x + (0, 0, 0))) - - def i2repr(self, pkt, x): - return self.i2h(pkt, x) - - def h2i(self, pkt, s): - t = () - if isinstance(s, str): - t = time.strptime(s) - t = t[:2] + t[2:-3] - else: - if not s: - y, m, d, h, min, sec, rest, rest, rest = time.gmtime(time.time()) # noqa: E501 - t = (y, m, d, h, min, sec) - else: - t = s - return t - - -########################### -# Packet abstract class # -########################### - -class SkinnyMessageGeneric(Packet): - name = 'Generic message' - - -class SkinnyMessageKeepAlive(Packet): - name = 'keep alive' - - -class SkinnyMessageKeepAliveAck(Packet): - name = 'keep alive ack' - - -class SkinnyMessageOffHook(Packet): - name = 'Off Hook' - fields_desc = [LEIntField("unknown1", 0), - LEIntField("unknown2", 0), ] - - -class SkinnyMessageOnHook(SkinnyMessageOffHook): - name = 'On Hook' - - -class SkinnyMessageCallState(Packet): - name = 'Skinny Call state message' - fields_desc = [LEIntEnumField("state", 1, skinny_callstates), - LEIntField("instance", 1), - LEIntField("callid", 0), - LEIntField("unknown1", 4), - LEIntField("unknown2", 0), - LEIntField("unknown3", 0)] - - -class SkinnyMessageSoftKeyEvent(Packet): - name = 'Soft Key Event' - fields_desc = [LEIntField("key", 0), - LEIntField("instance", 1), - LEIntField("callid", 0)] - - -class SkinnyMessageSetRinger(Packet): - name = 'Ring message' - fields_desc = [LEIntEnumField("ring", 0x1, skinny_ring_type), - LEIntField("unknown1", 0), - LEIntField("unknown2", 0), - LEIntField("unknown3", 0)] - - -_skinny_tones = { - 0x21: 'Inside dial tone', - 0x22: 'xxx', - 0x23: 'xxx', - 0x24: 'Alerting tone', - 0x25: 'Reorder Tone' -} - - -class SkinnyMessageStartTone(Packet): - name = 'Start tone' - fields_desc = [LEIntEnumField("tone", 0x21, _skinny_tones), - LEIntField("unknown1", 0), - LEIntField("instance", 1), - LEIntField("callid", 0)] - - -class SkinnyMessageStopTone(SkinnyMessageGeneric): - name = 'stop tone' - fields_desc = [LEIntField("instance", 1), - LEIntField("callid", 0)] - - -class SkinnyMessageSpeakerMode(Packet): - name = 'Speaker mdoe' - fields_desc = [LEIntEnumField("ring", 0x1, skinny_speaker_modes)] - - -class SkinnyMessageSetLamp(Packet): - name = 'Lamp message (light of the phone)' - fields_desc = [LEIntEnumField("stimulus", 0x5, skinny_stimulus), - LEIntField("instance", 1), - LEIntEnumField("mode", 2, skinny_lamp_mode)] - - -class SkinnyMessageStationSelectSoftKeysMessage(Packet): - name = 'Station Select Soft Keys Message' - fields_desc = [LEIntField("instance", 1), - LEIntField("callid", 0), - LEIntField("set", 0), - LEIntField("map", 0xffff)] - - -class SkinnyMessagePromptStatus(Packet): - name = 'Prompt status' - fields_desc = [LEIntField("timeout", 0), - StrFixedLenField("text", b"\0" * 32, 32), - LEIntField("instance", 1), - LEIntField("callid", 0)] - - -class SkinnyMessageCallPlane(Packet): - name = 'Activate/Deactivate Call Plane Message' - fields_desc = [LEIntField("instance", 1)] - - -class SkinnyMessageTimeDate(Packet): - name = 'Setting date and time' - fields_desc = [SkinnyDateTimeField("settime", None), - LEIntField("timestamp", 0)] - - -class SkinnyMessageClearPromptStatus(Packet): - name = 'clear prompt status' - fields_desc = [LEIntField("instance", 1), - LEIntField("callid", 0)] - - -class SkinnyMessageKeypadButton(Packet): - name = 'keypad button' - fields_desc = [LEIntField("key", 0), - LEIntField("instance", 1), - LEIntField("callid", 0)] - - -class SkinnyMessageDialedNumber(Packet): - name = 'dialed number' - fields_desc = [StrFixedLenField("number", "1337", 24), - LEIntField("instance", 1), - LEIntField("callid", 0)] - - -_skinny_message_callinfo_restrictions = ['CallerName', 'CallerNumber', 'CalledName', 'CalledNumber', 'OriginalCalledName', 'OriginalCalledNumber', 'LastRedirectName', 'LastRedirectNumber'] + ['Bit%d' % i for i in range(8, 15)] # noqa: E501 - - -class SkinnyMessageCallInfo(Packet): - name = 'call information' - fields_desc = [StrFixedLenField("callername", "Jean Valjean", 40), - StrFixedLenField("callernum", "1337", 24), - StrFixedLenField("calledname", "Causette", 40), - StrFixedLenField("callednum", "1034", 24), - LEIntField("lineinstance", 1), - LEIntField("callid", 0), - StrFixedLenField("originalcalledname", "Causette", 40), - StrFixedLenField("originalcallednum", "1034", 24), - StrFixedLenField("lastredirectingname", "Causette", 40), - StrFixedLenField("lastredirectingnum", "1034", 24), - LEIntField("originalredirectreason", 0), - LEIntField("lastredirectreason", 0), - StrFixedLenField('voicemailboxG', b'\0' * 24, 24), - StrFixedLenField('voicemailboxD', b'\0' * 24, 24), - StrFixedLenField('originalvoicemailboxD', b'\0' * 24, 24), - StrFixedLenField('lastvoicemailboxD', b'\0' * 24, 24), - LEIntField('security', 0), - FlagsField('restriction', 0, 16, _skinny_message_callinfo_restrictions), # noqa: E501 - LEIntField('unknown', 0)] - - -class SkinnyRateField(LEIntField): - def i2repr(self, pkt, x): - if x is None: - x = 0 - return '%d ms/pkt' % x - - -_skinny_codecs = { - 0x0: 'xxx', - 0x1: 'xxx', - 0x2: 'xxx', - 0x3: 'xxx', - 0x4: 'G711 ulaw 64k' -} - -_skinny_echo = { - 0x0: 'echo cancellation off', - 0x1: 'echo cancellation on' -} - - -class SkinnyMessageOpenReceiveChannel(Packet): - name = 'open receive channel' - fields_desc = [LEIntField('conference', 0), - LEIntField('passthru', 0), - SkinnyRateField('rate', 20), - LEIntEnumField('codec', 4, _skinny_codecs), - LEIntEnumField('echo', 0, _skinny_echo), - LEIntField('unknown1', 0), - LEIntField('callid', 0)] - - def guess_payload_class(self, p): - return conf.padding_layer - - -_skinny_receive_channel_status = { - 0x0: 'ok', - 0x1: 'ko' -} - - -class SkinnyMessageOpenReceiveChannelAck(Packet): - name = 'open receive channel' - fields_desc = [LEIntEnumField('status', 0, _skinny_receive_channel_status), - IPField('remote', '0.0.0.0'), - LEIntField('port', RandShort()), - LEIntField('passthru', 0), - LEIntField('callid', 0)] - - -_skinny_silence = { - 0x0: 'silence suppression off', - 0x1: 'silence suppression on', -} - - -class SkinnyFramePerPacketField(LEIntField): - def i2repr(self, pkt, x): - if x is None: - x = 0 - return '%d frames/pkt' % x - - -class SkinnyMessageStartMediaTransmission(Packet): - name = 'start multimedia transmission' - fields_desc = [LEIntField('conference', 0), - LEIntField('passthru', 0), - IPField('remote', '0.0.0.0'), - LEIntField('port', RandShort()), - SkinnyRateField('rate', 20), - LEIntEnumField('codec', 4, _skinny_codecs), - LEIntField('precedence', 200), - LEIntEnumField('silence', 0, _skinny_silence), - SkinnyFramePerPacketField('maxframes', 0), - LEIntField('unknown1', 0), - LEIntField('callid', 0)] - - def guess_payload_class(self, p): - return conf.padding_layer - - -class SkinnyMessageCloseReceiveChannel(Packet): - name = 'close receive channel' - fields_desc = [LEIntField('conference', 0), - LEIntField('passthru', 0), - IPField('remote', '0.0.0.0'), - LEIntField('port', RandShort()), - SkinnyRateField('rate', 20), - LEIntEnumField('codec', 4, _skinny_codecs), - LEIntField('precedence', 200), - LEIntEnumField('silence', 0, _skinny_silence), - LEIntField('callid', 0)] - - -class SkinnyMessageStopMultiMediaTransmission(Packet): - name = 'stop multimedia transmission' - fields_desc = [LEIntField('conference', 0), - LEIntField('passthru', 0), - LEIntField('callid', 0)] - - -class Skinny(Packet): - name = "Skinny" - fields_desc = [LEIntField("len", None), - LEIntField("res", 0), - LEIntEnumField("msg", 0, skinny_messages_cls)] - - def post_build(self, pkt, p): - if self.len is None: - # on compte pas les headers len et reserved - tmp_len = len(p) + len(pkt) - 8 - pkt = struct.pack('@I', tmp_len) + pkt[4:] - return pkt + p - -# An helper - - -def get_cls(name, fallback_cls): - return globals().get(name, fallback_cls) - # return __builtin__.__dict__.get(name, fallback_cls) - - -for msgid, strcls in skinny_messages_cls.items(): - cls = get_cls(strcls, SkinnyMessageGeneric) - bind_layers(Skinny, cls, {"msg": msgid}) - -bind_layers(TCP, Skinny, {"dport": 2000}) -bind_layers(TCP, Skinny, {"sport": 2000}) - -if __name__ == "__main__": - from scapy.main import interact - interact(mydict=globals(), mybanner="Welcome to Skinny add-on") diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/socks.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/socks.py deleted file mode 100644 index d4ec6b23b1..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/socks.py +++ /dev/null @@ -1,182 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -# scapy.contrib.description = Socket Secure (SOCKS) -# scapy.contrib.status = loads - -"""SOCKS4/5 Protocol - -You can change the server ports that are used in the SOCKS layer by editing. -conf.contribs['socks']['serverports'] -""" - -from scapy.config import conf -from scapy.error import warning -from scapy.layers.dns import DNSStrField -from scapy.layers.inet import TCP, UDP -from scapy.layers.inet6 import IP6Field -from scapy.fields import ByteField, ByteEnumField, ShortField, IPField, \ - StrField, MultipleTypeField -from scapy.packet import Packet, bind_layers, bind_bottom_up - -# TODO: support the 3 different authentication exchange procedures for SOCKS5 # noqa: E501 -# 1 - Plain (https://tools.ietf.org/html/rfc1928 - 3.Procedure for TCP-based clients) # noqa: E501 -# 2 - Username/password (https://tools.ietf.org/html/rfc1929) -# 3 - GSS-API (https://tools.ietf.org/html/rfc1961) - -conf.contribs.setdefault('socks', {}) -conf.contribs['socks'].setdefault('serverports', [1080]) - - -class SOCKS(Packet): - fields_desc = [ - ByteEnumField("vn", 0x5, - {0x4: "v4 - Request", 0x0: "v4 - Reply", 0x5: "v5"}), - ] - - def guess_payload_class(self, pkt): - d_port = s_port = True - if self.underlayer and isinstance(self.underlayer, TCP): - ports = conf.contribs['socks']['serverports'] - d_port = self.underlayer.dport in ports - s_port = self.underlayer.sport in ports - if self.vn == 0x5: - if d_port: - return SOCKS5Request - elif s_port: - return SOCKS5Reply - elif self.vn == 0x4: - if d_port: - return SOCKS4Request - elif self.vn == 0x0: - if s_port: - return SOCKS4Reply - warning("No TCP underlayer, or dport/sport not in " - "conf.contribs['socks']['serverports']. " - "Assuming a SOCKS v5 request layer") - return SOCKS5Request - - def add_payload(self, payload): - if self.underlayer and isinstance(self.underlayer, TCP): - if isinstance(payload, (SOCKS5Request, SOCKS4Request)): - self.underlayer.dport = 1080 - self.underlayer.sport = 1081 - elif isinstance(payload, (SOCKS5Reply, SOCKS4Reply)): - self.underlayer.sport = 1080 - self.underlayer.dport = 1081 - Packet.add_payload(self, payload) - - -bind_bottom_up(TCP, SOCKS, sport=1080) -bind_bottom_up(TCP, SOCKS, dport=1080) - -# SOCKS v4 - -_socks4_cd_request = { - 1: "Connect", - 2: "Bind" -} - - -class SOCKS4Request(Packet): - name = "SOCKS 4 - Request" - overload_fields = {SOCKS: {"vn": 0x4}} - fields_desc = [ - ByteEnumField("cd", 1, _socks4_cd_request), - ShortField("dstport", 80), - IPField("dst", "0.0.0.0"), - StrField("userid", ""), - ByteField("null", 0), - ] - - -_socks4_cd_reply = { - 90: "Request granted", - 91: "Request rejected", - 92: "Request rejected - SOCKS server cannot connect to identd", - 93: "Request rejected - user-ids mismatch" -} - - -class SOCKS4Reply(Packet): - name = "SOCKS 4 - Reply" - overload_fields = {SOCKS: {"vn": 0x0}} - fields_desc = [ - ByteEnumField("cd", 90, _socks4_cd_reply), - ] + SOCKS4Request.fields_desc[1:-2] # Re-use dstport, dst and userid - -# SOCKS v5 - TCP - - -_socks5_cdtypes = { - 1: "Connect", - 2: "Bind", - 3: "UDP associate", -} - - -class SOCKS5Request(Packet): - name = "SOCKS 5 - Request" - overload_fields = {SOCKS: {"vn": 0x5}} - fields_desc = [ - ByteEnumField("cd", 0x0, _socks5_cdtypes), - ByteField("res", 0), - ByteEnumField("atyp", 0x1, - {0x1: "IPv4", 0x3: "DomainName", 0x4: "IPv6"}), - MultipleTypeField( - [ - # IPv4 - (IPField("addr", "0.0.0.0"), lambda pkt: pkt.atyp == 0x1), - # DNS - (DNSStrField("addr", ""), lambda pkt: pkt.atyp == 0x3), - # IPv6 - (IP6Field("addr", "::"), lambda pkt: pkt.atyp == 0x4), - ], - StrField("addr", "") - ), - ShortField("port", 80), - ] - - -_socks5_rep = { - 0: "succeeded", - 1: "general server failure", - 2: "connection not allowed by ruleset", - 3: "network unreachable", - 4: "host unreachable", - 5: "connection refused", - 6: "TTL expired", - 7: "command not supported", - 8: "address type not supported", -} - - -class SOCKS5Reply(Packet): - name = "SOCKS 5 - Reply" - overload_fields = {SOCKS: {"vn": 0x5}} - # All fields are the same except the first one - fields_desc = [ - ByteEnumField("rep", 0x0, _socks5_rep), - ] + SOCKS5Request.fields_desc[1:] - - -# SOCKS v5 - UDP - -class SOCKS5UDP(Packet): - name = "SOCKS 5 - UDP Header" - fields_desc = [ - ShortField("res", 0), - ByteField("frag", 0), - ] + SOCKS5Request.fields_desc[2:] # Re-use the atyp, addr and port fields - - def guess_payload_class(self, s): - if self.port == 0: - return conf.raw_layer - return UDP(sport=self.port, dport=self.port).guess_payload_class(None) - - -bind_bottom_up(UDP, SOCKS5UDP, sport=1080) -bind_bottom_up(UDP, SOCKS5UDP, sport=1080) -bind_layers(UDP, SOCKS5UDP, sport=1080, dport=1080) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/spbm.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/spbm.py deleted file mode 100644 index 119d757f13..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/spbm.py +++ /dev/null @@ -1,60 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# IEEE 802.1aq - Shorest Path Bridging Mac-in-mac (SPBM): -# Ethernet based link state protocol that enables Layer 2 Unicast, Layer 2 Multicast, Layer 3 Unicast, and Layer 3 Multicast virtualized services # noqa: E501 -# https://en.wikipedia.org/wiki/IEEE_802.1aq -# Modeled after the scapy VXLAN contribution - -# scapy.contrib.description = Shorest Path Bridging Mac-in-mac (SBPM) -# scapy.contrib.status = loads - -""" - Example SPB Frame Creation - - Note the outer Dot1Q Ethertype marking (0x88e7) - - backboneEther = Ether(dst='00:bb:00:00:90:00', src='00:bb:00:00:40:00', type=0x8100) # noqa: E501 - backboneDot1Q = Dot1Q(vlan=4051,type=0x88e7) - backboneServiceID = SPBM(prio=1,isid=20011) - customerEther = Ether(dst='00:1b:4f:5e:ca:00',src='00:00:00:00:00:01',type=0x8100) # noqa: E501 - customerDot1Q = Dot1Q(prio=1,vlan=11,type=0x0800) - customerIP = IP(src='10.100.11.10',dst='10.100.12.10',id=0x0629,len=106) # noqa: E501 - customerUDP = UDP(sport=1024,dport=1025,chksum=0,len=86) - - spb_example = backboneEther/backboneDot1Q/backboneServiceID/customerEther/customerDot1Q/customerIP/customerUDP/"Payload" # noqa: E501 -""" - -from scapy.packet import Packet, bind_layers -from scapy.fields import BitField, ThreeBytesField -from scapy.layers.l2 import Ether, Dot1Q, Dot1AD - - -class SPBM(Packet): - name = "SPBM" - fields_desc = [BitField("prio", 0, 3), - BitField("dei", 0, 1), - BitField("nca", 0, 1), - BitField("res1", 0, 1), - BitField("res2", 0, 2), - ThreeBytesField("isid", 0)] - - def mysummary(self): - return self.sprintf("SPBM (isid=%SPBM.isid%") - - -bind_layers(Ether, SPBM, type=0x88e7) -bind_layers(Dot1Q, SPBM, type=0x88e7) -bind_layers(Dot1AD, SPBM, type=0x88e7) -bind_layers(SPBM, Ether) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/tacacs.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/tacacs.py deleted file mode 100755 index ed933f10d4..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/tacacs.py +++ /dev/null @@ -1,453 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# Copyright (C) 2017 Francois Contat - -# Based on tacacs+ v6 draft https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06 # noqa: E501 - -# scapy.contrib.description = Terminal Access Controller Access-Control System+ -# scapy.contrib.status = loads - -import struct -import hashlib - -from scapy.packet import Packet, bind_layers -from scapy.fields import ByteEnumField, ByteField, IntField -from scapy.fields import FieldListField -from scapy.fields import FieldLenField, ConditionalField, StrLenField -from scapy.layers.inet import TCP -from scapy.compat import chb, orb -from scapy.config import conf -from scapy.modules.six.moves import range - -SECRET = 'test' - - -def obfuscate(pay, secret, session_id, version, seq): - ''' - - Obfuscation methodology from section 3.7 - https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-3.7 - - ''' - - pad = b"" - curr_pad = b"" - - # pad length must equal the payload to obfuscate. - # pad = {MD5_1 [,MD5_2 [ ... ,MD5_n]]} - - while len(pad) < len(pay): - - msg = hashlib.md5() - msg.update(struct.pack('!I', session_id)) - msg.update(secret.encode()) - msg.update(struct.pack('!BB', version, seq)) - msg.update(curr_pad) - curr_pad = msg.digest() - pad += curr_pad - - # Obf/Unobfuscation via XOR operation between plaintext and pad - - return b"".join(chb(orb(pad[i]) ^ orb(pay[i])) for i in range(len(pay))) - - -TACACSPRIVLEVEL = {15: 'Root', - 1: 'User', - 0: 'Minimum'} - -########################## -# Authentication Packets # -########################## - -TACACSVERSION = {1: 'Tacacs', - 192: 'Tacacs+'} - -TACACSTYPE = {1: 'Authentication', - 2: 'Authorization', - 3: 'Accounting'} - -TACACSFLAGS = {1: 'Unencrypted', - 4: 'Single Connection'} - -TACACSAUTHENACTION = {1: 'Login', - 2: 'Change Pass', - 4: 'Send Authentication'} - -TACACSAUTHENTYPE = {1: 'ASCII', - 2: 'PAP', - 3: 'CHAP', - 4: 'ARAP', # Deprecated - 5: 'MSCHAP', - 6: 'MSCHAPv2'} - -TACACSAUTHENSERVICE = {0: 'None', - 1: 'Login', - 2: 'Enable', - 3: 'PPP', - 4: 'ARAP', - 5: 'PT', - 6: 'RCMD', - 7: 'X25', - 8: 'NASI', - 9: 'FwProxy'} - -TACACSREPLYPASS = {1: 'PASS', - 2: 'FAIL', - 3: 'GETDATA', - 4: 'GETUSER', - 5: 'GETPASS', - 6: 'RESTART', - 7: 'ERROR', - 21: 'FOLLOW'} - -TACACSREPLYFLAGS = {1: 'NOECHO'} - -TACACSCONTINUEFLAGS = {1: 'ABORT'} - - -class TacacsAuthenticationStart(Packet): - - ''' - - Tacacs authentication start body from section 4.1 - https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-4.1 - - ''' - - name = 'Tacacs Authentication Start Body' - fields_desc = [ByteEnumField('action', 1, TACACSAUTHENACTION), - ByteEnumField('priv_lvl', 1, TACACSPRIVLEVEL), - ByteEnumField('authen_type', 1, TACACSAUTHENTYPE), - ByteEnumField('authen_service', 1, TACACSAUTHENSERVICE), - FieldLenField('user_len', None, fmt='!B', length_of='user'), - FieldLenField('port_len', None, fmt='!B', length_of='port'), - FieldLenField('rem_addr_len', None, fmt='!B', length_of='rem_addr'), # noqa: E501 - FieldLenField('data_len', None, fmt='!B', length_of='data'), - ConditionalField(StrLenField('user', '', length_from=lambda x: x.user_len), # noqa: E501 - lambda x: x != ''), - StrLenField('port', '', length_from=lambda x: x.port_len), - StrLenField('rem_addr', '', length_from=lambda x: x.rem_addr_len), # noqa: E501 - StrLenField('data', '', length_from=lambda x: x.data_len)] - - -class TacacsAuthenticationReply(Packet): - - ''' - - Tacacs authentication reply body from section 4.2 - https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-4.2 - - ''' - - name = 'Tacacs Authentication Reply Body' - fields_desc = [ByteEnumField('status', 1, TACACSREPLYPASS), - ByteEnumField('flags', 0, TACACSREPLYFLAGS), - FieldLenField('server_msg_len', None, fmt='!H', length_of='server_msg'), # noqa: E501 - FieldLenField('data_len', None, fmt='!H', length_of='data'), - StrLenField('server_msg', '', length_from=lambda x: x.server_msg_len), # noqa: E501 - StrLenField('data', '', length_from=lambda x: x.data_len)] - - -class TacacsAuthenticationContinue(Packet): - - ''' - - Tacacs authentication continue body from section 4.3 - https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-4.3 - - ''' - - name = 'Tacacs Authentication Continue Body' - fields_desc = [FieldLenField('user_msg_len', None, fmt='!H', length_of='user_msg'), # noqa: E501 - FieldLenField('data_len', None, fmt='!H', length_of='data'), - ByteEnumField('flags', 1, TACACSCONTINUEFLAGS), - StrLenField('user_msg', '', length_from=lambda x: x.user_msg_len), # noqa: E501 - StrLenField('data', '', length_from=lambda x: x.data_len)] - -######################### -# Authorization Packets # -######################### - - -TACACSAUTHORTYPE = {0: 'Not Set', - 1: 'None', - 2: 'Kerberos 5', - 3: 'Line', - 4: 'Enable', - 5: 'Local', - 6: 'Tacacs+', - 8: 'Guest', - 16: 'Radius', - 17: 'Kerberos 4', - 32: 'RCMD'} - -TACACSAUTHORSTATUS = {1: 'Pass Add', - 2: 'Pass repl', - 16: 'Fail', - 17: 'Error', - 33: 'Follow'} - - -class TacacsAuthorizationRequest(Packet): - - ''' - - Tacacs authorization request body from section 5.1 - https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-5.1 - - ''' - - name = 'Tacacs Authorization Request Body' - fields_desc = [ByteEnumField('authen_method', 0, TACACSAUTHORTYPE), - ByteEnumField('priv_lvl', 1, TACACSPRIVLEVEL), - ByteEnumField('authen_type', 1, TACACSAUTHENTYPE), - ByteEnumField('authen_service', 1, TACACSAUTHENSERVICE), - FieldLenField('user_len', None, fmt='!B', length_of='user'), - FieldLenField('port_len', None, fmt='!B', length_of='port'), - FieldLenField('rem_addr_len', None, fmt='!B', length_of='rem_addr'), # noqa: E501 - FieldLenField('arg_cnt', None, fmt='!B', count_of='arg_len_list'), # noqa: E501 - FieldListField('arg_len_list', [], ByteField('', 0), - length_from=lambda pkt: pkt.arg_cnt), - StrLenField('user', '', length_from=lambda x: x.user_len), - StrLenField('port', '', length_from=lambda x: x.port_len), - StrLenField('rem_addr', '', length_from=lambda x: x.rem_addr_len)] # noqa: E501 - - def guess_payload_class(self, pay): - if self.arg_cnt > 0: - return TacacsPacketArguments - return conf.padding_layer - - -class TacacsAuthorizationReply(Packet): - - ''' - - Tacacs authorization reply body from section 5.2 - https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-5.2 - - ''' - - name = 'Tacacs Authorization Reply Body' - fields_desc = [ByteEnumField('status', 0, TACACSAUTHORSTATUS), - FieldLenField('arg_cnt', None, fmt='!B', count_of='arg_len_list'), # noqa: E501 - FieldLenField('server_msg_len', None, fmt='!H', length_of='server_msg'), # noqa: E501 - FieldLenField('data_len', None, fmt='!H', length_of='data'), - FieldListField('arg_len_list', [], ByteField('', 0), - length_from=lambda pkt: pkt.arg_cnt), - StrLenField('server_msg', '', length_from=lambda x: x.server_msg_len), # noqa: E501 - StrLenField('data', '', length_from=lambda x: x.data_len)] - - def guess_payload_class(self, pay): - if self.arg_cnt > 0: - return TacacsPacketArguments - return conf.padding_layer - - -###################### -# Accounting Packets # -###################### - -TACACSACNTFLAGS = {2: 'Start', - 4: 'Stop', - 8: 'Watchdog'} - -TACACSACNTSTATUS = {1: 'Success', - 2: 'Error', - 33: 'Follow'} - - -class TacacsAccountingRequest(Packet): - - ''' - - Tacacs accounting request body from section 6.1 - https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-6.1 - - ''' - - name = 'Tacacs Accounting Request Body' - fields_desc = [ByteEnumField('flags', 0, TACACSACNTFLAGS), - ByteEnumField('authen_method', 0, TACACSAUTHORTYPE), - ByteEnumField('priv_lvl', 1, TACACSPRIVLEVEL), - ByteEnumField('authen_type', 1, TACACSAUTHENTYPE), - ByteEnumField('authen_service', 1, TACACSAUTHENSERVICE), - FieldLenField('user_len', None, fmt='!B', length_of='user'), - FieldLenField('port_len', None, fmt='!B', length_of='port'), - FieldLenField('rem_addr_len', None, fmt='!B', length_of='rem_addr'), # noqa: E501 - FieldLenField('arg_cnt', None, fmt='!B', count_of='arg_len_list'), # noqa: E501 - FieldListField('arg_len_list', [], ByteField('', 0), - length_from=lambda pkt: pkt.arg_cnt), - StrLenField('user', '', length_from=lambda x: x.user_len), - StrLenField('port', '', length_from=lambda x: x.port_len), - StrLenField('rem_addr', '', length_from=lambda x: x.rem_addr_len)] # noqa: E501 - - def guess_payload_class(self, pay): - if self.arg_cnt > 0: - return TacacsPacketArguments - return conf.padding_layer - - -class TacacsAccountingReply(Packet): - - ''' - - Tacacs accounting reply body from section 6.2 - https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-6.2 - - ''' - - name = 'Tacacs Accounting Reply Body' - fields_desc = [FieldLenField('server_msg_len', None, fmt='!H', length_of='server_msg'), # noqa: E501 - FieldLenField('data_len', None, fmt='!H', length_of='data'), - ByteEnumField('status', None, TACACSACNTSTATUS), - StrLenField('server_msg', '', length_from=lambda x: x.server_msg_len), # noqa: E501 - StrLenField('data', '', length_from=lambda x: x.data_len)] - - -class TacacsPacketArguments(Packet): - - ''' - - Class defined to handle the arguments listed at the end of tacacs+ - Authorization and Accounting packets. - - ''' - - __slots__ = ['_len'] - name = 'Arguments in Tacacs+ packet' - fields_desc = [StrLenField('data', '', length_from=lambda pkt: pkt._len)] - - def pre_dissect(self, s): - cur = self.underlayer - i = 0 - - # Searching the position in layer in order to get its length - - while isinstance(cur, TacacsPacketArguments): - cur = cur.underlayer - i += 1 - self._len = cur.arg_len_list[i] - return s - - def guess_payload_class(self, pay): - cur = self.underlayer - i = 0 - - # Guessing if Argument packet. Nothing in encapsulated via tacacs+ - - while isinstance(cur, TacacsPacketArguments): - cur = cur.underlayer - i += 1 - if i + 1 < cur.arg_cnt: - return TacacsPacketArguments - return conf.padding_layer - - -class TacacsClientPacket(Packet): - - ''' - - Super class for tacacs packet in order to get them unencrypted - Obfuscation methodology from section 3.7 - https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-3.7 - - ''' - - def post_dissect(self, pay): - - if self.flags == 0: - pay = obfuscate(pay, SECRET, self.session_id, self.version, self.seq) # noqa: E501 - return pay - - -class TacacsHeader(TacacsClientPacket): - - ''' - - Tacacs Header packet from section 3.8 - https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-3.8 - - ''' - - name = 'Tacacs Header' - fields_desc = [ByteEnumField('version', 192, TACACSVERSION), - ByteEnumField('type', 1, TACACSTYPE), - ByteField('seq', 1), - ByteEnumField('flags', 0, TACACSFLAGS), - IntField('session_id', 0), - IntField('length', None)] - - def guess_payload_class(self, payload): - - # Guessing packet type from type and seq values - - # Authentication packet - type 1 - - if self.type == 1: - if self.seq % 2 == 0: - return TacacsAuthenticationReply - if sum(struct.unpack('bbbb', payload[4:8])) == len(payload[8:]): - return TacacsAuthenticationStart - elif sum(struct.unpack('!hh', payload[:4])) == len(payload[5:]): - return TacacsAuthenticationContinue - - # Authorization packet - type 2 - - if self.type == 2: - if self.seq % 2 == 0: - return TacacsAuthorizationReply - return TacacsAuthorizationRequest - - # Accounting packet - type 3 - - if self.type == 3: - if self.seq % 2 == 0: - return TacacsAccountingReply - return TacacsAccountingRequest - - return conf.raw_layer - - def post_build(self, p, pay): - - # Setting length of packet to obfuscate if not filled by user - - if self.length is None and pay: - p = p[:-4] + struct.pack('!I', len(pay)) - - if self.flags == 0: - - pay = obfuscate(pay, SECRET, self.session_id, self.version, self.seq) # noqa: E501 - return p + pay - - return p - - def hashret(self): - return struct.pack('I', self.session_id) - - def answers(self, other): - return (isinstance(other, TacacsHeader) and - self.seq == other.seq + 1 and - self.type == other.type and - self.session_id == other.session_id) - - -bind_layers(TCP, TacacsHeader, dport=49) -bind_layers(TCP, TacacsHeader, sport=49) -bind_layers(TacacsHeader, TacacsAuthenticationStart, type=1, dport=49) -bind_layers(TacacsHeader, TacacsAuthenticationReply, type=1, sport=49) - -if __name__ == '__main__': - from scapy.main import interact - interact(mydict=globals(), mybanner='tacacs+') diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/tzsp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/tzsp.py deleted file mode 100644 index a959579659..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/tzsp.py +++ /dev/null @@ -1,486 +0,0 @@ -#! /usr/bin/env python -# -# scapy.contrib.description = TaZmen Sniffer Protocol (TZSP) -# scapy.contrib.status = loads - -""" - TZSP - TaZmen Sniffer Protocol - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - :author: Thomas Tannhaeuser, hecke@naberius.de - :license: GPLv2 - - This module is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This module 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. - - :description: - - This module provides Scapy layers for the TZSP protocol. - - references: - - https://en.wikipedia.org/wiki/TZSP - - https://web.archive.org/web/20050404125022/http://www.networkchemistry.com/support/appnotes/an001_tzsp.html # noqa: E501 - - :NOTES: - - to allow Scapy to dissect this layer automatically, you need to bind the TZSP layer to UDP using # noqa: E501 - the default TZSP port (0x9090), e.g. - - bind_layers(UDP, TZSP, sport=TZSP_PORT_DEFAULT) - bind_layers(UDP, TZSP, dport=TZSP_PORT_DEFAULT) - - - packet format definition from www.networkchemistry.com is different from the one given by wikipedia # noqa: E501 - - seems Wireshark implements the wikipedia protocol version (didn't dive into their code) # noqa: E501 - - observed (miss)behavior of Wireshark (2.2.6) - - fails to decode RSSI & SNR using short values - only one byte taken - - SNR is labeled as silence - - WlanRadioHdrSerial is labeled as Sensor MAC - - doesn't know the packet count tag (40 / 0x28) - -""" -from scapy.compat import orb -from scapy.contrib.avs import AVSWLANHeader -from scapy.error import warning, Scapy_Exception -from scapy.fields import ByteField, ShortEnumField, IntField, FieldLenField, YesNoByteField # noqa: E501 -from scapy.layers.dot11 import Packet, Dot11, PrismHeader -from scapy.layers.l2 import Ether -from scapy.fields import StrLenField, ByteEnumField, ShortField, XStrLenField -from scapy.packet import Raw - - -TZSP_PORT_DEFAULT = 0x9090 - - -class TZSP(Packet): - TYPE_RX_PACKET = 0x00 - TYPE_TX_PACKET = 0x01 - TYPE_CONFIG = 0x03 - TYPE_KEEPALIVE = TYPE_NULL = 0x04 - TYPE_PORT = 0x05 - - TYPES = { - TYPE_RX_PACKET: 'RX_PACKET', - TYPE_TX_PACKET: 'TX_PACKET', - TYPE_CONFIG: 'CONFIG', - TYPE_NULL: 'KEEPALIVE/NULL', - TYPE_PORT: 'PORT', - } - - ENCAPSULATED_ETHERNET = 0x01 - ENCAPSULATED_IEEE_802_11 = 0x12 - ENCAPSULATED_PRISM_HEADER = 0x77 - ENCAPSULATED_WLAN_AVS = 0x7f - - ENCAPSULATED_PROTOCOLS = { - ENCAPSULATED_ETHERNET: 'ETHERNET', - ENCAPSULATED_IEEE_802_11: 'IEEE 802.11', - ENCAPSULATED_PRISM_HEADER: 'PRISM HEADER', - ENCAPSULATED_WLAN_AVS: 'WLAN AVS' - } - - ENCAPSULATED_PROTOCOL_CLASSES = { - ENCAPSULATED_ETHERNET: Ether, - ENCAPSULATED_IEEE_802_11: Dot11, - ENCAPSULATED_PRISM_HEADER: PrismHeader, - ENCAPSULATED_WLAN_AVS: AVSWLANHeader - } - - fields_desc = [ - ByteField('version', 0x01), - ByteEnumField('type', TYPE_RX_PACKET, TYPES), - ShortEnumField('encapsulated_protocol', ENCAPSULATED_ETHERNET, ENCAPSULATED_PROTOCOLS) # noqa: E501 - ] - - def get_encapsulated_payload_class(self): - """ - get the class that holds the encapsulated payload of the TZSP packet - :return: class representing the payload, Raw() on error - """ - - try: - return TZSP.ENCAPSULATED_PROTOCOL_CLASSES[self.encapsulated_protocol] # noqa: E501 - except KeyError: - warning( - 'unknown or invalid encapsulation type (%i) - returning payload as raw()' % self.encapsulated_protocol) # noqa: E501 - return Raw - - def guess_payload_class(self, payload): - if self.type == TZSP.TYPE_KEEPALIVE: - if len(payload): - warning('payload (%i bytes) in KEEPALIVE/NULL packet' % len(payload)) # noqa: E501 - return Raw - else: - return _tzsp_guess_next_tag(payload) - - def get_encapsulated_payload(self): - - has_encapsulated_data = self.type == TZSP.TYPE_RX_PACKET or self.type == TZSP.TYPE_TX_PACKET # noqa: E501 - - if has_encapsulated_data: - end_tag_lyr = self.payload.getlayer(TZSPTagEnd) - if end_tag_lyr: - return end_tag_lyr.payload - else: - return None - - -def _tzsp_handle_unknown_tag(payload, tag_type): - - payload_len = len(payload) - - if payload_len < 2: - warning('invalid or unknown tag type (%i) and too short packet - treat remaining data as Raw' % tag_type) # noqa: E501 - return Raw - - tag_data_length = orb(payload[1]) - - tag_data_fits_in_payload = (tag_data_length + 2) <= payload_len - if not tag_data_fits_in_payload: - warning('invalid or unknown tag type (%i) and too short packet - treat remaining data as Raw' % tag_type) # noqa: E501 - return Raw - - warning('invalid or unknown tag type (%i)' % tag_type) - - return TZSPTagUnknown - - -def _tzsp_guess_next_tag(payload): - """ - :return: class representing the next tag, Raw on error, None on missing payload # noqa: E501 - """ - - if not payload: - warning('missing payload') - return None - - tag_type = orb(payload[0]) - - try: - tag_class_definition = _TZSP_TAG_CLASSES[tag_type] - - except KeyError: - - return _tzsp_handle_unknown_tag(payload, tag_type) - - if type(tag_class_definition) is not dict: - return tag_class_definition - - try: - length = orb(payload[1]) - except IndexError: - length = None - - if not length: - warning('no tag length given - packet to short') - return Raw - - try: - return tag_class_definition[length] - except KeyError: - warning('invalid tag length {} for tag type {}'.format(length, tag_type)) # noqa: E501 - return Raw - - -class _TZSPTag(Packet): - TAG_TYPE_PADDING = 0x00 - TAG_TYPE_END = 0x01 - TAG_TYPE_RAW_RSSI = 0x0a - TAG_TYPE_SNR = 0x0b - TAG_TYPE_DATA_RATE = 0x0c - TAG_TYPE_TIMESTAMP = 0x0d - TAG_TYPE_CONTENTION_FREE = 0x0f - TAG_TYPE_DECRYPTED = 0x10 - TAG_TYPE_FCS_ERROR = 0x11 - TAG_TYPE_RX_CHANNEL = 0x12 - TAG_TYPE_PACKET_COUNT = 0x28 - TAG_TYPE_RX_FRAME_LENGTH = 0x29 - TAG_TYPE_WLAN_RADIO_HDR_SERIAL = 0x3c - - TAG_TYPES = { - TAG_TYPE_PADDING: 'PADDING', - TAG_TYPE_END: 'END', - TAG_TYPE_RAW_RSSI: 'RAW_RSSI', - TAG_TYPE_SNR: 'SNR', - TAG_TYPE_DATA_RATE: 'DATA_RATE', - TAG_TYPE_TIMESTAMP: 'TIMESTAMP', - TAG_TYPE_CONTENTION_FREE: 'CONTENTION_FREE', - TAG_TYPE_DECRYPTED: 'DECRYPTED', - TAG_TYPE_FCS_ERROR: 'FCS_ERROR', - TAG_TYPE_RX_CHANNEL: 'RX_CHANNEL', - TAG_TYPE_PACKET_COUNT: 'PACKET_COUNT', - TAG_TYPE_RX_FRAME_LENGTH: 'RX_FRAME_LENGTH', - TAG_TYPE_WLAN_RADIO_HDR_SERIAL: 'WLAN_RADIO_HDR_SERIAL' - } - - def guess_payload_class(self, payload): - return _tzsp_guess_next_tag(payload) - - -class TZSPStructureException(Scapy_Exception): - pass - - -class TZSPTagPadding(_TZSPTag): - """ - padding tag (should be ignored) - """ - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_PADDING, _TZSPTag.TAG_TYPES), - ] - - -class TZSPTagEnd(Packet): - """ - last tag - """ - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_END, _TZSPTag.TAG_TYPES), - ] - - def guess_payload_class(self, payload): - """ - the type of the payload encapsulation is given be the outer TZSP layers attribute encapsulation_protocol # noqa: E501 - """ - - under_layer = self.underlayer - tzsp_header = None - - while under_layer: - if isinstance(under_layer, TZSP): - tzsp_header = under_layer - break - under_layer = under_layer.underlayer - - if tzsp_header: - - return tzsp_header.get_encapsulated_payload_class() - else: - raise TZSPStructureException('missing parent TZSP header') - - -class TZSPTagRawRSSIByte(_TZSPTag): - """ - relative received signal strength - signed byte value - """ - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_RAW_RSSI, _TZSPTag.TAG_TYPES), - ByteField('len', 1), - ByteField('raw_rssi', 0) - ] - - -class TZSPTagRawRSSIShort(_TZSPTag): - """ - relative received signal strength - signed short value - """ - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_RAW_RSSI, _TZSPTag.TAG_TYPES), - ByteField('len', 2), - ShortField('raw_rssi', 0) - ] - - -class TZSPTagSNRByte(_TZSPTag): - """ - signal noise ratio - signed byte value - """ - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_SNR, _TZSPTag.TAG_TYPES), - ByteField('len', 1), - ByteField('snr', 0) - ] - - -class TZSPTagSNRShort(_TZSPTag): - """ - signal noise ratio - signed short value - """ - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_SNR, _TZSPTag.TAG_TYPES), - ByteField('len', 2), - ShortField('snr', 0) - ] - - -class TZSPTagDataRate(_TZSPTag): - """ - wireless link data rate - """ - DATA_RATE_UNKNOWN = 0x00 - DATA_RATE_1 = 0x02 - DATA_RATE_2 = 0x04 - DATA_RATE_5_5 = 0x0B - DATA_RATE_6 = 0x0C - DATA_RATE_9 = 0x12 - DATA_RATE_11 = 0x16 - DATA_RATE_12 = 0x18 - DATA_RATE_18 = 0x24 - DATA_RATE_22 = 0x2C - DATA_RATE_24 = 0x30 - DATA_RATE_33 = 0x42 - DATA_RATE_36 = 0x48 - DATA_RATE_48 = 0x60 - DATA_RATE_54 = 0x6C - DATA_RATE_LEGACY_1 = 0x0A - DATA_RATE_LEGACY_2 = 0x14 - DATA_RATE_LEGACY_5_5 = 0x37 - DATA_RATE_LEGACY_11 = 0x6E - - DATA_RATES = { - DATA_RATE_UNKNOWN: 'unknown', - DATA_RATE_1: '1 MB/s', - DATA_RATE_2: '2 MB/s', - DATA_RATE_5_5: '5.5 MB/s', - DATA_RATE_6: '6 MB/s', - DATA_RATE_9: '9 MB/s', - DATA_RATE_11: '11 MB/s', - DATA_RATE_12: '12 MB/s', - DATA_RATE_18: '18 MB/s', - DATA_RATE_22: '22 MB/s', - DATA_RATE_24: '24 MB/s', - DATA_RATE_33: '33 MB/s', - DATA_RATE_36: '36 MB/s', - DATA_RATE_48: '48 MB/s', - DATA_RATE_54: '54 MB/s', - DATA_RATE_LEGACY_1: '1 MB/s (legacy)', - DATA_RATE_LEGACY_2: '2 MB/s (legacy)', - DATA_RATE_LEGACY_5_5: '5.5 MB/s (legacy)', - DATA_RATE_LEGACY_11: '11 MB/s (legacy)', - } - - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_DATA_RATE, _TZSPTag.TAG_TYPES), - ByteField('len', 1), - ByteEnumField('data_rate', DATA_RATE_UNKNOWN, DATA_RATES) - ] - - -class TZSPTagTimestamp(_TZSPTag): - """ - MAC receive timestamp - """ - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_TIMESTAMP, _TZSPTag.TAG_TYPES), - ByteField('len', 4), - IntField('timestamp', 0) - ] - - -class TZSPTagContentionFree(_TZSPTag): - """ - packet received in contention free period - """ - NO = 0x00 - YES = 0x01 - - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_CONTENTION_FREE, _TZSPTag.TAG_TYPES), # noqa: E501 - ByteField('len', 1), - YesNoByteField('contention_free', NO) - ] - - -class TZSPTagDecrypted(_TZSPTag): - """ - packet was decrypted - """ - YES = 0x00 - NO = 0x01 - - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_DECRYPTED, _TZSPTag.TAG_TYPES), - ByteField('len', 1), - YesNoByteField('decrypted', NO, config={'yes': YES, 'no': (NO, 0xff)}) - ] - - -class TZSPTagError(_TZSPTag): - """ - frame checksum error - """ - NO = 0x00 - YES = 0x01 - - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_FCS_ERROR, _TZSPTag.TAG_TYPES), - ByteField('len', 1), - YesNoByteField('fcs_error', NO, config={'no': NO, 'yes': YES, 'reserved': (YES + 1, 0xff)}) # noqa: E501 - ] - - -class TZSPTagRXChannel(_TZSPTag): - """ - channel the sensor was on while receiving the frame - """ - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_RX_CHANNEL, _TZSPTag.TAG_TYPES), # noqa: E501 - ByteField('len', 1), - ByteField('rx_channel', 0) - ] - - -class TZSPTagPacketCount(_TZSPTag): - """ - packet counter - """ - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_PACKET_COUNT, _TZSPTag.TAG_TYPES), # noqa: E501 - ByteField('len', 4), - IntField('packet_count', 0) - ] - - -class TZSPTagRXFrameLength(_TZSPTag): - """ - received packet length - """ - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_RX_FRAME_LENGTH, _TZSPTag.TAG_TYPES), # noqa: E501 - ByteField('len', 2), - ShortField('rx_frame_length', 0) - ] - - -class TZSPTagWlanRadioHdrSerial(_TZSPTag): - """ - (vendor specific) unique capture device (sensor/AP) identifier - """ - fields_desc = [ - ByteEnumField('type', _TZSPTag.TAG_TYPE_WLAN_RADIO_HDR_SERIAL, _TZSPTag.TAG_TYPES), # noqa: E501 - FieldLenField('len', None, length_of='sensor_id', fmt='b'), - StrLenField('sensor_id', '', length_from=lambda pkt:pkt.len) - ] - - -class TZSPTagUnknown(_TZSPTag): - """ - unknown tag type dummy - """ - fields_desc = [ - ByteField('type', 0xff), - FieldLenField('len', None, length_of='data', fmt='b'), - XStrLenField('data', '', length_from=lambda pkt: pkt.len) - ] - - -_TZSP_TAG_CLASSES = { - _TZSPTag.TAG_TYPE_PADDING: TZSPTagPadding, - _TZSPTag.TAG_TYPE_END: TZSPTagEnd, - _TZSPTag.TAG_TYPE_RAW_RSSI: {1: TZSPTagRawRSSIByte, 2: TZSPTagRawRSSIShort}, # noqa: E501 - _TZSPTag.TAG_TYPE_SNR: {1: TZSPTagSNRByte, 2: TZSPTagSNRShort}, - _TZSPTag.TAG_TYPE_DATA_RATE: TZSPTagDataRate, - _TZSPTag.TAG_TYPE_TIMESTAMP: TZSPTagTimestamp, - _TZSPTag.TAG_TYPE_CONTENTION_FREE: TZSPTagContentionFree, - _TZSPTag.TAG_TYPE_DECRYPTED: TZSPTagDecrypted, - _TZSPTag.TAG_TYPE_FCS_ERROR: TZSPTagError, - _TZSPTag.TAG_TYPE_RX_CHANNEL: TZSPTagRXChannel, - _TZSPTag.TAG_TYPE_PACKET_COUNT: TZSPTagPacketCount, - _TZSPTag.TAG_TYPE_RX_FRAME_LENGTH: TZSPTagRXFrameLength, - _TZSPTag.TAG_TYPE_WLAN_RADIO_HDR_SERIAL: TZSPTagWlanRadioHdrSerial -} diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ubberlogger.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/ubberlogger.py deleted file mode 100644 index 92721d1371..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/ubberlogger.py +++ /dev/null @@ -1,129 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# Author: Sylvain SARMEJEANNE - -# scapy.contrib.description = Ubberlogger dissectors -# scapy.contrib.status = loads - -from scapy.packet import Packet, bind_layers -from scapy.fields import ByteEnumField, ByteField, IntField, ShortField - -# Syscalls known by Uberlogger -uberlogger_sys_calls = {0: "READ_ID", - 1: "OPEN_ID", - 2: "WRITE_ID", - 3: "CHMOD_ID", - 4: "CHOWN_ID", - 5: "SETUID_ID", - 6: "CHROOT_ID", - 7: "CREATE_MODULE_ID", - 8: "INIT_MODULE_ID", - 9: "DELETE_MODULE_ID", - 10: "CAPSET_ID", - 11: "CAPGET_ID", - 12: "FORK_ID", - 13: "EXECVE_ID"} - -# First part of the header - - -class Uberlogger_honeypot_caract(Packet): - name = "Uberlogger honeypot_caract" - fields_desc = [ByteField("honeypot_id", 0), - ByteField("reserved", 0), - ByteField("os_type_and_version", 0)] - -# Second part of the header - - -class Uberlogger_uber_h(Packet): - name = "Uberlogger uber_h" - fields_desc = [ByteEnumField("syscall_type", 0, uberlogger_sys_calls), - IntField("time_sec", 0), - IntField("time_usec", 0), - IntField("pid", 0), - IntField("uid", 0), - IntField("euid", 0), - IntField("cap_effective", 0), - IntField("cap_inheritable", 0), - IntField("cap_permitted", 0), - IntField("res", 0), - IntField("length", 0)] - -# The 9 following classes are options depending on the syscall type - - -class Uberlogger_capget_data(Packet): - name = "Uberlogger capget_data" - fields_desc = [IntField("target_pid", 0)] - - -class Uberlogger_capset_data(Packet): - name = "Uberlogger capset_data" - fields_desc = [IntField("target_pid", 0), - IntField("effective_cap", 0), - IntField("permitted_cap", 0), - IntField("inheritable_cap", 0)] - - -class Uberlogger_chmod_data(Packet): - name = "Uberlogger chmod_data" - fields_desc = [ShortField("mode", 0)] - - -class Uberlogger_chown_data(Packet): - name = "Uberlogger chown_data" - fields_desc = [IntField("uid", 0), - IntField("gid", 0)] - - -class Uberlogger_open_data(Packet): - name = "Uberlogger open_data" - fields_desc = [IntField("flags", 0), - IntField("mode", 0)] - - -class Uberlogger_read_data(Packet): - name = "Uberlogger read_data" - fields_desc = [IntField("fd", 0), - IntField("count", 0)] - - -class Uberlogger_setuid_data(Packet): - name = "Uberlogger setuid_data" - fields_desc = [IntField("uid", 0)] - - -class Uberlogger_create_module_data(Packet): - name = "Uberlogger create_module_data" - fields_desc = [IntField("size", 0)] - - -class Uberlogger_execve_data(Packet): - name = "Uberlogger execve_data" - fields_desc = [IntField("nbarg", 0)] - - -# Layer bounds for Uberlogger -bind_layers(Uberlogger_honeypot_caract, Uberlogger_uber_h) -bind_layers(Uberlogger_uber_h, Uberlogger_capget_data) -bind_layers(Uberlogger_uber_h, Uberlogger_capset_data) -bind_layers(Uberlogger_uber_h, Uberlogger_chmod_data) -bind_layers(Uberlogger_uber_h, Uberlogger_chown_data) -bind_layers(Uberlogger_uber_h, Uberlogger_open_data) -bind_layers(Uberlogger_uber_h, Uberlogger_read_data) -bind_layers(Uberlogger_uber_h, Uberlogger_setuid_data) -bind_layers(Uberlogger_uber_h, Uberlogger_create_module_data) -bind_layers(Uberlogger_uber_h, Uberlogger_execve_data) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/vqp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/vqp.py deleted file mode 100644 index 9bc5a7503c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/vqp.py +++ /dev/null @@ -1,76 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = VLAN Query Protocol -# scapy.contrib.status = loads - -import struct - -from scapy.packet import Packet, bind_layers -from scapy.fields import ByteEnumField, ByteField, ConditionalField, \ - FieldLenField, IntEnumField, IntField, IPField, MACField, StrLenField -from scapy.layers.inet import UDP - - -class VQP(Packet): - name = "VQP" - fields_desc = [ - ByteField("const", 1), - ByteEnumField("type", 1, { - 1: "requestPort", 2: "responseVLAN", - 3: "requestReconfirm", 4: "responseReconfirm" - }), - ByteEnumField("errorcodeaction", 0, { - 0: "none", 3: "accessDenied", - 4: "shutdownPort", 5: "wrongDomain" - }), - ByteEnumField("unknown", 2, { - 2: "inGoodResponse", 6: "inRequests" - }), - IntField("seq", 0), - ] - - -class VQPEntry(Packet): - name = "VQPEntry" - fields_desc = [ - IntEnumField("datatype", 0, { - 3073: "clientIPAddress", 3074: "portName", - 3075: "VLANName", 3076: "Domain", 3077: "ethernetPacket", - 3078: "ReqMACAddress", 3079: "unknown", - 3080: "ResMACAddress" - }), - FieldLenField("len", None), - ConditionalField(IPField("datatom", "0.0.0.0"), - lambda p: p.datatype == 3073), - ConditionalField(MACField("data", "00:00:00:00:00:00"), - lambda p: p.datatype == 3078), - ConditionalField(MACField("data", "00:00:00:00:00:00"), - lambda p: p.datatype == 3080), - ConditionalField(StrLenField("data", None, - length_from=lambda p: p.len), - lambda p: p.datatype not in [3073, 3078, 3080]), - ] - - def post_build(self, p, pay): - if self.len is None: - tmp_len = len(p.data) - p = p[:2] + struct.pack("!H", tmp_len) + p[4:] - return p - - -bind_layers(UDP, VQP, sport=1589) -bind_layers(UDP, VQP, dport=1589) -bind_layers(VQP, VQPEntry,) -bind_layers(VQPEntry, VQPEntry,) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/vtp.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/vtp.py deleted file mode 100644 index 186b03c2f9..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/vtp.py +++ /dev/null @@ -1,194 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = VLAN Trunking Protocol (VTP) -# scapy.contrib.status = loads - -""" - VTP Scapy Extension - ~~~~~~~~~~~~~~~~~~~~~ - - :version: 2009-02-15 - :copyright: 2009 by Jochen Bartl - :e-mail: lobo@c3a.de / jochen.bartl@gmail.com - :license: GPL v2 - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - 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. - - :TODO - - - Join messages - - RE MD5 hash calculation - - Have a closer look at 8 byte padding in summary adv. - "debug sw-vlan vtp packets" says the TLV length is invalid, - when I change the values - b'\x00\x00\x00\x01\x06\x01\x00\x02' - * \x00\x00 ? - * \x00\x01 tlvtype? - * \x06 length? - * \x00\x02 value? - - h2i function for VTPTimeStampField - - :References: - - - Understanding VLAN Trunk Protocol (VTP) - http://www.cisco.com/en/US/tech/tk389/tk689/technologies_tech_note09186a0080094c52.shtml -""" - -from scapy.packet import Packet, bind_layers -from scapy.fields import ByteEnumField, ByteField, ConditionalField, \ - FieldLenField, IPField, PacketListField, ShortField, SignedIntField, \ - StrFixedLenField, StrLenField, XIntField -from scapy.layers.l2 import SNAP -from scapy.config import conf - -_VTP_VLAN_TYPE = { - 1: 'Ethernet', - 2: 'FDDI', - 3: 'TrCRF', - 4: 'FDDI-net', - 5: 'TrBRF' -} - -_VTP_VLANINFO_TLV_TYPE = { - 0x01: 'Source-Routing Ring Number', - 0x02: 'Source-Routing Bridge Number', - 0x03: 'Spanning-Tree Protocol Type', - 0x04: 'Parent VLAN', - 0x05: 'Translationally Bridged VLANs', - 0x06: 'Pruning', - 0x07: 'Bridge Type', - 0x08: 'Max ARE Hop Count', - 0x09: 'Max STE Hop Count', - 0x0A: 'Backup CRF Mode' -} - - -class VTPVlanInfoTlv(Packet): - name = "VTP VLAN Info TLV" - fields_desc = [ - ByteEnumField("type", 0, _VTP_VLANINFO_TLV_TYPE), - ByteField("length", 0), - StrLenField("value", None, length_from=lambda pkt: pkt.length + 1) - ] - - def guess_payload_class(self, p): - return conf.padding_layer - - -class VTPVlanInfo(Packet): - name = "VTP VLAN Info" - fields_desc = [ - ByteField("len", None), # FIXME: compute length - ByteEnumField("status", 0, {0: "active", 1: "suspended"}), - ByteEnumField("type", 1, _VTP_VLAN_TYPE), - FieldLenField("vlannamelen", None, "vlanname", "B"), - ShortField("vlanid", 1), - ShortField("mtu", 1500), - XIntField("dot10index", None), - StrLenField("vlanname", "default", length_from=lambda pkt: 4 * ((pkt.vlannamelen + 3) / 4)), # noqa: E501 - ConditionalField(PacketListField("tlvlist", [], VTPVlanInfoTlv, - length_from=lambda pkt:pkt.len - 12 - (4 * ((pkt.vlannamelen + 3) / 4))), # noqa: E501 - lambda pkt:pkt.type not in [1, 2]) - ] - - def post_build(self, p, pay): - vlannamelen = 4 * ((len(self.vlanname) + 3) / 4) - - if self.len is None: - tmp_len = vlannamelen + 12 - p = chr(tmp_len & 0xff) + p[1:] - - # Pad vlan name with zeros if vlannamelen > len(vlanname) - tmp_len = vlannamelen - len(self.vlanname) - if tmp_len != 0: - p += b"\x00" * tmp_len - - p += pay - - return p - - def guess_payload_class(self, p): - return conf.padding_layer - - -_VTP_Types = { - 1: 'Summary Advertisement', - 2: 'Subset Advertisements', - 3: 'Advertisement Request', - 4: 'Join' -} - - -class VTPTimeStampField(StrFixedLenField): - def __init__(self, name, default): - StrFixedLenField.__init__(self, name, default, 12) - - def i2repr(self, pkt, x): - return "%s-%s-%s %s:%s:%s" % (x[:2], x[2:4], x[4:6], x[6:8], x[8:10], x[10:12]) # noqa: E501 - - -class VTP(Packet): - name = "VTP" - fields_desc = [ - ByteField("ver", 2), - ByteEnumField("code", 1, _VTP_Types), - ConditionalField(ByteField("followers", 1), - lambda pkt:pkt.code == 1), - ConditionalField(ByteField("seq", 1), - lambda pkt:pkt.code == 2), - ConditionalField(ByteField("reserved", 0), - lambda pkt:pkt.code == 3), - ByteField("domnamelen", None), - StrFixedLenField("domname", "manbearpig", 32), - ConditionalField(SignedIntField("rev", 0), - lambda pkt:pkt.code == 1 or - pkt.code == 2), - # updater identity - ConditionalField(IPField("uid", "192.168.0.1"), - lambda pkt:pkt.code == 1), - ConditionalField(VTPTimeStampField("timestamp", '930301000000'), - lambda pkt:pkt.code == 1), - ConditionalField(StrFixedLenField("md5", b"\x00" * 16, 16), - lambda pkt:pkt.code == 1), - ConditionalField( - PacketListField("vlaninfo", [], VTPVlanInfo), - lambda pkt: pkt.code == 2), - ConditionalField(ShortField("startvalue", 0), - lambda pkt:pkt.code == 3) - ] - - def post_build(self, p, pay): - if self.domnamelen is None: - domnamelen = len(self.domname.strip(b"\x00")) - p = p[:3] + chr(domnamelen & 0xff) + p[4:] - - p += pay - - return p - - -bind_layers(SNAP, VTP, code=0x2003) - -if __name__ == '__main__': - from scapy.main import interact - interact(mydict=globals(), mybanner="VTP") diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/wireguard.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/wireguard.py deleted file mode 100644 index 2263d00095..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/wireguard.py +++ /dev/null @@ -1,101 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - - -# scapy.contrib.description = WireGuard -# scapy.contrib.status = loads - -"""WireGuard Module -Implements the WireGuard network tunnel protocol. -Based on the whitepaper: https://www.wireguard.com/papers/wireguard.pdf -""" - -from scapy.fields import ByteEnumField, ThreeBytesField, XLEIntField, \ - XStrFixedLenField, XLELongField, XStrField -from scapy.layers.inet import UDP -from scapy.packet import Packet, bind_layers - - -class Wireguard(Packet): - """ - Wrapper that only contains the message type. - """ - name = "Wireguard" - - fields_desc = [ - ByteEnumField( - "message_type", 1, - { - 1: "initiate", - 2: "respond", - 3: "cookie reply", - 4: "transport" - } - ), - ThreeBytesField("reserved_zero", 0) - ] - - -class WireguardInitiation(Packet): - name = "Wireguard Initiation" - - fields_desc = [ - XLEIntField("sender_index", 0), - XStrFixedLenField("unencrypted_ephemeral", 0, 32), - XStrFixedLenField("encrypted_static", 0, 48), - XStrFixedLenField("encrypted_timestamp", 0, 28), - XStrFixedLenField("mac1", 0, 16), - XStrFixedLenField("mac2", 0, 16), - ] - - -class WireguardResponse(Packet): - name = "Wireguard Response" - - fields_desc = [ - XLEIntField("sender_index", 0), - XLEIntField("receiver_index", 0), - XStrFixedLenField("unencrypted_ephemeral", 0, 32), - XStrFixedLenField("encrypted_nothing", 0, 16), - XStrFixedLenField("mac1", 0, 16), - XStrFixedLenField("mac2", 0, 16), - ] - - -class WireguardTransport(Packet): - name = "Wireguard Transport" - - fields_desc = [ - XLEIntField("receiver_index", 0), - XLELongField("counter", 0), - XStrField("encrypted_encapsulated_packet", None) - ] - - -class WireguardCookieReply(Packet): - name = "Wireguard Cookie Reply" - - fields_desc = [ - XLEIntField("receiver_index", 0), - XStrFixedLenField("nonce", 0, 24), - XStrFixedLenField("encrypted_cookie", 0, 32), - ] - - -bind_layers(Wireguard, WireguardInitiation, message_type=1) -bind_layers(Wireguard, WireguardResponse, message_type=2) -bind_layers(Wireguard, WireguardCookieReply, message_type=3) -bind_layers(Wireguard, WireguardTransport, message_type=4) -bind_layers(UDP, Wireguard, dport=51820) -bind_layers(UDP, Wireguard, sport=51820) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/contrib/wpa_eapol.py b/scripts/external_libs/scapy-2.4.3/scapy/contrib/wpa_eapol.py deleted file mode 100644 index 388ca77f7c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/contrib/wpa_eapol.py +++ /dev/null @@ -1,51 +0,0 @@ -# This file is part of Scapy -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# scapy.contrib.description = WPA EAPOL-KEY -# scapy.contrib.status = loads - -from scapy.packet import Packet, bind_layers -from scapy.fields import ByteField, LenField, ShortField, StrFixedLenField, \ - StrLenField -from scapy.layers.eap import EAPOL - - -class WPA_key(Packet): - name = "WPA_key" - fields_desc = [ByteField("descriptor_type", 1), - ShortField("key_info", 0), - LenField("len", None, "H"), - StrFixedLenField("replay_counter", "", 8), - StrFixedLenField("nonce", "", 32), - StrFixedLenField("key_iv", "", 16), - StrFixedLenField("wpa_key_rsc", "", 8), - StrFixedLenField("wpa_key_id", "", 8), - StrFixedLenField("wpa_key_mic", "", 16), - LenField("wpa_key_length", None, "H"), - StrLenField("wpa_key", "", length_from=lambda pkt:pkt.wpa_key_length)] # noqa: E501 - - def extract_padding(self, s): - tmp_len = self.len - return s[:tmp_len], s[tmp_len:] - - def hashret(self): - return chr(self.type) + self.payload.hashret() - - def answers(self, other): - if isinstance(other, WPA_key): - return 1 - return 0 - - -bind_layers(EAPOL, WPA_key, type=3) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/crypto/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/crypto/__init__.py deleted file mode 100644 index b441863e82..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/crypto/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Arnaud Ebalard -## This program is published under a GPLv2 license - -""" -Tools for handling with digital certificates. -""" - -try: - import Crypto -except ImportError: - import logging - log_loading = logging.getLogger("scapy.loading") - log_loading.info("Can't import python Crypto lib. Disabled certificate manipulation tools") -else: - from scapy.crypto.cert import * diff --git a/scripts/external_libs/scapy-2.4.3/scapy/crypto/cert.py b/scripts/external_libs/scapy-2.4.3/scapy/crypto/cert.py deleted file mode 100644 index c42910590b..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/crypto/cert.py +++ /dev/null @@ -1,2486 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Arnaud Ebalard -## This program is published under a GPLv2 license - -""" -Cryptographic certificates. -""" - -import os, sys, math, socket, struct, hmac, string, time, random, tempfile -from subprocess import Popen, PIPE -from scapy.utils import strxor -try: - HAS_HASHLIB=True - import hashlib -except: - HAS_HASHLIB=False - -from Crypto.PublicKey import * -from Crypto.Cipher import * -from Crypto.Hash import * -from Crypto.Util import number - -# Maximum allowed size in bytes for a certificate file, to avoid -# loading huge file when importing a cert -MAX_KEY_SIZE=50*1024 -MAX_CERT_SIZE=50*1024 -MAX_CRL_SIZE=10*1024*1024 # some are that big - -##################################################################### -# Some helpers -##################################################################### - -def popen3(cmd): - p = Popen(cmd, shell=False, stdin=PIPE, stdout=PIPE, stderr=PIPE, - close_fds=True) - return p.stdout, p.stdin, p.stderr - -def warning(m): - print("WARNING: %s" % m) - -def randstring(l): - """ - Returns a random string of length l (l >= 0) - """ - tmp = map(lambda x: struct.pack("B", random.randrange(0, 256, 1)), [""]*l) - return "".join(tmp) - -def zerofree_randstring(l): - """ - Returns a random string of length l (l >= 0) without zero in it. - """ - tmp = map(lambda x: struct.pack("B", random.randrange(1, 256, 1)), [""]*l) - return "".join(tmp) - -def strand(s1, s2): - """ - Returns the binary AND of the 2 provided strings s1 and s2. s1 and s2 - must be of same length. - """ - return "".join(map(lambda x,y:chr(ord(x)&ord(y)), s1, s2)) - -# OS2IP function defined in RFC 3447 for octet string to integer conversion -def pkcs_os2ip(x): - """ - Accepts a byte string as input parameter and return the associated long - value: - - Input : x octet string to be converted - - Output: x corresponding nonnegative integer - - Reverse function is pkcs_i2osp() - """ - return number.bytes_to_long(x) - -# IP2OS function defined in RFC 3447 for octet string to integer conversion -def pkcs_i2osp(x,xLen): - """ - Converts a long (the first parameter) to the associated byte string - representation of length l (second parameter). Basically, the length - parameters allow the function to perform the associated padding. - - Input : x nonnegative integer to be converted - xLen intended length of the resulting octet string - - Output: x corresponding nonnegative integer - - Reverse function is pkcs_os2ip(). - """ - z = number.long_to_bytes(x) - padlen = max(0, xLen-len(z)) - return '\x00'*padlen + z - -# for every hash function a tuple is provided, giving access to -# - hash output length in byte -# - associated hash function that take data to be hashed as parameter -# XXX I do not provide update() at the moment. -# - DER encoding of the leading bits of digestInfo (the hash value -# will be concatenated to create the complete digestInfo). -# -# Notes: -# - MD4 asn.1 value should be verified. Also, as stated in -# PKCS#1 v2.1, MD4 should not be used. -# - hashlib is available from http://code.krypto.org/python/hashlib/ -# - 'tls' one is the concatenation of both md5 and sha1 hashes used -# by SSL/TLS when signing/verifying things -_hashFuncParams = { - "md2" : (16, - lambda x: MD2.new(x).digest(), - '\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02\x05\x00\x04\x10'), - "md4" : (16, - lambda x: MD4.new(x).digest(), - '\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x04\x05\x00\x04\x10'), # is that right ? - "md5" : (16, - lambda x: MD5.new(x).digest(), - '\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10'), - "sha1" : (20, - lambda x: SHA.new(x).digest(), - '\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14'), - "tls" : (36, - lambda x: MD5.new(x).digest() + SHA.new(x).digest(), - '') } - -if HAS_HASHLIB: - _hashFuncParams["sha224"] = (28, - lambda x: hashlib.sha224(x).digest(), - '\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c') - _hashFuncParams["sha256"] = (32, - lambda x: hashlib.sha256(x).digest(), - '\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20') - _hashFuncParams["sha384"] = (48, - lambda x: hashlib.sha384(x).digest(), - '\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30') - _hashFuncParams["sha512"] = (64, - lambda x: hashlib.sha512(x).digest(), - '\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40') -else: - warning("hashlib support is not available. Consider installing it") - warning("if you need sha224, sha256, sha384 and sha512 algs.") - -def pkcs_mgf1(mgfSeed, maskLen, h): - """ - Implements generic MGF1 Mask Generation function as described in - Appendix B.2.1 of RFC 3447. The hash function is passed by name. - valid values are 'md2', 'md4', 'md5', 'sha1', 'tls, 'sha256', - 'sha384' and 'sha512'. Returns None on error. - - Input: - mgfSeed: seed from which mask is generated, an octet string - maskLen: intended length in octets of the mask, at most 2^32 * hLen - hLen (see below) - h : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls', - 'sha256', 'sha384'). hLen denotes the length in octets of - the hash function output. - - Output: - an octet string of length maskLen - """ - - # steps are those of Appendix B.2.1 - if not h in _hashFuncParams: - warning("pkcs_mgf1: invalid hash (%s) provided") - return None - hLen = _hashFuncParams[h][0] - hFunc = _hashFuncParams[h][1] - if maskLen > 2**32 * hLen: # 1) - warning("pkcs_mgf1: maskLen > 2**32 * hLen") - return None - T = "" # 2) - maxCounter = math.ceil(float(maskLen) / float(hLen)) # 3) - counter = 0 - while counter < maxCounter: - C = pkcs_i2osp(counter, 4) - T += hFunc(mgfSeed + C) - counter += 1 - return T[:maskLen] - - -def pkcs_emsa_pss_encode(M, emBits, h, mgf, sLen): - """ - Implements EMSA-PSS-ENCODE() function described in Sect. 9.1.1 of RFC 3447 - - Input: - M : message to be encoded, an octet string - emBits: maximal bit length of the integer resulting of pkcs_os2ip(EM), - where EM is the encoded message, output of the function. - h : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls', - 'sha256', 'sha384'). hLen denotes the length in octets of - the hash function output. - mgf : the mask generation function f : seed, maskLen -> mask - sLen : intended length in octets of the salt - - Output: - encoded message, an octet string of length emLen = ceil(emBits/8) - - On error, None is returned. - """ - - # 1) is not done - hLen = _hashFuncParams[h][0] # 2) - hFunc = _hashFuncParams[h][1] - mHash = hFunc(M) - emLen = int(math.ceil(emBits/8.)) - if emLen < hLen + sLen + 2: # 3) - warning("encoding error (emLen < hLen + sLen + 2)") - return None - salt = randstring(sLen) # 4) - MPrime = '\x00'*8 + mHash + salt # 5) - H = hFunc(MPrime) # 6) - PS = '\x00'*(emLen - sLen - hLen - 2) # 7) - DB = PS + '\x01' + salt # 8) - dbMask = mgf(H, emLen - hLen - 1) # 9) - maskedDB = strxor(DB, dbMask) # 10) - l = (8*emLen - emBits)/8 # 11) - rem = 8*emLen - emBits - 8*l # additionnal bits - andMask = l*'\x00' - if rem: - j = chr(reduce(lambda x,y: x+y, map(lambda x: 1< mask - sLen : intended length in octets of the salt - - Output: - True if the verification is ok, False otherwise. - """ - - # 1) is not done - hLen = _hashFuncParams[h][0] # 2) - hFunc = _hashFuncParams[h][1] - mHash = hFunc(M) - emLen = int(math.ceil(emBits/8.)) # 3) - if emLen < hLen + sLen + 2: - return False - if EM[-1] != '\xbc': # 4) - return False - l = emLen - hLen - 1 # 5) - maskedDB = EM[:l] - H = EM[l:l+hLen] - l = (8*emLen - emBits)/8 # 6) - rem = 8*emLen - emBits - 8*l # additionnal bits - andMask = l*'\xff' - if rem: - val = reduce(lambda x,y: x+y, map(lambda x: 1< n-1: - warning("Key._rsaep() expects a long between 0 and n-1") - return None - - return self.key.encrypt(m, "")[0] - - - def _rsaes_pkcs1_v1_5_encrypt(self, M): - """ - Implements RSAES-PKCS1-V1_5-ENCRYPT() function described in section - 7.2.1 of RFC 3447. - - Input: - M: message to be encrypted, an octet string of length mLen, where - mLen <= k - 11 (k denotes the length in octets of the key modulus) - - Output: - ciphertext, an octet string of length k - - On error, None is returned. - """ - - # 1) Length checking - mLen = len(M) - k = self.modulusLen / 8 - if mLen > k - 11: - warning("Key._rsaes_pkcs1_v1_5_encrypt(): message too " - "long (%d > %d - 11)" % (mLen, k)) - return None - - # 2) EME-PKCS1-v1_5 encoding - PS = zerofree_randstring(k - mLen - 3) # 2.a) - EM = '\x00' + '\x02' + PS + '\x00' + M # 2.b) - - # 3) RSA encryption - m = pkcs_os2ip(EM) # 3.a) - c = self._rsaep(m) # 3.b) - C = pkcs_i2osp(c, k) # 3.c) - - return C # 4) - - - def _rsaes_oaep_encrypt(self, M, h=None, mgf=None, L=None): - """ - Internal method providing RSAES-OAEP-ENCRYPT as defined in Sect. - 7.1.1 of RFC 3447. Not intended to be used directly. Please, see - encrypt() method for type "OAEP". - - - Input: - M : message to be encrypted, an octet string of length mLen - where mLen <= k - 2*hLen - 2 (k denotes the length in octets - of the RSA modulus and hLen the length in octets of the hash - function output) - h : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls', - 'sha256', 'sha384'). hLen denotes the length in octets of - the hash function output. 'sha1' is used by default if not - provided. - mgf: the mask generation function f : seed, maskLen -> mask - L : optional label to be associated with the message; the default - value for L, if not provided is the empty string - - Output: - ciphertext, an octet string of length k - - On error, None is returned. - """ - # The steps below are the one described in Sect. 7.1.1 of RFC 3447. - # 1) Length Checking - # 1.a) is not done - mLen = len(M) - if h is None: - h = "sha1" - if not h in _hashFuncParams: - warning("Key._rsaes_oaep_encrypt(): unknown hash function %s.", h) - return None - hLen = _hashFuncParams[h][0] - hFun = _hashFuncParams[h][1] - k = self.modulusLen / 8 - if mLen > k - 2*hLen - 2: # 1.b) - warning("Key._rsaes_oaep_encrypt(): message too long.") - return None - - # 2) EME-OAEP encoding - if L is None: # 2.a) - L = "" - lHash = hFun(L) - PS = '\x00'*(k - mLen - 2*hLen - 2) # 2.b) - DB = lHash + PS + '\x01' + M # 2.c) - seed = randstring(hLen) # 2.d) - if mgf is None: # 2.e) - mgf = lambda x,y: pkcs_mgf1(x,y,h) - dbMask = mgf(seed, k - hLen - 1) - maskedDB = strxor(DB, dbMask) # 2.f) - seedMask = mgf(maskedDB, hLen) # 2.g) - maskedSeed = strxor(seed, seedMask) # 2.h) - EM = '\x00' + maskedSeed + maskedDB # 2.i) - - # 3) RSA Encryption - m = pkcs_os2ip(EM) # 3.a) - c = self._rsaep(m) # 3.b) - C = pkcs_i2osp(c, k) # 3.c) - - return C # 4) - - - def encrypt(self, m, t=None, h=None, mgf=None, L=None): - """ - Encrypt message 'm' using 't' encryption scheme where 't' can be: - - - None: the message 'm' is directly applied the RSAEP encryption - primitive, as described in PKCS#1 v2.1, i.e. RFC 3447 - Sect 5.1.1. Simply put, the message undergo a modular - exponentiation using the public key. Additionnal method - parameters are just ignored. - - - 'pkcs': the message 'm' is applied RSAES-PKCS1-V1_5-ENCRYPT encryption - scheme as described in section 7.2.1 of RFC 3447. In that - context, other parameters ('h', 'mgf', 'l') are not used. - - - 'oaep': the message 'm' is applied the RSAES-OAEP-ENCRYPT encryption - scheme, as described in PKCS#1 v2.1, i.e. RFC 3447 Sect - 7.1.1. In that context, - - o 'h' parameter provides the name of the hash method to use. - Possible values are "md2", "md4", "md5", "sha1", "tls", - "sha224", "sha256", "sha384" and "sha512". if none is provided, - sha1 is used. - - o 'mgf' is the mask generation function. By default, mgf - is derived from the provided hash function using the - generic MGF1 (see pkcs_mgf1() for details). - - o 'L' is the optional label to be associated with the - message. If not provided, the default value is used, i.e - the empty string. No check is done on the input limitation - of the hash function regarding the size of 'L' (for - instance, 2^61 - 1 for SHA-1). You have been warned. - """ - - if t is None: # Raw encryption - m = pkcs_os2ip(m) - c = self._rsaep(m) - return pkcs_i2osp(c, self.modulusLen/8) - - elif t == "pkcs": - return self._rsaes_pkcs1_v1_5_encrypt(m) - - elif t == "oaep": - return self._rsaes_oaep_encrypt(m, h, mgf, L) - - else: - warning("Key.encrypt(): Unknown encryption type (%s) provided" % t) - return None - - ### Below are verification related methods - - def _rsavp1(self, s): - """ - Internal method providing raw RSA verification, i.e. simple modular - exponentiation of the given signature representative 'c', an integer - between 0 and n-1. - - This is the signature verification primitive RSAVP1 described in - PKCS#1 v2.1, i.e. RFC 3447 Sect. 5.2.2. - - Input: - s: signature representative, an integer between 0 and n-1, - where n is the key modulus. - - Output: - message representative, an integer between 0 and n-1 - - Not intended to be used directly. Please, see verify() method. - """ - return self._rsaep(s) - - def _rsassa_pss_verify(self, M, S, h=None, mgf=None, sLen=None): - """ - Implements RSASSA-PSS-VERIFY() function described in Sect 8.1.2 - of RFC 3447 - - Input: - M: message whose signature is to be verified - S: signature to be verified, an octet string of length k, where k - is the length in octets of the RSA modulus n. - - Output: - True is the signature is valid. False otherwise. - """ - - # Set default parameters if not provided - if h is None: # By default, sha1 - h = "sha1" - if not h in _hashFuncParams: - warning("Key._rsassa_pss_verify(): unknown hash function " - "provided (%s)" % h) - return False - if mgf is None: # use mgf1 with underlying hash function - mgf = lambda x,y: pkcs_mgf1(x, y, h) - if sLen is None: # use Hash output length (A.2.3 of RFC 3447) - hLen = _hashFuncParams[h][0] - sLen = hLen - - # 1) Length checking - modBits = self.modulusLen - k = modBits / 8 - if len(S) != k: - return False - - # 2) RSA verification - s = pkcs_os2ip(S) # 2.a) - m = self._rsavp1(s) # 2.b) - emLen = math.ceil((modBits - 1) / 8.) # 2.c) - EM = pkcs_i2osp(m, emLen) - - # 3) EMSA-PSS verification - Result = pkcs_emsa_pss_verify(M, EM, modBits - 1, h, mgf, sLen) - - return Result # 4) - - - def _rsassa_pkcs1_v1_5_verify(self, M, S, h): - """ - Implements RSASSA-PKCS1-v1_5-VERIFY() function as described in - Sect. 8.2.2 of RFC 3447. - - Input: - M: message whose signature is to be verified, an octet string - S: signature to be verified, an octet string of length k, where - k is the length in octets of the RSA modulus n - h: hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls', - 'sha256', 'sha384'). - - Output: - True if the signature is valid. False otherwise. - """ - - # 1) Length checking - k = self.modulusLen / 8 - if len(S) != k: - warning("invalid signature (len(S) != k)") - return False - - # 2) RSA verification - s = pkcs_os2ip(S) # 2.a) - m = self._rsavp1(s) # 2.b) - EM = pkcs_i2osp(m, k) # 2.c) - - # 3) EMSA-PKCS1-v1_5 encoding - EMPrime = pkcs_emsa_pkcs1_v1_5_encode(M, k, h) - if EMPrime is None: - warning("Key._rsassa_pkcs1_v1_5_verify(): unable to encode.") - return False - - # 4) Comparison - return EM == EMPrime - - - def verify(self, M, S, t=None, h=None, mgf=None, sLen=None): - """ - Verify alleged signature 'S' is indeed the signature of message 'M' using - 't' signature scheme where 't' can be: - - - None: the alleged signature 'S' is directly applied the RSAVP1 signature - primitive, as described in PKCS#1 v2.1, i.e. RFC 3447 Sect - 5.2.1. Simply put, the provided signature is applied a moular - exponentiation using the public key. Then, a comparison of the - result is done against 'M'. On match, True is returned. - Additionnal method parameters are just ignored. - - - 'pkcs': the alleged signature 'S' and message 'M' are applied - RSASSA-PKCS1-v1_5-VERIFY signature verification scheme as - described in Sect. 8.2.2 of RFC 3447. In that context, - the hash function name is passed using 'h'. Possible values are - "md2", "md4", "md5", "sha1", "tls", "sha224", "sha256", "sha384" - and "sha512". If none is provided, sha1 is used. Other additionnal - parameters are ignored. - - - 'pss': the alleged signature 'S' and message 'M' are applied - RSASSA-PSS-VERIFY signature scheme as described in Sect. 8.1.2. - of RFC 3447. In that context, - - o 'h' parameter provides the name of the hash method to use. - Possible values are "md2", "md4", "md5", "sha1", "tls", "sha224", - "sha256", "sha384" and "sha512". if none is provided, sha1 - is used. - - o 'mgf' is the mask generation function. By default, mgf - is derived from the provided hash function using the - generic MGF1 (see pkcs_mgf1() for details). - - o 'sLen' is the length in octet of the salt. You can overload the - default value (the octet length of the hash value for provided - algorithm) by providing another one with that parameter. - """ - if t is None: # RSAVP1 - S = pkcs_os2ip(S) - n = self.modulus - if S > n-1: - warning("Signature to be verified is too long for key modulus") - return False - m = self._rsavp1(S) - if m is None: - return False - l = int(math.ceil(math.log(m, 2) / 8.)) # Hack - m = pkcs_i2osp(m, l) - return M == m - - elif t == "pkcs": # RSASSA-PKCS1-v1_5-VERIFY - if h is None: - h = "sha1" - return self._rsassa_pkcs1_v1_5_verify(M, S, h) - - elif t == "pss": # RSASSA-PSS-VERIFY - return self._rsassa_pss_verify(M, S, h, mgf, sLen) - - else: - warning("Key.verify(): Unknown signature type (%s) provided" % t) - return None - -class _DecryptAndSignMethods(OSSLHelper): - ### Below are decryption related methods. Encryption ones are inherited - ### from PubKey - - def _rsadp(self, c): - """ - Internal method providing raw RSA decryption, i.e. simple modular - exponentiation of the given ciphertext representative 'c', a long - between 0 and n-1. - - This is the decryption primitive RSADP described in PKCS#1 v2.1, - i.e. RFC 3447 Sect. 5.1.2. - - Input: - c: ciphertest representative, a long between 0 and n-1, where - n is the key modulus. - - Output: - ciphertext representative, a long between 0 and n-1 - - Not intended to be used directly. Please, see encrypt() method. - """ - - n = self.modulus - if type(c) is int: - c = long(c) - if type(c) is not long or c > n-1: - warning("Key._rsaep() expects a long between 0 and n-1") - return None - - return self.key.decrypt(c) - - - def _rsaes_pkcs1_v1_5_decrypt(self, C): - """ - Implements RSAES-PKCS1-V1_5-DECRYPT() function described in section - 7.2.2 of RFC 3447. - - Input: - C: ciphertext to be decrypted, an octet string of length k, where - k is the length in octets of the RSA modulus n. - - Output: - an octet string of length k at most k - 11 - - on error, None is returned. - """ - - # 1) Length checking - cLen = len(C) - k = self.modulusLen / 8 - if cLen != k or k < 11: - warning("Key._rsaes_pkcs1_v1_5_decrypt() decryption error " - "(cLen != k or k < 11)") - return None - - # 2) RSA decryption - c = pkcs_os2ip(C) # 2.a) - m = self._rsadp(c) # 2.b) - EM = pkcs_i2osp(m, k) # 2.c) - - # 3) EME-PKCS1-v1_5 decoding - - # I am aware of the note at the end of 7.2.2 regarding error - # conditions reporting but the one provided below are for _local_ - # debugging purposes. --arno - - if EM[0] != '\x00': - warning("Key._rsaes_pkcs1_v1_5_decrypt(): decryption error " - "(first byte is not 0x00)") - return None - - if EM[1] != '\x02': - warning("Key._rsaes_pkcs1_v1_5_decrypt(): decryption error " - "(second byte is not 0x02)") - return None - - tmp = EM[2:].split('\x00', 1) - if len(tmp) != 2: - warning("Key._rsaes_pkcs1_v1_5_decrypt(): decryption error " - "(no 0x00 to separate PS from M)") - return None - - PS, M = tmp - if len(PS) < 8: - warning("Key._rsaes_pkcs1_v1_5_decrypt(): decryption error " - "(PS is less than 8 byte long)") - return None - - return M # 4) - - - def _rsaes_oaep_decrypt(self, C, h=None, mgf=None, L=None): - """ - Internal method providing RSAES-OAEP-DECRYPT as defined in Sect. - 7.1.2 of RFC 3447. Not intended to be used directly. Please, see - encrypt() method for type "OAEP". - - - Input: - C : ciphertext to be decrypted, an octet string of length k, where - k = 2*hLen + 2 (k denotes the length in octets of the RSA modulus - and hLen the length in octets of the hash function output) - h : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls', - 'sha256', 'sha384'). 'sha1' is used if none is provided. - mgf: the mask generation function f : seed, maskLen -> mask - L : optional label whose association with the message is to be - verified; the default value for L, if not provided is the empty - string. - - Output: - message, an octet string of length k mLen, where mLen <= k - 2*hLen - 2 - - On error, None is returned. - """ - # The steps below are the one described in Sect. 7.1.2 of RFC 3447. - - # 1) Length Checking - # 1.a) is not done - if h is None: - h = "sha1" - if not h in _hashFuncParams: - warning("Key._rsaes_oaep_decrypt(): unknown hash function %s.", h) - return None - hLen = _hashFuncParams[h][0] - hFun = _hashFuncParams[h][1] - k = self.modulusLen / 8 - cLen = len(C) - if cLen != k: # 1.b) - warning("Key._rsaes_oaep_decrypt(): decryption error. " - "(cLen != k)") - return None - if k < 2*hLen + 2: - warning("Key._rsaes_oaep_decrypt(): decryption error. " - "(k < 2*hLen + 2)") - return None - - # 2) RSA decryption - c = pkcs_os2ip(C) # 2.a) - m = self._rsadp(c) # 2.b) - EM = pkcs_i2osp(m, k) # 2.c) - - # 3) EME-OAEP decoding - if L is None: # 3.a) - L = "" - lHash = hFun(L) - Y = EM[:1] # 3.b) - if Y != '\x00': - warning("Key._rsaes_oaep_decrypt(): decryption error. " - "(Y is not zero)") - return None - maskedSeed = EM[1:1+hLen] - maskedDB = EM[1+hLen:] - if mgf is None: - mgf = lambda x,y: pkcs_mgf1(x, y, h) - seedMask = mgf(maskedDB, hLen) # 3.c) - seed = strxor(maskedSeed, seedMask) # 3.d) - dbMask = mgf(seed, k - hLen - 1) # 3.e) - DB = strxor(maskedDB, dbMask) # 3.f) - - # I am aware of the note at the end of 7.1.2 regarding error - # conditions reporting but the one provided below are for _local_ - # debugging purposes. --arno - - lHashPrime = DB[:hLen] # 3.g) - tmp = DB[hLen:].split('\x01', 1) - if len(tmp) != 2: - warning("Key._rsaes_oaep_decrypt(): decryption error. " - "(0x01 separator not found)") - return None - PS, M = tmp - if PS != '\x00'*len(PS): - warning("Key._rsaes_oaep_decrypt(): decryption error. " - "(invalid padding string)") - return None - if lHash != lHashPrime: - warning("Key._rsaes_oaep_decrypt(): decryption error. " - "(invalid hash)") - return None - return M # 4) - - - def decrypt(self, C, t=None, h=None, mgf=None, L=None): - """ - Decrypt ciphertext 'C' using 't' decryption scheme where 't' can be: - - - None: the ciphertext 'C' is directly applied the RSADP decryption - primitive, as described in PKCS#1 v2.1, i.e. RFC 3447 - Sect 5.1.2. Simply, put the message undergo a modular - exponentiation using the private key. Additionnal method - parameters are just ignored. - - - 'pkcs': the ciphertext 'C' is applied RSAES-PKCS1-V1_5-DECRYPT - decryption scheme as described in section 7.2.2 of RFC 3447. - In that context, other parameters ('h', 'mgf', 'l') are not - used. - - - 'oaep': the ciphertext 'C' is applied the RSAES-OAEP-DECRYPT decryption - scheme, as described in PKCS#1 v2.1, i.e. RFC 3447 Sect - 7.1.2. In that context, - - o 'h' parameter provides the name of the hash method to use. - Possible values are "md2", "md4", "md5", "sha1", "tls", - "sha224", "sha256", "sha384" and "sha512". if none is provided, - sha1 is used by default. - - o 'mgf' is the mask generation function. By default, mgf - is derived from the provided hash function using the - generic MGF1 (see pkcs_mgf1() for details). - - o 'L' is the optional label to be associated with the - message. If not provided, the default value is used, i.e - the empty string. No check is done on the input limitation - of the hash function regarding the size of 'L' (for - instance, 2^61 - 1 for SHA-1). You have been warned. - """ - if t is None: - C = pkcs_os2ip(C) - c = self._rsadp(C) - l = int(math.ceil(math.log(c, 2) / 8.)) # Hack - return pkcs_i2osp(c, l) - - elif t == "pkcs": - return self._rsaes_pkcs1_v1_5_decrypt(C) - - elif t == "oaep": - return self._rsaes_oaep_decrypt(C, h, mgf, L) - - else: - warning("Key.decrypt(): Unknown decryption type (%s) provided" % t) - return None - - ### Below are signature related methods. Verification ones are inherited from - ### PubKey - - def _rsasp1(self, m): - """ - Internal method providing raw RSA signature, i.e. simple modular - exponentiation of the given message representative 'm', an integer - between 0 and n-1. - - This is the signature primitive RSASP1 described in PKCS#1 v2.1, - i.e. RFC 3447 Sect. 5.2.1. - - Input: - m: message representative, an integer between 0 and n-1, where - n is the key modulus. - - Output: - signature representative, an integer between 0 and n-1 - - Not intended to be used directly. Please, see sign() method. - """ - return self._rsadp(m) - - - def _rsassa_pss_sign(self, M, h=None, mgf=None, sLen=None): - """ - Implements RSASSA-PSS-SIGN() function described in Sect. 8.1.1 of - RFC 3447. - - Input: - M: message to be signed, an octet string - - Output: - signature, an octet string of length k, where k is the length in - octets of the RSA modulus n. - - On error, None is returned. - """ - - # Set default parameters if not provided - if h is None: # By default, sha1 - h = "sha1" - if not h in _hashFuncParams: - warning("Key._rsassa_pss_sign(): unknown hash function " - "provided (%s)" % h) - return None - if mgf is None: # use mgf1 with underlying hash function - mgf = lambda x,y: pkcs_mgf1(x, y, h) - if sLen is None: # use Hash output length (A.2.3 of RFC 3447) - hLen = _hashFuncParams[h][0] - sLen = hLen - - # 1) EMSA-PSS encoding - modBits = self.modulusLen - k = modBits / 8 - EM = pkcs_emsa_pss_encode(M, modBits - 1, h, mgf, sLen) - if EM is None: - warning("Key._rsassa_pss_sign(): unable to encode") - return None - - # 2) RSA signature - m = pkcs_os2ip(EM) # 2.a) - s = self._rsasp1(m) # 2.b) - S = pkcs_i2osp(s, k) # 2.c) - - return S # 3) - - - def _rsassa_pkcs1_v1_5_sign(self, M, h): - """ - Implements RSASSA-PKCS1-v1_5-SIGN() function as described in - Sect. 8.2.1 of RFC 3447. - - Input: - M: message to be signed, an octet string - h: hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls' - 'sha256', 'sha384'). - - Output: - the signature, an octet string. - """ - - # 1) EMSA-PKCS1-v1_5 encoding - k = self.modulusLen / 8 - EM = pkcs_emsa_pkcs1_v1_5_encode(M, k, h) - if EM is None: - warning("Key._rsassa_pkcs1_v1_5_sign(): unable to encode") - return None - - # 2) RSA signature - m = pkcs_os2ip(EM) # 2.a) - s = self._rsasp1(m) # 2.b) - S = pkcs_i2osp(s, k) # 2.c) - - return S # 3) - - - def sign(self, M, t=None, h=None, mgf=None, sLen=None): - """ - Sign message 'M' using 't' signature scheme where 't' can be: - - - None: the message 'M' is directly applied the RSASP1 signature - primitive, as described in PKCS#1 v2.1, i.e. RFC 3447 Sect - 5.2.1. Simply put, the message undergo a modular exponentiation - using the private key. Additionnal method parameters are just - ignored. - - - 'pkcs': the message 'M' is applied RSASSA-PKCS1-v1_5-SIGN signature - scheme as described in Sect. 8.2.1 of RFC 3447. In that context, - the hash function name is passed using 'h'. Possible values are - "md2", "md4", "md5", "sha1", "tls", "sha224", "sha256", "sha384" - and "sha512". If none is provided, sha1 is used. Other additionnal - parameters are ignored. - - - 'pss' : the message 'M' is applied RSASSA-PSS-SIGN signature scheme as - described in Sect. 8.1.1. of RFC 3447. In that context, - - o 'h' parameter provides the name of the hash method to use. - Possible values are "md2", "md4", "md5", "sha1", "tls", "sha224", - "sha256", "sha384" and "sha512". if none is provided, sha1 - is used. - - o 'mgf' is the mask generation function. By default, mgf - is derived from the provided hash function using the - generic MGF1 (see pkcs_mgf1() for details). - - o 'sLen' is the length in octet of the salt. You can overload the - default value (the octet length of the hash value for provided - algorithm) by providing another one with that parameter. - """ - - if t is None: # RSASP1 - M = pkcs_os2ip(M) - n = self.modulus - if M > n-1: - warning("Message to be signed is too long for key modulus") - return None - s = self._rsasp1(M) - if s is None: - return None - return pkcs_i2osp(s, self.modulusLen/8) - - elif t == "pkcs": # RSASSA-PKCS1-v1_5-SIGN - if h is None: - h = "sha1" - return self._rsassa_pkcs1_v1_5_sign(M, h) - - elif t == "pss": # RSASSA-PSS-SIGN - return self._rsassa_pss_sign(M, h, mgf, sLen) - - else: - warning("Key.sign(): Unknown signature type (%s) provided" % t) - return None - - -def openssl_parse_RSA(fmt="PEM"): - return popen3(['openssl', 'rsa', '-text', '-pubin', '-inform', fmt, '-noout']) -def openssl_convert_RSA(infmt="PEM", outfmt="DER"): - return ['openssl', 'rsa', '-pubin', '-inform', infmt, '-outform', outfmt] - -class PubKey(OSSLHelper, _EncryptAndVerify): - # Below are the fields we recognize in the -text output of openssl - # and from which we extract information. We expect them in that - # order. Number of spaces does matter. - possible_fields = [ "Modulus (", - "Exponent:" ] - possible_fields_count = len(possible_fields) - - def __init__(self, keypath): - error_msg = "Unable to import key." - - # XXX Temporary hack to use PubKey inside Cert - if type(keypath) is tuple: - e, m, mLen = keypath - self.modulus = m - self.modulusLen = mLen - self.pubExp = e - return - - fields_dict = {} - for k in self.possible_fields: - fields_dict[k] = None - - self.keypath = None - rawkey = None - - if (not '\x00' in keypath) and os.path.isfile(keypath): # file - self.keypath = keypath - key_size = os.path.getsize(keypath) - if key_size > MAX_KEY_SIZE: - raise Exception(error_msg) - try: - f = open(keypath) - rawkey = f.read() - f.close() - except: - raise Exception(error_msg) - else: - rawkey = keypath - - if rawkey is None: - raise Exception(error_msg) - - self.rawkey = rawkey - - key_header = "-----BEGIN PUBLIC KEY-----" - key_footer = "-----END PUBLIC KEY-----" - l = rawkey.split(key_header, 1) - if len(l) == 2: # looks like PEM - tmp = l[1] - l = tmp.split(key_footer, 1) - if len(l) == 2: - tmp = l[0] - rawkey = "%s%s%s\n" % (key_header, tmp, key_footer) - else: - raise Exception(error_msg) - r,w,e = openssl_parse_RSA("PEM") - w.write(rawkey) - w.close() - textkey = r.read() - r.close() - res = e.read() - e.close() - if res == '': - self.format = "PEM" - self.pemkey = rawkey - self.textkey = textkey - cmd = openssl_convert_RSA_cmd("PEM", "DER") - self.derkey = self._apply_ossl_cmd(cmd, rawkey) - else: - raise Exception(error_msg) - else: # not PEM, try DER - r,w,e = openssl_parse_RSA("DER") - w.write(rawkey) - w.close() - textkey = r.read() - r.close() - res = e.read() - if res == '': - self.format = "DER" - self.derkey = rawkey - self.textkey = textkey - cmd = openssl_convert_RSA_cmd("DER", "PEM") - self.pemkey = self._apply_ossl_cmd(cmd, rawkey) - cmd = openssl_convert_RSA_cmd("DER", "DER") - self.derkey = self._apply_ossl_cmd(cmd, rawkey) - else: - try: # Perhaps it is a cert - c = Cert(keypath) - except: - raise Exception(error_msg) - # TODO: - # Reconstruct a key (der and pem) and provide: - # self.format - # self.derkey - # self.pemkey - # self.textkey - # self.keypath - - self.osslcmdbase = ['openssl', 'rsa', '-pubin', '-inform', self.format] - - self.keypath = keypath - - # Parse the -text output of openssl to make things available - l = self.textkey.split('\n', 1) - if len(l) != 2: - raise Exception(error_msg) - cur, tmp = l - i = 0 - k = self.possible_fields[i] # Modulus ( - cur = cur[len(k):] + '\n' - while k: - l = tmp.split('\n', 1) - if len(l) != 2: # Over - fields_dict[k] = cur - break - l, tmp = l - - newkey = 0 - # skip fields we have already seen, this is the purpose of 'i' - for j in range(i, self.possible_fields_count): - f = self.possible_fields[j] - if l.startswith(f): - fields_dict[k] = cur - cur = l[len(f):] + '\n' - k = f - newkey = 1 - i = j+1 - break - if newkey == 1: - continue - cur += l + '\n' - - # modulus and modulus length - v = fields_dict["Modulus ("] - self.modulusLen = None - if v: - v, rem = v.split(' bit):', 1) - self.modulusLen = int(v) - rem = rem.replace('\n','').replace(' ','').replace(':','') - self.modulus = long(rem, 16) - if self.modulus is None: - raise Exception(error_msg) - - # public exponent - v = fields_dict["Exponent:"] - self.pubExp = None - if v: - self.pubExp = long(v.split('(', 1)[0]) - if self.pubExp is None: - raise Exception(error_msg) - - self.key = RSA.construct((self.modulus, self.pubExp, )) - - def __str__(self): - return self.derkey - - -class Key(_DecryptAndSignMethods, _EncryptAndVerify): - # Below are the fields we recognize in the -text output of openssl - # and from which we extract information. We expect them in that - # order. Number of spaces does matter. - possible_fields = [ "Private-Key: (", - "modulus:", - "publicExponent:", - "privateExponent:", - "prime1:", - "prime2:", - "exponent1:", - "exponent2:", - "coefficient:" ] - possible_fields_count = len(possible_fields) - - def __init__(self, keypath): - error_msg = "Unable to import key." - - fields_dict = {} - for k in self.possible_fields: - fields_dict[k] = None - - self.keypath = None - rawkey = None - - if (not '\x00' in keypath) and os.path.isfile(keypath): - self.keypath = keypath - key_size = os.path.getsize(keypath) - if key_size > MAX_KEY_SIZE: - raise Exception(error_msg) - try: - f = open(keypath) - rawkey = f.read() - f.close() - except: - raise Exception(error_msg) - else: - rawkey = keypath - - if rawkey is None: - raise Exception(error_msg) - - self.rawkey = rawkey - - # Let's try to get file format : PEM or DER. - fmtstr = 'openssl rsa -text -inform %s -noout' - convertstr = 'openssl rsa -inform %s -outform %s' - key_header = "-----BEGIN RSA PRIVATE KEY-----" - key_footer = "-----END RSA PRIVATE KEY-----" - l = rawkey.split(key_header, 1) - if len(l) == 2: # looks like PEM - tmp = l[1] - l = tmp.split(key_footer, 1) - if len(l) == 2: - tmp = l[0] - rawkey = "%s%s%s\n" % (key_header, tmp, key_footer) - else: - raise Exception(error_msg) - r,w,e = popen3((fmtstr % "PEM").split(" ")) - w.write(rawkey) - w.close() - textkey = r.read() - r.close() - res = e.read() - e.close() - if res == '': - self.format = "PEM" - self.pemkey = rawkey - self.textkey = textkey - cmd = (convertstr % ("PEM", "DER")).split(" ") - self.derkey = self._apply_ossl_cmd(cmd, rawkey) - else: - raise Exception(error_msg) - else: # not PEM, try DER - r,w,e = popen3((fmtstr % "DER").split(" ")) - w.write(rawkey) - w.close() - textkey = r.read() - r.close() - res = e.read() - if res == '': - self.format = "DER" - self.derkey = rawkey - self.textkey = textkey - cmd = (convertstr % ("DER", "PEM")).split(" ") - self.pemkey = self._apply_ossl_cmd(cmd, rawkey) - cmd = (convertstr % ("DER", "DER")).split(" ") - self.derkey = self._apply_ossl_cmd(cmd, rawkey) - else: - raise Exception(error_msg) - - self.osslcmdbase = ['openssl', 'rsa', '-inform', self.format] - - r,w,e = popen3(["openssl", "asn1parse", "-inform", "DER"]) - w.write(self.derkey) - w.close() - self.asn1parsekey = r.read() - r.close() - res = e.read() - e.close() - if res != '': - raise Exception(error_msg) - - self.keypath = keypath - - # Parse the -text output of openssl to make things available - l = self.textkey.split('\n', 1) - if len(l) != 2: - raise Exception(error_msg) - cur, tmp = l - i = 0 - k = self.possible_fields[i] # Private-Key: ( - cur = cur[len(k):] + '\n' - while k: - l = tmp.split('\n', 1) - if len(l) != 2: # Over - fields_dict[k] = cur - break - l, tmp = l - - newkey = 0 - # skip fields we have already seen, this is the purpose of 'i' - for j in range(i, self.possible_fields_count): - f = self.possible_fields[j] - if l.startswith(f): - fields_dict[k] = cur - cur = l[len(f):] + '\n' - k = f - newkey = 1 - i = j+1 - break - if newkey == 1: - continue - cur += l + '\n' - - # modulus length - v = fields_dict["Private-Key: ("] - self.modulusLen = None - if v: - self.modulusLen = int(v.split(' bit', 1)[0]) - if self.modulusLen is None: - raise Exception(error_msg) - - # public exponent - v = fields_dict["publicExponent:"] - self.pubExp = None - if v: - self.pubExp = long(v.split('(', 1)[0]) - if self.pubExp is None: - raise Exception(error_msg) - - tmp = {} - for k in ["modulus:", "privateExponent:", "prime1:", "prime2:", - "exponent1:", "exponent2:", "coefficient:"]: - v = fields_dict[k] - if v: - s = v.replace('\n', '').replace(' ', '').replace(':', '') - tmp[k] = long(s, 16) - else: - raise Exception(error_msg) - - self.modulus = tmp["modulus:"] - self.privExp = tmp["privateExponent:"] - self.prime1 = tmp["prime1:"] - self.prime2 = tmp["prime2:"] - self.exponent1 = tmp["exponent1:"] - self.exponent2 = tmp["exponent2:"] - self.coefficient = tmp["coefficient:"] - - self.key = RSA.construct((self.modulus, self.pubExp, self.privExp)) - - def __str__(self): - return self.derkey - - -# We inherit from PubKey to get access to all encryption and verification -# methods. To have that working, we simply need Cert to provide -# modulusLen and key attribute. -# XXX Yes, it is a hack. -class Cert(OSSLHelper, _EncryptAndVerify): - # Below are the fields we recognize in the -text output of openssl - # and from which we extract information. We expect them in that - # order. Number of spaces does matter. - possible_fields = [ " Version:", - " Serial Number:", - " Signature Algorithm:", - " Issuer:", - " Not Before:", - " Not After :", - " Subject:", - " Public Key Algorithm:", - " Modulus (", - " Exponent:", - " X509v3 Subject Key Identifier:", - " X509v3 Authority Key Identifier:", - " keyid:", - " DirName:", - " serial:", - " X509v3 Basic Constraints:", - " X509v3 Key Usage:", - " X509v3 Extended Key Usage:", - " X509v3 CRL Distribution Points:", - " Authority Information Access:", - " Signature Algorithm:" ] - possible_fields_count = len(possible_fields) - - def __init__(self, certpath): - error_msg = "Unable to import certificate." - - fields_dict = {} - for k in self.possible_fields: - fields_dict[k] = None - - self.certpath = None - rawcert = None - - if (not '\x00' in certpath) and os.path.isfile(certpath): # file - self.certpath = certpath - cert_size = os.path.getsize(certpath) - if cert_size > MAX_CERT_SIZE: - raise Exception(error_msg) - try: - f = open(certpath) - rawcert = f.read() - f.close() - except: - raise Exception(error_msg) - else: - rawcert = certpath - - if rawcert is None: - raise Exception(error_msg) - - self.rawcert = rawcert - - # Let's try to get file format : PEM or DER. - fmtstr = 'openssl x509 -text -inform %s -noout' - convertstr = 'openssl x509 -inform %s -outform %s' - cert_header = "-----BEGIN CERTIFICATE-----" - cert_footer = "-----END CERTIFICATE-----" - l = rawcert.split(cert_header, 1) - if len(l) == 2: # looks like PEM - tmp = l[1] - l = tmp.split(cert_footer, 1) - if len(l) == 2: - tmp = l[0] - rawcert = "%s%s%s\n" % (cert_header, tmp, cert_footer) - else: - raise Exception(error_msg) - r,w,e = popen3((fmtstr % "PEM").split(" ")) - w.write(rawcert) - w.close() - textcert = r.read() - r.close() - res = e.read() - e.close() - if res == '': - self.format = "PEM" - self.pemcert = rawcert - self.textcert = textcert - cmd = (convertstr % ("PEM", "DER")).split(" ") - self.dercert = self._apply_ossl_cmd(cmd, rawcert) - else: - raise Exception(error_msg) - else: # not PEM, try DER - r,w,e = popen3((fmtstr % "DER").split(" ")) - w.write(rawcert) - w.close() - textcert = r.read() - r.close() - res = e.read() - if res == '': - self.format = "DER" - self.dercert = rawcert - self.textcert = textcert - cmd = (convertstr % ("DER", "PEM")).split(" ") - self.pemcert = self._apply_ossl_cmd(cmd, rawcert) - cmd = (convertstr % ("DER", "DER")).split(" ") - self.dercert = self._apply_ossl_cmd(cmd, rawcert) - else: - raise Exception(error_msg) - - self.osslcmdbase = ['openssl', 'x509', '-inform', self.format] - - r,w,e = popen3('openssl asn1parse -inform DER'.split(' ')) - w.write(self.dercert) - w.close() - self.asn1parsecert = r.read() - r.close() - res = e.read() - e.close() - if res != '': - raise Exception(error_msg) - - # Grab _raw_ X509v3 Authority Key Identifier, if any. - tmp = self.asn1parsecert.split(":X509v3 Authority Key Identifier", 1) - self.authorityKeyID = None - if len(tmp) == 2: - tmp = tmp[1] - tmp = tmp.split("[HEX DUMP]:", 1)[1] - self.authorityKeyID=tmp.split('\n',1)[0] - - # Grab _raw_ X509v3 Subject Key Identifier, if any. - tmp = self.asn1parsecert.split(":X509v3 Subject Key Identifier", 1) - self.subjectKeyID = None - if len(tmp) == 2: - tmp = tmp[1] - tmp = tmp.split("[HEX DUMP]:", 1)[1] - self.subjectKeyID=tmp.split('\n',1)[0] - - # Get tbsCertificate using the worst hack. output of asn1parse - # looks like that: - # - # 0:d=0 hl=4 l=1298 cons: SEQUENCE - # 4:d=1 hl=4 l=1018 cons: SEQUENCE - # ... - # - l1,l2 = self.asn1parsecert.split('\n', 2)[:2] - hl1 = int(l1.split("hl=",1)[1].split("l=",1)[0]) - rem = l2.split("hl=",1)[1] - hl2, rem = rem.split("l=",1) - hl2 = int(hl2) - l = int(rem.split("cons",1)[0]) - self.tbsCertificate = self.dercert[hl1:hl1+hl2+l] - - # Parse the -text output of openssl to make things available - tmp = self.textcert.split('\n', 2)[2] - l = tmp.split('\n', 1) - if len(l) != 2: - raise Exception(error_msg) - cur, tmp = l - i = 0 - k = self.possible_fields[i] # Version: - cur = cur[len(k):] + '\n' - while k: - l = tmp.split('\n', 1) - if len(l) != 2: # Over - fields_dict[k] = cur - break - l, tmp = l - - newkey = 0 - # skip fields we have already seen, this is the purpose of 'i' - for j in range(i, self.possible_fields_count): - f = self.possible_fields[j] - if l.startswith(f): - fields_dict[k] = cur - cur = l[len(f):] + '\n' - k = f - newkey = 1 - i = j+1 - break - if newkey == 1: - continue - cur += l + '\n' - - # version - v = fields_dict[" Version:"] - self.version = None - if v: - self.version = int(v[1:2]) - if self.version is None: - raise Exception(error_msg) - - # serial number - v = fields_dict[" Serial Number:"] - self.serial = None - if v: - v = v.replace('\n', '').strip() - if "0x" in v: - v = v.split("0x", 1)[1].split(')', 1)[0] - v = v.replace(':', '').upper() - if len(v) % 2: - v = '0' + v - self.serial = v - if self.serial is None: - raise Exception(error_msg) - - # Signature Algorithm - v = fields_dict[" Signature Algorithm:"] - self.sigAlg = None - if v: - v = v.split('\n',1)[0] - v = v.strip() - self.sigAlg = v - if self.sigAlg is None: - raise Exception(error_msg) - - # issuer - v = fields_dict[" Issuer:"] - self.issuer = None - if v: - v = v.split('\n',1)[0] - v = v.strip() - self.issuer = v - if self.issuer is None: - raise Exception(error_msg) - - # not before - v = fields_dict[" Not Before:"] - self.notBefore_str = None - if v: - v = v.split('\n',1)[0] - v = v.strip() - self.notBefore_str = v - if self.notBefore_str is None: - raise Exception(error_msg) - try: - self.notBefore = time.strptime(self.notBefore_str, - "%b %d %H:%M:%S %Y %Z") - except: - self.notBefore = time.strptime(self.notBefore_str, - "%b %d %H:%M:%S %Y") - self.notBefore_str_simple = time.strftime("%x", self.notBefore) - - # not after - v = fields_dict[" Not After :"] - self.notAfter_str = None - if v: - v = v.split('\n',1)[0] - v = v.strip() - self.notAfter_str = v - if self.notAfter_str is None: - raise Exception(error_msg) - try: - self.notAfter = time.strptime(self.notAfter_str, - "%b %d %H:%M:%S %Y %Z") - except: - self.notAfter = time.strptime(self.notAfter_str, - "%b %d %H:%M:%S %Y") - self.notAfter_str_simple = time.strftime("%x", self.notAfter) - - # subject - v = fields_dict[" Subject:"] - self.subject = None - if v: - v = v.split('\n',1)[0] - v = v.strip() - self.subject = v - if self.subject is None: - raise Exception(error_msg) - - # Public Key Algorithm - v = fields_dict[" Public Key Algorithm:"] - self.pubKeyAlg = None - if v: - v = v.split('\n',1)[0] - v = v.strip() - self.pubKeyAlg = v - if self.pubKeyAlg is None: - raise Exception(error_msg) - - # Modulus - v = fields_dict[" Modulus ("] - self.modulus = None - if v: - v,t = v.split(' bit):',1) - self.modulusLen = int(v) - t = t.replace(' ', '').replace('\n', ''). replace(':', '') - self.modulus_hexdump = t - self.modulus = long(t, 16) - if self.modulus is None: - raise Exception(error_msg) - - # Exponent - v = fields_dict[" Exponent:"] - self.exponent = None - if v: - v = v.split('(',1)[0] - self.exponent = long(v) - if self.exponent is None: - raise Exception(error_msg) - - # Public Key instance - self.key = RSA.construct((self.modulus, self.exponent, )) - - # Subject Key Identifier - - # Authority Key Identifier: keyid, dirname and serial - self.authorityKeyID_keyid = None - self.authorityKeyID_dirname = None - self.authorityKeyID_serial = None - if self.authorityKeyID: # (hex version already done using asn1parse) - v = fields_dict[" keyid:"] - if v: - v = v.split('\n',1)[0] - v = v.strip().replace(':', '') - self.authorityKeyID_keyid = v - v = fields_dict[" DirName:"] - if v: - v = v.split('\n',1)[0] - self.authorityKeyID_dirname = v - v = fields_dict[" serial:"] - if v: - v = v.split('\n',1)[0] - v = v.strip().replace(':', '') - self.authorityKeyID_serial = v - - # Basic constraints - self.basicConstraintsCritical = False - self.basicConstraints=None - v = fields_dict[" X509v3 Basic Constraints:"] - if v: - self.basicConstraints = {} - v,t = v.split('\n',2)[:2] - if "critical" in v: - self.basicConstraintsCritical = True - if "CA:" in t: - self.basicConstraints["CA"] = t.split('CA:')[1][:4] == "TRUE" - if "pathlen:" in t: - self.basicConstraints["pathlen"] = int(t.split('pathlen:')[1]) - - # X509v3 Key Usage - self.keyUsage = [] - v = fields_dict[" X509v3 Key Usage:"] - if v: - # man 5 x509v3_config - ku_mapping = {"Digital Signature": "digitalSignature", - "Non Repudiation": "nonRepudiation", - "Key Encipherment": "keyEncipherment", - "Data Encipherment": "dataEncipherment", - "Key Agreement": "keyAgreement", - "Certificate Sign": "keyCertSign", - "CRL Sign": "cRLSign", - "Encipher Only": "encipherOnly", - "Decipher Only": "decipherOnly"} - v = v.split('\n',2)[1] - l = map(lambda x: x.strip(), v.split(',')) - while l: - c = l.pop() - if c in ku_mapping: - self.keyUsage.append(ku_mapping[c]) - else: - self.keyUsage.append(c) # Add it anyway - print("Found unknown X509v3 Key Usage: '%s'" % c) - print("Report it to arno (at) natisbad.org for addition") - - # X509v3 Extended Key Usage - self.extKeyUsage = [] - v = fields_dict[" X509v3 Extended Key Usage:"] - if v: - # man 5 x509v3_config: - eku_mapping = {"TLS Web Server Authentication": "serverAuth", - "TLS Web Client Authentication": "clientAuth", - "Code Signing": "codeSigning", - "E-mail Protection": "emailProtection", - "Time Stamping": "timeStamping", - "Microsoft Individual Code Signing": "msCodeInd", - "Microsoft Commercial Code Signing": "msCodeCom", - "Microsoft Trust List Signing": "msCTLSign", - "Microsoft Encrypted File System": "msEFS", - "Microsoft Server Gated Crypto": "msSGC", - "Netscape Server Gated Crypto": "nsSGC", - "IPSec End System": "iPsecEndSystem", - "IPSec Tunnel": "iPsecTunnel", - "IPSec User": "iPsecUser"} - v = v.split('\n',2)[1] - l = map(lambda x: x.strip(), v.split(',')) - while l: - c = l.pop() - if c in eku_mapping: - self.extKeyUsage.append(eku_mapping[c]) - else: - self.extKeyUsage.append(c) # Add it anyway - print("Found unknown X509v3 Extended Key Usage: '%s'" % c) - print("Report it to arno (at) natisbad.org for addition") - - # CRL Distribution points - self.cRLDistributionPoints = [] - v = fields_dict[" X509v3 CRL Distribution Points:"] - if v: - v = v.split("\n\n", 1)[0] - v = v.split("URI:")[1:] - self.CRLDistributionPoints = map(lambda x: x.strip(), v) - - # Authority Information Access: list of tuples ("method", "location") - self.authorityInfoAccess = [] - v = fields_dict[" Authority Information Access:"] - if v: - v = v.split("\n\n", 1)[0] - v = v.split("\n")[1:] - for e in v: - method, location = map(lambda x: x.strip(), e.split(" - ", 1)) - self.authorityInfoAccess.append((method, location)) - - # signature field - v = fields_dict[" Signature Algorithm:" ] - self.sig = None - if v: - v = v.split('\n',1)[1] - v = v.replace(' ', '').replace('\n', '') - self.sig = "".join(map(lambda x: chr(int(x, 16)), v.split(':'))) - self.sigLen = len(self.sig) - if self.sig is None: - raise Exception(error_msg) - - def isIssuerCert(self, other): - """ - True if 'other' issued 'self', i.e.: - - self.issuer == other.subject - - self is signed by other - """ - # XXX should be done on raw values, instead of their textual repr - if self.issuer != other.subject: - return False - - # Sanity check regarding modulus length and the - # signature length - keyLen = (other.modulusLen + 7)/8 - if keyLen != self.sigLen: - return False - - unenc = other.encrypt(self.sig) # public key encryption, i.e. decrypt - - # XXX Check block type (00 or 01 and type of padding) - unenc = unenc[1:] - if not '\x00' in unenc: - return False - pos = unenc.index('\x00') - unenc = unenc[pos+1:] - - found = None - for k in _hashFuncParams.keys(): - if self.sigAlg.startswith(k): - found = k - break - if not found: - return False - hlen, hfunc, digestInfo = _hashFuncParams[k] - - if len(unenc) != (hlen+len(digestInfo)): - return False - - if not unenc.startswith(digestInfo): - return False - - h = unenc[-hlen:] - myh = hfunc(self.tbsCertificate) - - return h == myh - - def chain(self, certlist): - """ - Construct the chain of certificates leading from 'self' to the - self signed root using the certificates in 'certlist'. If the - list does not provide all the required certs to go to the root - the function returns a incomplete chain starting with the - certificate. This fact can be tested by tchecking if the last - certificate of the returned chain is self signed (if c is the - result, c[-1].isSelfSigned()) - """ - d = {} - for c in certlist: - # XXX we should check if we have duplicate - d[c.subject] = c - res = [self] - cur = self - while not cur.isSelfSigned(): - if cur.issuer in d: - possible_issuer = d[cur.issuer] - if cur.isIssuerCert(possible_issuer): - res.append(possible_issuer) - cur = possible_issuer - else: - break - return res - - def remainingDays(self, now=None): - """ - Based on the value of notBefore field, returns the number of - days the certificate will still be valid. The date used for the - comparison is the current and local date, as returned by - time.localtime(), except if 'now' argument is provided another - one. 'now' argument can be given as either a time tuple or a string - representing the date. Accepted format for the string version - are: - - - '%b %d %H:%M:%S %Y %Z' e.g. 'Jan 30 07:38:59 2008 GMT' - - '%m/%d/%y' e.g. '01/30/08' (less precise) - - If the certificate is no more valid at the date considered, then, - a negative value is returned representing the number of days - since it has expired. - - The number of days is returned as a float to deal with the unlikely - case of certificates that are still just valid. - """ - if now is None: - now = time.localtime() - elif type(now) is str: - try: - if '/' in now: - now = time.strptime(now, '%m/%d/%y') - else: - now = time.strptime(now, '%b %d %H:%M:%S %Y %Z') - except: - warning("Bad time string provided '%s'. Using current time" % now) - now = time.localtime() - - now = time.mktime(now) - nft = time.mktime(self.notAfter) - diff = (nft - now)/(24.*3600) - return diff - - - # return SHA-1 hash of cert embedded public key - # !! At the moment, the trailing 0 is in the hashed string if any - def keyHash(self): - m = self.modulus_hexdump - res = [] - i = 0 - l = len(m) - while i MAX_CRL_SIZE: - raise Exception(error_msg) - try: - f = open(crlpath) - rawcrl = f.read() - f.close() - except: - raise Exception(error_msg) - else: - rawcrl = crlpath - - if rawcrl is None: - raise Exception(error_msg) - - self.rawcrl = rawcrl - - # Let's try to get file format : PEM or DER. - fmtstr = 'openssl crl -text -inform %s -noout' - convertstr = 'openssl crl -inform %s -outform %s' - crl_header = "-----BEGIN X509 CRL-----" - crl_footer = "-----END X509 CRL-----" - l = rawcrl.split(crl_header, 1) - if len(l) == 2: # looks like PEM - tmp = l[1] - l = tmp.split(crl_footer, 1) - if len(l) == 2: - tmp = l[0] - rawcrl = "%s%s%s\n" % (crl_header, tmp, crl_footer) - else: - raise Exception(error_msg) - r,w,e = popen3((fmtstr % "PEM").split(" ")) - w.write(rawcrl) - w.close() - textcrl = r.read() - r.close() - res = e.read() - e.close() - if res == '': - self.format = "PEM" - self.pemcrl = rawcrl - self.textcrl = textcrl - cmd = (convertstr % ("PEM", "DER")).split(" ") - self.dercrl = self._apply_ossl_cmd(cmd, rawcrl) - else: - raise Exception(error_msg) - else: # not PEM, try DER - r,w,e = popen3((fmtstr % "DER").split(' ')) - w.write(rawcrl) - w.close() - textcrl = r.read() - r.close() - res = e.read() - if res == '': - self.format = "DER" - self.dercrl = rawcrl - self.textcrl = textcrl - cmd = (convertstr % ("DER", "PEM")).split(" ") - self.pemcrl = self._apply_ossl_cmd(cmd, rawcrl) - cmd = (convertstr % ("DER", "DER")).split(" ") - self.dercrl = self._apply_ossl_cmd(cmd, rawcrl) - else: - raise Exception(error_msg) - - self.osslcmdbase = ['openssl', 'crl', '-inform', self.format] - - r,w,e = popen3(('openssl asn1parse -inform DER').split(" ")) - w.write(self.dercrl) - w.close() - self.asn1parsecrl = r.read() - r.close() - res = e.read() - e.close() - if res != '': - raise Exception(error_msg) - - # Grab _raw_ X509v3 Authority Key Identifier, if any. - tmp = self.asn1parsecrl.split(":X509v3 Authority Key Identifier", 1) - self.authorityKeyID = None - if len(tmp) == 2: - tmp = tmp[1] - tmp = tmp.split("[HEX DUMP]:", 1)[1] - self.authorityKeyID=tmp.split('\n',1)[0] - - # Parse the -text output of openssl to make things available - tmp = self.textcrl.split('\n', 1)[1] - l = tmp.split('\n', 1) - if len(l) != 2: - raise Exception(error_msg) - cur, tmp = l - i = 0 - k = self.possible_fields[i] # Version - cur = cur[len(k):] + '\n' - while k: - l = tmp.split('\n', 1) - if len(l) != 2: # Over - fields_dict[k] = cur - break - l, tmp = l - - newkey = 0 - # skip fields we have already seen, this is the purpose of 'i' - for j in range(i, self.possible_fields_count): - f = self.possible_fields[j] - if l.startswith(f): - fields_dict[k] = cur - cur = l[len(f):] + '\n' - k = f - newkey = 1 - i = j+1 - break - if newkey == 1: - continue - cur += l + '\n' - - # version - v = fields_dict[" Version"] - self.version = None - if v: - self.version = int(v[1:2]) - if self.version is None: - raise Exception(error_msg) - - # signature algorithm - v = fields_dict[" Signature Algorithm:"] - self.sigAlg = None - if v: - v = v.split('\n',1)[0] - v = v.strip() - self.sigAlg = v - if self.sigAlg is None: - raise Exception(error_msg) - - # issuer - v = fields_dict[" Issuer:"] - self.issuer = None - if v: - v = v.split('\n',1)[0] - v = v.strip() - self.issuer = v - if self.issuer is None: - raise Exception(error_msg) - - # last update - v = fields_dict[" Last Update:"] - self.lastUpdate_str = None - if v: - v = v.split('\n',1)[0] - v = v.strip() - self.lastUpdate_str = v - if self.lastUpdate_str is None: - raise Exception(error_msg) - self.lastUpdate = time.strptime(self.lastUpdate_str, - "%b %d %H:%M:%S %Y %Z") - self.lastUpdate_str_simple = time.strftime("%x", self.lastUpdate) - - # next update - v = fields_dict[" Next Update:"] - self.nextUpdate_str = None - if v: - v = v.split('\n',1)[0] - v = v.strip() - self.nextUpdate_str = v - if self.nextUpdate_str is None: - raise Exception(error_msg) - self.nextUpdate = time.strptime(self.nextUpdate_str, - "%b %d %H:%M:%S %Y %Z") - self.nextUpdate_str_simple = time.strftime("%x", self.nextUpdate) - - # XXX Do something for Issuer Alternative Name - - # Authority Key Identifier: keyid, dirname and serial - self.authorityKeyID_keyid = None - self.authorityKeyID_dirname = None - self.authorityKeyID_serial = None - if self.authorityKeyID: # (hex version already done using asn1parse) - v = fields_dict[" keyid:"] - if v: - v = v.split('\n',1)[0] - v = v.strip().replace(':', '') - self.authorityKeyID_keyid = v - v = fields_dict[" DirName:"] - if v: - v = v.split('\n',1)[0] - self.authorityKeyID_dirname = v - v = fields_dict[" serial:"] - if v: - v = v.split('\n',1)[0] - v = v.strip().replace(':', '') - self.authorityKeyID_serial = v - - # number - v = fields_dict[" X509v3 CRL Number:"] - self.number = None - if v: - v = v.split('\n',2)[1] - v = v.strip() - self.number = int(v) - - # Get the list of serial numbers of revoked certificates - self.revoked_cert_serials = [] - v = fields_dict["Revoked Certificates:"] - t = fields_dict["No Revoked Certificates."] - if (t is None and v is not None): - v = v.split("Serial Number: ")[1:] - for r in v: - s,d = r.split('\n', 1) - s = s.split('\n', 1)[0] - d = d.split("Revocation Date:", 1)[1] - d = time.strptime(d.strip(), "%b %d %H:%M:%S %Y %Z") - self.revoked_cert_serials.append((s,d)) - - # signature field - v = fields_dict[" Signature Algorithm:" ] - self.sig = None - if v: - v = v.split('\n',1)[1] - v = v.replace(' ', '').replace('\n', '') - self.sig = "".join(map(lambda x: chr(int(x, 16)), v.split(':'))) - self.sigLen = len(self.sig) - if self.sig is None: - raise Exception(error_msg) - - def __str__(self): - return self.dercrl - - # Print main informations stored in CRL - def show(self): - print("Version: %d" % self.version) - print("sigAlg: " + self.sigAlg) - print("Issuer: " + self.issuer) - print("lastUpdate: %s" % self.lastUpdate_str_simple) - print("nextUpdate: %s" % self.nextUpdate_str_simple) - - def verify(self, anchors): - """ - Return True if the CRL is signed by one of the provided - anchors. False on error (invalid signature, missing anchorand, ...) - """ - cafile = create_temporary_ca_file(anchors) - if cafile is None: - return False - try: - cmd = self.osslcmdbase + ["-noout", "-CAfile", cafile] - cmdres = self._apply_ossl_cmd(cmd, self.rawcrl) - except: - os.unlink(cafile) - return False - os.unlink(cafile) - return "verify OK" in cmdres - - - diff --git a/scripts/external_libs/scapy-2.4.3/scapy/dadict.py b/scripts/external_libs/scapy-2.4.3/scapy/dadict.py deleted file mode 100644 index d1b2bc259f..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/dadict.py +++ /dev/null @@ -1,122 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Direct Access dictionary. -""" - -from __future__ import absolute_import -from __future__ import print_function -from scapy.error import Scapy_Exception -import scapy.modules.six as six -from scapy.compat import plain_str - -############################### -# Direct Access dictionary # -############################### - - -def fixname(x): - if x and str(x[0]) in "0123456789": - x = "n_" + x - return x.translate( - "________________________________________________" - "0123456789_______ABCDEFGHIJKLMNOPQRSTUVWXYZ______" - "abcdefghijklmnopqrstuvwxyz____________________________" - "______________________________________________________" - "___________________________________________________" - ) - - -class DADict_Exception(Scapy_Exception): - pass - - -class DADict: - def __init__(self, _name="DADict", **kargs): - self._name = _name - self.update(kargs) - - def fixname(self, val): - return fixname(plain_str(val)) - - def __contains__(self, val): - return val in self.__dict__ - - def __getitem__(self, attr): - return getattr(self, attr) - - def __setitem__(self, attr, val): - return setattr(self, self.fixname(attr), val) - - def __iter__(self): - return (value for key, value in six.iteritems(self.__dict__) - if key and key[0] != '_') - - def _show(self): - for k in self.__dict__: - if k and k[0] != "_": - print("%10s = %r" % (k, getattr(self, k))) - - def __repr__(self): - return "<%s - %s elements>" % (self._name, len(self.__dict__)) - - def _branch(self, br, uniq=0): - if uniq and br._name in self: - raise DADict_Exception("DADict: [%s] already branched in [%s]" % (br._name, self._name)) # noqa: E501 - self[br._name] = br - - def _my_find(self, *args, **kargs): - if args and self._name not in args: - return False - return all(k in self and self[k] == v for k, v in six.iteritems(kargs)) - - def update(self, *args, **kwargs): - for k, v in six.iteritems(dict(*args, **kwargs)): - self[k] = v - - def _find(self, *args, **kargs): - return self._recurs_find((), *args, **kargs) - - def _recurs_find(self, path, *args, **kargs): - if self in path: - return None - if self._my_find(*args, **kargs): - return self - for o in self: - if isinstance(o, DADict): - p = o._recurs_find(path + (self,), *args, **kargs) - if p is not None: - return p - return None - - def _find_all(self, *args, **kargs): - return self._recurs_find_all((), *args, **kargs) - - def _recurs_find_all(self, path, *args, **kargs): - r = [] - if self in path: - return r - if self._my_find(*args, **kargs): - r.append(self) - for o in self: - if isinstance(o, DADict): - p = o._recurs_find_all(path + (self,), *args, **kargs) - r += p - return r - - def keys(self): - return list(self.iterkeys()) - - def iterkeys(self): - return (x for x in self.__dict__ if x and x[0] != "_") - - def __len__(self): - return len(self.__dict__) - - def __nonzero__(self): - # Always has at least its name - return len(self.__dict__) > 1 - __bool__ = __nonzero__ diff --git a/scripts/external_libs/scapy-2.4.3/scapy/data.py b/scripts/external_libs/scapy-2.4.3/scapy/data.py deleted file mode 100644 index edf4466483..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/data.py +++ /dev/null @@ -1,358 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Global variables and functions for handling external data sets. -""" - -import calendar -import os -import re - - -from scapy.dadict import DADict -from scapy.consts import FREEBSD, NETBSD, OPENBSD, WINDOWS -from scapy.error import log_loading -from scapy.compat import plain_str -import scapy.modules.six as six - - -############ -# Consts # -############ - -ETHER_ANY = b"\x00" * 6 -ETHER_BROADCAST = b"\xff" * 6 - -ETH_P_ALL = 3 -ETH_P_IP = 0x800 -ETH_P_ARP = 0x806 -ETH_P_IPV6 = 0x86dd -ETH_P_MACSEC = 0x88e5 - -# From net/if_arp.h -ARPHDR_ETHER = 1 -ARPHDR_METRICOM = 23 -ARPHDR_PPP = 512 -ARPHDR_LOOPBACK = 772 -ARPHDR_TUN = 65534 - -# From pcap/dlt.h -DLT_NULL = 0 -DLT_EN10MB = 1 -DLT_EN3MB = 2 -DLT_AX25 = 3 -DLT_PRONET = 4 -DLT_CHAOS = 5 -DLT_IEEE802 = 6 -DLT_ARCNET = 7 -DLT_SLIP = 8 -DLT_PPP = 9 -DLT_FDDI = 10 -if OPENBSD: - DLT_RAW = 14 -else: - DLT_RAW = 12 -DLT_RAW_ALT = 101 # At least in Argus -if FREEBSD or NETBSD: - DLT_SLIP_BSDOS = 13 - DLT_PPP_BSDOS = 14 -else: - DLT_SLIP_BSDOS = 15 - DLT_PPP_BSDOS = 16 -if FREEBSD: - DLT_PFSYNC = 121 -else: - DLT_PFSYNC = 18 - DLT_HHDLC = 121 -DLT_ATM_CLIP = 19 -DLT_PPP_SERIAL = 50 -DLT_PPP_ETHER = 51 -DLT_SYMANTEC_FIREWALL = 99 -DLT_C_HDLC = 104 -DLT_IEEE802_11 = 105 -if OPENBSD: - DLT_LOOP = 12 - DLT_ENC = 13 -else: - DLT_LOOP = 108 - DLT_ENC = 109 -DLT_LINUX_SLL = 113 -DLT_PFLOG = 117 -DLT_PRISM_HEADER = 119 -DLT_AIRONET_HEADER = 120 -DLT_IEEE802_11_RADIO = 127 -DLT_LINUX_IRDA = 144 -DLT_IEEE802_11_RADIO_AVS = 163 -DLT_BLUETOOTH_HCI_H4 = 187 -DLT_USB_LINUX = 189 -DLT_IEEE802_15_4_WITHFCS = 195 -DLT_BLUETOOTH_HCI_H4_WITH_PHDR = 201 -DLT_PPP_WITH_DIR = 204 -DLT_PPI = 192 -DLT_CAN_SOCKETCAN = 227 -DLT_IPV4 = 228 -DLT_IPV6 = 229 -DLT_IEEE802_15_4_NOFCS = 230 -DLT_USBPCAP = 249 -DLT_USB_DARWIN = 266 -DLT_BLUETOOTH_LE_LL = 251 -DLT_BLUETOOTH_LE_LL_WITH_PHDR = 256 - -# From net/ipv6.h on Linux (+ Additions) -IPV6_ADDR_UNICAST = 0x01 -IPV6_ADDR_MULTICAST = 0x02 -IPV6_ADDR_CAST_MASK = 0x0F -IPV6_ADDR_LOOPBACK = 0x10 -IPV6_ADDR_GLOBAL = 0x00 -IPV6_ADDR_LINKLOCAL = 0x20 -IPV6_ADDR_SITELOCAL = 0x40 # deprecated since Sept. 2004 by RFC 3879 -IPV6_ADDR_SCOPE_MASK = 0xF0 -# IPV6_ADDR_COMPATv4 = 0x80 # deprecated; i.e. ::/96 -# IPV6_ADDR_MAPPED = 0x1000 # i.e.; ::ffff:0.0.0.0/96 -IPV6_ADDR_6TO4 = 0x0100 # Added to have more specific info (should be 0x0101 ?) # noqa: E501 -IPV6_ADDR_UNSPECIFIED = 0x10000 - -# Constants for PPI header types. -PPI_DOT11COMMON = 2 -PPI_DOT11NMAC = 3 -PPI_DOT11NMACPHY = 4 -PPI_SPECTRUM_MAP = 5 -PPI_PROCESS_INFO = 6 -PPI_CAPTURE_INFO = 7 -PPI_AGGREGATION = 8 -PPI_DOT3 = 9 -PPI_GPS = 30002 -PPI_VECTOR = 30003 -PPI_SENSOR = 30004 -PPI_ANTENNA = 30005 -PPI_BTLE = 30006 - -# Human-readable type names for PPI header types. -PPI_TYPES = { - PPI_DOT11COMMON: 'dot11-common', - PPI_DOT11NMAC: 'dot11-nmac', - PPI_DOT11NMACPHY: 'dot11-nmacphy', - PPI_SPECTRUM_MAP: 'spectrum-map', - PPI_PROCESS_INFO: 'process-info', - PPI_CAPTURE_INFO: 'capture-info', - PPI_AGGREGATION: 'aggregation', - PPI_DOT3: 'dot3', - PPI_GPS: 'gps', - PPI_VECTOR: 'vector', - PPI_SENSOR: 'sensor', - PPI_ANTENNA: 'antenna', - PPI_BTLE: 'btle', -} - - -# On windows, epoch is 01/02/1970 at 00:00 -EPOCH = calendar.timegm((1970, 1, 2, 0, 0, 0, 3, 1, 0)) - 86400 - -MTU = 0xffff # a.k.a give me all you have - - -def load_protocols(filename, _fallback=None, _integer_base=10): - """"Parse /etc/protocols and return values as a dictionary.""" - spaces = re.compile(b"[ \t]+|\n") - dct = DADict(_name=filename) - - def _process_data(fdesc): - for line in fdesc: - try: - shrp = line.find(b"#") - if shrp >= 0: - line = line[:shrp] - line = line.strip() - if not line: - continue - lt = tuple(re.split(spaces, line)) - if len(lt) < 2 or not lt[0]: - continue - dct[lt[0]] = int(lt[1], _integer_base) - except Exception as e: - log_loading.info( - "Couldn't parse file [%s]: line [%r] (%s)", - filename, - line, - e, - ) - try: - if not filename: - raise IOError - with open(filename, "rb") as fdesc: - _process_data(fdesc) - except IOError: - if _fallback: - _process_data(_fallback.split(b"\n")) - else: - log_loading.info("Can't open %s file", filename) - return dct - - -def load_ethertypes(filename): - """"Parse /etc/ethertypes and return values as a dictionary. - If unavailable, use the copy bundled with Scapy.""" - from scapy.modules.ethertypes import DATA - return load_protocols(filename, _fallback=DATA, _integer_base=16) - - -def load_services(filename): - spaces = re.compile(b"[ \t]+|\n") - tdct = DADict(_name="%s-tcp" % filename) - udct = DADict(_name="%s-udp" % filename) - # TRex Change - return tdct, udct - try: - with open(filename, "rb") as fdesc: - for line in fdesc: - try: - shrp = line.find(b"#") - if shrp >= 0: - line = line[:shrp] - line = line.strip() - if not line: - continue - lt = tuple(re.split(spaces, line)) - if len(lt) < 2 or not lt[0]: - continue - if lt[1].endswith(b"/tcp"): - tdct[lt[0]] = int(lt[1].split(b'/')[0]) - elif lt[1].endswith(b"/udp"): - udct[lt[0]] = int(lt[1].split(b'/')[0]) - except Exception as e: - log_loading.warning( - "Couldn't parse file [%s]: line [%r] (%s)", - filename, - line, - e, - ) - except IOError: - log_loading.info("Can't open /etc/services file") - return tdct, udct - - -class ManufDA(DADict): - def fixname(self, val): - return plain_str(val) - - def __dir__(self): - return ["lookup", "reverse_lookup"] - - def _get_manuf_couple(self, mac): - oui = ":".join(mac.split(":")[:3]).upper() - return self.__dict__.get(oui, (mac, mac)) - - def _get_manuf(self, mac): - return self._get_manuf_couple(mac)[1] - - def _get_short_manuf(self, mac): - return self._get_manuf_couple(mac)[0] - - def _resolve_MAC(self, mac): - oui = ":".join(mac.split(":")[:3]).upper() - if oui in self: - return ":".join([self[oui][0]] + mac.split(":")[3:]) - return mac - - def lookup(self, mac): - """Find OUI name matching to a MAC""" - oui = ":".join(mac.split(":")[:3]).upper() - return self[oui] - - def reverse_lookup(self, name, case_sensitive=False): - """Find all MACs registered to a OUI - params: - - name: the OUI name - - case_sensitive: default to False - returns: a dict of mac:tuples (Name, Extended Name) - """ - if case_sensitive: - filtr = lambda x, l: any(x == z for z in l) - else: - name = name.lower() - filtr = lambda x, l: any(x == z.lower() for z in l) - return {k: v for k, v in six.iteritems(self.__dict__) - if filtr(name, v)} - - -def load_manuf(filename): - """Load manuf file from Wireshark. - param: - - filename: the file to load the manuf file from""" - manufdb = ManufDA(_name=filename) - with open(filename, "rb") as fdesc: - for line in fdesc: - try: - line = line.strip() - if not line or line.startswith(b"#"): - continue - parts = line.split(None, 2) - oui, shrt = parts[:2] - lng = parts[2].lstrip(b"#").strip() if len(parts) > 2 else "" - lng = lng or shrt - manufdb[oui] = plain_str(shrt), plain_str(lng) - except Exception: - log_loading.warning("Couldn't parse one line from [%s] [%r]", - filename, line, exc_info=True) - return manufdb - - -def select_path(directories, filename): - """Find filename among several directories""" - for directory in directories: - path = os.path.join(directory, filename) - if os.path.exists(path): - return path - - -if WINDOWS: - IP_PROTOS = load_protocols(os.environ["SystemRoot"] + "\\system32\\drivers\\etc\\protocol") # noqa: E501 - TCP_SERVICES, UDP_SERVICES = load_services(os.environ["SystemRoot"] + "\\system32\\drivers\\etc\\services") # noqa: E501 - # Default values, will be updated by arch.windows - ETHER_TYPES = load_ethertypes(None) - MANUFDB = ManufDA() -else: - IP_PROTOS = load_protocols("/etc/protocols") - ETHER_TYPES = load_ethertypes("/etc/ethertypes") - TCP_SERVICES, UDP_SERVICES = load_services("/etc/services") - MANUFDB = ManufDA() - manuf_path = select_path( - ['/usr', '/usr/local', '/opt', '/opt/wireshark', - '/Applications/Wireshark.app/Contents/Resources'], - "share/wireshark/manuf" - ) - if manuf_path: - try: - MANUFDB = load_manuf(manuf_path) - except (IOError, OSError): - log_loading.warning("Cannot read wireshark manuf database") - - -##################### -# knowledge bases # -##################### - -class KnowledgeBase: - def __init__(self, filename): - self.filename = filename - self.base = None - - def lazy_init(self): - self.base = "" - - def reload(self, filename=None): - if filename is not None: - self.filename = filename - oldbase = self.base - self.base = None - self.lazy_init() - if self.base is None: - self.base = oldbase - - def get_base(self): - if self.base is None: - self.lazy_init() - return self.base diff --git a/scripts/external_libs/scapy-2.4.3/scapy/error.py b/scripts/external_libs/scapy-2.4.3/scapy/error.py deleted file mode 100644 index 9c265aa75b..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/error.py +++ /dev/null @@ -1,97 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Logging subsystem and basic exception class. -""" - -############################# -# Logging subsystem # -############################# - - -import logging -import traceback -import time - - -class Scapy_Exception(Exception): - pass - - -class ScapyInvalidPlatformException(Scapy_Exception): - pass - - -class ScapyFreqFilter(logging.Filter): - def __init__(self): - logging.Filter.__init__(self) - self.warning_table = {} - - def filter(self, record): - from scapy.config import conf - wt = conf.warning_threshold - if wt > 0: - stk = traceback.extract_stack() - caller = None - for f, l, n, c in stk: - if n == 'warning': - break - caller = l - tm, nb = self.warning_table.get(caller, (0, 0)) - ltm = time.time() - if ltm - tm > wt: - tm = ltm - nb = 0 - else: - if nb < 2: - nb += 1 - if nb == 2: - record.msg = "more " + record.msg - else: - return 0 - self.warning_table[caller] = (tm, nb) - return 1 - - -# Inspired from python-colorbg (MIT) -class ScapyColoredFormatter(logging.Formatter): - """A subclass of logging.Formatter that handles colors.""" - levels_colored = { - 'DEBUG': 'reset', - 'INFO': 'reset', - 'WARNING': 'bold+yellow', - 'ERROR': 'bold+red', - 'CRITICAL': 'bold+white+bg_red' - } - - def format(self, record): - message = super(ScapyColoredFormatter, self).format(record) - from scapy.config import conf - message = conf.color_theme.format( - message, - self.levels_colored[record.levelname] - ) - return message - - -log_scapy = logging.getLogger("scapy") -log_scapy.setLevel(logging.WARNING) -log_scapy.addHandler(logging.NullHandler()) -# logs at runtime -log_runtime = logging.getLogger("scapy.runtime") -log_runtime.addFilter(ScapyFreqFilter()) -# logs in interactive functions -log_interactive = logging.getLogger("scapy.interactive") -log_interactive.setLevel(logging.DEBUG) -# logs when loading Scapy -log_loading = logging.getLogger("scapy.loading") - - -def warning(x, *args, **kargs): - """ - Prints a warning during runtime. - """ - log_runtime.warning(x, *args, **kargs) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/extlib.py b/scripts/external_libs/scapy-2.4.3/scapy/extlib.py deleted file mode 100644 index ee33fa4a51..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/extlib.py +++ /dev/null @@ -1,62 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -External link to programs -""" - -import os -import subprocess -from scapy.error import log_loading - -# Notice: this file must not be called before main.py, if started -# in interactive mode, because it needs to be called after the -# logger has been setup, to be able to print the warning messages - -# MATPLOTLIB - -try: - from matplotlib import get_backend as matplotlib_get_backend - from matplotlib import pyplot as plt - MATPLOTLIB = 1 - if "inline" in matplotlib_get_backend(): - MATPLOTLIB_INLINED = 1 - else: - MATPLOTLIB_INLINED = 0 - MATPLOTLIB_DEFAULT_PLOT_KARGS = {"marker": "+"} -# RuntimeError to catch gtk "Cannot open display" error -# TRex Change - Add AttributeError -except (ImportError, RuntimeError, AttributeError): - plt = None - MATPLOTLIB = 0 - MATPLOTLIB_INLINED = 0 - MATPLOTLIB_DEFAULT_PLOT_KARGS = dict() - log_loading.info("Can't import matplotlib. Won't be able to plot.") - -# PYX - - -def _test_pyx(): - """Returns if PyX is correctly installed or not""" - try: - with open(os.devnull, 'wb') as devnull: - r = subprocess.check_call(["pdflatex", "--version"], - stdout=devnull, stderr=subprocess.STDOUT) - except (subprocess.CalledProcessError, OSError): - return False - else: - return r == 0 - - -try: - import pyx # noqa: F401 - if _test_pyx(): - PYX = 1 - else: - log_loading.info("PyX dependencies are not installed ! Please install TexLive or MikTeX.") # noqa: E501 - PYX = 0 -except ImportError: - log_loading.info("Can't import PyX. Won't be able to use psdump() or pdfdump().") # noqa: E501 - PYX = 0 diff --git a/scripts/external_libs/scapy-2.4.3/scapy/fields.py b/scripts/external_libs/scapy-2.4.3/scapy/fields.py deleted file mode 100644 index 3a003438a1..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/fields.py +++ /dev/null @@ -1,2616 +0,0 @@ -# -*- mode: python3; indent-tabs-mode: nil; tab-width: 4 -*- -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Copyright (C) Michael Farrell -# This program is published under a GPLv2 license - -""" -Fields: basic data structures that make up parts of packets. -""" - -from __future__ import absolute_import -import calendar -import collections -import copy -import inspect -import socket -import struct -import time -from types import MethodType -from uuid import UUID - - -from scapy.config import conf -from scapy.dadict import DADict -from scapy.volatile import RandBin, RandByte, RandEnumKeys, RandInt, \ - RandIP, RandIP6, RandLong, RandMAC, RandNum, RandShort, RandSInt, \ - RandSByte, RandTermString, RandUUID, VolatileValue, RandSShort, \ - RandSLong, RandFloat -from scapy.data import EPOCH -from scapy.error import log_runtime, Scapy_Exception -from scapy.compat import bytes_hex, chb, orb, plain_str, raw, bytes_encode -from scapy.pton_ntop import inet_ntop, inet_pton -from scapy.utils import inet_aton, inet_ntoa, lhex, mac2str, str2mac, str2bytes -from scapy.utils6 import in6_6to4ExtractAddr, in6_isaddr6to4, \ - in6_isaddrTeredo, in6_ptop, Net6, teredoAddrExtractInfo -from scapy.base_classes import BasePacket, Gen, Net, Field_metaclass -from scapy.error import warning -import scapy.modules.six as six -from scapy.modules.six.moves import range - - -""" -Helper class to specify a protocol extendable for runtime modifications -""" - - -class ObservableDict(dict): - def __init__(self, *args, **kw): - self.observers = [] - super(ObservableDict, self).__init__(*args, **kw) - - def observe(self, observer): - self.observers.append(observer) - - def __setitem__(self, key, value): - for o in self.observers: - o.notify_set(self, key, value) - super(ObservableDict, self).__setitem__(key, value) - - def __delitem__(self, key): - for o in self.observers: - o.notify_del(self, key) - super(ObservableDict, self).__delitem__(key) - - def update(self, anotherDict): - for k in anotherDict: - self[k] = anotherDict[k] - - -############ -# Fields # -############ - -class Field(six.with_metaclass(Field_metaclass, object)): - """For more information on how this work, please refer to - http://www.secdev.org/projects/scapy/files/scapydoc.pdf - chapter ``Adding a New Field''""" - __slots__ = ["name", "fmt", "default", "sz", "owners", "_offset"] - islist = 0 - ismutable = False - holds_packets = 0 - - def __init__(self, name, default, fmt="H"): - self.name = name - if fmt[0] in "@=<>!": - self.fmt = fmt - else: - self.fmt = "!" + fmt - self.default = self.any2i(None, default) - self.sz = struct.calcsize(self.fmt) - self.owners = [] - self._offset = 0 # TRex Change - - - # TRex Change - def get_size_bytes(self): - if hasattr(self, 'size'): - return 0 # bitfield - else: - return self.sz - - # TRex Change - def get_size_bits(self): - return getattr(self, 'size', self.sz * 8) - - def register_owner(self, cls): - self.owners.append(cls) - - def i2len(self, pkt, x): - """Convert internal value to a length usable by a FieldLenField""" - return self.sz - - def i2count(self, pkt, x): - """Convert internal value to a number of elements usable by a FieldLenField. - Always 1 except for list fields""" - return 1 - - def h2i(self, pkt, x): - """Convert human value to internal value""" - return x - - def i2h(self, pkt, x): - """Convert internal value to human value""" - return x - - def m2i(self, pkt, x): - """Convert machine value to internal value""" - return x - - def i2m(self, pkt, x): - """Convert internal value to machine value""" - if x is None: - x = 0 - elif isinstance(x, str): - return bytes_encode(x) - return x - - def any2i(self, pkt, x): - """Try to understand the most input values possible and make an internal value from them""" # noqa: E501 - return self.h2i(pkt, x) - - def i2repr(self, pkt, x): - """Convert internal value to a nice representation""" - return repr(self.i2h(pkt, x)) - - def addfield(self, pkt, s, val): - """Add an internal value to a string - - Copy the network representation of field `val` (belonging to layer - `pkt`) to the raw string packet `s`, and return the new string packet. - """ - return s + struct.pack(self.fmt, self.i2m(pkt, val)) - - def getfield(self, pkt, s): - """Extract an internal value from a string - - Extract from the raw packet `s` the field value belonging to layer - `pkt`. - - Returns a two-element list, - first the raw packet string after having removed the extracted field, - second the extracted field itself in internal representation. - """ - return s[self.sz:], self.m2i(pkt, struct.unpack(self.fmt, s[:self.sz])[0]) # noqa: E501 - - def do_copy(self, x): - if hasattr(x, "copy"): - return x.copy() - if isinstance(x, list): - x = x[:] - for i in range(len(x)): - if isinstance(x[i], BasePacket): - x[i] = x[i].copy() - return x - - def __repr__(self): - return "" % (",".join(x.__name__ for x in self.owners), self.name) # noqa: E501 - - def copy(self): - return copy.deepcopy(self) - - def randval(self): - """Return a volatile object whose value is both random and suitable for this field""" # noqa: E501 - fmtt = self.fmt[-1] - if fmtt in "BbHhIiQq": - return {"B": RandByte, "b": RandSByte, - "H": RandShort, "h": RandSShort, - "I": RandInt, "i": RandSInt, - "Q": RandLong, "q": RandSLong}[fmtt]() - elif fmtt == "s": - if self.fmt[0] in "0123456789": - value = int(self.fmt[:-1]) - else: - value = int(self.fmt[1:-1]) - return RandBin(value) - else: - warning("no random class for [%s] (fmt=%s).", self.name, self.fmt) - - -class Emph(object): - """Empathize sub-layer for display""" - __slots__ = ["fld", "_offset"] - - def __init__(self, fld): - self.fld = fld - - def __getattr__(self, attr): - return getattr(self.fld, attr) - - def __hash__(self): - return hash(self.fld) - - def __eq__(self, other): - return self.fld == other - - -class ActionField(object): - __slots__ = ["_fld", "_action_method", "_privdata"] - - def __init__(self, fld, action_method, **kargs): - self._fld = fld - self._action_method = action_method - self._privdata = kargs - - def any2i(self, pkt, val): - getattr(pkt, self._action_method)(val, self._fld, **self._privdata) - return getattr(self._fld, "any2i")(pkt, val) - - def __getattr__(self, attr): - return getattr(self._fld, attr) - - -class ConditionalField(object): - __slots__ = ["fld", "cond", "_offset"] - - def __init__(self, fld, cond): - self.fld = fld - self.cond = cond - - def _evalcond(self, pkt): - return self.cond(pkt) - - def getfield(self, pkt, s): - if self._evalcond(pkt): - return self.fld.getfield(pkt, s) - else: - return s, None - - def addfield(self, pkt, s, val): - if self._evalcond(pkt): - return self.fld.addfield(pkt, s, val) - else: - return s - - def __getattr__(self, attr): - return getattr(self.fld, attr) - - -class MultipleTypeField(object): - """MultipleTypeField are used for fields that can be implemented by -various Field subclasses, depending on conditions on the packet. - -It is initialized with `flds` and `dflt`. - -`dflt` is the default field type, to be used when none of the -conditions matched the current packet. - -`flds` is a list of tuples (`fld`, `cond`), where `fld` if a field -type, and `cond` a "condition" to determine if `fld` is the field type -that should be used. - -`cond` is either: - - - a callable `cond_pkt` that accepts one argument (the packet) and - returns True if `fld` should be used, False otherwise. - - - a tuple (`cond_pkt`, `cond_pkt_val`), where `cond_pkt` is the same - as in the previous case and `cond_pkt_val` is a callable that - accepts two arguments (the packet, and the value to be set) and - returns True if `fld` should be used, False otherwise. - -See scapy.layers.l2.ARP (type "help(ARP)" in Scapy) for an example of -use. - - """ - - __slots__ = ["flds", "dflt", "name", "_offset"] - - def __init__(self, flds, dflt): - self.flds = flds - self.dflt = dflt - self.name = self.dflt.name - - def _iterate_fields_cond(self, pkt, val, use_val): - """Internal function used by _find_fld_pkt & _find_fld_pkt_val""" - # Iterate through the fields - for fld, cond in self.flds: - if isinstance(cond, tuple): - if use_val: - if cond[1](pkt, val): - return fld - continue - else: - cond = cond[0] - if cond(pkt): - return fld - return self.dflt - - def _find_fld_pkt(self, pkt): - """Given a Packet instance `pkt`, returns the Field subclass to be -used. If you know the value to be set (e.g., in .addfield()), use -._find_fld_pkt_val() instead. - - """ - return self._iterate_fields_cond(pkt, None, False) - - def _find_fld_pkt_val(self, pkt, val): - """Given a Packet instance `pkt` and the value `val` to be set, -returns the Field subclass to be used, and the updated `val` if necessary. - - """ - fld = self._iterate_fields_cond(pkt, val, True) - # Default ? (in this case, let's make sure it's up-do-date) - dflts_pkt = pkt.default_fields - if val == dflts_pkt[self.name] and self.name not in pkt.fields: - dflts_pkt[self.name] = fld.default - val = fld.default - return fld, val - - def _find_fld(self): - """Returns the Field subclass to be used, depending on the Packet -instance, or the default subclass. - -DEV: since the Packet instance is not provided, we have to use a hack -to guess it. It should only be used if you cannot provide the current -Packet instance (for example, because of the current Scapy API). - -If you have the current Packet instance, use ._find_fld_pkt_val() (if -the value to set is also known) of ._find_fld_pkt() instead. - - """ - # Hack to preserve current Scapy API - # See https://stackoverflow.com/a/7272464/3223422 - frame = inspect.currentframe().f_back.f_back - while frame is not None: - try: - pkt = frame.f_locals['self'] - except KeyError: - pass - else: - if isinstance(pkt, tuple(self.dflt.owners)): - if not pkt.default_fields: - # Packet not initialized - return self.dflt - return self._find_fld_pkt(pkt) - frame = frame.f_back - return self.dflt - - def getfield(self, pkt, s): - return self._find_fld_pkt(pkt).getfield(pkt, s) - - def addfield(self, pkt, s, val): - fld, val = self._find_fld_pkt_val(pkt, val) - return fld.addfield(pkt, s, val) - - def any2i(self, pkt, val): - fld, val = self._find_fld_pkt_val(pkt, val) - return fld.any2i(pkt, val) - - def h2i(self, pkt, val): - fld, val = self._find_fld_pkt_val(pkt, val) - return fld.h2i(pkt, val) - - def i2h(self, pkt, val): - fld, val = self._find_fld_pkt_val(pkt, val) - return fld.i2h(pkt, val) - - def i2m(self, pkt, val): - fld, val = self._find_fld_pkt_val(pkt, val) - return fld.i2m(pkt, val) - - def i2len(self, pkt, val): - fld, val = self._find_fld_pkt_val(pkt, val) - return fld.i2len(pkt, val) - - def i2repr(self, pkt, val): - fld, val = self._find_fld_pkt_val(pkt, val) - return fld.i2repr(pkt, val) - - def register_owner(self, cls): - for fld, _ in self.flds: - fld.owners.append(cls) - self.dflt.owners.append(cls) - - def __getattr__(self, attr): - return getattr(self._find_fld(), attr) - - -class PadField(object): - """Add bytes after the proxified field so that it ends at the specified - alignment from its beginning""" - __slots__ = ["_fld", "_align", "_padwith"] - - def __init__(self, fld, align, padwith=None): - self._fld = fld - self._align = align - self._padwith = padwith or b"" - - def padlen(self, flen): - return -flen % self._align - - def getfield(self, pkt, s): - remain, val = self._fld.getfield(pkt, s) - padlen = self.padlen(len(s) - len(remain)) - return remain[padlen:], val - - def addfield(self, pkt, s, val): - sval = self._fld.addfield(pkt, b"", val) - return s + sval + struct.pack("%is" % (self.padlen(len(sval))), self._padwith) # noqa: E501 - - def __getattr__(self, attr): - return getattr(self._fld, attr) - - -class ReversePadField(PadField): - """Add bytes BEFORE the proxified field so that it starts at the specified - alignment from its beginning""" - - def getfield(self, pkt, s): - # We need to get the length that has already been dissected - padlen = self.padlen(pkt._tmp_dissect_pos) - remain, val = self._fld.getfield(pkt, s[padlen:]) - return remain, val - - def addfield(self, pkt, s, val): - sval = self._fld.addfield(pkt, b"", val) - return s + struct.pack("%is" % (self.padlen(len(s))), self._padwith) + sval # noqa: E501 - - -class FCSField(Field): - """Special Field that gets its value from the end of the *packet* - (Note: not layer, but packet). - - Mostly used for FCS - """ - def getfield(self, pkt, s): - previous_post_dissect = pkt.post_dissect - val = self.m2i(pkt, struct.unpack(self.fmt, s[-self.sz:])[0]) - - def _post_dissect(self, s): - # Reset packet to allow post_build - self.raw_packet_cache = None - self.post_dissect = previous_post_dissect - return previous_post_dissect(s) - pkt.post_dissect = MethodType(_post_dissect, pkt) - return s[:-self.sz], val - - def addfield(self, pkt, s, val): - previous_post_build = pkt.post_build - value = struct.pack(self.fmt, self.i2m(pkt, val)) - - def _post_build(self, p, pay): - pay += value - self.post_build = previous_post_build - return previous_post_build(p, pay) - pkt.post_build = MethodType(_post_build, pkt) - return s - - def i2repr(self, pkt, x): - return lhex(self.i2h(pkt, x)) - - -class DestField(Field): - __slots__ = ["defaultdst"] - # Each subclass must have its own bindings attribute - # bindings = {} - - def __init__(self, name, default): - self.defaultdst = default - - def dst_from_pkt(self, pkt): - for addr, condition in self.bindings.get(pkt.payload.__class__, []): - try: - if all(pkt.payload.getfieldval(field) == value - for field, value in six.iteritems(condition)): - return addr - except AttributeError: - pass - return self.defaultdst - - @classmethod - def bind_addr(cls, layer, addr, **condition): - cls.bindings.setdefault(layer, []).append((addr, condition)) - - -class MACField(Field): - def __init__(self, name, default): - Field.__init__(self, name, default, "6s") - - def i2m(self, pkt, x): - if x is None: - return b"\0\0\0\0\0\0" - return mac2str(x) - - def m2i(self, pkt, x): - return str2mac(x) - - def any2i(self, pkt, x): - # TRex Change - if isinstance(x, str) and len(x) == 6: - x = str2bytes(x) - if isinstance(x, bytes) and len(x) == 6: - x = self.m2i(pkt, x) - return x - - def i2repr(self, pkt, x): - x = self.i2h(pkt, x) - if self in conf.resolve: - x = conf.manufdb._resolve_MAC(x) - return x - - def randval(self): - return RandMAC() - - -class IPField(Field): - slots = [] - - def __init__(self, name, default): - Field.__init__(self, name, default, "4s") - - def h2i(self, pkt, x): - if isinstance(x, bytes): - x = plain_str(x) - if isinstance(x, str): - try: - inet_aton(x) - except socket.error: - x = Net(x) - elif isinstance(x, list): - x = [self.h2i(pkt, n) for n in x] - return x - - def resolve(self, x): - if self in conf.resolve: - try: - ret = socket.gethostbyaddr(x)[0] - except Exception: - pass - else: - if ret: - return ret - return x - - def i2m(self, pkt, x): - if x is None: - return b'\x00\x00\x00\x00' - return inet_aton(plain_str(x)) - - def m2i(self, pkt, x): - return inet_ntoa(x) - - def any2i(self, pkt, x): - return self.h2i(pkt, x) - - def i2repr(self, pkt, x): - r = self.resolve(self.i2h(pkt, x)) - return r if isinstance(r, str) else repr(r) - - def randval(self): - return RandIP() - - -class SourceIPField(IPField): - __slots__ = ["dstname"] - - def __init__(self, name, dstname): - IPField.__init__(self, name, None) - self.dstname = dstname - - def __findaddr(self, pkt): - if conf.route is None: - # unused import, only to initialize conf.route - import scapy.route # noqa: F401 - dst = ("0.0.0.0" if self.dstname is None - else getattr(pkt, self.dstname) or "0.0.0.0") - if isinstance(dst, (Gen, list)): - r = {conf.route.route(str(daddr)) for daddr in dst} - if len(r) > 1: - warning("More than one possible route for %r" % (dst,)) - return min(r)[1] - return conf.route.route(dst)[1] - - def i2m(self, pkt, x): - if x is None: - # TRex Change - x = "16.0.0.1" - return IPField.i2m(self, pkt, x) - - def i2h(self, pkt, x): - if x is None: - x = self.__findaddr(pkt) - return IPField.i2h(self, pkt, x) - - -class IP6Field(Field): - def __init__(self, name, default): - Field.__init__(self, name, default, "16s") - - def h2i(self, pkt, x): - if isinstance(x, bytes): - x = plain_str(x) - if isinstance(x, str): - try: - x = in6_ptop(x) - except socket.error: - x = Net6(x) - elif isinstance(x, list): - x = [self.h2i(pkt, n) for n in x] - return x - - def i2m(self, pkt, x): - if x is None: - x = "::" - return inet_pton(socket.AF_INET6, plain_str(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 isinstance(x, list): - if in6_isaddrTeredo(x): # print Teredo info - server, _, maddr, mport = teredoAddrExtractInfo(x) - return "%s [Teredo srv: %s cli: %s:%s]" % (self.i2h(pkt, x), server, maddr, mport) # noqa: E501 - elif in6_isaddr6to4(x): # print encapsulated address - vaddr = in6_6to4ExtractAddr(x) - return "%s [6to4 GW: %s]" % (self.i2h(pkt, x), vaddr) - r = self.i2h(pkt, x) # No specific information to return - return r if isinstance(r, str) else repr(r) - - def randval(self): - return RandIP6() - - -class SourceIP6Field(IP6Field): - __slots__ = ["dstname"] - - def __init__(self, name, dstname): - IP6Field.__init__(self, name, None) - self.dstname = dstname - - def i2m(self, pkt, x): - if x is None: - dst = ("::" if self.dstname is None else - getattr(pkt, self.dstname) or "::") - iff, x, nh = conf.route6.route(dst) - return IP6Field.i2m(self, pkt, x) - - def i2h(self, pkt, x): - if x is None: - if conf.route6 is None: - # unused import, only to initialize conf.route6 - import scapy.route6 # noqa: F401 - dst = ("::" if self.dstname is None else getattr(pkt, self.dstname)) # noqa: E501 - if isinstance(dst, (Gen, list)): - r = {conf.route6.route(str(daddr)) for daddr in dst} - if len(r) > 1: - warning("More than one possible route for %r" % (dst,)) - x = min(r)[1] - else: - x = conf.route6.route(dst)[1] - return IP6Field.i2h(self, pkt, x) - - -class DestIP6Field(IP6Field, DestField): - bindings = {} - - def __init__(self, name, default): - IP6Field.__init__(self, name, None) - DestField.__init__(self, name, default) - - def i2m(self, pkt, x): - if x is None: - x = self.dst_from_pkt(pkt) - return IP6Field.i2m(self, pkt, x) - - def i2h(self, pkt, x): - if x is None: - x = self.dst_from_pkt(pkt) - return IP6Field.i2h(self, pkt, x) - - -class ByteField(Field): - def __init__(self, name, default): - Field.__init__(self, name, default, "B") - - -class XByteField(ByteField): - def i2repr(self, pkt, x): - return lhex(self.i2h(pkt, x)) - - -class OByteField(ByteField): - def i2repr(self, pkt, x): - return "%03o" % self.i2h(pkt, x) - - -class ThreeBytesField(ByteField): - def __init__(self, name, default): - Field.__init__(self, name, default, "!I") - - def addfield(self, pkt, s, val): - return s + struct.pack(self.fmt, self.i2m(pkt, val))[1:4] - - def getfield(self, pkt, s): - return s[3:], self.m2i(pkt, struct.unpack(self.fmt, b"\x00" + s[:3])[0]) # noqa: E501 - - # TRex Change - def i2repr(self, pkt, x): - return ByteField.i2repr(self, pkt, x) - - -class X3BytesField(ThreeBytesField, XByteField): - def i2repr(self, pkt, x): - return XByteField.i2repr(self, pkt, x) - - -class LEThreeBytesField(ByteField): - def __init__(self, name, default): - Field.__init__(self, name, default, ", ) including the last value. a single-value tuple # noqa: E501 - is treated as scalar. - - a list defines a set of (probably non consecutive) values that should be associated to a given key. # noqa: E501 - - all values not associated with a key will be shown as number of type unsigned byte. # noqa: E501 - - config = { - 'no' : 0, - 'foo' : (1,22), - 'yes' : 23, - 'bar' : [24,25, 42, 48, 87, 253] - } - - generates the following representations: - - x == 0 : 'no' - x == 15: 'foo' - x == 23: 'yes' - x == 42: 'bar' - x == 43: 43 - - using the config attribute one could also revert the stock-yes-no-behavior: - - config = { - 'yes' : 0, - 'no' : (1,255) - } - - will generate the following value representation: - - x == 0 : 'yes' - x != 0 : 'no' - - """ - __slots__ = ['eval_fn'] - - def _build_config_representation(self, config): - assoc_table = dict() - for key in config: - value_spec = config[key] - - value_spec_type = type(value_spec) - - if value_spec_type is int: - if value_spec < 0 or value_spec > 255: - raise FieldValueRangeException('given field value {} invalid - ' # noqa: E501 - 'must be in range [0..255]'.format(value_spec)) # noqa: E501 - assoc_table[value_spec] = key - - elif value_spec_type is list: - for value in value_spec: - if value < 0 or value > 255: - raise FieldValueRangeException('given field value {} invalid - ' # noqa: E501 - 'must be in range [0..255]'.format(value)) # noqa: E501 - assoc_table[value] = key - - elif value_spec_type is tuple: - value_spec_len = len(value_spec) - if value_spec_len != 2: - raise FieldAttributeException('invalid length {} of given config item tuple {} - must be ' # noqa: E501 - '(, ).'.format(value_spec_len, value_spec)) # noqa: E501 - - value_range_start = value_spec[0] - if value_range_start < 0 or value_range_start > 255: - raise FieldValueRangeException('given field value {} invalid - ' # noqa: E501 - 'must be in range [0..255]'.format(value_range_start)) # noqa: E501 - - value_range_end = value_spec[1] - if value_range_end < 0 or value_range_end > 255: - raise FieldValueRangeException('given field value {} invalid - ' # noqa: E501 - 'must be in range [0..255]'.format(value_range_end)) # noqa: E501 - - for value in range(value_range_start, value_range_end + 1): - - assoc_table[value] = key - - self.eval_fn = lambda x: assoc_table[x] if x in assoc_table else x - - def __init__(self, name, default, config=None, *args, **kargs): - - if not config: - # this represents the common use case and therefore it is kept small # noqa: E501 - self.eval_fn = lambda x: 'no' if x == 0 else 'yes' - else: - self._build_config_representation(config) - ByteField.__init__(self, name, default, *args, **kargs) - - def i2repr(self, pkt, x): - return self.eval_fn(x) - - -class ShortField(Field): - def __init__(self, name, default): - Field.__init__(self, name, default, "H") - -# TRex Change -class SignedShortField(Field): - def __init__(self, name, default): - Field.__init__(self, name, default, "h") - - -class LEShortField(Field): - def __init__(self, name, default): - Field.__init__(self, name, default, " int - * length_from: a callback that returns the number of bytes that must be dissected by this field. The # noqa: E501 - callback prototype is: - length_from(pkt:Packet) -> int - * next_cls_cb: a callback that enables a Scapy developer to dynamically discover if another Packet instance # noqa: E501 - should be dissected or not. See below for this callback prototype. - - The bytes that are not consumed during the dissection of this field are passed to the next field of the current # noqa: E501 - packet. - - For the serialization of such a field, the list of Packets that are contained in a PacketListField can be # noqa: E501 - heterogeneous and is unrestricted. - - The type of the Packet instances that are dissected with this field is specified or discovered using one of the # noqa: E501 - following mechanism: - * the cls parameter may contain a callable that returns an instance of the dissected Packet. This # noqa: E501 - may either be a reference of a Packet subclass (e.g. DNSRROPT in layers/dns.py) to generate an # noqa: E501 - homogeneous PacketListField or a function deciding the type of the Packet instance # noqa: E501 - (e.g. _CDPGuessAddrRecord in contrib/cdp.py) - * the cls parameter may contain a class object with a defined "dispatch_hook" classmethod. That # noqa: E501 - method must return a Packet instance. The dispatch_hook callmethod must implement the following prototype: # noqa: E501 - dispatch_hook(cls, _pkt:Optional[Packet], *args, **kargs) -> Packet_metaclass # noqa: E501 - The _pkt parameter may contain a reference to the packet instance containing the PacketListField that is # noqa: E501 - being dissected. - * the next_cls_cb parameter may contain a callable whose prototype is: # noqa: E501 - cbk(pkt:Packet, lst:List[Packet], cur:Optional[Packet], remain:str) -> Optional[Packet_metaclass] # noqa: E501 - The pkt argument contains a reference to the Packet instance containing the PacketListField that is # noqa: E501 - being dissected. The lst argument is the list of all Packet instances that were previously parsed during # noqa: E501 - the current PacketListField dissection, save for the very last Packet instance. The cur argument # noqa: E501 - contains a reference to that very last parsed Packet instance. The remain argument contains the bytes # noqa: E501 - that may still be consumed by the current PacketListField dissection operation. This callback returns # noqa: E501 - either the type of the next Packet to dissect or None to indicate that no more Packet are to be # noqa: E501 - dissected. - These four arguments allows a variety of dynamic discovery of the number of Packet to dissect and of the # noqa: E501 - type of each one of these Packets, including: type determination based on current Packet instances or # noqa: E501 - its underlayers, continuation based on the previously parsed Packet instances within that # noqa: E501 - PacketListField, continuation based on a look-ahead on the bytes to be dissected... # noqa: E501 - - The cls and next_cls_cb parameters are semantically exclusive, although one could specify both. If both are # noqa: E501 - specified, cls is silently ignored. The same is true for count_from and next_cls_cb. # noqa: E501 - length_from and next_cls_cb are compatible and the dissection will end, whichever of the two stop conditions # noqa: E501 - comes first. - - @param name: the name of the field - @param default: the default value of this field; generally an empty Python list # noqa: E501 - @param cls: either a callable returning a Packet instance or a class object defining a dispatch_hook class # noqa: E501 - method - @param count_from: a callback returning the number of Packet instances to dissect # noqa: E501 - @param length_from: a callback returning the number of bytes to dissect - @param next_cls_cb: a callback returning either None or the type of the next Packet to dissect. # noqa: E501 - """ - if default is None: - default = [] # Create a new list for each instance - PacketField.__init__(self, name, default, cls) - self.count_from = count_from - self.length_from = length_from - self.next_cls_cb = next_cls_cb - - def any2i(self, pkt, x): - if not isinstance(x, list): - return [x] - else: - return x - - def i2count(self, pkt, val): - if isinstance(val, list): - return len(val) - return 1 - - def i2len(self, pkt, val): - return sum(len(p) for p in val) - - def do_copy(self, x): - if x is None: - return None - else: - return [p if isinstance(p, (str, bytes)) else p.copy() for p in x] - - def getfield(self, pkt, s): - c = len_pkt = cls = None - if self.length_from is not None: - len_pkt = self.length_from(pkt) - elif self.count_from is not None: - c = self.count_from(pkt) - if self.next_cls_cb is not None: - cls = self.next_cls_cb(pkt, [], None, s) - c = 1 - - lst = [] - ret = b"" - remain = s - if len_pkt is not None: - remain, ret = s[:len_pkt], s[len_pkt:] - while remain: - if c is not None: - if c <= 0: - break - c -= 1 - try: - if cls is not None: - p = cls(remain) - else: - p = self.m2i(pkt, remain) - except Exception: - if conf.debug_dissector: - raise - p = conf.raw_layer(load=remain) - remain = b"" - else: - if conf.padding_layer in p: - pad = p[conf.padding_layer] - remain = pad.load - del(pad.underlayer.payload) - if self.next_cls_cb is not None: - cls = self.next_cls_cb(pkt, lst, p, remain) - if cls is not None: - c = 0 if c is None else c - c += 1 - else: - remain = b"" - lst.append(p) - return remain + ret, lst - - def addfield(self, pkt, s, val): - return s + b"".join(bytes_encode(v) for v in val) - - -class StrFixedLenField(StrField): - __slots__ = ["length_from"] - - def __init__(self, name, default, length=None, length_from=None): - StrField.__init__(self, name, default) - self.length_from = length_from - if length is not None: - self.length_from = lambda pkt, length=length: length - - def i2repr(self, pkt, v): - if isinstance(v, bytes): - v = v.rstrip(b"\0") - return super(StrFixedLenField, self).i2repr(pkt, v) - - def getfield(self, pkt, s): - len_pkt = self.length_from(pkt) - return s[len_pkt:], self.m2i(pkt, s[:len_pkt]) - - def addfield(self, pkt, s, val): - len_pkt = self.length_from(pkt) - if len_pkt is None: - return s + self.i2m(pkt, val) - return s + struct.pack("%is" % len_pkt, self.i2m(pkt, val)) - - def randval(self): - try: - len_pkt = self.length_from(None) - except Exception: - len_pkt = RandNum(0, 200) - return RandBin(len_pkt) - - -class StrFixedLenEnumField(StrFixedLenField): - __slots__ = ["enum"] - - def __init__(self, name, default, length=None, enum=None, length_from=None): # noqa: E501 - StrFixedLenField.__init__(self, name, default, length=length, length_from=length_from) # noqa: E501 - self.enum = enum - - def i2repr(self, pkt, v): - r = v.rstrip("\0" if isinstance(v, str) else b"\0") - rr = repr(r) - if v in self.enum: - rr = "%s (%s)" % (rr, self.enum[v]) - elif r in self.enum: - rr = "%s (%s)" % (rr, self.enum[r]) - return rr - - -class NetBIOSNameField(StrFixedLenField): - def __init__(self, name, default, length=31): - StrFixedLenField.__init__(self, name, default, length) - - def i2m(self, pkt, x): - len_pkt = self.length_from(pkt) // 2 - x = bytes_encode(x) - if x is None: - x = b"" - x += b" " * len_pkt - x = x[:len_pkt] - x = b"".join(chb(0x41 + (orb(b) >> 4)) + chb(0x41 + (orb(b) & 0xf)) for b in x) # noqa: E501 - x = b" " + x - return x - - def m2i(self, pkt, x): - x = x.strip(b"\x00").strip(b" ") - return b"".join(map(lambda x, y: chb((((orb(x) - 1) & 0xf) << 4) + ((orb(y) - 1) & 0xf)), x[::2], x[1::2])) # noqa: E501 - - -class StrLenField(StrField): - __slots__ = ["length_from", "max_length"] - - def __init__(self, name, default, fld=None, length_from=None, max_length=None): # noqa: E501 - StrField.__init__(self, name, default) - self.length_from = length_from - self.max_length = max_length - - def getfield(self, pkt, s): - len_pkt = self.length_from(pkt) - return s[len_pkt:], self.m2i(pkt, s[:len_pkt]) - - def randval(self): - return RandBin(RandNum(0, self.max_length or 1200)) - - -# TRex Change - Added the class -class UTF8LenField(StrLenField): - """ - StrField which value is decoded as UTF-8. - """ - def i2h(self, pkt, x): - try: - return x.decode('utf-8') - except: - return x - - -# TRex Change - Added the class -class VarLenIntField(StrLenField): - """ - StrField which value is attempted to be converted to an int. - """ - def i2h(self, pkt, x): - if type(x) is str: - return str2int(x) - return x - - i2repr = i2h - - -class XStrField(StrField): - """ - StrField which value is printed as hexadecimal. - """ - - def i2repr(self, pkt, x): - if x is None: - return repr(x) - return bytes_hex(x).decode() - - -class _XStrLenField: - def i2repr(self, pkt, x): - if not x: - return repr(x) - return bytes_hex(x[:self.length_from(pkt)]).decode() - - -class XStrLenField(_XStrLenField, StrLenField): - """ - StrLenField which value is printed as hexadecimal. - """ - - -class XStrFixedLenField(_XStrLenField, StrFixedLenField): - """ - StrFixedLenField which value is printed as hexadecimal. - """ - - -class XLEStrLenField(XStrLenField): - def i2m(self, pkt, x): - return x[:: -1] - - def m2i(self, pkt, x): - return x[:: -1] - - -class StrLenFieldUtf16(StrLenField): - def h2i(self, pkt, x): - return plain_str(x).encode('utf-16')[2:] - - def i2h(self, pkt, x): - return x.decode('utf-16') - - -class BoundStrLenField(StrLenField): - __slots__ = ["minlen", "maxlen"] - - def __init__(self, name, default, minlen=0, maxlen=255, fld=None, length_from=None): # noqa: E501 - StrLenField.__init__(self, name, default, fld, length_from) - self.minlen = minlen - self.maxlen = maxlen - - def randval(self): - return RandBin(RandNum(self.minlen, self.maxlen)) - - -class FieldListField(Field): - __slots__ = ["field", "count_from", "length_from"] - islist = 1 - - def __init__(self, name, default, field, length_from=None, count_from=None): # noqa: E501 - if default is None: - default = [] # Create a new list for each instance - self.field = field - Field.__init__(self, name, default) - self.count_from = count_from - self.length_from = length_from - - def i2count(self, pkt, val): - if isinstance(val, list): - return len(val) - return 1 - - def i2len(self, pkt, val): - return int(sum(self.field.i2len(pkt, v) for v in val)) - - def i2m(self, pkt, val): - if val is None: - val = [] - return val - - def any2i(self, pkt, x): - if not isinstance(x, list): - return [self.field.any2i(pkt, x)] - else: - return [self.field.any2i(pkt, e) for e in x] - - def i2repr(self, pkt, x): - return "[%s]" % ", ".join(self.field.i2repr(pkt, v) for v in x) - - def addfield(self, pkt, s, val): - val = self.i2m(pkt, val) - for v in val: - s = self.field.addfield(pkt, s, v) - return s - - def getfield(self, pkt, s): - c = len_pkt = None - if self.length_from is not None: - len_pkt = self.length_from(pkt) - elif self.count_from is not None: - c = self.count_from(pkt) - - val = [] - ret = b"" - if len_pkt is not None: - s, ret = s[:len_pkt], s[len_pkt:] - - while s: - if c is not None: - if c <= 0: - break - c -= 1 - s, v = self.field.getfield(pkt, s) - val.append(v) - return s + ret, val - - -class FieldLenField(Field): - __slots__ = ["length_of", "count_of", "adjust"] - - def __init__(self, name, default, length_of=None, fmt="H", count_of=None, adjust=lambda pkt, x: x, fld=None): # noqa: E501 - Field.__init__(self, name, default, fmt) - self.length_of = length_of - self.count_of = count_of - self.adjust = adjust - if fld is not None: - # FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__) - self.length_of = fld - - def i2m(self, pkt, x): - if x is None: - if self.length_of is not None: - fld, fval = pkt.getfield_and_val(self.length_of) - f = fld.i2len(pkt, fval) - else: - fld, fval = pkt.getfield_and_val(self.count_of) - f = fld.i2count(pkt, fval) - x = self.adjust(pkt, f) - return x - - -class StrNullField(StrField): - def addfield(self, pkt, s, val): - return s + self.i2m(pkt, val) + b"\x00" - - def getfield(self, pkt, s): - len_str = s.find(b"\x00") - if len_str < 0: - # XXX \x00 not found - return b"", s - return s[len_str + 1:], self.m2i(pkt, s[:len_str]) - - def randval(self): - return RandTermString(RandNum(0, 1200), b"\x00") - - -class StrStopField(StrField): - __slots__ = ["stop", "additional"] - - def __init__(self, name, default, stop, additional=0): - Field.__init__(self, name, default) - self.stop = stop - self.additional = additional - - def getfield(self, pkt, s): - len_str = s.find(self.stop) - if len_str < 0: - return b"", s -# raise Scapy_Exception,"StrStopField: stop value [%s] not found" %stop # noqa: E501 - len_str += len(self.stop) + self.additional - return s[len_str:], s[:len_str] - - def randval(self): - return RandTermString(RandNum(0, 1200), self.stop) - - -class LenField(Field): - __slots__ = ["adjust"] - - def __init__(self, name, default, fmt="H", adjust=lambda x: x): - Field.__init__(self, name, default, fmt) - self.adjust = adjust - - def i2m(self, pkt, x): - if x is None: - x = self.adjust(len(pkt.payload)) - return x - - -class BCDFloatField(Field): - def i2m(self, pkt, x): - return int(256 * x) - - def m2i(self, pkt, x): - return x / 256.0 - - -class BitField(Field): - __slots__ = ["rev", "size"] - - def __init__(self, name, default, size): - Field.__init__(self, name, default) - self.rev = size < 0 - self.size = abs(size) - - def reverse(self, val): - if self.size == 16: - # Replaces socket.ntohs (but work on both little/big endian) - val = struct.unpack('>H', struct.pack('I', struct.pack('= 8: - bitsdone -= 8 - s = s + struct.pack("!B", v >> bitsdone) - v &= (1 << bitsdone) - 1 - if bitsdone: - return s, bitsdone, v - else: - return s - - def getfield(self, pkt, s): - if isinstance(s, tuple): - s, bn = s - else: - bn = 0 - # we don't want to process all the string - nb_bytes = (self.size + bn - 1) // 8 + 1 - w = s[:nb_bytes] - - # split the substring byte by byte - _bytes = struct.unpack('!%dB' % nb_bytes, w) - - b = 0 - for c in range(nb_bytes): - b |= int(_bytes[c]) << (nb_bytes - c - 1) * 8 - - # get rid of high order bits - b &= (1 << (nb_bytes * 8 - bn)) - 1 - - # remove low order bits - b = b >> (nb_bytes * 8 - self.size - bn) - - if self.rev: - b = self.reverse(b) - - bn += self.size - s = s[bn // 8:] - bn = bn % 8 - b = self.m2i(pkt, b) - if bn: - return (s, bn), b - else: - return s, b - - def randval(self): - return RandNum(0, 2**self.size - 1) - - def i2len(self, pkt, x): - return float(self.size) / 8 - - -class BitFieldLenField(BitField): - __slots__ = ["length_of", "count_of", "adjust"] - - def __init__(self, name, default, size, length_of=None, count_of=None, adjust=lambda pkt, x: x): # noqa: E501 - BitField.__init__(self, name, default, size) - self.length_of = length_of - self.count_of = count_of - self.adjust = adjust - - def i2m(self, pkt, x): - return (FieldLenField.i2m.__func__ if six.PY2 else FieldLenField.i2m)(self, pkt, x) # noqa: E501 - - -class XBitField(BitField): - def i2repr(self, pkt, x): - return lhex(self.i2h(pkt, x)) - - -class _EnumField(Field): - def __init__(self, name, default, enum, fmt="H"): - """ Initializes enum fields. - - @param name: name of this field - @param default: default value of this field - @param enum: either a dict or a tuple of two callables. Dict keys are # noqa: E501 - the internal values, while the dict values are the - user-friendly representations. If the tuple is provided, # noqa: E501 - the first callable receives the internal value as - parameter and returns the user-friendly representation - and the second callable does the converse. The first - callable may return None to default to a literal string - (repr()) representation. - @param fmt: struct.pack format used to parse and serialize the - internal value from and to machine representation. - """ - if isinstance(enum, ObservableDict): - enum.observe(self) - - if isinstance(enum, tuple): - self.i2s_cb = enum[0] - self.s2i_cb = enum[1] - self.i2s = None - self.s2i = None - else: - i2s = self.i2s = {} - s2i = self.s2i = {} - self.i2s_cb = None - self.s2i_cb = None - if isinstance(enum, list): - keys = list(range(len(enum))) - elif isinstance(enum, DADict): - keys = enum.keys() - else: - keys = list(enum) - if any(isinstance(x, str) for x in keys): - i2s, s2i = s2i, i2s - for k in keys: - i2s[k] = enum[k] - s2i[enum[k]] = k - Field.__init__(self, name, default, fmt) - - def any2i_one(self, pkt, x): - if isinstance(x, str): - try: - x = self.s2i[x] - except TypeError: - x = self.s2i_cb(x) - return x - - def i2repr_one(self, pkt, x): - if self not in conf.noenum and not isinstance(x, VolatileValue): - try: - return self.i2s[x] - except KeyError: - pass - except TypeError: - ret = self.i2s_cb(x) - if ret is not None: - return ret - return repr(x) - - def any2i(self, pkt, x): - if isinstance(x, list): - return [self.any2i_one(pkt, z) for z in x] - else: - return self.any2i_one(pkt, x) - - def i2repr(self, pkt, x): - if isinstance(x, list): - return [self.i2repr_one(pkt, z) for z in x] - else: - return self.i2repr_one(pkt, x) - - def notify_set(self, enum, key, value): - log_runtime.debug("At %s: Change to %s at 0x%x" % (self, value, key)) - self.i2s[key] = value - self.s2i[value] = key - - def notify_del(self, enum, key): - log_runtime.debug("At %s: Delete value at 0x%x" % (self, key)) - value = self.i2s[key] - del self.i2s[key] - del self.s2i[value] - - -class EnumField(_EnumField): - __slots__ = ["i2s", "s2i", "s2i_cb", "i2s_cb"] - - -class CharEnumField(EnumField): - def __init__(self, name, default, enum, fmt="1s"): - EnumField.__init__(self, name, default, enum, fmt) - if self.i2s is not None: - k = list(self.i2s) - if k and len(k[0]) != 1: - self.i2s, self.s2i = self.s2i, self.i2s - - def any2i_one(self, pkt, x): - if len(x) != 1: - if self.s2i is None: - x = self.s2i_cb(x) - else: - x = self.s2i[x] - return x - - -class BitEnumField(BitField, _EnumField): - __slots__ = EnumField.__slots__ - - def __init__(self, name, default, size, enum): - _EnumField.__init__(self, name, default, enum) - self.rev = size < 0 - self.size = abs(size) - - def any2i(self, pkt, x): - return _EnumField.any2i(self, pkt, x) - - def i2repr(self, pkt, x): - return _EnumField.i2repr(self, pkt, x) - - -class ShortEnumField(EnumField): - __slots__ = EnumField.__slots__ - - def __init__(self, name, default, enum): - EnumField.__init__(self, name, default, enum, "H") - - -class LEShortEnumField(EnumField): - def __init__(self, name, default, enum): - EnumField.__init__(self, name, default, enum, ">= self.cursor - while x: - self.cursor += 1 - if x & 1: - return self.flagvalue.names[self.cursor - 1] - x >>= 1 - raise StopIteration - - next = __next__ - - -class FlagValue(object): - __slots__ = ["value", "names", "multi"] - - def _fixvalue(self, value): - if not value: - return 0 - if isinstance(value, six.string_types): - value = value.split('+') if self.multi else list(value) - if isinstance(value, list): - y = 0 - for i in value: - y |= 1 << self.names.index(i) - value = y - return int(value) - - def __init__(self, value, names): - self.multi = isinstance(names, list) - self.names = names - self.value = self._fixvalue(value) - - def __hash__(self): - return hash(self.value) - - def __int__(self): - return self.value - - def __eq__(self, other): - return self.value == self._fixvalue(other) - - def __lt__(self, other): - return self.value < self._fixvalue(other) - - def __le__(self, other): - return self.value <= self._fixvalue(other) - - def __gt__(self, other): - return self.value > self._fixvalue(other) - - def __ge__(self, other): - return self.value >= self._fixvalue(other) - - def __ne__(self, other): - return self.value != self._fixvalue(other) - - def __and__(self, other): - return self.__class__(self.value & self._fixvalue(other), self.names) - __rand__ = __and__ - - def __or__(self, other): - return self.__class__(self.value | self._fixvalue(other), self.names) - __ror__ = __or__ - - def __lshift__(self, other): - return self.value << self._fixvalue(other) - - def __rshift__(self, other): - return self.value >> self._fixvalue(other) - - def __nonzero__(self): - return bool(self.value) - __bool__ = __nonzero__ - - def flagrepr(self): - warning("obj.flagrepr() is obsolete. Use str(obj) instead.") - return str(self) - - def __str__(self): - i = 0 - r = [] - x = int(self) - while x: - if x & 1: - r.append(self.names[i]) - i += 1 - x >>= 1 - return ("+" if self.multi else "").join(r) - - def __iter__(self): - return FlagValueIter(self) - - def __repr__(self): - return "" % (self, self) - - def __deepcopy__(self, memo): - return self.__class__(int(self), self.names) - - def __getattr__(self, attr): - if attr in self.__slots__: - return super(FlagValue, self).__getattr__(attr) - try: - if self.multi: - return bool((2 ** self.names.index(attr)) & int(self)) - return all(bool((2 ** self.names.index(flag)) & int(self)) - for flag in attr) - except ValueError: - if '_' in attr: - try: - return self.__getattr__(attr.replace('_', '-')) - except AttributeError: - pass - return super(FlagValue, self).__getattr__(attr) - - def __setattr__(self, attr, value): - if attr == "value" and not isinstance(value, six.integer_types): - raise ValueError(value) - if attr in self.__slots__: - return super(FlagValue, self).__setattr__(attr, value) - if attr in self.names: - if value: - self.value |= (2 ** self.names.index(attr)) - else: - self.value &= ~(2 ** self.names.index(attr)) - else: - return super(FlagValue, self).__setattr__(attr, value) - - def copy(self): - return self.__class__(self.value, self.names) - - -class FlagsField(BitField): - """ Handle Flag type field - - Make sure all your flags have a label - - Example: - >>> from scapy.packet import Packet - >>> class FlagsTest(Packet): - fields_desc = [FlagsField("flags", 0, 8, ["f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7"])] # noqa: E501 - >>> FlagsTest(flags=9).show2() - ###[ FlagsTest ]### - flags = f0+f3 - >>> FlagsTest(flags=0).show2().strip() - ###[ FlagsTest ]### - flags = - - :param name: field's name - :param default: default value for the field - :param size: number of bits in the field - :param names: (list or dict) label for each flag, Least Significant Bit tag's name is written first # noqa: E501 - """ - ismutable = True - __slots__ = ["multi", "names"] - - def __init__(self, name, default, size, names): - self.multi = isinstance(names, list) - self.names = names - BitField.__init__(self, name, default, size) - - def _fixup_val(self, x): - """Returns a FlagValue instance when needed. Internal method, to be -used in *2i() and i2*() methods. - - """ - if isinstance(x, FlagValue): - return x - if x is None: - return None - return FlagValue(x, self.names) - - def any2i(self, pkt, x): - return self._fixup_val(super(FlagsField, self).any2i(pkt, x)) - - def m2i(self, pkt, x): - return self._fixup_val(super(FlagsField, self).m2i(pkt, x)) - - def i2h(self, pkt, x): - if isinstance(x, VolatileValue): - return super(FlagsField, self).i2h(pkt, x) - return self._fixup_val(super(FlagsField, self).i2h(pkt, x)) - - def i2repr(self, pkt, x): - if isinstance(x, (list, tuple)): - return repr(type(x)( - None if v is None else str(self._fixup_val(v)) for v in x - )) - return None if x is None else str(self._fixup_val(x)) - - -MultiFlagsEntry = collections.namedtuple('MultiFlagEntry', ['short', 'long']) - - -class MultiFlagsField(BitField): - __slots__ = FlagsField.__slots__ + ["depends_on"] - - def __init__(self, name, default, size, names, depends_on): - self.names = names - self.depends_on = depends_on - super(MultiFlagsField, self).__init__(name, default, size) - - def any2i(self, pkt, x): - assert isinstance(x, six.integer_types + (set,)), 'set expected' - - if pkt is not None: - if isinstance(x, six.integer_types): - x = self.m2i(pkt, x) - else: - v = self.depends_on(pkt) - if v is not None: - assert v in self.names, 'invalid dependency' - these_names = self.names[v] - s = set() - for i in x: - for val in six.itervalues(these_names): - if val.short == i: - s.add(i) - break - else: - assert False, 'Unknown flag "{}" with this dependency'.format(i) # noqa: E501 - continue - x = s - return x - - def i2m(self, pkt, x): - v = self.depends_on(pkt) - these_names = self.names.get(v, {}) - - r = 0 - for flag_set in x: - for i, val in six.iteritems(these_names): - if val.short == flag_set: - r |= 1 << i - break - else: - r |= 1 << int(flag_set[len('bit '):]) - return r - - def m2i(self, pkt, x): - v = self.depends_on(pkt) - these_names = self.names.get(v, {}) - - r = set() - i = 0 - while x: - if x & 1: - if i in these_names: - r.add(these_names[i].short) - else: - r.add('bit {}'.format(i)) - x >>= 1 - i += 1 - return r - - def i2repr(self, pkt, x): - v = self.depends_on(pkt) - these_names = self.names.get(v, {}) - - r = set() - for flag_set in x: - for i in six.itervalues(these_names): - if i.short == flag_set: - r.add("{} ({})".format(i.long, i.short)) - break - else: - r.add(flag_set) - return repr(r) - - -class FixedPointField(BitField): - __slots__ = ['frac_bits'] - - def __init__(self, name, default, size, frac_bits=16): - self.frac_bits = frac_bits - BitField.__init__(self, name, default, size) - - def any2i(self, pkt, val): - if val is None: - return val - ival = int(val) - fract = int((val - ival) * 2**self.frac_bits) - return (ival << self.frac_bits) | fract - - def i2h(self, pkt, val): - int_part = val >> self.frac_bits - frac_part = val & (1 << self.frac_bits) - 1 - frac_part /= 2.0**self.frac_bits - return int_part + frac_part - - def i2repr(self, pkt, val): - return self.i2h(pkt, val) - - -# Base class for IPv4 and IPv6 Prefixes inspired by IPField and IP6Field. -# Machine values are encoded in a multiple of wordbytes bytes. -class _IPPrefixFieldBase(Field): - __slots__ = ["wordbytes", "maxbytes", "aton", "ntoa", "length_from"] - - def __init__(self, name, default, wordbytes, maxbytes, aton, ntoa, length_from): # noqa: E501 - self.wordbytes = wordbytes - self.maxbytes = maxbytes - self.aton = aton - self.ntoa = ntoa - Field.__init__(self, name, default, "%is" % self.maxbytes) - self.length_from = length_from - - def _numbytes(self, pfxlen): - wbits = self.wordbytes * 8 - return ((pfxlen + (wbits - 1)) // wbits) * self.wordbytes - - def h2i(self, pkt, x): - # "fc00:1::1/64" -> ("fc00:1::1", 64) - [pfx, pfxlen] = x.split('/') - self.aton(pfx) # check for validity - return (pfx, int(pfxlen)) - - def i2h(self, pkt, x): - # ("fc00:1::1", 64) -> "fc00:1::1/64" - (pfx, pfxlen) = x - return "%s/%i" % (pfx, pfxlen) - - def i2m(self, pkt, x): - # ("fc00:1::1", 64) -> (b"\xfc\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 64) # noqa: E501 - (pfx, pfxlen) = x - s = self.aton(pfx) - return (s[:self._numbytes(pfxlen)], pfxlen) - - def m2i(self, pkt, x): - # (b"\xfc\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 64) -> ("fc00:1::1", 64) # noqa: E501 - (s, pfxlen) = x - - if len(s) < self.maxbytes: - s = s + (b"\0" * (self.maxbytes - len(s))) - return (self.ntoa(s), pfxlen) - - def any2i(self, pkt, x): - if x is None: - return (self.ntoa(b"\0" * self.maxbytes), 1) - - return self.h2i(pkt, x) - - def i2len(self, pkt, x): - (_, pfxlen) = x - return pfxlen - - def addfield(self, pkt, s, val): - (rawpfx, pfxlen) = self.i2m(pkt, val) - fmt = "!%is" % self._numbytes(pfxlen) - return s + struct.pack(fmt, rawpfx) - - def getfield(self, pkt, s): - pfxlen = self.length_from(pkt) - numbytes = self._numbytes(pfxlen) - fmt = "!%is" % numbytes - return s[numbytes:], self.m2i(pkt, (struct.unpack(fmt, s[:numbytes])[0], pfxlen)) # noqa: E501 - - -class IPPrefixField(_IPPrefixFieldBase): - def __init__(self, name, default, wordbytes=1, length_from=None): - _IPPrefixFieldBase.__init__(self, name, default, wordbytes, 4, inet_aton, inet_ntoa, length_from) # noqa: E501 - - -class IP6PrefixField(_IPPrefixFieldBase): - def __init__(self, name, default, wordbytes=1, length_from=None): - _IPPrefixFieldBase.__init__(self, name, default, wordbytes, 16, lambda a: inet_pton(socket.AF_INET6, a), lambda n: inet_ntop(socket.AF_INET6, n), length_from) # noqa: E501 - - -class UTCTimeField(IntField): - __slots__ = ["epoch", "delta", "strf", - "use_msec", "use_micro", "use_nano"] - - # Do not change the order of the keywords in here - # Netflow heavily rely on this - def __init__(self, name, default, - use_msec=False, - use_micro=False, - use_nano=False, - epoch=None, - strf="%a, %d %b %Y %H:%M:%S %z"): - IntField.__init__(self, name, default) - mk_epoch = EPOCH if epoch is None else calendar.timegm(epoch) - self.epoch = mk_epoch - self.delta = mk_epoch - EPOCH - self.strf = strf - self.use_msec = use_msec - self.use_micro = use_micro - self.use_nano = use_nano - - def i2repr(self, pkt, x): - if x is None: - x = 0 - elif self.use_msec: - x = x / 1e3 - elif self.use_micro: - x = x / 1e6 - elif self.use_nano: - x = x / 1e9 - x = int(x) + self.delta - t = time.strftime(self.strf, time.gmtime(x)) - return "%s (%d)" % (t, x) - - def i2m(self, pkt, x): - return int(x) if x is not None else 0 - - -class SecondsIntField(IntField): - __slots__ = ["use_msec", "use_micro", "use_nano"] - - # Do not change the order of the keywords in here - # Netflow heavily rely on this - def __init__(self, name, default, - use_msec=False, - use_micro=False, - use_nano=False): - IntField.__init__(self, name, default) - self.use_msec = use_msec - self.use_micro = use_micro - self.use_nano = use_nano - - def i2repr(self, pkt, x): - if x is None: - x = 0 - elif self.use_msec: - x = x / 1e3 - elif self.use_micro: - x = x / 1e6 - elif self.use_nano: - x = x / 1e9 - return "%s sec" % x - - -class ScalingField(Field): - """ Handle physical values which are scaled and/or offset for communication - - Example: - >>> from scapy.packet import Packet - >>> class ScalingFieldTest(Packet): - fields_desc = [ScalingField('data', 0, scaling=0.1, offset=-1, unit='mV')] # noqa: E501 - >>> ScalingFieldTest(data=10).show2() - ###[ ScalingFieldTest ]### - data= 10.0 mV - >>> hexdump(ScalingFieldTest(data=10)) - 0000 6E n - >>> hexdump(ScalingFieldTest(data=b"\x6D")) - 0000 6D m - >>> ScalingFieldTest(data=b"\x6D").show2() - ###[ ScalingFieldTest ]### - data= 9.9 mV - - bytes(ScalingFieldTest(...)) will produce 0x6E in this example. - 0x6E is 110 (decimal). This is calculated through the scaling factor - and the offset. "data" was set to 10, which means, we want to transfer - the physical value 10 mV. To calculate the value, which has to be - sent on the bus, the offset has to subtracted and the scaling has to be - applied by division through the scaling factor. - bytes = (data - offset) / scaling - bytes = ( 10 - (-1) ) / 0.1 - bytes = 110 = 0x6E - - If you want to force a certain internal value, you can assign a byte- - string to the field (data=b"\x6D"). If a string of a bytes object is - given to the field, no internal value conversion will be applied - - :param name: field's name - :param default: default value for the field - :param scaling: scaling factor for the internal value conversion - :param unit: string for the unit representation of the internal value - :param offset: value to offset the internal value during conversion - :param ndigits: number of fractional digits for the internal conversion - :param fmt: struct.pack format used to parse and serialize the internal value from and to machine representation # noqa: E501 - """ - __slots__ = ["scaling", "unit", "offset", "ndigits"] - - def __init__(self, name, default, scaling=1, unit="", - offset=0, ndigits=3, fmt="B"): - self.scaling = scaling - self.unit = unit - self.offset = offset - self.ndigits = ndigits - Field.__init__(self, name, default, fmt) - - def i2m(self, pkt, x): - if x is None: - x = 0 - x = (x - self.offset) / self.scaling - if isinstance(x, float) and self.fmt[-1] != "f": - x = int(round(x)) - return x - - def m2i(self, pkt, x): - x = x * self.scaling + self.offset - if isinstance(x, float) and self.fmt[-1] != "f": - x = round(x, self.ndigits) - return x - - def any2i(self, pkt, x): - if isinstance(x, str) or isinstance(x, bytes): - x = struct.unpack(self.fmt, bytes_encode(x))[0] - x = self.m2i(pkt, x) - return x - - def i2repr(self, pkt, x): - return "%s %s" % (self.i2h(pkt, x), self.unit) - - def randval(self): - value = super(ScalingField, self).randval() - if value is not None: - min_val = round(value.min * self.scaling + self.offset, - self.ndigits) - max_val = round(value.max * self.scaling + self.offset, - self.ndigits) - - return RandFloat(min(min_val, max_val), max(min_val, max_val)) - - -class UUIDField(Field): - """Field for UUID storage, wrapping Python's uuid.UUID type. - - The internal storage format of this field is ``uuid.UUID`` from the Python - standard library. - - There are three formats (``uuid_fmt``) for this field type:: - - * ``FORMAT_BE`` (default): the UUID is six fields in big-endian byte order, - per RFC 4122. - - This format is used by DHCPv6 (RFC 6355) and most network protocols. - - * ``FORMAT_LE``: the UUID is six fields, with ``time_low``, ``time_mid`` - and ``time_high_version`` in little-endian byte order. This _doesn't_ - change the arrangement of the fields from RFC 4122. - - This format is used by Microsoft's COM/OLE libraries. - - * ``FORMAT_REV``: the UUID is a single 128-bit integer in little-endian - byte order. This _changes the arrangement_ of the fields. - - This format is used by Bluetooth Low Energy. - - Note: You should use the constants here. - - The "human encoding" of this field supports a number of different input - formats, and wraps Python's ``uuid.UUID`` library appropriately:: - - * Given a bytearray, bytes or str of 16 bytes, this class decodes UUIDs in - wire format. - - * Given a bytearray, bytes or str of other lengths, this delegates to - ``uuid.UUID`` the Python standard library. This supports a number of - different encoding options -- see the Python standard library - documentation for more details. - - * Given an int or long, presumed to be a 128-bit integer to pass to - ``uuid.UUID``. - - * Given a tuple: - - * Tuples of 11 integers are treated as having the last 6 integers forming - the ``node`` field, and are merged before being passed as a tuple of 6 - integers to ``uuid.UUID``. - - * Otherwise, the tuple is passed as the ``fields`` parameter to - ``uuid.UUID`` directly without modification. - - ``uuid.UUID`` expects a tuple of 6 integers. - - Other types (such as ``uuid.UUID``) are passed through. - """ - - __slots__ = ["uuid_fmt"] - - FORMAT_BE = 0 - FORMAT_LE = 1 - FORMAT_REV = 2 - - # Change this when we get new formats - FORMATS = (FORMAT_BE, FORMAT_LE, FORMAT_REV) - - def __init__(self, name, default, uuid_fmt=FORMAT_BE): - self.uuid_fmt = uuid_fmt - self._check_uuid_fmt() - Field.__init__(self, name, default, "16s") - - def _check_uuid_fmt(self): - """Checks .uuid_fmt, and raises an exception if it is not valid.""" - if self.uuid_fmt not in UUIDField.FORMATS: - raise FieldValueRangeException( - "Unsupported uuid_fmt ({})".format(self.uuid_fmt)) - - def i2m(self, pkt, x): - self._check_uuid_fmt() - if x is None: - return b'\0' * 16 - if self.uuid_fmt == UUIDField.FORMAT_BE: - return x.bytes - elif self.uuid_fmt == UUIDField.FORMAT_LE: - return x.bytes_le - elif self.uuid_fmt == UUIDField.FORMAT_REV: - return x.bytes[::-1] - - def m2i(self, pkt, x): - self._check_uuid_fmt() - if self.uuid_fmt == UUIDField.FORMAT_BE: - return UUID(bytes=x) - elif self.uuid_fmt == UUIDField.FORMAT_LE: - return UUID(bytes_le=x) - elif self.uuid_fmt == UUIDField.FORMAT_REV: - return UUID(bytes=x[::-1]) - - def any2i(self, pkt, x): - # Python's uuid doesn't handle bytearray, so convert to an immutable - # type first. - if isinstance(x, bytearray): - x = bytes(x) - - if isinstance(x, six.integer_types): - x = UUID(int=x) - elif isinstance(x, tuple): - if len(x) == 11: - # For compatibility with dce_rpc: this packs into a tuple where - # elements 7..10 are the 48-bit node ID. - node = 0 - for i in x[5:]: - node = (node << 8) | i - - x = (x[0], x[1], x[2], x[3], x[4], node) - - x = UUID(fields=x) - elif isinstance(x, (six.binary_type, six.text_type)): - if len(x) == 16: - # Raw bytes - x = self.m2i(pkt, x) - else: - x = UUID(plain_str(x)) - return x - - @staticmethod - def randval(): - return RandUUID() - - -class BitExtendedField(Field): - """ - Bit Extended Field - ------------------ - - This type of field has a variable number of bytes. Each byte is defined - as follows: - - 7 bits of data - - 1 bit an an extension bit - * 0 means it is last byte of the field ("stopping bit") - * 1 means there is another byte after this one ("forwarding bit") - - To get the actual data, it is necessary to hop the binary data byte per - byte and to check the extension bit until 0 - """ - - __slots__ = ["extension_bit"] - - def prepare_byte(self, x): - # Moves the forwarding bit to the LSB - x = int(x) - fx_bit = (x & 2**self.extension_bit) >> self.extension_bit - lsb_bits = x & 2**self.extension_bit - 1 - msb_bits = x >> (self.extension_bit + 1) - x = (msb_bits << (self.extension_bit + 1)) + (lsb_bits << 1) + fx_bit - return x - - def str2extended(self, x=""): - # For convenience, we reorder the byte so that the forwarding - # bit is always the LSB. We then apply the same algorithm - # whatever the real forwarding bit position - - # First bit is the stopping bit at zero - bits = 0b0 - end = None - - # We retrieve 7 bits. - # If "forwarding bit" is 1 then we continue on another byte - i = 0 - for c in bytearray(x): - c = self.prepare_byte(c) - bits = bits << 7 | (int(c) >> 1) - if not int(c) & 0b1: - end = x[i + 1:] - break - i = i + 1 - if end is None: - # We reached the end of the data but there was no - # "ending bit". This is not normal. - return None, None - else: - return end, bits - - def extended2str(self, x): - x = int(x) - s = [] - LSByte = True - FX_Missing = True - bits = 0b0 - i = 0 - while (x > 0 or FX_Missing): - if i == 8: - # End of byte - i = 0 - s.append(bits) - bits = 0b0 - FX_Missing = True - else: - if i % 8 == self.extension_bit: - # This is extension bit - if LSByte: - bits = bits | 0b0 << i - LSByte = False - else: - bits = bits | 0b1 << i - FX_Missing = False - else: - bits = bits | (x & 0b1) << i - x = x >> 1 - # Still some bits - i = i + 1 - s.append(bits) - - result = "".encode() - for x in s[:: -1]: - result = result + struct.pack(">B", x) - return result - - def __init__(self, name, default, extension_bit): - Field.__init__(self, name, default, "B") - self.extension_bit = extension_bit - - def i2m(self, pkt, x): - return self.extended2str(x) - - def m2i(self, pkt, x): - return self.str2extended(x)[1] - - def addfield(self, pkt, s, val): - return s + self.i2m(pkt, val) - - def getfield(self, pkt, s): - return self.str2extended(s) - - -class LSBExtendedField(BitExtendedField): - # This is a BitExtendedField with the extension bit on LSB - def __init__(self, name, default): - BitExtendedField.__init__(self, name, default, extension_bit=0) - - -class MSBExtendedField(BitExtendedField): - # This is a BitExtendedField with the extension bit on MSB - def __init__(self, name, default): - BitExtendedField.__init__(self, name, default, extension_bit=7) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/__init__.py deleted file mode 100644 index 326b77a23e..0000000000 --- a/scripts/external_libs/scapy-2.4.3/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 information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Layer package. -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/all.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/all.py deleted file mode 100644 index d73b631ca3..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/all.py +++ /dev/null @@ -1,29 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -All layers. Configurable with conf.load_layers. -""" - -from __future__ import absolute_import -from scapy.config import conf -from scapy.error import log_loading -from scapy.main import load_layer -import logging -import scapy.modules.six as six - -ignored = list(six.moves.builtins.__dict__) + ["sys"] -log = logging.getLogger("scapy.loading") - -__all__ = [] - -for _l in conf.load_layers: - log_loading.debug("Loading layer %s" % _l) - try: - load_layer(_l, globals_dict=globals(), symb_list=__all__) - except Exception as e: - log.warning("can't import layer %s: %s", _l, e) - -del _l diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/bluetooth.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/bluetooth.py deleted file mode 100644 index fc819d667f..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/bluetooth.py +++ /dev/null @@ -1,1537 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Copyright (C) Mike Ryan -# Copyright (C) Michael Farrell -# This program is published under a GPLv2 license - -""" -Bluetooth layers, sockets and send/receive functions. -""" - -import ctypes -import functools -import socket -import struct -from select import select -from ctypes import sizeof - -from scapy.config import conf -from scapy.data import DLT_BLUETOOTH_HCI_H4, DLT_BLUETOOTH_HCI_H4_WITH_PHDR -from scapy.packet import bind_layers, Packet -from scapy.fields import ByteEnumField, ByteField, Field, FieldLenField, \ - FieldListField, FlagsField, IntField, LEShortEnumField, LEShortField, \ - LenField, PacketListField, SignedByteField, StrField, StrFixedLenField, \ - StrLenField, XByteField, BitField, XLELongField, PadField, UUIDField, \ - XStrLenField, ConditionalField -from scapy.supersocket import SuperSocket -from scapy.sendrecv import sndrcv -from scapy.data import MTU -from scapy.consts import WINDOWS -from scapy.error import warning -from scapy.utils import lhex, mac2str, str2mac -from scapy.volatile import RandMAC -from scapy.modules import six - - -########## -# Fields # -########## - -class XLEShortField(LEShortField): - def i2repr(self, pkt, x): - return lhex(self.i2h(pkt, x)) - - -class LEMACField(Field): - def __init__(self, name, default): - Field.__init__(self, name, default, "6s") - - def i2m(self, pkt, x): - if x is None: - return b"\0\0\0\0\0\0" - return mac2str(x)[::-1] - - def m2i(self, pkt, x): - return str2mac(x[::-1]) - - def any2i(self, pkt, x): - if isinstance(x, (six.binary_type, six.text_type)) and len(x) == 6: - x = self.m2i(pkt, x) - return x - - def i2repr(self, pkt, x): - x = self.i2h(pkt, x) - if self in conf.resolve: - x = conf.manufdb._resolve_MAC(x) - return x - - def randval(self): - return RandMAC() - - -########## -# Layers # -########## - -# See bluez/lib/hci.h for details - -# Transport layers - -class HCI_PHDR_Hdr(Packet): - name = "HCI PHDR transport layer" - fields_desc = [IntField("direction", 0)] - - -# Real layers - -_bluetooth_packet_types = { - 0: "Acknowledgement", - 1: "Command", - 2: "ACL Data", - 3: "Synchronous", - 4: "Event", - 5: "Reserve", - 14: "Vendor", - 15: "Link Control" -} - -_bluetooth_error_codes = { - 0x00: "success", - 0x01: "unknown command", - 0x02: "no connection", - 0x03: "hardware failure", - 0x04: "page timeout", - 0x05: "authentication failure", - 0x06: "pin or key missing", - 0x07: "memory full", - 0x08: "connection timeout", - 0x09: "max number of connections", - 0x0a: "max number of sco connections", - 0x0b: "acl connection exists", - 0x0c: "command disallowed", - 0x0d: "rejected limited resources", - 0x0e: "rejected security", - 0x0f: "rejected personal", - 0x10: "host timeout", - 0x11: "unsupported feature", - 0x12: "invalid parameters", - 0x13: "oe user ended connection", - 0x14: "oe low resources", - 0x15: "oe power off", - 0x16: "connection terminated", - 0x17: "repeated attempts", - 0x18: "pairing not allowed", - 0x19: "unknown lmp pdu", - 0x1a: "unsupported remote feature", - 0x1b: "sco offset rejected", - 0x1c: "sco interval rejected", - 0x1d: "air mode rejected", - 0x1e: "invalid lmp parameters", - 0x1f: "unspecified error", - 0x20: "unsupported lmp parameter value", - 0x21: "role change not allowed", - 0x22: "lmp response timeout", - 0x23: "lmp error transaction collision", - 0x24: "lmp pdu not allowed", - 0x25: "encryption mode not accepted", - 0x26: "unit link key used", - 0x27: "qos not supported", - 0x28: "instant passed", - 0x29: "pairing not supported", - 0x2a: "transaction collision", - 0x2c: "qos unacceptable parameter", - 0x2d: "qos rejected", - 0x2e: "classification not supported", - 0x2f: "insufficient security", - 0x30: "parameter out of range", - 0x32: "role switch pending", - 0x34: "slot violation", - 0x35: "role switch failed", - 0x36: "eir too large", - 0x37: "simple pairing not supported", - 0x38: "host busy pairing" -} - - -class HCI_Hdr(Packet): - name = "HCI header" - fields_desc = [ByteEnumField("type", 2, _bluetooth_packet_types)] - - def mysummary(self): - return self.sprintf("HCI %type%") - - -class HCI_ACL_Hdr(Packet): - name = "HCI ACL header" - # NOTE: the 2-bytes entity formed by the 2 flags + handle must be LE - # This means that we must reverse those two bytes manually (we don't have - # a field that can reverse a group of fields) - fields_desc = [BitField("BC", 0, 2), # ] - BitField("PB", 0, 2), # ]=> 2 bytes - BitField("handle", 0, 12), # ] - LEShortField("len", None), ] - - def pre_dissect(self, s): - return s[:2][::-1] + s[2:] # Reverse the 2 first bytes - - def post_dissect(self, s): - self.raw_packet_cache = None # Reset packet to allow post_build - return s - - def post_build(self, p, pay): - p += pay - if self.len is None: - p = p[:2] + struct.pack("= pkt.len: - return functools.partial( - ATT_Handle_Variable, - val_length=pkt.len - 2 - ) - return None - - -class ATT_Read_Request(Packet): - name = "Read Request" - fields_desc = [XLEShortField("gatt_handle", 0), ] - - -class ATT_Read_Response(Packet): - name = "Read Response" - fields_desc = [StrField("value", "")] - - -class ATT_Read_Multiple_Request(Packet): - name = "Read Multiple Request" - fields_desc = [FieldListField("handles", [], XLEShortField("", 0))] - - -class ATT_Read_Multiple_Response(Packet): - name = "Read Multiple Response" - fields_desc = [StrField("values", "")] - - -class ATT_Read_By_Group_Type_Request(Packet): - name = "Read By Group Type Request" - fields_desc = [XLEShortField("start", 0), - XLEShortField("end", 0xffff), - XLEShortField("uuid", 0), ] - - -class ATT_Read_By_Group_Type_Response(Packet): - name = "Read By Group Type Response" - fields_desc = [XByteField("length", 0), - StrField("data", ""), ] - - -class ATT_Write_Request(Packet): - name = "Write Request" - fields_desc = [XLEShortField("gatt_handle", 0), - StrField("data", ""), ] - - -class ATT_Write_Command(Packet): - name = "Write Request" - fields_desc = [XLEShortField("gatt_handle", 0), - StrField("data", ""), ] - - -class ATT_Write_Response(Packet): - name = "Write Response" - - -class ATT_Prepare_Write_Request(Packet): - name = "Prepare Write Request" - fields_desc = [ - XLEShortField("gatt_handle", 0), - LEShortField("offset", 0), - StrField("data", "") - ] - - -class ATT_Prepare_Write_Response(ATT_Prepare_Write_Request): - name = "Prepare Write Response" - - -class ATT_Handle_Value_Notification(Packet): - name = "Handle Value Notification" - fields_desc = [XLEShortField("gatt_handle", 0), - StrField("value", ""), ] - - -class ATT_Execute_Write_Request(Packet): - name = "Execute Write Request" - fields_desc = [ - ByteEnumField("flags", 1, { - 0: "Cancel all prepared writes", - 1: "Immediately write all pending prepared values", - }), - ] - - -class ATT_Execute_Write_Response(Packet): - name = "Execute Write Response" - - -class ATT_Read_Blob_Request(Packet): - name = "Read Blob Request" - fields_desc = [ - XLEShortField("gatt_handle", 0), - LEShortField("offset", 0) - ] - - -class ATT_Read_Blob_Response(Packet): - name = "Read Blob Response" - fields_desc = [ - StrField("value", "") - ] - - -class ATT_Handle_Value_Indication(Packet): - name = "Handle Value Indication" - fields_desc = [ - XLEShortField("gatt_handle", 0), - StrField("value", ""), - ] - - -class SM_Hdr(Packet): - name = "SM header" - fields_desc = [ByteField("sm_command", None)] - - -class SM_Pairing_Request(Packet): - name = "Pairing Request" - fields_desc = [ByteEnumField("iocap", 3, {0: "DisplayOnly", 1: "DisplayYesNo", 2: "KeyboardOnly", 3: "NoInputNoOutput", 4: "KeyboardDisplay"}), # noqa: E501 - ByteEnumField("oob", 0, {0: "Not Present", 1: "Present (from remote device)"}), # noqa: E501 - BitField("authentication", 0, 8), - ByteField("max_key_size", 16), - ByteField("initiator_key_distribution", 0), - ByteField("responder_key_distribution", 0), ] - - -class SM_Pairing_Response(Packet): - name = "Pairing Response" - fields_desc = [ByteEnumField("iocap", 3, {0: "DisplayOnly", 1: "DisplayYesNo", 2: "KeyboardOnly", 3: "NoInputNoOutput", 4: "KeyboardDisplay"}), # noqa: E501 - ByteEnumField("oob", 0, {0: "Not Present", 1: "Present (from remote device)"}), # noqa: E501 - BitField("authentication", 0, 8), - ByteField("max_key_size", 16), - ByteField("initiator_key_distribution", 0), - ByteField("responder_key_distribution", 0), ] - - -class SM_Confirm(Packet): - name = "Pairing Confirm" - fields_desc = [StrFixedLenField("confirm", b'\x00' * 16, 16)] - - -class SM_Random(Packet): - name = "Pairing Random" - fields_desc = [StrFixedLenField("random", b'\x00' * 16, 16)] - - -class SM_Failed(Packet): - name = "Pairing Failed" - fields_desc = [XByteField("reason", 0)] - - -class SM_Encryption_Information(Packet): - name = "Encryption Information" - fields_desc = [StrFixedLenField("ltk", b"\x00" * 16, 16), ] - - -class SM_Master_Identification(Packet): - name = "Master Identification" - fields_desc = [XLEShortField("ediv", 0), - StrFixedLenField("rand", b'\x00' * 8, 8), ] - - -class SM_Identity_Information(Packet): - name = "Identity Information" - fields_desc = [StrFixedLenField("irk", b'\x00' * 16, 16), ] - - -class SM_Identity_Address_Information(Packet): - name = "Identity Address Information" - fields_desc = [ByteEnumField("atype", 0, {0: "public"}), - LEMACField("address", None), ] - - -class SM_Signing_Information(Packet): - name = "Signing Information" - fields_desc = [StrFixedLenField("csrk", b'\x00' * 16, 16), ] - - -class EIR_Hdr(Packet): - name = "EIR Header" - fields_desc = [ - LenField("len", None, fmt="B", adjust=lambda x: x + 1), # Add bytes mark # noqa: E501 - # https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile - ByteEnumField("type", 0, { - 0x01: "flags", - 0x02: "incomplete_list_16_bit_svc_uuids", - 0x03: "complete_list_16_bit_svc_uuids", - 0x04: "incomplete_list_32_bit_svc_uuids", - 0x05: "complete_list_32_bit_svc_uuids", - 0x06: "incomplete_list_128_bit_svc_uuids", - 0x07: "complete_list_128_bit_svc_uuids", - 0x08: "shortened_local_name", - 0x09: "complete_local_name", - 0x0a: "tx_power_level", - 0x0d: "class_of_device", - 0x0e: "simple_pairing_hash", - 0x0f: "simple_pairing_rand", - - 0x10: "sec_mgr_tk", - 0x11: "sec_mgr_oob_flags", - 0x12: "slave_conn_intvl_range", - 0x14: "list_16_bit_svc_sollication_uuids", - 0x15: "list_128_bit_svc_sollication_uuids", - 0x16: "svc_data_16_bit_uuid", - 0x17: "pub_target_addr", - 0x18: "rand_target_addr", - 0x19: "appearance", - 0x1a: "adv_intvl", - 0x1b: "le_addr", - 0x1c: "le_role", - 0x1d: "simple_pairing_hash_256", - 0x1e: "simple_pairing_rand_256", - 0x1f: "list_32_bit_svc_sollication_uuids", - - 0x20: "svc_data_32_bit_uuid", - 0x21: "svc_data_128_bit_uuid", - 0x22: "sec_conn_confirm", - 0x23: "sec_conn_rand", - 0x24: "uri", - 0x25: "indoor_positioning", - 0x26: "transport_discovery", - 0x27: "le_supported_features", - 0x28: "channel_map_update", - 0x29: "mesh_pb_adv", - 0x2a: "mesh_message", - 0x2b: "mesh_beacon", - - 0x3d: "3d_information", - - 0xff: "mfg_specific_data", - }), - ] - - def mysummary(self): - return self.sprintf("EIR %type%") - - -class EIR_Element(Packet): - name = "EIR Element" - - def extract_padding(self, s): - # Needed to end each EIR_Element packet and make PacketListField work. - return b'', s - - @staticmethod - def length_from(pkt): - if not pkt.underlayer: - warning("Missing an upper-layer") - return 0 - # 'type' byte is included in the length, so subtract 1: - return pkt.underlayer.len - 1 - - -class EIR_Raw(EIR_Element): - name = "EIR Raw" - fields_desc = [ - StrLenField("data", "", length_from=EIR_Element.length_from) - ] - - -class EIR_Flags(EIR_Element): - name = "Flags" - fields_desc = [ - FlagsField("flags", 0x2, 8, - ["limited_disc_mode", "general_disc_mode", - "br_edr_not_supported", "simul_le_br_edr_ctrl", - "simul_le_br_edr_host"] + 3 * ["reserved"]) - ] - - -class EIR_CompleteList16BitServiceUUIDs(EIR_Element): - name = "Complete list of 16-bit service UUIDs" - fields_desc = [ - # https://www.bluetooth.com/specifications/assigned-numbers/16-bit-uuids-for-members - FieldListField("svc_uuids", None, XLEShortField("uuid", 0), - length_from=EIR_Element.length_from) - ] - - -class EIR_IncompleteList16BitServiceUUIDs(EIR_CompleteList16BitServiceUUIDs): - name = "Incomplete list of 16-bit service UUIDs" - - -class EIR_CompleteList128BitServiceUUIDs(EIR_Element): - name = "Complete list of 128-bit service UUIDs" - fields_desc = [ - FieldListField("svc_uuids", None, - UUIDField("uuid", None, uuid_fmt=UUIDField.FORMAT_REV), - length_from=EIR_Element.length_from) - ] - - -class EIR_IncompleteList128BitServiceUUIDs(EIR_CompleteList128BitServiceUUIDs): - name = "Incomplete list of 128-bit service UUIDs" - - -class EIR_CompleteLocalName(EIR_Element): - name = "Complete Local Name" - fields_desc = [ - StrLenField("local_name", "", length_from=EIR_Element.length_from) - ] - - -class EIR_ShortenedLocalName(EIR_CompleteLocalName): - name = "Shortened Local Name" - - -class EIR_TX_Power_Level(EIR_Element): - name = "TX Power Level" - fields_desc = [SignedByteField("level", 0)] - - -class EIR_Manufacturer_Specific_Data(EIR_Element): - name = "EIR Manufacturer Specific Data" - fields_desc = [ - # https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers - XLEShortField("company_id", None), - ] - - registered_magic_payloads = {} - - @classmethod - def register_magic_payload(cls, payload_cls, magic_check=None): - """ - Registers a payload type that uses magic data. - - Traditional payloads require registration of a Bluetooth Company ID - (requires company membership of the Bluetooth SIG), or a Bluetooth - Short UUID (requires a once-off payment). - - There are alternatives which don't require registration (such as - 128-bit UUIDs), but the biggest consumer of energy in a beacon is the - radio -- so the energy consumption of a beacon is proportional to the - number of bytes in a beacon frame. - - Some beacon formats side-step this issue by using the Company ID of - their beacon hardware manufacturer, and adding a "magic data sequence" - at the start of the Manufacturer Specific Data field. - - Examples of this are AltBeacon and GeoBeacon. - - For an example of this method in use, see ``scapy.contrib.altbeacon``. - - :param Type[Packet] payload_cls: - A reference to a Packet subclass to register as a payload. - :param Callable[[bytes], bool] magic_check: - (optional) callable to use to if a payload should be associated - with this type. If not supplied, ``payload_cls.magic_check`` is - used instead. - :raises TypeError: If ``magic_check`` is not specified, - and ``payload_cls.magic_check`` is not implemented. - """ - if magic_check is None: - if hasattr(payload_cls, "magic_check"): - magic_check = payload_cls.magic_check - else: - raise TypeError("magic_check not specified, and {} has no " - "attribute magic_check".format(payload_cls)) - - cls.registered_magic_payloads[payload_cls] = magic_check - - def default_payload_class(self, payload): - for cls, check in six.iteritems( - EIR_Manufacturer_Specific_Data.registered_magic_payloads): - if check(payload): - return cls - - return Packet.default_payload_class(self, payload) - - def extract_padding(self, s): - # Needed to end each EIR_Element packet and make PacketListField work. - plen = EIR_Element.length_from(self) - 2 - return s[:plen], s[plen:] - - -class EIR_Device_ID(EIR_Element): - name = "Device ID" - fields_desc = [ - XLEShortField("vendor_id_source", 0), - XLEShortField("vendor_id", 0), - XLEShortField("product_id", 0), - XLEShortField("version", 0), - ] - - -class EIR_ServiceData16BitUUID(EIR_Element): - name = "EIR Service Data - 16-bit UUID" - fields_desc = [ - # https://www.bluetooth.com/specifications/assigned-numbers/16-bit-uuids-for-members - XLEShortField("svc_uuid", None), - ] - - def extract_padding(self, s): - # Needed to end each EIR_Element packet and make PacketListField work. - plen = EIR_Element.length_from(self) - 2 - return s[:plen], s[plen:] - - -class HCI_Command_Hdr(Packet): - name = "HCI Command header" - fields_desc = [XLEShortField("opcode", 0), - LenField("len", None, fmt="B"), ] - - def answers(self, other): - return False - - def post_build(self, p, pay): - p += pay - if self.len is None: - p = p[:2] + struct.pack("B", len(pay)) + p[3:] - return p - - -class HCI_Cmd_Reset(Packet): - name = "Reset" - - -class HCI_Cmd_Set_Event_Filter(Packet): - name = "Set Event Filter" - fields_desc = [ByteEnumField("type", 0, {0: "clear"}), ] - - -class HCI_Cmd_Connect_Accept_Timeout(Packet): - name = "Connection Attempt Timeout" - fields_desc = [LEShortField("timeout", 32000)] # 32000 slots is 20000 msec - - -class HCI_Cmd_LE_Host_Supported(Packet): - name = "LE Host Supported" - fields_desc = [ByteField("supported", 1), - ByteField("simultaneous", 1), ] - - -class HCI_Cmd_Set_Event_Mask(Packet): - name = "Set Event Mask" - fields_desc = [StrFixedLenField("mask", b"\xff\xff\xfb\xff\x07\xf8\xbf\x3d", 8)] # noqa: E501 - - -class HCI_Cmd_Read_BD_Addr(Packet): - name = "Read BD Addr" - - -class HCI_Cmd_Write_Local_Name(Packet): - name = "Write Local Name" - fields_desc = [StrField("name", "")] - - -class HCI_Cmd_Write_Extended_Inquiry_Response(Packet): - name = "Write Extended Inquiry Response" - fields_desc = [ByteField("fec_required", 0), - PacketListField("eir_data", [], EIR_Hdr, - length_from=lambda pkt:pkt.len)] - - -class HCI_Cmd_LE_Set_Scan_Parameters(Packet): - name = "LE Set Scan Parameters" - fields_desc = [ByteEnumField("type", 1, {1: "active"}), - XLEShortField("interval", 16), - XLEShortField("window", 16), - ByteEnumField("atype", 0, {0: "public"}), - ByteEnumField("policy", 0, {0: "all", 1: "whitelist"})] - - -class HCI_Cmd_LE_Set_Scan_Enable(Packet): - name = "LE Set Scan Enable" - fields_desc = [ByteField("enable", 1), - ByteField("filter_dups", 1), ] - - -class HCI_Cmd_Disconnect(Packet): - name = "Disconnect" - fields_desc = [XLEShortField("handle", 0), - ByteField("reason", 0x13), ] - - -class HCI_Cmd_LE_Create_Connection(Packet): - name = "LE Create Connection" - fields_desc = [LEShortField("interval", 96), - LEShortField("window", 48), - ByteEnumField("filter", 0, {0: "address"}), - ByteEnumField("patype", 0, {0: "public", 1: "random"}), - LEMACField("paddr", None), - ByteEnumField("atype", 0, {0: "public", 1: "random"}), - LEShortField("min_interval", 40), - LEShortField("max_interval", 56), - LEShortField("latency", 0), - LEShortField("timeout", 42), - LEShortField("min_ce", 0), - LEShortField("max_ce", 0), ] - - -class HCI_Cmd_LE_Create_Connection_Cancel(Packet): - name = "LE Create Connection Cancel" - - -class HCI_Cmd_LE_Read_White_List_Size(Packet): - name = "LE Read White List Size" - - -class HCI_Cmd_LE_Clear_White_List(Packet): - name = "LE Clear White List" - - -class HCI_Cmd_LE_Add_Device_To_White_List(Packet): - name = "LE Add Device to White List" - fields_desc = [ByteEnumField("atype", 0, {0: "public", 1: "random"}), - LEMACField("address", None)] - - -class HCI_Cmd_LE_Remove_Device_From_White_List(HCI_Cmd_LE_Add_Device_To_White_List): # noqa: E501 - name = "LE Remove Device from White List" - - -class HCI_Cmd_LE_Connection_Update(Packet): - name = "LE Connection Update" - fields_desc = [XLEShortField("handle", 0), - XLEShortField("min_interval", 0), - XLEShortField("max_interval", 0), - XLEShortField("latency", 0), - XLEShortField("timeout", 0), - LEShortField("min_ce", 0), - LEShortField("max_ce", 0xffff), ] - - -class HCI_Cmd_LE_Read_Buffer_Size(Packet): - name = "LE Read Buffer Size" - - -class HCI_Cmd_LE_Read_Remote_Used_Features(Packet): - name = "LE Read Remote Used Features" - fields_desc = [LEShortField("handle", 64)] - - -class HCI_Cmd_LE_Set_Random_Address(Packet): - name = "LE Set Random Address" - fields_desc = [LEMACField("address", None)] - - -class HCI_Cmd_LE_Set_Advertising_Parameters(Packet): - name = "LE Set Advertising Parameters" - fields_desc = [LEShortField("interval_min", 0x0800), - LEShortField("interval_max", 0x0800), - ByteEnumField("adv_type", 0, {0: "ADV_IND", 1: "ADV_DIRECT_IND", 2: "ADV_SCAN_IND", 3: "ADV_NONCONN_IND", 4: "ADV_DIRECT_IND_LOW"}), # noqa: E501 - ByteEnumField("oatype", 0, {0: "public", 1: "random"}), - ByteEnumField("datype", 0, {0: "public", 1: "random"}), - LEMACField("daddr", None), - ByteField("channel_map", 7), - ByteEnumField("filter_policy", 0, {0: "all:all", 1: "connect:all scan:whitelist", 2: "connect:whitelist scan:all", 3: "all:whitelist"}), ] # noqa: E501 - - -class HCI_Cmd_LE_Set_Advertising_Data(Packet): - name = "LE Set Advertising Data" - fields_desc = [FieldLenField("len", None, length_of="data", fmt="B"), - PadField( - PacketListField("data", [], EIR_Hdr, - length_from=lambda pkt:pkt.len), - align=31, padwith=b"\0"), ] - - -class HCI_Cmd_LE_Set_Scan_Response_Data(Packet): - name = "LE Set Scan Response Data" - fields_desc = [FieldLenField("len", None, length_of="data", fmt="B"), - StrLenField("data", "", length_from=lambda pkt:pkt.len), ] - - -class HCI_Cmd_LE_Set_Advertise_Enable(Packet): - name = "LE Set Advertise Enable" - fields_desc = [ByteField("enable", 0)] - - -class HCI_Cmd_LE_Start_Encryption_Request(Packet): - name = "LE Start Encryption" - fields_desc = [LEShortField("handle", 0), - StrFixedLenField("rand", None, 8), - XLEShortField("ediv", 0), - StrFixedLenField("ltk", b'\x00' * 16, 16), ] - - -class HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply(Packet): - name = "LE Long Term Key Request Negative Reply" - fields_desc = [LEShortField("handle", 0), ] - - -class HCI_Cmd_LE_Long_Term_Key_Request_Reply(Packet): - name = "LE Long Term Key Request Reply" - fields_desc = [LEShortField("handle", 0), - StrFixedLenField("ltk", b'\x00' * 16, 16), ] - - -class HCI_Event_Hdr(Packet): - name = "HCI Event header" - fields_desc = [XByteField("code", 0), - LenField("len", None, fmt="B"), ] - - def answers(self, other): - if HCI_Command_Hdr not in other: - return False - - # Delegate answers to event types - return self.payload.answers(other) - - -class HCI_Event_Disconnection_Complete(Packet): - name = "Disconnection Complete" - fields_desc = [ByteEnumField("status", 0, {0: "success"}), - LEShortField("handle", 0), - XByteField("reason", 0), ] - - -class HCI_Event_Encryption_Change(Packet): - name = "Encryption Change" - fields_desc = [ByteEnumField("status", 0, {0: "change has occurred"}), - LEShortField("handle", 0), - ByteEnumField("enabled", 0, {0: "OFF", 1: "ON (LE)", 2: "ON (BR/EDR)"}), ] # noqa: E501 - - -class HCI_Event_Command_Complete(Packet): - name = "Command Complete" - fields_desc = [ByteField("number", 0), - XLEShortField("opcode", 0), - ByteEnumField("status", 0, _bluetooth_error_codes)] - - def answers(self, other): - if HCI_Command_Hdr not in other: - return False - - return other[HCI_Command_Hdr].opcode == self.opcode - - -class HCI_Cmd_Complete_Read_BD_Addr(Packet): - name = "Read BD Addr" - fields_desc = [LEMACField("addr", None), ] - - -class HCI_Cmd_Complete_LE_Read_White_List_Size(Packet): - name = "LE Read White List Size" - fields_desc = [ByteField("status", 0), - ByteField("size", 0), ] - - -class HCI_Event_Command_Status(Packet): - name = "Command Status" - fields_desc = [ByteEnumField("status", 0, {0: "pending"}), - ByteField("number", 0), - XLEShortField("opcode", None), ] - - def answers(self, other): - if HCI_Command_Hdr not in other: - return False - - return other[HCI_Command_Hdr].opcode == self.opcode - - -class HCI_Event_Number_Of_Completed_Packets(Packet): - name = "Number Of Completed Packets" - fields_desc = [ByteField("number", 0)] - - -class HCI_Event_LE_Meta(Packet): - name = "LE Meta" - fields_desc = [ByteEnumField("event", 0, { - 1: "connection_complete", - 2: "advertising_report", - 3: "connection_update_complete", - 5: "long_term_key_request", - }), ] - - def answers(self, other): - if not self.payload: - return False - - # Delegate answers to payload - return self.payload.answers(other) - - -class HCI_LE_Meta_Connection_Complete(Packet): - name = "Connection Complete" - fields_desc = [ByteEnumField("status", 0, {0: "success"}), - LEShortField("handle", 0), - ByteEnumField("role", 0, {0: "master"}), - ByteEnumField("patype", 0, {0: "public", 1: "random"}), - LEMACField("paddr", None), - LEShortField("interval", 54), - LEShortField("latency", 0), - LEShortField("supervision", 42), - XByteField("clock_latency", 5), ] - - def answers(self, other): - if HCI_Cmd_LE_Create_Connection not in other: - return False - - return (other[HCI_Cmd_LE_Create_Connection].patype == self.patype and - other[HCI_Cmd_LE_Create_Connection].paddr == self.paddr) - - -class HCI_LE_Meta_Connection_Update_Complete(Packet): - name = "Connection Update Complete" - fields_desc = [ByteEnumField("status", 0, {0: "success"}), - LEShortField("handle", 0), - LEShortField("interval", 54), - LEShortField("latency", 0), - LEShortField("timeout", 42), ] - - -class HCI_LE_Meta_Advertising_Report(Packet): - name = "Advertising Report" - fields_desc = [ByteEnumField("type", 0, {0: "conn_und", 4: "scan_rsp"}), - ByteEnumField("atype", 0, {0: "public", 1: "random"}), - LEMACField("addr", None), - FieldLenField("len", None, length_of="data", fmt="B"), - PacketListField("data", [], EIR_Hdr, - length_from=lambda pkt:pkt.len), - SignedByteField("rssi", 0)] - - def extract_padding(self, s): - return '', s - - -class HCI_LE_Meta_Advertising_Reports(Packet): - name = "Advertising Reports" - fields_desc = [FieldLenField("len", None, count_of="reports", fmt="B"), - PacketListField("reports", None, - HCI_LE_Meta_Advertising_Report, - count_from=lambda pkt:pkt.len)] - - -class HCI_LE_Meta_Long_Term_Key_Request(Packet): - name = "Long Term Key Request" - fields_desc = [LEShortField("handle", 0), - StrFixedLenField("rand", None, 8), - XLEShortField("ediv", 0), ] - - -bind_layers(HCI_PHDR_Hdr, HCI_Hdr) - -bind_layers(HCI_Hdr, HCI_Command_Hdr, type=1) -bind_layers(HCI_Hdr, HCI_ACL_Hdr, type=2) -bind_layers(HCI_Hdr, HCI_Event_Hdr, type=4) -bind_layers(HCI_Hdr, conf.raw_layer,) - -conf.l2types.register(DLT_BLUETOOTH_HCI_H4, HCI_Hdr) -conf.l2types.register(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, HCI_PHDR_Hdr) - -bind_layers(HCI_Command_Hdr, HCI_Cmd_Reset, opcode=0x0c03) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Mask, opcode=0x0c01) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Filter, opcode=0x0c05) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Connect_Accept_Timeout, opcode=0x0c16) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Host_Supported, opcode=0x0c6d) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Extended_Inquiry_Response, opcode=0x0c52) # noqa: E501 -bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_BD_Addr, opcode=0x1009) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Local_Name, opcode=0x0c13) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size, opcode=0x2002) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Random_Address, opcode=0x2005) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Parameters, opcode=0x2006) # noqa: E501 -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Data, opcode=0x2008) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Response_Data, opcode=0x2009) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertise_Enable, opcode=0x200a) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Parameters, opcode=0x200b) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Enable, opcode=0x200c) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Disconnect, opcode=0x406) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection, opcode=0x200d) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection_Cancel, opcode=0x200e) # noqa: E501 -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_White_List_Size, opcode=0x200f) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Clear_White_List, opcode=0x2010) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Add_Device_To_White_List, opcode=0x2011) # noqa: E501 -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Remove_Device_From_White_List, opcode=0x2012) # noqa: E501 -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Connection_Update, opcode=0x2013) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Remote_Used_Features, opcode=0x2016) # noqa: E501 - - -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Start_Encryption_Request, opcode=0x2019) # noqa: E501 - -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Start_Encryption_Request, opcode=0x2019) # noqa: E501 - -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Reply, opcode=0x201a) # noqa: E501 -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply, opcode=0x201b) # noqa: E501 - -bind_layers(HCI_Event_Hdr, HCI_Event_Disconnection_Complete, code=0x5) -bind_layers(HCI_Event_Hdr, HCI_Event_Encryption_Change, code=0x8) -bind_layers(HCI_Event_Hdr, HCI_Event_Command_Complete, code=0xe) -bind_layers(HCI_Event_Hdr, HCI_Event_Command_Status, code=0xf) -bind_layers(HCI_Event_Hdr, HCI_Event_Number_Of_Completed_Packets, code=0x13) -bind_layers(HCI_Event_Hdr, HCI_Event_LE_Meta, code=0x3e) - -bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_BD_Addr, opcode=0x1009) # noqa: E501 -bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_LE_Read_White_List_Size, opcode=0x200f) # noqa: E501 - -bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Complete, event=1) -bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Advertising_Reports, event=2) -bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Update_Complete, event=3) -bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Long_Term_Key_Request, event=5) - -bind_layers(EIR_Hdr, EIR_Flags, type=0x01) -bind_layers(EIR_Hdr, EIR_IncompleteList16BitServiceUUIDs, type=0x02) -bind_layers(EIR_Hdr, EIR_CompleteList16BitServiceUUIDs, type=0x03) -bind_layers(EIR_Hdr, EIR_IncompleteList128BitServiceUUIDs, type=0x06) -bind_layers(EIR_Hdr, EIR_CompleteList128BitServiceUUIDs, type=0x07) -bind_layers(EIR_Hdr, EIR_ShortenedLocalName, type=0x08) -bind_layers(EIR_Hdr, EIR_CompleteLocalName, type=0x09) -bind_layers(EIR_Hdr, EIR_Device_ID, type=0x10) -bind_layers(EIR_Hdr, EIR_TX_Power_Level, type=0x0a) -bind_layers(EIR_Hdr, EIR_ServiceData16BitUUID, type=0x16) -bind_layers(EIR_Hdr, EIR_Manufacturer_Specific_Data, type=0xff) -bind_layers(EIR_Hdr, EIR_Raw) - -bind_layers(HCI_ACL_Hdr, L2CAP_Hdr,) -bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=1) -bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=5) # LE L2CAP Signaling Channel -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) -bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Request, code=18) -bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Response, code=19) -bind_layers(L2CAP_Hdr, ATT_Hdr, cid=4) -bind_layers(ATT_Hdr, ATT_Error_Response, opcode=0x1) -bind_layers(ATT_Hdr, ATT_Exchange_MTU_Request, opcode=0x2) -bind_layers(ATT_Hdr, ATT_Exchange_MTU_Response, opcode=0x3) -bind_layers(ATT_Hdr, ATT_Find_Information_Request, opcode=0x4) -bind_layers(ATT_Hdr, ATT_Find_Information_Response, opcode=0x5) -bind_layers(ATT_Hdr, ATT_Find_By_Type_Value_Request, opcode=0x6) -bind_layers(ATT_Hdr, ATT_Find_By_Type_Value_Response, opcode=0x7) -bind_layers(ATT_Hdr, ATT_Read_By_Type_Request_128bit, opcode=0x8) -bind_layers(ATT_Hdr, ATT_Read_By_Type_Request, opcode=0x8) -bind_layers(ATT_Hdr, ATT_Read_By_Type_Response, opcode=0x9) -bind_layers(ATT_Hdr, ATT_Read_Request, opcode=0xa) -bind_layers(ATT_Hdr, ATT_Read_Response, opcode=0xb) -bind_layers(ATT_Hdr, ATT_Read_Blob_Request, opcode=0xc) -bind_layers(ATT_Hdr, ATT_Read_Blob_Response, opcode=0xd) -bind_layers(ATT_Hdr, ATT_Read_Multiple_Request, opcode=0xe) -bind_layers(ATT_Hdr, ATT_Read_Multiple_Response, opcode=0xf) -bind_layers(ATT_Hdr, ATT_Read_By_Group_Type_Request, opcode=0x10) -bind_layers(ATT_Hdr, ATT_Read_By_Group_Type_Response, opcode=0x11) -bind_layers(ATT_Hdr, ATT_Write_Request, opcode=0x12) -bind_layers(ATT_Hdr, ATT_Write_Response, opcode=0x13) -bind_layers(ATT_Hdr, ATT_Prepare_Write_Request, opcode=0x16) -bind_layers(ATT_Hdr, ATT_Prepare_Write_Response, opcode=0x17) -bind_layers(ATT_Hdr, ATT_Execute_Write_Request, opcode=0x18) -bind_layers(ATT_Hdr, ATT_Execute_Write_Response, opcode=0x19) -bind_layers(ATT_Hdr, ATT_Write_Command, opcode=0x52) -bind_layers(ATT_Hdr, ATT_Handle_Value_Notification, opcode=0x1b) -bind_layers(ATT_Hdr, ATT_Handle_Value_Indication, opcode=0x1d) -bind_layers(L2CAP_Hdr, SM_Hdr, cid=6) -bind_layers(SM_Hdr, SM_Pairing_Request, sm_command=1) -bind_layers(SM_Hdr, SM_Pairing_Response, sm_command=2) -bind_layers(SM_Hdr, SM_Confirm, sm_command=3) -bind_layers(SM_Hdr, SM_Random, sm_command=4) -bind_layers(SM_Hdr, SM_Failed, sm_command=5) -bind_layers(SM_Hdr, SM_Encryption_Information, sm_command=6) -bind_layers(SM_Hdr, SM_Master_Identification, sm_command=7) -bind_layers(SM_Hdr, SM_Identity_Information, sm_command=8) -bind_layers(SM_Hdr, SM_Identity_Address_Information, sm_command=9) -bind_layers(SM_Hdr, SM_Signing_Information, sm_command=0x0a) - - -########### -# Helpers # -########### - -class LowEnergyBeaconHelper: - """ - Helpers for building packets for Bluetooth Low Energy Beacons. - - Implementors provide a :meth:`build_eir` implementation. - - This is designed to be used as a mix-in -- see - ``scapy.contrib.eddystone`` and ``scapy.contrib.ibeacon`` for examples. - """ - - # Basic flags that should be used by most beacons. - base_eir = [EIR_Hdr() / EIR_Flags(flags=[ - "general_disc_mode", "br_edr_not_supported"]), ] - - def build_eir(self): - """ - Builds a list of EIR messages to wrap this frame. - - Users of this helper must implement this method. - - :returns: List of HCI_Hdr with payloads that describe this beacon type - :rtype: list[HCI_Hdr] - """ - raise NotImplementedError("build_eir") - - def build_advertising_report(self): - """ - Builds a HCI_LE_Meta_Advertising_Report containing this frame. - - :rtype: HCI_LE_Meta_Advertising_Report - """ - - return HCI_LE_Meta_Advertising_Report( - type=0, # Undirected - atype=1, # Random address - data=self.build_eir() - ) - - def build_set_advertising_data(self): - """Builds a HCI_Cmd_LE_Set_Advertising_Data containing this frame. - - This includes the :class:`HCI_Hdr` and :class:`HCI_Command_Hdr` layers. - - :rtype: HCI_Hdr - """ - - return HCI_Hdr() / HCI_Command_Hdr() / HCI_Cmd_LE_Set_Advertising_Data( - data=self.build_eir() - ) - - -########### -# Sockets # -########### - -class BluetoothSocketError(BaseException): - pass - - -class BluetoothCommandError(BaseException): - pass - - -class BluetoothL2CAPSocket(SuperSocket): - desc = "read/write packets on a connected L2CAP socket" - - def __init__(self, bt_address): - if WINDOWS: - warning("Not available on Windows") - return - s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, - socket.BTPROTO_L2CAP) - s.connect((bt_address, 0)) - self.ins = self.outs = s - - def recv(self, x=MTU): - return L2CAP_CmdHdr(self.ins.recv(x)) - - -class BluetoothRFCommSocket(BluetoothL2CAPSocket): - """read/write packets on a connected RFCOMM socket""" - - def __init__(self, bt_address, port=0): - s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, - socket.BTPROTO_RFCOMM) - s.connect((bt_address, port)) - self.ins = self.outs = s - - -class BluetoothHCISocket(SuperSocket): - desc = "read/write on a BlueTooth HCI socket" - - def __init__(self, iface=0x10000, type=None): - if WINDOWS: - warning("Not available on Windows") - return - s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) # noqa: E501 - 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 # noqa: E501 - s.bind((iface,)) - self.ins = self.outs = s -# s.connect((peer,0)) - - def recv(self, x=MTU): - return HCI_Hdr(self.ins.recv(x)) - - -class sockaddr_hci(ctypes.Structure): - _fields_ = [ - ("sin_family", ctypes.c_ushort), - ("hci_dev", ctypes.c_ushort), - ("hci_channel", ctypes.c_ushort), - ] - - -class BluetoothUserSocket(SuperSocket): - desc = "read/write H4 over a Bluetooth user channel" - - def __init__(self, adapter_index=0): - if WINDOWS: - warning("Not available on Windows") - return - # s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) # noqa: E501 - # s.bind((0,1)) - - # yeah, if only - # thanks to Python's weak ass socket and bind implementations, we have - # to call down into libc with ctypes - - sockaddr_hcip = ctypes.POINTER(sockaddr_hci) - ctypes.cdll.LoadLibrary("libc.so.6") - libc = ctypes.CDLL("libc.so.6") - - socket_c = libc.socket - socket_c.argtypes = (ctypes.c_int, ctypes.c_int, ctypes.c_int) - socket_c.restype = ctypes.c_int - - bind = libc.bind - bind.argtypes = (ctypes.c_int, - ctypes.POINTER(sockaddr_hci), - ctypes.c_int) - bind.restype = ctypes.c_int - - ######## - # actual code - - s = socket_c(31, 3, 1) # (AF_BLUETOOTH, SOCK_RAW, HCI_CHANNEL_USER) - if s < 0: - raise BluetoothSocketError("Unable to open PF_BLUETOOTH socket") - - sa = sockaddr_hci() - sa.sin_family = 31 # AF_BLUETOOTH - sa.hci_dev = adapter_index # adapter index - sa.hci_channel = 1 # HCI_USER_CHANNEL - - r = bind(s, sockaddr_hcip(sa), sizeof(sa)) - if r != 0: - raise BluetoothSocketError("Unable to bind") - - self.ins = self.outs = socket.fromfd(s, 31, 3, 1) - - def send_command(self, cmd): - opcode = cmd.opcode - self.send(cmd) - while True: - r = self.recv() - if r.type == 0x04 and r.code == 0xe and r.opcode == opcode: - if r.status != 0: - raise BluetoothCommandError("Command %x failed with %x" % (opcode, r.status)) # noqa: E501 - return r - - def recv(self, x=MTU): - return HCI_Hdr(self.ins.recv(x)) - - def readable(self, timeout=0): - (ins, outs, foo) = select([self.ins], [], [], timeout) - return len(ins) > 0 - - def flush(self): - while self.readable(): - self.recv() - - def close(self): - if self.closed: - return - - # Properly close socket so we can free the device - ctypes.cdll.LoadLibrary("libc.so.6") - libc = ctypes.CDLL("libc.so.6") - - close = libc.close - close.restype = ctypes.c_int - self.closed = True - if hasattr(self, "outs"): - if not hasattr(self, "ins") or self.ins != self.outs: - if self.outs and (WINDOWS or self.outs.fileno() != -1): - close(self.outs.fileno()) - if hasattr(self, "ins"): - if self.ins and (WINDOWS or self.ins.fileno() != -1): - close(self.ins.fileno()) - - -conf.BTsocket = BluetoothRFCommSocket - -# Bluetooth - - -@conf.commands.register -def srbt(bt_address, pkts, inter=0.1, *args, **kargs): - """send and receive using a bluetooth socket""" - if "port" in kargs: - s = conf.BTsocket(bt_address=bt_address, port=kargs.pop("port")) - else: - s = conf.BTsocket(bt_address=bt_address) - a, b = sndrcv(s, pkts, inter=inter, *args, **kargs) - s.close() - return a, b - - -@conf.commands.register -def srbt1(bt_address, pkts, *args, **kargs): - """send and receive 1 packet using a bluetooth socket""" - a, b = srbt(bt_address, pkts, *args, **kargs) - if len(a) > 0: - return a[0][1] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/bluetooth4LE.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/bluetooth4LE.py deleted file mode 100644 index 82cee33603..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/bluetooth4LE.py +++ /dev/null @@ -1,313 +0,0 @@ -# This file is for use with Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Airbus DS CyberSecurity -# Authors: Jean-Michel Picod, Arnaud Lebrun, Jonathan Christofer Demay -# This program is published under a GPLv2 license - -"""Bluetooth 4LE layer""" - -import struct - -from scapy.compat import orb, chb -from scapy.config import conf -from scapy.data import DLT_BLUETOOTH_LE_LL, DLT_BLUETOOTH_LE_LL_WITH_PHDR, \ - PPI_BTLE -from scapy.packet import Packet, bind_layers -from scapy.fields import BitEnumField, BitField, ByteEnumField, ByteField, \ - Field, FlagsField, LEIntField, LEShortEnumField, LEShortField, \ - MACField, PacketListField, SignedByteField, X3BytesField, XBitField, \ - XByteField, XIntField, XShortField, XLEIntField, XLEShortField - -from scapy.layers.bluetooth import EIR_Hdr, L2CAP_Hdr -from scapy.layers.ppi import PPI_Element, PPI_Hdr - -from scapy.modules.six.moves import range -from scapy.utils import mac2str, str2mac - -#################### -# Transport Layers # -#################### - - -class BTLE_PPI(PPI_Element): - """Cooked BTLE PPI header - - See ``ppi_btle_t`` in - https://github.com/greatscottgadgets/libbtbb/blob/master/lib/src/pcap.c - """ - name = "BTLE PPI header" - fields_desc = [ - ByteField("btle_version", 0), - # btle_channel is a frequency in MHz. Named for consistency with - # other users. - LEShortField("btle_channel", None), - ByteField("btle_clkn_high", None), - LEIntField("btle_clk_100ns", None), - SignedByteField("rssi_max", None), - SignedByteField("rssi_min", None), - SignedByteField("rssi_avg", None), - ByteField("rssi_count", None) - ] - - -class BTLE_RF(Packet): - """Cooked BTLE link-layer pseudoheader. - - http://www.whiterocker.com/bt/LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR.html - """ - name = "BTLE RF info header" - fields_desc = [ - ByteField("rf_channel", 0), - SignedByteField("signal", -128), - SignedByteField("noise", -128), - ByteField("access_address_offenses", 0), - XLEIntField("reference_access_address", 0), - FlagsField("flags", 0, -16, [ - "dewhitened", "sig_power_valid", "noise_power_valid", - "decrypted", "reference_access_address_valid", - "access_address_offenses_valid", "channel_aliased", - "res1", "res2", "res3", "crc_checked", "crc_valid", - "mic_checked", "mic_valid", "res4", "res5" - ]) - ] - - -########## -# Fields # -########## - -class BDAddrField(MACField): - def __init__(self, name, default, resolve=False): - MACField.__init__(self, name, default) - if resolve: - conf.resolve.add(self) - - def i2m(self, pkt, x): - if x is None: - return b"\0\0\0\0\0\0" - return mac2str(':'.join(x.split(':')[::-1])) - - def m2i(self, pkt, x): - return str2mac(x[::-1]) - - -class BTLEChanMapField(XByteField): - def __init__(self, name, default): - Field.__init__(self, name, default, "> 8) & 0xff) << 8) + (swapbits((init >> 16) & 0xff) << 16) # noqa: E501 - lfsr_mask = 0x5a6000 - for i in (orb(x) for x in pdu): - for j in range(8): - next_bit = (state ^ i) & 1 - i >>= 1 - state >>= 1 - if next_bit: - state |= 1 << 23 - state ^= lfsr_mask - return struct.pack(" 2: - l_pay = len(pay) - else: - l_pay = 0 - p = p[:1] + chb(l_pay & 0x3f) + p[2:] - if not isinstance(self.underlayer, BTLE): - self.add_underlayer(BTLE) - return p - - -class BTLE_DATA(Packet): - name = "BTLE data header" - fields_desc = [ - BitField("RFU", 0, 3), # Unused - BitField("MD", 0, 1), - BitField("SN", 0, 1), - BitField("NESN", 0, 1), - BitEnumField("LLID", 0, 2, {1: "continue", 2: "start", 3: "control"}), - ByteField("len", None), - ] - - def post_build(self, p, pay): - if self.len is None: - p = p[:-1] + chb(len(pay)) - return p + pay - - -class BTLE_ADV_IND(Packet): - name = "BTLE ADV_IND" - fields_desc = [ - BDAddrField("AdvA", None), - PacketListField("data", None, EIR_Hdr) - ] - - -class BTLE_ADV_DIRECT_IND(Packet): - name = "BTLE ADV_DIRECT_IND" - fields_desc = [ - BDAddrField("AdvA", None), - BDAddrField("InitA", None) - ] - - -class BTLE_ADV_NONCONN_IND(BTLE_ADV_IND): - name = "BTLE ADV_NONCONN_IND" - - -class BTLE_ADV_SCAN_IND(BTLE_ADV_IND): - name = "BTLE ADV_SCAN_IND" - - -class BTLE_SCAN_REQ(Packet): - name = "BTLE scan request" - fields_desc = [ - BDAddrField("ScanA", None), - BDAddrField("AdvA", None) - ] - - def answers(self, other): - return BTLE_SCAN_RSP in other and self.AdvA == other.AdvA - - -class BTLE_SCAN_RSP(Packet): - name = "BTLE scan response" - fields_desc = [ - BDAddrField("AdvA", None), - PacketListField("data", None, EIR_Hdr) - ] - - def answers(self, other): - return BTLE_SCAN_REQ in other and self.AdvA == other.AdvA - - -class BTLE_CONNECT_REQ(Packet): - name = "BTLE connect request" - fields_desc = [ - BDAddrField("InitA", None), - BDAddrField("AdvA", None), - # LLDATA - XIntField("AA", 0x00), - X3BytesField("crc_init", 0x0), - XByteField("win_size", 0x0), - XLEShortField("win_offset", 0x0), - XLEShortField("interval", 0x0), - XLEShortField("latency", 0x0), - XLEShortField("timeout", 0x0), - BTLEChanMapField("chM", 0), - BitField("SCA", 0, 3), - BitField("hop", 0, 5), - ] - - -BTLE_Versions = { - 7: '4.1' -} -BTLE_Corp_IDs = { - 0xf: 'Broadcom Corporation' -} - - -class CtrlPDU(Packet): - name = "CtrlPDU" - fields_desc = [ - XByteField("optcode", 0), - ByteEnumField("version", 0, BTLE_Versions), - LEShortEnumField("Company", 0, BTLE_Corp_IDs), - XShortField("subversion", 0) - ] - - -bind_layers(BTLE, BTLE_ADV, access_addr=0x8E89BED6) -bind_layers(BTLE, BTLE_DATA) -bind_layers(BTLE_ADV, BTLE_ADV_IND, PDU_type=0) -bind_layers(BTLE_ADV, BTLE_ADV_DIRECT_IND, PDU_type=1) -bind_layers(BTLE_ADV, BTLE_ADV_NONCONN_IND, PDU_type=2) -bind_layers(BTLE_ADV, BTLE_SCAN_REQ, PDU_type=3) -bind_layers(BTLE_ADV, BTLE_SCAN_RSP, PDU_type=4) -bind_layers(BTLE_ADV, BTLE_CONNECT_REQ, PDU_type=5) -bind_layers(BTLE_ADV, BTLE_ADV_SCAN_IND, PDU_type=6) - -bind_layers(BTLE_DATA, L2CAP_Hdr, LLID=2) # BTLE_DATA / L2CAP_Hdr / ATT_Hdr -# LLID=1 -> Continue -bind_layers(BTLE_DATA, CtrlPDU, LLID=3) - -conf.l2types.register(DLT_BLUETOOTH_LE_LL, BTLE) -conf.l2types.register(DLT_BLUETOOTH_LE_LL_WITH_PHDR, BTLE_RF) - -bind_layers(BTLE_RF, BTLE) - -bind_layers(PPI_Hdr, BTLE_PPI, pfh_type=PPI_BTLE) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/can.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/can.py deleted file mode 100644 index 677f7ddc55..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/can.py +++ /dev/null @@ -1,442 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - - -"""A minimal implementation of the CANopen protocol, based on -Wireshark dissectors. See https://wiki.wireshark.org/CANopen - -""" - -import os -import gzip -import struct -import binascii -import scapy.modules.six as six -from scapy.config import conf -from scapy.compat import orb -from scapy.data import DLT_CAN_SOCKETCAN, MTU -from scapy.fields import FieldLenField, FlagsField, StrLenField, \ - ThreeBytesField, XBitField, ScalingField -from scapy.volatile import RandFloat, RandBinFloat -from scapy.packet import Packet, bind_layers -from scapy.layers.l2 import CookedLinux -from scapy.error import Scapy_Exception -from scapy.plist import PacketList - -__all__ = ["CAN", "SignalPacket", "SignalField", "LESignedSignalField", - "LEUnsignedSignalField", "LEFloatSignalField", "BEFloatSignalField", - "BESignedSignalField", "BEUnsignedSignalField", "rdcandump", - "CandumpReader"] - -# Mimics the Wireshark CAN dissector parameter 'Byte-swap the CAN ID/flags field' # noqa: E501 -# set to True when working with PF_CAN sockets -conf.contribs['CAN'] = {'swap-bytes': False} - - -class CAN(Packet): - """A minimal implementation of the CANopen protocol, based on - Wireshark dissectors. See https://wiki.wireshark.org/CANopen - - """ - fields_desc = [ - FlagsField('flags', 0, 3, ['error', - 'remote_transmission_request', - 'extended']), - XBitField('identifier', 0, 29), - FieldLenField('length', None, length_of='data', fmt='B'), - ThreeBytesField('reserved', 0), - StrLenField('data', '', length_from=lambda pkt: pkt.length), - ] - - @staticmethod - def inv_endianness(pkt): - """ Invert the order of the first four bytes of a CAN packet - - This method is meant to be used specifically to convert a CAN packet - between the pcap format and the socketCAN format - - :param pkt: str of the CAN packet - :return: packet str with the first four bytes swapped - """ - len_partial = len(pkt) - 4 # len of the packet, CAN ID excluded - return struct.pack('I{}s'.format(len_partial), pkt)) - - def pre_dissect(self, s): - """ Implements the swap-bytes functionality when dissecting """ - if conf.contribs['CAN']['swap-bytes']: - return CAN.inv_endianness(s) - return s - - def post_dissect(self, s): - self.raw_packet_cache = None # Reset packet to allow post_build - return s - - def post_build(self, pkt, pay): - """ Implements the swap-bytes functionality when building - - this is based on a copy of the Packet.self_build default method. - The goal is to affect only the CAN layer data and keep - under layers (e.g LinuxCooked) unchanged - """ - if conf.contribs['CAN']['swap-bytes']: - return CAN.inv_endianness(pkt) + pay - return pkt + pay - - def extract_padding(self, p): - return b'', p - - -conf.l2types.register(DLT_CAN_SOCKETCAN, CAN) -bind_layers(CookedLinux, CAN, proto=12) - - -class SignalField(ScalingField): - __slots__ = ["start", "size"] - - def __init__(self, name, default, start, size, scaling=1, unit="", - offset=0, ndigits=3, fmt="B"): - ScalingField.__init__(self, name, default, scaling, unit, offset, - ndigits, fmt) - self.start = start - self.size = abs(size) - - if fmt[-1] == "f" and self.size != 32: - raise Scapy_Exception("SignalField size has to be 32 for floats") - - _lookup_table = [7, 6, 5, 4, 3, 2, 1, 0, - 15, 14, 13, 12, 11, 10, 9, 8, - 23, 22, 21, 20, 19, 18, 17, 16, - 31, 30, 29, 28, 27, 26, 25, 24, - 39, 38, 37, 36, 35, 34, 33, 32, - 47, 46, 45, 44, 43, 42, 41, 40, - 55, 54, 53, 52, 51, 50, 49, 48, - 63, 62, 61, 60, 59, 58, 57, 56] - - @staticmethod - def _msb_lookup(start): - return SignalField._lookup_table.index(start) - - @staticmethod - def _lsb_lookup(start, size): - return SignalField._lookup_table[SignalField._msb_lookup(start) + - size - 1] - - @staticmethod - def _convert_to_unsigned(number, bit_length): - if number & (1 << (bit_length - 1)): - mask = (2 ** bit_length) - return mask + number - return number - - @staticmethod - def _convert_to_signed(number, bit_length): - mask = (2 ** bit_length) - 1 - if number & (1 << (bit_length - 1)): - return number | ~mask - return number & mask - - def _is_little_endian(self): - return self.fmt[0] == "<" - - def _is_signed_number(self): - return self.fmt[-1].islower() - - def _is_float_number(self): - return self.fmt[-1] == "f" - - def addfield(self, pkt, s, val): - if not isinstance(pkt, SignalPacket): - raise Scapy_Exception("Only use SignalFields in a SignalPacket") - - val = self.i2m(pkt, val) - - if self._is_little_endian(): - msb_pos = self.start + self.size - 1 - lsb_pos = self.start - shift = lsb_pos - fmt = "> shift - fld_val &= ((1 << self.size) - 1) - - if self._is_float_number(): - fld_val = struct.unpack(self.fmt, - struct.pack(self.fmt[0] + "I", fld_val))[0] - elif self._is_signed_number(): - fld_val = self._convert_to_signed(fld_val, self.size) - - return s, self.m2i(pkt, fld_val) - - def randval(self): - if self._is_float_number(): - return RandBinFloat(0, 0) - - if self._is_signed_number(): - min_val = -2**(self.size - 1) - max_val = 2**(self.size - 1) - 1 - else: - min_val = 0 - max_val = 2 ** self.size - 1 - - min_val = round(min_val * self.scaling + self.offset, self.ndigits) - max_val = round(max_val * self.scaling + self.offset, self.ndigits) - - return RandFloat(min(min_val, max_val), max(min_val, max_val)) - - def i2len(self, pkt, x): - return float(self.size) / 8 - - -class LEUnsignedSignalField(SignalField): - def __init__(self, name, default, start, size, scaling=1, unit="", - offset=0, ndigits=3): - SignalField.__init__(self, name, default, start, size, - scaling, unit, offset, ndigits, "B") - - -class BESignedSignalField(SignalField): - def __init__(self, name, default, start, size, scaling=1, unit="", - offset=0, ndigits=3): - SignalField.__init__(self, name, default, start, size, - scaling, unit, offset, ndigits, ">b") - - -class LEFloatSignalField(SignalField): - def __init__(self, name, default, start, scaling=1, unit="", - offset=0, ndigits=3): - SignalField.__init__(self, name, default, start, 32, - scaling, unit, offset, ndigits, "f") - - -class SignalPacket(Packet): - def pre_dissect(self, s): - if not all(isinstance(f, SignalField) for f in self.fields_desc): - raise Scapy_Exception("Use only SignalFields in a SignalPacket") - return s - - def post_dissect(self, s): - """ SignalFields can be dissected on packets with unordered fields. - The order of SignalFields is defined from the start parameter. - After a build, the consumed bytes of the length of all SignalFields - have to be removed from the SignalPacket. - """ - if self.wirelen > 8: - raise Scapy_Exception("Only 64 bits for all SignalFields " - "are supported") - self.raw_packet_cache = None # Reset packet to allow post_build - return s[self.wirelen:] - - -def rdcandump(filename, count=-1, interface=None): - """Read a candump log file and return a packet list - - filename: file to read - count: read only packets - interfaces: return only packets from a specified interface - """ - with CandumpReader(filename, interface) as fdesc: - return fdesc.read_all(count=count) - - -class CandumpReader: - """A stateful candump reader. Each packet is returned as a CAN packet""" - - read_allowed_exceptions = () # emulate SuperSocket - nonblocking_socket = True - - def __init__(self, filename, interface=None): - self.filename, self.f = self.open(filename) - self.ifilter = None - if interface is not None: - if isinstance(interface, six.string_types): - self.ifilter = [interface] - else: - self.ifilter = interface - - def __iter__(self): - return self - - @staticmethod - def open(filename): - """Open (if necessary) filename.""" - if isinstance(filename, six.string_types): - try: - fdesc = gzip.open(filename, "rb") - except IOError: - fdesc = open(filename, "rb") - else: - fdesc = filename - filename = getattr(fdesc, "name", "No name") - return filename, fdesc - - def next(self): - """implement the iterator protocol on a set of packets - """ - try: - pkt = None - while pkt is None: - pkt = self.read_packet() - except EOFError: - raise StopIteration - - return pkt - __next__ = next - - def read_packet(self, size=MTU): - """return a single packet read from the file or None if filters apply - - raise EOFError when no more packets are available - """ - line = self.f.readline() - line = line.lstrip() - if len(line) < 16: - raise EOFError - - is_log_file_format = orb(line[0]) == orb(b"(") - - if is_log_file_format: - t, intf, f = line.split() - idn, data = f.split(b'#') - le = None - t = float(t[1:-1]) - else: - h, data = line.split(b']') - intf, idn, le = h.split() - t = None - - if self.ifilter is not None and \ - intf.decode('ASCII') not in self.ifilter: - return None - - data = data.replace(b' ', b'') - data = data.strip() - - pkt = CAN(identifier=int(idn, 16), data=binascii.unhexlify(data)) - if le is not None: - pkt.length = int(le[1:]) - else: - pkt.length = len(pkt.data) - - if len(idn) > 3: - pkt.flags = 0b100 - - if t is not None: - pkt.time = t - - return pkt - - def dispatch(self, callback): - """call the specified callback routine for each packet read - - This is just a convenience function for the main loop - that allows for easy launching of packet processing in a - thread. - """ - for p in self: - callback(p) - - def read_all(self, count=-1): - """return a list of all packets in the candump file - """ - res = [] - while count != 0: - try: - p = self.read_packet() - if p is None: - continue - except EOFError: - break - count -= 1 - res.append(p) - return PacketList(res, name=os.path.basename(self.filename)) - - def recv(self, size=MTU): - """ Emulate a socket - """ - return self.read_packet(size=size) - - def fileno(self): - return self.f.fileno() - - def close(self): - return self.f.close() - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, tracback): - self.close() - - # emulate SuperSocket - @staticmethod - def select(sockets, remain=None): - return sockets, None diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/clns.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/clns.py deleted file mode 100644 index 5ffbd86f63..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/clns.py +++ /dev/null @@ -1,83 +0,0 @@ -""" - CLNS Extension - ~~~~~~~~~~~~~~~~~~~~~ - - :copyright: 2014, 2015 BENOCS GmbH, Berlin (Germany) - :author: Marcel Patzlaff, mpatzlaff@benocs.com - :license: GPLv2 - - This module is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This module 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. - - :description: - - This module provides a registration function and a generic PDU - for OSI Connectionless-mode Network Services (such as IS-IS). -""" - -from scapy.config import conf -from scapy.fields import ByteEnumField, PacketField -from scapy.layers.l2 import LLC -from scapy.packet import Packet, bind_top_down, bind_bottom_up -from scapy.compat import orb - -network_layer_protocol_ids = { - 0x00: "Null", - 0x08: "Q.933", - 0x80: "IEEE SNAP", - 0x81: "ISO 8438 CLNP", - 0x82: "ISO 9542 ES-IS", - 0x83: "ISO 10589 IS-IS", - 0x8E: "IPv6", - 0xB0: "FRF.9", - 0xB1: "FRF.12", - 0xC0: "TRILL", - 0xC1: "IEEE 802.aq", - 0xCC: "IPv4", - 0xCF: "PPP" -} - - -_cln_protocols = {} - - -class _GenericClnsPdu(Packet): - name = "Generic CLNS PDU" - fields_desc = [ - ByteEnumField("nlpid", 0x00, network_layer_protocol_ids), - PacketField("rawdata", None, conf.raw_layer) - ] - - -def _create_cln_pdu(s, **kwargs): - pdu_cls = conf.raw_layer - - if len(s) >= 1: - nlpid = orb(s[0]) - pdu_cls = _cln_protocols.get(nlpid, _GenericClnsPdu) - - return pdu_cls(s, **kwargs) - - -@conf.commands.register -def register_cln_protocol(nlpid, cln_protocol_class): - if nlpid is None or cln_protocol_class is None: - return - - chk = _cln_protocols.get(nlpid, None) - if chk is not None and chk != cln_protocol_class: - raise ValueError("different protocol already registered!") - - _cln_protocols[nlpid] = cln_protocol_class - bind_top_down(LLC, cln_protocol_class, dsap=0xfe, ssap=0xfe, ctrl=3) - - -bind_top_down(LLC, _GenericClnsPdu, dsap=0xfe, ssap=0xfe, ctrl=3) -bind_bottom_up(LLC, _create_cln_pdu, dsap=0xfe, ssap=0xfe, ctrl=3) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/dhcp.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/dhcp.py deleted file mode 100644 index 3265f6360b..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/dhcp.py +++ /dev/null @@ -1,437 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -DHCP (Dynamic Host Configuration Protocol) and BOOTP -""" - -from __future__ import absolute_import -from __future__ import print_function -try: - from collections.abc import Iterable -except ImportError: - # For backwards compatibility. This was removed in Python 3.8 - from collections import Iterable -import random -import struct - -from scapy.ansmachine import AnsweringMachine -from scapy.base_classes import Net -from scapy.compat import chb, orb, bytes_encode -from scapy.fields import ByteEnumField, ByteField, Field, FieldListField, \ - FlagsField, IntField, IPField, ShortField, StrField -from scapy.layers.inet import UDP, IP -from scapy.layers.l2 import Ether -from scapy.packet import bind_layers, bind_bottom_up, Packet -from scapy.utils import atol, itom, ltoa, sane -from scapy.volatile import RandBin, RandField, RandNum, RandNumExpo - -from scapy.arch import get_if_raw_hwaddr -from scapy.sendrecv import srp1, sendp -from scapy.error import warning -import scapy.modules.six as six -from scapy.modules.six.moves import range -from scapy.config import conf - -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 # noqa: E501 - payload = self.options[len(dhcpmagic):] - self.options = self.options[:len(dhcpmagic)] - return payload, None - else: - return b"", None - - def hashret(self): - return struct.pack("!I", self.xid) - - def answers(self, other): - if not isinstance(other, BOOTP): - return 0 - return self.xid == other.xid - - -class _DHCPParamReqFieldListField(FieldListField): - def getfield(self, pkt, s): - ret = [] - while s: - s, val = FieldListField.getfield(self, pkt, s) - ret.append(val) - return b"", [x[0] for x in ret] - -# 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"), - 10: IPField("impress-servers", "0.0.0.0"), - 11: IPField("resource-location-servers", "0.0.0.0"), - 12: "hostname", - 13: ShortField("boot-size", 1000), - 14: "dump_path", - 15: "domain", - 16: IPField("swap-server", "0.0.0.0"), - 17: "root_disk_path", - 18: "extensions-path", - 19: ByteField("ip-forwarding", 0), - 20: ByteField("non-local-source-routing", 0), - 21: IPField("policy-filter", "0.0.0.0"), - 22: "max_dgram_reass_size", - 23: "default_ttl", - 24: "pmtu_timeout", - 25: ShortField("path-mtu-plateau-table", 1000), - 26: ShortField("interface-mtu", 50), - 27: ByteField("all-subnets-local", 0), - 28: IPField("broadcast_address", "0.0.0.0"), - 29: ByteField("perform-mask-discovery", 0), - 30: ByteField("mask-supplier", 0), - 31: ByteField("router-discovery", 0), - 32: IPField("router-solicitation-address", "0.0.0.0"), - 33: IPField("static-routes", "0.0.0.0"), - 34: ByteField("trailer-encapsulation", 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"), - 46: ByteField("static-routes", 100), - 47: "netbios-scope", - 48: IPField("font-servers", "0.0.0.0"), - 49: IPField("x-display-manager", "0.0.0.0"), - 50: IPField("requested_addr", "0.0.0.0"), - 51: IntField("lease_time", 43200), - 52: ByteField("dhcp-option-overload", 100), - 53: ByteEnumField("message-type", 1, DHCPTypes), - 54: IPField("server_id", "0.0.0.0"), - 55: _DHCPParamReqFieldListField("param_req_list", [], ByteField("opcode", 0), length_from=lambda x: 1), # noqa: E501 - 56: "error_message", - 57: ShortField("max_dhcp_size", 1500), - 58: IntField("renewal_time", 21600), - 59: IntField("rebinding_time", 37800), - 60: "vendor_class_id", - 61: "client_id", - 62: "nwip-domain-name", - 64: "NISplus_domain", - 65: IPField("NISplus_server", "0.0.0.0"), - 67: StrField("boot-file-name", ""), - 68: IPField("mobile-ip-home-agent", "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", - 81: "client_FQDN", - 82: "relay_agent_Information", - 91: IntField("client-last-transaction-time", 1000), - 92: IPField("associated-ip", "0.0.0.0"), - 118: IPField("subnet-selection", "0.0.0.0"), - 255: "end" -} - -DHCPRevOptions = {} - -for k, v in six.iteritems(DHCPOptions): - if isinstance(v, 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(six.itervalues(DHCPOptions)) - self._opts.remove("pad") - self._opts.remove("end") - - def _fix(self): - op = [] - for k in range(self.size): - o = random.choice(self._opts) - if isinstance(o, 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 isinstance(v, tuple) and len(v) >= 2: - if v[0] in DHCPRevOptions and isinstance(DHCPRevOptions[v[0]][1], Field): # noqa: E501 - 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 = orb(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) < orb(x[1]) + 2: - opt.append(x) - break - elif o in DHCPOptions: - f = DHCPOptions[o] - - if isinstance(f, str): - olen = orb(x[1]) - opt.append((f, x[2:olen + 2])) - x = x[olen + 2:] - else: - olen = orb(x[1]) - lval = [f.name] - try: - left = x[2:olen + 2] - while left: - left, val = f.getfield(pkt, left) - lval.append(val) - except Exception: - opt.append(x) - break - else: - otuple = tuple(lval) - opt.append(otuple) - x = x[olen + 2:] - else: - olen = orb(x[1]) - opt.append((o, x[2:olen + 2])) - x = x[olen + 2:] - return opt - - def i2m(self, pkt, x): - if isinstance(x, str): - return x - s = b"" - for o in x: - if isinstance(o, 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) # noqa: E501 - else: - lval = (bytes_encode(x) for x in lval) - oval = b"".join(lval) - else: - warning("Unknown field option %s", name) - continue - - s += chb(onum) - s += chb(len(oval)) - s += oval - - elif (isinstance(o, str) and o in DHCPRevOptions and - DHCPRevOptions[o][1] is None): - s += chb(DHCPRevOptions[o][0]) - elif isinstance(o, int): - s += chb(o) + b"\0" - elif isinstance(o, (str, bytes)): - s += bytes_encode(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') - - -@conf.commands.register -def dhcp_request(iface=None, **kargs): - """Send a DHCP discover request and return the answer""" - if conf.checkIPaddr: - warning( - "conf.checkIPaddr is enabled, may not be able to match the answer" - ) - if iface is None: - iface = conf.iface - fam, 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) / # noqa: E501 - BOOTP(chaddr=hw) / DHCP(options=[("message-type", "discover"), "end"]), iface=iface, **kargs) # noqa: E501 - - -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", # noqa: E501 - domain="localnet", renewal_time=60, lease_time=1800): - 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, six.string_types): - pool = Net(pool) - if isinstance(pool, Iterable): - pool = [k for k in pool if k not in [gw, self.network, self.broadcast]] # noqa: E501 - 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[Ether].src - if isinstance(self.pool, list): - if mac not 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 # noqa: E501 - 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 isinstance(op, tuple) and op[0] == "message-type"] # noqa: E501 - 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-2.4.3/scapy/layers/dhcp6.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/dhcp6.py deleted file mode 100644 index 136ca4ff52..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/dhcp6.py +++ /dev/null @@ -1,1871 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -# Copyright (C) 2005 Guillaume Valadon -# Arnaud Ebalard - -""" -DHCPv6: Dynamic Host Configuration Protocol for IPv6. [RFC 3315] -""" - -from __future__ import print_function -import socket -import struct -import time - -from scapy.ansmachine import AnsweringMachine -from scapy.arch import get_if_raw_hwaddr, in6_getifaddr -from scapy.config import conf -from scapy.data import EPOCH, ETHER_ANY -from scapy.compat import raw, orb, chb -from scapy.error import warning -from scapy.fields import BitField, ByteEnumField, ByteField, FieldLenField, \ - FlagsField, IntEnumField, IntField, MACField, PacketField, \ - PacketListField, ShortEnumField, ShortField, StrField, StrFixedLenField, \ - StrLenField, UTCTimeField, X3BytesField, XIntField, XShortEnumField, \ - PacketLenField, UUIDField, FieldListField -from scapy.layers.inet import UDP -from scapy.layers.inet6 import DomainNameListField, IP6Field, IP6ListField, \ - IPv6 -from scapy.packet import Packet, bind_bottom_up -from scapy.pton_ntop import inet_pton -from scapy.sendrecv import send -from scapy.themes import Color -from scapy.utils6 import in6_addrtovendor, in6_islladdr -import scapy.modules.six as six - -############################################################################# -# Helpers ## -############################################################################# - - -def get_cls(name, fallback_cls): - return globals().get(name, fallback_cls) - - -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(orb(x[0]), "Raw"), conf.raw_layer) - return cls(x, *args, **kargs) - -############################################################################# -############################################################################# -# 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 - 40: "OPTION_PANA_AGENT", # RFC5192 - 41: "OPTION_NEW_POSIX_TIMEZONE", # RFC4833 - 42: "OPTION_NEW_TZDB_TIMEZONE", # RFC4833 - 48: "OPTION_LQ_CLIENT_LINK", # RFC5007 - 59: "OPT_BOOTFILE_URL", # RFC5970 - 60: "OPT_BOOTFILE_PARAM", # RFC5970 - 61: "OPTION_CLIENT_ARCH_TYPE", # RFC5970 - 62: "OPTION_NII", # RFC5970 - 65: "OPTION_ERP_LOCAL_DOMAIN_NAME", # RFC6440 - 66: "OPTION_RELAY_SUPPLIED_OPTIONS", # RFC6422 - 68: "OPTION_VSS", # RFC6607 - 79: "OPTION_CLIENT_LINKLAYER_ADDR"} # RFC6939 - -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 # noqa: E501 - 37: "DHCP6OptRemoteID", # RFC4649 - 38: "DHCP6OptSubscriberID", # RFC4580 - 39: "DHCP6OptClientFQDN", # RFC4704 - 40: "DHCP6OptPanaAuthAgent", # RFC-ietf-dhc-paa-option-05.txt # noqa: E501 - 41: "DHCP6OptNewPOSIXTimeZone", # RFC4833 - 42: "DHCP6OptNewTZDBTimeZone", # RFC4833 - 43: "DHCP6OptRelayAgentERO", # RFC4994 - # 44: "DHCP6OptLQQuery", #RFC5007 - # 45: "DHCP6OptLQClientData", #RFC5007 - # 46: "DHCP6OptLQClientTime", #RFC5007 - # 47: "DHCP6OptLQRelayData", #RFC5007 - 48: "DHCP6OptLQClientLink", # RFC5007 - 59: "DHCP6OptBootFileUrl", # RFC5790 - 60: "DHCP6OptBootFileParam", # RFC5970 - 61: "DHCP6OptClientArchType", # RFC5970 - 62: "DHCP6OptClientNetworkInterId", # RFC5970 - 65: "DHCP6OptERPDomain", # RFC6440 - 66: "DHCP6OptRelaySuppliedOpt", # RFC6422 - 68: "DHCP6OptVSS", # RFC6607 - 79: "DHCP6OptClientLinkLayerAddr", # RFC6939 - } - - -# 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", - 4: "UUID"} - -# 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(UTCTimeField): - def __init__(self, *args, **kargs): - epoch_2000 = (2000, 1, 1, 0, 0, 0, 5, 1, 0) # required Epoch - UTCTimeField.__init__(self, epoch=epoch_2000, *args, **kargs) - - -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/assignments/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", "")] - - -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)] - - -class DUID_UUID(Packet): # RFC 6355 - name = "DUID - Based on UUID" - fields_desc = [ShortEnumField("type", 4, duidtypes), - UUIDField("uuid", None, uuid_fmt=UUIDField.FORMAT_BE)] - - -duid_cls = {1: "DUID_LLT", - 2: "DUID_EN", - 3: "DUID_LL", - 4: "DUID_UUID"} - -##################################################################### -# DHCPv6 Options classes # -##################################################################### - - -class _DHCP6OptGuessPayload(Packet): - @classmethod - def _just_guess_payload_class(cls, payload): - # try to guess what option is in the 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 - - def guess_payload_class(self, payload): - # this method is used in case of all derived classes - # from _DHCP6OptGuessPayload in this file - cls = _DHCP6OptGuessPayload._just_guess_payload_class(payload) - return cls - - @classmethod - def dispatch_hook(cls, payload=None, *args, **kargs): - # this classmethod is used in case of list of different suboptions - # e.g. in ianaopts in DHCP6OptIA_NA - cls_ = cls._just_guess_payload_class(payload) - 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", "", - length_from=lambda pkt: pkt.optlen)] - - -class _DUIDField(PacketField): - __slots__ = ["length_from"] - - def __init__(self, name, default, length_from=None): - StrField.__init__(self, name, default) - self.length_from = length_from - - def i2m(self, pkt, i): - return raw(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): - tmp_len = self.length_from(pkt) - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - - -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), - StrLenField("iaaddropts", "", - length_from=lambda pkt: pkt.optlen - 24)] - - def guess_payload_class(self, payload): - return conf.padding_layer - - -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), - PacketListField("ianaopts", [], _DHCP6OptGuessPayload, - length_from=lambda pkt: pkt.optlen - 12)] - - -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), - PacketListField("iataopts", [], _DHCP6OptGuessPayload, - 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") # noqa: E501 - return r - r.append(struct.unpack("!H", x[:2])[0]) - x = x[2:] - return r - - def i2m(self, pkt, x): - return b"".join(struct.pack('!H', y) for y in 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"), # noqa: E501 - _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 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", "A" * 8, 8), # TODO: XXX - StrLenField("authinfo", "", - 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", "", - 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(len(raw(x)) for x in z) - - def getfield(self, pkt, s): - tmp_len = self.length_from(pkt) - lst = [] - remain, payl = s[:tmp_len], s[tmp_len:] - 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 USER_CLASS_DATA(Packet): - name = "user class data" - fields_desc = [FieldLenField("len", None, length_of="data"), - StrLenField("data", "", - 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)] # noqa: E501 - -# 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", "", - 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)] # noqa: E501 - -# 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", "", - 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 Information-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)] - - -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 + 25), - 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 # noqa: E501 - StrLenField("iaprefopts", "", - length_from=lambda pkt: pkt.optlen - 25)] - - -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", - fmt="!H", adjust=lambda pkt, x: x + 12), - XIntField("iaid", None), - IntField("T1", None), - IntField("T2", None), - PacketListField("iapdopt", [], _DHCP6OptGuessPayload, - 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): - tmp_len = self.length_from(pkt) - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - - def i2len(self, pkt, x): - return len(self.i2m(pkt, x)) - - def m2i(self, pkt, x): - cur = [] - while x: - tmp_len = orb(x[0]) - cur.append(x[1:1 + tmp_len]) - x = x[tmp_len + 1:] - return b".".join(cur) - - def i2m(self, pkt, x): - if not x: - return b"" - return b"".join(chb(len(z)) + z for z in x.split(b'.')) - - -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 # noqa: E501 - 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", "", - 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", "", - 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 DHCP6OptPanaAuthAgent(_DHCP6OptGuessPayload): # RFC5192 - name = "DHCP6 PANA Authentication Agent Option" - fields_desc = [ShortEnumField("optcode", 40, dhcp6opts), - FieldLenField("optlen", None, length_of="paaaddr"), - IP6ListField("paaaddr", [], - length_from=lambda pkt: pkt.optlen)] - - -class DHCP6OptNewPOSIXTimeZone(_DHCP6OptGuessPayload): # RFC4833 - name = "DHCP6 POSIX Timezone Option" - fields_desc = [ShortEnumField("optcode", 41, dhcp6opts), - FieldLenField("optlen", None, length_of="optdata"), - StrLenField("optdata", "", - length_from=lambda pkt: pkt.optlen)] - - -class DHCP6OptNewTZDBTimeZone(_DHCP6OptGuessPayload): # RFC4833 - name = "DHCP6 TZDB Timezone Option" - fields_desc = [ShortEnumField("optcode", 42, dhcp6opts), - FieldLenField("optlen", None, length_of="optdata"), - StrLenField("optdata", "", - length_from=lambda pkt: pkt.optlen)] - - -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)] - - -class DHCP6OptLQClientLink(_DHCP6OptGuessPayload): # RFC5007 - name = "DHCP6 Client Link Option" - fields_desc = [ShortEnumField("optcode", 48, dhcp6opts), - FieldLenField("optlen", None, length_of="linkaddress"), - IP6ListField("linkaddress", [], - length_from=lambda pkt: pkt.optlen)] - - -class DHCP6OptBootFileUrl(_DHCP6OptGuessPayload): # RFC5970 - name = "DHCP6 Boot File URL Option" - fields_desc = [ShortEnumField("optcode", 59, dhcp6opts), - FieldLenField("optlen", None, length_of="optdata"), - StrLenField("optdata", "", - length_from=lambda pkt: pkt.optlen)] - - -class DHCP6OptClientArchType(_DHCP6OptGuessPayload): # RFC5970 - name = "DHCP6 Client System Architecture Type Option" - fields_desc = [ShortEnumField("optcode", 61, dhcp6opts), - FieldLenField("optlen", None, length_of="archtypes", - fmt="!H"), - FieldListField("archtypes", [], - ShortField("archtype", 0), - length_from=lambda pkt: pkt.optlen)] - - -class DHCP6OptClientNetworkInterId(_DHCP6OptGuessPayload): # RFC5970 - name = "DHCP6 Client Network Interface Identifier Option" - fields_desc = [ShortEnumField("optcode", 62, dhcp6opts), - ShortField("optlen", 3), - ByteField("iitype", 0), - ByteField("iimajor", 0), - ByteField("iiminor", 0)] - - -class DHCP6OptERPDomain(_DHCP6OptGuessPayload): # RFC6440 - name = "DHCP6 Option - ERP Domain Name List" - fields_desc = [ShortEnumField("optcode", 65, dhcp6opts), - FieldLenField("optlen", None, length_of="erpdomain"), - DomainNameListField("erpdomain", [], - length_from=lambda pkt: pkt.optlen)] - - -class DHCP6OptRelaySuppliedOpt(_DHCP6OptGuessPayload): # RFC6422 - name = "DHCP6 Relay-Supplied Options Option" - fields_desc = [ShortEnumField("optcode", 66, dhcp6opts), - FieldLenField("optlen", None, length_of="relaysupplied", - fmt="!H"), - PacketListField("relaysupplied", [], _DHCP6OptGuessPayload, - length_from=lambda pkt: pkt.optlen)] - - -# Virtual Subnet selection -class DHCP6OptVSS(_DHCP6OptGuessPayload): # RFC6607 - name = "DHCP6 Option - Virtual Subnet Selection" - fields_desc = [ShortEnumField("optcode", 68, dhcp6opts), - FieldLenField("optlen", None, length_of="data", - adjust=lambda pkt, x: x + 1), - ByteField("type", 255), # Default Global/default table - StrLenField("data", "", - length_from=lambda pkt: pkt.optlen)] - - -# "Client link-layer address type. The link-layer type MUST be a valid hardware # noqa: E501 -# type assigned by the IANA, as described in [RFC0826] -class DHCP6OptClientLinkLayerAddr(_DHCP6OptGuessPayload): # RFC6939 - name = "DHCP6 Option - Client Link Layer address" - fields_desc = [ShortEnumField("optcode", 79, dhcp6opts), - FieldLenField("optlen", None, length_of="clladdr", - adjust=lambda pkt, x: x + 2), - ShortField("lltype", 1), # ethernet - _LLAddrField("clladdr", ETHER_ANY)] - - -##################################################################### -# 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) - -##################################################################### -# 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] - -# 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), - FieldLenField("optlen", None, fmt="!H", - length_of="message"), - PacketLenField("message", DHCP6(), _dhcp6_dispatcher, - length_from=lambda p: p.optlen)] - -##################################################################### -# 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 -# containing 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 client 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_Solicit, 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(_DHCP6OptGuessPayload, Packet): - name = "DHCPv6 Relay Forward Message (Relay Agent/Server Message)" - fields_desc = [ByteEnumField("msgtype", 12, dhcp6types), - ByteField("hopcount", None), - IP6Field("linkaddr", "::"), - IP6Field("peeraddr", "::")] - overload_fields = {UDP: {"sport": 547, "dport": 547}} - - 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 message 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) - - -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 = """ -DHCPv6_am.parse_options( 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, - bcmcsdomains=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 isinstance(val, list): - return val - elif isinstance(val, str): - tmp_len = val.split(',') - return [x.strip() for x in tmp_len] - 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)), # noqa: E501 - (sntpservers, "sntpservers", 31, lambda x: DHCP6OptSNTPServers(sntpservers=x)), # noqa: E501 - (sipservers, "sipservers", 22, lambda x: DHCP6OptSIPServers(sipservers=x)), # noqa: E501 - (sipdomains, "sipdomains", 21, lambda x: DHCP6OptSIPDomains(sipdomains=x)), # noqa: E501 - (nisservers, "nisservers", 27, lambda x: DHCP6OptNISServers(nisservers=x)), # noqa: E501 - (nisdomain, "nisdomain", 29, lambda x: DHCP6OptNISDomain(nisdomain=(x + [""])[0])), # noqa: E501 - (nispservers, "nispservers", 28, lambda x: DHCP6OptNISPServers(nispservers=x)), # noqa: E501 - (nispdomain, "nispdomain", 30, lambda x: DHCP6OptNISPDomain(nispdomain=(x + [""])[0])), # noqa: E501 - (bcmcsservers, "bcmcsservers", 33, lambda x: DHCP6OptBCMCSServers(bcmcsservers=x)), # noqa: E501 - (bcmcsdomains, "bcmcsdomains", 34, lambda x: DHCP6OptBCMCSDomains(bcmcsdomains=x))]: # noqa: E501 - - 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 = sorted(self.dhcpv6_options) - 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 - epoch = (2000, 1, 1, 0, 0, 0, 5, 1, 0) - delta = time.mktime(epoch) - EPOCH - timeval = time.time() - delta - - # Mac Address - rawmac = get_if_raw_hwaddr(iface)[1] - mac = ":".join("%.02x" % orb(x) for x in 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 - try: - addr = next(x for x in in6_getifaddr() if x[2] == iface and in6_islladdr(x[0])) # noqa: E501 - except (StopIteration, RuntimeError): - warning("Unable to get a Link-Local address") - return - else: - self.src_addr = addr[0] - - #### - # Our leases - self.leases = {} - - if self.debug: - print("\n[+] Starting DHCPv6 service on %s:" % self.iface) - - def is_request(self, p): - if IPv6 not in p: - return False - - src = p[IPv6].src - - 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 ((DHCP6OptClientId not 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 ((DHCP6OptServerId not in p) or - (DHCP6OptClientId not in p)): - return False - # provided server DUID must match ours - duid = p[DHCP6OptServerId].duid - if not isinstance(duid, type(self.duid)): - return False - if raw(duid) != raw(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: - lst = [] - if isinstance(it, DHCP6OptIA_NA): - lst = it.ianaopts - elif isinstance(it, DHCP6OptIA_TA): - lst = it.iataopts - - addrs += [x.addr for x in lst if isinstance(x, DHCP6OptIAAddress)] # noqa: E501 - it = it.payload - - addrs = [bo + x + n for x in addrs] - if self.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 not isinstance(duid, type(self.duid)): - return False - if raw(duid) != raw(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)) # noqa: E501 - - def make_reply(self, req): - p = req[IPv6] - req_src = p.src - - p = p.payload.payload - - msgtype = p.msgtype - trid = p.trid - - def _include_options(query, answer): - """ - Include options from the DHCPv6 query - """ - - # See which options should be included - reqopts = [] - if query.haslayer(DHCP6OptOptReq): # add only asked ones - reqopts = query[DHCP6OptOptReq].reqopts - for o, opt in six.iteritems(self.dhcpv6_options): - if o in reqopts: - answer /= opt - else: - # advertise everything we have available - # Should not happen has clients MUST include - # and ORO in requests (sec 18.1.1) -- arno - for o, opt in six.iteritems(self.dhcpv6_options): - answer /= opt - - 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() - - _include_options(p, resp) - - 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) - - _include_options(p, resp) - - 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") # noqa: E501 - 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 - for o, opt in six.iteritems(self.dhcpv6_options): - resp /= opt - - 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-2.4.3/scapy/layers/dns.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/dns.py deleted file mode 100644 index 8e7835df4a..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/dns.py +++ /dev/null @@ -1,969 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -DNS: Domain Name System. -""" - -from __future__ import absolute_import -import struct -import time - -from scapy.config import conf -from scapy.packet import Packet, bind_layers, NoPayload -from scapy.fields import BitEnumField, BitField, ByteEnumField, ByteField, \ - ConditionalField, FieldLenField, FlagsField, IntField, \ - PacketListField, ShortEnumField, ShortField, StrField, StrFixedLenField, \ - StrLenField, MultipleTypeField, UTCTimeField -from scapy.compat import orb, raw, chb, bytes_encode -from scapy.ansmachine import AnsweringMachine -from scapy.sendrecv import sr1 -from scapy.layers.inet import IP, DestIPField, IPField, UDP, TCP -from scapy.layers.inet6 import DestIP6Field, IP6Field -from scapy.error import warning, Scapy_Exception -import scapy.modules.six as six -from scapy.modules.six.moves import range - - -def dns_get_str(s, pointer=0, pkt=None, _fullpacket=False): - """This function decompresses a string s, starting - from the given pointer. - - :param s: the string to decompress - :param pointer: first pointer on the string (default: 0) - :param pkt: (optional) an InheritOriginDNSStrPacket packet - - :returns: (decoded_string, end_index, left_string) - """ - # The _fullpacket parameter is reserved for scapy. It indicates - # that the string provided is the full dns packet, and thus - # will be the same than pkt._orig_str. The "Cannot decompress" - # error will not be prompted if True. - max_length = len(s) - # The result = the extracted name - name = b"" - # Will contain the index after the pointer, to be returned - after_pointer = None - processed_pointers = [] # Used to check for decompression loops - # Analyse given pkt - if pkt and hasattr(pkt, "_orig_s") and pkt._orig_s: - s_full = pkt._orig_s - else: - s_full = None - bytes_left = None - while True: - if abs(pointer) >= max_length: - warning("DNS RR prematured end (ofs=%i, len=%i)" % (pointer, - len(s))) - break - cur = orb(s[pointer]) # get pointer value - pointer += 1 # make pointer go forward - if cur & 0xc0: # Label pointer - if after_pointer is None: - # after_pointer points to where the remaining bytes start, - # as pointer will follow the jump token - after_pointer = pointer + 1 - if pointer >= max_length: - warning("DNS incomplete jump token at (ofs=%i)" % pointer) - break - # Follow the pointer - pointer = ((cur & ~0xc0) << 8) + orb(s[pointer]) - 12 - if pointer in processed_pointers: - warning("DNS decompression loop detected") - break - if not _fullpacket: - # Do we have access to the whole packet ? - if s_full: - # Yes -> use it to continue - bytes_left = s[after_pointer:] - s = s_full - max_length = len(s) - _fullpacket = True - else: - # No -> abort - raise Scapy_Exception("DNS message can't be compressed" + - "at this point!") - processed_pointers.append(pointer) - continue - elif cur > 0: # Label - # cur = length of the string - name += s[pointer:pointer + cur] + b"." - pointer += cur - else: - break - if after_pointer is not None: - # Return the real end index (not the one we followed) - pointer = after_pointer - if bytes_left is None: - bytes_left = s[pointer:] - # name, end_index, remaining - return name, pointer, bytes_left - - -def dns_encode(x, check_built=False): - """Encodes a bytes string into the DNS format - - :param x: the string - :param check_built: detect already-built strings and ignore them - :returns: the encoded bytes string - """ - if not x or x == b".": - return b"\x00" - - if check_built and b"." not in x and ( - orb(x[-1]) == 0 or (orb(x[-2]) & 0xc0) == 0xc0 - ): - # The value has already been processed. Do not process it again - return x - - # Truncate chunks that cannot be encoded (more than 63 bytes..) - x = b"".join(chb(len(y)) + y for y in (k[:63] for k in x.split(b"."))) - if x[-1:] != b"\x00": - x += b"\x00" - return x - - -def DNSgetstr(*args, **kwargs): - """Legacy function. Deprecated""" - warning("DNSgetstr deprecated. Use dns_get_str instead") - return dns_get_str(*args, **kwargs) - - -def dns_compress(pkt): - """This function compresses a DNS packet according to compression rules. - """ - if DNS not in pkt: - raise Scapy_Exception("Can only compress DNS layers") - pkt = pkt.copy() - dns_pkt = pkt.getlayer(DNS) - build_pkt = raw(dns_pkt) - - def field_gen(dns_pkt): - """Iterates through all DNS strings that can be compressed""" - for lay in [dns_pkt.qd, dns_pkt.an, dns_pkt.ns, dns_pkt.ar]: - if lay is None: - continue - current = lay - while not isinstance(current, NoPayload): - if isinstance(current, InheritOriginDNSStrPacket): - for field in current.fields_desc: - if isinstance(field, DNSStrField) or \ - (isinstance(field, MultipleTypeField) and - current.type in [2, 3, 4, 5, 12, 15]): - # Get the associated data and store it accordingly # noqa: E501 - dat = current.getfieldval(field.name) - yield current, field.name, dat - current = current.payload - - def possible_shortens(dat): - """Iterates through all possible compression parts in a DNS string""" - yield dat - for x in range(1, dat.count(b".")): - yield dat.split(b".", x)[x] - data = {} - burned_data = 0 - for current, name, dat in field_gen(dns_pkt): - for part in possible_shortens(dat): - # Encode the data - encoded = dns_encode(part, check_built=True) - if part not in data: - # We have no occurrence of such data, let's store it as a - # possible pointer for future strings. - # We get the index of the encoded data - index = build_pkt.index(encoded) - index -= burned_data - # The following is used to build correctly the pointer - fb_index = ((index >> 8) | 0xc0) - sb_index = index - (256 * (fb_index - 0xc0)) - pointer = chb(fb_index) + chb(sb_index) - data[part] = [(current, name, pointer)] - else: - # This string already exists, let's mark the current field - # with it, so that it gets compressed - data[part].append((current, name)) - # calculate spared space - burned_data += len(encoded) - 2 - break - # Apply compression rules - for ck in data: - # compression_key is a DNS string - replacements = data[ck] - # replacements is the list of all tuples (layer, field name) - # where this string was found - replace_pointer = replacements.pop(0)[2] - # replace_pointer is the packed pointer that should replace - # those strings. Note that pop remove it from the list - for rep in replacements: - # setfieldval edits the value of the field in the layer - val = rep[0].getfieldval(rep[1]) - assert val.endswith(ck) - kept_string = dns_encode(val[:-len(ck)], check_built=True)[:-1] - new_val = kept_string + replace_pointer - rep[0].setfieldval(rep[1], new_val) - try: - del(rep[0].rdlen) - except AttributeError: - pass - # End of the compression algorithm - # Destroy the previous DNS layer if needed - if not isinstance(pkt, DNS) and pkt.getlayer(DNS).underlayer: - pkt.getlayer(DNS).underlayer.remove_payload() - return pkt / dns_pkt - return dns_pkt - - -class InheritOriginDNSStrPacket(Packet): - __slots__ = Packet.__slots__ + ["_orig_s", "_orig_p"] - - def __init__(self, _pkt=None, _orig_s=None, _orig_p=None, *args, **kwargs): - self._orig_s = _orig_s - self._orig_p = _orig_p - Packet.__init__(self, _pkt=_pkt, *args, **kwargs) - - -class DNSStrField(StrLenField): - """ - Special StrField that handles DNS encoding/decoding. - It will also handle DNS decompression. - (may be StrLenField if a length_from is passed), - """ - - def h2i(self, pkt, x): - if not x: - return b"." - return x - - def i2m(self, pkt, x): - return dns_encode(x, check_built=True) - - def i2len(self, pkt, x): - return len(self.i2m(pkt, x)) - - def getfield(self, pkt, s): - remain = b"" - if self.length_from: - remain, s = StrLenField.getfield(self, pkt, s) - # Decode the compressed DNS message - decoded, _, left = dns_get_str(s, 0, pkt) - # returns (remaining, decoded) - return left + remain, decoded - - -class DNSRRCountField(ShortField): - __slots__ = ["rr"] - - 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 - - -class DNSRRField(StrField): - __slots__ = ["countfld", "passon"] - 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_encode(x) - - def decodeRR(self, name, s, p): - ret = s[p:p + 10] - # type, cls, ttl, rdlen - typ, cls, _, rdlen = struct.unpack("!HHIH", ret) - p += 10 - cls = DNSRR_DISPATCHER.get(typ, DNSRR) - rr = cls(b"\x00" + ret + s[p:p + rdlen], _orig_s=s, _orig_p=p) - # Will have changed because of decompression - rr.rdlen = None - rr.rrname = name - - p += rdlen - return rr, p - - def getfield(self, pkt, s): - if isinstance(s, 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, _ = dns_get_str(s, p, _fullpacket=True) - 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): - def decodeRR(self, name, s, p): - ret = s[p:p + 4] - p += 4 - rr = DNSQR(b"\x00" + ret, _orig_s=s, _orig_p=p) - rr.qname = name - return rr, p - - -class DNSTextField(StrLenField): - """ - Special StrLenField that handles DNS TEXT data (16) - """ - - islist = 1 - - def m2i(self, pkt, s): - ret_s = list() - 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 = orb(tmp_s[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))) # noqa: E501 - ret_s.append(tmp_s[1:tmp_len]) - tmp_s = tmp_s[tmp_len:] - return ret_s - - def any2i(self, pkt, x): - if isinstance(x, (str, bytes)): - return [x] - return x - - def i2len(self, pkt, x): - return len(self.i2m(pkt, x)) - - def i2m(self, pkt, s): - ret_s = b"" - for text in s: - text = bytes_encode(text) - # The initial string must be split into a list of strings - # prepended with theirs sizes. - while len(text) >= 255: - ret_s += b"\xff" + text[:255] - text = text[255:] - # The remaining string is less than 255 bytes long - if len(text): - ret_s += struct.pack("!B", len(text)) + text - return ret_s - - -class DNS(Packet): - name = "DNS" - fields_desc = [ - ConditionalField(ShortField("length", None), - lambda p: isinstance(p.underlayer, TCP)), - 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", 1, 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.rdata - else: - type = "Qry" - if self.qdcount > 0 and isinstance(self.qd, DNSQR): - name = ' "%s"' % self.qd.qname - return 'DNS %s%s ' % (type, name) - - def post_build(self, pkt, pay): - if isinstance(self.underlayer, TCP) and self.length is None: - pkt = struct.pack("!H", len(pkt) - 2) + pkt[2:] - return pkt + pay - - def compress(self): - """Return the compressed DNS packet (using `dns_compress()`""" - return dns_compress(self) - - -# https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4 -dnstypes = { - 0: "ANY", - 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", 19: "X25", 20: "ISDN", 21: "RT", # noqa: E501 - 22: "NSAP", 23: "NSAP-PTR", 24: "SIG", 25: "KEY", 26: "PX", 27: "GPOS", - 28: "AAAA", 29: "LOC", 30: "NXT", 31: "EID", 32: "NIMLOC", 33: "SRV", - 34: "ATMA", 35: "NAPTR", 36: "KX", 37: "CERT", 38: "A6", 39: "DNAME", - 40: "SINK", 41: "OPT", 42: "APL", 43: "DS", 44: "SSHFP", 45: "IPSECKEY", - 46: "RRSIG", 47: "NSEC", 48: "DNSKEY", 49: "DHCID", 50: "NSEC3", - 51: "NSEC3PARAM", 52: "TLSA", 53: "SMIMEA", 55: "HIP", 56: "NINFO", 57: "RKEY", # noqa: E501 - 58: "TALINK", 59: "CDS", 60: "CDNSKEY", 61: "OPENPGPKEY", 62: "CSYNC", - 99: "SPF", 100: "UINFO", 101: "UID", 102: "GID", 103: "UNSPEC", 104: "NID", - 105: "L32", 106: "L64", 107: "LP", 108: "EUI48", 109: "EUI64", - 249: "TKEY", 250: "TSIG", 256: "URI", 257: "CAA", 258: "AVC", - 32768: "TA", 32769: "DLV", 65535: "RESERVED" -} - -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(InheritOriginDNSStrPacket): - name = "DNS Question Record" - show_indent = 0 - fields_desc = [DNSStrField("qname", "www.example.com"), - 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"}), # noqa: E501 - FieldLenField("optlen", None, "optdata", fmt="H"), - StrLenField("optdata", "", length_from=lambda pkt: pkt.optlen)] # noqa: E501 - - def extract_padding(self, p): - return "", p - - -class DNSRROPT(InheritOriginDNSStrPacket): - name = "DNS OPT Resource Record" - fields_desc = [DNSStrField("rrname", ""), - 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)] # noqa: E501 - -# 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 # noqa: E501 -dnssecalgotypes = {0: "Reserved", 1: "RSA/MD5", 2: "Diffie-Hellman", 3: "DSA/SHA-1", # noqa: E501 - 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", # noqa: E501 - 252: "Reserved for Indirect Keys", 253: "Private algorithms - domain name", # noqa: E501 - 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"} # noqa: E501 - - -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 = orb(bitmap[0]) # window number - offset = 256 * window_block # offset of the Resource Record - bitmap_len = orb(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 orb(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 = [abs(x) for x in sorted(set(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 = sorted(x for x in lst if 256 * wb <= x < 256 * (wb + 1)) - if not rrlist: - continue - - # Compute the number of bytes used to store the bitmap - if rrlist[-1] == 0: # only one element in the list - bytes_count = 1 - else: - max = rrlist[-1] - 256 * wb - bytes_count = int(math.ceil(max // 8)) + 1 # use at least 1 byte - if bytes_count > 32: # Don't encode more than 256 bits / values - bytes_count = 32 - - bitmap += struct.pack("BB", wb, bytes_count) - - # Generate the bitmap - # The idea is to remove out of range Resource Records with these steps - # 1. rescale to fit into 8 bits - # 2. x gives the bit position ; compute the corresponding value - # 3. sum everything - bitmap += b"".join( - struct.pack( - b"B", - sum(2 ** (7 - (x - 256 * wb) + (tmp * 8)) for x in rrlist - if 256 * wb + 8 * tmp <= x < 256 * wb + 8 * tmp + 8), - ) for tmp in range(bytes_count) - ) - - return bitmap - - -class RRlistField(StrField): - def h2i(self, pkt, x): - if isinstance(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] if rrlist else repr(x) - - -class _DNSRRdummy(InheritOriginDNSStrPacket): - name = "Dummy class that implements post_build() for Resource Records" - - def post_build(self, pkt, pay): - if self.rdlen is not None: - return pkt + pay - - lrrname = len(self.fields_desc[0].i2m("", self.getfieldval("rrname"))) - tmp_len = len(pkt) - lrrname - 10 - tmp_pkt = pkt[:lrrname + 8] - pkt = struct.pack("!H", tmp_len) + pkt[lrrname + 8 + 2:] - - return tmp_pkt + pkt + pay - - -class DNSRRMX(_DNSRRdummy): - name = "DNS MX Resource Record" - fields_desc = [DNSStrField("rrname", ""), - ShortEnumField("type", 6, dnstypes), - ShortEnumField("rclass", 1, dnsclasses), - IntField("ttl", 0), - ShortField("rdlen", None), - ShortField("preference", 0), - DNSStrField("exchange", ""), - ] - - -class DNSRRSOA(_DNSRRdummy): - name = "DNS SOA Resource Record" - fields_desc = [DNSStrField("rrname", ""), - ShortEnumField("type", 6, dnstypes), - ShortEnumField("rclass", 1, dnsclasses), - IntField("ttl", 0), - ShortField("rdlen", None), - DNSStrField("mname", ""), - DNSStrField("rname", ""), - 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", ""), - 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), - UTCTimeField("expiration", 0), - UTCTimeField("inception", 0), - ShortField("keytag", 0), - DNSStrField("signersname", ""), - StrField("signature", "") - ] - - -class DNSRRNSEC(_DNSRRdummy): - name = "DNS NSEC Resource Record" - fields_desc = [DNSStrField("rrname", ""), - ShortEnumField("type", 47, dnstypes), - ShortEnumField("rclass", 1, dnsclasses), - IntField("ttl", 0), - ShortField("rdlen", None), - DNSStrField("nextname", ""), - RRlistField("typebitmaps", "") - ] - - -class DNSRRDNSKEY(_DNSRRdummy): - name = "DNS DNSKEY Resource Record" - fields_desc = [DNSStrField("rrname", ""), - 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", "") - ] - - -class DNSRRDS(_DNSRRdummy): - name = "DNS DS Resource Record" - fields_desc = [DNSStrField("rrname", ""), - 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", "") - ] - - -# 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", ""), - 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", "", length_from=lambda x: x.saltlength), - FieldLenField("hashlength", 0, fmt="!B", length_of="nexthashedownername"), # noqa: E501 - StrLenField("nexthashedownername", "", length_from=lambda x: x.hashlength), # noqa: E501 - RRlistField("typebitmaps", "") - ] - - -class DNSRRNSEC3PARAM(_DNSRRdummy): - name = "DNS NSEC3PARAM Resource Record" - fields_desc = [DNSStrField("rrname", ""), - 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", "", length_from=lambda pkt: pkt.saltlength) # noqa: E501 - ] - -# RFC 2782 - A DNS RR for specifying the location of services (DNS SRV) - - -class DNSRRSRV(_DNSRRdummy): - name = "DNS SRV Resource Record" - fields_desc = [DNSStrField("rrname", ""), - ShortEnumField("type", 33, dnstypes), - ShortEnumField("rclass", 1, dnsclasses), - IntField("ttl", 0), - ShortField("rdlen", None), - ShortField("priority", 0), - ShortField("weight", 0), - ShortField("port", 0), - DNSStrField("target", ""), ] - - -# RFC 2845 - Secret Key Transaction Authentication for DNS (TSIG) -tsig_algo_sizes = {"HMAC-MD5.SIG-ALG.REG.INT": 16, - "hmac-sha1": 20} - - -class TimeSignedField(StrFixedLenField): - def __init__(self, name, default): - StrFixedLenField.__init__(self, name, default, 6) - - def _convert_seconds(self, packed_seconds): - """Unpack the internal representation.""" - seconds = struct.unpack("!H", packed_seconds[:2])[0] - seconds += struct.unpack("!I", packed_seconds[2:])[0] - return seconds - - def h2i(self, pkt, seconds): - """Convert the number of seconds since 1-Jan-70 UTC to the packed - representation.""" - - if seconds is None: - seconds = 0 - - tmp_short = (seconds >> 32) & 0xFFFF - tmp_int = seconds & 0xFFFFFFFF - - return struct.pack("!HI", tmp_short, tmp_int) - - def i2h(self, pkt, packed_seconds): - """Convert the internal representation to the number of seconds - since 1-Jan-70 UTC.""" - - if packed_seconds is None: - return None - - return self._convert_seconds(packed_seconds) - - def i2repr(self, pkt, packed_seconds): - """Convert the internal representation to a nice one using the RFC - format.""" - time_struct = time.gmtime(self._convert_seconds(packed_seconds)) - return time.strftime("%a %b %d %H:%M:%S %Y", time_struct) - - -class DNSRRTSIG(_DNSRRdummy): - name = "DNS TSIG Resource Record" - fields_desc = [DNSStrField("rrname", ""), - ShortEnumField("type", 250, dnstypes), - ShortEnumField("rclass", 1, dnsclasses), - IntField("ttl", 0), - ShortField("rdlen", None), - DNSStrField("algo_name", "hmac-sha1"), - TimeSignedField("time_signed", 0), - ShortField("fudge", 0), - FieldLenField("mac_len", 20, fmt="!H", length_of="mac_data"), # noqa: E501 - StrLenField("mac_data", "", length_from=lambda pkt: pkt.mac_len), # noqa: E501 - ShortField("original_id", 0), - ShortField("error", 0), - FieldLenField("other_len", 0, fmt="!H", length_of="other_data"), # noqa: E501 - StrLenField("other_data", "", length_from=lambda pkt: pkt.other_len) # noqa: E501 - ] - - -DNSRR_DISPATCHER = { - 6: DNSRRSOA, # RFC 1035 - 15: DNSRRMX, # RFC 1035 - 33: DNSRRSRV, # RFC 2782 - 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 - 250: DNSRRTSIG, # RFC 2845 - 32769: DNSRRDLV, # RFC 4431 -} - -DNSSEC_CLASSES = tuple(six.itervalues(DNSRR_DISPATCHER)) - - -def isdnssecRR(obj): - return isinstance(obj, DNSSEC_CLASSES) - - -class DNSRR(InheritOriginDNSStrPacket): - name = "DNS Resource Record" - show_indent = 0 - fields_desc = [DNSStrField("rrname", ""), - ShortEnumField("type", 1, dnstypes), - ShortEnumField("rclass", 1, dnsclasses), - IntField("ttl", 0), - FieldLenField("rdlen", None, length_of="rdata", fmt="H"), - MultipleTypeField( - [ - # A - (IPField("rdata", "0.0.0.0"), - lambda pkt: pkt.type == 1), - # AAAA - (IP6Field("rdata", "::"), - lambda pkt: pkt.type == 28), - # NS, MD, MF, CNAME, PTR - (DNSStrField("rdata", "", - length_from=lambda pkt: pkt.rdlen), - lambda pkt: pkt.type in [2, 3, 4, 5, 12]), - # TEXT - (DNSTextField("rdata", [], - length_from=lambda pkt: pkt.rdlen), - lambda pkt: pkt.type == 16), - ], - StrLenField("rdata", "", - length_from=lambda pkt:pkt.rdlen) - )] - - -bind_layers(UDP, DNS, dport=5353) -bind_layers(UDP, DNS, sport=5353) -bind_layers(UDP, DNS, dport=53) -bind_layers(UDP, DNS, sport=53) -DestIPField.bind_addr(UDP, "224.0.0.251", dport=5353) -DestIP6Field.bind_addr(UDP, "ff02::fb", dport=5353) -bind_layers(TCP, DNS, dport=53) -bind_layers(TCP, 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")], # noqa: E501 - 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")], # noqa: E501 - ns=[DNSRR(rrname=name, type=type, - rclass="ANY", ttl=0, rdata="")]), # noqa: E501 - 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-2.4.3/scapy/layers/dot11.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/dot11.py deleted file mode 100644 index ab18230a95..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/dot11.py +++ /dev/null @@ -1,1280 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# Copyright (C) Philippe Biondi - -""" -Wireless LAN according to IEEE 802.11. -""" - -from __future__ import print_function -import math -import re -import struct -from zlib import crc32 - -from scapy.config import conf, crypto_validator -from scapy.data import ETHER_ANY, DLT_IEEE802_11, DLT_PRISM_HEADER, \ - DLT_IEEE802_11_RADIO -from scapy.compat import raw, plain_str, orb, chb -from scapy.packet import Packet, bind_layers, bind_top_down, NoPayload -from scapy.fields import ByteField, LEShortField, BitField, LEShortEnumField, \ - ByteEnumField, X3BytesField, FlagsField, LELongField, StrField, \ - StrLenField, IntField, XByteField, LEIntField, StrFixedLenField, \ - LESignedIntField, ReversePadField, ConditionalField, PacketListField, \ - ShortField, BitEnumField, FieldLenField, LEFieldLenField, \ - FieldListField, XStrFixedLenField, PacketField, FCSField -from scapy.ansmachine import AnsweringMachine -from scapy.plist import PacketList -from scapy.layers.l2 import Ether, LLC, MACField -from scapy.layers.inet import IP, TCP -from scapy.error import warning, log_loading -from scapy.sendrecv import sniff, sendp -from scapy.utils import issubtype - - -if conf.crypto_valid: - from cryptography.hazmat.backends import default_backend - from cryptography.hazmat.primitives.ciphers import Cipher, algorithms -else: - default_backend = Ciphers = algorithms = None - log_loading.info("Can't import python-cryptography v1.7+. Disabled WEP decryption/encryption. (Dot11)") # noqa: E501 - - -# 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) - - -# RadioTap - -class _RadiotapReversePadField(ReversePadField): - def __init__(self, fld): - self._fld = fld - self._padwith = b"\x00" - # Quote from https://www.radiotap.org/: - # ""Radiotap requires that all fields in the radiotap header are aligned to natural boundaries. # noqa: E501 - # For radiotap, that means all 8-, 16-, 32-, and 64-bit fields must begin on 8-, 16-, 32-, and 64-bit boundaries, respectively."" # noqa: E501 - if isinstance(self._fld, BitField): - self._align = int(math.ceil(self.i2len(None, None))) - else: - self._align = struct.calcsize(self._fld.fmt) - - -class _dbmField(ByteField): - def i2m(self, pkt, x): - return super(ByteField, self).i2m(pkt, x + 256) - - def m2i(self, pkt, x): - return super(ByteField, self).m2i(pkt, x) - 256 - - def i2repr(self, pkt, x): - return "%sdBm" % x - - -def _next_radiotap_extpm(pkt, lst, cur, s): - """Generates the next RadioTapExtendedPresenceMask""" - if cur is None or (cur.present and cur.present.Ext): - st = len(lst) + (cur is not None) - return lambda *args: RadioTapExtendedPresenceMask(*args, index=st) - return None - - -class RadioTapExtendedPresenceMask(Packet): - """RadioTapExtendedPresenceMask should be instantiated by passing an - `index=` kwarg, stating which place the item has in the list. - - Passing index will update the b[x] fields accordingly to the index. - e.g. - >>> a = RadioTapExtendedPresenceMask(present="b0+b12+b29+Ext") - >>> b = RadioTapExtendedPresenceMask(index=1, present="b33+b45+b59+b62") - >>> pkt = RadioTap(present="Ext", Ext=[a, b]) - """ - name = "RadioTap Extended presence mask" - fields_desc = [FlagsField('present', None, -32, - ["b%s" % i for i in range(0, 31)] + ["Ext"])] - - def __init__(self, _pkt=None, index=0, **kwargs): - self._restart_indentation(index) - Packet.__init__(self, _pkt, **kwargs) - - def _restart_indentation(self, index): - st = index * 32 - self.fields_desc[0].names = ["b%s" % (i + st) for i in range(0, 31)] + ["Ext"] # noqa: E501 - - def guess_payload_class(self, pay): - return conf.padding_layer - -# RadioTap constants - - -_rt_present = ['TSFT', 'Flags', 'Rate', 'Channel', 'FHSS', 'dBm_AntSignal', - 'dBm_AntNoise', 'Lock_Quality', 'TX_Attenuation', - 'dB_TX_Attenuation', 'dBm_TX_Power', 'Antenna', - 'dB_AntSignal', 'dB_AntNoise', 'RXFlags', 'TXFlags', - 'b17', 'b18', 'ChannelPlus', 'MCS', 'A_MPDU', - 'VHT', 'timestamp', 'HE', 'HE_MU', 'HE_MU_other_user', - 'zero_length_psdu', 'L_SIG', 'b28', - 'RadiotapNS', 'VendorNS', 'Ext'] - -# Note: Inconsistencies with wireshark -# Wireshark ignores the suggested fields, whereas we implement some of them -# (some are well-used even though not accepted) -# However, flags that conflicts with Wireshark are not and MUST NOT be -# implemented -> b17, b18 - -_rt_flags = ['CFP', 'ShortPreamble', 'wep', 'fragment', 'FCS', 'pad', - 'badFCS', 'ShortGI'] - -_rt_channelflags = ['res1', 'res2', 'res3', 'res4', 'Turbo', 'CCK', - 'OFDM', '2GHz', '5GHz', 'Passive', 'Dynamic_CCK_OFDM', - 'GFSK', 'GSM', 'StaticTurbo', '10MHz', '5MHz'] - -_rt_rxflags = ["res1", "BAD_PLCP", "res2"] - -_rt_txflags = ["TX_FAIL", "CTS", "RTS", "NOACK", "NOSEQ"] - -_rt_channelflags2 = ['res1', 'res2', 'res3', 'res4', 'Turbo', 'CCK', - 'OFDM', '2GHz', '5GHz', 'Passive', 'Dynamic_CCK_OFDM', - 'GFSK', 'GSM', 'StaticTurbo', '10MHz', '5MHz', - '20MHz', '40MHz_ext_channel_above', - '40MHz_ext_channel_below', - 'res5', 'res6', 'res7', 'res8', 'res9'] - -_rt_knownmcs = ['MCS_bandwidth', 'MCS_index', 'guard_interval', 'HT_format', - 'FEC_type', 'STBC_streams', 'Ness', 'Ness_MSB'] - -_rt_bandwidth = {0: "20MHz", 1: "40MHz", 2: "ht40Mhz-", 3: "ht40MHz+"} - -_rt_a_mpdu_flags = ['Report0Subframe', 'Is0Subframe', 'KnownLastSubframe', - 'LastSubframe', 'CRCerror', 'EOFsubframe', 'KnownEOF', - 'res1', 'res2', 'res3', 'res4', 'res5', 'res6', 'res7', - 'res8'] - -_rt_vhtbandwidth = { - 0: "20MHz", 1: "40MHz", 2: "40MHz", 3: "40MHz", 4: "80MHz", 5: "80MHz", - 6: "80MHz", 7: "80MHz", 8: "80MHz", 9: "80MHz", 10: "80MHz", 11: "160MHz", - 12: "160MHz", 13: "160MHz", 14: "160MHz", 15: "160MHz", 16: "160MHz", - 17: "160MHz", 18: "160MHz", 19: "160MHz", 20: "160MHz", 21: "160MHz", - 22: "160MHz", 23: "160MHz", 24: "160MHz", 25: "160MHz" -} - -_rt_knownvht = ['STBC', 'TXOP_PS_NOT_ALLOWED', 'GuardInterval', 'SGINsysmDis', - 'LDPCextraOFDM', 'Beamformed', 'Bandwidth', 'GroupID', - 'PartialAID', - 'res1', 'res2', 'res3', 'res4', 'res5', 'res6', 'res7'] - -_rt_presentvht = ['STBC', 'TXOP_PS_NOT_ALLOWED', 'GuardInterval', - 'SGINsysmDis', 'LDPCextraOFDM', 'Beamformed', - 'res1', 'res2'] - -_rt_hemuother_per_user_known = { - 'user field position', - 'STA-ID', - 'NSTS', - 'Tx Beamforming', - 'Spatial Configuration', - 'MCS', - 'DCM', - 'Coding', -} - - -class RadioTap(Packet): - name = "RadioTap dummy" - deprecated_fields = { - "Channel": ("ChannelFrequency", "2.4.3"), - "ChannelFlags2": ("ChannelPlusFlags", "2.4.3"), - "ChannelNumber": ("ChannelPlusNumber", "2.4.3"), - } - fields_desc = [ - ByteField('version', 0), - ByteField('pad', 0), - LEShortField('len', None), - FlagsField('present', None, -32, _rt_present), # noqa: E501 - # Extended presence mask - ConditionalField(PacketListField("Ext", [], next_cls_cb=_next_radiotap_extpm), lambda pkt: pkt.present and pkt.present.Ext), # noqa: E501 - # RadioTap fields - each starts with a _RadiotapReversePadField - # to handle padding - - # TSFT - ConditionalField( - _RadiotapReversePadField( - LELongField("mac_timestamp", 0) - ), - lambda pkt: pkt.present and pkt.present.TSFT), - # Flags - ConditionalField( - _RadiotapReversePadField( - FlagsField("Flags", None, -8, _rt_flags) - ), - lambda pkt: pkt.present and pkt.present.Flags), - # Rate - ConditionalField( - _RadiotapReversePadField( - ByteField("Rate", 0) - ), - lambda pkt: pkt.present and pkt.present.Rate), - # Channel - ConditionalField( - _RadiotapReversePadField( - LEShortField("ChannelFrequency", 0) - ), - lambda pkt: pkt.present and pkt.present.Channel), - ConditionalField( - FlagsField("ChannelFlags", None, -16, _rt_channelflags), - lambda pkt: pkt.present and pkt.present.Channel), - # dBm_AntSignal - ConditionalField( - _RadiotapReversePadField( - _dbmField("dBm_AntSignal", -256) - ), - lambda pkt: pkt.present and pkt.present.dBm_AntSignal), - # dBm_AntNoise - ConditionalField( - _RadiotapReversePadField( - _dbmField("dBm_AntNoise", -256) - ), - lambda pkt: pkt.present and pkt.present.dBm_AntNoise), - # Lock_Quality - ConditionalField( - _RadiotapReversePadField( - LEShortField("Lock_Quality", 0), - ), - lambda pkt: pkt.present and pkt.present.Lock_Quality), - # Antenna - ConditionalField( - _RadiotapReversePadField( - ByteField("Antenna", 0) - ), - lambda pkt: pkt.present and pkt.present.Antenna), - # RX Flags - ConditionalField( - _RadiotapReversePadField( - FlagsField("RXFlags", None, -16, _rt_rxflags) - ), - lambda pkt: pkt.present and pkt.present.RXFlags), - # TX Flags - ConditionalField( - _RadiotapReversePadField( - FlagsField("TXFlags", None, -16, _rt_txflags) - ), - lambda pkt: pkt.present and pkt.present.TXFlags), - # ChannelPlus - ConditionalField( - _RadiotapReversePadField( - FlagsField("ChannelPlusFlags", None, -32, _rt_channelflags2) - ), - lambda pkt: pkt.present and pkt.present.ChannelPlus), - ConditionalField( - LEShortField("ChannelPlusFrequency", 0), - lambda pkt: pkt.present and pkt.present.ChannelPlus), - ConditionalField( - ByteField("ChannelPlusNumber", 0), - lambda pkt: pkt.present and pkt.present.ChannelPlus), - # MCS - ConditionalField( - _RadiotapReversePadField( - FlagsField("knownMCS", None, -8, _rt_knownmcs) - ), - lambda pkt: pkt.present and pkt.present.MCS), - ConditionalField( - BitField("Ness_LSB", 0, 1), - lambda pkt: pkt.present and pkt.present.MCS), - ConditionalField( - BitField("STBC_streams", 0, 2), - lambda pkt: pkt.present and pkt.present.MCS), - ConditionalField( - BitEnumField("FEC_type", 0, 1, {0: "BCC", 1: "LDPC"}), - lambda pkt: pkt.present and pkt.present.MCS), - ConditionalField( - BitEnumField("HT_format", 0, 1, {0: "mixed", 1: "greenfield"}), - lambda pkt: pkt.present and pkt.present.MCS), - ConditionalField( - BitEnumField("guard_interval", 0, 1, {0: "Long_GI", 1: "Short_GI"}), # noqa: E501 - lambda pkt: pkt.present and pkt.present.MCS), - ConditionalField( - BitEnumField("MCS_bandwidth", 0, 2, _rt_bandwidth), - lambda pkt: pkt.present and pkt.present.MCS), - ConditionalField( - ByteField("MCS_index", 0), - lambda pkt: pkt.present and pkt.present.MCS), - # A_MPDU - ConditionalField( - _RadiotapReversePadField( - LEIntField("A_MPDU_ref", 0) - ), - lambda pkt: pkt.present and pkt.present.A_MPDU), - ConditionalField( - FlagsField("A_MPDU_flags", None, -32, _rt_a_mpdu_flags), - lambda pkt: pkt.present and pkt.present.A_MPDU), - # VHT - ConditionalField( - _RadiotapReversePadField( - FlagsField("KnownVHT", None, -16, _rt_knownvht) - ), - lambda pkt: pkt.present and pkt.present.VHT), - ConditionalField( - FlagsField("PresentVHT", None, -8, _rt_presentvht), - lambda pkt: pkt.present and pkt.present.VHT), - ConditionalField( - ByteEnumField("VHT_bandwidth", 0, _rt_vhtbandwidth), - lambda pkt: pkt.present and pkt.present.VHT), - ConditionalField( - StrFixedLenField("mcs_nss", 0, length=5), - lambda pkt: pkt.present and pkt.present.VHT), - ConditionalField( - ByteField("GroupID", 0), - lambda pkt: pkt.present and pkt.present.VHT), - ConditionalField( - ShortField("PartialAID", 0), - lambda pkt: pkt.present and pkt.present.VHT), - # timestamp - ConditionalField( - _RadiotapReversePadField( - LELongField("timestamp", 0) - ), - lambda pkt: pkt.present and pkt.present.timestamp), - ConditionalField( - LEShortField("ts_accuracy", 0), - lambda pkt: pkt.present and pkt.present.timestamp), - ConditionalField( - ByteField("ts_position", 0), - lambda pkt: pkt.present and pkt.present.timestamp), - ConditionalField( - ByteField("ts_flags", 0), - lambda pkt: pkt.present and pkt.present.timestamp), - # HE - XXX not complete - ConditionalField( - _RadiotapReversePadField( - ShortField("he_data1", 0) - ), - lambda pkt: pkt.present and pkt.present.HE), - ConditionalField( - ShortField("he_data2", 0), - lambda pkt: pkt.present and pkt.present.HE), - ConditionalField( - ShortField("he_data3", 0), - lambda pkt: pkt.present and pkt.present.HE), - ConditionalField( - ShortField("he_data4", 0), - lambda pkt: pkt.present and pkt.present.HE), - ConditionalField( - ShortField("he_data5", 0), - lambda pkt: pkt.present and pkt.present.HE), - ConditionalField( - ShortField("he_data6", 0), - lambda pkt: pkt.present and pkt.present.HE), - # HE_MU - ConditionalField( - _RadiotapReversePadField( - LEShortField("hemu_flags1", 0) - ), - lambda pkt: pkt.present and pkt.present.HE_MU), - ConditionalField( - LEShortField("hemu_flags2", 0), - lambda pkt: pkt.present and pkt.present.HE_MU), - ConditionalField( - FieldListField("RU_channel1", [], ByteField, - count_from=lambda x: 4), - lambda pkt: pkt.present and pkt.present.HE_MU), - ConditionalField( - FieldListField("RU_channel2", [], ByteField, - count_from=lambda x: 4), - lambda pkt: pkt.present and pkt.present.HE_MU), - # HE_MU_other_user - ConditionalField( - _RadiotapReversePadField( - LEShortField("hemuou_per_user_1", 0x7fff) - ), - lambda pkt: pkt.present and pkt.present.HE_MU_other_user), - ConditionalField( - LEShortField("hemuou_per_user_2", 0x003f), - lambda pkt: pkt.present and pkt.present.HE_MU_other_user), - ConditionalField( - ByteField("hemuou_per_user_position", 0), - lambda pkt: pkt.present and pkt.present.HE_MU_other_user), - ConditionalField( - FlagsField("hemuou_per_user_known", 0, -16, - _rt_hemuother_per_user_known), - lambda pkt: pkt.present and pkt.present.HE_MU_other_user), - # L_SIG - ConditionalField( - _RadiotapReversePadField( - FlagsField("lsig_data1", 0, -16, ["rate", "length"]) - ), - lambda pkt: pkt.present and pkt.present.L_SIG), - ConditionalField( - BitField("lsig_length", 0, 12), - lambda pkt: pkt.present and pkt.present.L_SIG), - ConditionalField( - BitField("lsig_rate", 0, 4), - lambda pkt: pkt.present and pkt.present.L_SIG), - # Remaining - StrLenField('notdecoded', "", - length_from=lambda pkt: max( - pkt.len - pkt._tmp_dissect_pos, 0 - )) - ] - - def guess_payload_class(self, payload): - if self.present and self.present.Flags and self.Flags.FCS: - return Dot11FCS - return Dot11 - - def post_build(self, p, pay): - if self.len is None: - p = p[:2] + struct.pack("!H", len(p))[::-1] + p[4:] - return p + pay - - -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", "protected", "order"]), - ShortField("ID", 0), - MACField("addr1", ETHER_ANY), - ConditionalField( - MACField("addr2", ETHER_ANY), - lambda pkt: (pkt.type != 1 or - pkt.subtype in [0x8, 0x9, 0xa, 0xb, 0xe, 0xf]), - ), - ConditionalField( - MACField("addr3", ETHER_ANY), - lambda pkt: pkt.type in [0, 2], - ), - ConditionalField(LEShortField("SC", 0), lambda pkt: pkt.type != 1), - ConditionalField( - MACField("addr4", ETHER_ANY), - lambda pkt: (pkt.type == 2 and - pkt.FCfield & 3 == 3), # from-DS+to-DS - ) - ] - - def mysummary(self): - # Supports both Dot11 and Dot11FCS - return self.sprintf("802.11 %%%s.type%% %%%s.subtype%% %%%s.addr2%% > %%%s.addr1%%" % ((self.__class__.__name__,) * 4)) # noqa: E501 - - def guess_payload_class(self, payload): - if self.type == 0x02 and (0x08 <= self.subtype <= 0xF and self.subtype != 0xD): # noqa: E501 - return Dot11QoS - elif self.FCfield.protected: - # When a frame is handled by encryption, the Protected Frame bit - # (previously called WEP bit) is set to 1, and the Frame Body - # begins with the appropriate cryptographic header. - return Dot11Encrypted - 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 # noqa: E501 - 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 Dot11FCS(Dot11): - name = "802.11-FCS" - match_subclass = True - fields_desc = Dot11.fields_desc + [FCSField("fcs", None, fmt="= 3: - length = orb(s[1]) - if length > 0 and length <= 255: - self.info = s[2:2 + length] - return s - - def post_build(self, p, pay): - if self.len is None: - p = p[:1] + chb(len(p) - 2) + p[2:] - return p + pay - - -class RSNCipherSuite(Packet): - name = "Cipher suite" - fields_desc = [ - X3BytesField("oui", 0x000fac), - ByteEnumField("cipher", 0x04, { - 0x00: "Use group cipher suite", - 0x01: "WEP-40", - 0x02: "TKIP", - 0x03: "Reserved", - 0x04: "CCMP", - 0x05: "WEP-104" - }) - ] - - def extract_padding(self, s): - return "", s - - -class AKMSuite(Packet): - name = "AKM suite" - fields_desc = [ - X3BytesField("oui", 0x000fac), - ByteEnumField("suite", 0x01, { - 0x00: "Reserved", - 0x01: "IEEE 802.1X / PMKSA caching", - 0x02: "PSK" - }) - ] - - def extract_padding(self, s): - return "", s - - -class PMKIDListPacket(Packet): - name = "PMKIDs" - fields_desc = [ - LEFieldLenField("nb_pmkids", 0, count_of="pmk_id_list"), - FieldListField( - "pmkid_list", - None, - XStrFixedLenField("", "", length=16), - count_from=lambda pkt: pkt.nb_pmkids - ) - ] - - def extract_padding(self, s): - return "", s - - -class Dot11EltRSN(Dot11Elt): - name = "802.11 RSN information" - fields_desc = [ - ByteField("ID", 48), - ByteField("len", None), - LEShortField("version", 1), - PacketField("group_cipher_suite", RSNCipherSuite(), RSNCipherSuite), - LEFieldLenField( - "nb_pairwise_cipher_suites", - 1, - count_of="pairwise_cipher_suites" - ), - PacketListField( - "pairwise_cipher_suites", - [RSNCipherSuite()], - RSNCipherSuite, - count_from=lambda p: p.nb_pairwise_cipher_suites - ), - LEFieldLenField( - "nb_akm_suites", - 1, - count_of="akm_suites" - ), - PacketListField( - "akm_suites", - [AKMSuite()], - AKMSuite, - count_from=lambda p: p.nb_akm_suites - ), - BitField("mfp_capable", 0, 1), - BitField("mfp_required", 0, 1), - BitField("gtksa_replay_counter", 0, 2), - BitField("ptksa_replay_counter", 0, 2), - BitField("no_pairwise", 0, 1), - BitField("pre_auth", 0, 1), - BitField("reserved", 0, 8), - ConditionalField( - PacketField("pmkids", None, PMKIDListPacket), - lambda pkt: ( - 0 if pkt.len is None else - pkt.len - (12 + (pkt.nb_pairwise_cipher_suites * 4) + - (pkt.nb_akm_suites * 4)) >= 18) - ) - ] - - -class Dot11EltCountryConstraintTriplet(Packet): - name = "802.11 Country Constraint Triplet" - fields_desc = [ - ByteField("first_channel_number", 1), - ByteField("num_channels", 24), - ByteField("mtp", 0) - ] - - def extract_padding(self, s): - return b"", s - - -class Dot11EltCountry(Dot11Elt): - name = "802.11 Country" - fields_desc = [ - ByteField("ID", 7), - ByteField("len", None), - StrFixedLenField("country_string", b"\0\0\0", length=3), - PacketListField( - "descriptors", - [], - Dot11EltCountryConstraintTriplet, - length_from=lambda pkt: ( - pkt.len - 3 - (pkt.len % 3) - ) - ), - ConditionalField( - ByteField("pad", 0), - lambda pkt: (pkt.len + 1) % 2 - ) - ] - - -class Dot11EltMicrosoftWPA(Dot11Elt): - name = "802.11 Microsoft WPA" - fields_desc = [ - ByteField("ID", 221), - ByteField("len", None), - X3BytesField("oui", 0x0050f2), - XByteField("type", 0x01), - LEShortField("version", 1), - PacketField("group_cipher_suite", RSNCipherSuite(), RSNCipherSuite), - LEFieldLenField( - "nb_pairwise_cipher_suites", - 1, - count_of="pairwise_cipher_suites" - ), - PacketListField( - "pairwise_cipher_suites", - RSNCipherSuite(), - RSNCipherSuite, - count_from=lambda p: p.nb_pairwise_cipher_suites - ), - LEFieldLenField( - "nb_akm_suites", - 1, - count_of="akm_suites" - ), - PacketListField( - "akm_suites", - AKMSuite(), - AKMSuite, - count_from=lambda p: p.nb_akm_suites - ) - ] - - -class Dot11EltRates(Dot11Elt): - name = "802.11 Rates" - fields_desc = [ - ByteField("ID", 1), - ByteField("len", None), - FieldListField( - "rates", - [], - XByteField("", 0), - count_from=lambda p: p.len - ) - ] - - -class Dot11EltVendorSpecific(Dot11Elt): - name = "802.11 Vendor Specific" - fields_desc = [ - ByteField("ID", 221), - ByteField("len", None), - X3BytesField("oui", 0x000000), - StrLenField("info", "", length_from=lambda x: x.len - 3) - ] - - -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(_Dot11NetStats): - name = "802.11 Probe Response" - - -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 Dot11Encrypted(Packet): - name = "802.11 Encrypted (unknown algorithm)" - fields_desc = [StrField("data", None)] - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - # Extracted from - # https://github.com/wireshark/wireshark/blob/master/epan/dissectors/packet-ieee80211.c # noqa: E501 - KEY_EXTIV = 0x20 - EXTIV_LEN = 8 - if _pkt and len(_pkt) >= 3: - if (orb(_pkt[3]) & KEY_EXTIV) and (len(_pkt) >= EXTIV_LEN): - if orb(_pkt[1]) == ((orb(_pkt[0]) | 0x20) & 0x7f): # IS_TKIP - return Dot11TKIP - elif orb(_pkt[2]) == 0: # IS_CCMP - return Dot11CCMP - else: - # Unknown encryption algorithm - return Dot11Encrypted - else: - return Dot11WEP - return conf.raw_layer - - -class Dot11WEP(Dot11Encrypted): - 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 decrypt(self, key=None): - if key is None: - key = conf.wepkey - if key and conf.crypto_valid: - d = Cipher( - algorithms.ARC4(self.iv + key.encode("utf8")), - None, - default_backend(), - ).decryptor() - self.add_payload(LLC(d.update(self.wepdata) + d.finalize())) - - def post_dissect(self, s): - self.decrypt() - - def build_payload(self): - if self.wepdata is None: - return Packet.build_payload(self) - return b"" - - @crypto_validator - def encrypt(self, p, pay, key=None): - if key is None: - key = conf.wepkey - if key: - if self.icv is None: - pay += struct.pack(" LE = reversed order - BitField("res", 0, 5), # - # ext_iv - 4 bytes - ConditionalField(ByteField("TSC2", 0), lambda pkt: pkt.ext_iv), - ConditionalField(ByteField("TSC3", 0), lambda pkt: pkt.ext_iv), - ConditionalField(ByteField("TSC4", 0), lambda pkt: pkt.ext_iv), - ConditionalField(ByteField("TSC5", 0), lambda pkt: pkt.ext_iv), - # data - StrField("data", None), - ] - - -class Dot11CCMP(Dot11Encrypted): - name = "802.11 TKIP packet" - fields_desc = [ - # iv - 8 bytes - ByteField("PN0", 0), - ByteField("PN1", 0), - ByteField("res0", 0), - BitField("key_id", 0, 2), # - BitField("ext_iv", 0, 1), # => LE = reversed order - BitField("res1", 0, 5), # - ByteField("PN2", 0), - ByteField("PN3", 0), - ByteField("PN4", 0), - ByteField("PN5", 0), - # data - StrField("data", None), - ] - - -class Dot11Ack(Packet): - name = "802.11 Ack packet" - - -bind_top_down(RadioTap, Dot11FCS, present=2, Flags=16) - -bind_layers(PrismHeader, Dot11,) -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(Dot11, Dot11Ack, subtype=13, type=1) -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,) -bind_layers(Dot11TKIP, conf.raw_layer) -bind_layers(Dot11CCMP, conf.raw_layer) - - -conf.l2types.register(DLT_IEEE802_11, Dot11) -conf.l2types.register_num2layer(801, Dot11) -conf.l2types.register(DLT_PRISM_HEADER, PrismHeader) -conf.l2types.register_num2layer(802, PrismHeader) -conf.l2types.register(DLT_IEEE802_11_RADIO, RadioTap) -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=conf.iface, ifto=conf.iface, replace="", - pattern="", ignorepattern=""): - self.iffrom = iffrom - self.ifto = ifto - self.ptrn = re.compile(pattern.encode()) - self.iptrn = re.compile(ignorepattern.encode()) - self.replace = replace - - 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 - tcp = pkt.getlayer(TCP) - pay = raw(tcp.payload) - if not self.ptrn.match(pay): - return 0 - if self.iptrn.match(pay) is True: - return 0 - return True - - def make_reply(self, p): - ip = p.getlayer(IP) - tcp = p.getlayer(TCP) - pay = raw(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(self.replace) - return [p, q] - - def print_reply(self, query, *reply): - p = reply[0][0] - 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) - - -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 = [x[Dot11] for x in self.res if Dot11 in x 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-2.4.3/scapy/layers/dot15d4.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/dot15d4.py deleted file mode 100644 index 7e93b25944..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/dot15d4.py +++ /dev/null @@ -1,449 +0,0 @@ -# This program is published under a GPLv2 license -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Ryan Speers 2011-2012 -# Copyright (C) Roger Meyer : 2012-03-10 Added frames -# Copyright (C) Gabriel Potter : 2018 -# Intern at INRIA Grand Nancy Est -# This program is published under a GPLv2 license - -""" -Wireless MAC according to IEEE 802.15.4. -""" - -import struct - -from scapy.compat import orb, chb -from scapy.error import warning -from scapy.config import conf - -from scapy.data import DLT_IEEE802_15_4_WITHFCS, DLT_IEEE802_15_4_NOFCS -from scapy.packet import Packet, bind_layers -from scapy.fields import BitEnumField, BitField, ByteEnumField, ByteField, \ - ConditionalField, Field, LELongField, PacketField, XByteField, \ - XLEIntField, XLEShortField, FCSField, Emph - -# Fields # - - -class dot15d4AddressField(Field): - __slots__ = ["adjust", "length_of"] - - def __init__(self, name, default, length_of=None, fmt=" %Dot15d4.fcf_srcaddrmode% ) Seq#%Dot15d4.seqnum%") # noqa: E501 - - def guess_payload_class(self, payload): - if self.fcf_frametype == 0x00: - return Dot15d4Beacon - elif self.fcf_frametype == 0x01: - return Dot15d4Data - elif self.fcf_frametype == 0x02: - return Dot15d4Ack - elif self.fcf_frametype == 0x03: - return Dot15d4Cmd - else: - return Packet.guess_payload_class(self, payload) - - def answers(self, other): - if isinstance(other, Dot15d4): - if self.fcf_frametype == 2: # ack - if self.seqnum != other.seqnum: # check for seqnum matching - return 0 - elif other.fcf_ackreq == 1: # check that an ack was indeed requested # noqa: E501 - return 1 - return 0 - - def post_build(self, p, pay): - # This just forces destaddrmode to None for Ack frames. - if self.fcf_frametype == 2 and self.fcf_destaddrmode != 0: - self.fcf_destaddrmode = 0 - return p[:1] + \ - chb((self.fcf_srcaddrmode << 6) + (self.fcf_framever << 4)) \ - + p[2:] + pay - else: - return p + pay - - -class Dot15d4FCS(Dot15d4): - ''' - This class is a drop-in replacement for the Dot15d4 class above, except - it expects a FCS/checksum in the input, and produces one in the output. - This provides the user flexibility, as many 802.15.4 interfaces will have an AUTO_CRC setting # noqa: E501 - that will validate the FCS/CRC in firmware, and add it automatically when transmitting. # noqa: E501 - ''' - name = "802.15.4 - FCS" - match_subclass = True - fields_desc = Dot15d4.fields_desc + [FCSField("fcs", None, fmt=" %Dot15d4Data.dest_panid%:%Dot15d4Data.dest_addr% )") # noqa: E501 - - -class Dot15d4Beacon(Packet): - name = "802.15.4 Beacon" - fields_desc = [ - XLEShortField("src_panid", 0x0), - dot15d4AddressField("src_addr", None, length_of="fcf_srcaddrmode"), - # Security field present if fcf_security == True - ConditionalField(PacketField("aux_sec_header", Dot15d4AuxSecurityHeader(), Dot15d4AuxSecurityHeader), # noqa: E501 - lambda pkt:pkt.underlayer.getfieldval("fcf_security") is True), # noqa: E501 - - # Superframe spec field: - BitField("sf_sforder", 15, 4), # not used by ZigBee - BitField("sf_beaconorder", 15, 4), # not used by ZigBee - BitEnumField("sf_assocpermit", 0, 1, [False, True]), - BitEnumField("sf_pancoord", 0, 1, [False, True]), - BitField("sf_reserved", 0, 1), # not used by ZigBee - BitEnumField("sf_battlifeextend", 0, 1, [False, True]), # not used by ZigBee # noqa: E501 - BitField("sf_finalcapslot", 15, 4), # not used by ZigBee - - # GTS Fields - # GTS Specification (1 byte) - BitEnumField("gts_spec_permit", 1, 1, [False, True]), # GTS spec bit 7, true=1 iff PAN cord is accepting GTS requests # noqa: E501 - BitField("gts_spec_reserved", 0, 4), # GTS spec bits 3-6 - BitField("gts_spec_desccount", 0, 3), # GTS spec bits 0-2 - # GTS Directions (0 or 1 byte) - ConditionalField(BitField("gts_dir_reserved", 0, 1), lambda pkt:pkt.getfieldval("gts_spec_desccount") != 0), # noqa: E501 - ConditionalField(BitField("gts_dir_mask", 0, 7), lambda pkt:pkt.getfieldval("gts_spec_desccount") != 0), # noqa: E501 - # GTS List (variable size) - # TODO add a Packet/FieldListField tied to 3bytes per count in gts_spec_desccount # noqa: E501 - - # Pending Address Fields: - # Pending Address Specification (1 byte) - BitField("pa_num_short", 0, 3), # number of short addresses pending - BitField("pa_reserved_1", 0, 1), - BitField("pa_num_long", 0, 3), # number of long addresses pending - BitField("pa_reserved_2", 0, 1), - # Address List (var length) - # TODO add a FieldListField of the pending short addresses, followed by the pending long addresses, with max 7 addresses # noqa: E501 - # TODO beacon payload - ] - - def mysummary(self): - return self.sprintf("802.15.4 Beacon ( %Dot15d4Beacon.src_panid%:%Dot15d4Beacon.src_addr% ) assocPermit(%Dot15d4Beacon.sf_assocpermit%) panCoord(%Dot15d4Beacon.sf_pancoord%)") # noqa: E501 - - -class Dot15d4Cmd(Packet): - name = "802.15.4 Command" - fields_desc = [ - XLEShortField("dest_panid", 0xFFFF), - # Users should correctly set the dest_addr field. By default is 0x0 for construction to work. # noqa: E501 - dot15d4AddressField("dest_addr", 0x0, length_of="fcf_destaddrmode"), - ConditionalField(XLEShortField("src_panid", 0x0), \ - lambda pkt:util_srcpanid_present(pkt)), - ConditionalField(dot15d4AddressField("src_addr", None, - length_of="fcf_srcaddrmode"), - lambda pkt:pkt.underlayer.getfieldval("fcf_srcaddrmode") != 0), # noqa: E501 - # Security field present if fcf_security == True - ConditionalField(PacketField("aux_sec_header", Dot15d4AuxSecurityHeader(), Dot15d4AuxSecurityHeader), # noqa: E501 - lambda pkt:pkt.underlayer.getfieldval("fcf_security") is True), # noqa: E501 - ByteEnumField("cmd_id", 0, { - 1: "AssocReq", # Association request - 2: "AssocResp", # Association response - 3: "DisassocNotify", # Disassociation notification - 4: "DataReq", # Data request - 5: "PANIDConflictNotify", # PAN ID conflict notification - 6: "OrphanNotify", # Orphan notification - 7: "BeaconReq", # Beacon request - 8: "CoordRealign", # coordinator realignment - 9: "GTSReq" # GTS request - # 0x0a - 0xff reserved - }), - # TODO command payload - ] - - def mysummary(self): - return self.sprintf("802.15.4 Command %Dot15d4Cmd.cmd_id% ( %Dot15dCmd.src_panid%:%Dot15d4Cmd.src_addr% -> %Dot15d4Cmd.dest_panid%:%Dot15d4Cmd.dest_addr% )") # noqa: E501 - - # command frame payloads are complete: DataReq, PANIDConflictNotify, OrphanNotify, BeaconReq don't have any payload # noqa: E501 - # Although BeaconReq can have an optional ZigBee Beacon payload (implemented in ZigBeeBeacon) # noqa: E501 - def guess_payload_class(self, payload): - if self.cmd_id == 1: - return Dot15d4CmdAssocReq - elif self.cmd_id == 2: - return Dot15d4CmdAssocResp - elif self.cmd_id == 3: - return Dot15d4CmdDisassociation - elif self.cmd_id == 8: - return Dot15d4CmdCoordRealign - elif self.cmd_id == 9: - return Dot15d4CmdGTSReq - else: - return Packet.guess_payload_class(self, payload) - - -class Dot15d4CmdCoordRealign(Packet): - name = "802.15.4 Coordinator Realign Command" - fields_desc = [ - # PAN Identifier (2 octets) - XLEShortField("panid", 0xFFFF), - # Coordinator Short Address (2 octets) - XLEShortField("coord_address", 0x0000), - # Logical Channel (1 octet): the logical channel that the coordinator intends to use for all future communications # noqa: E501 - ByteField("channel", 0), - # Short Address (2 octets) - XLEShortField("dev_address", 0xFFFF), - # Channel page (0/1 octet) TODO optional - # ByteField("channel_page", 0), - ] - - def mysummary(self): - return self.sprintf("802.15.4 Coordinator Realign Payload ( PAN ID: %Dot15dCmdCoordRealign.pan_id% : channel %Dot15d4CmdCoordRealign.channel% )") # noqa: E501 - - -# Utility Functions # - - -def util_srcpanid_present(pkt): - '''A source PAN ID is included if and only if both src addr mode != 0 and PAN ID Compression in FCF == 0''' # noqa: E501 - if (pkt.underlayer.getfieldval("fcf_srcaddrmode") != 0) and (pkt.underlayer.getfieldval("fcf_panidcompress") == 0): # noqa: E501 - return True - else: - return False - - -class Dot15d4CmdAssocReq(Packet): - name = "802.15.4 Association Request Payload" - fields_desc = [ - BitField("allocate_address", 0, 1), # Allocate Address - BitField("security_capability", 0, 1), # Security Capability - BitField("reserved2", 0, 1), # bit 5 is reserved - BitField("reserved1", 0, 1), # bit 4 is reserved - BitField("receiver_on_when_idle", 0, 1), # Receiver On When Idle - BitField("power_source", 0, 1), # Power Source - BitField("device_type", 0, 1), # Device Type - BitField("alternate_pan_coordinator", 0, 1), # Alternate PAN Coordinator # noqa: E501 - ] - - def mysummary(self): - return self.sprintf("802.15.4 Association Request Payload ( Alt PAN Coord: %Dot15d4CmdAssocReq.alternate_pan_coordinator% Device Type: %Dot15d4CmdAssocReq.device_type% )") # noqa: E501 - - -class Dot15d4CmdAssocResp(Packet): - name = "802.15.4 Association Response Payload" - fields_desc = [ - XLEShortField("short_address", 0xFFFF), # Address assigned to device from coordinator (0xFFFF == none) # noqa: E501 - # Association Status - # 0x00 == successful - # 0x01 == PAN at capacity - # 0x02 == PAN access denied - # 0x03 - 0x7f == Reserved - # 0x80 - 0xff == Reserved for MAC primitive enumeration values - ByteEnumField("association_status", 0x00, {0: 'successful', 1: 'PAN_at_capacity', 2: 'PAN_access_denied'}), # noqa: E501 - ] - - def mysummary(self): - return self.sprintf("802.15.4 Association Response Payload ( Association Status: %Dot15d4CmdAssocResp.association_status% Assigned Address: %Dot15d4CmdAssocResp.short_address% )") # noqa: E501 - - -class Dot15d4CmdDisassociation(Packet): - name = "802.15.4 Disassociation Notification Payload" - fields_desc = [ - # Disassociation Reason - # 0x00 == Reserved - # 0x01 == The coordinator wishes the device to leave the PAN - # 0x02 == The device wishes to leave the PAN - # 0x03 - 0x7f == Reserved - # 0x80 - 0xff == Reserved for MAC primitive enumeration values - ByteEnumField("disassociation_reason", 0x02, {1: 'coord_wishes_device_to_leave', 2: 'device_wishes_to_leave'}), # noqa: E501 - ] - - def mysummary(self): - return self.sprintf("802.15.4 Disassociation Notification Payload ( Disassociation Reason %Dot15d4CmdDisassociation.disassociation_reason% )") # noqa: E501 - - -class Dot15d4CmdGTSReq(Packet): - name = "802.15.4 GTS request command" - fields_desc = [ - # GTS Characteristics field (1 octet) - # Reserved (bits 6-7) - BitField("reserved", 0, 2), - # Characteristics Type (bit 5) - BitField("charact_type", 0, 1), - # GTS Direction (bit 4) - BitField("gts_dir", 0, 1), - # GTS Length (bits 0-3) - BitField("gts_len", 0, 4), - ] - - def mysummary(self): - return self.sprintf("802.15.4 GTS Request Command ( %Dot15d4CmdGTSReq.gts_len% : %Dot15d4CmdGTSReq.gts_dir% )") # noqa: E501 - - -# PAN ID conflict notification command frame is not necessary, only Dot15d4Cmd with cmd_id = 5 ("PANIDConflictNotify") # noqa: E501 -# Orphan notification command not necessary, only Dot15d4Cmd with cmd_id = 6 ("OrphanNotify") # noqa: E501 - -# Bindings # -bind_layers(Dot15d4, Dot15d4Beacon, fcf_frametype=0) -bind_layers(Dot15d4, Dot15d4Data, fcf_frametype=1) -bind_layers(Dot15d4, Dot15d4Ack, fcf_frametype=2) -bind_layers(Dot15d4, Dot15d4Cmd, fcf_frametype=3) - -# DLT Types # -conf.l2types.register(DLT_IEEE802_15_4_WITHFCS, Dot15d4FCS) -conf.l2types.register(DLT_IEEE802_15_4_NOFCS, Dot15d4) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/eap.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/eap.py deleted file mode 100644 index 82f6c5c187..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/eap.py +++ /dev/null @@ -1,786 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Extensible Authentication Protocol (EAP) -""" - -from __future__ import absolute_import -from __future__ import print_function - -import struct - -from scapy.fields import BitField, ByteField, XByteField,\ - ShortField, IntField, XIntField, ByteEnumField, StrLenField, XStrField,\ - XStrLenField, XStrFixedLenField, LenField, FieldLenField, FieldListField,\ - PacketField, PacketListField, ConditionalField, PadField -from scapy.packet import Packet, Padding, bind_layers -from scapy.layers.l2 import SourceMACField, Ether, CookedLinux, GRE, SNAP -from scapy.utils import issubtype -from scapy.config import conf -from scapy.compat import orb, chb - -# -# EAPOL -# - -######################################################################### -# -# EAPOL protocol version -# IEEE Std 802.1X-2010 - Section 11.3.1 -######################################################################### -# - -eapol_versions = { - 0x1: "802.1X-2001", - 0x2: "802.1X-2004", - 0x3: "802.1X-2010", -} - -######################################################################### -# -# EAPOL Packet Types -# IEEE Std 802.1X-2010 - Table 11.3 -######################################################################### -# - -eapol_types = { - 0x0: "EAP-Packet", # "EAPOL-EAP" in 801.1X-2010 - 0x1: "EAPOL-Start", - 0x2: "EAPOL-Logoff", - 0x3: "EAPOL-Key", - 0x4: "EAPOL-Encapsulated-ASF-Alert", - 0x5: "EAPOL-MKA", - 0x6: "EAPOL-Announcement (Generic)", - 0x7: "EAPOL-Announcement (Specific)", - 0x8: "EAPOL-Announcement-Req" -} - - -class EAPOL(Packet): - """ - EAPOL - IEEE Std 802.1X-2010 - """ - - name = "EAPOL" - fields_desc = [ - ByteEnumField("version", 1, eapol_versions), - ByteEnumField("type", 0, eapol_types), - LenField("len", None, "H") - ] - - EAP_PACKET = 0 - START = 1 - LOGOFF = 2 - KEY = 3 - ASF = 4 - - def extract_padding(self, s): - tmp_len = self.len - return s[:tmp_len], s[tmp_len:] - - def hashret(self): - return chb(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%") - - -# -# EAP -# - - -######################################################################### -# -# EAP methods types -# http://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml#eap-numbers-4 -######################################################################### -# - -eap_types = { - 0: "Reserved", - 1: "Identity", - 2: "Notification", - 3: "Legacy Nak", - 4: "MD5-Challenge", - 5: "One-Time Password (OTP)", - 6: "Generic Token Card (GTC)", - 7: "Allocated - RFC3748", - 8: "Allocated - RFC3748", - 9: "RSA Public Key Authentication", - 10: "DSS Unilateral", - 11: "KEA", - 12: "KEA-VALIDATE", - 13: "EAP-TLS", - 14: "Defender Token (AXENT)", - 15: "RSA Security SecurID EAP", - 16: "Arcot Systems EAP", - 17: "EAP-Cisco Wireless", - 18: "GSM Subscriber Identity Modules (EAP-SIM)", - 19: "SRP-SHA1", - 20: "Unassigned", - 21: "EAP-TTLS", - 22: "Remote Access Service", - 23: "EAP-AKA Authentication", - 24: "EAP-3Com Wireless", - 25: "PEAP", - 26: "MS-EAP-Authentication", - 27: "Mutual Authentication w/Key Exchange (MAKE)", - 28: "CRYPTOCard", - 29: "EAP-MSCHAP-V2", - 30: "DynamID", - 31: "Rob EAP", - 32: "Protected One-Time Password", - 33: "MS-Authentication-TLV", - 34: "SentriNET", - 35: "EAP-Actiontec Wireless", - 36: "Cogent Systems Biometrics Authentication EAP", - 37: "AirFortress EAP", - 38: "EAP-HTTP Digest", - 39: "SecureSuite EAP", - 40: "DeviceConnect EAP", - 41: "EAP-SPEKE", - 42: "EAP-MOBAC", - 43: "EAP-FAST", - 44: "ZoneLabs EAP (ZLXEAP)", - 45: "EAP-Link", - 46: "EAP-PAX", - 47: "EAP-PSK", - 48: "EAP-SAKE", - 49: "EAP-IKEv2", - 50: "EAP-AKA", - 51: "EAP-GPSK", - 52: "EAP-pwd", - 53: "EAP-EKE Version 1", - 54: "EAP Method Type for PT-EAP", - 55: "TEAP", - 254: "Reserved for the Expanded Type", - 255: "Experimental", -} - - -######################################################################### -# -# EAP codes -# http://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml#eap-numbers-1 -######################################################################### -# - -eap_codes = { - 1: "Request", - 2: "Response", - 3: "Success", - 4: "Failure", - 5: "Initiate", - 6: "Finish" -} - - -class EAP(Packet): - """ - RFC 3748 - Extensible Authentication Protocol (EAP) - """ - - name = "EAP" - fields_desc = [ - ByteEnumField("code", 4, eap_codes), - ByteField("id", 0), - ShortField("len", None), - ConditionalField(ByteEnumField("type", 0, eap_types), - lambda pkt:pkt.code not in [ - EAP.SUCCESS, EAP.FAILURE]), - ConditionalField(FieldListField( - "desired_auth_types", - [], - ByteEnumField("auth_type", 0, eap_types), - length_from=lambda pkt: pkt.len - 4 - ), - lambda pkt:pkt.code == EAP.RESPONSE and pkt.type == 3), # noqa: E501 - ConditionalField( - StrLenField("identity", '', length_from=lambda pkt: pkt.len - 5), - lambda pkt: pkt.code == EAP.RESPONSE and hasattr(pkt, 'type') and pkt.type == 1), # noqa: E501 - ConditionalField( - StrLenField("message", '', length_from=lambda pkt: pkt.len - 5), - lambda pkt: pkt.code == EAP.REQUEST and hasattr(pkt, 'type') and pkt.type == 1) # noqa: E501 - ] - - ######################################################################### - # - # EAP codes - # http://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml#eap-numbers-1 - ######################################################################### - # - - REQUEST = 1 - RESPONSE = 2 - SUCCESS = 3 - FAILURE = 4 - INITIATE = 5 - FINISH = 6 - - registered_methods = {} - - @classmethod - def register_variant(cls): - cls.registered_methods[cls.type.default] = cls - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt: - c = orb(_pkt[0]) - if c in [1, 2] and len(_pkt) >= 5: - t = orb(_pkt[4]) - return cls.registered_methods.get(t, cls) - return cls - - def haslayer(self, cls): - if cls == "EAP": - if isinstance(self, EAP): - return True - elif issubtype(cls, EAP): - if isinstance(self, cls): - return True - return super(EAP, self).haslayer(cls) - - def getlayer(self, cls, nb=1, _track=None, _subclass=True, **flt): - return super(EAP, self).getlayer(cls, nb=nb, _track=_track, - _subclass=True, **flt) - - 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 mysummary(self): - summary_str = "EAP %{eap_class}.code% %{eap_class}.type%".format( - eap_class=self.__class__.__name__ - ) - if self.type == 1 and self.code == EAP.RESPONSE: - summary_str += " %{eap_class}.identity%".format( - eap_class=self.__class__.__name__ - ) - return self.sprintf(summary_str) - - def post_build(self, p, pay): - if self.len is None: - tmp_len = len(p) + len(pay) - tmp_p = p[:2] + chb((tmp_len >> 8) & 0xff) + chb(tmp_len & 0xff) - p = tmp_p + p[4:] - return p + pay - - def guess_payload_class(self, _): - return Padding - - -class EAP_MD5(EAP): - """ - RFC 3748 - "Extensible Authentication Protocol (EAP)" - """ - - name = "EAP-MD5" - fields_desc = [ - ByteEnumField("code", 1, eap_codes), - ByteField("id", 0), - FieldLenField("len", None, fmt="H", length_of="optional_name", - adjust=lambda p, x: x + 6 + (p.value_size or 0)), - ByteEnumField("type", 4, eap_types), - FieldLenField("value_size", None, fmt="B", length_of="value"), - XStrLenField("value", '', length_from=lambda p: p.value_size), - XStrLenField("optional_name", '', length_from=lambda p: 0 if p.len is None or p.value_size is None else (p.len - p.value_size - 6)) # noqa: E501 - ] - - -class EAP_TLS(EAP): - """ - RFC 5216 - "The EAP-TLS Authentication Protocol" - """ - - name = "EAP-TLS" - fields_desc = [ - ByteEnumField("code", 1, eap_codes), - ByteField("id", 0), - FieldLenField("len", None, fmt="H", length_of="tls_data", - adjust=lambda p, x: x + 10 if p.L == 1 else x + 6), - ByteEnumField("type", 13, eap_types), - BitField('L', 0, 1), - BitField('M', 0, 1), - BitField('S', 0, 1), - BitField('reserved', 0, 5), - ConditionalField(IntField('tls_message_len', 0), lambda pkt: pkt.L == 1), # noqa: E501 - XStrLenField('tls_data', '', length_from=lambda pkt: 0 if pkt.len is None else pkt.len - (6 + 4 * pkt.L)) # noqa: E501 - ] - - -class EAP_TTLS(EAP): - """ - RFC 5281 - "Extensible Authentication Protocol Tunneled Transport Layer - Security Authenticated Protocol Version 0 (EAP-TTLSv0)" - """ - - name = "EAP-TTLS" - fields_desc = [ - ByteEnumField("code", 1, eap_codes), - ByteField("id", 0), - FieldLenField("len", None, fmt="H", length_of="data", - adjust=lambda p, x: x + 10 if p.L == 1 else x + 6), - ByteEnumField("type", 21, eap_types), - BitField("L", 0, 1), - BitField("M", 0, 1), - BitField("S", 0, 1), - BitField("reserved", 0, 2), - BitField("version", 0, 3), - ConditionalField(IntField("message_len", 0), lambda pkt: pkt.L == 1), - XStrLenField("data", "", length_from=lambda pkt: 0 if pkt.len is None else pkt.len - (6 + 4 * pkt.L)) # noqa: E501 - ] - - -class EAP_PEAP(EAP): - """ - draft-josefsson-pppext-eap-tls-eap-05.txt - "Protected EAP Protocol (PEAP)" - """ - - name = "PEAP" - fields_desc = [ - ByteEnumField("code", 1, eap_codes), - ByteField("id", 0), - FieldLenField("len", None, fmt="H", length_of="tls_data", - adjust=lambda p, x: x + 10 if p.L == 1 else x + 6), - ByteEnumField("type", 25, eap_types), - BitField("L", 0, 1), - BitField("M", 0, 1), - BitField("S", 0, 1), - BitField("reserved", 0, 3), - BitField("version", 1, 2), - ConditionalField(IntField("tls_message_len", 0), lambda pkt: pkt.L == 1), # noqa: E501 - XStrLenField("tls_data", "", length_from=lambda pkt: 0 if pkt.len is None else pkt.len - (6 + 4 * pkt.L)) # noqa: E501 - ] - - -class EAP_FAST(EAP): - """ - RFC 4851 - "The Flexible Authentication via Secure Tunneling - Extensible Authentication Protocol Method (EAP-FAST)" - """ - - name = "EAP-FAST" - fields_desc = [ - ByteEnumField("code", 1, eap_codes), - ByteField("id", 0), - FieldLenField("len", None, fmt="H", length_of="data", - adjust=lambda p, x: x + 10 if p.L == 1 else x + 6), - ByteEnumField("type", 43, eap_types), - BitField('L', 0, 1), - BitField('M', 0, 1), - BitField('S', 0, 1), - BitField('reserved', 0, 2), - BitField('version', 0, 3), - ConditionalField(IntField('message_len', 0), lambda pkt: pkt.L == 1), - XStrLenField('data', '', length_from=lambda pkt: 0 if pkt.len is None else pkt.len - (6 + 4 * pkt.L)) # noqa: E501 - ] - - -class LEAP(EAP): - """ - Cisco LEAP (Lightweight EAP) - https://freeradius.org/rfc/leap.txt - """ - - name = "Cisco LEAP" - fields_desc = [ - ByteEnumField("code", 1, eap_codes), - ByteField("id", 0), - ShortField("len", None), - ByteEnumField("type", 17, eap_types), - ByteField('version', 1), - XByteField('unused', 0), - FieldLenField("count", None, "challenge_response", "B", adjust=lambda p, x: len(p.challenge_response)), # noqa: E501 - XStrLenField("challenge_response", "", length_from=lambda p: 0 or p.count), # noqa: E501 - StrLenField("username", "", length_from=lambda p: p.len - (8 + (0 or p.count))) # noqa: E501 - ] - - -############################################################################# -# IEEE 802.1X-2010 - MACsec Key Agreement (MKA) protocol -############################################################################# - -######################################################################### -# -# IEEE 802.1X-2010 standard -# Section 11.11.1 -######################################################################### -# - -_parameter_set_types = { - 1: "Live Peer List", - 2: "Potential Peer List", - 3: "MACsec SAK Use", - 4: "Distributed SAK", - 5: "Distributed CAK", - 6: "KMD", - 7: "Announcement", - 255: "ICV Indicator" -} - - -# Used by MKAParamSet::dispatch_hook() to instantiate the appropriate class -_param_set_cls = { - 1: "MKALivePeerListParamSet", - 2: "MKAPotentialPeerListParamSet", - 3: "MKASAKUseParamSet", - 4: "MKADistributedSAKParamSet", - 255: "MKAICVSet", -} - - -class MACsecSCI(Packet): - """ - Secure Channel Identifier. - """ - - ######################################################################### - # - # IEEE 802.1AE-2006 standard - # Section 9.9 - ######################################################################### - # - - name = "SCI" - fields_desc = [ - SourceMACField("system_identifier"), - ShortField("port_identifier", 0) - ] - - def extract_padding(self, s): - return "", s - - -class MKAParamSet(Packet): - """ - Class from which every parameter set class inherits (except - MKABasicParamSet, which has no "Parameter set type" field, and must - come first in the list of parameter sets). - """ - - MACSEC_DEFAULT_ICV_LEN = 16 - EAPOL_MKA_DEFAULT_KEY_WRAP_LEN = 24 - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - """ - Returns the right parameter set class. - """ - - cls = conf.raw_layer - if _pkt is not None: - ptype = orb(_pkt[0]) - return globals().get(_param_set_cls.get(ptype), conf.raw_layer) - - return cls - - -class MKABasicParamSet(Packet): - """ - Basic Parameter Set (802.1X-2010, section 11.11). - """ - - ######################################################################### - # - # IEEE 802.1X-2010 standard - # Section 11.11 - ######################################################################### - # - - name = "Basic Parameter Set" - fields_desc = [ - ByteField("mka_version_id", 0), - ByteField("key_server_priority", 0), - BitField("key_server", 0, 1), - BitField("macsec_desired", 0, 1), - BitField("macsec_capability", 0, 2), - BitField("param_set_body_len", 0, 12), - PacketField("SCI", MACsecSCI(), MACsecSCI), - XStrFixedLenField("actor_member_id", "", length=12), - XIntField("actor_message_number", 0), - XIntField("algorithm_agility", 0), - PadField( - XStrLenField( - "cak_name", - "", - length_from=lambda pkt: (pkt.param_set_body_len - 28) - ), - 4, - padwith=b"\x00" - ) - ] - - def extract_padding(self, s): - return "", s - - -class MKAPeerListTuple(Packet): - """ - Live / Potential Peer List parameter sets tuples (802.1X-2010, section 11.11). # noqa: E501 - """ - - name = "Peer List Tuple" - fields_desc = [ - XStrFixedLenField("member_id", "", length=12), - XStrFixedLenField("message_number", "", length=4), - ] - - -class MKALivePeerListParamSet(MKAParamSet): - """ - Live Peer List parameter sets (802.1X-2010, section 11.11). - """ - - ######################################################################### - # - # IEEE 802.1X-2010 standard - # Section 11.11 - ######################################################################### - # - - name = "Live Peer List Parameter Set" - fields_desc = [ - PadField( - ByteEnumField( - "param_set_type", - 1, - _parameter_set_types - ), - 2, - padwith=b"\x00" - ), - ShortField("param_set_body_len", 0), - PacketListField("member_id_message_num", [], MKAPeerListTuple) - ] - - -class MKAPotentialPeerListParamSet(MKAParamSet): - """ - Potential Peer List parameter sets (802.1X-2010, section 11.11). - """ - - ######################################################################### - # - # IEEE 802.1X-2010 standard - # Section 11.11 - ######################################################################### - # - - name = "Potential Peer List Parameter Set" - fields_desc = [ - PadField( - ByteEnumField( - "param_set_type", - 2, - _parameter_set_types - ), - 2, - padwith=b"\x00" - ), - ShortField("param_set_body_len", 0), - PacketListField("member_id_message_num", [], MKAPeerListTuple) - ] - - -class MKASAKUseParamSet(MKAParamSet): - """ - SAK Use Parameter Set (802.1X-2010, section 11.11). - """ - - ######################################################################### - # - # IEEE 802.1X-2010 standard - # Section 11.11 - ######################################################################### - # - - name = "SAK Use Parameter Set" - fields_desc = [ - ByteEnumField("param_set_type", 3, _parameter_set_types), - BitField("latest_key_an", 0, 2), - BitField("latest_key_tx", 0, 1), - BitField("latest_key_rx", 0, 1), - BitField("old_key_an", 0, 2), - BitField("old_key_tx", 0, 1), - BitField("old_key_rx", 0, 1), - BitField("plain_tx", 0, 1), - BitField("plain_rx", 0, 1), - BitField("X", 0, 1), - BitField("delay_protect", 0, 1), - BitField("param_set_body_len", 0, 12), - XStrFixedLenField("latest_key_key_server_member_id", "", length=12), - XStrFixedLenField("latest_key_key_number", "", length=4), - XStrFixedLenField("latest_key_lowest_acceptable_pn", "", length=4), - XStrFixedLenField("old_key_key_server_member_id", "", length=12), - XStrFixedLenField("old_key_key_number", "", length=4), - XStrFixedLenField("old_key_lowest_acceptable_pn", "", length=4) - ] - - -class MKADistributedSAKParamSet(MKAParamSet): - """ - Distributed SAK parameter set (802.1X-2010, section 11.11). - """ - - ######################################################################### - # - # IEEE 802.1X-2010 standard - # Section 11.11 - ######################################################################### - # - - name = "Distributed SAK parameter set" - fields_desc = [ - ByteEnumField("param_set_type", 4, _parameter_set_types), - BitField("distributed_an", 0, 2), - BitField("confidentiality_offset", 0, 2), - BitField("unused", 0, 4), - ShortField("param_set_body_len", 0), - XStrFixedLenField("key_number", "", length=4), - ConditionalField( - XStrFixedLenField("macsec_cipher_suite", "", length=8), - lambda pkt: pkt.param_set_body_len > 28 - ), - XStrFixedLenField( - "sak_aes_key_wrap", - "", - length=MKAParamSet.EAPOL_MKA_DEFAULT_KEY_WRAP_LEN - ) - ] - - -class MKADistributedCAKParamSet(MKAParamSet): - """ - Distributed CAK Parameter Set (802.1X-2010, section 11.11). - """ - - ######################################################################### - # - # IEEE 802.1X-2010 standard - # Section 11.11 - ######################################################################### - # - - name = "Distributed CAK parameter set" - fields_desc = [ - PadField( - ByteEnumField( - "param_set_type", - 5, - _parameter_set_types - ), - 2, - padwith=b"\x00" - ), - ShortField("param_set_body_len", 0), - XStrFixedLenField( - "cak_aes_key_wrap", - "", - length=MKAParamSet.EAPOL_MKA_DEFAULT_KEY_WRAP_LEN - ), - XStrField("cak_key_name", "") - ] - - -class MKAICVSet(MKAParamSet): - """ - ICV (802.1X-2010, section 11.11). - """ - - ######################################################################### - # - # IEEE 802.1X-2010 standard - # Section 11.11 - ######################################################################### - # - - name = "ICV" - fields_desc = [ - PadField( - ByteEnumField( - "param_set_type", - 255, - _parameter_set_types - ), - 2, - padwith=b"\x00" - ), - ShortField("param_set_body_len", 0), - XStrFixedLenField("icv", "", length=MKAParamSet.MACSEC_DEFAULT_ICV_LEN) - ] - - -class MKAParamSetPacketListField(PacketListField): - """ - PacketListField that handles the parameter sets. - """ - - PARAM_SET_LEN_MASK = 0b0000111111111111 - - def m2i(self, pkt, m): - return MKAParamSet(m) - - def getfield(self, pkt, s): - lst = [] - remain = s - - while remain: - len_bytes = struct.unpack("!H", remain[2:4])[0] - param_set_len = self.__class__.PARAM_SET_LEN_MASK & len_bytes - current = remain[:4 + param_set_len] - remain = remain[4 + param_set_len:] - current_packet = self.m2i(pkt, current) - lst.append(current_packet) - - return remain, lst - - -class MKAPDU(Packet): - """ - MACsec Key Agreement Protocol Data Unit. - """ - - ######################################################################### - # - # IEEE 802.1X-2010 standard - # Section 11.11 - ######################################################################### - # - - name = "MKPDU" - fields_desc = [ - PacketField("basic_param_set", "", MKABasicParamSet), - MKAParamSetPacketListField("parameter_sets", [], MKAParamSet), - ] - - def extract_padding(self, s): - return "", s - - -bind_layers(Ether, EAPOL, type=34958) -bind_layers(Ether, EAPOL, dst='01:80:c2:00:00:03', type=34958) -bind_layers(CookedLinux, EAPOL, proto=34958) -bind_layers(GRE, EAPOL, proto=34958) -bind_layers(EAPOL, EAP, type=0) -bind_layers(SNAP, EAPOL, code=34958) -bind_layers(EAPOL, MKAPDU, type=5) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/gprs.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/gprs.py deleted file mode 100644 index 8a35efae5c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/gprs.py +++ /dev/null @@ -1,22 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -GPRS (General Packet Radio Service) for mobile data communication. -""" - -from scapy.fields import StrStopField -from scapy.packet import Packet, bind_layers -from scapy.layers.inet import IP - - -class GPRS(Packet): - name = "GPRSdummy" - fields_desc = [ - StrStopField("dummy", "", b"\x65\x00\x00", 1) - ] - - -bind_layers(GPRS, IP,) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/hsrp.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/hsrp.py deleted file mode 100644 index 791a1cfeff..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/hsrp.py +++ /dev/null @@ -1,89 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# 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. # noqa: E501 -""" - -from scapy.fields import ByteEnumField, ByteField, IPField, SourceIPField, \ - StrFixedLenField, XIntField, XShortField -from scapy.packet import Packet, bind_layers, bind_bottom_up -from scapy.layers.inet import DestIPField, UDP -from scapy.layers.inet6 import DestIP6Field - - -class HSRP(Packet): - name = "HSRP" - fields_desc = [ - ByteField("version", 0), - ByteEnumField("opcode", 0, {0: "Hello", 1: "Coup", 2: "Resign", 3: "Advertise"}), # noqa: E501 - ByteEnumField("state", 16, {0: "Initial", 1: "Learn", 2: "Listen", 4: "Speak", 8: "Standby", 16: "Active"}), # noqa: E501 - ByteField("hellotime", 3), - ByteField("holdtime", 10), - ByteField("priority", 120), - ByteField("group", 1), - ByteField("reserved", 0), - StrFixedLenField("auth", b"cisco" + b"\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), - SourceIPField("sourceip", None), - XIntField("keyid", 0x00), - StrFixedLenField("authdigest", b"\00" * 16, 16)] - - def post_build(self, p, pay): - if self.len is None and pay: - tmp_len = len(pay) - p = p[:1] + hex(tmp_len)[30:] + p[30:] - return p - - -bind_bottom_up(UDP, HSRP, dport=1985) -bind_bottom_up(UDP, HSRP, sport=1985) -bind_bottom_up(UDP, HSRP, dport=2029) -bind_bottom_up(UDP, HSRP, sport=2029) -bind_layers(UDP, HSRP, dport=1985, sport=1985) -bind_layers(UDP, HSRP, dport=2029, sport=2029) -DestIPField.bind_addr(UDP, "224.0.0.2", dport=1985) -DestIP6Field.bind_addr(UDP, "ff02::66", dport=2029) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/http.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/http.py deleted file mode 100644 index 444b0a8503..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/http.py +++ /dev/null @@ -1,620 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) 2019 Gabriel Potter -# Copyright (C) 2012 Luca Invernizzi -# Copyright (C) 2012 Steeve Barbeau - -# This program is published under a GPLv2 license - -""" -HTTP 1.0 layer. - -Load using: ->>> load_layer("http") -Note that this layer ISN'T loaded by default, as quite experimental for now. - -To follow HTTP packets streams = group packets together to get the -whole request/answer, use `TCPSession` as: ->>> sniff(session=TCPSession) # Live on-the-flow session ->>> sniff(offline="./http_chunk.pcap", session=TCPSession) # pcap - -This will decode HTTP packets using `Content_Length` or chunks, -and will also decompress the packets when needed. -Note: on failure, decompression will be ignored. - -You can turn auto-decompression/auto-compression off with: ->>> conf.contribs["http"]["auto_compression"] = True -""" - -# This file is a modified version of the former scapy_http plugin. -# It was reimplemented for scapy 2.4.3+ using sessions, stream handling. -# Original Authors : Steeve Barbeau, Luca Invernizzi -# Originally published under a GPLv2 license - -import os -import re -import subprocess - -from scapy.compat import plain_str, bytes_encode, \ - gzip_compress, gzip_decompress -from scapy.config import conf -from scapy.consts import WINDOWS -from scapy.error import warning -from scapy.fields import StrField -from scapy.packet import Packet, bind_layers, bind_bottom_up, Raw -from scapy.utils import get_temp_file, ContextManagerSubprocess - -from scapy.layers.inet import TCP, TCP_client - -from scapy.modules import six - -if "http" not in conf.contribs: - conf.contribs["http"] = {} - conf.contribs["http"]["auto_compression"] = True - -# https://en.wikipedia.org/wiki/List_of_HTTP_header_fields - -GENERAL_HEADERS = [ - "Cache-Control", - "Connection", - "Permanent", - "Content-Length", - "Content-MD5", - "Content-Type", - "Date", - "Keep-Alive", - "Pragma", - "Upgrade", - "Via", - "Warning" -] - -COMMON_UNSTANDARD_GENERAL_HEADERS = [ - "X-Request-ID", - "X-Correlation-ID" -] - -REQUEST_HEADERS = [ - "A-IM", - "Accept", - "Accept-Charset", - "Accept-Encoding", - "Accept-Language", - "Accept-Datetime", - "Access-Control-Request-Method", - "Access-Control-Request-Headers", - "Authorization", - "Cookie", - "Expect", - "Forwarded", - "From", - "Host", - "HTTP2-Settings", - "If-Match", - "If-Modified-Since", - "If-None-Match", - "If-Range", - "If-Unmodified-Since", - "Max-Forwards", - "Origin", - "Proxy-Authorization", - "Range", - "Referer", - "TE", - "User-Agent" -] - -COMMON_UNSTANDARD_REQUEST_HEADERS = [ - "Upgrade-Insecure-Requests", - "Upgrade-Insecure-Requests", - "X-Requested-With", - "DNT", - "X-Forwarded-For", - "X-Forwarded-Host", - "X-Forwarded-Proto", - "Front-End-Https", - "X-Http-Method-Override", - "X-ATT-DeviceId", - "X-Wap-Profile", - "Proxy-Connection", - "X-UIDH", - "X-Csrf-Token", - "Save-Data", -] - -RESPONSE_HEADERS = [ - "Access-Control-Allow-Origin", - "Access-Control-Allow-Credentials", - "Access-Control-Expose-Headers", - "Access-Control-Max-Age", - "Access-Control-Allow-Methods", - "Access-Control-Allow-Headers", - "Accept-Patch", - "Accept-Ranges", - "Age", - "Allow", - "Alt-Svc", - "Content-Disposition", - "Content-Encoding", - "Content-Language", - "Content-Location", - "Content-Range", - "Delta-Base", - "ETag", - "Expires", - "IM", - "Last-Modified", - "Link", - "Location", - "Permanent", - "P3P", - "Proxy-Authenticate", - "Public-Key-Pins", - "Retry-After", - "Server", - "Set-Cookie", - "Strict-Transport-Security", - "Trailer", - "Transfer-Encoding", - "Tk", - "Vary", - "WWW-Authenticate", - "X-Frame-Options", -] - -COMMON_UNSTANDARD_RESPONSE_HEADERS = [ - "Content-Security-Policy", - "X-Content-Security-Policy", - "X-WebKit-CSP", - "Refresh", - "Status", - "Timing-Allow-Origin", - "X-Content-Duration", - "X-Content-Type-Options", - "X-Powered-By", - "X-UA-Compatible", - "X-XSS-Protection", -] - -# Dissection / Build tools - - -def _strip_header_name(name): - """Takes a header key (i.e., "Host" in "Host: www.google.com", - and returns a stripped representation of it - """ - return plain_str(name.strip()).replace("-", "_") - - -def _header_line(name, val): - """Creates a HTTP header line""" - # Python 3.4 doesn't support % on bytes - return bytes_encode(name) + b": " + bytes_encode(val) - - -def _parse_headers(s): - headers = s.split(b"\r\n") - headers_found = {} - for header_line in headers: - try: - key, value = header_line.split(b':', 1) - except ValueError: - continue - header_key = _strip_header_name(key).lower() - headers_found[header_key] = (key, value.strip()) - return headers_found - - -def _parse_headers_and_body(s): - ''' Takes a HTTP packet, and returns a tuple containing: - _ the first line (e.g., "GET ...") - _ the headers in a dictionary - _ the body - ''' - crlfcrlf = b"\r\n\r\n" - crlfcrlfIndex = s.find(crlfcrlf) - if crlfcrlfIndex != -1: - headers = s[:crlfcrlfIndex + len(crlfcrlf)] - body = s[crlfcrlfIndex + len(crlfcrlf):] - else: - headers = s - body = b'' - first_line, headers = headers.split(b"\r\n", 1) - return first_line.strip(), _parse_headers(headers), body - - -def _dissect_headers(obj, s): - """Takes a HTTP packet as the string s, and populates the scapy layer obj - (either HTTPResponse or HTTPRequest). Returns the first line of the - HTTP packet, and the body - """ - first_line, headers, body = _parse_headers_and_body(s) - for f in obj.fields_desc: - # We want to still parse wrongly capitalized fields - stripped_name = _strip_header_name(f.name).lower() - try: - _, value = headers.pop(stripped_name) - except KeyError: - continue - obj.setfieldval(f.name, value) - if headers: - headers = {key: value for key, value in six.itervalues(headers)} - obj.setfieldval('Unknown_Headers', headers) - return first_line, body - - -class _HTTPContent(Packet): - # https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Transfer-Encoding - def _get_encodings(self): - encodings = [] - if isinstance(self, HTTPResponse): - if self.Transfer_Encoding: - encodings += [plain_str(x).strip().lower() for x in - plain_str(self.Transfer_Encoding).split(",")] - if self.Content_Encoding: - encodings += [plain_str(x).strip().lower() for x in - plain_str(self.Content_Encoding).split(",")] - return encodings - - def hashret(self): - # The only field both Answers and Responses have in common - return self.Http_Version - - def post_dissect(self, s): - if not conf.contribs["http"]["auto_compression"]: - return s - encodings = self._get_encodings() - # Un-chunkify - if "chunked" in encodings: - data = b"" - while s: - length, _, body = s.partition(b"\r\n") - try: - length = int(length, 16) - except ValueError: - # Not a valid chunk. Ignore - break - else: - load = body[:length] - if body[length:length + 2] != b"\r\n": - # Invalid chunk. Ignore - break - s = body[length + 2:] - data += load - if not s: - s = data - # Decompress - try: - if "deflate" in encodings: - import zlib - s = zlib.decompress(s) - elif "gzip" in encodings: - s = gzip_decompress(s) - elif "compress" in encodings: - import lzw - s = lzw.decompress(s) - except Exception: - # Cannot decompress - probably incomplete data - pass - return s - - def post_build(self, pkt, pay): - if not conf.contribs["http"]["auto_compression"]: - return pkt + pay - encodings = self._get_encodings() - # Compress - if "deflate" in encodings: - import zlib - pay = zlib.compress(pay) - elif "gzip" in encodings: - pay = gzip_compress(pay) - elif "compress" in encodings: - import lzw - pay = lzw.compress(pay) - return pkt + pay - - def self_build(self, field_pos_list=None): - ''' Takes an HTTPRequest or HTTPResponse object, and creates its - string representation.''' - if not isinstance(self.underlayer, HTTP): - warning( - "An HTTPResponse/HTTPRequest should always be below an HTTP" - ) - # Check for cache - if self.raw_packet_cache is not None: - return self.raw_packet_cache - p = b"" - # Walk all the fields, in order - for f in self.fields_desc: - if f.name == "Unknown_Headers": - continue - # Get the field value - val = self.getfieldval(f.name) - if not val: - # Not specified. Skip - continue - if f.name not in ['Method', 'Path', 'Reason_Phrase', - 'Http_Version', 'Status_Code']: - val = _header_line(f.real_name, val) - # Fields used in the first line have a space as a separator, - # whereas headers are terminated by a new line - if isinstance(self, HTTPRequest): - if f.name in ['Method', 'Path']: - separator = b' ' - else: - separator = b'\r\n' - elif isinstance(self, HTTPResponse): - if f.name in ['Http_Version', 'Status_Code']: - separator = b' ' - else: - separator = b'\r\n' - # Add the field into the packet - p = f.addfield(self, p, val + separator) - # Handle Unknown_Headers - if self.Unknown_Headers: - headers_text = b"" - for name, value in six.iteritems(self.Unknown_Headers): - headers_text += _header_line(name, value) + b"\r\n" - p = self.get_field("Unknown_Headers").addfield( - self, p, headers_text - ) - # The packet might be empty, and in that case it should stay empty. - if p: - # Add an additional line after the last header - p = f.addfield(self, p, b'\r\n') - return p - - -class _HTTPHeaderField(StrField): - """Modified StrField to handle HTTP Header names""" - __slots__ = ["real_name"] - - def __init__(self, name, default): - self.real_name = name - name = _strip_header_name(name) - StrField.__init__(self, name, default, fmt="H") - - -def _generate_headers(*args): - """Generate the header fields based on their name""" - # Order headers - all_headers = [] - for headers in args: - all_headers += headers - # Generate header fields - results = [] - for h in sorted(all_headers): - results.append(_HTTPHeaderField(h, None)) - return results - -# Create Request and Response packets - - -class HTTPRequest(_HTTPContent): - name = "HTTP Request" - fields_desc = [ - # First line - _HTTPHeaderField("Method", "GET"), - _HTTPHeaderField("Path", "/"), - _HTTPHeaderField("Http-Version", "HTTP/1.1"), - # Headers - ] + ( - _generate_headers( - GENERAL_HEADERS, - REQUEST_HEADERS, - COMMON_UNSTANDARD_GENERAL_HEADERS, - COMMON_UNSTANDARD_REQUEST_HEADERS - ) - ) + [ - _HTTPHeaderField("Unknown-Headers", None), - ] - - def do_dissect(self, s): - """From the HTTP packet string, populate the scapy object""" - first_line, body = _dissect_headers(self, s) - try: - Method, Path, HTTPVersion = re.split(br"\s+", first_line, 2) - self.setfieldval('Method', Method) - self.setfieldval('Path', Path) - self.setfieldval('Http_Version', HTTPVersion) - except ValueError: - pass - if body: - self.raw_packet_cache = s[:-len(body)] - else: - self.raw_packet_cache = s - return body - - def mysummary(self): - return self.sprintf( - "%HTTPRequest.Method% %HTTPRequest.Path% " - "%HTTPRequest.Http_Version%" - ) - - -class HTTPResponse(_HTTPContent): - name = "HTTP Response" - fields_desc = [ - # First line - _HTTPHeaderField("Http-Version", "HTTP/1.1"), - _HTTPHeaderField("Status-Code", "200"), - _HTTPHeaderField("Reason-Phrase", "OK"), - # Headers - ] + ( - _generate_headers( - GENERAL_HEADERS, - RESPONSE_HEADERS, - COMMON_UNSTANDARD_GENERAL_HEADERS, - COMMON_UNSTANDARD_RESPONSE_HEADERS - ) - ) + [ - _HTTPHeaderField("Unknown-Headers", None), - ] - - def answers(self, other): - return HTTPRequest in other - - def do_dissect(self, s): - ''' From the HTTP packet string, populate the scapy object ''' - first_line, body = _dissect_headers(self, s) - try: - HTTPVersion, Status, Reason = re.split(br"\s+", first_line, 2) - self.setfieldval('Http_Version', HTTPVersion) - self.setfieldval('Status_Code', Status) - self.setfieldval('Reason_Phrase', Reason) - except ValueError: - pass - if body: - self.raw_packet_cache = s[:-len(body)] - else: - self.raw_packet_cache = s - return body - - def mysummary(self): - return self.sprintf( - "%HTTPResponse.Http_Version% %HTTPResponse.Status_Code% " - "%HTTPResponse.Reason_Phrase%" - ) - -# General HTTP class + defragmentation - - -class HTTP(Packet): - name = "HTTP 1" - fields_desc = [] - show_indent = 0 - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and False: - # XXX TODO - from scapy.contrib.contrib.http2 import H2Frame - return H2Frame - return cls - - # tcp_reassemble is used by TCPSession in session.py - @classmethod - def tcp_reassemble(cls, data, metadata): - detect_end = metadata.get("detect_end", None) - is_unknown = metadata.get("detect_unknown", True) - if not detect_end or is_unknown: - metadata["detect_unknown"] = False - http_packet = HTTP(data) - # Detect packing method - if not isinstance(http_packet.payload, _HTTPContent): - return http_packet - length = http_packet.Content_Length - if length is not None: - # The packet provides a Content-Length attribute: let's - # use it. When the total size of the frags is high enough, - # we have the packet - length = int(length) - # Subtract the length of the "HTTP*" layer - if http_packet.payload.payload or length == 0: - http_length = len(data) - len(http_packet.payload.payload) - detect_end = lambda dat: len(dat) - http_length >= length - else: - # The HTTP layer isn't fully received. - detect_end = lambda dat: False - metadata["detect_unknown"] = True - else: - # It's not Content-Length based. It could be chunked - encodings = http_packet[HTTP].payload._get_encodings() - chunked = ("chunked" in encodings) - if chunked: - detect_end = lambda dat: dat.endswith(b"\r\n\r\n") - else: - # If neither Content-Length nor chunked is specified, - # it means it's the TCP packet that contains the data, - # or that the information hasn't been given yet. - detect_end = lambda dat: metadata.get("tcp_end", False) - metadata["detect_unknown"] = True - metadata["detect_end"] = detect_end - if detect_end(data): - return http_packet - else: - if detect_end(data): - http_packet = HTTP(data) - return http_packet - - def guess_payload_class(self, payload): - """Decides if the payload is an HTTP Request or Response, or - something else. - """ - try: - prog = re.compile( - br"^(?:OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT) " - br"(?:.+?) " - br"HTTP/\d\.\d$" - ) - crlfIndex = payload.index(b"\r\n") - req = payload[:crlfIndex] - result = prog.match(req) - if result: - return HTTPRequest - else: - prog = re.compile(br"^HTTP/\d\.\d \d\d\d .*$") - result = prog.match(req) - if result: - return HTTPResponse - except ValueError: - # Anything that isn't HTTP but on port 80 - pass - return Raw - - -def http_request(host, path="/", port=80, timeout=3, - display=False, verbose=None, **headers): - """Util to perform an HTTP request, using the TCP_client. - - :param host: the host to connect to - :param path: the path of the request (default /) - :param port: the port (default 80) - :param timeout: timeout before None is returned - :param display: display the resullt in the default browser (default False) - :param **headers: any additional headers passed to the request - - :returns: the HTTPResponse packet - """ - http_headers = { - "Accept_Encoding": b'gzip, deflate', - "Cache_Control": b'no-cache', - "Pragma": b'no-cache', - "Connection": b'keep-alive', - "Host": host, - "Path": path, - } - http_headers.update(headers) - req = HTTP() / HTTPRequest(**http_headers) - tcp_client = TCP_client.tcplink(HTTP, host, 80) - ans = None - try: - ans = tcp_client.sr1(req, timeout=timeout, verbose=verbose) - finally: - tcp_client.close() - if ans: - if display: - # Write file - file = get_temp_file(autoext=".html") - with open(file, "wb") as fd: - fd.write(ans.load) - # Open browser - if WINDOWS: - os.startfile(file) - else: - with ContextManagerSubprocess("http_request()", - conf.prog.universal_open): - subprocess.Popen([conf.prog.universal_open, file]) - else: - return ans - - -# Bindings - - -bind_bottom_up(TCP, HTTP, sport=80) -bind_bottom_up(TCP, HTTP, dport=80) -bind_layers(TCP, HTTP, sport=80, dport=80) - -bind_bottom_up(TCP, HTTP, sport=8080) -bind_bottom_up(TCP, HTTP, dport=8080) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/iapp.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/iapp.py deleted file mode 100644 index ba865da760..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/iapp.py +++ /dev/null @@ -1,18 +0,0 @@ -# TRex Change -from scapy.fields import * -from scapy.packet import * -from scapy.layers.l2 import SNAP -from scapy.layers.netflow import NetflowHeader - -class IAPP(Packet): - name = "IAPP Header" - fields_desc = [ - LenField("iapp_id_length", None, "H"), - ByteField("type", 0), - ByteField("subtype", 0), - MACField("dst_mac", ETHER_ANY), - MACField("src_mac", ETHER_ANY) - ] - -bind_layers( SNAP, IAPP, code=0 ) #code=0 is IAPP type -bind_layers( IAPP, NetflowHeader, type=0x63 ) #99 is Netflow \ No newline at end of file diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/inet.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/inet.py deleted file mode 100644 index ca5e771633..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/inet.py +++ /dev/null @@ -1,1946 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -IPv4 (Internet Protocol v4). -""" - -from __future__ import absolute_import -from __future__ import print_function -import time -import struct -import re -import random -import socket -from select import select -from collections import defaultdict - -from scapy.utils import checksum, do_graph, incremental_label, \ - linehexdump, strxor, whois, colgen -from scapy.base_classes import Gen, Net -from scapy.data import ETH_P_IP, ETH_P_ALL, DLT_RAW, DLT_RAW_ALT, DLT_IPV4, \ - IP_PROTOS, TCP_SERVICES, UDP_SERVICES -from scapy.layers.l2 import Ether, Dot3, getmacbyip, CookedLinux, GRE, SNAP, \ - Loopback -from scapy.compat import raw, chb, orb, bytes_encode -from scapy.config import conf -from scapy.extlib import plt, MATPLOTLIB, MATPLOTLIB_INLINED, \ - MATPLOTLIB_DEFAULT_PLOT_KARGS -from scapy.fields import ConditionalField, IPField, BitField, BitEnumField, \ - FieldLenField, StrLenField, ByteField, ShortField, ByteEnumField, \ - DestField, FieldListField, FlagsField, IntField, MultiEnumField, \ - PacketListField, ShortEnumField, SourceIPField, StrField, \ - StrFixedLenField, XByteField, XShortField, Emph -from scapy.packet import Packet, bind_layers, bind_bottom_up, NoPayload -from scapy.volatile import RandShort, RandInt, RandBin, RandNum, VolatileValue -from scapy.sendrecv import sr, sr1 -from scapy.plist import PacketList, SndRcvList -from scapy.automaton import Automaton, ATMT -from scapy.error import warning -from scapy.pton_ntop import inet_pton - -import scapy.as_resolvers - -import scapy.modules.six as six -from scapy.modules.six.moves import range - -#################### -# IP Tools class # -#################### - - -class IPTools(object): - """Add more powers to a class with an "src" attribute.""" - __slots__ = [] - - def whois(self): - """whois the source and print the output""" - print(whois(self.src).decode("utf8", "ignore")) - - def _ttl(self): - """Returns ttl or hlim, depending on the IP version""" - return self.hlim if isinstance(self, scapy.layers.inet6.IPv6) else self.ttl # noqa: E501 - - def ottl(self): - t = sorted([32, 64, 128, 255] + [self._ttl()]) - return t[t.index(self._ttl()) + 1] - - def hops(self): - return self.ottl() - self._ttl() - - -_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 # noqa: E501 - length_of="value", adjust=lambda pkt, l:l + 2), # noqa: E501 - StrLenField("value", "", length_from=lambda pkt:pkt.length - 2)] # noqa: E501 - - 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 = orb(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_RR(IPOption): - name = "IP Option Record Route" - option = 7 - fields_desc = [_IPOption_HDR, - FieldLenField("length", None, fmt="B", - length_of="routers", adjust=lambda pkt, l:l + 3), # noqa: E501 - 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_LSRR(IPOption_RR): - name = "IP Option Loose Source and Record Route" - copy_flag = 1 - option = 3 - - -class IPOption_SSRR(IPOption_RR): - name = "IP Option Strict Source and Record Route" - copy_flag = 1 - option = 9 - - -class IPOption_Stream_Id(IPOption): - name = "IP Option Stream ID" - copy_flag = 1 - 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" - 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"}), ] # noqa: E501 - - -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), # noqa: E501 - 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"), - 28: ("UTO", "!H"), - 34: ("TFO", "!II"), - # RFC 3692 - # 253: ("Experiment", "!HHHH"), - # 254: ("Experiment", "!HHHH"), - }, - {"EOL": 0, - "NOP": 1, - "MSS": 2, - "WScale": 3, - "SAckOK": 4, - "SAck": 5, - "Timestamp": 8, - "AltChkSum": 14, - "AltChkSumOpt": 15, - "Mood": 25, - "UTO": 28, - "TFO": 34, - }) - - -class RandTCPOptions(VolatileValue): - def __init__(self, size=None): - if size is None: - size = RandNum(1, 5) - self.size = size - - def _fix(self): - # Pseudo-Random amount of options - # Random ("NAME", fmt) - rand_patterns = [ - random.choice(list( - (opt, fmt) for opt, fmt in six.itervalues(TCPOptions[0]) - if opt != 'EOL' - )) - for _ in range(self.size) - ] - rand_vals = [] - for oname, fmt in rand_patterns: - if fmt is None: - rand_vals.append((oname, b'')) - else: - # Process the fmt arguments 1 by 1 - structs = fmt[1:] if fmt[0] == "!" else fmt - rval = [] - for stru in structs: - stru = "!" + stru - if "s" in stru or "p" in stru: # str / chr - v = bytes(RandBin(struct.calcsize(stru))) - else: # int - _size = struct.calcsize(stru) - v = random.randint(0, 2 ** (8 * _size) - 1) - rval.append(v) - rand_vals.append((oname, tuple(rval))) - return rand_vals - - def __bytes__(self): - return TCPOptionsField.i2m(None, None, self._fix()) - - -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 = orb(x[0]) - if onum == 0: - opt.append(("EOL", None)) - x = x[1:] - break - if onum == 1: - opt.append(("NOP", None)) - x = x[1:] - continue - try: - olen = orb(x[1]) - except IndexError: - olen = 0 - 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 i2h(self, pkt, x): - if not x: - return [] - return x - - def i2m(self, pkt, x): - opt = b"" - for oname, oval in x: - # We check for a (0, b'') or (1, b'') option first - oname = {0: "EOL", 1: "NOP"}.get(oname, oname) - if isinstance(oname, 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 += "%iI" % len(oval) - _test_isinstance = not isinstance(oval, (bytes, str)) - if ofmt is not None and (_test_isinstance or "s" in ofmt): - if not isinstance(oval, tuple): - oval = (oval,) - oval = struct.pack(ofmt, *oval) - else: - warning("option [%s] unknown. Skipped.", oname) - continue - else: - onum = oname - if not isinstance(onum, int): - warning("Invalid option number [%i]" % onum) - continue - if not isinstance(oval, (bytes, str)): - warning("option [%i] is not bytes." % onum) - continue - if isinstance(oval, str): - oval = bytes_encode(oval) - opt += chb(onum) + chb(2 + len(oval)) + oval - return opt + b"\x00" * (3 - ((len(opt) + 3) % 4)) # Padding - - def randval(self): - return RandTCPOptions() - - -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}))?)?)?$") # noqa: E501 - - 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 isinstance(val, 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 # noqa: E501 - else: - val = 0 - elif val is None: - val = int((time.time() % (24 * 60 * 60)) * 1000) - return val - - -class DestIPField(IPField, DestField): - bindings = {} - - def __init__(self, name, default): - IPField.__init__(self, name, None) - DestField.__init__(self, name, default) - - def i2m(self, pkt, x): - if x is None: - x = self.dst_from_pkt(pkt) - return IPField.i2m(self, pkt, x) - - def i2h(self, pkt, x): - if x is None: - x = self.dst_from_pkt(pkt) - return IPField.i2h(self, pkt, x) - - -class IP(Packet, IPTools): - __slots__ = ["_defrag_pos"] - 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), - # TRex Change - Put fixed Src and Dst to prevent from looking up the Src and Dst. - # IPField("src", "127.0.0.1"), - # Emph(SourceIPField("src", "dst")), - # Emph(DestIPField("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)] # noqa: E501 - - 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 = chb(((self.version & 0xf) << 4) | ihl & 0x0f) + p[1:] - if self.len is None: - tmp_len = len(p) + len(pay) - p = p[:2] + struct.pack("!H", tmp_len) + p[4:] - if self.chksum is None: - ck = checksum(p) - p = p[:10] + chb(ck >> 8) + chb(ck & 0xff) + p[12:] - return p + pay - - def extract_padding(self, s): - tmp_len = self.len - (self.ihl << 2) - if tmp_len < 0: - return s, b"" - return s[:tmp_len], s[tmp_len:] - - def route(self): - dst = self.dst - if isinstance(dst, Gen): - dst = next(iter(dst)) - if conf.route is None: - # unused import, only to initialize conf.route - import scapy.route # noqa: F401 - 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() - if not conf.checkIPinIP and self.proto in [4, 41]: # IP, IPv6 - return self.payload.hashret() - if self.dst == "224.0.0.251": # mDNS - return struct.pack("B", self.proto) + self.payload.hashret() - if conf.checkIPsrc and conf.checkIPaddr: - return (strxor(inet_pton(socket.AF_INET, self.src), - inet_pton(socket.AF_INET, self.dst)) + - struct.pack("B", self.proto) + self.payload.hashret()) - return struct.pack("B", self.proto) + self.payload.hashret() - - def answers(self, other): - if not conf.checkIPinIP: # skip IP in IP and IPv6 in IP - if self.proto in [4, 41]: - return self.payload.answers(other) - if isinstance(other, IP) and other.proto in [4, 41]: - return self.answers(other.payload) - if conf.ipv6_enabled \ - and isinstance(other, scapy.layers.inet6.IPv6) \ - and other.nh in [4, 41]: - return self.answers(other.payload) - if not isinstance(other, IP): - return 0 - if conf.checkIPaddr: - if other.dst == "224.0.0.251" and self.dst == "224.0.0.251": # mDNS # noqa: E501 - return self.payload.answers(other.payload) - elif (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 = raw(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[fnb].flags |= 1 - q[fnb].frag += i * fragsize // 8 - r = conf.raw_layer(load=s[i * fragsize:(i + 1) * fragsize]) - r.overload_fields = p[fnb].payload.overload_fields.copy() - q.add_payload(r) - lst.append(q) - return lst - - -def in4_chksum(proto, u, p): - """ - As Specified in RFC 2460 - 8.1 Upper-Layer Checksums - - Performs IPv4 Upper Layer checksum computation. Provided parameters are: - - 'proto' : value of upper layer protocol - - 'u' : IP upper layer instance - - 'p' : the payload of the upper layer provided as a string - """ - if not isinstance(u, IP): - warning("No IP underlayer to compute checksum. Leaving null.") - return 0 - if u.len is not None: - if u.ihl is None: - olen = sum(len(x) for x in u.options) - ihl = 5 + olen // 4 + (1 if olen % 4 else 0) - else: - ihl = u.ihl - ln = max(u.len - 4 * ihl, 0) - else: - ln = len(p) - psdhdr = struct.pack("!4s4sHH", - inet_pton(socket.AF_INET, u.src), - inet_pton(socket.AF_INET, u.dst), - proto, - ln) - return checksum(psdhdr + p) - - -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, 3), - FlagsField("flags", 0x2, 9, "FSRPAUECN"), - 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) # noqa: E501 - p = p[:12] + chb((dataofs << 4) | orb(p[12]) & 0x0f) + p[13:] - if self.chksum is None: - if isinstance(self.underlayer, IP): - ck = in4_chksum(socket.IPPROTO_TCP, self.underlayer, 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): # noqa: E501 - ck = scapy.layers.inet6.in6_chksum(socket.IPPROTO_TCP, self.underlayer, p) # noqa: E501 - 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() # noqa: E501 - else: - return self.payload.hashret() - - def answers(self, other): - if not isinstance(other, TCP): - return 0 - # RST packets don't get answers - if other.flags.R: - return 0 - # We do not support the four-way handshakes with the SYN+ACK - # answer split in two packets (one ACK and one SYN): in that - # case the ACK will be seen as an answer, but not the SYN. - if self.flags.S: - # SYN packets without ACK are not answers - if not self.flags.A: - return 0 - # SYN+ACK packets answer SYN packets - if not other.flags.S: - return 0 - if conf.checkIPsrc: - if not ((self.sport == other.dport) and - (self.dport == other.sport)): - return 0 - # Do not check ack value for SYN packets without ACK - if not (other.flags.S and not other.flags.A) \ - and abs(other.ack - self.seq) > 2: - return 0 - # Do not check ack value for RST packets without ACK - if self.flags.R and not self.flags.A: - return 1 - 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%") # noqa: E501 - elif conf.ipv6_enabled and isinstance(self.underlayer, scapy.layers.inet6.IPv6): # noqa: E501 - return self.underlayer.sprintf("TCP %IPv6.src%:%TCP.sport% > %IPv6.dst%:%TCP.dport% %TCP.flags%") # noqa: E501 - 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 - tmp_len = self.len - if tmp_len is None: - tmp_len = len(p) - p = p[:4] + struct.pack("!H", tmp_len) + p[6:] - if self.chksum is None: - if isinstance(self.underlayer, IP): - ck = in4_chksum(socket.IPPROTO_UDP, self.underlayer, p) - # According to RFC768 if the result checksum is 0, it should be set to 0xFFFF # noqa: E501 - if ck == 0: - ck = 0xFFFF - 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): # noqa: E501 - ck = scapy.layers.inet6.in6_chksum(socket.IPPROTO_UDP, self.underlayer, p) # noqa: E501 - # According to RFC2460 if the result checksum is 0, it should be set to 0xFFFF # noqa: E501 - if ck == 0: - ck = 0xFFFF - 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): - tmp_len = self.len - 8 - return s[:tmp_len], s[tmp_len:] - - 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%") # noqa: E501 - elif isinstance(self.underlayer, scapy.layers.inet6.IPv6): - return self.underlayer.sprintf("UDP %IPv6.src%:%UDP.sport% > %IPv6.dst%:%UDP.dport%") # noqa: E501 - 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", - 30: "traceroute", - 31: "datagram-conversion-error", - 32: "mobile-host-redirect", - 33: "ipv6-where-are-you", - 34: "ipv6-i-am-here", - 35: "mobile-registration-request", - 36: "mobile-registration-reply", - 37: "domain-name-request", - 38: "domain-name-reply", - 39: "skip", - 40: "photuris"} - - -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", }, - 40: {0: "bad-spi", - 1: "authentication-failed", - 2: "decompression-failed", - 3: "decryption-failed", - 4: "need-authentification", - 5: "need-authorization", }, } - - -class ICMP(Packet): - name = "ICMP" - fields_desc = [ByteEnumField("type", 8, icmptypes), - MultiEnumField("code", 0, icmpcodes, depends_on=lambda pkt:pkt.type, fmt="B"), # noqa: E501 - XShortField("chksum", None), - ConditionalField(XShortField("id", 0), lambda pkt:pkt.type in [0, 8, 13, 14, 15, 16, 17, 18]), # noqa: E501 - ConditionalField(XShortField("seq", 0), lambda pkt:pkt.type in [0, 8, 13, 14, 15, 16, 17, 18]), # noqa: E501 - ConditionalField(ICMPTimeStampField("ts_ori", None), lambda pkt:pkt.type in [13, 14]), # noqa: E501 - ConditionalField(ICMPTimeStampField("ts_rx", None), lambda pkt:pkt.type in [13, 14]), # noqa: E501 - ConditionalField(ICMPTimeStampField("ts_tx", None), lambda pkt:pkt.type in [13, 14]), # noqa: E501 - ConditionalField(IPField("gw", "0.0.0.0"), lambda pkt:pkt.type == 5), # noqa: E501 - ConditionalField(ByteField("ptr", 0), lambda pkt:pkt.type == 12), # noqa: E501 - ConditionalField(ByteField("reserved", 0), lambda pkt:pkt.type in [3, 11]), # noqa: E501 - ConditionalField(ByteField("length", 0), lambda pkt:pkt.type in [3, 11, 12]), # noqa: E501 - ConditionalField(IPField("addr_mask", "0.0.0.0"), lambda pkt:pkt.type in [17, 18]), # noqa: E501 - ConditionalField(ShortField("nexthopmtu", 0), lambda pkt:pkt.type == 3), # noqa: E501 - ConditionalField(ShortField("unused", 0), lambda pkt:pkt.type in [11, 12]), # noqa: E501 - ConditionalField(IntField("unused", 0), lambda pkt:pkt.type not in [0, 3, 5, 8, 11, 12, 13, 14, 15, 16, 17, 18]) # noqa: E501 - ] - - def post_build(self, p, pay): - p += pay - if self.chksum is None: - ck = checksum(p) - p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:] - return p - - def hashret(self): - if self.type in [0, 8, 13, 14, 15, 16, 17, 18, 33, 34, 35, 36, 37, 38]: - return struct.pack("HH", self.id, self.seq) + self.payload.hashret() # noqa: E501 - 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), (33, 34), (35, 36), (37, 38)] and # noqa: E501 - 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%") # noqa: E501 - 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 - - # Check if IP addresses match - test_IPsrc = not conf.checkIPsrc or self.src == other.src - test_IPdst = self.dst == other.dst - - # Check if IP ids match - test_IPid = not conf.checkIPID or self.id == other.id - test_IPid |= conf.checkIPID and self.id == socket.htons(other.id) - - # Check if IP protocols match - test_IPproto = self.proto == other.proto - - if not (test_IPsrc and test_IPdst and test_IPid and test_IPproto): - return 0 - - return self.payload.answers(other.payload) - - def mysummary(self): - return Packet.mysummary(self) - - -class TCPerror(TCP): - name = "TCP in ICMP" - - 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_bottom_up(Loopback, IP, type=0) -bind_layers(Loopback, IP, type=socket.AF_INET) -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(DLT_RAW, IP) -conf.l2types.register_num2layer(DLT_RAW_ALT, IP) -conf.l2types.register(DLT_IPV4, IP) - -conf.l3types.register(ETH_P_IP, IP) -conf.l3types.register_num2layer(ETH_P_ALL, IP) - - -def inet_register_l3(l2, l3): - return getmacbyip(l3.dst) - - -conf.neighbor.register_l3(Ether, IP, inet_register_l3) -conf.neighbor.register_l3(Dot3, IP, inet_register_l3) - - -################### -# 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 = raw(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 - 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 - - -@conf.commands.register -def overlap_frag(p, overlap, fragsize=8, overlap_fragsize=None): - """Build overlapping fragments to bypass NIPS - -p: the original packet -overlap: the overlapping data -fragsize: the fragment size of the packet -overlap_fragsize: the fragment size of the overlapping packet""" - - 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) - - -def _defrag_list(lst, defrag, missfrag): - """Internal usage only. Part of the _defrag_logic""" - p = lst[0] - lastp = lst[-1] - if p.frag > 0 or lastp.flags.MF: # first or last fragment missing - missfrag.append(lst) - return - 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)) # noqa: E501 - 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()) - if q.time > p.time: - p.time = q.time - else: - ip.flags.MF = False - del(ip.chksum) - del(ip.len) - p = p / txt - p._defrag_pos = max(x._defrag_pos for x in lst) - defrag.append(p) - - -def _defrag_logic(plist, complete=False): - """Internal function used to defragment a list of packets. - It contains the logic behind the defrag() and defragment() functions - """ - 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.MF: - uniq = (ip.id, ip.src, ip.dst, ip.proto) - frags[uniq].append(p) - continue - final.append(p) - - defrag = [] - missfrag = [] - for lst in six.itervalues(frags): - lst.sort(key=lambda x: x.frag) - _defrag_list(lst, defrag, missfrag) - defrag2 = [] - for p in defrag: - q = p.__class__(raw(p)) - q._defrag_pos = p._defrag_pos - q.time = p.time - defrag2.append(q) - if complete: - final.extend(defrag2) - final.extend(missfrag) - final.sort(key=lambda x: x._defrag_pos) - if hasattr(plist, "listname"): - name = "Defragmented %s" % plist.listname - else: - name = "Defragmented" - return PacketList(final, name=name) - else: - return PacketList(final), PacketList(defrag2), PacketList(missfrag) - - -@conf.commands.register -def defrag(plist): - """defrag(plist) -> ([not fragmented], [defragmented], - [ [bad fragments], [bad fragments], ... ])""" - return _defrag_logic(plist, complete=False) - - -@conf.commands.register -def defragment(plist): - """defragment(plist) -> plist defragmented as much as possible """ - return _defrag_logic(plist, complete=True) - - -# 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""" # noqa: E501 - - # Filter TCP segments which source address is 'ip' - tmp = (self._elt2pkt(x) for x in self.res) - b = (x for x in tmp if IP in x and x[IP].src == ip and TCP in x) - - # Build a list of tuples (creation_time, replied_timestamp) - c = [] - tsf = ICMPTimeStampField("", None) - for p in b: - opts = p.getlayer(TCP).options - for o in opts: - if o[0] == "Timestamp": - c.append((p.time, tsf.any2i("", o[1][0]))) - - # Stop if the list is empty - if not c: - warning("No timestamps found in packet list") - return [] - - # Prepare the data that will be plotted - first_creation_time = c[0][0] - first_replied_timestamp = c[0][1] - - def _wrap_data(ts_tuple, wrap_seconds=2000): - """Wrap the list of tuples.""" - - ct, rt = ts_tuple # (creation_time, replied_timestamp) - X = ct % wrap_seconds - Y = ((ct - first_creation_time) - ((rt - first_replied_timestamp) / 1000.0)) # noqa: E501 - - return X, Y - - data = [_wrap_data(e) for e in c] - - # Mimic the default gnuplot output - if kargs == {}: - kargs = MATPLOTLIB_DEFAULT_PLOT_KARGS - lines = plt.plot(data, **kargs) - - # Call show() if matplotlib is not inlined - if not MATPLOTLIB_INLINED: - plt.show() - - return lines - - -PacketList.timeskew_graph = _packetlist_timeskew_graph - - -# Create a new packet list -class TracerouteResult(SndRcvList): - __slots__ = ["graphdef", "graphpadding", "graphASres", "padding", "hloc", - "nloc"] - - def __init__(self, res=None, name="Traceroute", stats=None): - PacketList.__init__(self, res, name, stats) - self.graphdef = None - self.graphASres = None - 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}"), # noqa: E501 - s.ttl, - r.sprintf("%-15s,IP.src% {TCP:%TCP.flags%}{ICMP:%ir,ICMP.type%}"))) # noqa: E501 - - def get_trace(self): - trace = {} - for s, r in self.res: - if IP not in s: - continue - d = s[IP].dst - if d not in trace: - trace[d] = {} - trace[d][s[IP].ttl] = r[IP].src, ICMP not in r - for k in six.itervalues(trace): - try: - m = min(x for x, y in six.iteritems(k) if y[1]) - except ValueError: - continue - for l in list(k): # use list(): k is modified in the loop - if l > m: - del k[l] - return trace - - def trace3D(self, join=True): - """Give a 3D representation of the traceroute. - right button: rotate the scene - middle button: zoom - shift-left button: move the scene - left button on a ball: toggle IP displaying - double-click button on a ball: scan ports 21,22,23,25,80 and 443 and display the result""" # noqa: E501 - # When not ran from a notebook, vpython pooly closes itself - # using os._exit once finished. We pack it into a Process - import multiprocessing - p = multiprocessing.Process(target=self.trace3D_notebook) - p.start() - if join: - p.join() - - def trace3D_notebook(self): - """Same than trace3D, used when ran from Jupyther notebooks""" - trace = self.get_trace() - import vpython - - class IPsphere(vpython.sphere): - def __init__(self, ip, **kargs): - vpython.sphere.__init__(self, **kargs) - self.ip = ip - self.label = None - self.setlabel(self.ip) - self.last_clicked = None - self.full = False - self.savcolor = vpython.vec(*self.color.value) - - def fullinfos(self): - self.full = True - self.color = vpython.vec(1, 0, 0) - a, b = sr(IP(dst=self.ip) / TCP(dport=[21, 22, 23, 25, 80, 443], flags="S"), timeout=2, verbose=0) # noqa: E501 - if len(a) == 0: - txt = "%s:\nno results" % self.ip - else: - txt = "%s:\n" % self.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") # noqa: E501 - self.setlabel(txt, visible=1) - - def unfull(self): - self.color = self.savcolor - self.full = False - 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 = vpython.label(text=txt, pos=self.pos, space=self.radius, xoffset=10, yoffset=20, visible=visible) # noqa: E501 - - def check_double_click(self): - try: - if self.full or not self.label.visible: - return False - if self.last_clicked is not None: - return (time.time() - self.last_clicked) < 0.5 - return False - finally: - self.last_clicked = time.time() - - def action(self): - self.label.visible ^= 1 - if self.full: - self.unfull() - - vpython.scene = vpython.canvas() - vpython.scene.title = "
%s
" % self.listname # noqa: E501 - vpython.scene.append_to_caption( - re.sub( - r'\%(.*)\%', - r'\1', - re.sub( - r'\`(.*)\`', - r'\1', - """Commands: -%Click% to toggle information about a node. -%Double click% to perform a quick web scan on this node. -Camera usage: -`Right button drag or Ctrl-drag` to rotate "camera" to view scene. -`Shift-drag` to move the object around. -`Middle button or Alt-drag` to drag up or down to zoom in or out. - On a two-button mouse, `middle is wheel or left + right`. -Touch screen: pinch/extend to zoom, swipe or two-finger rotate.""" - ) - ) - ) - vpython.scene.exit = True - start = vpython.box() - rings = {} - tr3d = {} - for i in trace: - tr = trace[i] - tr3d[i] = [] - for t in range(1, max(tr) + 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] - tmp_len = len(r) - for i in range(tmp_len): - if r[i][1] == -1: - col = vpython.vec(0.75, 0.75, 0.75) - elif r[i][1]: - col = vpython.color.green - else: - col = vpython.color.blue - - s = IPsphere(pos=vpython.vec((tmp_len - 1) * vpython.cos(2 * i * vpython.pi / tmp_len), (tmp_len - 1) * vpython.sin(2 * i * vpython.pi / tmp_len), 2 * t), # noqa: E501 - ip=r[i][0], - color=col) - for trlst in six.itervalues(tr3d): - 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 six.itervalues(tr3d): - col = vpython.vec(*next(forecol)) - start = vpython.vec(0, 0, 0) - for ip in trlst: - vpython.cylinder(pos=start, axis=ip.pos - start, color=col, radius=0.2) # noqa: E501 - start = ip.pos - - vpython.rate(50) - - # Keys handling - # TODO: there is currently no way of closing vpython correctly - # https://github.com/BruceSherwood/vpython-jupyter/issues/36 - # def keyboard_press(ev): - # k = ev.key - # if k == "esc" or k == "q": - # pass # TODO: close - # - # vpython.scene.bind('keydown', keyboard_press) - - # Mouse handling - def mouse_click(ev): - if ev.press == "left": - o = vpython.scene.mouse.pick - if o and isinstance(o, IPsphere): - if o.check_double_click(): - if o.ip == "unk": - return - o.fullinfos() - else: - o.action() - - vpython.scene.bind('mousedown', mouse_click) - - def world_trace(self): - """Display traceroute results on a world map.""" - - # Check that the geoip2 module can be imported - # Doc: http://geoip2.readthedocs.io/en/latest/ - try: - # GeoIP2 modules need to be imported as below - import geoip2.database - import geoip2.errors - except ImportError: - warning("Cannot import geoip2. Won't be able to plot the world.") - return [] - # Check availability of database - if not conf.geoip_city: - warning("Cannot import the geolite2 CITY database.\n" - "Download it from http://dev.maxmind.com/geoip/geoip2/geolite2/" # noqa: E501 - " then set its path to conf.geoip_city") - return [] - # Check availability of plotting devices - try: - import cartopy.crs as ccrs - except ImportError: - warning("Cannot import cartopy.\n" - "More infos on http://scitools.org.uk/cartopy/docs/latest/installing.html") # noqa: E501 - return [] - if not MATPLOTLIB: - warning("Matplotlib is not installed. Won't be able to plot the world.") # noqa: E501 - return [] - - # Open & read the GeoListIP2 database - try: - db = geoip2.database.Reader(conf.geoip_city) - except Exception: - warning("Cannot open geoip2 database at %s", conf.geoip_city) - return [] - - # Regroup results per trace - 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 - - # Get the addresses locations - trt = {} - for trace_id in rt: - trace = rt[trace_id] - loctrace = [] - for i in range(max(trace)): - ip = trace.get(i, None) - if ip is None: - continue - # Fetch database - try: - sresult = db.city(ip) - except geoip2.errors.AddressNotFoundError: - continue - loctrace.append((sresult.location.longitude, sresult.location.latitude)) # noqa: E501 - if loctrace: - trt[trace_id] = loctrace - - # Load the map renderer - plt.figure(num='Scapy') - ax = plt.axes(projection=ccrs.PlateCarree()) - # Draw countries - ax.coastlines() - ax.stock_img() - # Set normal size - ax.set_global() - # Add title - plt.title("Scapy traceroute results") - - from matplotlib.collections import LineCollection - from matplotlib import colors as mcolors - colors_cycle = iter(mcolors.BASE_COLORS) - lines = [] - - # Split traceroute measurement - for key, trc in six.iteritems(trt): - # Get next color - color = next(colors_cycle) - # Gather mesurments data - data_lines = [(trc[i], trc[i + 1]) for i in range(len(trc) - 1)] - # Create line collection - line_col = LineCollection(data_lines, linewidths=2, - label=key[1], - color=color) - lines.append(line_col) - ax.add_collection(line_col) - # Create map points - lines.extend([ax.plot(*x, marker='.', color=color) for x in trc]) - - # Generate legend - ax.legend() - - # Call show() if matplotlib is not inlined - if not MATPLOTLIB_INLINED: - plt.show() - - # Clean - ax.remove() - - # Return the drawn lines - return lines - - def make_graph(self, ASres=None, padding=0): - 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 # noqa: E501 - s = s.getlayer(IP) or (conf.ipv6_enabled and s[scapy.layers.inet6.IPv6]) or s # noqa: E501 - 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 # noqa: E501 - 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): # noqa: E501 - 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(" %TCP.sport% %TCP.flags%")) # noqa: E501 - trace[ttl] = r.sprintf('"%r,src%":T%ir,TCP.sport%') - elif UDP in r: - p.append(r.sprintf(" %UDP.sport%")) - trace[ttl] = r.sprintf('"%r,src%":U%ir,UDP.sport%') - elif ICMP in r: - p.append(r.sprintf(" ICMP %ICMP.type%")) - trace[ttl] = r.sprintf('"%r,src%":I%ir,ICMP.type%') - else: - p.append(r.sprintf("{IP: IP %proto%}{IPv6: IPv6 %nh%}")) # noqa: E501 - trace[ttl] = r.sprintf('"%r,src%":{IP:P%ir,proto%}{IPv6:P%ir,nh%}') # noqa: E501 - 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] - max_trace = max(trace) - for n in range(min(trace), max_trace): - if n not in trace: - trace[n] = next(unknown_label) - if rtk not 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_trace + 1] = bh - blackholes.append(bh) - - # Find AS numbers - ASN_query_list = set(x.rsplit(" ", 1)[0] for x in ips) - 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])) # noqa: E501 - - s += "\n#Blackholes\n" - for bh in blackholes: - s += '\t%s [shape=octagon,color=black,fillcolor=red,style=filled];\n' % bh # noqa: E501 - - 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 != b"\x00" * len(p): - pad[rcv.src] = None - for rcv in pad: - s += '\t"%s" [shape=triangle,color=black,fillcolor=red,style=filled];\n' % rcv # noqa: E501 - - 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] - maxtrace = max(trace) - for n in range(min(trace), maxtrace): - s += '\t%s ->\n' % trace[n] - s += '\t%s;\n' % trace[maxtrace] - - s += "}\n" - self.graphdef = s - - def graph(self, ASres=conf.AS_resolver, 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") - type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option # noqa: E501 - target: filename or redirect. Defaults pipe to Imagemagick's display program # noqa: E501 - prog: which graphviz program to use""" - 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): # noqa: E501 - """Instant TCP traceroute - - :param target: hostnames or IP addresses - :param dport: TCP destination port (default is 80) - :param minttl: minimum TTL (default is 1) - :param maxttl: maximum TTL (default is 30) - :param sport: TCP source port (default is random) - :param l4: use a Scapy packet instead of TCP - :param filter: BPF filter applied to received packets - :param timeout: time to wait for answers (default is 2s) - :param verbose: detailed output - :return: an TracerouteResult, and a list of unanswered packets""" - 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))" # noqa: E501 - if l4 is None: - a, b = sr(IP(dst=target, id=RandShort(), ttl=(minttl, maxttl)) / TCP(seq=RandInt(), sport=sport, dport=dport), # noqa: E501 - 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 - - -@conf.commands.register -def traceroute_map(ips, **kargs): - """Util function to call traceroute on multiple targets, then - show the different paths on a map. - params: - - ips: a list of IPs on which traceroute will be called - - optional: kwargs, passed to traceroute""" - kargs.setdefault("verbose", 0) - return traceroute(ips)[0].world_trace() - -############################# -# Simple TCP client stack # -############################# - - -class TCP_client(Automaton): - """ - Creates a TCP Client Automaton. - This automaton will handle TCP 3-way handshake. - - Usage: the easiest usage is to use it as a SuperSocket. - >>> a = TCP_client.tcplink(HTTP, "www.google.com", 80) - >>> a.send(HTTPRequest()) - >>> a.recv() - """ - def parse_args(self, ip, port, *args, **kargs): - from scapy.sessions import TCPSession - self.dst = str(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.sack = self.l4[TCP].ack - self.rel_seq = None - self.rcvbuf = TCPSession(self._transmit_packet, False) - bpf = "host %s and host %s and port %i and port %i" % (self.src, - self.dst, - self.sport, - self.dport) - Automaton.parse_args(self, filter=bpf, **kargs) - - def _transmit_packet(self, pkt): - """Transmits a packet from TCPSession to the SuperSocket""" - self.oi.tcp.send(pkt[TCP].payload) - - 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 # noqa: E501 - ((self.l4[TCP].ack == 0) or (self.sack <= pkt[TCP].seq <= self.l4[TCP].ack + pkt[TCP].window))) # noqa: E501 - - @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.SA: - 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, conf.padding_layer)): - raise self.ESTABLISHED().action_parameters(pkt) - - @ATMT.action(incoming_data_received) - def receive_data(self, pkt): - data = raw(pkt[TCP].payload) - if data and self.l4[TCP].ack == pkt[TCP].seq: - self.sack = self.l4[TCP].ack - self.l4[TCP].ack += len(data) - self.l4[TCP].flags = "A" - # Answer with an Ack - self.send(self.l4) - # Process data - will be sent to the SuperSocket through this - self.rcvbuf.on_packet_received(pkt) - - @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.R: - raise self.CLOSED() - - @ATMT.receive_condition(ESTABLISHED) - def fin_received(self, pkt): - if pkt[TCP].flags.F: - 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.A: - raise self.CLOSED() - - -##################### -# Reporting stuff # -##################### - - -@conf.commands.register -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") # noqa: E501 - 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 - - -@conf.commands.register -def IPID_count(lst, funcID=lambda x: x[1].id, funcpres=lambda x: x[1].summary()): # noqa: E501 - """Identify IP id values classes in a list of packets - -lst: a list of packets -funcID: a function that returns IP id values -funcpres: a function used to summarize packets""" - idlst = [funcID(e) for e in lst] - idlst.sort() - classes = [idlst[0]] - classes += [t[1] for t in zip(idlst[:-1], idlst[1:]) if abs(t[0] - t[1]) > 50] # noqa: E501 - lst = [(funcID(x), funcpres(x)) for x in lst] - lst.sort() - print("Probably %i classes:" % len(classes), classes) - for id, pr in lst: - print("%5i" % id, pr) - - -@conf.commands.register -def fragleak(target, sport=123, dport=123, timeout=0.2, onlyasc=0, count=None): - load = "XXXXYYYYYYYYYY" - pkt = IP(dst=target, id=RandShort(), options=b"\x00" * 40, flags=1) - pkt /= UDP(sport=sport, dport=sport) / load - s = conf.L3socket() - intr = 0 - found = {} - try: - while count is None or count: - if count is not None and isinstance(count, int): - count -= 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=' ') - if not ans.haslayer(conf.padding_layer): - continue - 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 - - -@conf.commands.register -def fragleak2(target, timeout=0.4, onlyasc=0, count=None): - found = {} - try: - while count is None or count: - if count is not None and isinstance(count, int): - count -= 1 - - pkt = IP(dst=target, options=b"\x00" * 40, proto=200) - pkt /= "XXXXYYYYYYYYYYYY" - p = sr1(pkt, 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 Exception: - 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-2.4.3/scapy/layers/inet6.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/inet6.py deleted file mode 100644 index c007e1cb17..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/inet6.py +++ /dev/null @@ -1,4085 +0,0 @@ -#! /usr/bin/env python -############################################################################# -# # -# inet6.py --- IPv6 support for Scapy # -# see http://natisbad.org/IPv6/ # -# for more information # -# # -# Copyright (C) 2005 Guillaume Valadon # -# Arnaud Ebalard # -# # -# 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). -""" - - -from __future__ import absolute_import -from __future__ import print_function - -from hashlib import md5 -import random -import socket -import struct -from time import gmtime, strftime - -from scapy.arch import get_if_hwaddr -from scapy.as_resolvers import AS_resolver_riswhois -from scapy.base_classes import Gen -from scapy.compat import chb, orb, raw, plain_str, bytes_encode -from scapy.config import conf -import scapy.consts -from scapy.data import DLT_IPV6, DLT_RAW, DLT_RAW_ALT, ETHER_ANY, ETH_P_IPV6, \ - MTU -from scapy.error import warning -from scapy.fields import BitEnumField, BitField, ByteEnumField, ByteField, \ - DestIP6Field, FieldLenField, FlagsField, IntField, IP6Field, \ - LongField, MACField, PacketLenField, PacketListField, ShortEnumField, \ - ShortField, SourceIP6Field, StrField, StrFixedLenField, StrLenField, \ - X3BytesField, XBitField, XIntField, XShortField -from scapy.layers.inet import IP, IPTools, TCP, TCPerror, TracerouteResult, \ - UDP, UDPerror -from scapy.layers.l2 import CookedLinux, Ether, GRE, Loopback, SNAP -import scapy.modules.six as six -from scapy.packet import bind_layers, Packet, Raw -from scapy.sendrecv import sendp, sniff, sr, srp1 -from scapy.supersocket import SuperSocket, L3RawSocket -from scapy.utils import checksum, strxor -from scapy.pton_ntop import inet_pton, inet_ntop -from scapy.utils6 import in6_getnsma, in6_getnsmac, in6_isaddr6to4, \ - in6_isaddrllallnodes, in6_isaddrllallservers, in6_isaddrTeredo, \ - in6_isllsnmaddr, in6_ismaddr, Net6, teredoAddrExtractInfo -from scapy.volatile import RandInt, RandShort - -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"): - # Workaround for https://bitbucket.org/secdev/scapy/issue/5119 - socket.IPPROTO_IPIP = 4 - -# TRex Change -if not ('IPPROTO_IPIP ' in globals()): - IPPROTO_IPIP = 4 - -if conf.route6 is None: - # unused import, only to initialize conf.route6 - import scapy.route6 - -########################## -# Neighbor cache stuff # -########################## - -conf.netcache.new_cache("in6_neighbor", 120) - - -@conf.commands.register -def neighsol(addr, src, iface, timeout=1, chainCC=0): - """Sends and receive an ICMPv6 Neighbor Solicitation message - - This function sends an ICMPv6 Neighbor Solicitation message - to get the MAC address of the neighbor with specified IPv6 address address. - - '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 - - -@conf.commands.register -def getmacbyip6(ip6, chainCC=0): - """Returns the MAC address corresponding to an IPv6 address - - 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 isinstance(ip6, Net6): - ip6 = str(ip6) - - if in6_ismaddr(ip6): # Multicast - mac = in6_getnsmac(inet_pton(socket.AF_INET6, ip6)) - return mac - - iff, a, nh = conf.route6.route(ip6) - - if iff == scapy.consts.LOOPBACK_INTERFACE: - 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 Class # -############################################################################# -############################################################################# - -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", - 112: "VRRP", - 132: "SCTP", - 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): - __slots__ = ["count_from", "length_from"] - 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 isinstance(i, list): - return len(i) - return 0 - - def getfield(self, pkt, s): - c = tmp_len = None - if self.length_from is not None: - tmp_len = self.length_from(pkt) - elif self.count_from is not None: - c = self.count_from(pkt) - - lst = [] - ret = b"" - remain = s - if tmp_len is not None: - remain, ret = s[:tmp_len], s[tmp_len:] - 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 Exception: - 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 is 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 = orb(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, float("inf")): # Other ICMPv6 messages # noqa: E501 - if t == 130 and len(p) >= 28: - # RFC 3810 - 8.1. Query Version Distinctions - return ICMPv6MLQuery2 - return icmp6typescls.get(t, Raw) - return Raw - elif self.nh == 135 and len(p) > 3: # Mobile IPv6 - return _mip6_mhtype2cls.get(orb(p[2]), MIP6MH_Generic) - elif self.nh == 43 and orb(p[2]) == 4: # Segment Routing header - return IPv6ExtHdrSegmentRouting - return ipv6nhcls.get(self.nh, 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), - # TRex Change - Put Fixed Source Field to avoid look up. - IP6Field("src", "::2"), - # SourceIP6Field("src", "dst"), # dst is for src @ selection - DestIP6Field("dst", "::1")] - - def route(self): - """Used to select the L2 address""" - 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: - tmp_len = len(p) - 40 - p = p[:4] + struct.pack("!H", tmp_len) + p[6:] - return p - - def extract_padding(self, data): - """Extract the IPv6 payload""" - - if self.plen == 0 and self.nh == 0 and len(data) >= 8: - # Extract Hop-by-Hop extension length - hbh_len = orb(data[1]) - hbh_len = 8 + hbh_len * 8 - - # Extract length from the Jumbogram option - # Note: the following algorithm take advantage of the Jumbo option - # mandatory alignment (4n + 2, RFC2675 Section 2) - jumbo_len = None - idx = 0 - offset = 4 * idx + 2 - while offset <= len(data): - opt_type = orb(data[offset]) - if opt_type == 0xc2: # Jumbo option - jumbo_len = struct.unpack("I", data[offset + 2:offset + 2 + 4])[0] # noqa: E501 - break - offset = 4 * idx + 2 - idx += 1 - - if jumbo_len is None: - warning("Scapy did not find a Jumbo option") - jumbo_len = 0 - - tmp_len = hbh_len + jumbo_len - else: - tmp_len = self.plen - - return data[:tmp_len], data[tmp_len:] - - 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() - - if not conf.checkIPinIP and self.nh in [4, 41]: # IP, IPv6 - return 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 # noqa: E501 - # 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 == 43 and isinstance(self.payload, IPv6ExtHdrSegmentRouting): # noqa: E501 - # With segment routing header (rh == 4), the destination is - # the first address of the IPv6 addresses list - try: - sd = self.addresses[0] - except IndexError: - sd = self.dst - - 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 and not in6_ismaddr(sd): - sd = inet_pton(socket.AF_INET6, sd) - ss = inet_pton(socket.AF_INET6, self.src) - return strxor(sd, ss) + struct.pack("B", nh) + self.payload.hashret() # noqa: E501 - else: - return struct.pack("B", nh) + self.payload.hashret() - - def answers(self, other): - if not conf.checkIPinIP: # skip IP in IP and IPv6 in IP - if self.nh in [4, 41]: - return self.payload.answers(other) - if isinstance(other, IPv6) and other.nh in [4, 41]: - return self.answers(other.payload) - if isinstance(other, IP) and other.proto in [4, 41]: - return self.answers(other.payload) - 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))): # noqa: E501 - 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: # noqa: E501 - # 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) - 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 # noqa: E501 - elif other.nh == 43 and isinstance(other.payload, IPv6ExtHdrSegmentRouting): # noqa: E501 - return self.payload.answers(other.payload.payload) # Buggy if self.payload is a IPv6ExtHdrRouting # noqa: E501 - 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 # noqa: E501 - return self.payload.payload.answers(other.payload) - else: - if (self.nh != other.nh): - return False - return self.payload.answers(other.payload) - - -class _IPv46(IP): - """ - This class implements a dispatcher that is used to detect the IP version - while parsing Raw IP pcap files. - """ - @classmethod - def dispatch_hook(cls, _pkt=None, *_, **kargs): - if _pkt: - if orb(_pkt[0]) >> 4 == 6: - return IPv6 - elif kargs.get("version") == 6: - return IPv6 - return IP - - -def inet6_register_l3(l2, l3): - return getmacbyip6(l3.dst) - - -conf.neighbor.register_l3(Ether, IPv6, inet6_register_l3) - - -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 = raw(selfup) - s2 = raw(otherup) - tmp_len = min(len(s1), len(s2)) - res = s1[:tmp_len] == s2[:tmp_len] - - # 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 = raw(selfup) - s2 = raw(otherup) - tmp_len = min(len(s1), len(s2)) - return s1[:tmp_len] == s2[:tmp_len] - - 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): - """ - As Specified in RFC 2460 - 8.1 Upper-Layer Checksums - - 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 is not 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, IPv6ExtHdrSegmentRouting) and - u.segleft != 0 and len(u.addresses) != 0 and - final_dest_addr_found == 0): - rthdr = u.addresses[0] - 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 = raw(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 usually 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 - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt: - o = orb(_pkt[0]) # Option type - if o in _hbhoptcls: - return _hbhoptcls[o] - return cls - - def extract_padding(self, p): - return b"", p - - -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 - - def extract_padding(self, p): - return b"", p - - -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 - - def extract_padding(self, p): - return b"", p - - -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", # noqa: E501 - 68: "NSIS NATFW NSLP", - 69: "MPLS OAM", - 65535: "Reserved"})] - # TODO : Check IANA has not defined new values for value field of RouterAlertOption # noqa: E501 - # TODO : Now that we have that option, we should do something in MLD class that need it # noqa: E501 - # TODO : IANA has defined ranges of values which can't be easily represented here. # noqa: E501 - # iana.org/assignments/ipv6-routeralert-values/ipv6-routeralert-values.xhtml - - def alignment_delta(self, curpos): # alignment requirement : 2n+0 - x = 2 - y = 0 - delta = x * ((curpos - y + x - 1) // x) + y - curpos - return delta - - def extract_padding(self, p): - return b"", p - - -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 - - def extract_padding(self, p): - return b"", p - - -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 - - def extract_padding(self, p): - return b"", p - - -_hbhoptcls = {0x00: Pad1, - 0x01: PadN, - 0x05: RouterAlert, - 0xC2: Jumbo, - 0xC9: HAO} - - -# Hop-by-Hop Extension Header # - -class _OptionsField(PacketListField): - __slots__ = ["curpos"] - - def __init__(self, name, default, cls, curpos, *args, **kargs): - self.curpos = curpos - PacketListField.__init__(self, name, default, cls, *args, **kargs) - - def i2len(self, pkt, i): - return len(self.i2m(pkt, i)) - - def i2m(self, pkt, x): - autopad = None - try: - autopad = getattr(pkt, "autopad") # Hack : 'autopad' phantom field - except Exception: - 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 += raw(Pad1()) - elif d != 0: - s += raw(PadN(optdata=b'\x00' * (d - 2))) - pstr = raw(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 += raw(Pad1()) - elif d != 0: - s += raw(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 # noqa: E501 - _OptionsField("options", [], HBHOptUnknown, 2, - length_from=lambda pkt: (8 * (pkt.len + 1)) - 2)] # noqa: E501 - 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 # noqa: E501 - _OptionsField("options", [], HBHOptUnknown, 2, - length_from=lambda pkt: (8 * (pkt.len + 1)) - 2)] # noqa: E501 - 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 # noqa: E501 - ByteField("type", 0), - ByteField("segleft", None), - BitField("reserved", 0, 32), # There is meaning in this field ... # noqa: E501 - 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) - - -# Segment Routing Header # - -# This implementation is based on draft 06, available at: -# https://tools.ietf.org/html/draft-ietf-6man-segment-routing-header-06 - -class IPv6ExtHdrSegmentRoutingTLV(Packet): - name = "IPv6 Option Header Segment Routing - Generic TLV" - fields_desc = [ByteField("type", 0), - ByteField("len", 0), - ByteField("reserved", 0), - ByteField("flags", 0), - StrLenField("value", "", length_from=lambda pkt: pkt.len)] - - def extract_padding(self, p): - return b"", p - - registered_sr_tlv = {} - - @classmethod - def register_variant(cls): - cls.registered_sr_tlv[cls.type.default] = cls - - @classmethod - def dispatch_hook(cls, pkt=None, *args, **kargs): - if pkt: - tmp_type = orb(pkt[0]) - return cls.registered_sr_tlv.get(tmp_type, cls) - return cls - - -class IPv6ExtHdrSegmentRoutingTLVIngressNode(IPv6ExtHdrSegmentRoutingTLV): - name = "IPv6 Option Header Segment Routing - Ingress Node TLV" - fields_desc = [ByteField("type", 1), - ByteField("len", 18), - ByteField("reserved", 0), - ByteField("flags", 0), - IP6Field("ingress_node", "::1")] - - -class IPv6ExtHdrSegmentRoutingTLVEgressNode(IPv6ExtHdrSegmentRoutingTLV): - name = "IPv6 Option Header Segment Routing - Egress Node TLV" - fields_desc = [ByteField("type", 2), - ByteField("len", 18), - ByteField("reserved", 0), - ByteField("flags", 0), - IP6Field("egress_node", "::1")] - - -class IPv6ExtHdrSegmentRoutingTLVPadding(IPv6ExtHdrSegmentRoutingTLV): - name = "IPv6 Option Header Segment Routing - Padding TLV" - fields_desc = [ByteField("type", 4), - FieldLenField("len", None, length_of="padding", fmt="B"), - StrLenField("padding", b"\x00", length_from=lambda pkt: pkt.len)] # noqa: E501 - - -class IPv6ExtHdrSegmentRouting(_IPv6ExtHdr): - name = "IPv6 Option Header Segment Routing" - fields_desc = [ByteEnumField("nh", 59, ipv6nh), - ByteField("len", None), - ByteField("type", 4), - ByteField("segleft", None), - ByteField("lastentry", None), - BitField("unused1", 0, 1), - BitField("protected", 0, 1), - BitField("oam", 0, 1), - BitField("alert", 0, 1), - BitField("hmac", 0, 1), - BitField("unused2", 0, 3), - ShortField("tag", 0), - IP6ListField("addresses", ["::1"], - count_from=lambda pkt: (pkt.lastentry + 1)), - PacketListField("tlv_objects", [], - IPv6ExtHdrSegmentRoutingTLV, - length_from=lambda pkt: 8 * pkt.len - 16 * ( - pkt.lastentry + 1 - ))] - - overload_fields = {IPv6: {"nh": 43}} - - def post_build(self, pkt, pay): - - if self.len is None: - - # The extension must be align on 8 bytes - tmp_mod = (len(pkt) - 8) % 8 - if tmp_mod == 1: - warning("IPv6ExtHdrSegmentRouting(): can't pad 1 byte!") - elif tmp_mod >= 2: - # Add the padding extension - tmp_pad = b"\x00" * (tmp_mod - 2) - tlv = IPv6ExtHdrSegmentRoutingTLVPadding(padding=tmp_pad) - pkt += raw(tlv) - - tmp_len = (len(pkt) - 8) // 8 - pkt = pkt[:1] + struct.pack("B", tmp_len) + pkt[2:] - - if self.segleft is None: - tmp_len = len(self.addresses) - if tmp_len: - tmp_len -= 1 - pkt = pkt[:3] + struct.pack("B", tmp_len) + pkt[4:] - - if self.lastentry is None: - lastentry = len(self.addresses) - if lastentry == 0: - warning( - "IPv6ExtHdrSegmentRouting(): the addresses list is empty!" - ) - else: - lastentry -= 1 - pkt = pkt[:4] + struct.pack("B", lastentry) + pkt[5:] - - 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(packets): - """ - Performs defragmentation of a list of IPv6 packets. Packets are reordered. - Crap is dropped. What lacks is completed by 'X' characters. - """ - - # Remove non fragments - lst = [x for x in packets if IPv6ExtHdrFragment in x] - if not lst: - return [] - - id = lst[0][IPv6ExtHdrFragment].id - - llen = len(lst) - lst = [x for x in lst if x[IPv6ExtHdrFragment].id == id] - if len(lst) != llen: - warning("defragment6: some fragmented packets have been removed from list") # noqa: E501 - llen = len(lst) - - # reorder fragments - res = [] - while lst: - min_pos = 0 - min_offset = lst[0][IPv6ExtHdrFragment].offset - for p in lst: - cur_offset = p[IPv6ExtHdrFragment].offset - if cur_offset < min_offset: - min_pos = 0 - min_offset = cur_offset - res.append(lst[min_pos]) - del(lst[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)) # noqa: E501 - fragmentable += b"X" * (offset - len(fragmentable)) - fragmentable += raw(q.payload) - - # Regenerate the unfragmentable part. - q = res[0] - nh = q[IPv6ExtHdrFragment].nh - q[IPv6ExtHdrFragment].underlayer.nh = nh - q[IPv6ExtHdrFragment].underlayer.plen = len(fragmentable) - del q[IPv6ExtHdrFragment].underlayer.payload - q /= conf.raw_layer(load=fragmentable) - del(q.plen) - - return IPv6(raw(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 IPv6ExtHdrFragment not 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(raw(pkt[IPv6ExtHdrFragment])) > 65535: - warning("An IPv6 packet can'be bigger than 65535, please use a Jumbo payload.") # noqa: E501 - return [] - - s = raw(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 = raw(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 = pkt[IPv6ExtHdrFragment].nh - - # Keep fragment header - fragHeader = pkt[IPv6ExtHdrFragment] - del fragHeader.payload # detach payload - - # Unfragmentable Part - unfragPartLen = len(s) - fragPartLen - 8 - unfragPart = pkt - del pkt[IPv6ExtHdrFragment].underlayer.payload # 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", # MLDv1 or MLDv2 - 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: "ICMPv6MLReport2", - 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, - # TRex Change - Change 143 from 8 to 16. - 143: 16, - 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: "MLD Report Version 2", - 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"} - -# TRex Change - Added MLDv2 Group Types -mldv2_group_types = { - 1: 'Mode is include (1)', - 2: 'Mode is exclude (2)', - 3: 'Change to include mode (3)', - 4: 'Change to exclude mode (4)', - 5: 'Alloc new sources (5)', - 6: 'Block old sources (6)', - } - -class _ICMPv6(Packet): - name = "ICMPv6 dummy class" - overload_fields = {IPv6: {"nh": 58}} - - def post_build(self, p, pay): - p += pay - if self.cksum is 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", # noqa: E501 - 2: "Beyond scope of source address", # noqa: E501 - 3: "Address unreachable", - 4: "Port unreachable"}), - XShortField("cksum", None), - ByteField("length", 0), - X3BytesField("unused", 0)] - - -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", # noqa: E501 - 1: "fragment reassembly time exceeded"}), # noqa: E501 - XShortField("cksum", None), - ByteField("length", 0), - X3BytesField("unused", 0)] - -# 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", - 3: "first fragment has incomplete header chain"}), - 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 (RFC2710) # - -# 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 # 10s for mrd - mladdr = "::" - overload_fields = {IPv6: {"dst": "ff02::1", "hlim": 1, "nh": 58}} - - -# 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}} - - def answers(self, query): - """Check the query type""" - return ICMPv6MLQuery in query - -# 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}} - - -# Multicast Listener Discovery Version 2 (MLDv2) (RFC3810) # -# TRex Change - Added ICMPv6MLReportV2 -class ICMPv6MLReportV2(_ICMPv6): # RFC 3810 - name = 'MLDv2 - Multicast Listener Report' - fields_desc = [ ByteEnumField('type', 143, icmp6types), - ByteField('code', 0), - XShortField('cksum', None), - ShortField('reserved', 0), - ShortField('records_count', 1) ] # for now it's fixed 1 record - overload_fields = {IPv6: { 'dst': 'ff02::16', 'hlim': 1, 'nh': 58 }} - - def default_payload_class(self, p): - return MLDv2Addr - -# TRex Change - Added MLDv2Addr -# assumes empty aux -class MLDv2Addr(Packet): - name = 'MLDv2 - Address group' - fields_desc = [ - ByteEnumField('type', 3, mldv2_group_types), - ByteField('aux_len', 0), - ShortField('len', 0), - IP6Field('multicast_addr', '::'), - IP6ListField('addrlist', [], count_from = lambda pkt:pkt.len) - ] - - def default_payload_class(self, p): - return MLDv2Addr - - -class ICMPv6MLQuery2(_ICMPv6): # RFC 3810 - name = "MLDv2 - Multicast Listener Query" - fields_desc = [ByteEnumField("type", 130, icmp6types), - ByteField("code", 0), - XShortField("cksum", None), - ShortField("mrd", 10000), - ShortField("reserved", 0), - IP6Field("mladdr", "::"), - BitField("Resv", 0, 4), - BitField("S", 0, 1), - BitField("QRV", 0, 3), - ByteField("QQIC", 0), - ShortField("sources_number", None), - IP6ListField("sources", [], - count_from=lambda pkt: pkt.sources_number)] - - # RFC8810 - 4. Message Formats - overload_fields = {IPv6: {"dst": "ff02::1", "hlim": 1, "nh": 58}} - - def post_build(self, packet, payload): - """Compute the 'sources_number' field when needed""" - if self.sources_number is None: - srcnum = struct.pack("!H", len(self.sources)) - packet = packet[:26] + srcnum + packet[28:] - return _ICMPv6.post_build(self, packet, payload) - - -class ICMPv6MLDMultAddrRec(Packet): - name = "ICMPv6 MLDv2 - Multicast Address Record" - fields_desc = [ByteField("rtype", 4), - FieldLenField("auxdata_len", None, - length_of="auxdata", - fmt="B"), - FieldLenField("sources_number", None, - length_of="sources", - adjust=lambda p, num: num // 16), - IP6Field("dst", "::"), - IP6ListField("sources", [], - length_from=lambda p: 16 * p.sources_number), - StrLenField("auxdata", "", - length_from=lambda p: p.auxdata_len)] - - def default_payload_class(self, packet): - """Multicast Address Record followed by another one""" - return self.__class__ - - -class ICMPv6MLReport2(_ICMPv6): # RFC 3810 - name = "MLDv2 - Multicast Listener Report" - fields_desc = [ByteEnumField("type", 143, icmp6types), - ByteField("res", 0), - XShortField("cksum", None), - ShortField("reserved", 0), - ShortField("records_number", None), - PacketListField("records", [], - ICMPv6MLDMultAddrRec, - count_from=lambda p: p.records_number)] - - # RFC8810 - 4. Message Formats - overload_fields = {IPv6: {"dst": "ff02::16", "hlim": 1, "nh": 58}} - - def post_build(self, packet, payload): - """Compute the 'records_number' field when needed""" - if self.records_number is None: - recnum = struct.pack("!H", len(self.records)) - packet = packet[:6] + recnum + packet[8:] - return _ICMPv6.post_build(self, packet, payload) - - def answers(self, query): - """Check the query type""" - return isinstance(query, ICMPv6MLQuery2) - - -# 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: "Recursive 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: ICMPv6NDOptCGA, RFC3971 - contrib/send.py - # 12: ICMPv6NDOptRsaSig, RFC3971 - contrib/send.py - # 13: ICMPv6NDOptTmstp, RFC3971 - contrib/send.py - # 14: ICMPv6NDOptNonce, RFC3971 - contrib/send.py - # 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", - 31: "ICMPv6NDOptDNSSL" - } - -icmp6ndraprefs = {0: "Medium (default)", - 1: "High", - 2: "Reserved", - 3: "Low"} # RFC 4191 - - -class _ICMPv6NDGuessPayload: - name = "Dummy ND class that implements guess_payload_class()" - - def guess_payload_class(self, p): - if len(p) > 1: - return icmp6ndoptscls.get(orb(p[0]), Raw) # s/Raw/ICMPv6NDOptUnknown/g ? # noqa: E501 - - -# 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%/%prefixlen% " - "On-link %L% Autonomous Address %A% " - "Router Address %R%") - -# TODO: We should also limit the size of included packet to something -# like (initiallen - 40 - 2) - - -class TruncPktLenField(PacketLenField): - __slots__ = ["cur_shift"] - - def __init__(self, name, default, cls, cur_shift, length_from=None, shift=0): # noqa: E501 - PacketLenField.__init__(self, name, default, cls, length_from=length_from) # noqa: E501 - self.cur_shift = cur_shift - - def getfield(self, pkt, s): - tmp_len = self.length_from(pkt) - i = self.m2i(pkt, s[:tmp_len]) - return s[tmp_len:], i - - def m2i(self, pkt, m): - s = None - try: # It can happen we have sth shorter than 40 bytes - s = self.cls(m) - except Exception: - return conf.raw_layer(m) - return s - - def i2m(self, pkt, x): - s = raw(x) - tmp_len = len(s) - r = (tmp_len + self.cur_shift) % 8 - tmp_len = tmp_len - r - return s[:tmp_len] - - 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)] - - def mysummary(self): - return self.sprintf("%name% %mtu%") - - -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)" # noqa: E501 - 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", # noqa: E501 - 6: "No preifx info available for AP identified by the LLA", # noqa: E501 - 7: "No fast handovers support for AP identified by the LLA"} # noqa: E501 - - -class ICMPv6NDOptLLA(_ICMPv6NDGuessPayload, Packet): # RFC 4068 - name = "ICMPv6 Neighbor Discovery - Link-Layer Address (LLA) Option (FH for MIPv6)" # noqa: E501 - 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): - __slots__ = ["length_from"] - - 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): - tmp_len = self.length_from(pkt) - p = s[:tmp_len] - if tmp_len < 16: - p += b'\x00' * (16 - tmp_len) - return s[tmp_len:], self.m2i(pkt, p) - - def i2len(self, pkt, x): - return len(self.i2m(pkt, x)) - - def i2m(self, pkt, x): - tmp_len = pkt.len - - if x is None: - x = "::" - if tmp_len is None: - tmp_len = 1 - x = inet_pton(socket.AF_INET6, x) - - if tmp_len is None: - return x - if tmp_len in [0, 1]: - return b"" - if tmp_len in [2, 3]: - return x[:8 * (tmp_len - 1)] - - return x + b'\x00' * 8 * (tmp_len - 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), - BitEnumField("prf", 0, 2, icmp6ndraprefs), - BitField("res2", 0, 3), - IntField("rtlifetime", 0xffffffff), - _IP6PrefixField("prefix", None)] - - def mysummary(self): - return self.sprintf("%name% %prefix%/%plen% Preference %prf%") - - -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))] - - def mysummary(self): - return self.sprintf("%name% " + ", ".join(self.dns)) - - -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)] - -# 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): - __slots__ = ["padded"] - islist = 1 - padded_unit = 8 - - def __init__(self, name, default, fld=None, length_from=None, padded=False): # noqa: E501 - self.padded = padded - StrLenField.__init__(self, name, default, fld, length_from) - - def i2len(self, pkt, x): - return len(self.i2m(pkt, x)) - - def m2i(self, pkt, x): - x = plain_str(x) # Decode bytes to string - res = [] - while x: - # Get a name until \x00 is reached - cur = [] - while x and ord(x[0]) != 0: - tmp_len = ord(x[0]) - cur.append(x[1:tmp_len + 1]) - x = x[tmp_len + 1:] - if self.padded: - # Discard following \x00 in padded mode - if len(cur): - res.append(".".join(cur) + ".") - else: - # Store the current name - res.append(".".join(cur) + ".") - if x and ord(x[0]) == 0: - x = x[1:] - return res - - def i2m(self, pkt, x): - def conditionalTrailingDot(z): - if z and orb(z[-1]) == 0: - return z - return z + b'\x00' - # Build the encode names - tmp = ([chb(len(z)) + z.encode("utf8") for z in y.split('.')] for y in x) # Also encode string to bytes # noqa: E501 - ret_string = b"".join(conditionalTrailingDot(b"".join(x)) for x in tmp) - - # In padded mode, add some \x00 bytes - if self.padded and not len(ret_string) % self.padded_unit == 0: - ret_string += b"\x00" * (self.padded_unit - len(ret_string) % self.padded_unit) # noqa: E501 - - return ret_string - - -class ICMPv6NDOptDNSSL(_ICMPv6NDGuessPayload, Packet): # RFC 6106 - name = "ICMPv6 Neighbor Discovery Option - DNS Search List Option" - fields_desc = [ByteField("type", 31), - FieldLenField("len", None, length_of="searchlist", fmt="B", - adjust=lambda pkt, x: 1 + x // 8), - ShortField("res", None), - IntField("lifetime", 0xffffffff), - DomainNameListField("searchlist", [], - length_from=lambda pkt: 8 * pkt.len - 8, - padded=True) - ] - - def mysummary(self): - return self.sprintf("%name% " + ", ".join(self.searchlist)) - -# 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, icmp6ndraprefs), # 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) - - def mysummary(self): - return self.sprintf("%name% Lifetime %routerlifetime% " - "Hop Limit %chlim% Preference %prf% " - "Managed %M% Other %O% Home %H%") - - -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 bytes_encode(self.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 bytes_encode(self.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", b"\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). # noqa: E501 -# [ ] 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 bytes_encode(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() - - -@conf.commands.register -def computeNIGroupAddr(name): - """Compute the NI group Address. Can take a FQDN as input parameter""" - name = name.lower().split(".")[0] - record = chr(len(name)) + name - h = md5(record.encode("utf8")) - 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 specific -# type of value provided : -# -# - IPv6 if acceptable for inet_pton(AF_INET6, ): code is set to 0, -# if not overridden by user -# - IPv4 if acceptable for inet_pton(AF_INET, ): code is set to 2, -# if not overridden -# - Name in the other cases: code is set to 0, if not overridden 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 isinstance(x, bytes): - if x and x[-1:] == b'\x00': # stupid heuristic - return x - x = [x] - - res = [] - for n in x: - termin = b"\x00" - if n.count(b'.') == 0: # single-component gets one more - termin += b'\x00' - n = b"".join(chb(len(y)) + y for y in 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"" - while x: - tmp_len = orb(x[0]) - x = x[1:] - if not tmp_len: - if cur and cur[-1:] == b'.': - cur = cur[:-1] - res.append(cur) - cur = b"" - if x and orb(x[0]) == 0: # single component - x = x[1:] - continue - if tmp_len & 0xc0: # XXX TODO : work on that -- arno - raise Exception("DNS message can't be compressed at this point!") - cur += x[:tmp_len] + b"." - x = x[tmp_len:] - 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 isinstance(x[0], int): - return x - - # Try IPv6 - try: - inet_pton(socket.AF_INET6, x.decode()) - return (0, x.decode()) - except Exception: - pass - # Try IPv4 - try: - inet_pton(socket.AF_INET, x.decode()) - return (2, x.decode()) - except Exception: - pass - # Try DNS - if x is None: - x = b"" - x = names2dnsrepr(x) - return (1, x) - - 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 = [] - while val: - tmp_len = orb(val[0]) - val = val[1:] - if tmp_len == 0: - break - res.append(plain_str(val[:tmp_len]) + ".") - val = val[tmp_len:] - 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 ((isinstance(val, tuple) and val[1] is None) or - val is None): - val = (1, b"") - t = val[0] - if t == 1: - return s + val[1] - 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") : unknown 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 not isinstance(x, tuple): - if pkt is not None: - qtype = 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 isinstance(x, (str, bytes)): # listify the string - x = [x] - if isinstance(x, list): - x = [val.encode() if isinstance(val, str) else val for val in x] # noqa: E501 - if x and isinstance(x[0], six.integer_types): - ttl = x[0] - names = x[1:] - else: - ttl = 0 - names = x - return (2, [ttl, names2dnsrepr(names)]) - - elif qtype in [3, 4]: # IPv4 or IPv6 addr - if not isinstance(x, list): - x = [x] # User directly provided an IP, instead of list - - def fixvalue(x): - # List elements are not tuples, user probably - # omitted ttl value : we will use 0 instead - if not isinstance(x, tuple): - x = (0, x) - # Decode bytes - if six.PY3 and isinstance(x[1], bytes): - x = (x[0], x[1].decode()) - return x - - return (qtype, [fixvalue(d) for d in 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 + b"".join(map(lambda x_y1: struct.pack("!I", x_y1[0]) + inet_pton(socket.AF_INET6, x_y1[1]), tmp)) # noqa: E501 - elif t == 4: - return s + b"".join(map(lambda x_y2: struct.pack("!I", x_y2[0]) + inet_pton(socket.AF_INET, x_y2[1]), tmp)) # noqa: E501 - 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 isinstance(x, tuple) and len(x) == 2: - t, val = x - if t == 2: # DNS names - ttl, tmp_len = val - tmp_len = dnsrepr2names(tmp_len) - names_list = (plain_str(name) for name in tmp_len) - return "ttl:%d %s" % (ttl, ",".join(names_list)) - elif t == 3 or t == 4: - return "[ %s ]" % (", ".join(map(lambda x_y: "(%d, %s)" % (x_y[0], x_y[1]), val))) # noqa: E501 - 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 = orb(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 = orb(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(Packet): - """ 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)""" - - __slots__ = ["x", "y"] - - 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 - - def extract_padding(self, p): - return b"", p - - -class MIP6OptBRAdvice(_MIP6OptAlign): - 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): - 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): - 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): - 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): # 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): # 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): # 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): # 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", # noqa: E501 - 2: "MN-AAA authentication mobility option"}), # noqa: E501 - 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): - 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 - t = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime(res)) - - return "%s (%d)" % (t, x) - - -class MIP6OptReplayProtection(_MIP6OptAlign): # 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): # 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): # 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): # 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): # 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): # 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): # 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", b'\x00' * 8, - length_from=lambda pkt: pkt.olen)] - x = 0 - y = 0 # alignment requirement: none - - -class MIP6OptUnknown(_MIP6OptAlign): - 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 - - @classmethod - def dispatch_hook(cls, _pkt=None, *_, **kargs): - if _pkt: - o = orb(_pkt[0]) # Option type - if o in moboptcls: - return moboptcls[o] - return cls - - -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 - tmp_len = self.len - if self.len is None: - tmp_len = (len(p) - 8) // 8 - p = p[:1] + struct.pack("B", tmp_len) + 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)] - - -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 # noqa: E501 - _OptionsField("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 b"\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", b"\x00" * 2, 2), - StrFixedLenField("cookie", b"\x00" * 8, 8), - _PhantomAutoPadField("autopad", 1), # autopad activated by default # noqa: E501 - _OptionsField("options", [], MIP6OptUnknown, 16, - length_from=lambda pkt: 8 * (pkt.len - 1))] # noqa: E501 - overload_fields = {IPv6: {"nh": 135}} - - def hashret(self): - return bytes_encode(self.cookie) - - -class MIP6MH_CoTI(MIP6MH_HoTI): - name = "IPv6 Mobility Header - Care-of Test Init" - mhtype = 2 - - def hashret(self): - return bytes_encode(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", b"\x00" * 8, 8), - StrFixedLenField("token", b"\x00" * 8, 8), - _PhantomAutoPadField("autopad", 1), # autopad activated by default # noqa: E501 - _OptionsField("options", [], MIP6OptUnknown, 24, - length_from=lambda pkt: 8 * (pkt.len - 2))] # noqa: E501 - overload_fields = {IPv6: {"nh": 135}} - - def hashret(self): - return bytes_encode(self.cookie) - - def answers(self, other): - 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 bytes_encode(self.cookie) - - def answers(self, other): - 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) # noqa: E501 - 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 # noqa: E501 - _OptionsField("options", [], MIP6OptUnknown, 12, - length_from=lambda pkt: 8 * pkt.len - 4)] # noqa: E501 - overload_fields = {IPv6: {"nh": 135}} - - def hashret(self): # Hack: see comment in MIP6MH_BRR.hashret() - return b"\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) # noqa: E501 - 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 # noqa: E501 - _OptionsField("options", [], MIP6OptUnknown, 12, - length_from=lambda pkt: 8 * pkt.len - 4)] # noqa: E501 - overload_fields = {IPv6: {"nh": 135}} - - def hashret(self): # Hack: see comment in MIP6MH_BRR.hashret() - return b"\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) # noqa: E501 - ByteEnumField("mhtype", 7, mhtypes), - ByteField("res", 0), - XShortField("cksum", None), - ByteEnumField("status", 0, _bestatus), - ByteField("reserved", 0), - IP6Field("ha", "::"), - _OptionsField("options", [], MIP6OptUnknown, 24, - length_from=lambda pkt: 8 * (pkt.len - 2))] # noqa: E501 - 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) - - if asn.startswith("AS"): - try: - asn = int(asn[2:]) - except ValueError: - pass - - return ip, asn, desc - - -class TracerouteResult6(TracerouteResult): - __slots__ = [] - - 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 ! # noqa: E501 - s.hlim, - r.sprintf("%-42s,IPv6.src% {TCP:%TCP.flags%}" + # noqa: E501 - "{ICMPv6DestUnreach:%ir,type%}{ICMPv6PacketTooBig:%ir,type%}" + # noqa: E501 - "{ICMPv6TimeExceeded:%ir,type%}{ICMPv6ParamProblem:%ir,type%}" + # noqa: E501 - "{ICMPv6EchoReply:%ir,type%}"))) # noqa: E501 - - 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 six.itervalues(trace): - try: - m = min(x for x, y in six.iteritems(k) if y[1]) - except ValueError: - continue - for l in list(k): # use list(): k is modified in the loop - if l > m: - del k[l] - - return trace - - def graph(self, ASres=AS_resolver6(), **kargs): - TracerouteResult.graph(self, ASres=ASres, **kargs) - - -@conf.commands.register -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), # noqa: E501 - timeout=timeout, filter="icmp6 or tcp", verbose=verbose, **kargs) # noqa: E501 - 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): # noqa: E501 - L3RawSocket.__init__(self, type, filter, iface, promisc) - # NOTE: if fragmentation is needed, it will be done by the kernel (RFC 2292) # noqa: E501 - self.outs = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_RAW) # noqa: E501 - self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type)) # noqa: E501 - - -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): # noqa: E501 - 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) # noqa: E501 - - -############################################################################# -############################################################################# -# Neighbor Discovery Protocol Attacks # -############################################################################# -############################################################################# - -def _NDP_Attack_DAD_DoS(reply_callback, iface=None, mac_src_filter=None, - tgt_filter=None, reply_mac=None): - """ - Internal generic helper accepting a specific callback as first argument, - for NS or NA reply. See the two specific functions below. - """ - - def is_request(req, mac_src_filter, tgt_filter): - """ - Check if packet req is a request - """ - - # Those simple checks are based on Section 5.4.2 of RFC 4862 - if not (Ether in req and IPv6 in req and ICMPv6ND_NS in req): - return 0 - - # Get and compare the MAC address - mac_src = req[Ether].src - if mac_src_filter and mac_src != mac_src_filter: - return 0 - - # Source must be the unspecified address - if req[IPv6].src != "::": - return 0 - - # Check destination is the link-local solicited-node multicast - # address associated with target address in received NS - tgt = inet_pton(socket.AF_INET6, req[ICMPv6ND_NS].tgt) - if tgt_filter and tgt != tgt_filter: - return 0 - received_snma = inet_pton(socket.AF_INET6, req[IPv6].dst) - expected_snma = in6_getnsma(tgt) - if received_snma != expected_snma: - return 0 - - return 1 - - if not iface: - iface = conf.iface - - # To prevent sniffing our own traffic - if not reply_mac: - reply_mac = get_if_hwaddr(iface) - sniff_filter = "icmp6 and not ether src %s" % reply_mac - - sniff(store=0, - filter=sniff_filter, - lfilter=lambda x: is_request(x, mac_src_filter, tgt_filter), - prn=lambda x: reply_callback(x, reply_mac, iface), - iface=iface) - - -def NDP_Attack_DAD_DoS_via_NS(iface=None, mac_src_filter=None, tgt_filter=None, - reply_mac=None): - """ - Perform the DAD DoS attack using NS described in section 4.1.3 of RFC - 3756. This is done by listening incoming NS messages sent from the - unspecified address and sending a NS reply for the target address, - leading the peer to believe that another node is also performing DAD - for that address. - - By default, the fake NS sent to create the DoS uses: - - as target address the target address found in received NS. - - as IPv6 source address: the unspecified address (::). - - as IPv6 destination address: the link-local solicited-node multicast - address derived from the target address in received NS. - - the mac address of the interface as source (or reply_mac, see below). - - the multicast mac address derived from the solicited node multicast - address used as IPv6 destination address. - - Following arguments can be used to change the behavior: - - iface: a specific interface (e.g. "eth0") of the system on which the - DoS should be launched. If None is provided conf.iface is used. - - mac_src_filter: a mac address (e.g "00:13:72:8c:b5:69") to filter on. - Only NS messages received from this source will trigger replies. - This allows limiting the effects of the DoS to a single target by - filtering on its mac address. The default value is None: the DoS - is not limited to a specific mac address. - - tgt_filter: Same as previous but for a specific target IPv6 address for - received NS. If the target address in the NS message (not the IPv6 - destination address) matches that address, then a fake reply will - be sent, i.e. the emitter will be a target of the DoS. - - reply_mac: allow specifying a specific source mac address for the reply, - i.e. to prevent the use of the mac address of the interface. - """ - - def ns_reply_callback(req, reply_mac, iface): - """ - Callback that reply to a NS by sending a similar NS - """ - - # Let's build a reply and send it - mac = req[Ether].src - dst = req[IPv6].dst - tgt = req[ICMPv6ND_NS].tgt - rep = Ether(src=reply_mac) / IPv6(src="::", dst=dst) / ICMPv6ND_NS(tgt=tgt) # noqa: E501 - sendp(rep, iface=iface, verbose=0) - - print("Reply NS for target address %s (received from %s)" % (tgt, mac)) - - _NDP_Attack_DAD_DoS(ns_reply_callback, iface, mac_src_filter, - tgt_filter, reply_mac) - - -def NDP_Attack_DAD_DoS_via_NA(iface=None, mac_src_filter=None, tgt_filter=None, - reply_mac=None): - """ - Perform the DAD DoS attack using NS described in section 4.1.3 of RFC - 3756. This is done by listening incoming NS messages *sent from the - unspecified address* and sending a NA reply for the target address, - leading the peer to believe that another node is also performing DAD - for that address. - - By default, the fake NA sent to create the DoS uses: - - as target address the target address found in received NS. - - as IPv6 source address: the target address found in received NS. - - as IPv6 destination address: the link-local solicited-node multicast - address derived from the target address in received NS. - - the mac address of the interface as source (or reply_mac, see below). - - the multicast mac address derived from the solicited node multicast - address used as IPv6 destination address. - - A Target Link-Layer address option (ICMPv6NDOptDstLLAddr) filled - with the mac address used as source of the NA. - - Following arguments can be used to change the behavior: - - iface: a specific interface (e.g. "eth0") of the system on which the - DoS should be launched. If None is provided conf.iface is used. - - mac_src_filter: a mac address (e.g "00:13:72:8c:b5:69") to filter on. - Only NS messages received from this source will trigger replies. - This allows limiting the effects of the DoS to a single target by - filtering on its mac address. The default value is None: the DoS - is not limited to a specific mac address. - - tgt_filter: Same as previous but for a specific target IPv6 address for - received NS. If the target address in the NS message (not the IPv6 - destination address) matches that address, then a fake reply will - be sent, i.e. the emitter will be a target of the DoS. - - reply_mac: allow specifying a specific source mac address for the reply, - i.e. to prevent the use of the mac address of the interface. This - address will also be used in the Target Link-Layer Address option. - """ - - def na_reply_callback(req, reply_mac, iface): - """ - Callback that reply to a NS with a NA - """ - - # Let's build a reply and send it - mac = req[Ether].src - dst = req[IPv6].dst - tgt = req[ICMPv6ND_NS].tgt - rep = Ether(src=reply_mac) / IPv6(src=tgt, dst=dst) - rep /= ICMPv6ND_NA(tgt=tgt, S=0, R=0, O=1) # noqa: E741 - rep /= ICMPv6NDOptDstLLAddr(lladdr=reply_mac) - sendp(rep, iface=iface, verbose=0) - - print("Reply NA for target address %s (received from %s)" % (tgt, mac)) - - _NDP_Attack_DAD_DoS(na_reply_callback, iface, mac_src_filter, - tgt_filter, reply_mac) - - -def NDP_Attack_NA_Spoofing(iface=None, mac_src_filter=None, tgt_filter=None, - reply_mac=None, router=False): - """ - The main purpose of this function is to send fake Neighbor Advertisement - messages to a victim. As the emission of unsolicited Neighbor Advertisement - is pretty pointless (from an attacker standpoint) because it will not - lead to a modification of a victim's neighbor cache, the function send - advertisements in response to received NS (NS sent as part of the DAD, - i.e. with an unspecified address as source, are not considered). - - By default, the fake NA sent to create the DoS uses: - - as target address the target address found in received NS. - - as IPv6 source address: the target address - - as IPv6 destination address: the source IPv6 address of received NS - message. - - the mac address of the interface as source (or reply_mac, see below). - - the source mac address of the received NS as destination macs address - of the emitted NA. - - A Target Link-Layer address option (ICMPv6NDOptDstLLAddr) - filled with the mac address used as source of the NA. - - Following arguments can be used to change the behavior: - - iface: a specific interface (e.g. "eth0") of the system on which the - DoS should be launched. If None is provided conf.iface is used. - - mac_src_filter: a mac address (e.g "00:13:72:8c:b5:69") to filter on. - Only NS messages received from this source will trigger replies. - This allows limiting the effects of the DoS to a single target by - filtering on its mac address. The default value is None: the DoS - is not limited to a specific mac address. - - tgt_filter: Same as previous but for a specific target IPv6 address for - received NS. If the target address in the NS message (not the IPv6 - destination address) matches that address, then a fake reply will - be sent, i.e. the emitter will be a target of the DoS. - - reply_mac: allow specifying a specific source mac address for the reply, - i.e. to prevent the use of the mac address of the interface. This - address will also be used in the Target Link-Layer Address option. - - router: by the default (False) the 'R' flag in the NA used for the reply - is not set. If the parameter is set to True, the 'R' flag in the - NA is set, advertising us as a router. - - Please, keep the following in mind when using the function: for obvious - reasons (kernel space vs. Python speed), when the target of the address - resolution is on the link, the sender of the NS receives 2 NA messages - in a row, the valid one and our fake one. The second one will overwrite - the information provided by the first one, i.e. the natural latency of - Scapy helps here. - - In practice, on a common Ethernet link, the emission of the NA from the - genuine target (kernel stack) usually occurs in the same millisecond as - the receipt of the NS. The NA generated by Scapy6 will usually come after - something 20+ ms. On a usual testbed for instance, this difference is - sufficient to have the first data packet sent from the victim to the - destination before it even receives our fake NA. - """ - - def is_request(req, mac_src_filter, tgt_filter): - """ - Check if packet req is a request - """ - - # Those simple checks are based on Section 5.4.2 of RFC 4862 - if not (Ether in req and IPv6 in req and ICMPv6ND_NS in req): - return 0 - - mac_src = req[Ether].src - if mac_src_filter and mac_src != mac_src_filter: - return 0 - - # Source must NOT be the unspecified address - if req[IPv6].src == "::": - return 0 - - tgt = inet_pton(socket.AF_INET6, req[ICMPv6ND_NS].tgt) - if tgt_filter and tgt != tgt_filter: - return 0 - - dst = req[IPv6].dst - if in6_isllsnmaddr(dst): # Address is Link Layer Solicited Node mcast. - - # If this is a real address resolution NS, then the destination - # address of the packet is the link-local solicited node multicast - # address associated with the target of the NS. - # Otherwise, the NS is a NUD related one, i.e. the peer is - # unicasting the NS to check the target is still alive (L2 - # information is still in its cache and it is verified) - received_snma = inet_pton(socket.AF_INET6, dst) - expected_snma = in6_getnsma(tgt) - if received_snma != expected_snma: - print("solicited node multicast @ does not match target @!") - return 0 - - return 1 - - def reply_callback(req, reply_mac, router, iface): - """ - Callback that reply to a NS with a spoofed NA - """ - - # Let's build a reply (as defined in Section 7.2.4. of RFC 4861) and - # send it back. - mac = req[Ether].src - pkt = req[IPv6] - src = pkt.src - tgt = req[ICMPv6ND_NS].tgt - rep = Ether(src=reply_mac, dst=mac) / IPv6(src=tgt, dst=src) - # Use the target field from the NS - rep /= ICMPv6ND_NA(tgt=tgt, S=1, R=router, O=1) # noqa: E741 - - # "If the solicitation IP Destination Address is not a multicast - # address, the Target Link-Layer Address option MAY be omitted" - # Given our purpose, we always include it. - rep /= ICMPv6NDOptDstLLAddr(lladdr=reply_mac) - - sendp(rep, iface=iface, verbose=0) - - print("Reply NA for target address %s (received from %s)" % (tgt, mac)) - - if not iface: - iface = conf.iface - # To prevent sniffing our own traffic - if not reply_mac: - reply_mac = get_if_hwaddr(iface) - sniff_filter = "icmp6 and not ether src %s" % reply_mac - - router = (router and 1) or 0 # Value of the R flags in NA - - sniff(store=0, - filter=sniff_filter, - lfilter=lambda x: is_request(x, mac_src_filter, tgt_filter), - prn=lambda x: reply_callback(x, reply_mac, router, iface), - iface=iface) - - -def NDP_Attack_NS_Spoofing(src_lladdr=None, src=None, target="2001:db8::1", - dst=None, src_mac=None, dst_mac=None, loop=True, - inter=1, iface=None): - """ - The main purpose of this function is to send fake Neighbor Solicitations - messages to a victim, in order to either create a new entry in its neighbor - cache or update an existing one. In section 7.2.3 of RFC 4861, it is stated - that a node SHOULD create the entry or update an existing one (if it is not - currently performing DAD for the target of the NS). The entry's reachability # noqa: E501 - state is set to STALE. - - The two main parameters of the function are the source link-layer address - (carried by the Source Link-Layer Address option in the NS) and the - source address of the packet. - - Unlike some other NDP_Attack_* function, this one is not based on a - stimulus/response model. When called, it sends the same NS packet in loop - every second (the default) - - Following arguments can be used to change the format of the packets: - - src_lladdr: the MAC address used in the Source Link-Layer Address option - included in the NS packet. This is the address that the peer should - associate in its neighbor cache with the IPv6 source address of the - packet. If None is provided, the mac address of the interface is - used. - - src: the IPv6 address used as source of the packet. If None is provided, - an address associated with the emitting interface will be used - (based on the destination address of the packet). - - target: the target address of the NS packet. If no value is provided, - a dummy address (2001:db8::1) is used. The value of the target - has a direct impact on the destination address of the packet if it - is not overridden. By default, the solicited-node multicast address - associated with the target is used as destination address of the - packet. Consider specifying a specific destination address if you - intend to use a target address different than the one of the victim. - - dst: The destination address of the NS. By default, the solicited node - multicast address associated with the target address (see previous - parameter) is used if no specific value is provided. The victim - is not expected to check the destination address of the packet, - so using a multicast address like ff02::1 should work if you want - the attack to target all hosts on the link. On the contrary, if - you want to be more stealth, you should provide the target address - for this parameter in order for the packet to be sent only to the - victim. - - src_mac: the MAC address used as source of the packet. By default, this - is the address of the interface. If you want to be more stealth, - feel free to use something else. Note that this address is not the - that the victim will use to populate its neighbor cache. - - dst_mac: The MAC address used as destination address of the packet. If - the IPv6 destination address is multicast (all-nodes, solicited - node, ...), it will be computed. If the destination address is - unicast, a neighbor solicitation will be performed to get the - associated address. If you want the attack to be stealth, you - can provide the MAC address using this parameter. - - loop: By default, this parameter is True, indicating that NS packets - will be sent in loop, separated by 'inter' seconds (see below). - When set to False, a single packet is sent. - - inter: When loop parameter is True (the default), this parameter provides - the interval in seconds used for sending NS packets. - - iface: to force the sending interface. - """ - - if not iface: - iface = conf.iface - - # Use provided MAC address as source link-layer address option - # or the MAC address of the interface if none is provided. - if not src_lladdr: - src_lladdr = get_if_hwaddr(iface) - - # Prepare packets parameters - ether_params = {} - if src_mac: - ether_params["src"] = src_mac - - if dst_mac: - ether_params["dst"] = dst_mac - - ipv6_params = {} - if src: - ipv6_params["src"] = src - if dst: - ipv6_params["dst"] = dst - else: - # Compute the solicited-node multicast address - # associated with the target address. - tmp = inet_ntop(socket.AF_INET6, - in6_getnsma(inet_pton(socket.AF_INET6, target))) - ipv6_params["dst"] = tmp - - pkt = Ether(**ether_params) - pkt /= IPv6(**ipv6_params) - pkt /= ICMPv6ND_NS(tgt=target) - pkt /= ICMPv6NDOptSrcLLAddr(lladdr=src_lladdr) - - sendp(pkt, inter=inter, loop=loop, iface=iface, verbose=0) - - -def NDP_Attack_Kill_Default_Router(iface=None, mac_src_filter=None, - ip_src_filter=None, reply_mac=None, - tgt_mac=None): - """ - The purpose of the function is to monitor incoming RA messages - sent by default routers (RA with a non-zero Router Lifetime values) - and invalidate them by immediately replying with fake RA messages - advertising a zero Router Lifetime value. - - The result on receivers is that the router is immediately invalidated, - i.e. the associated entry is discarded from the default router list - and destination cache is updated to reflect the change. - - By default, the function considers all RA messages with a non-zero - Router Lifetime value but provides configuration knobs to allow - filtering RA sent by specific routers (Ethernet source address). - With regard to emission, the multicast all-nodes address is used - by default but a specific target can be used, in order for the DoS to - apply only to a specific host. - - More precisely, following arguments can be used to change the behavior: - - iface: a specific interface (e.g. "eth0") of the system on which the - DoS should be launched. If None is provided conf.iface is used. - - mac_src_filter: a mac address (e.g "00:13:72:8c:b5:69") to filter on. - Only RA messages received from this source will trigger replies. - If other default routers advertised their presence on the link, - their clients will not be impacted by the attack. The default - value is None: the DoS is not limited to a specific mac address. - - ip_src_filter: an IPv6 address (e.g. fe80::21e:bff:fe4e:3b2) to filter - on. Only RA messages received from this source address will trigger - replies. If other default routers advertised their presence on the - link, their clients will not be impacted by the attack. The default - value is None: the DoS is not limited to a specific IPv6 source - address. - - reply_mac: allow specifying a specific source mac address for the reply, - i.e. to prevent the use of the mac address of the interface. - - tgt_mac: allow limiting the effect of the DoS to a specific host, - by sending the "invalidating RA" only to its mac address. - """ - - def is_request(req, mac_src_filter, ip_src_filter): - """ - Check if packet req is a request - """ - - if not (Ether in req and IPv6 in req and ICMPv6ND_RA in req): - return 0 - - mac_src = req[Ether].src - if mac_src_filter and mac_src != mac_src_filter: - return 0 - - ip_src = req[IPv6].src - if ip_src_filter and ip_src != ip_src_filter: - return 0 - - # Check if this is an advertisement for a Default Router - # by looking at Router Lifetime value - if req[ICMPv6ND_RA].routerlifetime == 0: - return 0 - - return 1 - - def ra_reply_callback(req, reply_mac, tgt_mac, iface): - """ - Callback that sends an RA with a 0 lifetime - """ - - # Let's build a reply and send it - - src = req[IPv6].src - - # Prepare packets parameters - ether_params = {} - if reply_mac: - ether_params["src"] = reply_mac - - if tgt_mac: - ether_params["dst"] = tgt_mac - - # Basis of fake RA (high pref, zero lifetime) - rep = Ether(**ether_params) / IPv6(src=src, dst="ff02::1") - rep /= ICMPv6ND_RA(prf=1, routerlifetime=0) - - # Add it a PIO from the request ... - tmp = req - while ICMPv6NDOptPrefixInfo in tmp: - pio = tmp[ICMPv6NDOptPrefixInfo] - tmp = pio.payload - del(pio.payload) - rep /= pio - - # ... and source link layer address option - if ICMPv6NDOptSrcLLAddr in req: - mac = req[ICMPv6NDOptSrcLLAddr].lladdr - else: - mac = req[Ether].src - rep /= ICMPv6NDOptSrcLLAddr(lladdr=mac) - - sendp(rep, iface=iface, verbose=0) - - print("Fake RA sent with source address %s" % src) - - if not iface: - iface = conf.iface - # To prevent sniffing our own traffic - if not reply_mac: - reply_mac = get_if_hwaddr(iface) - sniff_filter = "icmp6 and not ether src %s" % reply_mac - - sniff(store=0, - filter=sniff_filter, - lfilter=lambda x: is_request(x, mac_src_filter, ip_src_filter), - prn=lambda x: ra_reply_callback(x, reply_mac, tgt_mac, iface), - iface=iface) - - -def NDP_Attack_Fake_Router(ra, iface=None, mac_src_filter=None, - ip_src_filter=None): - """ - The purpose of this function is to send provided RA message at layer 2 - (i.e. providing a packet starting with IPv6 will not work) in response - to received RS messages. In the end, the function is a simple wrapper - around sendp() that monitor the link for RS messages. - - It is probably better explained with an example: - - >>> ra = Ether()/IPv6()/ICMPv6ND_RA() - >>> ra /= ICMPv6NDOptPrefixInfo(prefix="2001:db8:1::", prefixlen=64) - >>> ra /= ICMPv6NDOptPrefixInfo(prefix="2001:db8:2::", prefixlen=64) - >>> ra /= ICMPv6NDOptSrcLLAddr(lladdr="00:11:22:33:44:55") - >>> NDP_Attack_Fake_Router(ra, iface="eth0") - Fake RA sent in response to RS from fe80::213:58ff:fe8c:b573 - Fake RA sent in response to RS from fe80::213:72ff:fe8c:b9ae - ... - - Following arguments can be used to change the behavior: - - ra: the RA message to send in response to received RS message. - - iface: a specific interface (e.g. "eth0") of the system on which the - DoS should be launched. If none is provided, conf.iface is - used. - - mac_src_filter: a mac address (e.g "00:13:72:8c:b5:69") to filter on. - Only RS messages received from this source will trigger a reply. - Note that no changes to provided RA is done which imply that if - you intend to target only the source of the RS using this option, - you will have to set the Ethernet destination address to the same - value in your RA. - The default value for this parameter is None: no filtering on the - source of RS is done. - - ip_src_filter: an IPv6 address (e.g. fe80::21e:bff:fe4e:3b2) to filter - on. Only RS messages received from this source address will trigger - replies. Same comment as for previous argument apply: if you use - the option, you will probably want to set a specific Ethernet - destination address in the RA. - """ - - def is_request(req, mac_src_filter, ip_src_filter): - """ - Check if packet req is a request - """ - - if not (Ether in req and IPv6 in req and ICMPv6ND_RS in req): - return 0 - - mac_src = req[Ether].src - if mac_src_filter and mac_src != mac_src_filter: - return 0 - - ip_src = req[IPv6].src - if ip_src_filter and ip_src != ip_src_filter: - return 0 - - return 1 - - def ra_reply_callback(req, iface): - """ - Callback that sends an RA in reply to an RS - """ - - src = req[IPv6].src - sendp(ra, iface=iface, verbose=0) - print("Fake RA sent in response to RS from %s" % src) - - if not iface: - iface = conf.iface - sniff_filter = "icmp6" - - sniff(store=0, - filter=sniff_filter, - lfilter=lambda x: is_request(x, mac_src_filter, ip_src_filter), - prn=lambda x: ra_reply_callback(x, iface), - iface=iface) - -############################################################################# -# Pre-load classes ## -############################################################################# - - -def _get_cls(name): - return globals().get(name, Raw) - - -def _load_dict(d): - for k, v in d.items(): - d[k] = _get_cls(v) - - -_load_dict(icmp6ndoptscls) -_load_dict(icmp6typescls) -_load_dict(ipv6nhcls) - -############################################################################# -############################################################################# -# Layers binding # -############################################################################# -############################################################################# - -conf.l3types.register(ETH_P_IPV6, IPv6) -conf.l2types.register(31, IPv6) -conf.l2types.register(DLT_IPV6, IPv6) -conf.l2types.register(DLT_RAW, _IPv46) -conf.l2types.register_num2layer(DLT_RAW_ALT, _IPv46) - -bind_layers(Ether, IPv6, type=0x86dd) -bind_layers(CookedLinux, IPv6, proto=0x86dd) -bind_layers(GRE, IPv6, proto=0x86dd) -bind_layers(SNAP, IPv6, code=0x86dd) -bind_layers(Loopback, IPv6, type=socket.AF_INET6) -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=socket.IPPROTO_IPIP) -bind_layers(IPv6, GRE, nh=socket.IPPROTO_GRE) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/ipsec.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/ipsec.py deleted file mode 100644 index ae057ee155..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/ipsec.py +++ /dev/null @@ -1,1102 +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('testdata') ->>> p = IP(raw(p)) ->>> p ->> # noqa: E501 ->>> ->>> e = sa.encrypt(p) ->>> e -> # noqa: E501 ->>> ->>> d = sa.decrypt(e) ->>> d ->> # noqa: E501 ->>> ->>> d == p -True -""" - -from __future__ import absolute_import -try: - from math import gcd -except ImportError: - from fractions import gcd -import os -import socket -import struct - -from scapy.config import conf, crypto_validator -from scapy.compat import orb, raw -from scapy.data import IP_PROTOS -from scapy.error import log_loading -from scapy.fields import ByteEnumField, ByteField, IntField, PacketField, \ - ShortField, StrField, XIntField, XStrField, XStrLenField -from scapy.packet import Packet, bind_layers, Raw -from scapy.layers.inet import IP, UDP -import scapy.modules.six as six -from scapy.modules.six.moves import range -from scapy.layers.inet6 import IPv6, IPv6ExtHdrHopByHop, IPv6ExtHdrDestOpt, \ - IPv6ExtHdrRouting - - -############################################################################### -class AH(Packet): - """ - Authentication Header - - See https://tools.ietf.org/rfc/rfc4302.txt - """ - - name = 'AH' - - def __get_icv_len(self): - """ - Compute the size of the ICV based on the payloadlen field. - Padding size is included as it can only be known from the authentication # noqa: E501 - algorithm provided by the Security Association. - """ - # payloadlen = length of AH in 32-bit words (4-byte units), minus "2" - # payloadlen = 3 32-bit word fixed fields + ICV + padding - 2 - # ICV = (payloadlen + 2 - 3 - padding) in 32-bit words - return (self.payloadlen - 1) * 4 - - fields_desc = [ - ByteEnumField('nh', None, IP_PROTOS), - ByteField('payloadlen', None), - ShortField('reserved', None), - XIntField('spi', 0x0), - IntField('seq', 0), - XStrLenField('icv', None, length_from=__get_icv_len), - # Padding len can only be known with the SecurityAssociation.auth_algo - XStrLenField('padding', None, length_from=lambda x: 0), - ] - - 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) -bind_layers(AH, IP, nh=socket.IPPROTO_IP) -bind_layers(AH, IPv6, nh=socket.IPPROTO_IPV6) - -############################################################################### - - -class ESP(Packet): - """ - Encapsulated Security Payload - - See https://tools.ietf.org/rfc/rfc4303.txt - """ - name = 'ESP' - - fields_desc = [ - XIntField('spi', 0x0), - IntField('seq', 0), - XStrField('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 raw(self.data) + self.padding + struct.pack("BB", self.padlen, self.nh) # noqa: E501 - - -############################################################################### -if conf.crypto_valid: - from cryptography.exceptions import InvalidTag - from cryptography.hazmat.backends import default_backend - from cryptography.hazmat.primitives.ciphers import ( - Cipher, - algorithms, - modes, - ) -else: - log_loading.info("Can't import python-cryptography v1.7+. " - "Disabled IPsec encryption/authentication.") - InvalidTag = default_backend = None - Cipher = algorithms = modes = None - -############################################################################### - - -def _lcm(a, b): - """ - Least Common Multiple between 2 integers. - """ - if a == 0 or b == 0: - return 0 - else: - return abs(a * b) // gcd(a, b) - - -class CryptAlgo(object): - """ - IPsec encryption algorithm - """ - - def __init__(self, name, cipher, mode, block_size=None, iv_size=None, - key_size=None, icv_size=None, salt_size=None, format_mode_iv=None): # noqa: E501 - """ - @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. - @param icv_size: the length of the Integrity Check Value of this algo. - Used by Combined Mode Algorithms e.g. GCM - @param salt_size: the length of the salt to use as the IV prefix. - Usually used by Counter modes e.g. CTR - @param format_mode_iv: function to format the Initialization Vector - e.g. handle the salt value - Default is the random buffer from `generate_iv` - """ - self.name = name - self.cipher = cipher - self.mode = mode - self.icv_size = icv_size - - if modes and self.mode is not None: - self.is_aead = issubclass(self.mode, - modes.ModeWithAuthenticationTag) - else: - self.is_aead = False - - if block_size is not None: - self.block_size = block_size - elif cipher is not None: - self.block_size = cipher.block_size // 8 - 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 = tuple(i // 8 for i in cipher.key_sizes) - else: - self.key_size = None - - if salt_size is None: - self.salt_size = 0 - else: - self.salt_size = salt_size - - if format_mode_iv is None: - self._format_mode_iv = lambda iv, **kw: iv - else: - self._format_mode_iv = format_mode_iv - - 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): # noqa: E501 - raise TypeError('invalid key size %s, must be %s' % - (len(key), self.key_size)) - - def generate_iv(self): - """ - Generate a random initialization vector. - """ - # XXX: Handle counter modes with real counters? RFCs allow the use of - # XXX: random bytes for counters, so it is not wrong to do it that way - return os.urandom(self.iv_size) - - @crypto_validator - def new_cipher(self, key, mode_iv, digest=None): - """ - @param key: the secret key, a byte string - @param mode_iv: the initialization vector or nonce, a byte string. - Formatted by `format_mode_iv`. - @param digest: also known as tag or icv. A byte string containing the - digest of the encrypted data. Only use this during - decryption! - - @return: an initialized cipher object for this algo - """ - if self.is_aead and digest is not None: - # With AEAD, the mode needs the digest during decryption. - return Cipher( - self.cipher(key), - self.mode(mode_iv, digest, len(digest)), - default_backend(), - ) - else: - return Cipher( - self.cipher(key), - self.mode(mode_iv), - default_backend(), - ) - - 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 - bytes. - - @param esp: an unencrypted _ESPPlain packet - - @return: an unencrypted _ESPPlain packet with valid padding - """ - # 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 - - # Still according to the RFC, the default value for padding *MUST* be an # noqa: E501 - # array of bytes starting from 1 to padlen - # TODO: Handle padding function according to the encryption algo - esp.padding = struct.pack("B" * esp.padlen, *range(1, esp.padlen + 1)) - - # 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.') # noqa: E501 - - return esp - - def encrypt(self, sa, esp, key, esn_en=False, esn=0): - """ - Encrypt an ESP packet - - @param sa: the SecurityAssociation associated with the ESP packet. - @param esp: an unencrypted _ESPPlain packet with valid padding - @param key: the secret key used for encryption - @esn_en: extended sequence number enable which allows to use 64-bit - sequence number instead of 32-bit when using an AEAD - algorithm - @esn: extended sequence number (32 MSB) - @return: a valid ESP packet encrypted with this algorithm - """ - data = esp.data_for_encryption() - - if self.cipher: - mode_iv = self._format_mode_iv(algo=self, sa=sa, iv=esp.iv) - cipher = self.new_cipher(key, mode_iv) - encryptor = cipher.encryptor() - - if self.is_aead: - if esn_en: - aad = struct.pack('!LLL', esp.spi, esn, esp.seq) - else: - aad = struct.pack('!LL', esp.spi, esp.seq) - encryptor.authenticate_additional_data(aad) - data = encryptor.update(data) + encryptor.finalize() - data += encryptor.tag[:self.icv_size] - else: - data = encryptor.update(data) + encryptor.finalize() - - return ESP(spi=esp.spi, seq=esp.seq, data=esp.iv + data) - - def decrypt(self, sa, esp, key, icv_size=None, esn_en=False, esn=0): - """ - Decrypt an ESP packet - - @param sa: the SecurityAssociation associated with the ESP packet. # noqa: E501 - @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 - @esn_en: extended sequence number enable which allows to use 64-bit - sequence number instead of 32-bit when using an AEAD algorithm - @esn: extended sequence number (32 MSB) - @return: a valid ESP packet encrypted with this algorithm - @raise IPSecIntegrityError: if the integrity check fails with an AEAD - algorithm - """ - if icv_size is None: - icv_size = self.icv_size if self.is_aead else 0 - - 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: - mode_iv = self._format_mode_iv(sa=sa, iv=iv) - cipher = self.new_cipher(key, mode_iv, icv) - decryptor = cipher.decryptor() - - if self.is_aead: - # Tag value check is done during the finalize method - if esn_en: - decryptor.authenticate_additional_data( - struct.pack('!LLL', esp.spi, esn, esp.seq)) - else: - decryptor.authenticate_additional_data( - struct.pack('!LL', esp.spi, esp.seq)) - try: - data = decryptor.update(data) + decryptor.finalize() - except InvalidTag as err: - raise IPSecIntegrityError(err) - - # extract padlen and nh - padlen = orb(data[-2]) - nh = orb(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 # noqa: E501 -# see http://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml - - -CRYPT_ALGOS = { - 'NULL': CryptAlgo('NULL', cipher=None, mode=None, iv_size=0), -} - -if algorithms: - CRYPT_ALGOS['AES-CBC'] = CryptAlgo('AES-CBC', - cipher=algorithms.AES, - mode=modes.CBC) - _aes_ctr_format_mode_iv = lambda sa, iv, **kw: sa.crypt_salt + iv + b'\x00\x00\x00\x01' # noqa: E501 - CRYPT_ALGOS['AES-CTR'] = CryptAlgo('AES-CTR', - cipher=algorithms.AES, - mode=modes.CTR, - iv_size=8, - salt_size=4, - format_mode_iv=_aes_ctr_format_mode_iv) - _salt_format_mode_iv = lambda sa, iv, **kw: sa.crypt_salt + iv - CRYPT_ALGOS['AES-GCM'] = CryptAlgo('AES-GCM', - cipher=algorithms.AES, - mode=modes.GCM, - salt_size=4, - iv_size=8, - icv_size=16, - format_mode_iv=_salt_format_mode_iv) - if hasattr(modes, 'CCM'): - CRYPT_ALGOS['AES-CCM'] = CryptAlgo('AES-CCM', - cipher=algorithms.AES, - mode=modes.CCM, - iv_size=8, - salt_size=3, - icv_size=16, - format_mode_iv=_salt_format_mode_iv) - # XXX: Flagged as weak by 'cryptography'. Kept for backward compatibility - CRYPT_ALGOS['Blowfish'] = CryptAlgo('Blowfish', - cipher=algorithms.Blowfish, - mode=modes.CBC) - # XXX: RFC7321 states that DES *MUST NOT* be implemented. - # XXX: Keep for backward compatibility? - # Using a TripleDES cipher algorithm for DES is done by using the same 64 - # bits key 3 times (done by cryptography when given a 64 bits key) - CRYPT_ALGOS['DES'] = CryptAlgo('DES', - cipher=algorithms.TripleDES, - mode=modes.CBC, - key_size=(8,)) - CRYPT_ALGOS['3DES'] = CryptAlgo('3DES', - cipher=algorithms.TripleDES, - mode=modes.CBC) - CRYPT_ALGOS['CAST'] = CryptAlgo('CAST', - cipher=algorithms.CAST5, - mode=modes.CBC) - -############################################################################### -if conf.crypto_valid: - from cryptography.hazmat.primitives.hmac import HMAC - from cryptography.hazmat.primitives.cmac import CMAC - from cryptography.hazmat.primitives import hashes -else: - # no error if cryptography is not available but authentication won't be supported # noqa: E501 - HMAC = CMAC = hashes = 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)) - - @crypto_validator - def new_mac(self, key): - """ - @param key: a byte string - @return: an initialized mac object for this algo - """ - if self.mac is CMAC: - return self.mac(self.digestmod(key), default_backend()) - else: - return self.mac(key, self.digestmod(), default_backend()) - - 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 - - mac = self.new_mac(key) - - if pkt.haslayer(ESP): - mac.update(raw(pkt[ESP])) - pkt[ESP].data += mac.finalize()[:self.icv_size] - - elif pkt.haslayer(AH): - clone = zero_mutable_fields(pkt.copy(), sending=True) - mac.update(raw(clone)) - pkt[AH].icv = mac.finalize()[: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 - - 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:] - clone = pkt.copy() - clone.data = clone.data[:len(clone.data) - self.icv_size] - - elif pkt.haslayer(AH): - if len(pkt[AH].icv) != self.icv_size: - # Fill padding since we know the actual icv_size - pkt[AH].padding = pkt[AH].icv[self.icv_size:] - pkt[AH].icv = pkt[AH].icv[:self.icv_size] - pkt_icv = pkt[AH].icv - clone = zero_mutable_fields(pkt.copy(), sending=False) - - mac.update(raw(clone)) - computed_icv = mac.finalize()[:self.icv_size] - - # XXX: Cannot use mac.verify because the ICV can be truncated - 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 # noqa: E501 -# 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 and hashes: - # XXX: NIST has deprecated SHA1 but is required by RFC7321 - AUTH_ALGOS['HMAC-SHA1-96'] = AuthAlgo('HMAC-SHA1-96', - mac=HMAC, - digestmod=hashes.SHA1, - icv_size=12) - AUTH_ALGOS['SHA2-256-128'] = AuthAlgo('SHA2-256-128', - mac=HMAC, - digestmod=hashes.SHA256, - icv_size=16) - AUTH_ALGOS['SHA2-384-192'] = AuthAlgo('SHA2-384-192', - mac=HMAC, - digestmod=hashes.SHA384, - icv_size=24) - AUTH_ALGOS['SHA2-512-256'] = AuthAlgo('SHA2-512-256', - mac=HMAC, - digestmod=hashes.SHA512, - icv_size=32) - # XXX:Flagged as deprecated by 'cryptography'. Kept for backward compat - AUTH_ALGOS['HMAC-MD5-96'] = AuthAlgo('HMAC-MD5-96', - mac=HMAC, - digestmod=hashes.MD5, - icv_size=12) -if CMAC and algorithms: - AUTH_ALGOS['AES-CMAC-96'] = AuthAlgo('AES-CMAC-96', - mac=CMAC, - digestmod=algorithms.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. - """ - # force resolution of default fields to avoid padding errors - header = orig_pkt.__class__(raw(orig_pkt)) - 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)): # noqa: E501 - 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 = b"\x00" * 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(b"\x00" * 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)): # noqa: E501 - 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 = b"\x00" * 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. # noqa: E501 - 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. # noqa: E501 - """ - - 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, esn_en=False, esn=0): # noqa: E501 - """ - @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. - @esn_en: extended sequence number enable which allows to use 64-bit - sequence number instead of 32-bit when using an AEAD - algorithm - @esn: extended sequence number (32 MSB) - """ - - if proto not in (ESP, AH, ESP.name, AH.name): - raise ValueError("proto must be either ESP or AH") - if isinstance(proto, six.string_types): - self.proto = eval(proto) - else: - self.proto = proto - - self.spi = spi - self.seq_num = seq_num - self.esn_en = esn_en - # Get Extended Sequence (32 MSB) - self.esn = esn - if crypt_algo: - if crypt_algo not in CRYPT_ALGOS: - raise TypeError('unsupported encryption algo %r, try %r' % - (crypt_algo, list(CRYPT_ALGOS))) - self.crypt_algo = CRYPT_ALGOS[crypt_algo] - - if crypt_key: - salt_size = self.crypt_algo.salt_size - self.crypt_key = crypt_key[:len(crypt_key) - salt_size] - self.crypt_salt = crypt_key[len(crypt_key) - salt_size:] - else: - self.crypt_key = None - self.crypt_salt = None - - 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, list(AUTH_ALGOS))) - self.auth_algo = AUTH_ALGOS[auth_algo] - 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)) # noqa: E501 - 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, esn_en=None, esn=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) # noqa: E501 - - 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__(raw(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(self, esp, self.crypt_key, - esn_en=esn_en or self.esn_en, - esn=esn or self.esn) - - 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__(raw(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=b"\x00" * 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__(raw(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 = b"\x00" * (-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 = b"\x00" * (-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__(raw(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) # noqa: E501 - - # 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, esn_en=None, esn=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 - @esn_en: extended sequence number enable which allows to - use 64-bit sequence number instead of 32-bit when - using an AEAD algorithm - @esn: extended sequence number (32 MSB) - @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, esn_en=esn_en, - esn=esn) - else: - return self._encrypt_ah(pkt, seq_num=seq_num) - - def _decrypt_esp(self, pkt, verify=True, esn_en=None, esn=None): - - encrypted = pkt[ESP] - - if verify: - self.check_spi(pkt) - self.auth_algo.verify(encrypted, self.auth_key) - - esp = self.crypt_algo.decrypt(self, encrypted, self.crypt_key, - self.crypt_algo.icv_size or - self.auth_algo.icv_size, - esn_en=esn_en or self.esn_en, - esn=esn or self.esn) - - 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__(raw(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__(raw(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, esn_en=None, esn=None): - """ - 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 - @esn_en: extended sequence number enable which allows to use 64-bit - sequence number instead of 32-bit when using an AEAD - algorithm - @esn: extended sequence number (32 MSB) - @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, - esn_en=esn_en, esn=esn) - 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-2.4.3/scapy/layers/ir.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/ir.py deleted file mode 100644 index c25fc0852c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/ir.py +++ /dev/null @@ -1,45 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -IrDA infrared data communication. -""" - -from scapy.packet import Packet, bind_layers -from scapy.fields import BitEnumField, ByteEnumField, StrField, XBitField, \ - XByteField, XIntField, XShortField -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-2.4.3/scapy/layers/isakmp.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/isakmp.py deleted file mode 100644 index 4267e22b9b..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/isakmp.py +++ /dev/null @@ -1,353 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -ISAKMP (Internet Security Association and Key Management Protocol). -""" - -# Mostly based on https://tools.ietf.org/html/rfc2408 - -from __future__ import absolute_import -import struct -from scapy.config import conf -from scapy.packet import Packet, bind_bottom_up, bind_top_down, bind_layers -from scapy.compat import chb -from scapy.fields import ByteEnumField, ByteField, FieldLenField, FlagsField, \ - IntEnumField, IntField, PacketLenField, ShortEnumField, ShortField, \ - StrFixedLenField, StrLenField, XByteField -from scapy.layers.inet import IP, UDP -from scapy.sendrecv import sr -from scapy.volatile import RandString -from scapy.error import warning -from functools import reduce - -# TODO: some ISAKMP payloads are not implemented, -# and inherit a default ISAKMP_payload - - -# 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, # noqa: E501 - "XAUTHRespRSARevisedEncryptio": 65010, }, 0), # noqa: E501 - "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 - - @staticmethod - def type2num(type_val_tuple): - typ, val = type_val_tuple - type_val, enc_dict, tlv = ISAKMPTransformTypes.get(typ, (typ, {}, 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" % typ) # noqa: E501 - n = 0 - while val: - s = chb(val & 0xff) + s - val >>= 8 - n += 1 - val = n - else: - type_val |= 0x8000 - return struct.pack("!HH", type_val, val) + s - - @staticmethod - def num2type(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 = [ISAKMPTransformSetField.type2num(e) for e in 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 transform type=%#6x" % trans_type) # noqa: E501 - value = m[4:4 + value_len] - value = reduce(lambda x, y: (x << 8) | y, struct.unpack("!%s" % ("B" * len(value),), value), 0) # noqa: E501 - else: - trans_type &= 0x7fff - value_len = 0 - value, = struct.unpack("!H", m[2:4]) - m = m[4 + value_len:] - lst.append(ISAKMPTransformSetField.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 # noqa: E501 - 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) # noqa: E501 - # 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: - tmp_len = len(p) - tmp_pay = p[:2] + chb((tmp_len >> 8) & 0xff) - p = tmp_pay + chb(tmp_len & 0xff) + p[4:] - p += pay - return p - - -# https://tools.ietf.org/html/rfc2408#section-3.5 -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), # noqa: E501 - 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), # noqa: E501 - ] - - -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_payload): - name = "ISAKMP Vendor ID" - - -class ISAKMP_payload_SA(ISAKMP_class): - name = "ISAKMP SA" - fields_desc = [ - ByteEnumField("next_payload", None, ISAKMP_payload_type), - ByteField("res", 0), - FieldLenField("length", None, "prop", "H", adjust=lambda pkt, x:x + 12), # noqa: E501 - 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), # noqa: E501 - ] - - -class ISAKMP_payload_Nonce(ISAKMP_payload): - name = "ISAKMP Nonce" - - -class ISAKMP_payload_KE(ISAKMP_payload): - name = "ISAKMP Key Exchange" - - -class ISAKMP_payload_ID(ISAKMP_class): - name = "ISAKMP Identification" - 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_payload): - name = "ISAKMP Hash" - - -bind_bottom_up(UDP, ISAKMP, dport=500) -bind_bottom_up(UDP, ISAKMP, sport=500) -bind_layers(UDP, ISAKMP, dport=500, sport=500) - -# Add building bindings -# (Dissection bindings are located in ISAKMP_class.guess_payload_class) -bind_top_down(ISAKMP_class, ISAKMP_payload, next_payload=0) -bind_top_down(ISAKMP_class, ISAKMP_payload_SA, next_payload=1) -bind_top_down(ISAKMP_class, ISAKMP_payload_Proposal, next_payload=2) -bind_top_down(ISAKMP_class, ISAKMP_payload_Transform, next_payload=3) -bind_top_down(ISAKMP_class, ISAKMP_payload_KE, next_payload=4) -bind_top_down(ISAKMP_class, ISAKMP_payload_ID, next_payload=5) -# bind_top_down(ISAKMP_class, ISAKMP_payload_CERT, next_payload=6) -# bind_top_down(ISAKMP_class, ISAKMP_payload_CR, next_payload=7) -bind_top_down(ISAKMP_class, ISAKMP_payload_Hash, next_payload=8) -# bind_top_down(ISAKMP_class, ISAKMP_payload_SIG, next_payload=9) -bind_top_down(ISAKMP_class, ISAKMP_payload_Nonce, next_payload=10) -# bind_top_down(ISAKMP_class, ISAKMP_payload_Notification, next_payload=11) -# bind_top_down(ISAKMP_class, ISAKMP_payload_Delete, next_payload=12) -bind_top_down(ISAKMP_class, ISAKMP_payload_VendorID, next_payload=13) - - -def ikescan(ip): - """Sends/receives a ISAMPK payload SA with payload proposal""" - pkt = IP(dst=ip) - pkt /= UDP() - pkt /= ISAKMP(init_cookie=RandString(8), exch_type=2) - pkt /= ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal()) - return sr(pkt) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/l2.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/l2.py deleted file mode 100644 index 3f9c312a67..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/l2.py +++ /dev/null @@ -1,789 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Classes and functions for layer 2 protocols. -""" - -from __future__ import absolute_import -from __future__ import print_function -import os -import struct -import time -import socket - -from scapy.ansmachine import AnsweringMachine -from scapy.arch import get_if_addr, get_if_hwaddr -from scapy.base_classes import Gen, Net -from scapy.compat import chb, orb -from scapy.config import conf -from scapy import consts -from scapy.data import ARPHDR_ETHER, ARPHDR_LOOPBACK, ARPHDR_METRICOM, \ - DLT_LINUX_IRDA, DLT_LINUX_SLL, DLT_LOOP, DLT_NULL, ETHER_ANY, \ - ETHER_BROADCAST, ETHER_TYPES, ETH_P_ARP, ETH_P_MACSEC -from scapy.error import warning -from scapy.fields import BCDFloatField, BitField, ByteField, \ - ConditionalField, FieldLenField, IntEnumField, IntField, IP6Field, \ - IPField, LenField, MACField, MultipleTypeField, ShortEnumField, \ - ShortField, SourceIP6Field, SourceIPField, StrFixedLenField, StrLenField, \ - X3BytesField, XByteField, XIntField, XShortEnumField, XShortField -from scapy.modules.six import viewitems -from scapy.packet import bind_layers, Packet -from scapy.plist import PacketList, SndRcvList -from scapy.sendrecv import sendp, srp, srp1 -from scapy.utils import checksum, hexdump, hexstr, inet_ntoa, inet_aton, \ - mac2str, valid_mac, valid_net, valid_net6 -if conf.route is None: - # unused import, only to initialize conf.route - import scapy.route # noqa: F401 - - -################# -# 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) # noqa: E501 - - -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 or "0.0.0.0")) - tmp = [orb(e) for e in inet_aton(ip)] - if (tmp[0] & 0xf0) == 0xe0: # mcast @ - return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1] & 0x7f, tmp[2], tmp[3]) - iff, _, gw = conf.route.route(ip) - if ((iff == consts.LOOPBACK_INTERFACE) or (ip == conf.route.get_if_bcast(iff))): # noqa: E501 - 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 - - try: - 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) - except Exception as ex: - warning("getmacbyip failed on %s" % ex) - return None - 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) - - # TRex Change - Commenting out in order to avoid resolve. - # def i2h(self, pkt, x): - # if x is None: - # try: - # x = conf.neighbor.resolve(pkt, pkt.payload) - # except socket.error: - # pass - # if x is None: - # x = "ff:ff:ff:ff:ff:ff" - # warning("Mac address to reach destination not found. Using broadcast.") # noqa: E501 - # return MACField.i2h(self, pkt, x) - - def i2m(self, pkt, x): - return MACField.i2m(self, pkt, self.i2h(pkt, x)) - - -class SourceMACField(MACField): - __slots__ = ["getif"] - - def __init__(self, name, getif=None): - MACField.__init__(self, name, None) - self.getif = (lambda pkt: pkt.route()[0]) if getif is None else getif - - # TRex Change - Commenting out. - # def i2h(self, pkt, x): - # if x is None: - # iff = self.getif(pkt) - # if iff is None: - # iff = conf.iface - # if iff: - # try: - # x = get_if_hwaddr(iff) - # except Exception as e: - # warning("Could not get the source MAC: %s" % e) - # 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 - -ETHER_TYPES['802_AD'] = 0x88a8 -ETHER_TYPES['802_1AE'] = ETH_P_MACSEC - - -class Ether(Packet): - name = "Ethernet" - # TRex Change - Avoid lookup by putting fixed fields. - fields_desc = [ MACField("dst","00:00:00:01:00:00"), - MACField("src","00:00:00:02:00:00"), - XShortEnumField("type", 0x9000, ETHER_TYPES)] - __slots__ = ["_defrag_pos"] - - 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): - tmp_len = self.len - return s[:tmp_len], s[tmp_len:] - - 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)] - - -def l2_register_l3(l2, l3): - return conf.neighbor.resolve(l2, l3.payload) - - -conf.neighbor.register_l3(Ether, LLC, l2_register_l3) -conf.neighbor.register_l3(Dot3, LLC, l2_register_l3) - - -class CookedLinux(Packet): - # Documentation: http://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html - name = "cooked linux" - # from wireshark's database - fields_desc = [ShortEnumField("pkttype", 0, {0: "unicast", - 1: "broadcast", - 2: "multicast", - 3: "unicast-to-another-host", - 4: "sent-by-us"}), - 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, l2_register_l3) - - -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%") # noqa: E501 - else: - return self.sprintf("802.1q (%Dot1Q.type%) vlan %Dot1Q.vlan%") - - -conf.neighbor.register_l3(Ether, Dot1Q, l2_register_l3) - - -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 ARP(Packet): - name = "ARP" - fields_desc = [ - XShortField("hwtype", 0x0001), - XShortEnumField("ptype", 0x0800, ETHER_TYPES), - FieldLenField("hwlen", None, fmt="B", length_of="hwsrc"), - FieldLenField("plen", None, fmt="B", length_of="psrc"), - 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 - }), - MultipleTypeField( - [ - (SourceMACField("hwsrc"), - (lambda pkt: pkt.hwtype == 1 and pkt.hwlen == 6, - lambda pkt, val: pkt.hwtype == 1 and ( - pkt.hwlen == 6 or (pkt.hwlen is None and - (val is None or len(val) == 6 or - valid_mac(val))) - ))), - ], - StrFixedLenField("hwsrc", None, length_from=lambda pkt: pkt.hwlen), - ), - MultipleTypeField( - [ - (SourceIPField("psrc", "pdst"), - (lambda pkt: pkt.ptype == 0x0800 and pkt.plen == 4, - lambda pkt, val: pkt.ptype == 0x0800 and ( - pkt.plen == 4 or (pkt.plen is None and - (val is None or valid_net(val))) - ))), - (SourceIP6Field("psrc", "pdst"), - (lambda pkt: pkt.ptype == 0x86dd and pkt.plen == 16, - lambda pkt, val: pkt.ptype == 0x86dd and ( - pkt.plen == 16 or (pkt.plen is None and - (val is None or valid_net6(val))) - ))), - ], - StrFixedLenField("psrc", None, length_from=lambda pkt: pkt.plen), - ), - MultipleTypeField( - [ - (MACField("hwdst", ETHER_ANY), - (lambda pkt: pkt.hwtype == 1 and pkt.hwlen == 6, - lambda pkt, val: pkt.hwtype == 1 and ( - pkt.hwlen == 6 or (pkt.hwlen is None and - (val is None or len(val) == 6 or - valid_mac(val))) - ))), - ], - StrFixedLenField("hwdst", None, length_from=lambda pkt: pkt.hwlen), - ), - MultipleTypeField( - [ - (IPField("pdst", "0.0.0.0"), - (lambda pkt: pkt.ptype == 0x0800 and pkt.plen == 4, - lambda pkt, val: pkt.ptype == 0x0800 and ( - pkt.plen == 4 or (pkt.plen is None and - (val is None or valid_net(val))) - ))), - (IP6Field("pdst", "::"), - (lambda pkt: pkt.ptype == 0x86dd and pkt.plen == 16, - lambda pkt, val: pkt.ptype == 0x86dd and ( - pkt.plen == 16 or (pkt.plen is None and - (val is None or valid_net6(val))) - ))), - ], - StrFixedLenField("pdst", None, length_from=lambda pkt: pkt.plen), - ), - ] - - def hashret(self): - return struct.pack(">HHH", self.hwtype, self.ptype, - ((self.op + 1) // 2)) + self.payload.hashret() - - def answers(self, other): - if not isinstance(other, ARP): - return False - if self.op != other.op + 1: - return False - # We use a loose comparison on psrc vs pdst to catch answers - # with ARP leaks - self_psrc = self.get_field('psrc').i2m(self, self.psrc) - other_pdst = other.get_field('pdst').i2m(other, other.pdst) - return self_psrc[:len(other_pdst)] == other_pdst[:len(self_psrc)] - - def route(self): - fld, dst = self.getfield_and_val("pdst") - fld, dst = fld._find_fld_pkt_val(self, dst) - if isinstance(dst, Gen): - dst = next(iter(dst)) - if isinstance(fld, IP6Field): - return conf.route6.route(dst) - elif isinstance(fld, IPField): - return conf.route.route(dst) - else: - return None, None, None - - def extract_padding(self, s): - return "", s - - def mysummary(self): - if self.op == 1: - return self.sprintf("ARP who has %pdst% says %psrc%") - if self.op == 2: - return self.sprintf("ARP is at %hwsrc% says %psrc%") - return self.sprintf("ARP %op% %psrc% > %pdst%") - - -def l2_register_l3_arp(l2, l3): - return getmacbyip(l3.pdst) - - -conf.neighbor.register_l3(Ether, ARP, l2_register_l3_arp) - - -class ERSPAN(Packet): - name = "ERSPAN" - fields_desc = [BitField("ver", 0, 4), - BitField("vlan", 0, 12), - BitField("cos", 0, 3), - BitField("en", 0, 2), - BitField("t", 0, 1), - BitField("session_id", 0, 10), - BitField("reserved", 0, 12), - BitField("index", 0, 20), - ] - - -class GRErouting(Packet): - name = "GRE routing information" - 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), # noqa: E501 - ConditionalField(XShortField("offset", None), lambda pkt:pkt.chksum_present == 1 or pkt.routing_present == 1), # noqa: E501 - ConditionalField(XIntField("key", None), lambda pkt:pkt.key_present == 1), # noqa: E501 - ConditionalField(XIntField("seqence_number", None), lambda pkt:pkt.seqnum_present == 1), # noqa: E501 - ] - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and struct.unpack("!H", _pkt[2:4])[0] == 0x880b: - return GRE_PPTP - return cls - - def post_build(self, p, pay): - p += pay - if self.chksum_present and self.chksum is None: - c = checksum(p) - p = p[:4] + chb((c >> 8) & 0xff) + chb(c & 0xff) + p[6:] - return p - - -class GRE_PPTP(GRE): - - """ - Enhanced GRE header used with PPTP - RFC 2637 - """ - - name = "GRE PPTP" - fields_desc = [BitField("chksum_present", 0, 1), - BitField("routing_present", 0, 1), - BitField("key_present", 1, 1), - BitField("seqnum_present", 0, 1), - BitField("strict_route_source", 0, 1), - BitField("recursion_control", 0, 3), - BitField("acknum_present", 0, 1), - BitField("flags", 0, 4), - BitField("version", 1, 3), - XShortEnumField("proto", 0x880b, ETHER_TYPES), - ShortField("payload_len", None), - ShortField("call_id", None), - ConditionalField(XIntField("seqence_number", None), lambda pkt: pkt.seqnum_present == 1), # noqa: E501 - ConditionalField(XIntField("ack_number", None), lambda pkt: pkt.acknum_present == 1)] # noqa: E501 - - def post_build(self, p, pay): - p += pay - if self.payload_len is None: - pay_len = len(pay) - p = p[:4] + chb((pay_len >> 8) & 0xff) + chb(pay_len & 0xff) + p[6:] # noqa: E501 - return p - - -# *BSD loopback layer - -class LoIntEnumField(IntEnumField): - - def m2i(self, pkt, x): - return x >> 24 - - def i2m(self, pkt, x): - return x << 24 - - -# https://github.com/wireshark/wireshark/blob/fe219637a6748130266a0b0278166046e60a2d68/epan/dissectors/packet-null.c -# https://www.wireshark.org/docs/wsar_html/epan/aftypes_8h.html -LOOPBACK_TYPES = {0x2: "IPv4", - 0x7: "OSI", - 0x10: "Appletalk", - 0x17: "Netware IPX/SPX", - 0x18: "IPv6", 0x1c: "IPv6", 0x1e: "IPv6"} - - -class Loopback(Packet): - """*BSD loopback layer""" - - name = "Loopback" - if consts.OPENBSD: - fields_desc = [IntEnumField("type", 0x2, LOOPBACK_TYPES)] - else: - fields_desc = [LoIntEnumField("type", 0x2, LOOPBACK_TYPES)] - __slots__ = ["_defrag_pos"] - - -class Dot1AD(Dot1Q): - name = '802_1AD' - - -bind_layers(Dot3, LLC,) -bind_layers(Ether, LLC, type=122) -bind_layers(Ether, LLC, type=34928) -bind_layers(Ether, Dot1Q, type=33024) -bind_layers(Ether, Dot1AD, type=0x88a8) -bind_layers(Dot1AD, Dot1AD, type=0x88a8) -bind_layers(Dot1AD, Dot1Q, type=0x8100) -bind_layers(Dot1Q, Dot1AD, type=0x88a8) -bind_layers(ERSPAN, Ether) -bind_layers(Ether, Ether, type=1) -bind_layers(Ether, ARP, type=2054) -bind_layers(CookedLinux, LLC, proto=122) -bind_layers(CookedLinux, Dot1Q, proto=33024) -bind_layers(CookedLinux, Dot1AD, type=0x88a8) -bind_layers(CookedLinux, Ether, proto=1) -bind_layers(CookedLinux, ARP, proto=2054) -bind_layers(GRE, LLC, proto=122) -bind_layers(GRE, Dot1Q, proto=33024) -bind_layers(GRE, Dot1AD, type=0x88a8) -bind_layers(GRE, Ether, proto=0x6558) -bind_layers(GRE, ARP, proto=2054) -bind_layers(GRE, ERSPAN, proto=0x88be, seqnum_present=1) -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(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, Dot1AD, type=0x88a8) -bind_layers(SNAP, Ether, code=1) -bind_layers(SNAP, ARP, code=2054) -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(DLT_LINUX_SLL, CookedLinux) -conf.l2types.register_num2layer(DLT_LINUX_IRDA, CookedLinux) -conf.l2types.register(DLT_LOOP, Loopback) -conf.l2types.register_num2layer(DLT_NULL, Loopback) - -conf.l3types.register(ETH_P_ARP, ARP) - - -# Techniques - - -@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 True: - 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, # noqa: E501 - filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs) # noqa: E501 - 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()) # noqa: E501 - if ans is not None and 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.""" # noqa: E501 - - responses = srp1(Ether(dst=fake_bcast) / ARP(op="who-has", pdst=ip), type=ETH_P_ARP, iface_hint=ip, timeout=1, verbose=0, **kargs) # noqa: E501 - - 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) # noqa: E501 - ans = ARPingResult(ans.res, name="PROMISCPing") - - ans.display() - return ans, unans - - -class ARP_am(AnsweringMachine): - """Fake ARP Relay Daemon (farpd) - - example: - To respond to an ARP request for 192.168.100 replying on the - ingress interface; - farpd(IP_addr='192.168.1.100',ARP_addr='00:01:02:03:04:05') - To respond on a different interface add the interface parameter - farpd(IP_addr='192.168.1.100',ARP_addr='00:01:02:03:04:05',iface='eth0') - To respond on ANY arp request on an interface with mac address ARP_addr - farpd(ARP_addr='00:01:02:03:04:05',iface='eth1') - To respond on ANY arp request with my mac addr on the given interface - farpd(iface='eth1') - - Optional Args - inter= Interval in seconds between ARP replies being sent - - """ - - function_name = "farpd" - filter = "arp" - send_function = staticmethod(sendp) - - def parse_options(self, IP_addr=None, ARP_addr=None): - self.IP_addr = IP_addr - self.ARP_addr = ARP_addr - - def is_request(self, req): - return (req.haslayer(ARP) and - req.getlayer(ARP).op == 1 and - (self.IP_addr is None or self.IP_addr == req.getlayer(ARP).pdst)) # noqa: E501 - - def make_reply(self, req): - ether = req.getlayer(Ether) - arp = req.getlayer(ARP) - - if 'iface' in self.optsend: - iff = self.optsend.get('iface') - else: - iff, a, gw = conf.route.route(arp.psrc) - self.iff = iff - if self.ARP_addr is None: - try: - ARP_addr = get_if_hwaddr(iff) - except Exception: - ARP_addr = "00:00:00:00:00:00" - pass - else: - ARP_addr = self.ARP_addr - resp = Ether(dst=ether.src, - src=ARP_addr) / ARP(op="is-at", - hwsrc=ARP_addr, - psrc=arp.pdst, - hwdst=arp.hwsrc, - pdst=arp.psrc) - return resp - - def send_reply(self, reply): - if 'iface' in self.optsend: - self.send_function(reply, **self.optsend) - else: - self.send_function(reply, iface=self.iff, **self.optsend) - - def print_reply(self, req, reply): - print("%s ==> %s on %s" % (req.summary(), reply.summary(), self.iff)) - - -@conf.commands.register -def etherleak(target, **kargs): - """Exploit Etherleak flaw""" - return srp(Ether() / ARP(pdst=target), - prn=lambda s_r: conf.padding_layer in s_r[1] and hexstr(s_r[1][conf.padding_layer].load), # noqa: E501 - filter="arp", **kargs) - - -@conf.commands.register -def arpleak(target, plen=255, hwlen=255, **kargs): - """Exploit ARP leak flaws, like NetBSD-SA2017-002. - -https://ftp.netbsd.org/pub/NetBSD/security/advisories/NetBSD-SA2017-002.txt.asc - - """ - # We want explicit packets - pkts_iface = {} - for pkt in ARP(pdst=target): - # We have to do some of Scapy's work since we mess with - # important values - iface = conf.route.route(pkt.pdst)[0] - psrc = get_if_addr(iface) - hwsrc = get_if_hwaddr(iface) - pkt.plen = plen - pkt.hwlen = hwlen - if plen == 4: - pkt.psrc = psrc - else: - pkt.psrc = inet_aton(psrc)[:plen] - pkt.pdst = inet_aton(pkt.pdst)[:plen] - if hwlen == 6: - pkt.hwsrc = hwsrc - else: - pkt.hwsrc = mac2str(hwsrc)[:hwlen] - pkts_iface.setdefault(iface, []).append( - Ether(src=hwsrc, dst=ETHER_BROADCAST) / pkt - ) - ans, unans = SndRcvList(), PacketList(name="Unanswered") - for iface, pkts in viewitems(pkts_iface): - ans_new, unans_new = srp(pkts, iface=iface, filter="arp", **kargs) - ans += ans_new - unans += unans_new - ans.listname = "Results" - unans.listname = "Unanswered" - for _, rcv in ans: - if ARP not in rcv: - continue - rcv = rcv[ARP] - psrc = rcv.get_field('psrc').i2m(rcv, rcv.psrc) - if plen > 4 and len(psrc) > 4: - print("psrc") - hexdump(psrc[4:]) - print() - hwsrc = rcv.get_field('hwsrc').i2m(rcv, rcv.hwsrc) - if hwlen > 6 and len(hwsrc) > 6: - print("hwsrc") - hexdump(hwsrc[6:]) - print() - return ans, unans diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/l2tp.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/l2tp.py deleted file mode 100644 index dc79de393a..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/l2tp.py +++ /dev/null @@ -1,52 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -L2TP (Layer 2 Tunneling Protocol) for VPNs. - -[RFC 2661] -""" - -import struct - -from scapy.packet import Packet, bind_layers, bind_bottom_up -from scapy.fields import BitEnumField, ConditionalField, FlagsField, \ - PadField, ShortField -from scapy.layers.inet import UDP -from scapy.layers.ppp import PPP - - -class L2TP(Packet): - name = "L2TP" - fields_desc = [ - FlagsField("hdr", 0, 12, ['res00', 'res01', 'res02', 'res03', 'priority', 'offset', # noqa: E501 - 'res06', 'sequence', 'res08', 'res09', 'length', 'control']), # noqa: E501 - BitEnumField("version", 2, 4, {2: 'L2TPv2'}), - - ConditionalField(ShortField("len", 0), - lambda pkt: pkt.hdr & 'control+length'), - ShortField("tunnel_id", 0), - ShortField("session_id", 0), - ConditionalField(ShortField("ns", 0), - lambda pkt: pkt.hdr & 'sequence+control'), - ConditionalField(ShortField("nr", 0), - lambda pkt: pkt.hdr & 'sequence+control'), - ConditionalField( - PadField(ShortField("offset", 0), 4, b"\x00"), - lambda pkt: not (pkt.hdr & 'control') and pkt.hdr & 'offset' - ) - ] - - def post_build(self, pkt, pay): - if self.len is None: - tmp_len = len(pkt) + len(pay) - pkt = pkt[:2] + struct.pack("!H", tmp_len) + pkt[4:] - return pkt + pay - - -bind_bottom_up(UDP, L2TP, dport=1701) -bind_bottom_up(UDP, L2TP, sport=1701) -bind_layers(UDP, L2TP, dport=1701, sport=1701) -bind_layers(L2TP, PPP,) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/llmnr.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/llmnr.py deleted file mode 100644 index b606f3717e..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/llmnr.py +++ /dev/null @@ -1,77 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -LLMNR (Link Local Multicast Node Resolution). - -[RFC 4795] - -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 -""" - -import struct - -from scapy.fields import BitEnumField, BitField, ShortField -from scapy.packet import Packet, bind_layers, bind_bottom_up -from scapy.compat import orb -from scapy.layers.inet import UDP -from scapy.layers.dns import DNSQRField, DNSRRField, DNSRRCountField - - -_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) - - -class _LLMNR(Packet): - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if len(_pkt) >= 2: - if (orb(_pkt[2]) & 0x80): # Response - return LLMNRResponse - else: # Query - return LLMNRQuery - return cls - - -bind_bottom_up(UDP, _LLMNR, dport=5355) -bind_bottom_up(UDP, _LLMNR, sport=5355) -bind_layers(UDP, _LLMNR, sport=5355, dport=5355) - -# LLMNRQuery(id=RandShort(), qd=DNSQR(qname="vista."))) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/lltd.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/lltd.py deleted file mode 100644 index c9ce0c0adb..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/lltd.py +++ /dev/null @@ -1,845 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -"""LLTD Protocol - -https://msdn.microsoft.com/en-us/library/cc233983.aspx - -""" - -from __future__ import absolute_import -from array import array - -from scapy.fields import BitField, FlagsField, ByteField, ByteEnumField, \ - ShortField, ShortEnumField, ThreeBytesField, IntField, IntEnumField, \ - LongField, MultiEnumField, FieldLenField, FieldListField, \ - PacketListField, StrLenField, StrLenFieldUtf16, ConditionalField, MACField -from scapy.packet import Packet, Padding, bind_layers -from scapy.plist import PacketList -from scapy.layers.l2 import Ether -from scapy.layers.inet import IPField -from scapy.layers.inet6 import IP6Field -from scapy.data import ETHER_ANY -import scapy.modules.six as six -from scapy.compat import orb, chb - - -# Protocol layers -################## - - -class LLTD(Packet): - name = "LLTD" - answer_hashret = { - # (tos, function) tuple mapping (answer -> query), used by - # .hashret() - (1, 1): (0, 0), - (0, 12): (0, 11), - } - fields_desc = [ - ByteField("version", 1), - ByteEnumField("tos", 0, { - 0: "Topology discovery", - 1: "Quick discovery", - 2: "QoS diagnostics", - }), - ByteField("reserved", 0), - MultiEnumField("function", 0, { - 0: { - 0: "Discover", - 1: "Hello", - 2: "Emit", - 3: "Train", - 4: "Probe", - 5: "Ack", - 6: "Query", - 7: "QueryResp", - 8: "Reset", - 9: "Charge", - 10: "Flat", - 11: "QueryLargeTlv", - 12: "QueryLargeTlvResp", - }, - 1: { - 0: "Discover", - 1: "Hello", - 8: "Reset", - }, - 2: { - 0: "QosInitializeSink", - 1: "QosReady", - 2: "QosProbe", - 3: "QosQuery", - 4: "QosQueryResp", - 5: "QosReset", - 6: "QosError", - 7: "QosAck", - 8: "QosCounterSnapshot", - 9: "QosCounterResult", - 10: "QosCounterLease", - }, - }, depends_on=lambda pkt: pkt.tos, fmt="B"), - MACField("real_dst", None), - MACField("real_src", None), - ConditionalField(ShortField("xid", 0), - lambda pkt: pkt.function in [0, 8]), - ConditionalField(ShortField("seq", 0), - lambda pkt: pkt.function not in [0, 8]), - ] - - def post_build(self, pkt, pay): - if (self.real_dst is None or self.real_src is None) and \ - isinstance(self.underlayer, Ether): - eth = self.underlayer - if self.real_dst is None: - pkt = (pkt[:4] + eth.fields_desc[0].i2m(eth, eth.dst) + - pkt[10:]) - if self.real_src is None: - pkt = (pkt[:10] + eth.fields_desc[1].i2m(eth, eth.src) + - pkt[16:]) - return pkt + pay - - def mysummary(self): - if isinstance(self.underlayer, Ether): - return self.underlayer.sprintf( - 'LLTD %src% > %dst% %LLTD.tos% - %LLTD.function%' - ) - else: - return self.sprintf('LLTD %tos% - %function%') - - def hashret(self): - tos, function = self.tos, self.function - return "%c%c" % self.answer_hashret.get((tos, function), - (tos, function)) - - def answers(self, other): - if not isinstance(other, LLTD): - return False - if self.tos == 0: - if self.function == 0 and isinstance(self.payload, LLTDDiscover) \ - and len(self[LLTDDiscover].stations_list) == 1: - # "Topology discovery - Discover" with one MAC address - # discovered answers a "Quick discovery - Hello" - return other.tos == 1 and \ - other.function == 1 and \ - LLTDAttributeHostID in other and \ - other[LLTDAttributeHostID].mac == \ - self[LLTDDiscover].stations_list[0] - elif self.function == 12: - # "Topology discovery - QueryLargeTlvResp" answers - # "Topology discovery - QueryLargeTlv" with same .seq - # value - return other.tos == 0 and other.function == 11 \ - and other.seq == self.seq - elif self.tos == 1: - if self.function == 1 and isinstance(self.payload, LLTDHello): - # "Quick discovery - Hello" answers a "Topology - # discovery - Discover" - return other.tos == 0 and other.function == 0 and \ - other.real_src == self.current_mapper_address - return False - - -class LLTDHello(Packet): - name = "LLTD - Hello" - show_summary = False - fields_desc = [ - ShortField("gen_number", 0), - MACField("current_mapper_address", ETHER_ANY), - MACField("apparent_mapper_address", ETHER_ANY), - ] - - -class LLTDDiscover(Packet): - name = "LLTD - Discover" - fields_desc = [ - ShortField("gen_number", 0), - FieldLenField("stations_count", None, count_of="stations_list", - fmt="H"), - FieldListField("stations_list", [], MACField("", ETHER_ANY), - count_from=lambda pkt: pkt.stations_count) - ] - - def mysummary(self): - return (self.sprintf("Stations: %stations_list%") - if self.stations_list else "No station", [LLTD]) - - -class LLTDEmiteeDesc(Packet): - name = "LLTD - Emitee Desc" - fields_desc = [ - ByteEnumField("type", 0, {0: "Train", 1: "Probe"}), - ByteField("pause", 0), - MACField("src", None), - MACField("dst", ETHER_ANY), - ] - - -class LLTDEmit(Packet): - name = "LLTD - Emit" - fields_desc = [ - FieldLenField("descs_count", None, count_of="descs_list", - fmt="H"), - PacketListField("descs_list", [], LLTDEmiteeDesc, - count_from=lambda pkt: pkt.descs_count), - ] - - def mysummary(self): - return ", ".join(desc.sprintf("%src% > %dst%") - for desc in self.descs_list), [LLTD] - - -class LLTDRecveeDesc(Packet): - name = "LLTD - Recvee Desc" - fields_desc = [ - ShortEnumField("type", 0, {0: "Probe", 1: "ARP or ICMPv6"}), - MACField("real_src", ETHER_ANY), - MACField("ether_src", ETHER_ANY), - MACField("ether_dst", ETHER_ANY), - ] - - -class LLTDQueryResp(Packet): - name = "LLTD - Query Response" - fields_desc = [ - FlagsField("flags", 0, 2, "ME"), - BitField("descs_count", None, 14), - PacketListField("descs_list", [], LLTDRecveeDesc, - count_from=lambda pkt: pkt.descs_count), - ] - - def post_build(self, pkt, pay): - if self.descs_count is None: - # descs_count should be a FieldLenField but has an - # unsupported format (14 bits) - flags = orb(pkt[0]) & 0xc0 - count = len(self.descs_list) - pkt = chb(flags + (count >> 8)) + chb(count % 256) + pkt[2:] - return pkt + pay - - def mysummary(self): - return self.sprintf("%d response%s" % ( - self.descs_count, - "s" if self.descs_count > 1 else "")), [LLTD] - - -class LLTDQueryLargeTlv(Packet): - name = "LLTD - Query Large Tlv" - fields_desc = [ - ByteEnumField("type", 14, { - 14: "Icon image", - 17: "Friendly Name", - 19: "Hardware ID", - 22: "AP Association Table", - 24: "Detailed Icon Image", - 26: "Component Table", - 28: "Repeater AP Table", - }), - ThreeBytesField("offset", 0), - ] - - def mysummary(self): - return self.sprintf("%type% (offset %offset%)"), [LLTD] - - -class LLTDQueryLargeTlvResp(Packet): - name = "LLTD - Query Large Tlv Response" - fields_desc = [ - FlagsField("flags", 0, 2, "RM"), - BitField("len", None, 14), - StrLenField("value", "", length_from=lambda pkt: pkt.len) - ] - - def post_build(self, pkt, pay): - if self.len is None: - # len should be a FieldLenField but has an unsupported - # format (14 bits) - flags = orb(pkt[0]) & 0xc0 - length = len(self.value) - pkt = chb(flags + (length >> 8)) + chb(length % 256) + pkt[2:] - return pkt + pay - - def mysummary(self): - return self.sprintf("%%len%% bytes%s" % ( - " (last)" if not self.flags & 2 else "" - )), [LLTD] - - -class LLTDAttribute(Packet): - name = "LLTD Attribute" - show_indent = False - show_summary = False - # section 2.2.1.1 - fields_desc = [ - ByteEnumField("type", 0, { - 0: "End Of Property", - 1: "Host ID", - 2: "Characteristics", - 3: "Physical Medium", - 7: "IPv4 Address", - 9: "802.11 Max Rate", - 10: "Performance Counter Frequency", - 12: "Link Speed", - 14: "Icon Image", - 15: "Machine Name", - 18: "Device UUID", - 20: "QoS Characteristics", - 21: "802.11 Physical Medium", - 24: "Detailed Icon Image", - }), - FieldLenField("len", None, length_of="value", fmt="B"), - StrLenField("value", "", length_from=lambda pkt: pkt.len), - ] - - @classmethod - def dispatch_hook(cls, _pkt=None, *_, **kargs): - if _pkt: - cmd = orb(_pkt[0]) - elif "type" in kargs: - cmd = kargs["type"] - if isinstance(cmd, six.string_types): - cmd = cls.fields_desc[0].s2i[cmd] - else: - return cls - return SPECIFIC_CLASSES.get(cmd, cls) - - -SPECIFIC_CLASSES = {} - - -def _register_lltd_specific_class(*attr_types): - """This can be used as a class decorator; if we want to support Python - 2.5, we have to replace - -@_register_lltd_specific_class(x[, y[, ...]]) -class LLTDAttributeSpecific(LLTDAttribute): -[...] - -by - -class LLTDAttributeSpecific(LLTDAttribute): -[...] -LLTDAttributeSpecific = _register_lltd_specific_class(x[, y[, ...]])( - LLTDAttributeSpecific -) - - """ - def _register(cls): - for attr_type in attr_types: - SPECIFIC_CLASSES[attr_type] = cls - type_fld = LLTDAttribute.fields_desc[0].copy() - type_fld.default = attr_types[0] - cls.fields_desc = [type_fld] + cls.fields_desc - return cls - return _register - - -@_register_lltd_specific_class(0) -class LLTDAttributeEOP(LLTDAttribute): - name = "LLTD Attribute - End Of Property" - fields_desc = [] - - -@_register_lltd_specific_class(1) -class LLTDAttributeHostID(LLTDAttribute): - name = "LLTD Attribute - Host ID" - fields_desc = [ - ByteField("len", 6), - MACField("mac", ETHER_ANY), - ] - - def mysummary(self): - return "ID: %s" % self.mac, [LLTD, LLTDAttributeMachineName] - - -@_register_lltd_specific_class(2) -class LLTDAttributeCharacteristics(LLTDAttribute): - name = "LLTD Attribute - Characteristics" - fields_desc = [ - # According to MS doc, "this field MUST be set to 0x02". But - # according to MS implementation, that's wrong. - # ByteField("len", 2), - FieldLenField("len", None, length_of="reserved2", fmt="B", - adjust=lambda _, x: x + 2), - FlagsField("flags", 0, 5, "PXFML"), - BitField("reserved1", 0, 11), - StrLenField("reserved2", "", length_from=lambda x: x.len - 2) - ] - - -@_register_lltd_specific_class(3) -class LLTDAttributePhysicalMedium(LLTDAttribute): - name = "LLTD Attribute - Physical Medium" - fields_desc = [ - ByteField("len", 4), - IntEnumField("medium", 6, { - # https://www.iana.org/assignments/ianaiftype-mib/ianaiftype-mib - 1: "other", - 2: "regular1822", - 3: "hdh1822", - 4: "ddnX25", - 5: "rfc877x25", - 6: "ethernetCsmacd", - 7: "iso88023Csmacd", - 8: "iso88024TokenBus", - 9: "iso88025TokenRing", - 10: "iso88026Man", - 11: "starLan", - 12: "proteon10Mbit", - 13: "proteon80Mbit", - 14: "hyperchannel", - 15: "fddi", - 16: "lapb", - 17: "sdlc", - 18: "ds1", - 19: "e1", - 20: "basicISDN", - 21: "primaryISDN", - 22: "propPointToPointSerial", - 23: "ppp", - 24: "softwareLoopback", - 25: "eon", - 26: "ethernet3Mbit", - 27: "nsip", - 28: "slip", - 29: "ultra", - 30: "ds3", - 31: "sip", - 32: "frameRelay", - 33: "rs232", - 34: "para", - 35: "arcnet", - 36: "arcnetPlus", - 37: "atm", - 38: "miox25", - 39: "sonet", - 40: "x25ple", - 41: "iso88022llc", - 42: "localTalk", - 43: "smdsDxi", - 44: "frameRelayService", - 45: "v35", - 46: "hssi", - 47: "hippi", - 48: "modem", - 49: "aal5", - 50: "sonetPath", - 51: "sonetVT", - 52: "smdsIcip", - 53: "propVirtual", - 54: "propMultiplexor", - 55: "ieee80212", - 56: "fibreChannel", - 57: "hippiInterface", - 58: "frameRelayInterconnect", - 59: "aflane8023", - 60: "aflane8025", - 61: "cctEmul", - 62: "fastEther", - 63: "isdn", - 64: "v11", - 65: "v36", - 66: "g703at64k", - 67: "g703at2mb", - 68: "qllc", - 69: "fastEtherFX", - 70: "channel", - 71: "ieee80211", - 72: "ibm370parChan", - 73: "escon", - 74: "dlsw", - 75: "isdns", - 76: "isdnu", - 77: "lapd", - 78: "ipSwitch", - 79: "rsrb", - 80: "atmLogical", - 81: "ds0", - 82: "ds0Bundle", - 83: "bsc", - 84: "async", - 85: "cnr", - 86: "iso88025Dtr", - 87: "eplrs", - 88: "arap", - 89: "propCnls", - 90: "hostPad", - 91: "termPad", - 92: "frameRelayMPI", - 93: "x213", - 94: "adsl", - 95: "radsl", - 96: "sdsl", - 97: "vdsl", - 98: "iso88025CRFPInt", - 99: "myrinet", - 100: "voiceEM", - 101: "voiceFXO", - 102: "voiceFXS", - 103: "voiceEncap", - 104: "voiceOverIp", - 105: "atmDxi", - 106: "atmFuni", - 107: "atmIma", - 108: "pppMultilinkBundle", - 109: "ipOverCdlc", - 110: "ipOverClaw", - 111: "stackToStack", - 112: "virtualIpAddress", - 113: "mpc", - 114: "ipOverAtm", - 115: "iso88025Fiber", - 116: "tdlc", - 117: "gigabitEthernet", - 118: "hdlc", - 119: "lapf", - 120: "v37", - 121: "x25mlp", - 122: "x25huntGroup", - 123: "transpHdlc", - 124: "interleave", - 125: "fast", - 126: "ip", - 127: "docsCableMaclayer", - 128: "docsCableDownstream", - 129: "docsCableUpstream", - 130: "a12MppSwitch", - 131: "tunnel", - 132: "coffee", - 133: "ces", - 134: "atmSubInterface", - 135: "l2vlan", - 136: "l3ipvlan", - 137: "l3ipxvlan", - 138: "digitalPowerline", - 139: "mediaMailOverIp", - 140: "dtm", - 141: "dcn", - 142: "ipForward", - 143: "msdsl", - 144: "ieee1394", - 145: "if-gsn", - 146: "dvbRccMacLayer", - 147: "dvbRccDownstream", - 148: "dvbRccUpstream", - 149: "atmVirtual", - 150: "mplsTunnel", - 151: "srp", - 152: "voiceOverAtm", - 153: "voiceOverFrameRelay", - 154: "idsl", - 155: "compositeLink", - 156: "ss7SigLink", - 157: "propWirelessP2P", - 158: "frForward", - 159: "rfc1483", - 160: "usb", - 161: "ieee8023adLag", - 162: "bgppolicyaccounting", - 163: "frf16MfrBundle", - 164: "h323Gatekeeper", - 165: "h323Proxy", - 166: "mpls", - 167: "mfSigLink", - 168: "hdsl2", - 169: "shdsl", - 170: "ds1FDL", - 171: "pos", - 172: "dvbAsiIn", - 173: "dvbAsiOut", - 174: "plc", - 175: "nfas", - 176: "tr008", - 177: "gr303RDT", - 178: "gr303IDT", - 179: "isup", - 180: "propDocsWirelessMaclayer", - 181: "propDocsWirelessDownstream", - 182: "propDocsWirelessUpstream", - 183: "hiperlan2", - 184: "propBWAp2Mp", - 185: "sonetOverheadChannel", - 186: "digitalWrapperOverheadChannel", - 187: "aal2", - 188: "radioMAC", - 189: "atmRadio", - 190: "imt", - 191: "mvl", - 192: "reachDSL", - 193: "frDlciEndPt", - 194: "atmVciEndPt", - 195: "opticalChannel", - 196: "opticalTransport", - 197: "propAtm", - 198: "voiceOverCable", - 199: "infiniband", - 200: "teLink", - 201: "q2931", - 202: "virtualTg", - 203: "sipTg", - 204: "sipSig", - 205: "docsCableUpstreamChannel", - 206: "econet", - 207: "pon155", - 208: "pon622", - 209: "bridge", - 210: "linegroup", - 211: "voiceEMFGD", - 212: "voiceFGDEANA", - 213: "voiceDID", - 214: "mpegTransport", - 215: "sixToFour", - 216: "gtp", - 217: "pdnEtherLoop1", - 218: "pdnEtherLoop2", - 219: "opticalChannelGroup", - 220: "homepna", - 221: "gfp", - 222: "ciscoISLvlan", - 223: "actelisMetaLOOP", - 224: "fcipLink", - 225: "rpr", - 226: "qam", - 227: "lmp", - 228: "cblVectaStar", - 229: "docsCableMCmtsDownstream", - 230: "adsl2", - 231: "macSecControlledIF", - 232: "macSecUncontrolledIF", - 233: "aviciOpticalEther", - 234: "atmbond", - 235: "voiceFGDOS", - 236: "mocaVersion1", - 237: "ieee80216WMAN", - 238: "adsl2plus", - 239: "dvbRcsMacLayer", - 240: "dvbTdm", - 241: "dvbRcsTdma", - 242: "x86Laps", - 243: "wwanPP", - 244: "wwanPP2", - 245: "voiceEBS", - 246: "ifPwType", - 247: "ilan", - 248: "pip", - 249: "aluELP", - 250: "gpon", - 251: "vdsl2", - 252: "capwapDot11Profile", - 253: "capwapDot11Bss", - 254: "capwapWtpVirtualRadio", - 255: "bits", - 256: "docsCableUpstreamRfPort", - 257: "cableDownstreamRfPort", - 258: "vmwareVirtualNic", - 259: "ieee802154", - 260: "otnOdu", - 261: "otnOtu", - 262: "ifVfiType", - 263: "g9981", - 264: "g9982", - 265: "g9983", - 266: "aluEpon", - 267: "aluEponOnu", - 268: "aluEponPhysicalUni", - 269: "aluEponLogicalLink", - 271: "aluGponPhysicalUni", - 272: "vmwareNicTeam", - 277: "docsOfdmDownstream", - 278: "docsOfdmaUpstream", - 279: "gfast", - 280: "sdci", - }), - ] - - -@_register_lltd_specific_class(7) -class LLTDAttributeIPv4Address(LLTDAttribute): - name = "LLTD Attribute - IPv4 Address" - fields_desc = [ - ByteField("len", 4), - IPField("ipv4", "0.0.0.0"), - ] - - -@_register_lltd_specific_class(8) -class LLTDAttributeIPv6Address(LLTDAttribute): - name = "LLTD Attribute - IPv6 Address" - fields_desc = [ - ByteField("len", 16), - IP6Field("ipv6", "::"), - ] - - -@_register_lltd_specific_class(9) -class LLTDAttribute80211MaxRate(LLTDAttribute): - name = "LLTD Attribute - 802.11 Max Rate" - fields_desc = [ - ByteField("len", 2), - ShortField("rate", 0), - ] - - -@_register_lltd_specific_class(10) -class LLTDAttributePerformanceCounterFrequency(LLTDAttribute): - name = "LLTD Attribute - Performance Counter Frequency" - fields_desc = [ - ByteField("len", 8), - LongField("freq", 0), - ] - - -@_register_lltd_specific_class(12) -class LLTDAttributeLinkSpeed(LLTDAttribute): - name = "LLTD Attribute - Link Speed" - fields_desc = [ - ByteField("len", 4), - IntField("speed", 0), - ] - - -@_register_lltd_specific_class(14, 24, 26) -class LLTDAttributeLargeTLV(LLTDAttribute): - name = "LLTD Attribute - Large TLV" - fields_desc = [ - ByteField("len", 0), - ] - - -@_register_lltd_specific_class(15) -class LLTDAttributeMachineName(LLTDAttribute): - name = "LLTD Attribute - Machine Name" - fields_desc = [ - FieldLenField("len", None, length_of="hostname", fmt="B"), - StrLenFieldUtf16("hostname", "", length_from=lambda pkt: pkt.len), - ] - - def mysummary(self): - return (self.sprintf("Hostname: %r" % self.hostname), - [LLTD, LLTDAttributeHostID]) - - -@_register_lltd_specific_class(18) -class LLTDAttributeDeviceUUID(LLTDAttribute): - name = "LLTD Attribute - Device UUID" - fields_desc = [ - FieldLenField("len", None, length_of="uuid", fmt="B"), - StrLenField("uuid", b"\x00" * 16, length_from=lambda pkt: pkt.len), - ] - - -@_register_lltd_specific_class(20) -class LLTDAttributeQOSCharacteristics(LLTDAttribute): - name = "LLTD Attribute - QoS Characteristics" - fields_desc = [ - ByteField("len", 4), - FlagsField("flags", 0, 3, "EQP"), - BitField("reserved1", 0, 13), - ShortField("reserved2", 0), - ] - - -@_register_lltd_specific_class(21) -class LLTDAttribute80211PhysicalMedium(LLTDAttribute): - name = "LLTD Attribute - 802.11 Physical Medium" - fields_desc = [ - ByteField("len", 1), - ByteEnumField("medium", 0, { - 0: "Unknown", - 1: "FHSS 2.4 GHz", - 2: "DSSS 2.4 GHz", - 3: "IR Baseband", - 4: "OFDM 5 GHz", - 5: "HRDSSS", - 6: "ERP", - }), - ] - - -@_register_lltd_specific_class(25) -class LLTDAttributeSeesList(LLTDAttribute): - name = "LLTD Attribute - Sees List Working Set" - fields_desc = [ - ByteField("len", 2), - ShortField("max_entries", 0), - ] - - -bind_layers(Ether, LLTD, type=0x88d9) -bind_layers(LLTD, LLTDDiscover, tos=0, function=0) -bind_layers(LLTD, LLTDDiscover, tos=1, function=0) -bind_layers(LLTD, LLTDHello, tos=0, function=1) -bind_layers(LLTD, LLTDHello, tos=1, function=1) -bind_layers(LLTD, LLTDEmit, tos=0, function=2) -bind_layers(LLTD, LLTDQueryResp, tos=0, function=7) -bind_layers(LLTD, LLTDQueryLargeTlv, tos=0, function=11) -bind_layers(LLTD, LLTDQueryLargeTlvResp, tos=0, function=12) -bind_layers(LLTDHello, LLTDAttribute) -bind_layers(LLTDAttribute, LLTDAttribute) -bind_layers(LLTDAttribute, Padding, type=0) -bind_layers(LLTDEmiteeDesc, Padding) -bind_layers(LLTDRecveeDesc, Padding) - - -# Utils -######## - -class LargeTlvBuilder(object): - """An object to build content fetched through LLTDQueryLargeTlv / - LLTDQueryLargeTlvResp packets. - - Usable with a PacketList() object: - >>> p = LargeTlvBuilder() - >>> p.parse(rdpcap('capture_file.cap')) - - Or during a network capture: - >>> p = LargeTlvBuilder() - >>> sniff(filter="ether proto 0x88d9", prn=p.parse) - - To get the result, use .get_data() - - """ - - def __init__(self): - self.types_offsets = {} - self.data = {} - - def parse(self, plist): - """Update the builder using the provided `plist`. `plist` can - be either a Packet() or a PacketList(). - - """ - if not isinstance(plist, PacketList): - plist = PacketList(plist) - for pkt in plist[LLTD]: - if LLTDQueryLargeTlv in pkt: - key = "%s:%s:%d" % (pkt.real_dst, pkt.real_src, pkt.seq) - self.types_offsets[key] = (pkt[LLTDQueryLargeTlv].type, - pkt[LLTDQueryLargeTlv].offset) - elif LLTDQueryLargeTlvResp in pkt: - try: - key = "%s:%s:%d" % (pkt.real_src, pkt.real_dst, pkt.seq) - content, offset = self.types_offsets[key] - except KeyError: - continue - loc = slice(offset, offset + pkt[LLTDQueryLargeTlvResp].len) - key = "%s > %s [%s]" % ( - pkt.real_src, pkt.real_dst, - LLTDQueryLargeTlv.fields_desc[0].i2s.get(content, content), - ) - data = self.data.setdefault(key, array("B")) - datalen = len(data) - if datalen < loc.stop: - data.extend(array("B", b"\x00" * (loc.stop - datalen))) - data[loc] = array("B", pkt[LLTDQueryLargeTlvResp].value) - - def get_data(self): - """Returns a dictionary object, keys are strings "source > - destincation [content type]", and values are the content - fetched, also as a string. - - """ - return {key: "".join(chr(byte) for byte in data) - for key, data in six.iteritems(self.data)} diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/mgcp.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/mgcp.py deleted file mode 100644 index 34d020275a..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/mgcp.py +++ /dev/null @@ -1,47 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -MGCP (Media Gateway Control Protocol) - -[RFC 2805] -""" - -from scapy.packet import Packet, bind_layers, bind_bottom_up -from scapy.fields import StrFixedLenField, StrStopField -from scapy.layers.inet import UDP - - -class MGCP(Packet): - name = "MGCP" - longname = "Media Gateway Control Protocol" - fields_desc = [StrStopField("verb", "AUEP", b" ", -1), - StrFixedLenField("sep1", " ", 1), - StrStopField("transaction_id", "1234567", b" ", -1), - StrFixedLenField("sep2", " ", 1), - StrStopField("endpoint", "dummy@dummy.net", b" ", -1), - StrFixedLenField("sep3", " ", 1), - StrStopField("version", "MGCP 1.0 NCS 1.0", b"\x0a", -1), - StrFixedLenField("sep4", b"\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_bottom_up(UDP, MGCP, dport=2727) -bind_bottom_up(UDP, MGCP, sport=2727) -bind_layers(UDP, MGCP, sport=2727, dport=2727) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/mobileip.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/mobileip.py deleted file mode 100644 index 67c2ce2059..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/mobileip.py +++ /dev/null @@ -1,52 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Mobile IP. -""" - -from scapy.fields import ByteEnumField, ByteField, IPField, LongField, \ - ShortField, XByteField -from scapy.packet import Packet, bind_layers, bind_bottom_up -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_bottom_up(UDP, MobileIP, dport=434) -bind_bottom_up(UDP, MobileIP, sport=434) -bind_layers(UDP, MobileIP, sport=434, 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-2.4.3/scapy/layers/netbios.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/netbios.py deleted file mode 100644 index 2c5d54dc37..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/netbios.py +++ /dev/null @@ -1,292 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -NetBIOS over TCP/IP - -[RFC 1001/1002] -""" - -import struct - -from scapy.packet import Packet, bind_layers -from scapy.fields import BitEnumField, BitField, ByteEnumField, ByteField, \ - IPField, IntField, NetBIOSNameField, ShortEnumField, ShortField, \ - StrFixedLenField, XShortField -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: - tmp_len = len(p) - 14 - p = p[:10] + struct.pack("!H", tmp_len) + p[12:] - return p - -# ShortField("length",0), -# ShortField("Delimiter",0), -# ByteField("command",0), -# ByteField("data1",0), -# ShortField("data2",0), -# ShortField("XMIt",0), -# ShortField("RSPCor",0), -# StrFixedLenField("dest","",16), -# StrFixedLenField("source","",16), -# -# ] -# - -# NetBIOS - - -_NETBIOS_SUFFIXES = { - 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" -} - -_NETBIOS_QRTYPES = { - 0x20: "NB", - 0x21: "NBSTAT" -} - -_NETBIOS_QRCLASS = { - 1: "INTERNET" -} - -_NETBIOS_RNAMES = { - 0xC00C: "Label String Pointer to QUESTION_NAME" -} - -_NETBIOS_OWNER_MODE_TYPES = { - 0: "B node", - 1: "P node", - 2: "M node", - 3: "H node" -} - -_NETBIOS_GNAMES = { - 0: "Unique name", - 1: "Group name" -} - -# 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, _NETBIOS_SUFFIXES), - ByteField("NULL", 0), - ShortEnumField("QUESTION_TYPE", 0x20, _NETBIOS_QRTYPES), - ShortEnumField("QUESTION_CLASS", 1, _NETBIOS_QRCLASS)] - -# 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, _NETBIOS_SUFFIXES), - ByteField("NULL", 0), - ShortEnumField("QUESTION_TYPE", 0x20, _NETBIOS_QRTYPES), - ShortEnumField("QUESTION_CLASS", 1, _NETBIOS_QRCLASS), - ShortEnumField("RR_NAME", 0xC00C, _NETBIOS_RNAMES), - ShortEnumField("RR_TYPE", 0x20, _NETBIOS_QRTYPES), - ShortEnumField("RR_CLASS", 1, _NETBIOS_QRCLASS), - IntField("TTL", 0), - ShortField("RDLENGTH", 6), - BitEnumField("G", 0, 1, _NETBIOS_GNAMES), - BitEnumField("OWNER_NODE_TYPE", 00, 2, - _NETBIOS_OWNER_MODE_TYPES), - 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, _NETBIOS_SUFFIXES), - ByteField("NULL", 0), - ShortEnumField("QUESTION_TYPE", 0x20, _NETBIOS_QRTYPES), - ShortEnumField("QUESTION_CLASS", 1, _NETBIOS_QRCLASS), - 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, _NETBIOS_SUFFIXES), - ByteField("NULL", 0), - ShortEnumField("RR_TYPE", 0x20, _NETBIOS_QRTYPES), - ShortEnumField("RR_CLASS", 1, _NETBIOS_QRCLASS), - IntField("TTL", 0), - ShortField("RDLENGTH", 6), - BitEnumField("G", 0, 1, _NETBIOS_GNAMES), - BitEnumField("OWNER_NODE_TYPE", 00, 2, - _NETBIOS_OWNER_MODE_TYPES), - 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, _NETBIOS_SUFFIXES), - ByteField("NULL", 0), - ShortEnumField("RR_TYPE", 0x21, _NETBIOS_QRTYPES), - ShortEnumField("RR_CLASS", 1, _NETBIOS_QRCLASS), - 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, _NETBIOS_SUFFIXES), - ByteField("NULL", 0), - ShortEnumField("RR_TYPE", 0x20, _NETBIOS_QRTYPES), - ShortEnumField("RR_CLASS", 1, _NETBIOS_QRCLASS), - 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", "windows"), - ShortEnumField("SUFFIX1", 0x4141, _NETBIOS_SUFFIXES), - ByteField("NULL", 0), - NetBIOSNameField("DestinationName", "windows"), - ShortEnumField("SUFFIX2", 0x4141, _NETBIOS_SUFFIXES), - 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-2.4.3/scapy/layers/netflow.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/netflow.py deleted file mode 100755 index af4df1fbab..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/netflow.py +++ /dev/null @@ -1,1628 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license -# Netflow V5 appended by spaceB0x and Guillaume Valadon -# Netflow V9/10 appended ny Gabriel Potter - -""" -Cisco NetFlow protocol v1, v5, v9 and v10 (IPFix) - -HowTo dissect NetflowV9/10 (IPFix) packets: - -# From a pcap / list of packets - -Using sniff and sessions: ->>> sniff(offline=open("my_great_pcap.pcap", "rb"), session=NetflowSession) - -Using the netflowv9_defragment/ipfix_defragment commands: -- get a list of packets containing NetflowV9/10 packets -- call `netflowv9_defragment(plist)` to defragment the list - -(ipfix_defragment is an alias for netflowv9_defragment) - -# Live / on-the-flow / other: use NetflowSession ->>> sniff(session=NetflowSession, prn=[...]) -""" - -import struct - -from scapy.config import conf -from scapy.data import IP_PROTOS -from scapy.error import warning -# TRex Change - Add BitField, ConditionalField -from scapy.fields import ByteEnumField, ByteField, Field, FieldLenField, \ - FlagsField, IPField, IntField, MACField, \ - PacketListField, PadField, SecondsIntField, ShortEnumField, ShortField, \ - StrField, StrFixedLenField, ThreeBytesField, UTCTimeField, XByteField, \ - XShortField, LongField, BitField, ConditionalField -# TRex Change - Add Raw -from scapy.packet import Packet, bind_layers, bind_bottom_up, Raw -from scapy.plist import PacketList -from scapy.sessions import IPSession, DefaultSession - -from scapy.layers.inet import UDP -from scapy.layers.inet6 import IP6Field - - -class NetflowHeader(Packet): - name = "Netflow Header" - fields_desc = [ShortField("version", 1)] - - -for port in [2055, 2056, 9995, 9996, 6343]: # Classic NetFlow ports - bind_bottom_up(UDP, NetflowHeader, dport=port) - bind_bottom_up(UDP, NetflowHeader, sport=port) -# However, we'll default to 2055, classic among classics :) -bind_layers(UDP, NetflowHeader, dport=2055, sport=2055) - -########################################### -# Netflow Version 1 -########################################### - - -class NetflowHeaderV1(Packet): - name = "Netflow Header v1" - fields_desc = [ShortField("count", 0), - IntField("sysUptime", 0), - UTCTimeField("unixSecs", 0), - UTCTimeField("unixNanoSeconds", 0, use_nano=True)] - - -class NetflowRecordV1(Packet): - name = "Netflow Record v1" - 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) -bind_layers(NetflowRecordV1, NetflowRecordV1) - - -######################################### -# Netflow Version 5 -######################################### - - -class NetflowHeaderV5(Packet): - name = "Netflow Header v5" - fields_desc = [ShortField("count", 0), - IntField("sysUptime", 0), - UTCTimeField("unixSecs", 0), - UTCTimeField("unixNanoSeconds", 0, use_nano=True), - IntField("flowSequence", 0), - ByteField("engineType", 0), - ByteField("engineID", 0), - ShortField("samplingInterval", 0)] - - -class NetflowRecordV5(Packet): - name = "Netflow Record v5" - fields_desc = [IPField("src", "127.0.0.1"), - IPField("dst", "127.0.0.1"), - IPField("nexthop", "0.0.0.0"), - ShortField("input", 0), - ShortField("output", 0), - IntField("dpkts", 1), - IntField("dOctets", 60), - IntField("first", 0), - IntField("last", 0), - ShortField("srcport", 0), - ShortField("dstport", 0), - ByteField("pad1", 0), - FlagsField("tcpFlags", 0x2, 8, "FSRPAUEC"), - ByteEnumField("prot", IP_PROTOS["tcp"], IP_PROTOS), - ByteField("tos", 0), - ShortField("src_as", 0), - ShortField("dst_as", 0), - ByteField("src_mask", 0), - ByteField("dst_mask", 0), - ShortField("pad2", 0)] - - -bind_layers(NetflowHeader, NetflowHeaderV5, version=5) -bind_layers(NetflowHeaderV5, NetflowRecordV5) -bind_layers(NetflowRecordV5, NetflowRecordV5) - -######################################### -# Netflow Version 9/10 -######################################### - -# NetflowV9 RFC -# https://www.ietf.org/rfc/rfc3954.txt - -# IPFix RFC -# https://tools.ietf.org/html/rfc5101 -# https://tools.ietf.org/html/rfc5655 - -# This is v9_v10_template_types (with names from the rfc for the first 79) -# https://github.com/wireshark/wireshark/blob/master/epan/dissectors/packet-netflow.c # noqa: E501 -# (it has all values external to the RFC) -NTOP_BASE = 57472 -NetflowV910TemplateFieldTypes = { - 1: "IN_BYTES", - 2: "IN_PKTS", - 3: "FLOWS", - 4: "PROTOCOL", - 5: "TOS", - 6: "TCP_FLAGS", - 7: "L4_SRC_PORT", - 8: "IPV4_SRC_ADDR", - 9: "SRC_MASK", - 10: "INPUT_SNMP", - 11: "L4_DST_PORT", - 12: "IPV4_DST_ADDR", - 13: "DST_MASK", - 14: "OUTPUT_SNMP", - 15: "IPV4_NEXT_HOP", - 16: "SRC_AS", - 17: "DST_AS", - 18: "BGP_IPV4_NEXT_HOP", - 19: "MUL_DST_PKTS", - 20: "MUL_DST_BYTES", - 21: "LAST_SWITCHED", - 22: "FIRST_SWITCHED", - 23: "OUT_BYTES", - 24: "OUT_PKTS", - 25: "IP_LENGTH_MINIMUM", - 26: "IP_LENGTH_MAXIMUM", - 27: "IPV6_SRC_ADDR", - 28: "IPV6_DST_ADDR", - 29: "IPV6_SRC_MASK", - 30: "IPV6_DST_MASK", - 31: "IPV6_FLOW_LABEL", - 32: "ICMP_TYPE", - 33: "MUL_IGMP_TYPE", - 34: "SAMPLING_INTERVAL", - 35: "SAMPLING_ALGORITHM", - 36: "FLOW_ACTIVE_TIMEOUT", - 37: "FLOW_INACTIVE_TIMEOUT", - 38: "ENGINE_TYPE", - 39: "ENGINE_ID", - 40: "TOTAL_BYTES_EXP", - 41: "TOTAL_PKTS_EXP", - 42: "TOTAL_FLOWS_EXP", - 43: "IPV4_ROUTER_SC", - 44: "IP_SRC_PREFIX", - 45: "IP_DST_PREFIX", - 46: "MPLS_TOP_LABEL_TYPE", - 47: "MPLS_TOP_LABEL_IP_ADDR", - 48: "FLOW_SAMPLER_ID", - 49: "FLOW_SAMPLER_MODE", - 50: "FLOW_SAMPLER_RANDOM_INTERVAL", - 51: "FLOW_CLASS", - 52: "IP TTL MINIMUM", - 53: "IP TTL MAXIMUM", - 54: "IPv4 ID", - 55: "DST_TOS", - 56: "SRC_MAC", - 57: "DST_MAC", - 58: "SRC_VLAN", - 59: "DST_VLAN", - 60: "IP_PROTOCOL_VERSION", - 61: "DIRECTION", - 62: "IPV6_NEXT_HOP", - 63: "BGP_IPV6_NEXT_HOP", - 64: "IPV6_OPTION_HEADERS", - 70: "MPLS_LABEL_1", - 71: "MPLS_LABEL_2", - 72: "MPLS_LABEL_3", - 73: "MPLS_LABEL_4", - 74: "MPLS_LABEL_5", - 75: "MPLS_LABEL_6", - 76: "MPLS_LABEL_7", - 77: "MPLS_LABEL_8", - 78: "MPLS_LABEL_9", - 79: "MPLS_LABEL_10", - 80: "DESTINATION_MAC", - 81: "SOURCE_MAC", - 82: "IF_NAME", - 83: "IF_DESC", - 84: "SAMPLER_NAME", - 85: "BYTES_TOTAL", - 86: "PACKETS_TOTAL", - 88: "FRAGMENT_OFFSET", - 89: "FORWARDING_STATUS", - 90: "VPN_ROUTE_DISTINGUISHER", - 91: "mplsTopLabelPrefixLength", - 92: "SRC_TRAFFIC_INDEX", - 93: "DST_TRAFFIC_INDEX", - 94: "APPLICATION_DESC", - 95: "APPLICATION_ID", - 96: "APPLICATION_NAME", - 98: "postIpDiffServCodePoint", - 99: "multicastReplicationFactor", - 101: "classificationEngineId", - 128: "DST_AS_PEER", - 129: "SRC_AS_PEER", - 130: "exporterIPv4Address", - 131: "exporterIPv6Address", - 132: "DROPPED_BYTES", - 133: "DROPPED_PACKETS", - 134: "DROPPED_BYTES_TOTAL", - 135: "DROPPED_PACKETS_TOTAL", - 136: "flowEndReason", - 137: "commonPropertiesId", - 138: "observationPointId", - 139: "icmpTypeCodeIPv6", - 140: "MPLS_TOP_LABEL_IPv6_ADDRESS", - 141: "lineCardId", - 142: "portId", - 143: "meteringProcessId", - 144: "FLOW_EXPORTER", - 145: "templateId", - 146: "wlanChannelId", - 147: "wlanSSID", - 148: "flowId", - 149: "observationDomainId", - 150: "flowStartSeconds", - 151: "flowEndSeconds", - 152: "flowStartMilliseconds", - 153: "flowEndMilliseconds", - 154: "flowStartMicroseconds", - 155: "flowEndMicroseconds", - 156: "flowStartNanoseconds", - 157: "flowEndNanoseconds", - 158: "flowStartDeltaMicroseconds", - 159: "flowEndDeltaMicroseconds", - 160: "systemInitTimeMilliseconds", - 161: "flowDurationMilliseconds", - 162: "flowDurationMicroseconds", - 163: "observedFlowTotalCount", - 164: "ignoredPacketTotalCount", - 165: "ignoredOctetTotalCount", - 166: "notSentFlowTotalCount", - 167: "notSentPacketTotalCount", - 168: "notSentOctetTotalCount", - 169: "destinationIPv6Prefix", - 170: "sourceIPv6Prefix", - 171: "postOctetTotalCount", - 172: "postPacketTotalCount", - 173: "flowKeyIndicator", - 174: "postMCastPacketTotalCount", - 175: "postMCastOctetTotalCount", - 176: "ICMP_IPv4_TYPE", - 177: "ICMP_IPv4_CODE", - 178: "ICMP_IPv6_TYPE", - 179: "ICMP_IPv6_CODE", - 180: "UDP_SRC_PORT", - 181: "UDP_DST_PORT", - 182: "TCP_SRC_PORT", - 183: "TCP_DST_PORT", - 184: "TCP_SEQ_NUM", - 185: "TCP_ACK_NUM", - 186: "TCP_WINDOW_SIZE", - 187: "TCP_URGENT_PTR", - 188: "TCP_HEADER_LEN", - 189: "IP_HEADER_LEN", - 190: "IP_TOTAL_LEN", - 191: "payloadLengthIPv6", - 192: "IP_TTL", - 193: "nextHeaderIPv6", - 194: "mplsPayloadLength", - 195: "IP_DSCP", - 196: "IP_PRECEDENCE", - 197: "IP_FRAGMENT_FLAGS", - 198: "DELTA_BYTES_SQUARED", - 199: "TOTAL_BYTES_SQUARED", - 200: "MPLS_TOP_LABEL_TTL", - 201: "MPLS_LABEL_STACK_OCTETS", - 202: "MPLS_LABEL_STACK_DEPTH", - 203: "MPLS_TOP_LABEL_EXP", - 204: "IP_PAYLOAD_LENGTH", - 205: "UDP_LENGTH", - 206: "IS_MULTICAST", - 207: "IP_HEADER_WORDS", - 208: "IP_OPTION_MAP", - 209: "TCP_OPTION_MAP", - 210: "paddingOctets", - 211: "collectorIPv4Address", - 212: "collectorIPv6Address", - 213: "collectorInterface", - 214: "collectorProtocolVersion", - 215: "collectorTransportProtocol", - 216: "collectorTransportPort", - 217: "exporterTransportPort", - 218: "tcpSynTotalCount", - 219: "tcpFinTotalCount", - 220: "tcpRstTotalCount", - 221: "tcpPshTotalCount", - 222: "tcpAckTotalCount", - 223: "tcpUrgTotalCount", - 224: "ipTotalLength", - 225: "postNATSourceIPv4Address", - 226: "postNATDestinationIPv4Address", - 227: "postNAPTSourceTransportPort", - 228: "postNAPTDestinationTransportPort", - 229: "natOriginatingAddressRealm", - 230: "natEvent", - 231: "initiatorOctets", - 232: "responderOctets", - 233: "firewallEvent", - 234: "ingressVRFID", - 235: "egressVRFID", - 236: "VRFname", - 237: "postMplsTopLabelExp", - 238: "tcpWindowScale", - 239: "biflowDirection", - 240: "ethernetHeaderLength", - 241: "ethernetPayloadLength", - 242: "ethernetTotalLength", - 243: "dot1qVlanId", - 244: "dot1qPriority", - 245: "dot1qCustomerVlanId", - 246: "dot1qCustomerPriority", - 247: "metroEvcId", - 248: "metroEvcType", - 249: "pseudoWireId", - 250: "pseudoWireType", - 251: "pseudoWireControlWord", - 252: "ingressPhysicalInterface", - 253: "egressPhysicalInterface", - 254: "postDot1qVlanId", - 255: "postDot1qCustomerVlanId", - 256: "ethernetType", - 257: "postIpPrecedence", - 258: "collectionTimeMilliseconds", - 259: "exportSctpStreamId", - 260: "maxExportSeconds", - 261: "maxFlowEndSeconds", - 262: "messageMD5Checksum", - 263: "messageScope", - 264: "minExportSeconds", - 265: "minFlowStartSeconds", - 266: "opaqueOctets", - 267: "sessionScope", - 268: "maxFlowEndMicroseconds", - 269: "maxFlowEndMilliseconds", - 270: "maxFlowEndNanoseconds", - 271: "minFlowStartMicroseconds", - 272: "minFlowStartMilliseconds", - 273: "minFlowStartNanoseconds", - 274: "collectorCertificate", - 275: "exporterCertificate", - 276: "dataRecordsReliability", - 277: "observationPointType", - 278: "newConnectionDeltaCount", - 279: "connectionSumDurationSeconds", - 280: "connectionTransactionId", - 281: "postNATSourceIPv6Address", - 282: "postNATDestinationIPv6Address", - 283: "natPoolId", - 284: "natPoolName", - 285: "anonymizationFlags", - 286: "anonymizationTechnique", - 287: "informationElementIndex", - 288: "p2pTechnology", - 289: "tunnelTechnology", - 290: "encryptedTechnology", - 291: "basicList", - 292: "subTemplateList", - 293: "subTemplateMultiList", - 294: "bgpValidityState", - 295: "IPSecSPI", - 296: "greKey", - 297: "natType", - 298: "initiatorPackets", - 299: "responderPackets", - 300: "observationDomainName", - 301: "selectionSequenceId", - 302: "selectorId", - 303: "informationElementId", - 304: "selectorAlgorithm", - 305: "samplingPacketInterval", - 306: "samplingPacketSpace", - 307: "samplingTimeInterval", - 308: "samplingTimeSpace", - 309: "samplingSize", - 310: "samplingPopulation", - 311: "samplingProbability", - 312: "dataLinkFrameSize", - 313: "IP_SECTION HEADER", - 314: "IP_SECTION PAYLOAD", - 315: "dataLinkFrameSection", - 316: "mplsLabelStackSection", - 317: "mplsPayloadPacketSection", - 318: "selectorIdTotalPktsObserved", - 319: "selectorIdTotalPktsSelected", - 320: "absoluteError", - 321: "relativeError", - 322: "observationTimeSeconds", - 323: "observationTimeMilliseconds", - 324: "observationTimeMicroseconds", - 325: "observationTimeNanoseconds", - 326: "digestHashValue", - 327: "hashIPPayloadOffset", - 328: "hashIPPayloadSize", - 329: "hashOutputRangeMin", - 330: "hashOutputRangeMax", - 331: "hashSelectedRangeMin", - 332: "hashSelectedRangeMax", - 333: "hashDigestOutput", - 334: "hashInitialiserValue", - 335: "selectorName", - 336: "upperCILimit", - 337: "lowerCILimit", - 338: "confidenceLevel", - 339: "informationElementDataType", - 340: "informationElementDescription", - 341: "informationElementName", - 342: "informationElementRangeBegin", - 343: "informationElementRangeEnd", - 344: "informationElementSemantics", - 345: "informationElementUnits", - 346: "privateEnterpriseNumber", - 347: "virtualStationInterfaceId", - 348: "virtualStationInterfaceName", - 349: "virtualStationUUID", - 350: "virtualStationName", - 351: "layer2SegmentId", - 352: "layer2OctetDeltaCount", - 353: "layer2OctetTotalCount", - 354: "ingressUnicastPacketTotalCount", - 355: "ingressMulticastPacketTotalCount", - 356: "ingressBroadcastPacketTotalCount", - 357: "egressUnicastPacketTotalCount", - 358: "egressBroadcastPacketTotalCount", - 359: "monitoringIntervalStartMilliSeconds", - 360: "monitoringIntervalEndMilliSeconds", - 361: "portRangeStart", - 362: "portRangeEnd", - 363: "portRangeStepSize", - 364: "portRangeNumPorts", - 365: "staMacAddress", - 366: "staIPv4Address", - 367: "wtpMacAddress", - 368: "ingressInterfaceType", - 369: "egressInterfaceType", - 370: "rtpSequenceNumber", - 371: "userName", - 372: "applicationCategoryName", - 373: "applicationSubCategoryName", - 374: "applicationGroupName", - 375: "originalFlowsPresent", - 376: "originalFlowsInitiated", - 377: "originalFlowsCompleted", - 378: "distinctCountOfSourceIPAddress", - 379: "distinctCountOfDestinationIPAddress", - 380: "distinctCountOfSourceIPv4Address", - 381: "distinctCountOfDestinationIPv4Address", - 382: "distinctCountOfSourceIPv6Address", - 383: "distinctCountOfDestinationIPv6Address", - 384: "valueDistributionMethod", - 385: "rfc3550JitterMilliseconds", - 386: "rfc3550JitterMicroseconds", - 387: "rfc3550JitterNanoseconds", - 388: "dot1qDEI", - 389: "dot1qCustomerDEI", - 390: "flowSelectorAlgorithm", - 391: "flowSelectedOctetDeltaCount", - 392: "flowSelectedPacketDeltaCount", - 393: "flowSelectedFlowDeltaCount", - 394: "selectorIDTotalFlowsObserved", - 395: "selectorIDTotalFlowsSelected", - 396: "samplingFlowInterval", - 397: "samplingFlowSpacing", - 398: "flowSamplingTimeInterval", - 399: "flowSamplingTimeSpacing", - 400: "hashFlowDomain", - 401: "transportOctetDeltaCount", - 402: "transportPacketDeltaCount", - 403: "originalExporterIPv4Address", - 404: "originalExporterIPv6Address", - 405: "originalObservationDomainId", - 406: "intermediateProcessId", - 407: "ignoredDataRecordTotalCount", - 408: "dataLinkFrameType", - 409: "sectionOffset", - 410: "sectionExportedOctets", - 411: "dot1qServiceInstanceTag", - 412: "dot1qServiceInstanceId", - 413: "dot1qServiceInstancePriority", - 414: "dot1qCustomerSourceMacAddress", - 415: "dot1qCustomerDestinationMacAddress", - 416: "deprecated [dup of layer2OctetDeltaCount]", - 417: "postLayer2OctetDeltaCount", - 418: "postMCastLayer2OctetDeltaCount", - 419: "deprecated [dup of layer2OctetTotalCount", - 420: "postLayer2OctetTotalCount", - 421: "postMCastLayer2OctetTotalCount", - 422: "minimumLayer2TotalLength", - 423: "maximumLayer2TotalLength", - 424: "droppedLayer2OctetDeltaCount", - 425: "droppedLayer2OctetTotalCount", - 426: "ignoredLayer2OctetTotalCount", - 427: "notSentLayer2OctetTotalCount", - 428: "layer2OctetDeltaSumOfSquares", - 429: "layer2OctetTotalSumOfSquares", - 430: "layer2FrameDeltaCount", - 431: "layer2FrameTotalCount", - 432: "pseudoWireDestinationIPv4Address", - 433: "ignoredLayer2FrameTotalCount", - 434: "mibObjectValueInteger", - 435: "mibObjectValueOctetString", - 436: "mibObjectValueOID", - 437: "mibObjectValueBits", - 438: "mibObjectValueIPAddress", - 439: "mibObjectValueCounter", - 440: "mibObjectValueGauge", - 441: "mibObjectValueTimeTicks", - 442: "mibObjectValueUnsigned", - 443: "mibObjectValueTable", - 444: "mibObjectValueRow", - 445: "mibObjectIdentifier", - 446: "mibSubIdentifier", - 447: "mibIndexIndicator", - 448: "mibCaptureTimeSemantics", - 449: "mibContextEngineID", - 450: "mibContextName", - 451: "mibObjectName", - 452: "mibObjectDescription", - 453: "mibObjectSyntax", - 454: "mibModuleName", - 455: "mobileIMSI", - 456: "mobileMSISDN", - 457: "httpStatusCode", - 458: "sourceTransportPortsLimit", - 459: "httpRequestMethod", - 460: "httpRequestHost", - 461: "httpRequestTarget", - 462: "httpMessageVersion", - 463: "natInstanceID", - 464: "internalAddressRealm", - 465: "externalAddressRealm", - 466: "natQuotaExceededEvent", - 467: "natThresholdEvent", - 468: "httpUserAgent", - 469: "httpContentType", - 470: "httpReasonPhrase", - 471: "maxSessionEntries", - 472: "maxBIBEntries", - 473: "maxEntriesPerUser", - 474: "maxSubscribers", - 475: "maxFragmentsPendingReassembly", - 476: "addressPoolHighThreshold", - 477: "addressPoolLowThreshold", - 478: "addressPortMappingHighThreshold", - 479: "addressPortMappingLowThreshold", - 480: "addressPortMappingPerUserHighThreshold", - 481: "globalAddressMappingHighThreshold", - - # Ericsson NAT Logging - 24628: "NAT_LOG_FIELD_IDX_CONTEXT_ID", - 24629: "NAT_LOG_FIELD_IDX_CONTEXT_NAME", - 24630: "NAT_LOG_FIELD_IDX_ASSIGN_TS_SEC", - 24631: "NAT_LOG_FIELD_IDX_UNASSIGN_TS_SEC", - 24632: "NAT_LOG_FIELD_IDX_IPV4_INT_ADDR", - 24633: "NAT_LOG_FIELD_IDX_IPV4_EXT_ADDR", - 24634: "NAT_LOG_FIELD_IDX_EXT_PORT_FIRST", - 24635: "NAT_LOG_FIELD_IDX_EXT_PORT_LAST", - # Cisco ASA5500 Series NetFlow - 33000: "INGRESS_ACL_ID", - 33001: "EGRESS_ACL_ID", - 33002: "FW_EXT_EVENT", - # Cisco TrustSec - 34000: "SGT_SOURCE_TAG", - 34001: "SGT_DESTINATION_TAG", - 34002: "SGT_SOURCE_NAME", - 34003: "SGT_DESTINATION_NAME", - # medianet performance monitor - 37000: "PACKETS_DROPPED", - 37003: "BYTE_RATE", - 37004: "APPLICATION_MEDIA_BYTES", - 37006: "APPLICATION_MEDIA_BYTE_RATE", - 37007: "APPLICATION_MEDIA_PACKETS", - 37009: "APPLICATION_MEDIA_PACKET_RATE", - 37011: "APPLICATION_MEDIA_EVENT", - 37012: "MONITOR_EVENT", - 37013: "TIMESTAMP_INTERVAL", - 37014: "TRANSPORT_PACKETS_EXPECTED", - 37016: "TRANSPORT_ROUND_TRIP_TIME", - 37017: "TRANSPORT_EVENT_PACKET_LOSS", - 37019: "TRANSPORT_PACKETS_LOST", - 37021: "TRANSPORT_PACKETS_LOST_RATE", - 37022: "TRANSPORT_RTP_SSRC", - 37023: "TRANSPORT_RTP_JITTER_MEAN", - 37024: "TRANSPORT_RTP_JITTER_MIN", - 37025: "TRANSPORT_RTP_JITTER_MAX", - 37041: "TRANSPORT_RTP_PAYLOAD_TYPE", - 37071: "TRANSPORT_BYTES_OUT_OF_ORDER", - 37074: "TRANSPORT_PACKETS_OUT_OF_ORDER", - 37083: "TRANSPORT_TCP_WINDOWS_SIZE_MIN", - 37084: "TRANSPORT_TCP_WINDOWS_SIZE_MAX", - 37085: "TRANSPORT_TCP_WINDOWS_SIZE_MEAN", - 37086: "TRANSPORT_TCP_MAXIMUM_SEGMENT_SIZE", - # Cisco ASA 5500 - 40000: "AAA_USERNAME", - 40001: "XLATE_SRC_ADDR_IPV4", - 40002: "XLATE_DST_ADDR_IPV4", - 40003: "XLATE_SRC_PORT", - 40004: "XLATE_DST_PORT", - 40005: "FW_EVENT", - # v9 nTop extensions - 80 + NTOP_BASE: "SRC_FRAGMENTS", - 81 + NTOP_BASE: "DST_FRAGMENTS", - 82 + NTOP_BASE: "SRC_TO_DST_MAX_THROUGHPUT", - 83 + NTOP_BASE: "SRC_TO_DST_MIN_THROUGHPUT", - 84 + NTOP_BASE: "SRC_TO_DST_AVG_THROUGHPUT", - 85 + NTOP_BASE: "SRC_TO_SRC_MAX_THROUGHPUT", - 86 + NTOP_BASE: "SRC_TO_SRC_MIN_THROUGHPUT", - 87 + NTOP_BASE: "SRC_TO_SRC_AVG_THROUGHPUT", - 88 + NTOP_BASE: "NUM_PKTS_UP_TO_128_BYTES", - 89 + NTOP_BASE: "NUM_PKTS_128_TO_256_BYTES", - 90 + NTOP_BASE: "NUM_PKTS_256_TO_512_BYTES", - 91 + NTOP_BASE: "NUM_PKTS_512_TO_1024_BYTES", - 92 + NTOP_BASE: "NUM_PKTS_1024_TO_1514_BYTES", - 93 + NTOP_BASE: "NUM_PKTS_OVER_1514_BYTES", - 98 + NTOP_BASE: "CUMULATIVE_ICMP_TYPE", - 101 + NTOP_BASE: "SRC_IP_COUNTRY", - 102 + NTOP_BASE: "SRC_IP_CITY", - 103 + NTOP_BASE: "DST_IP_COUNTRY", - 104 + NTOP_BASE: "DST_IP_CITY", - 105 + NTOP_BASE: "FLOW_PROTO_PORT", - 106 + NTOP_BASE: "UPSTREAM_TUNNEL_ID", - 107 + NTOP_BASE: "LONGEST_FLOW_PKT", - 108 + NTOP_BASE: "SHORTEST_FLOW_PKT", - 109 + NTOP_BASE: "RETRANSMITTED_IN_PKTS", - 110 + NTOP_BASE: "RETRANSMITTED_OUT_PKTS", - 111 + NTOP_BASE: "OOORDER_IN_PKTS", - 112 + NTOP_BASE: "OOORDER_OUT_PKTS", - 113 + NTOP_BASE: "UNTUNNELED_PROTOCOL", - 114 + NTOP_BASE: "UNTUNNELED_IPV4_SRC_ADDR", - 115 + NTOP_BASE: "UNTUNNELED_L4_SRC_PORT", - 116 + NTOP_BASE: "UNTUNNELED_IPV4_DST_ADDR", - 117 + NTOP_BASE: "UNTUNNELED_L4_DST_PORT", - 118 + NTOP_BASE: "L7_PROTO", - 119 + NTOP_BASE: "L7_PROTO_NAME", - 120 + NTOP_BASE: "DOWNSTREAM_TUNNEL_ID", - 121 + NTOP_BASE: "FLOW_USER_NAME", - 122 + NTOP_BASE: "FLOW_SERVER_NAME", - 123 + NTOP_BASE: "CLIENT_NW_LATENCY_MS", - 124 + NTOP_BASE: "SERVER_NW_LATENCY_MS", - 125 + NTOP_BASE: "APPL_LATENCY_MS", - 126 + NTOP_BASE: "PLUGIN_NAME", - 127 + NTOP_BASE: "RETRANSMITTED_IN_BYTES", - 128 + NTOP_BASE: "RETRANSMITTED_OUT_BYTES", - 130 + NTOP_BASE: "SIP_CALL_ID", - 131 + NTOP_BASE: "SIP_CALLING_PARTY", - 132 + NTOP_BASE: "SIP_CALLED_PARTY", - 133 + NTOP_BASE: "SIP_RTP_CODECS", - 134 + NTOP_BASE: "SIP_INVITE_TIME", - 135 + NTOP_BASE: "SIP_TRYING_TIME", - 136 + NTOP_BASE: "SIP_RINGING_TIME", - 137 + NTOP_BASE: "SIP_INVITE_OK_TIME", - 138 + NTOP_BASE: "SIP_INVITE_FAILURE_TIME", - 139 + NTOP_BASE: "SIP_BYE_TIME", - 140 + NTOP_BASE: "SIP_BYE_OK_TIME", - 141 + NTOP_BASE: "SIP_CANCEL_TIME", - 142 + NTOP_BASE: "SIP_CANCEL_OK_TIME", - 143 + NTOP_BASE: "SIP_RTP_IPV4_SRC_ADDR", - 144 + NTOP_BASE: "SIP_RTP_L4_SRC_PORT", - 145 + NTOP_BASE: "SIP_RTP_IPV4_DST_ADDR", - 146 + NTOP_BASE: "SIP_RTP_L4_DST_PORT", - 147 + NTOP_BASE: "SIP_RESPONSE_CODE", - 148 + NTOP_BASE: "SIP_REASON_CAUSE", - 150 + NTOP_BASE: "RTP_FIRST_SEQ", - 151 + NTOP_BASE: "RTP_FIRST_TS", - 152 + NTOP_BASE: "RTP_LAST_SEQ", - 153 + NTOP_BASE: "RTP_LAST_TS", - 154 + NTOP_BASE: "RTP_IN_JITTER", - 155 + NTOP_BASE: "RTP_OUT_JITTER", - 156 + NTOP_BASE: "RTP_IN_PKT_LOST", - 157 + NTOP_BASE: "RTP_OUT_PKT_LOST", - 158 + NTOP_BASE: "RTP_OUT_PAYLOAD_TYPE", - 159 + NTOP_BASE: "RTP_IN_MAX_DELTA", - 160 + NTOP_BASE: "RTP_OUT_MAX_DELTA", - 161 + NTOP_BASE: "RTP_IN_PAYLOAD_TYPE", - 168 + NTOP_BASE: "SRC_PROC_PID", - 169 + NTOP_BASE: "SRC_PROC_NAME", - 180 + NTOP_BASE: "HTTP_URL", - 181 + NTOP_BASE: "HTTP_RET_CODE", - 182 + NTOP_BASE: "HTTP_REFERER", - 183 + NTOP_BASE: "HTTP_UA", - 184 + NTOP_BASE: "HTTP_MIME", - 185 + NTOP_BASE: "SMTP_MAIL_FROM", - 186 + NTOP_BASE: "SMTP_RCPT_TO", - 187 + NTOP_BASE: "HTTP_HOST", - 188 + NTOP_BASE: "SSL_SERVER_NAME", - 189 + NTOP_BASE: "BITTORRENT_HASH", - 195 + NTOP_BASE: "MYSQL_SRV_VERSION", - 196 + NTOP_BASE: "MYSQL_USERNAME", - 197 + NTOP_BASE: "MYSQL_DB", - 198 + NTOP_BASE: "MYSQL_QUERY", - 199 + NTOP_BASE: "MYSQL_RESPONSE", - 200 + NTOP_BASE: "ORACLE_USERNAME", - 201 + NTOP_BASE: "ORACLE_QUERY", - 202 + NTOP_BASE: "ORACLE_RSP_CODE", - 203 + NTOP_BASE: "ORACLE_RSP_STRING", - 204 + NTOP_BASE: "ORACLE_QUERY_DURATION", - 205 + NTOP_BASE: "DNS_QUERY", - 206 + NTOP_BASE: "DNS_QUERY_ID", - 207 + NTOP_BASE: "DNS_QUERY_TYPE", - 208 + NTOP_BASE: "DNS_RET_CODE", - 209 + NTOP_BASE: "DNS_NUM_ANSWERS", - 210 + NTOP_BASE: "POP_USER", - 220 + NTOP_BASE: "GTPV1_REQ_MSG_TYPE", - 221 + NTOP_BASE: "GTPV1_RSP_MSG_TYPE", - 222 + NTOP_BASE: "GTPV1_C2S_TEID_DATA", - 223 + NTOP_BASE: "GTPV1_C2S_TEID_CTRL", - 224 + NTOP_BASE: "GTPV1_S2C_TEID_DATA", - 225 + NTOP_BASE: "GTPV1_S2C_TEID_CTRL", - 226 + NTOP_BASE: "GTPV1_END_USER_IP", - 227 + NTOP_BASE: "GTPV1_END_USER_IMSI", - 228 + NTOP_BASE: "GTPV1_END_USER_MSISDN", - 229 + NTOP_BASE: "GTPV1_END_USER_IMEI", - 230 + NTOP_BASE: "GTPV1_APN_NAME", - 231 + NTOP_BASE: "GTPV1_RAI_MCC", - 232 + NTOP_BASE: "GTPV1_RAI_MNC", - 233 + NTOP_BASE: "GTPV1_ULI_CELL_LAC", - 234 + NTOP_BASE: "GTPV1_ULI_CELL_CI", - 235 + NTOP_BASE: "GTPV1_ULI_SAC", - 236 + NTOP_BASE: "GTPV1_RAT_TYPE", - 240 + NTOP_BASE: "RADIUS_REQ_MSG_TYPE", - 241 + NTOP_BASE: "RADIUS_RSP_MSG_TYPE", - 242 + NTOP_BASE: "RADIUS_USER_NAME", - 243 + NTOP_BASE: "RADIUS_CALLING_STATION_ID", - 244 + NTOP_BASE: "RADIUS_CALLED_STATION_ID", - 245 + NTOP_BASE: "RADIUS_NAS_IP_ADDR", - 246 + NTOP_BASE: "RADIUS_NAS_IDENTIFIER", - 247 + NTOP_BASE: "RADIUS_USER_IMSI", - 248 + NTOP_BASE: "RADIUS_USER_IMEI", - 249 + NTOP_BASE: "RADIUS_FRAMED_IP_ADDR", - 250 + NTOP_BASE: "RADIUS_ACCT_SESSION_ID", - 251 + NTOP_BASE: "RADIUS_ACCT_STATUS_TYPE", - 252 + NTOP_BASE: "RADIUS_ACCT_IN_OCTETS", - 253 + NTOP_BASE: "RADIUS_ACCT_OUT_OCTETS", - 254 + NTOP_BASE: "RADIUS_ACCT_IN_PKTS", - 255 + NTOP_BASE: "RADIUS_ACCT_OUT_PKTS", - 260 + NTOP_BASE: "IMAP_LOGIN", - 270 + NTOP_BASE: "GTPV2_REQ_MSG_TYPE", - 271 + NTOP_BASE: "GTPV2_RSP_MSG_TYPE", - 272 + NTOP_BASE: "GTPV2_C2S_S1U_GTPU_TEID", - 273 + NTOP_BASE: "GTPV2_C2S_S1U_GTPU_IP", - 274 + NTOP_BASE: "GTPV2_S2C_S1U_GTPU_TEID", - 275 + NTOP_BASE: "GTPV2_S2C_S1U_GTPU_IP", - 276 + NTOP_BASE: "GTPV2_END_USER_IMSI", - 277 + NTOP_BASE: "GTPV2_END_USER_MSISDN", - 278 + NTOP_BASE: "GTPV2_APN_NAME", - 279 + NTOP_BASE: "GTPV2_ULI_MCC", - 280 + NTOP_BASE: "GTPV2_ULI_MNC", - 281 + NTOP_BASE: "GTPV2_ULI_CELL_TAC", - 282 + NTOP_BASE: "GTPV2_ULI_CELL_ID", - 283 + NTOP_BASE: "GTPV2_RAT_TYPE", - 284 + NTOP_BASE: "GTPV2_PDN_IP", - 285 + NTOP_BASE: "GTPV2_END_USER_IMEI", - 290 + NTOP_BASE: "SRC_AS_PATH_1", - 291 + NTOP_BASE: "SRC_AS_PATH_2", - 292 + NTOP_BASE: "SRC_AS_PATH_3", - 293 + NTOP_BASE: "SRC_AS_PATH_4", - 294 + NTOP_BASE: "SRC_AS_PATH_5", - 295 + NTOP_BASE: "SRC_AS_PATH_6", - 296 + NTOP_BASE: "SRC_AS_PATH_7", - 297 + NTOP_BASE: "SRC_AS_PATH_8", - 298 + NTOP_BASE: "SRC_AS_PATH_9", - 299 + NTOP_BASE: "SRC_AS_PATH_10", - 300 + NTOP_BASE: "DST_AS_PATH_1", - 301 + NTOP_BASE: "DST_AS_PATH_2", - 302 + NTOP_BASE: "DST_AS_PATH_3", - 303 + NTOP_BASE: "DST_AS_PATH_4", - 304 + NTOP_BASE: "DST_AS_PATH_5", - 305 + NTOP_BASE: "DST_AS_PATH_6", - 306 + NTOP_BASE: "DST_AS_PATH_7", - 307 + NTOP_BASE: "DST_AS_PATH_8", - 308 + NTOP_BASE: "DST_AS_PATH_9", - 309 + NTOP_BASE: "DST_AS_PATH_10", - 320 + NTOP_BASE: "MYSQL_APPL_LATENCY_USEC", - 321 + NTOP_BASE: "GTPV0_REQ_MSG_TYPE", - 322 + NTOP_BASE: "GTPV0_RSP_MSG_TYPE", - 323 + NTOP_BASE: "GTPV0_TID", - 324 + NTOP_BASE: "GTPV0_END_USER_IP", - 325 + NTOP_BASE: "GTPV0_END_USER_MSISDN", - 326 + NTOP_BASE: "GTPV0_APN_NAME", - 327 + NTOP_BASE: "GTPV0_RAI_MCC", - 328 + NTOP_BASE: "GTPV0_RAI_MNC", - 329 + NTOP_BASE: "GTPV0_RAI_CELL_LAC", - 330 + NTOP_BASE: "GTPV0_RAI_CELL_RAC", - 331 + NTOP_BASE: "GTPV0_RESPONSE_CAUSE", - 332 + NTOP_BASE: "GTPV1_RESPONSE_CAUSE", - 333 + NTOP_BASE: "GTPV2_RESPONSE_CAUSE", - 334 + NTOP_BASE: "NUM_PKTS_TTL_5_32", - 335 + NTOP_BASE: "NUM_PKTS_TTL_32_64", - 336 + NTOP_BASE: "NUM_PKTS_TTL_64_96", - 337 + NTOP_BASE: "NUM_PKTS_TTL_96_128", - 338 + NTOP_BASE: "NUM_PKTS_TTL_128_160", - 339 + NTOP_BASE: "NUM_PKTS_TTL_160_192", - 340 + NTOP_BASE: "NUM_PKTS_TTL_192_224", - 341 + NTOP_BASE: "NUM_PKTS_TTL_224_255", - 342 + NTOP_BASE: "GTPV1_RAI_LAC", - 343 + NTOP_BASE: "GTPV1_RAI_RAC", - 344 + NTOP_BASE: "GTPV1_ULI_MCC", - 345 + NTOP_BASE: "GTPV1_ULI_MNC", - 346 + NTOP_BASE: "NUM_PKTS_TTL_2_5", - 347 + NTOP_BASE: "NUM_PKTS_TTL_EQ_1", - 348 + NTOP_BASE: "RTP_SIP_CALL_ID", - 349 + NTOP_BASE: "IN_SRC_OSI_SAP", - 350 + NTOP_BASE: "OUT_DST_OSI_SAP", - 351 + NTOP_BASE: "WHOIS_DAS_DOMAIN", - 352 + NTOP_BASE: "DNS_TTL_ANSWER", - 353 + NTOP_BASE: "DHCP_CLIENT_MAC", - 354 + NTOP_BASE: "DHCP_CLIENT_IP", - 355 + NTOP_BASE: "DHCP_CLIENT_NAME", - 356 + NTOP_BASE: "FTP_LOGIN", - 357 + NTOP_BASE: "FTP_PASSWORD", - 358 + NTOP_BASE: "FTP_COMMAND", - 359 + NTOP_BASE: "FTP_COMMAND_RET_CODE", - 360 + NTOP_BASE: "HTTP_METHOD", - 361 + NTOP_BASE: "HTTP_SITE", - 362 + NTOP_BASE: "SIP_C_IP", - 363 + NTOP_BASE: "SIP_CALL_STATE", - 364 + NTOP_BASE: "EPP_REGISTRAR_NAME", - 365 + NTOP_BASE: "EPP_CMD", - 366 + NTOP_BASE: "EPP_CMD_ARGS", - 367 + NTOP_BASE: "EPP_RSP_CODE", - 368 + NTOP_BASE: "EPP_REASON_STR", - 369 + NTOP_BASE: "EPP_SERVER_NAME", - 370 + NTOP_BASE: "RTP_IN_MOS", - 371 + NTOP_BASE: "RTP_IN_R_FACTOR", - 372 + NTOP_BASE: "SRC_PROC_USER_NAME", - 373 + NTOP_BASE: "SRC_FATHER_PROC_PID", - 374 + NTOP_BASE: "SRC_FATHER_PROC_NAME", - 375 + NTOP_BASE: "DST_PROC_PID", - 376 + NTOP_BASE: "DST_PROC_NAME", - 377 + NTOP_BASE: "DST_PROC_USER_NAME", - 378 + NTOP_BASE: "DST_FATHER_PROC_PID", - 379 + NTOP_BASE: "DST_FATHER_PROC_NAME", - 380 + NTOP_BASE: "RTP_RTT", - 381 + NTOP_BASE: "RTP_IN_TRANSIT", - 382 + NTOP_BASE: "RTP_OUT_TRANSIT", - 383 + NTOP_BASE: "SRC_PROC_ACTUAL_MEMORY", - 384 + NTOP_BASE: "SRC_PROC_PEAK_MEMORY", - 385 + NTOP_BASE: "SRC_PROC_AVERAGE_CPU_LOAD", - 386 + NTOP_BASE: "SRC_PROC_NUM_PAGE_FAULTS", - 387 + NTOP_BASE: "DST_PROC_ACTUAL_MEMORY", - 388 + NTOP_BASE: "DST_PROC_PEAK_MEMORY", - 389 + NTOP_BASE: "DST_PROC_AVERAGE_CPU_LOAD", - 390 + NTOP_BASE: "DST_PROC_NUM_PAGE_FAULTS", - 391 + NTOP_BASE: "DURATION_IN", - 392 + NTOP_BASE: "DURATION_OUT", - 393 + NTOP_BASE: "SRC_PROC_PCTG_IOWAIT", - 394 + NTOP_BASE: "DST_PROC_PCTG_IOWAIT", - 395 + NTOP_BASE: "RTP_DTMF_TONES", - 396 + NTOP_BASE: "UNTUNNELED_IPV6_SRC_ADDR", - 397 + NTOP_BASE: "UNTUNNELED_IPV6_DST_ADDR", - 398 + NTOP_BASE: "DNS_RESPONSE", - 399 + NTOP_BASE: "DIAMETER_REQ_MSG_TYPE", - 400 + NTOP_BASE: "DIAMETER_RSP_MSG_TYPE", - 401 + NTOP_BASE: "DIAMETER_REQ_ORIGIN_HOST", - 402 + NTOP_BASE: "DIAMETER_RSP_ORIGIN_HOST", - 403 + NTOP_BASE: "DIAMETER_REQ_USER_NAME", - 404 + NTOP_BASE: "DIAMETER_RSP_RESULT_CODE", - 405 + NTOP_BASE: "DIAMETER_EXP_RES_VENDOR_ID", - 406 + NTOP_BASE: "DIAMETER_EXP_RES_RESULT_CODE", - 407 + NTOP_BASE: "S1AP_ENB_UE_S1AP_ID", - 408 + NTOP_BASE: "S1AP_MME_UE_S1AP_ID", - 409 + NTOP_BASE: "S1AP_MSG_EMM_TYPE_MME_TO_ENB", - 410 + NTOP_BASE: "S1AP_MSG_ESM_TYPE_MME_TO_ENB", - 411 + NTOP_BASE: "S1AP_MSG_EMM_TYPE_ENB_TO_MME", - 412 + NTOP_BASE: "S1AP_MSG_ESM_TYPE_ENB_TO_MME", - 413 + NTOP_BASE: "S1AP_CAUSE_ENB_TO_MME", - 414 + NTOP_BASE: "S1AP_DETAILED_CAUSE_ENB_TO_MME", - 415 + NTOP_BASE: "TCP_WIN_MIN_IN", - 416 + NTOP_BASE: "TCP_WIN_MAX_IN", - 417 + NTOP_BASE: "TCP_WIN_MSS_IN", - 418 + NTOP_BASE: "TCP_WIN_SCALE_IN", - 419 + NTOP_BASE: "TCP_WIN_MIN_OUT", - 420 + NTOP_BASE: "TCP_WIN_MAX_OUT", - 421 + NTOP_BASE: "TCP_WIN_MSS_OUT", - 422 + NTOP_BASE: "TCP_WIN_SCALE_OUT", - 423 + NTOP_BASE: "DHCP_REMOTE_ID", - 424 + NTOP_BASE: "DHCP_SUBSCRIBER_ID", - 425 + NTOP_BASE: "SRC_PROC_UID", - 426 + NTOP_BASE: "DST_PROC_UID", - 427 + NTOP_BASE: "APPLICATION_NAME", - 428 + NTOP_BASE: "USER_NAME", - 429 + NTOP_BASE: "DHCP_MESSAGE_TYPE", - 430 + NTOP_BASE: "RTP_IN_PKT_DROP", - 431 + NTOP_BASE: "RTP_OUT_PKT_DROP", - 432 + NTOP_BASE: "RTP_OUT_MOS", - 433 + NTOP_BASE: "RTP_OUT_R_FACTOR", - 434 + NTOP_BASE: "RTP_MOS", - 435 + NTOP_BASE: "GTPV2_S5_S8_GTPC_TEID", - 436 + NTOP_BASE: "RTP_R_FACTOR", - 437 + NTOP_BASE: "RTP_SSRC", - 438 + NTOP_BASE: "PAYLOAD_HASH", - 439 + NTOP_BASE: "GTPV2_C2S_S5_S8_GTPU_TEID", - 440 + NTOP_BASE: "GTPV2_S2C_S5_S8_GTPU_TEID", - 441 + NTOP_BASE: "GTPV2_C2S_S5_S8_GTPU_IP", - 442 + NTOP_BASE: "GTPV2_S2C_S5_S8_GTPU_IP", - 443 + NTOP_BASE: "SRC_AS_MAP", - 444 + NTOP_BASE: "DST_AS_MAP", - 445 + NTOP_BASE: "DIAMETER_HOP_BY_HOP_ID", - 446 + NTOP_BASE: "UPSTREAM_SESSION_ID", - 447 + NTOP_BASE: "DOWNSTREAM_SESSION_ID", - 448 + NTOP_BASE: "SRC_IP_LONG", - 449 + NTOP_BASE: "SRC_IP_LAT", - 450 + NTOP_BASE: "DST_IP_LONG", - 451 + NTOP_BASE: "DST_IP_LAT", - 452 + NTOP_BASE: "DIAMETER_CLR_CANCEL_TYPE", - 453 + NTOP_BASE: "DIAMETER_CLR_FLAGS", - 454 + NTOP_BASE: "GTPV2_C2S_S5_S8_GTPC_IP", - 455 + NTOP_BASE: "GTPV2_S2C_S5_S8_GTPC_IP", - 456 + NTOP_BASE: "GTPV2_C2S_S5_S8_SGW_GTPU_TEID", - 457 + NTOP_BASE: "GTPV2_S2C_S5_S8_SGW_GTPU_TEID", - 458 + NTOP_BASE: "GTPV2_C2S_S5_S8_SGW_GTPU_IP", - 459 + NTOP_BASE: "GTPV2_S2C_S5_S8_SGW_GTPU_IP", - 460 + NTOP_BASE: "HTTP_X_FORWARDED_FOR", - 461 + NTOP_BASE: "HTTP_VIA", - 462 + NTOP_BASE: "SSDP_HOST", - 463 + NTOP_BASE: "SSDP_USN", - 464 + NTOP_BASE: "NETBIOS_QUERY_NAME", - 465 + NTOP_BASE: "NETBIOS_QUERY_TYPE", - 466 + NTOP_BASE: "NETBIOS_RESPONSE", - 467 + NTOP_BASE: "NETBIOS_QUERY_OS", - 468 + NTOP_BASE: "SSDP_SERVER", - 469 + NTOP_BASE: "SSDP_TYPE", - 470 + NTOP_BASE: "SSDP_METHOD", - 471 + NTOP_BASE: "NPROBE_IPV4_ADDRESS", -} - -ScopeFieldTypes = { - 1: "System", - 2: "Interface", - 3: "Line card", - 4: "Cache", - 5: "Template", -} - -NetflowV9TemplateFieldDefaultLengths = { - 1: 4, - 2: 4, - 3: 4, - 4: 1, - 5: 1, - 6: 1, - 7: 2, - 8: 4, - 9: 1, - 10: 2, - 11: 2, - 12: 4, - 13: 1, - 14: 2, - 15: 4, - 16: 2, - 17: 2, - 18: 4, - 19: 4, - 20: 4, - 21: 4, - 22: 4, - 23: 4, - 24: 4, - 27: 16, - 28: 16, - 29: 1, - 30: 1, - 31: 3, - 32: 2, - 33: 1, - 34: 4, - 35: 1, - 36: 2, - 37: 2, - 38: 1, - 39: 1, - 40: 4, - 41: 4, - 42: 4, - 46: 1, - 47: 4, - 48: 4, # from ERRATA - 49: 1, - 50: 4, - 55: 1, - 56: 6, - 57: 6, - 58: 2, - 59: 2, - 60: 1, - 61: 1, - 62: 16, - 63: 16, - 64: 4, - 70: 3, - 71: 3, - 72: 3, - 73: 3, - 74: 3, - 75: 3, - 76: 3, - 77: 3, - 78: 3, - 79: 3, -} - -# NetflowV9 Ready-made fields - - -class ShortOrInt(IntField): - def getfield(self, pkt, x): - if len(x) == 2: - Field.__init__(self, self.name, self.default, fmt="!H") - return Field.getfield(self, pkt, x) - - -class _AdjustableNetflowField(IntField, LongField): - """Fields that can receive a length kwarg, even though they normally can't. - Netflow usage only.""" - def __init__(self, name, default, length): - if length == 4: - IntField.__init__(self, name, default) - return - elif length == 8: - LongField.__init__(self, name, default) - return - LongField.__init__(self, name, default) - - -class N9SecondsIntField(SecondsIntField, _AdjustableNetflowField): - """Defines dateTimeSeconds (without EPOCH: just seconds)""" - def __init__(self, name, default, *args, **kargs): - length = kargs.pop("length", 8) - SecondsIntField.__init__(self, name, default, *args, **kargs) - _AdjustableNetflowField.__init__( - self, name, default, length - ) - - -class N9UTCTimeField(UTCTimeField, _AdjustableNetflowField): - """Defines dateTimeSeconds (EPOCH)""" - def __init__(self, name, default, *args, **kargs): - length = kargs.pop("length", 8) - UTCTimeField.__init__(self, name, default, *args, **kargs) - _AdjustableNetflowField.__init__( - self, name, default, length - ) - - -# TODO: There are hundreds of entries to add to the following :( -# https://tools.ietf.org/html/rfc5655 -# ==> feel free to contribute :D -NetflowV9TemplateFieldDecoders = { - # Only contains fields that have a fixed length - # ID: Field, - # or - # ID: (Field, [*optional_parameters]), - 4: (ByteEnumField, [IP_PROTOS]), # PROTOCOL - 5: XByteField, # TOS - 6: ByteField, # TCP_FLAGS - 7: ShortField, # L4_SRC_PORT - 8: IPField, # IPV4_SRC_ADDR - 9: ByteField, # SRC_MASK - 11: ShortField, # L4_DST_PORT - 12: IPField, # IPV4_DST_PORT - 13: ByteField, # DST_MASK - 15: IPField, # IPv4_NEXT_HOP - 16: ShortOrInt, # SRC_AS - 17: ShortOrInt, # DST_AS - 18: IPField, # BGP_IPv4_NEXT_HOP - 21: (SecondsIntField, [True]), # LAST_SWITCHED - 22: (SecondsIntField, [True]), # FIRST_SWITCHED - 27: IP6Field, # IPV6_SRC_ADDR - 28: IP6Field, # IPV6_DST_ADDR - 29: ByteField, # IPV6_SRC_MASK - 30: ByteField, # IPV6_DST_MASK - 31: ThreeBytesField, # IPV6_FLOW_LABEL - 32: XShortField, # ICMP_TYPE - 33: ByteField, # MUL_IGMP_TYPE - 34: IntField, # SAMPLING_INTERVAL - 35: XByteField, # SAMPLING_ALGORITHM - 36: ShortField, # FLOW_ACTIVE_TIMEOUT - 37: ShortField, # FLOW_ACTIVE_TIMEOUT - 38: ByteField, # ENGINE_TYPE - 39: ByteField, # ENGINE_ID - 46: (ByteEnumField, [{0x00: "UNKNOWN", 0x01: "TE-MIDPT", 0x02: "ATOM", 0x03: "VPN", 0x04: "BGP", 0x05: "LDP"}]), # MPLS_TOP_LABEL_TYPE # noqa: E501 - 47: IPField, # MPLS_TOP_LABEL_IP_ADDR - 48: ByteField, # FLOW_SAMPLER_ID - 49: ByteField, # FLOW_SAMPLER_MODE - 50: IntField, # FLOW_SAMPLER_RANDOM_INTERVAL - 55: XByteField, # DST_TOS - 56: MACField, # SRC_MAC - 57: MACField, # DST_MAC - 58: ShortField, # SRC_VLAN - 59: ShortField, # DST_VLAN - 60: ByteField, # IP_PROTOCOL_VERSION - 61: (ByteEnumField, [{0x00: "Ingress flow", 0x01: "Egress flow"}]), # DIRECTION # noqa: E501 - 62: IP6Field, # IPV6_NEXT_HOP - 63: IP6Field, # BGP_IPV6_NEXT_HOP - 130: IPField, # exporterIPv4Address - 131: IP6Field, # exporterIPv6Address - 150: N9UTCTimeField, # flowStartSeconds - 151: N9UTCTimeField, # flowEndSeconds - 152: (N9UTCTimeField, [True]), # flowStartMilliseconds - 153: (N9UTCTimeField, [True]), # flowEndMilliseconds - 154: (N9UTCTimeField, [False, True]), # flowStartMicroseconds - 155: (N9UTCTimeField, [False, True]), # flowEndMicroseconds - 156: (N9UTCTimeField, [False, False, True]), # flowStartNanoseconds - 157: (N9UTCTimeField, [False, False, True]), # flowEndNanoseconds - 158: (N9SecondsIntField, [False, True]), # flowStartDeltaMicroseconds - 159: (N9SecondsIntField, [False, True]), # flowEndDeltaMicroseconds - 160: (N9UTCTimeField, [True]), # systemInitTimeMilliseconds - 161: (N9SecondsIntField, [True]), # flowDurationMilliseconds - 162: (N9SecondsIntField, [False, True]), # flowDurationMicroseconds - 211: IPField, # collectorIPv4Address - 212: IP6Field, # collectorIPv6Address - 225: IPField, # postNATSourceIPv4Address - 226: IPField, # postNATDestinationIPv4Address - 258: (N9SecondsIntField, [True]), # collectionTimeMilliseconds - 260: N9SecondsIntField, # maxExportSeconds - 261: N9SecondsIntField, # maxFlowEndSeconds - 264: N9SecondsIntField, # minExportSeconds - 265: N9SecondsIntField, # minFlowStartSeconds - 268: (N9UTCTimeField, [False, True]), # maxFlowEndMicroseconds - 269: (N9UTCTimeField, [True]), # maxFlowEndMilliseconds - 270: (N9UTCTimeField, [False, False, True]), # maxFlowEndNanoseconds - 271: (N9UTCTimeField, [False, True]), # minFlowStartMicroseconds - 272: (N9UTCTimeField, [True]), # minFlowStartMilliseconds - 273: (N9UTCTimeField, [False, False, True]), # minFlowStartNanoseconds - 279: N9SecondsIntField, # connectionSumDurationSeconds - 281: IP6Field, # postNATSourceIPv6Address - 282: IP6Field, # postNATDestinationIPv6Address - 322: N9UTCTimeField, # observationTimeSeconds - 323: (N9UTCTimeField, [True]), # observationTimeMilliseconds - 324: (N9UTCTimeField, [False, True]), # observationTimeMicroseconds - 325: (N9UTCTimeField, [False, False, True]), # observationTimeNanoseconds - 365: MACField, # staMacAddress - 366: IPField, # staIPv4Address - 367: MACField, # wtpMacAddress - 380: IPField, # distinctCountOfSourceIPv4Address - 381: IPField, # distinctCountOfDestinationIPv4Address - 382: IP6Field, # distinctCountOfSourceIPv6Address - 383: IP6Field, # distinctCountOfDestinationIPv6Address - 403: IPField, # originalExporterIPv4Address - 404: IP6Field, # originalExporterIPv6Address - 414: MACField, # dot1qCustomerSourceMacAddress - 415: MACField, # dot1qCustomerDestinationMacAddress - 432: IPField, # pseudoWireDestinationIPv4Address - 24632: IPField, # NAT_LOG_FIELD_IDX_IPV4_INT_ADDR - 24633: IPField, # NAT_LOG_FIELD_IDX_IPV4_EXT_ADDR - 40001: IPField, # XLATE_SRC_ADDR_IPV4 - 40002: IPField, # XLATE_DST_ADDR_IPV4 - 114 + NTOP_BASE: IPField, # UNTUNNELED_IPV4_SRC_ADDR - 116 + NTOP_BASE: IPField, # UNTUNNELED_IPV4_DST_ADDR - 143 + NTOP_BASE: IPField, # SIP_RTP_IPV4_SRC_ADDR - 145 + NTOP_BASE: IPField, # SIP_RTP_IPV4_DST_ADDR - 353 + NTOP_BASE: MACField, # DHCP_CLIENT_MAC - 396 + NTOP_BASE: IP6Field, # UNTUNNELED_IPV6_SRC_ADDR - 397 + NTOP_BASE: IP6Field, # UNTUNNELED_IPV6_DST_ADDR - 471 + NTOP_BASE: IPField, # NPROBE_IPV4_ADDRESS -} - - -class NetflowHeaderV9(Packet): - name = "Netflow Header V9" - fields_desc = [ShortField("count", None), - IntField("sysUptime", 0), - UTCTimeField("unixSecs", None), - IntField("packageSequence", 0), - IntField("SourceID", 0)] - - def post_build(self, pkt, pay): - if self.count is None: - count = sum(1 for x in self.layers() if x in [ - NetflowFlowsetV9, - NetflowDataflowsetV9, - NetflowOptionsFlowsetV9] - ) - pkt = struct.pack("!H", count) + pkt[2:] - return pkt + pay - - -# https://tools.ietf.org/html/rfc5655#appendix-B.1.1 -class NetflowHeaderV10(Packet): - """IPFix (Netflow V10) Header""" - name = "IPFix (Netflow V10) Header" - fields_desc = [ShortField("length", None), - UTCTimeField("ExportTime", 0), - IntField("flowSequence", 0), - IntField("ObservationDomainID", 0)] - - -class NetflowTemplateFieldV9(Packet): - name = "Netflow Flowset Template Field V9/10" - fields_desc = [ShortEnumField("fieldType", None, - NetflowV910TemplateFieldTypes), - ShortField("fieldLength", 0)] - - def __init__(self, *args, **kwargs): - Packet.__init__(self, *args, **kwargs) - if self.fieldType is not None and not self.fieldLength and self.fieldType in NetflowV9TemplateFieldDefaultLengths: # noqa: E501 - self.fieldLength = NetflowV9TemplateFieldDefaultLengths[self.fieldType] # noqa: E501 - - def default_payload_class(self, p): - return conf.padding_layer - - -class NetflowTemplateV9(Packet): - name = "Netflow Flowset Template V9/10" - fields_desc = [ShortField("templateID", 255), - FieldLenField("fieldCount", None, count_of="template_fields"), # noqa: E501 - PacketListField("template_fields", [], NetflowTemplateFieldV9, # noqa: E501 - count_from=lambda pkt: pkt.fieldCount)] - - def default_payload_class(self, p): - return conf.padding_layer - - -class NetflowFlowsetV9(Packet): - name = "Netflow FlowSet V9/10" - fields_desc = [ShortField("flowSetID", 0), - FieldLenField("length", None, length_of="templates", - adjust=lambda pkt, x:x + 4), - PacketListField("templates", [], NetflowTemplateV9, - length_from=lambda pkt: pkt.length - 4)] - - -class _CustomStrFixedLenField(StrFixedLenField): - def i2repr(self, pkt, v): - return repr(v) - - -def _GenNetflowRecordV9(cls, lengths_list): - """Internal function used to generate the Records from - their template. - """ - _fields_desc = [] - for j, k in lengths_list: - _f_data = NetflowV9TemplateFieldDecoders.get(k, None) - _f_type, _f_args = ( - _f_data if isinstance(_f_data, tuple) else (_f_data, []) - ) - _f_kwargs = {} - if _f_type: - if issubclass(_f_type, _AdjustableNetflowField): - _f_kwargs["length"] = j - _fields_desc.append( - _f_type( - NetflowV910TemplateFieldTypes.get(k, "unknown_data"), - 0, *_f_args, **_f_kwargs - ) - ) - else: - _fields_desc.append( - _CustomStrFixedLenField( - NetflowV910TemplateFieldTypes.get(k, "unknown_data"), - b"", length=j - ) - ) - - # This will act exactly like a NetflowRecordV9, but has custom fields - class NetflowRecordV9I(cls): - fields_desc = _fields_desc - match_subclass = True - NetflowRecordV9I.name = cls.name - NetflowRecordV9I.__name__ = cls.__name__ - return NetflowRecordV9I - - -class NetflowRecordV9(Packet): - name = "Netflow DataFlowset Record V9/10" - fields_desc = [StrField("fieldValue", "")] - - def default_payload_class(self, p): - return conf.padding_layer - - -class NetflowDataflowsetV9(Packet): - name = "Netflow DataFlowSet V9/10" - fields_desc = [ShortField("templateID", 255), - FieldLenField("length", None, length_of="records", - adjust=lambda pkt, x: x + 4 + (-x % 4)), - PadField( - PacketListField( - "records", [], - NetflowRecordV9, - length_from=lambda pkt: pkt.length - 4 - ), 4, padwith=b"\x00")] - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt: - # https://tools.ietf.org/html/rfc5655#appendix-B.1.2 - # NetflowV9 - if _pkt[:2] == b"\x00\x00": - return NetflowFlowsetV9 - if _pkt[:2] == b"\x00\x01": - return NetflowOptionsFlowsetV9 - # IPFix - if _pkt[:2] == b"\x00\x02": - return NetflowFlowsetV9 - if _pkt[:2] == b"\x00\x03": - return NetflowOptionsFlowset10 - return cls - - -def _netflowv9_defragment_packet(pkt, definitions, definitions_opts, ignored): - """Used internally to process a single packet during defragmenting""" - # Dataflowset definitions - if NetflowFlowsetV9 in pkt: - current = pkt - while NetflowFlowsetV9 in current: - current = current[NetflowFlowsetV9] - for ntv9 in current.templates: - llist = [] - for tmpl in ntv9.template_fields: - llist.append((tmpl.fieldLength, tmpl.fieldType)) - if llist: - tot_len = sum(x[0] for x in llist) - cls = _GenNetflowRecordV9(NetflowRecordV9, llist) - definitions[ntv9.templateID] = (tot_len, cls) - current = current.payload - # Options definitions - if NetflowOptionsFlowsetV9 in pkt: - current = pkt - while NetflowOptionsFlowsetV9 in current: - current = current[NetflowOptionsFlowsetV9] - # Load scopes - llist = [] - for scope in current.scopes: - llist.append(( - scope.scopeFieldlength, - scope.scopeFieldType - )) - scope_tot_len = sum(x[0] for x in llist) - scope_cls = _GenNetflowRecordV9( - NetflowOptionsRecordScopeV9, - llist - ) - # Load options - llist = [] - for opt in current.options: - llist.append(( - opt.optionFieldlength, - opt.optionFieldType - )) - option_tot_len = sum(x[0] for x in llist) - option_cls = _GenNetflowRecordV9( - NetflowOptionsRecordOptionV9, - llist - ) - # Storage - definitions_opts[current.templateID] = ( - scope_tot_len, scope_cls, - option_tot_len, option_cls - ) - current = current.payload - # Dissect flowsets - if NetflowDataflowsetV9 in pkt: - datafl = pkt[NetflowDataflowsetV9] - tid = datafl.templateID - if tid not in definitions and tid not in definitions_opts: - ignored.add(tid) - return - # All data is stored in one record, awaiting to be split - # If fieldValue is available, the record has not been - # defragmented: pop it - try: - data = datafl.records[0].fieldValue - datafl.records.pop(0) - except (IndexError, AttributeError): - return - res = [] - # Flowset record - # Now, according to the flow/option data, - # let's re-dissect NetflowDataflowsetV9 - if tid in definitions: - tot_len, cls = definitions[tid] - while len(data) >= tot_len: - res.append(cls(data[:tot_len])) - data = data[tot_len:] - # Inject dissected data - datafl.records = res - datafl.do_dissect_payload(data) - # Options - elif tid in definitions_opts: - (scope_len, scope_cls, - option_len, option_cls) = definitions_opts[tid] - # Dissect scopes - if scope_len: - res.append(scope_cls(data[:scope_len])) - if option_len: - res.append( - option_cls(data[scope_len:scope_len + option_len]) - ) - if len(data) > scope_len + option_len: - res.append( - conf.padding_layer(data[scope_len + option_len:]) - ) - # Inject dissected data - datafl.records = res - datafl.name = "Netflow DataFlowSet V9/10 - OPTIONS" - - -def netflowv9_defragment(plist, verb=1): - """Process all NetflowV9/10 Packets to match IDs of the DataFlowsets - with the Headers - - params: - - plist: the list of mixed NetflowV9/10 packets. - - verb: verbose print (0/1) - """ - if not isinstance(plist, (PacketList, list)): - plist = [plist] - # We need the whole packet to be dissected to access field def in - # NetflowFlowsetV9 or NetflowOptionsFlowsetV9/10 - definitions = {} - definitions_opts = {} - ignored = set() - # Iterate through initial list - for pkt in plist: - _netflowv9_defragment_packet(pkt, - definitions, - definitions_opts, - ignored) - if conf.verb >= 1 and ignored: - warning("Ignored templateIDs (missing): %s" % list(ignored)) - return plist - - -def ipfix_defragment(*args, **kwargs): - """Alias for netflowv9_defragment""" - return netflowv9_defragment(*args, **kwargs) - - -class NetflowSession(IPSession): - """Session used to defragment NetflowV9/10 packets on the flow. - See help(scapy.layers.netflow) for more infos. - """ - def __init__(self, *args): - IPSession.__init__(self, *args) - self.definitions = {} - self.definitions_opts = {} - self.ignored = set() - - def _process_packet(self, pkt): - _netflowv9_defragment_packet(pkt, - self.definitions, - self.definitions_opts, - self.ignored) - return pkt - - def on_packet_received(self, pkt): - # First, defragment IP if necessary - pkt = self._ip_process_packet(pkt) - # Now handle NetflowV9 defragmentation - pkt = self._process_packet(pkt) - DefaultSession.on_packet_received(self, pkt) - - -class NetflowOptionsRecordScopeV9(NetflowRecordV9): - name = "Netflow Options Template Record V9/10 - Scope" - - -class NetflowOptionsRecordOptionV9(NetflowRecordV9): - name = "Netflow Options Template Record V9/10 - Option" - - -# Aka Set -class NetflowOptionsFlowsetOptionV9(Packet): - name = "Netflow Options Template FlowSet V9/10 - Option" - fields_desc = [ShortEnumField("optionFieldType", None, - NetflowV910TemplateFieldTypes), - ShortField("optionFieldlength", 0)] - - def default_payload_class(self, p): - return conf.padding_layer - - -# Aka Set -class NetflowOptionsFlowsetScopeV9(Packet): - name = "Netflow Options Template FlowSet V9/10 - Scope" - fields_desc = [ShortEnumField("scopeFieldType", None, ScopeFieldTypes), - ShortField("scopeFieldlength", 0)] - - def default_payload_class(self, p): - return conf.padding_layer - - -class NetflowOptionsFlowsetV9(Packet): - name = "Netflow Options Template FlowSet V9" - fields_desc = [ShortField("flowSetID", 1), - ShortField("length", None), - ShortField("templateID", 255), - FieldLenField("option_scope_length", None, - length_of="scopes"), - FieldLenField("option_field_length", None, - length_of="options"), - # We can't use PadField as we have 2 PacketListField - PacketListField( - "scopes", [], - NetflowOptionsFlowsetScopeV9, - length_from=lambda pkt: pkt.option_scope_length), - PacketListField( - "options", [], - NetflowOptionsFlowsetOptionV9, - length_from=lambda pkt: pkt.option_field_length)] - - def extract_padding(self, s): - if self.length is None: - return s, "" - # Calc pad length - pad_len = self.length - self.option_scope_length - \ - self.option_field_length - 10 - return s[pad_len:], s[:pad_len] - - def default_payload_class(self, p): - return conf.padding_layer - - def post_build(self, pkt, pay): - # Padding 4-bytes with b"\x00" - pkt += (-len(pkt) % 4) * b"\x00" - if self.length is None: - pkt = pkt[:2] + struct.pack("!H", len(pkt)) + pkt[4:] - return pkt + pay - - -# https://tools.ietf.org/html/rfc5101#section-3.4.2.2 -class NetflowOptionsFlowset10(NetflowOptionsFlowsetV9): - """Netflow V10 (IPFix) Options Template FlowSet""" - name = "Netflow V10 (IPFix) Options Template FlowSet" - fields_desc = [ShortField("flowSetID", 3), - ShortField("length", None), - ShortField("templateID", 255), - # Slightly different counting than in its NetflowV9 - # counterpart: we count the total, and among them which - # ones are scopes. Also, it's count, not length - FieldLenField("field_count", None, - count_of="options", - adjust=lambda pkt, x: ( - x + pkt.get_field( - "scope_field_count").i2m(pkt, None))), - FieldLenField("scope_field_count", None, - count_of="scopes"), - # We can't use PadField as we have 2 PacketListField - PacketListField( - "scopes", [], - NetflowOptionsFlowsetScopeV9, - count_from=lambda pkt: pkt.scope_field_count), - PacketListField( - "options", [], - NetflowOptionsFlowsetOptionV9, - count_from=lambda pkt: ( - pkt.field_count - pkt.scope_field_count - ))] - - def extract_padding(self, s): - if self.length is None: - return s, "" - # Calc pad length - pad_len = self.length - (self.scope_field_count * 4) - 10 - return s[pad_len:], s[:pad_len] - - -bind_layers(NetflowHeader, NetflowHeaderV9, version=9) -bind_layers(NetflowHeaderV9, NetflowDataflowsetV9) -bind_layers(NetflowDataflowsetV9, NetflowDataflowsetV9) -bind_layers(NetflowOptionsFlowsetV9, NetflowDataflowsetV9) -bind_layers(NetflowFlowsetV9, NetflowDataflowsetV9) - -# Apart from the first header, IPFix and NetflowV9 have the same format -# (except the Options Template) -# https://tools.ietf.org/html/rfc5655#appendix-B.1.2 -bind_layers(NetflowHeader, NetflowHeaderV10, version=10) -bind_layers(NetflowHeaderV10, NetflowDataflowsetV9) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/ntp.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/ntp.py deleted file mode 100644 index a294b606b3..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/ntp.py +++ /dev/null @@ -1,1834 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -NTP (Network Time Protocol). -References : RFC 5905, RC 1305, ntpd source code -""" - -from __future__ import absolute_import -import struct -import time -import datetime - -from scapy.packet import Packet, bind_layers -from scapy.fields import BitField, BitEnumField, ByteField, ByteEnumField, \ - XByteField, SignedByteField, FlagsField, ShortField, LEShortField, \ - IntField, LEIntField, FixedPointField, IPField, StrField, \ - StrFixedLenField, StrFixedLenEnumField, XStrFixedLenField, PacketField, \ - PacketLenField, PacketListField, FieldListField, ConditionalField, \ - PadField -from scapy.layers.inet6 import IP6Field -from scapy.layers.inet import UDP -from scapy.utils import issubtype, lhex -from scapy.compat import orb -from scapy.config import conf -import scapy.modules.six as six -from scapy.modules.six.moves import range - - -############################################################################# -# Constants -############################################################################# - -_NTP_AUTH_MD5_MIN_SIZE = 68 -_NTP_EXT_MIN_SIZE = 16 -_NTP_HDR_WITH_EXT_MIN_SIZE = _NTP_AUTH_MD5_MIN_SIZE + _NTP_EXT_MIN_SIZE -_NTP_AUTH_MD5_TAIL_SIZE = 20 -_NTP_AUTH_MD5_DGST_SIZE = 16 -_NTP_PRIVATE_PACKET_MIN_SIZE = 8 - -# ntpd "Private" messages are the shortest -_NTP_PACKET_MIN_SIZE = _NTP_PRIVATE_PACKET_MIN_SIZE - -_NTP_PRIVATE_REQ_PKT_TAIL_LEN = 28 - -# seconds between 01-01-1900 and 01-01-1970 -_NTP_BASETIME = 2208988800 - -# include/ntp.h -_NTP_SHIFT = 8 -_NTP_HASH_SIZE = 128 - - -############################################################################# -# Fields and utilities -############################################################################# - -class XLEShortField(LEShortField): - """ - XShortField which value is encoded in little endian. - """ - - def i2repr(self, pkt, x): - return lhex(self.i2h(pkt, x)) - - -class TimeStampField(FixedPointField): - """ - This field handles the timestamp fields in the NTP header. - """ - - 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)) # noqa: E501 - - def any2i(self, pkt, val): - if isinstance(val, six.string_types): - val = int(time.mktime(time.strptime(val))) + _NTP_BASETIME - elif isinstance(val, datetime.datetime): - val = int(val.strftime("%s")) + _NTP_BASETIME - 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) - - -############################################################################# -# NTP -############################################################################# - -# RFC 5905 / Section 7.3 -_leap_indicator = { - 0: "no warning", - 1: "last minute of the day has 61 seconds", - 2: "last minute of the day has 59 seconds", - 3: "unknown (clock unsynchronized)" -} - - -# RFC 5905 / Section 7.3 -_ntp_modes = { - 0: "reserved", - 1: "symmetric active", - 2: "symmetric passive", - 3: "client", - 4: "server", - 5: "broadcast", - 6: "NTP control message", - 7: "reserved for private use" -} - - -# RFC 5905 / Section 7.3 -_reference_identifiers = { - "GOES": "Geosynchronous Orbit Environment Satellite", - "GPS ": "Global Position System", - "GAL ": "Galileo Positioning System", - "PPS ": "Generic pulse-per-second", - "IRIG": "Inter-Range Instrumentation Group", - "WWVB": "LF Radio WWVB Ft. Collins, CO 60 kHz", - "DCF ": "LF Radio DCF77 Mainflingen, DE 77.5 kHz", - "HBG ": "LF Radio HBG Prangins, HB 75 kHz", - "MSF ": "LF Radio MSF Anthorn, UK 60 kHz", - "JJY ": "LF Radio JJY Fukushima, JP 40 kHz, Saga, JP 60 kHz", - "LORC": "MF Radio LORAN C station, 100 kHz", - "TDF ": "MF Radio Allouis, FR 162 kHz", - "CHU ": "HF Radio CHU Ottawa, Ontario", - "WWV ": "HF Radio WWV Ft. Collins, CO", - "WWVH": "HF Radio WWVH Kauai, HI", - "NIST": "NIST telephone modem", - "ACTS": "NIST telephone modem", - "USNO": "USNO telephone modem", - "PTB ": "European telephone modem", -} - - -# RFC 5905 / Section 7.4 -_kiss_codes = { - "ACST": "The association belongs to a unicast server.", - "AUTH": "Server authentication failed.", - "AUTO": "Autokey sequence failed.", - "BCST": "The association belongs to a broadcast server.", - "CRYP": "Cryptographic authentication or identification failed.", - "DENY": "Access denied by remote server.", - "DROP": "Lost peer in symmetric mode.", - "RSTR": "Access denied due to local policy.", - "INIT": "The association has not yet synchronized for the first time.", - "MCST": "The association belongs to a dynamically discovered server.", - "NKEY": "No key found.", - "RATE": "Rate exceeded.", - "RMOT": "Alteration of association from a remote host running ntpdc." -} - - -# Used by _ntp_dispatcher to instantiate the appropriate class -def _ntp_dispatcher(payload): - """ - Returns the right class for a given NTP packet. - """ - # By default, calling NTP() will build a NTP packet as defined in RFC 5905 - # (see the code of NTPHeader). Use NTPHeader for extension fields and MAC. - if payload is None: - return NTPHeader - else: - length = len(payload) - if length >= _NTP_PACKET_MIN_SIZE: - first_byte = orb(payload[0]) - # Extract NTP mode - mode = first_byte & 7 - return {6: NTPControl, 7: NTPPrivate}.get(mode, NTPHeader) - return conf.raw_layer - - -class NTP(Packet): - """ - Base class that allows easier instantiation of a NTP packet from binary - data. - """ - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - """ - Returns the right class for the given data. - """ - - return _ntp_dispatcher(_pkt) - - def pre_dissect(self, s): - """ - Check that the payload is long enough to build a NTP packet. - """ - length = len(s) - if length < _NTP_PACKET_MIN_SIZE: - err = " ({}".format(length) + " is < _NTP_PACKET_MIN_SIZE " - err += "({})).".format(_NTP_PACKET_MIN_SIZE) - raise _NTPInvalidDataException(err) - return s - - # NTPHeader, NTPControl and NTPPrivate are NTP packets. - # This might help, for example when reading a pcap file. - def haslayer(self, cls): - """Specific: NTPHeader().haslayer(NTP) should return True.""" - if cls == "NTP": - if isinstance(self, NTP): - return True - elif issubtype(cls, NTP): - if isinstance(self, cls): - return True - return super(NTP, self).haslayer(cls) - - def getlayer(self, cls, nb=1, _track=None, _subclass=True, **flt): - return super(NTP, self).getlayer(cls, nb=nb, _track=_track, - _subclass=True, **flt) - - def mysummary(self): - return self.sprintf("NTP v%ir,NTP.version%, %NTP.mode%") - - -class _NTPAuthenticatorPaddingField(StrField): - """ - StrField handling the padding that may be found before the - "authenticator" field. - """ - - def getfield(self, pkt, s): - ret = None - remain = s - length = len(s) - - if length > _NTP_AUTH_MD5_TAIL_SIZE: - start = length - _NTP_AUTH_MD5_TAIL_SIZE - ret = s[:start] - remain = s[start:] - return remain, ret - - -class NTPAuthenticator(Packet): - """ - Packet handling the "authenticator" part of a NTP packet, as - defined in RFC 5905. - """ - - name = "Authenticator" - fields_desc = [ - _NTPAuthenticatorPaddingField("padding", ""), - IntField("key_id", 0), - XStrFixedLenField("dgst", "", length_from=lambda x: 16) - ] - - def extract_padding(self, s): - return b"", s - - -class NTPExtension(Packet): - """ - Packet handling a NTPv4 extension. - """ - - ######################################################################### - # - # RFC 7822 - ######################################################################### - # - # 7.5. NTP Extension Field Format - # - # In NTPv3, one or more extension fields can be inserted after the - # header and before the MAC, if a MAC is present. - # - # Other than defining the field format, this document makes no use - # of the field contents. An extension field contains a request or - # response message in the format shown in Figure 14. - # - # 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 - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | Field Type | Length | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # . . - # . Value . - # . . - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | Padding (as needed) | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # - # Figure 14: Extension Field Format - # - # - # All extension fields are zero-padded to a word (four octets) - # boundary. - ######################################################################### - # - - name = "extension" - fields_desc = [ - ShortField("type", 0), - ShortField("len", 0), - PadField(PacketField("value", "", Packet), align=4, padwith=b"\x00") - ] - - -class NTPExtPacketListField(PacketListField): - - """ - PacketListField handling NTPv4 extensions (NTPExtension list). - """ - - def m2i(self, pkt, m): - ret = None - if len(m) >= 16: - ret = NTPExtension(m) - else: - ret = conf.raw_layer(m) - return ret - - def getfield(self, pkt, s): - lst = [] - remain = s - length = len(s) - if length > _NTP_AUTH_MD5_TAIL_SIZE: - end = length - _NTP_AUTH_MD5_TAIL_SIZE - extensions = s[:end] - remain = s[end:] - - extensions_len = len(extensions) - while extensions_len >= 16: - ext_len = struct.unpack("!H", extensions[2:4])[0] - ext_len = min(ext_len, extensions_len) - if ext_len < 1: - ext_len = extensions_len - current = extensions[:ext_len] - extensions = extensions[ext_len:] - current_packet = self.m2i(pkt, current) - lst.append(current_packet) - extensions_len = len(extensions) - - if extensions_len > 0: - lst.append(self.m2i(pkt, extensions)) - - return remain, lst - - -class NTPExtensions(Packet): - """ - Packet handling the NTPv4 extensions and the "MAC part" of the packet. - """ - - ######################################################################### - # - # RFC 5905 / RFC 7822 - ######################################################################### - # - # 7.5. NTP Extension Field Format - # - # In NTPv4, one or more extension fields can be inserted after the - # header and before the MAC, if a MAC is present. - ######################################################################### - # - - name = "NTPv4 extensions" - fields_desc = [ - NTPExtPacketListField("extensions", [], Packet), - PacketField("mac", NTPAuthenticator(), NTPAuthenticator) - ] - - -class NTPHeader(NTP): - - """ - Packet handling the RFC 5905 NTP packet. - """ - - ######################################################################### - # - # RFC 5905 - ######################################################################### - # - # 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 - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # |LI | VN |Mode | Stratum | Poll | Precision | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | Root Delay | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | Root Dispersion | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | Reference ID | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | | - # + Reference Timestamp (64) + - # | | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | | - # + Origin Timestamp (64) + - # | | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | | - # + Receive Timestamp (64) + - # | | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | | - # + Transmit Timestamp (64) + - # | | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | | - # . . - # . Extension Field 1 (variable) . - # . . - # | | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | | - # . . - # . Extension Field 2 (variable) . - # . . - # | | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | Key Identifier | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | | - # | dgst (128) | - # | | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # - # Figure 8: Packet Header Format - ######################################################################### - # - - name = "NTPHeader" - fields_desc = [ - BitEnumField("leap", 0, 2, _leap_indicator), - BitField("version", 4, 3), - BitEnumField("mode", 3, 3, _ntp_modes), - BitField("stratum", 2, 8), - BitField("poll", 0xa, 8), - BitField("precision", 0, 8), - FixedPointField("delay", 0, size=32, frac_bits=16), - FixedPointField("dispersion", 0, size=32, frac_bits=16), - ConditionalField(IPField("id", "127.0.0.1"), lambda p: p.stratum > 1), - ConditionalField( - StrFixedLenEnumField( - "ref_id", - "", - length=4, - enum=_reference_identifiers - ), - lambda p: p.stratum < 2 - ), - TimeStampField("ref", 0), - TimeStampField("orig", None), - TimeStampField("recv", 0), - TimeStampField("sent", None), - ] - - def guess_payload_class(self, payload): - """ - Handles NTPv4 extensions and MAC part (when authentication is used.) - """ - plen = len(payload) - - if plen > _NTP_AUTH_MD5_TAIL_SIZE: - return NTPExtensions - elif plen == _NTP_AUTH_MD5_TAIL_SIZE: - return NTPAuthenticator - - return Packet.guess_payload_class(self, payload) - - -class _NTPInvalidDataException(Exception): - """ - Raised when it is not possible to instantiate a NTP packet with the - given data. - """ - - def __init__(self, details): - Exception.__init__( - self, - "Data does not seem to be a valid NTP message" + details - ) - - -############################################################################## -# Private (mode 7) -############################################################################## - -# Operation codes -_op_codes = { - 0: "CTL_OP_UNSPEC", - 1: "CTL_OP_READSTAT", - 2: "CTL_OP_READVAR", - 3: "CTL_OP_WRITEVAR", - 4: "CTL_OP_READCLOCK", - 5: "CTL_OP_WRITECLOCK", - 6: "CTL_OP_SETTRAP", - 7: "CTL_OP_ASYNCMSG", - 8: "CTL_OP_CONFIGURE", - 9: "CTL_OP_SAVECONFIG", - 10: "CTL_OP_READ_MRU", - 11: "CTL_OP_READ_ORDLIST_A", - 12: "CTL_OP_REQ_NONCE", - 31: "CTL_OP_UNSETTRAP" -} - - -# System status words -_system_statuses = { - 0: "no warning", - 1: "last minute was 61 seconds", - 2: "last minute was 59 seconds", - 3: "alarm condition (clock not synchronized)" -} - - -_clock_sources = { - 0: "unspecified or unknown", - 1: " Calibrated atomic clock", - 2: "VLF (band 4) or LF (band 5) radio", - 3: "HF (band 7) radio", - 4: "UHF (band 9) satellite", - 5: "local net", - 6: "UDP/NTP", - 7: "UDP/TIME", - 8: "eyeball-and-wristwatch", - 9: "telephone modem" -} - - -_system_event_codes = { - 0: "unspecified", - 1: "system restart", - 2: "system or hardware fault", - 3: "system new status word (leap bits or synchronization change)", - 4: "system new synchronization source or stratum (sys.peer or sys.stratum change)", # noqa: E501 - 5: "system clock reset (offset correction exceeds CLOCK.MAX)", - 6: "system invalid time or date", - 7: "system clock exception", -} - - -# Peer status words -_peer_statuses = { - 0: "configured", - 1: "authentication enabled", - 2: "authentication okay", - 3: "reachability okay", - 4: "reserved" -} - - -_peer_selection = { - 0: "rejected", - 1: "passed sanity checks", - 2: "passed correctness checks", - 3: "passed candidate checks", - 4: "passed outlyer checks", - 5: "current synchronization source; max distance exceeded", - 6: "current synchronization source; max distance okay", - 7: "reserved" -} - - -_peer_event_codes = { - 0: "unspecified", - 1: "peer IP error", - 2: "peer authentication failure", - 3: "peer unreachable", - 4: "peer reachable", - 5: "peer clock exception", -} - - -# Clock status words -_clock_statuses = { - 0: "clock operating within nominals", - 1: "reply timeout", - 2: "bad reply format", - 3: "hardware or software fault", - 4: "propagation failure", - 5: "bad date format or value", - 6: "bad time format or value" -} - - -# Error status words -_error_statuses = { - 0: "unspecified", - 1: "authentication failure", - 2: "invalid message length or format", - 3: "invalid opcode", - 4: "unknown association identifier", - 5: "unknown variable name", - 6: "invalid variable value", - 7: "administratively prohibited" -} - - -class NTPStatusPacket(Packet): - """ - Packet handling a non specific status word. - """ - - name = "status" - fields_desc = [ShortField("status", 0)] - - def extract_padding(self, s): - return b"", s - - -class NTPSystemStatusPacket(Packet): - - """ - Packet handling the system status fields. - """ - - name = "system status" - fields_desc = [ - BitEnumField("leap_indicator", 0, 2, _system_statuses), - BitEnumField("clock_source", 0, 6, _clock_sources), - BitField("system_event_counter", 0, 4), - BitEnumField("system_event_code", 0, 4, _system_event_codes), - ] - - def extract_padding(self, s): - return b"", s - - -class NTPPeerStatusPacket(Packet): - """ - Packet handling the peer status fields. - """ - - name = "peer status" - fields_desc = [ - BitField("configured", 0, 1), - BitField("auth_enabled", 0, 1), - BitField("authentic", 0, 1), - BitField("reachability", 0, 1), - BitField("reserved", 0, 1), - BitEnumField("peer_sel", 0, 3, _peer_selection), - BitField("peer_event_counter", 0, 4), - BitEnumField("peer_event_code", 0, 4, _peer_event_codes), - ] - - def extract_padding(self, s): - return b"", s - - -class NTPClockStatusPacket(Packet): - """ - Packet handling the clock status fields. - """ - - name = "clock status" - fields_desc = [ - BitEnumField("clock_status", 0, 8, _clock_statuses), - BitField("code", 0, 8) - ] - - def extract_padding(self, s): - return b"", s - - -class NTPErrorStatusPacket(Packet): - """ - Packet handling the error status fields. - """ - - name = "error status" - fields_desc = [ - BitEnumField("error_code", 0, 8, _error_statuses), - BitField("reserved", 0, 8) - ] - - def extract_padding(self, s): - return b"", s - - -class NTPControlStatusField(PacketField): - """ - This field provides better readability for the "status" field. - """ - - ######################################################################### - # - # RFC 1305 - ######################################################################### - # - # Appendix B.3. Commands // ntpd source code: ntp_control.h - ######################################################################### - # - - def m2i(self, pkt, m): - ret = None - association_id = struct.unpack("!H", m[2:4])[0] - - if pkt.err == 1: - ret = NTPErrorStatusPacket(m) - - # op_code == CTL_OP_READSTAT - elif pkt.op_code == 1: - if association_id != 0: - ret = NTPPeerStatusPacket(m) - else: - ret = NTPSystemStatusPacket(m) - - # op_code == CTL_OP_READVAR - elif pkt.op_code == 2: - if association_id != 0: - ret = NTPPeerStatusPacket(m) - else: - ret = NTPSystemStatusPacket(m) - - # op_code == CTL_OP_WRITEVAR - elif pkt.op_code == 3: - ret = NTPStatusPacket(m) - - # op_code == CTL_OP_READCLOCK or op_code == CTL_OP_WRITECLOCK - elif pkt.op_code == 4 or pkt.op_code == 5: - ret = NTPClockStatusPacket(m) - - else: - ret = NTPStatusPacket(m) - - return ret - - -class NTPPeerStatusDataPacket(Packet): - """ - Packet handling the data field when op_code is CTL_OP_READSTAT - and the association_id field is null. - """ - - name = "data / peer status" - fields_desc = [ - ShortField("association_id", 0), - PacketField("peer_status", NTPPeerStatusPacket(), NTPPeerStatusPacket), - ] - - -class NTPControlDataPacketLenField(PacketLenField): - - """ - PacketField handling the "data" field of NTP control messages. - """ - - def m2i(self, pkt, m): - ret = None - - # op_code == CTL_OP_READSTAT - if pkt.op_code == 1: - if pkt.association_id == 0: - # Data contains association ID and peer status - ret = NTPPeerStatusDataPacket(m) - else: - ret = conf.raw_layer(m) - else: - ret = conf.raw_layer(m) - - return ret - - def getfield(self, pkt, s): - length = self.length_from(pkt) - i = None - if length > 0: - # RFC 1305 - # The maximum number of data octets is 468. - # - # include/ntp_control.h - # u_char data[480 + MAX_MAC_LEN]; /* data + auth */ - # - # Set the minimum length to 480 - 468 - length = max(12, length) - if length % 4: - length += (4 - length % 4) - try: - i = self.m2i(pkt, s[:length]) - except Exception: - if conf.debug_dissector: - raise - i = conf.raw_layer(load=s[:length]) - return s[length:], i - - -class NTPControl(NTP): - """ - Packet handling NTP mode 6 / "Control" messages. - """ - - ######################################################################### - # - # RFC 1305 - ######################################################################### - # - # Appendix B.3. Commands // ntpd source code: ntp_control.h - ######################################################################### - # - - name = "Control message" - fields_desc = [ - BitField("zeros", 0, 2), - BitField("version", 2, 3), - BitField("mode", 6, 3), - BitField("response", 0, 1), - BitField("err", 0, 1), - BitField("more", 0, 1), - BitEnumField("op_code", 0, 5, _op_codes), - ShortField("sequence", 0), - ConditionalField(NTPControlStatusField( - "status_word", "", Packet), lambda p: p.response == 1), - ConditionalField(ShortField("status", 0), lambda p: p.response == 0), - ShortField("association_id", 0), - ShortField("offset", 0), - ShortField("count", None), - NTPControlDataPacketLenField( - "data", "", Packet, length_from=lambda p: p.count), - PacketField("authenticator", "", NTPAuthenticator), - ] - - def post_build(self, p, pay): - if self.count is None: - length = 0 - if self.data: - length = len(self.data) - p = p[:11] + struct.pack("!H", length) + p[13:] - return p + pay - - -############################################################################## -# Private (mode 7) -############################################################################## - -_information_error_codes = { - 0: "INFO_OKAY", - 1: "INFO_ERR_IMPL", - 2: "INFO_ERR_REQ", - 3: "INFO_ERR_FMT", - 4: "INFO_ERR_NODATA", - 7: "INFO_ERR_AUTH" -} - - -_implementations = { - 0: "IMPL_UNIV", - 2: "IMPL_XNTPD_OLD", - 3: "XNTPD" -} - - -_request_codes = { - 0: "REQ_PEER_LIST", - 1: "REQ_PEER_LIST_SUM", - 2: "REQ_PEER_INFO", - 3: "REQ_PEER_STATS", - 4: "REQ_SYS_INFO", - 5: "REQ_SYS_STATS", - 6: "REQ_IO_STATS", - 7: "REQ_MEM_STATS", - 8: "REQ_LOOP_INFO", - 9: "REQ_TIMER_STATS", - 10: "REQ_CONFIG", - 11: "REQ_UNCONFIG", - 12: "REQ_SET_SYS_FLAG", - 13: "REQ_CLR_SYS_FLAG", - 14: "REQ_MONITOR", - 15: "REQ_NOMONITOR", - 16: "REQ_GET_RESTRICT", - 17: "REQ_RESADDFLAGS", - 18: "REQ_RESSUBFLAGS", - 19: "REQ_UNRESTRICT", - 20: "REQ_MON_GETLIST", - 21: "REQ_RESET_STATS", - 22: "REQ_RESET_PEER", - 23: "REQ_REREAD_KEYS", - 24: "REQ_DO_DIRTY_HACK", - 25: "REQ_DONT_DIRTY_HACK", - 26: "REQ_TRUSTKEY", - 27: "REQ_UNTRUSTKEY", - 28: "REQ_AUTHINFO", - 29: "REQ_TRAPS", - 30: "REQ_ADD_TRAP", - 31: "REQ_CLR_TRAP", - 32: "REQ_REQUEST_KEY", - 33: "REQ_CONTROL_KEY", - 34: "REQ_GET_CTLSTATS", - 35: "REQ_GET_LEAPINFO", - 36: "REQ_GET_CLOCKINFO", - 37: "REQ_SET_CLKFUDGE", - 38: "REQ_GET_KERNEL", - 39: "REQ_GET_CLKBUGINFO", - 41: "REQ_SET_PRECISION", - 42: "REQ_MON_GETLIST_1", - 43: "REQ_HOSTNAME_ASSOCID", - 44: "REQ_IF_STATS", - 45: "REQ_IF_RELOAD" -} - - -# Flags in the peer information returns -_peer_flags = [ - "INFO_FLAG_CONFIG", - "INFO_FLAG_SYSPEER", - "INFO_FLAG_BURST", - "INFO_FLAG_REFCLOCK", - "INFO_FLAG_PREFER", - "INFO_FLAG_AUTHENABLE", - "INFO_FLAG_SEL_CANDIDATE", - "INFO_FLAG_SHORTLIST", - "INFO_FLAG_IBURST" -] - - -# Flags in the system information returns -_sys_info_flags = [ - "INFO_FLAG_BCLIENT", - "INFO_FLAG_AUTHENTICATE", - "INFO_FLAG_NTP", - "INFO_FLAG_KERNEL", - "INFO_FLAG_CAL", - "INFO_FLAG_PPS_SYNC", - "INFO_FLAG_MONITOR", - "INFO_FLAG_FILEGEN", -] - - -class NTPInfoPeerList(Packet): - - """ - Used to return raw lists of peers. - """ - name = "info_peer_list" - fields_desc = [ - IPField("addr", "0.0.0.0"), - ShortField("port", 0), - ByteEnumField("hmode", 0, _ntp_modes), - FlagsField("flags", 0, 8, _peer_flags), - IntField("v6_flag", 0), - IntField("unused1", 0), - IP6Field("addr6", "::") - ] - - -class NTPInfoPeerSummary(Packet): - """ - Sort of the info that ntpdc returns by default. - """ - name = "info_peer_summary" - fields_desc = [ - IPField("dstaddr", "0.0.0.0"), - IPField("srcaddr", "0.0.0.0"), - ShortField("srcport", 0), - ByteField("stratum", 0), - ByteField("hpoll", 0), - ByteField("ppoll", 0), - ByteField("reach", 0), - FlagsField("flags", 0, 8, _peer_flags), - ByteField("hmode", _ntp_modes), - FixedPointField("delay", 0, size=32, frac_bits=16), - TimeStampField("offset", 0), - FixedPointField("dispersion", 0, size=32, frac_bits=16), - IntField("v6_flag", 0), - IntField("unused1", 0), - IP6Field("dstaddr6", "::"), - IP6Field("srcaddr6", "::") - ] - - -class NTPInfoPeer(Packet): - """ - Peer information structure. - """ - - name = "info_peer" - fields_desc = [ - IPField("dstaddr", "0.0.0.0"), - IPField("srcaddr", "0.0.0.0"), - ShortField("srcport", 0), - FlagsField("flags", 0, 8, _peer_flags), - ByteField("leap", 0), - ByteEnumField("hmode", 0, _ntp_modes), - ByteField("pmode", 0), - ByteField("stratum", 0), - ByteField("ppoll", 0), - ByteField("hpoll", 0), - SignedByteField("precision", 0), - ByteField("version", 0), - ByteField("unused8", 0), - ByteField("reach", 0), - ByteField("unreach", 0), - XByteField("flash", 0), - ByteField("ttl", 0), - XLEShortField("flash2", 0), - ShortField("associd", 0), - LEIntField("keyid", 0), - IntField("pkeyid", 0), - IPField("refid", 0), - IntField("timer", 0), - FixedPointField("rootdelay", 0, size=32, frac_bits=16), - FixedPointField("rootdispersion", 0, size=32, frac_bits=16), - TimeStampField("reftime", 0), - TimeStampField("org", 0), - TimeStampField("rec", 0), - TimeStampField("xmt", 0), - FieldListField( - "filtdelay", - [0.0 for i in range(0, _NTP_SHIFT)], - FixedPointField("", 0, size=32, frac_bits=16), - count_from=lambda p: _NTP_SHIFT - ), - FieldListField( - "filtoffset", - [0.0 for i in range(0, _NTP_SHIFT)], - TimeStampField("", 0), - count_from=lambda p: _NTP_SHIFT - ), - FieldListField( - "order", - [0 for i in range(0, _NTP_SHIFT)], - ByteField("", 0), - count_from=lambda p: _NTP_SHIFT - ), - FixedPointField("delay", 0, size=32, frac_bits=16), - FixedPointField("dispersion", 0, size=32, frac_bits=16), - TimeStampField("offset", 0), - FixedPointField("selectdisp", 0, size=32, frac_bits=16), - IntField("unused1", 0), - IntField("unused2", 0), - IntField("unused3", 0), - IntField("unused4", 0), - IntField("unused5", 0), - IntField("unused6", 0), - IntField("unused7", 0), - FixedPointField("estbdelay", 0, size=32, frac_bits=16), - IntField("v6_flag", 0), - IntField("unused9", 0), - IP6Field("dstaddr6", "::"), - IP6Field("srcaddr6", "::"), - ] - - -class NTPInfoPeerStats(Packet): - """ - Peer statistics structure. - """ - - name = "info_peer_stats" - fields_desc = [ - IPField("dstaddr", "0.0.0.0"), - IPField("srcaddr", "0.0.0.0"), - ShortField("srcport", 0), - FlagsField("flags", 0, 16, _peer_flags), - IntField("timereset", 0), - IntField("timereceived", 0), - IntField("timetosend", 0), - IntField("timereachable", 0), - IntField("sent", 0), - IntField("unused1", 0), - IntField("processed", 0), - IntField("unused2", 0), - IntField("badauth", 0), - IntField("bogusorg", 0), - IntField("oldpkt", 0), - IntField("unused3", 0), - IntField("unused4", 0), - IntField("seldisp", 0), - IntField("selbroken", 0), - IntField("unused5", 0), - ByteField("candidate", 0), - ByteField("unused6", 0), - ByteField("unused7", 0), - ByteField("unused8", 0), - IntField("v6_flag", 0), - IntField("unused9", 0), - IP6Field("dstaddr6", "::"), - IP6Field("srcaddr6", "::"), - ] - - -class NTPInfoLoop(Packet): - """ - Loop filter variables. - """ - - name = "info_loop" - fields_desc = [ - TimeStampField("last_offset", 0), - TimeStampField("drift_comp", 0), - IntField("compliance", 0), - IntField("watchdog_timer", 0) - ] - - -class NTPInfoSys(Packet): - """ - System info. Mostly the sys.* variables, plus a few unique to - the implementation. - """ - - name = "info_sys" - fields_desc = [ - IPField("peer", "0.0.0.0"), - ByteField("peer_mode", 0), - ByteField("leap", 0), - ByteField("stratum", 0), - ByteField("precision", 0), - FixedPointField("rootdelay", 0, size=32, frac_bits=16), - FixedPointField("rootdispersion", 0, size=32, frac_bits=16), - IPField("refid", 0), - TimeStampField("reftime", 0), - IntField("poll", 0), - FlagsField("flags", 0, 8, _sys_info_flags), - ByteField("unused1", 0), - ByteField("unused2", 0), - ByteField("unused3", 0), - FixedPointField("bdelay", 0, size=32, frac_bits=16), - FixedPointField("frequency", 0, size=32, frac_bits=16), - TimeStampField("authdelay", 0), - FixedPointField("stability", 0, size=32, frac_bits=16), - IntField("v6_flag", 0), - IntField("unused4", 0), - IP6Field("peer6", "::") - ] - - -class NTPInfoSysStats(Packet): - """ - System stats. These are collected in the protocol module. - """ - - name = "info_sys_stats" - fields_desc = [ - IntField("timeup", 0), - IntField("timereset", 0), - IntField("denied", 0), - IntField("oldversionpkt", 0), - IntField("newversionpkt", 0), - IntField("unknownversion", 0), - IntField("badlength", 0), - IntField("processed", 0), - IntField("badauth", 0), - IntField("received", 0), - IntField("limitrejected", 0) - ] - - -class NTPInfoMemStats(Packet): - """ - Peer memory statistics. - """ - - name = "info_mem_stats" - fields_desc = [ - IntField("timereset", 0), - ShortField("totalpeermem", 0), - ShortField("freepeermem", 0), - IntField("findpeer_calls", 0), - IntField("allocations", 0), - IntField("demobilizations", 0), - FieldListField( - "hashcount", - [0.0 for i in range(0, _NTP_HASH_SIZE)], - ByteField("", 0), - count_from=lambda p: _NTP_HASH_SIZE - ) - ] - - -class NTPInfoIOStats(Packet): - """ - I/O statistics. - """ - - name = "info_io_stats" - fields_desc = [ - IntField("timereset", 0), - ShortField("totalrecvbufs", 0), - ShortField("freerecvbufs", 0), - ShortField("fullrecvbufs", 0), - ShortField("lowwater", 0), - IntField("dropped", 0), - IntField("ignored", 0), - IntField("received", 0), - IntField("sent", 0), - IntField("notsent", 0), - IntField("interrupts", 0), - IntField("int_received", 0) - ] - - -class NTPInfoTimerStats(Packet): - """ - Timer stats. - """ - - name = "info_timer_stats" - fields_desc = [ - IntField("timereset", 0), - IntField("alarms", 0), - IntField("overflows", 0), - IntField("xmtcalls", 0), - ] - - -_conf_peer_flags = [ - "CONF_FLAG_AUTHENABLE", - "CONF_FLAG_PREFER", - "CONF_FLAG_BURST", - "CONF_FLAG_IBURST", - "CONF_FLAG_NOSELECT", - "CONF_FLAG_SKEY" -] - - -class NTPConfPeer(Packet): - """ - Structure for passing peer configuration information. - """ - - name = "conf_peer" - fields_desc = [ - IPField("peeraddr", "0.0.0.0"), - ByteField("hmode", 0), - ByteField("version", 0), - ByteField("minpoll", 0), - ByteField("maxpoll", 0), - FlagsField("flags", 0, 8, _conf_peer_flags), - ByteField("ttl", 0), - ShortField("unused1", 0), - IntField("keyid", 0), - StrFixedLenField("keystr", "", length=128), - IntField("v6_flag", 0), - IntField("unused2", 0), - IP6Field("peeraddr6", "::") - ] - - -class NTPConfUnpeer(Packet): - """ - Structure for passing peer deletion information. - """ - - name = "conf_unpeer" - fields_desc = [ - IPField("peeraddr", "0.0.0.0"), - IntField("v6_flag", 0), - IP6Field("peeraddr6", "::") - ] - - -_restrict_flags = [ - "RES_IGNORE", - "RES_DONTSERVE", - "RES_DONTTRUST", - "RES_VERSION", - "RES_NOPEER", - "RES_LIMITED", - "RES_NOQUERY", - "RES_NOMODIFY", - "RES_NOTRAP", - "RES_LPTRAP", - "RES_KOD", - "RES_MSSNTP", - "RES_FLAKE", - "RES_NOMRULIST", -] - - -class NTPConfRestrict(Packet): - """ - Structure used for specifying restrict entries. - """ - - name = "conf_restrict" - fields_desc = [ - IPField("addr", "0.0.0.0"), - IPField("mask", "0.0.0.0"), - FlagsField("flags", 0, 16, _restrict_flags), - ShortField("m_flags", 0), - IntField("v6_flag", 0), - IP6Field("addr6", "::"), - IP6Field("mask6", "::") - ] - - -class NTPInfoKernel(Packet): - """ - Structure used for returning kernel pll/PPS information - """ - - name = "info_kernel" - fields_desc = [ - IntField("offset", 0), - IntField("freq", 0), - IntField("maxerror", 0), - IntField("esterror", 0), - ShortField("status", 0), - ShortField("shift", 0), - IntField("constant", 0), - IntField("precision", 0), - IntField("tolerance", 0), - IntField("ppsfreq", 0), - IntField("jitter", 0), - IntField("stabil", 0), - IntField("jitcnt", 0), - IntField("calcnt", 0), - IntField("errcnt", 0), - IntField("stbcnt", 0), - ] - - -class NTPInfoIfStatsIPv4(Packet): - """ - Interface statistics. - """ - - name = "info_if_stats" - fields_desc = [ - PadField(IPField("unaddr", "0.0.0.0"), 16, padwith=b"\x00"), - PadField(IPField("unbcast", "0.0.0.0"), 16, padwith=b"\x00"), - PadField(IPField("unmask", "0.0.0.0"), 16, padwith=b"\x00"), - IntField("v6_flag", 0), - StrFixedLenField("ifname", "", length=32), - IntField("flags", 0), - IntField("last_ttl", 0), - IntField("num_mcast", 0), - IntField("received", 0), - IntField("sent", 0), - IntField("notsent", 0), - IntField("uptime", 0), - IntField("scopeid", 0), - IntField("ifindex", 0), - IntField("ifnum", 0), - IntField("peercnt", 0), - ShortField("family", 0), - ByteField("ignore_packets", 0), - ByteField("action", 0), - IntField("_filler0", 0) - ] - - -class NTPInfoIfStatsIPv6(Packet): - """ - Interface statistics. - """ - - name = "info_if_stats" - fields_desc = [ - IP6Field("unaddr", "::"), - IP6Field("unbcast", "::"), - IP6Field("unmask", "::"), - IntField("v6_flag", 0), - StrFixedLenField("ifname", "", length=32), - IntField("flags", 0), - IntField("last_ttl", 0), - IntField("num_mcast", 0), - IntField("received", 0), - IntField("sent", 0), - IntField("notsent", 0), - IntField("uptime", 0), - IntField("scopeid", 0), - IntField("ifindex", 0), - IntField("ifnum", 0), - IntField("peercnt", 0), - ShortField("family", 0), - ByteField("ignore_packets", 0), - ByteField("action", 0), - IntField("_filler0", 0) - ] - - -class NTPInfoMonitor1(Packet): - """ - Structure used for returning monitor data. - """ - - name = "InfoMonitor1" - fields_desc = [ - IntField("lasttime", 0), - IntField("firsttime", 0), - IntField("lastdrop", 0), - IntField("count", 0), - IPField("addr", "0.0.0.0"), - IPField("daddr", "0.0.0.0"), - IntField("flags", 0), - ShortField("port", 0), - ByteField("mode", 0), - ByteField("version", 0), - IntField("v6_flag", 0), - IntField("unused1", 0), - IP6Field("addr6", "::"), - IP6Field("daddr6", "::") - ] - - -class NTPInfoAuth(Packet): - """ - Structure used to return information concerning the authentication module. - """ - - name = "info_auth" - fields_desc = [ - IntField("timereset", 0), - IntField("numkeys", 0), - IntField("numfreekeys", 0), - IntField("keylookups", 0), - IntField("keynotfound", 0), - IntField("encryptions", 0), - IntField("decryptions", 0), - IntField("expired", 0), - IntField("keyuncached", 0), - ] - - -class NTPConfTrap(Packet): - """ - Structure used to pass add/clear trap information to the client - """ - - name = "conf_trap" - fields_desc = [ - IPField("local_address", "0.0.0.0"), - IPField("trap_address", "0.0.0.0"), - ShortField("trap_port", 0), - ShortField("unused", 0), - IntField("v6_flag", 0), - IP6Field("local_address6", "::"), - IP6Field("trap_address6", "::"), - ] - - -class NTPInfoControl(Packet): - """ - Structure used to return statistics from the control module. - """ - - name = "info_control" - fields_desc = [ - IntField("ctltimereset", 0), - IntField("numctlreq", 0), - IntField("numctlbadpkts", 0), - IntField("numctlresponses", 0), - IntField("numctlfrags", 0), - IntField("numctlerrors", 0), - IntField("numctltooshort", 0), - IntField("numctlinputresp", 0), - IntField("numctlinputfrag", 0), - IntField("numctlinputerr", 0), - IntField("numctlbadoffset", 0), - IntField("numctlbadversion", 0), - IntField("numctldatatooshort", 0), - IntField("numctlbadop", 0), - IntField("numasyncmsgs", 0), - ] - - -# ntp_request.h -_ntpd_private_errors = { - 0: "no error", - 1: "incompatible implementation number", - 2: "unimplemented request code", - 3: "format error (wrong data items, data size, packet size etc.)", - 4: "no data available (e.g. request for details on unknown peer)", - 5: "I don\"t know", - 6: "I don\"t know", - 7: "authentication failure (i.e. permission denied)", -} - - -# dict mapping request codes to the right response data class -_private_data_objects = { - 0: NTPInfoPeerList, # "REQ_PEER_LIST", - 1: NTPInfoPeerSummary, # "REQ_PEER_LIST_SUM", - 2: NTPInfoPeer, # "REQ_PEER_INFO", - 3: NTPInfoPeerStats, # "REQ_PEER_STATS", - 4: NTPInfoSys, # "REQ_SYS_INFO", - 5: NTPInfoSysStats, # "REQ_SYS_STATS", - 6: NTPInfoIOStats, # "REQ_IO_STATS", - 7: NTPInfoMemStats, # "REQ_MEM_STATS", - 8: NTPInfoLoop, # "REQ_LOOP_INFO", - 9: NTPInfoTimerStats, # "REQ_TIMER_STATS", - 10: NTPConfPeer, # "REQ_CONFIG", - 11: NTPConfUnpeer, # "REQ_UNCONFIG", - 28: NTPInfoAuth, # "REQ_AUTHINFO", - 30: NTPConfTrap, # "REQ_ADD_TRAP", - 34: NTPInfoControl, # "REQ_GET_CTLSTATS", - 38: NTPInfoKernel, # "REQ_GET_KERNEL", - 42: NTPInfoMonitor1, # "REQ_MON_GETLIST_1", -} - - -class NTPPrivateRespPacketListField(PacketListField): - """ - PacketListField handling the response data. - """ - - def m2i(self, pkt, s): - ret = None - - # info_if_stats - if pkt.request_code == 44 or pkt.request_code == 45: - is_v6 = struct.unpack("!I", s[48:52])[0] - ret = NTPInfoIfStatsIPv6(s) if is_v6 else NTPInfoIfStatsIPv4(s) - else: - ret = _private_data_objects.get(pkt.request_code, conf.raw_layer)(s) # noqa: E501 - - return ret - - def getfield(self, pkt, s): - lst = [] - remain = s - length = pkt.data_item_size - if length > 0: - item_counter = 0 - # Response payloads can be placed in several packets - while len(remain) >= pkt.data_item_size and item_counter < pkt.nb_items: # noqa: E501 - current = remain[:length] - remain = remain[length:] - current_packet = self.m2i(pkt, current) - lst.append(current_packet) - item_counter += 1 - - return remain, lst - - -class NTPPrivateReqPacket(Packet): - """ - Packet handling request data. - """ - - name = "request data" - fields_desc = [StrField("req_data", "")] - - -_request_codes = { - 0: "REQ_PEER_LIST", - 1: "REQ_PEER_LIST_SUM", - 2: "REQ_PEER_INFO", - 3: "REQ_PEER_STATS", - 4: "REQ_SYS_INFO", - 5: "REQ_SYS_STATS", - 6: "REQ_IO_STATS", - 7: "REQ_MEM_STATS", - 8: "REQ_LOOP_INFO", - 9: "REQ_TIMER_STATS", - 10: "REQ_CONFIG", - 11: "REQ_UNCONFIG", - 12: "REQ_SET_SYS_FLAG", - 13: "REQ_CLR_SYS_FLAG", - 14: "REQ_MONITOR", - 15: "REQ_NOMONITOR", - 16: "REQ_GET_RESTRICT", - 17: "REQ_RESADDFLAGS", - 18: "REQ_RESSUBFLAGS", - 19: "REQ_UNRESTRICT", - 20: "REQ_MON_GETLIST", - 21: "REQ_RESET_STATS", - 22: "REQ_RESET_PEER", - 23: "REQ_REREAD_KEYS", - 24: "REQ_DO_DIRTY_HACK", - 25: "REQ_DONT_DIRTY_HACK", - 26: "REQ_TRUSTKEY", - 27: "REQ_UNTRUSTKEY", - 28: "REQ_AUTHINFO", - 29: "REQ_TRAPS", - 30: "REQ_ADD_TRAP", - 31: "REQ_CLR_TRAP", - 32: "REQ_REQUEST_KEY", - 33: "REQ_CONTROL_KEY", - 34: "REQ_GET_CTLSTATS", - 35: "REQ_GET_LEAPINFO", - 36: "REQ_GET_CLOCKINFO", - 37: "REQ_SET_CLKFUDGE", - 38: "REQ_GET_KERNEL", - 39: "REQ_GET_CLKBUGINFO", - 41: "REQ_SET_PRECISION", - 42: "REQ_MON_GETLIST_1", - 43: "REQ_HOSTNAME_ASSOCID", - 44: "REQ_IF_STATS", - 45: "REQ_IF_RELOAD" -} - - -class NTPPrivateReqPacketListField(PacketListField): - """ - Handles specific request packets. - """ - - # See ntpdc/ntpdc.c and ntpdc/ntpdc_ops.c - - def m2i(self, pkt, s): - ret = None - - if pkt.request_code == 2 or pkt.request_code == 3: - # REQ_PEER_INFO (see ntpdc/ntpdc_ops.c: showpeer()) - # REQ_PEER_STATS (for request only) - ret = NTPInfoPeerList(s) - - elif pkt.request_code == 10: - # REQ_CONFIG - ret = NTPConfPeer(s) - - elif pkt.request_code == 11: - # REQ_CONFIG - ret = NTPConfUnpeer(s) - - elif pkt.request_code == 17: - # REQ_RESADDFLAGS - ret = NTPConfRestrict(s) - - elif pkt.request_code == 18: - # REQ_RESSUBFLAGS - ret = NTPConfRestrict(s) - - elif pkt.request_code == 22: - # REQ_RESET_PEER - ret = NTPConfUnpeer(s) - - elif pkt.request_code == 30 or pkt.request_code == 31: - # REQ_ADD_TRAP - ret = NTPConfTrap(s) - - else: - ret = NTPPrivateReqPacket(s) - - return ret - - def getfield(self, pkt, s): - lst = [] - remain = s - length = pkt.data_item_size - if length > 0: - item_counter = 0 - while len(remain) >= pkt.data_item_size * pkt.nb_items and item_counter < pkt.nb_items: # noqa: E501 - current = remain[:length] - remain = remain[length:] - current_packet = self.m2i(pkt, current) - lst.append(current_packet) - item_counter += 1 - - # If "auth" bit is set, don't forget the padding bytes - if pkt.auth: - padding_end = len(remain) - _NTP_PRIVATE_REQ_PKT_TAIL_LEN - current_packet = conf.raw_layer(remain[:padding_end]) - lst.append(current_packet) - remain = remain[padding_end:] - - return remain, lst - - -class NTPPrivatePktTail(Packet): - """ - include/ntp_request.h - The req_pkt_tail structure is used by ntpd to adjust for different - packet sizes that may arrive. - """ - - name = "req_pkt_tail" - fields_desc = [ - TimeStampField("tstamp", 0), - IntField("key_id", 0), - XStrFixedLenField( - "dgst", "", length_from=lambda x: _NTP_AUTH_MD5_DGST_SIZE) - ] - - -class NTPPrivate(NTP): - """ - Packet handling the private (mode 7) messages. - """ - - ######################################################################### - # ntpd source code: ntp_request.h - ######################################################################### - # - # A mode 7 packet is used exchanging data between an NTP server - # and a client for purposes other than time synchronization, e.g. - # monitoring, statistics gathering and configuration. A mode 7 - # packet has the following format: - # - # 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 - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # |R|M| VN | Mode|A| Sequence | Implementation| Req Code | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | Err | Number of data items | MBZ | Size of data item | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | | - # | Data (Minimum 0 octets, maximum 500 octets) | - # | | - # [...] | - # | | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | Encryption Keyid (when A bit set) | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # | | - # | Message Authentication Code (when A bit set) | - # | | - # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - # - # where the fields are (note that the client sends requests, the server - # responses): - # - # Response Bit: This packet is a response (if clear, packet is a request). - # - # More Bit: Set for all packets but the last in a response which - # requires more than one packet. - # - # Version Number: 2 for current version - # - # Mode: Always 7 - # - # Authenticated bit: If set, this packet is authenticated. - # - # Sequence number: For a multipacket response, contains the sequence - # number of this packet. 0 is the first in the sequence, - # 127 (or less) is the last. The More Bit must be set in - # all packets but the last. - # - # Implementation number: The number of the implementation this request code - # is defined by. An implementation number of zero is used - # for request codes/data formats which all implementations - # agree on. Implementation number 255 is reserved (for - # extensions, in case we run out). - # - # Request code: An implementation-specific code which specifies the - # operation to be (which has been) performed and/or the - # format and semantics of the data included in the packet. - # - # Err: Must be 0 for a request. For a response, holds an error - # code relating to the request. If nonzero, the operation - # requested wasn't performed. - # - # 0 - no error - # 1 - incompatible implementation number - # 2 - unimplemented request code - # 3 - format error (wrong data items, data size, packet size etc.) # noqa: E501 - # 4 - no data available (e.g. request for details on unknown peer) # noqa: E501 - # 5-6 I don"t know - # 7 - authentication failure (i.e. permission denied) - # - # Number of data items: number of data items in packet. 0 to 500 - # - # MBZ: A reserved data field, must be zero in requests and responses. - # - # Size of data item: size of each data item in packet. 0 to 500 - # - # Data: Variable sized area containing request/response data. For - # requests and responses the size in octets must be greater - # than or equal to the product of the number of data items - # and the size of a data item. For requests the data area - # must be exactly 40 octets in length. For responses the - # data area may be any length between 0 and 500 octets - # inclusive. - # - # Message Authentication Code: Same as NTP spec, in definition and function. # noqa: E501 - # May optionally be included in requests which require - # authentication, is never included in responses. - # - # The version number, mode and keyid have the same function and are - # in the same location as a standard NTP packet. The request packet - # is the same size as a standard NTP packet to ease receive buffer - # management, and to allow the same encryption procedure to be used - # both on mode 7 and standard NTP packets. The mac is included when - # it is required that a request be authenticated, the keyid should be - # zero in requests in which the mac is not included. - # - # The data format depends on the implementation number/request code pair - # and whether the packet is a request or a response. The only requirement - # is that data items start in the octet immediately following the size - # word and that data items be concatenated without padding between (i.e. - # if the data area is larger than data_items*size, all padding is at - # the end). Padding is ignored, other than for encryption purposes. - # Implementations using encryption might want to include a time stamp - # or other data in the request packet padding. The key used for requests - # is implementation defined, but key 15 is suggested as a default. - ######################################################################### - # - - name = "Private (mode 7)" - fields_desc = [ - BitField("response", 0, 1), - BitField("more", 0, 1), - BitField("version", 2, 3), - BitField("mode", 0, 3), - BitField("auth", 0, 1), - BitField("seq", 0, 7), - ByteEnumField("implementation", 0, _implementations), - ByteEnumField("request_code", 0, _request_codes), - BitEnumField("err", 0, 4, _ntpd_private_errors), - BitField("nb_items", 0, 12), - BitField("mbz", 0, 4), - BitField("data_item_size", 0, 12), - ConditionalField( - NTPPrivateReqPacketListField( - "req_data", - [], - Packet, - length_from=lambda p: p.data_item_size, - count_from=lambda p: p.nb_items - ), - lambda p: p.response == 0 - ), - # Responses - ConditionalField( - NTPPrivateRespPacketListField( - "data", - [], - Packet, - length_from=lambda p: p.data_item_size, - count_from=lambda p: p.nb_items - ), - lambda p: p.response == 1 - ), - # Responses are not supposed to be authenticated - ConditionalField(PacketField("authenticator", "", NTPPrivatePktTail), - lambda p: p.response == 0 and p.auth == 1), - ] - - -############################################################################## -# Layer bindings -############################################################################## - -bind_layers(UDP, NTP, {"sport": 123}) -bind_layers(UDP, NTP, {"dport": 123}) -bind_layers(UDP, NTP, {"sport": 123, "dport": 123}) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/pflog.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/pflog.py deleted file mode 100644 index 65e3e517c5..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/pflog.py +++ /dev/null @@ -1,66 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -PFLog: OpenBSD PF packet filter logging. -""" - -import socket - -from scapy.data import DLT_PFLOG -from scapy.packet import Packet, bind_layers -from scapy.fields import ByteEnumField, ByteField, IntField, SignedIntField, \ - StrFixedLenField -from scapy.layers.inet import IP -from scapy.config import conf -if conf.ipv6_enabled: - from scapy.layers.inet6 import IPv6 - - -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", b"\x00\x00\x00", 3)] - - def mysummary(self): - return self.sprintf("%PFLog.addrfamily% %PFLog.action% on %PFLog.iface% by rule %PFLog.rulenumber%") # noqa: E501 - - -bind_layers(PFLog, IP, addrfamily=socket.AF_INET) -if conf.ipv6_enabled: - bind_layers(PFLog, IPv6, addrfamily=socket.AF_INET6) - -conf.l2types.register(DLT_PFLOG, PFLog) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/ppi.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/ppi.py deleted file mode 100644 index 3b11a20e6d..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/ppi.py +++ /dev/null @@ -1,96 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Scapy is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# any later version. -# -# Scapy 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. -# -# You should have received a copy of the GNU General Public License -# along with Scapy. If not, see . - -# Original PPI author: -# scapy.contrib.description = CACE Per-Packet Information (PPI) header -# scapy.contrib.status = loads - -""" -CACE Per-Packet Information (PPI) header. - -A method for adding metadata to link-layer packets. - -For example, one can tag an 802.11 packet with GPS co-ordinates of where it -was captured, and include it in the PCAP file. - -New PPI types should: - - * Make their packet a subclass of ``PPI_Element`` - * Call ``bind_layers(PPI_Hdr, ExamplePPI, pfh_type=0xffff)`` - -See ``layers/contrib/ppi_cace.py`` for an example. -""" - -from scapy.config import conf -from scapy.data import DLT_PPI, PPI_TYPES -from scapy.error import warning -from scapy.packet import Packet -from scapy.fields import ByteField, FieldLenField, LEIntField, \ - PacketListField, LEShortEnumField, LenField - - -class PPI_Hdr(Packet): - name = 'PPI Header' - fields_desc = [ - LEShortEnumField('pfh_type', 0, PPI_TYPES), - LenField('pfh_length', None, fmt=' -# This program is published under a GPLv2 license - -""" -PPP (Point to Point Protocol) - -[RFC 1661] -""" - -import struct -from scapy.config import conf -from scapy.data import DLT_PPP, DLT_PPP_SERIAL, DLT_PPP_ETHER, \ - DLT_PPP_WITH_DIR -from scapy.compat import orb -from scapy.packet import Packet, bind_layers -from scapy.layers.eap import EAP -from scapy.layers.l2 import Ether, CookedLinux, GRE_PPTP -from scapy.layers.inet import IP -from scapy.layers.inet6 import IPv6 -from scapy.fields import BitField, ByteEnumField, ByteField, \ - ConditionalField, FieldLenField, IntField, IPField, \ - PacketListField, PacketField, ShortEnumField, ShortField, \ - StrFixedLenField, StrLenField, XByteField, XShortField, XStrLenField -from scapy.modules import six - - -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: - tmp_len = len(p) - 6 - p = p[:4] + struct.pack("!H", tmp_len) + p[6:] - return p - - -# PPPoE Active Discovery Code fields (RFC2516, RFC5578) -class PPPoED(PPPoE): - name = "PPP over Ethernet Discovery" - - code_list = {0x00: "PPP Session Stage", - 0x09: "PPPoE Active Discovery Initiation (PADI)", - 0x07: "PPPoE Active Discovery Offer (PADO)", - 0x0a: "PPPoE Active Discovery Session-Grant (PADG)", - 0x0b: "PPPoE Active Discovery Session-Credit Response (PADC)", - 0x0c: "PPPoE Active Discovery Quality (PADQ)", - 0x19: "PPPoE Active Discovery Request (PADR)", - 0x65: "PPPoE Active Discovery Session-confirmation (PADS)", - 0xa7: "PPPoE Active Discovery Terminate (PADT)"} - - fields_desc = [BitField("version", 1, 4), - BitField("type", 1, 4), - ByteEnumField("code", 0x09, code_list), - XShortField("sessionid", 0x0), - ShortField("len", None)] - - -# PPPoE Tag types (RFC2516, RFC4638, RFC5578) -class PPPoETag(Packet): - name = "PPPoE Tag" - - tag_list = {0x0000: 'End-Of-List', - 0x0101: 'Service-Name', - 0x0102: 'AC-Name', - 0x0103: 'Host-Uniq', - 0x0104: 'AC-Cookie', - 0x0105: 'Vendor-Specific', - 0x0106: 'Credits', - 0x0107: 'Metrics', - 0x0108: 'Sequence Number', - 0x0109: 'Credit Scale Factor', - 0x0110: 'Relay-Session-Id', - 0x0120: 'PPP-Max-Payload', - 0x0201: 'Service-Name-Error', - 0x0202: 'AC-System-Error', - 0x0203: 'Generic-Error'} - - fields_desc = [ - ShortEnumField('tag_type', None, tag_list), - FieldLenField('tag_len', None, length_of='tag_value', fmt='H'), - StrLenField('tag_value', '', length_from=lambda pkt:pkt.tag_len) - ] - - def extract_padding(self, s): - return '', s - - -class PPPoED_Tags(Packet): - name = "PPPoE Tag List" - fields_desc = [PacketListField('tag_list', None, PPPoETag)] - - -_PPP_PROTOCOLS = { - 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)] - - -# LINKTYPE_PPP_WITH_DIR -class DIR_PPP(Packet): - fields_desc = [ByteEnumField("direction", 0, ["received", "sent"])] - - -class PPP(Packet): - name = "PPP Link Layer" - fields_desc = [ShortEnumField("proto", 0x0021, _PPP_PROTOCOLS)] - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt: - first_byte = orb(_pkt[0]) - if first_byte == 0xff: - return HDLC - # See RFC 1661 section 2 - # - if first_byte & 0x01: - return PPP_ - return cls - - -class PPP_(PPP): - fields_desc = [ - ByteEnumField("proto", 0x21, - {k: v for k, v in six.iteritems(_PPP_PROTOCOLS) - if k < 0x100}), - ] - - -_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", - # not implemented, present for completeness - 4: "Mobile-IPv4", - 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 _, val: val + 2), - StrLenField("data", "", length_from=lambda pkt: max(0, pkt.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 = orb(_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 _, val: val + 2), - IPField("data", "0.0.0.0"), - StrLenField("garbage", "", length_from=lambda pkt: pkt.len - 6), - ] - - -class PPP_IPCP_Option_DNS1(PPP_IPCP_Option_IPAddress): - name = "PPP IPCP Option: DNS1 Address" - type = 129 - - -class PPP_IPCP_Option_DNS2(PPP_IPCP_Option_IPAddress): - name = "PPP IPCP Option: DNS2 Address" - type = 131 - - -class PPP_IPCP_Option_NBNS1(PPP_IPCP_Option_IPAddress): - name = "PPP IPCP Option: NBNS1 Address" - type = 130 - - -class PPP_IPCP_Option_NBNS2(PPP_IPCP_Option_IPAddress): - name = "PPP IPCP Option: NBNS2 Address" - type = 132 - - -class PPP_IPCP(Packet): - fields_desc = [ - ByteEnumField("code", 1, _PPP_conftypes), - XByteField("id", 0), - FieldLenField("len", None, fmt="H", length_of="options", - adjust=lambda _, val: val + 4), - PacketListField("options", [], PPP_IPCP_Option, - length_from=lambda pkt: pkt.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 _, val: val + 2), - StrLenField("data", "", length_from=lambda pkt: max(0, pkt.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 = orb(_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 _, val: val + 6), - StrFixedLenField("oui", "", 3), - ByteField("subtype", 0), - StrLenField("data", "", length_from=lambda pkt: pkt.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 _, val: val + 4), - PacketListField("options", [], PPP_ECP_Option, - length_from=lambda pkt: pkt.len - 4), - ] - -# Link Control Protocol (RFC 1661) - - -_PPP_lcptypes = {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"} - - -class PPP_LCP(Packet): - name = "PPP Link Control Protocol" - fields_desc = [ - ByteEnumField("code", 5, _PPP_lcptypes), - XByteField("id", 0), - FieldLenField("len", None, fmt="H", length_of="data", - adjust=lambda _, val: val + 4), - StrLenField("data", "", length_from=lambda pkt: pkt.len - 4), - ] - - def mysummary(self): - return self.sprintf('LCP %code%') - - def extract_padding(self, pay): - return b"", pay - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt: - o = orb(_pkt[0]) - if o in [1, 2, 3, 4]: - return PPP_LCP_Configure - elif o in [5, 6]: - return PPP_LCP_Terminate - elif o == 7: - return PPP_LCP_Code_Reject - elif o == 8: - return PPP_LCP_Protocol_Reject - elif o in [9, 10]: - return PPP_LCP_Echo - elif o == 11: - return PPP_LCP_Discard_Request - else: - return cls - return cls - - -_PPP_lcp_optiontypes = {1: "Maximum-Receive-Unit", - 2: "Async-Control-Character-Map", - 3: "Authentication-protocol", - 4: "Quality-protocol", - 5: "Magic-number", - 7: "Protocol-Field-Compression", - 8: "Address-and-Control-Field-Compression", - 13: "Callback"} - - -class PPP_LCP_Option(Packet): - name = "PPP LCP Option" - fields_desc = [ - ByteEnumField("type", None, _PPP_lcp_optiontypes), - FieldLenField("len", None, fmt="B", length_of="data", - adjust=lambda _, val: val + 2), - StrLenField("data", None, length_from=lambda pkt: pkt.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 = orb(_pkt[0]) - return cls.registered_options.get(o, cls) - return cls - - -class PPP_LCP_MRU_Option(PPP_LCP_Option): - fields_desc = [ByteEnumField("type", 1, _PPP_lcp_optiontypes), - ByteField("len", 4), - ShortField("max_recv_unit", 1500)] - - -_PPP_LCP_auth_protocols = { - 0xc023: "Password authentication protocol", - 0xc223: "Challenge-response authentication protocol", - 0xc227: "PPP Extensible authentication protocol", -} - -_PPP_LCP_CHAP_algorithms = { - 5: "MD5", - 6: "SHA1", - 128: "MS-CHAP", - 129: "MS-CHAP-v2", -} - - -class PPP_LCP_ACCM_Option(PPP_LCP_Option): - fields_desc = [ - ByteEnumField("type", 2, _PPP_lcp_optiontypes), - ByteField("len", 6), - BitField("accm", 0x00000000, 32), - ] - - -def adjust_auth_len(pkt, x): - if pkt.auth_protocol == 0xc223: - return 5 - elif pkt.auth_protocol == 0xc023: - return 4 - else: - return x + 4 - - -class PPP_LCP_Auth_Protocol_Option(PPP_LCP_Option): - fields_desc = [ - ByteEnumField("type", 3, _PPP_lcp_optiontypes), - FieldLenField("len", None, fmt="B", length_of="data", - adjust=adjust_auth_len), - ShortEnumField("auth_protocol", 0xc023, _PPP_LCP_auth_protocols), - ConditionalField( - StrLenField("data", '', length_from=lambda pkt: pkt.len - 4), - lambda pkt: pkt.auth_protocol != 0xc223 - ), - ConditionalField( - ByteEnumField("algorithm", 5, _PPP_LCP_CHAP_algorithms), - lambda pkt: pkt.auth_protocol == 0xc223 - ), - ] - - -_PPP_LCP_quality_protocols = {0xc025: "Link Quality Report"} - - -class PPP_LCP_Quality_Protocol_Option(PPP_LCP_Option): - fields_desc = [ - ByteEnumField("type", 4, _PPP_lcp_optiontypes), - FieldLenField("len", None, fmt="B", length_of="data", - adjust=lambda _, val: val + 4), - ShortEnumField("quality_protocol", 0xc025, _PPP_LCP_quality_protocols), - StrLenField("data", "", length_from=lambda pkt: pkt.len - 4), - ] - - -class PPP_LCP_Magic_Number_Option(PPP_LCP_Option): - fields_desc = [ - ByteEnumField("type", 5, _PPP_lcp_optiontypes), - ByteField("len", 6), - IntField("magic_number", None), - ] - - -_PPP_lcp_callback_operations = { - 0: "Location determined by user authentication", - 1: "Dialing string", - 2: "Location identifier", - 3: "E.164 number", - 4: "Distinguished name", -} - - -class PPP_LCP_Callback_Option(PPP_LCP_Option): - fields_desc = [ - ByteEnumField("type", 13, _PPP_lcp_optiontypes), - FieldLenField("len", None, fmt="B", length_of="message", - adjust=lambda _, val: val + 3), - ByteEnumField("operation", 0, _PPP_lcp_callback_operations), - StrLenField("message", "", length_from=lambda pkt: pkt.len - 3) - ] - - -class PPP_LCP_Configure(PPP_LCP): - fields_desc = [ - ByteEnumField("code", 1, _PPP_lcptypes), - XByteField("id", 0), - FieldLenField("len", None, fmt="H", length_of="options", - adjust=lambda _, val: val + 4), - PacketListField("options", [], PPP_LCP_Option, - length_from=lambda pkt: pkt.len - 4), - ] - - def answers(self, other): - return ( - isinstance(other, PPP_LCP_Configure) and self.code in [2, 3, 4] and - other.code == 1 and other.id == self.id - ) - - -class PPP_LCP_Terminate(PPP_LCP): - - def answers(self, other): - return ( - isinstance(other, PPP_LCP_Terminate) and self.code == 6 and - other.code == 5 and other.id == self.id - ) - - -class PPP_LCP_Code_Reject(PPP_LCP): - fields_desc = [ - ByteEnumField("code", 7, _PPP_lcptypes), - XByteField("id", 0), - FieldLenField("len", None, fmt="H", length_of="rejected_packet", - adjust=lambda _, val: val + 4), - PacketField("rejected_packet", None, PPP_LCP), - ] - - -class PPP_LCP_Protocol_Reject(PPP_LCP): - fields_desc = [ - ByteEnumField("code", 8, _PPP_lcptypes), - XByteField("id", 0), - FieldLenField("len", None, fmt="H", length_of="rejected_information", - adjust=lambda _, val: val + 6), - ShortEnumField("rejected_protocol", None, _PPP_PROTOCOLS), - PacketField("rejected_information", None, Packet), - ] - - -class PPP_LCP_Discard_Request(PPP_LCP): - fields_desc = [ - ByteEnumField("code", 11, _PPP_lcptypes), - XByteField("id", 0), - FieldLenField("len", None, fmt="H", length_of="data", - adjust=lambda _, val: val + 8), - IntField("magic_number", None), - StrLenField("data", "", length_from=lambda pkt: pkt.len - 8), - ] - - -class PPP_LCP_Echo(PPP_LCP_Discard_Request): - code = 9 - - def answers(self, other): - return ( - isinstance(other, PPP_LCP_Echo) and self.code == 10 and - other.code == 9 and self.id == other.id - ) - - -# Password authentication protocol (RFC 1334) - - -_PPP_paptypes = {1: "Authenticate-Request", - 2: "Authenticate-Ack", - 3: "Authenticate-Nak"} - - -class PPP_PAP(Packet): - name = "PPP Password Authentication Protocol" - fields_desc = [ - ByteEnumField("code", 1, _PPP_paptypes), - XByteField("id", 0), - FieldLenField("len", None, fmt="!H", length_of="data", - adjust=lambda _, val: val + 4), - StrLenField("data", "", length_from=lambda pkt: pkt.len - 4), - ] - - @classmethod - def dispatch_hook(cls, _pkt=None, *_, **kargs): - code = None - if _pkt: - code = orb(_pkt[0]) - elif "code" in kargs: - code = kargs["code"] - if isinstance(code, six.string_types): - code = cls.fields_desc[0].s2i[code] - - if code == 1: - return PPP_PAP_Request - elif code in [2, 3]: - return PPP_PAP_Response - return cls - - def extract_padding(self, pay): - return "", pay - - -class PPP_PAP_Request(PPP_PAP): - fields_desc = [ - ByteEnumField("code", 1, _PPP_paptypes), - XByteField("id", 0), - FieldLenField("len", None, fmt="!H", length_of="username", - adjust=lambda pkt, val: val + 6 + len(pkt.password)), - FieldLenField("username_len", None, fmt="B", length_of="username"), - StrLenField("username", None, - length_from=lambda pkt: pkt.username_len), - FieldLenField("passwd_len", None, fmt="B", length_of="password"), - StrLenField("password", None, length_from=lambda pkt: pkt.passwd_len), - ] - - def mysummary(self): - return self.sprintf("PAP-Request username=%PPP_PAP_Request.username%" - " password=%PPP_PAP_Request.password%") - - -class PPP_PAP_Response(PPP_PAP): - fields_desc = [ - ByteEnumField("code", 2, _PPP_paptypes), - XByteField("id", 0), - FieldLenField("len", None, fmt="!H", length_of="message", - adjust=lambda _, val: val + 5), - FieldLenField("msg_len", None, fmt="B", length_of="message"), - StrLenField("message", "", length_from=lambda pkt: pkt.msg_len), - ] - - def answers(self, other): - return isinstance(other, PPP_PAP_Request) and other.id == self.id - - def mysummary(self): - res = "PAP-Ack" if self.code == 2 else "PAP-Nak" - if self.msg_len > 0: - res += self.sprintf(" msg=%PPP_PAP_Response.message%") - return res - - -# Challenge Handshake Authentication protocol (RFC1994) - -_PPP_chaptypes = {1: "Challenge", - 2: "Response", - 3: "Success", - 4: "Failure"} - - -class PPP_CHAP(Packet): - name = "PPP Challenge Handshake Authentication Protocol" - fields_desc = [ - ByteEnumField("code", 1, _PPP_chaptypes), - XByteField("id", 0), - FieldLenField("len", None, fmt="!H", length_of="data", - adjust=lambda _, val: val + 4), - StrLenField("data", "", length_from=lambda pkt: pkt.len - 4), - ] - - def answers(self, other): - return isinstance(other, PPP_CHAP_ChallengeResponse) \ - and other.code == 2 and self.code in (3, 4) \ - and self.id == other.id - - @classmethod - def dispatch_hook(cls, _pkt=None, *_, **kargs): - code = None - if _pkt: - code = orb(_pkt[0]) - elif "code" in kargs: - code = kargs["code"] - if isinstance(code, six.string_types): - code = cls.fields_desc[0].s2i[code] - - if code in (1, 2): - return PPP_CHAP_ChallengeResponse - return cls - - def extract_padding(self, pay): - return "", pay - - def mysummary(self): - if self.code == 3: - return self.sprintf("CHAP Success message=%PPP_CHAP.data%") - elif self.code == 4: - return self.sprintf("CHAP Failure message=%PPP_CHAP.data%") - - -class PPP_CHAP_ChallengeResponse(PPP_CHAP): - fields_desc = [ - ByteEnumField("code", 1, _PPP_chaptypes), - XByteField("id", 0), - FieldLenField( - "len", None, fmt="!H", length_of="value", - adjust=lambda pkt, val: val + len(pkt.optional_name) + 5, - ), - FieldLenField("value_size", None, fmt="B", length_of="value"), - XStrLenField("value", b'\x00\x00\x00\x00\x00\x00\x00\x00', - length_from=lambda pkt: pkt.value_size), - StrLenField("optional_name", "", - length_from=lambda pkt: pkt.len - pkt.value_size - 5), - ] - - def answers(self, other): - return isinstance(other, PPP_CHAP_ChallengeResponse) \ - and other.code == 1 and self.code == 2 and self.id == other.id - - def mysummary(self): - if self.code == 1: - return self.sprintf( - "CHAP challenge=0x%PPP_CHAP_ChallengeResponse.value% " - "optional_name=%PPP_CHAP_ChallengeResponse.optional_name%" - ) - elif self.code == 2: - return self.sprintf( - "CHAP response=0x%PPP_CHAP_ChallengeResponse.value% " - "optional_name=%PPP_CHAP_ChallengeResponse.optional_name%" - ) - else: - return super(PPP_CHAP_ChallengeResponse, self).mysummary() - - -bind_layers(PPPoED, PPPoED_Tags, type=1) -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(DIR_PPP, PPP) -bind_layers(PPP, EAP, proto=0xc227) -bind_layers(PPP, IP, proto=0x0021) -bind_layers(PPP, IPv6, proto=0x0057) -bind_layers(PPP, PPP_CHAP, proto=0xc223) -bind_layers(PPP, PPP_IPCP, proto=0x8021) -bind_layers(PPP, PPP_ECP, proto=0x8053) -bind_layers(PPP, PPP_LCP, proto=0xc021) -bind_layers(PPP, PPP_PAP, proto=0xc023) -bind_layers(Ether, PPP_IPCP, type=0x8021) -bind_layers(Ether, PPP_ECP, type=0x8053) -bind_layers(GRE_PPTP, PPP, proto=0x880b) - - -conf.l2types.register(DLT_PPP, PPP) -conf.l2types.register(DLT_PPP_SERIAL, HDLC) -conf.l2types.register(DLT_PPP_ETHER, PPPoE) -conf.l2types.register(DLT_PPP_WITH_DIR, DIR_PPP) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/pptp.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/pptp.py deleted file mode 100644 index c43959ec17..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/pptp.py +++ /dev/null @@ -1,381 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Jan Sebechlebsky -# This program is published under a GPLv2 license - -""" -PPTP (Point to Point Tunneling Protocol) - -[RFC 2637] -""" - -from scapy.packet import Packet, bind_layers -from scapy.layers.inet import TCP -from scapy.compat import orb -from scapy.fields import ByteEnumField, FieldLenField, FlagsField, IntField, \ - IntEnumField, LenField, XIntField, ShortField, ShortEnumField, \ - StrFixedLenField, StrLenField, XShortField, XByteField - -_PPTP_MAGIC_COOKIE = 0x1a2b3c4d - -_PPTP_msg_type = {1: "Control Message", - 2: "Managemenent Message"} - -_PPTP_ctrl_msg_type = { # Control Connection Management - 1: "Start-Control-Connection-Request", - 2: "Start-Control-Connection-Reply", - 3: "Stop-Control-Connection-Request", - 4: "Stop-Control-Connection-Reply", - 5: "Echo-Request", - 6: "Echo-Reply", - # Call Management - 7: "Outgoing-Call-Request", - 8: "Outgoing-Call-Reply", - 9: "Incoming-Call-Request", - 10: "Incoming-Call-Reply", - 11: "Incoming-Call-Connected", - 12: "Call-Clear-Request", - 13: "Call-Disconnect-Notify", - # Error Reporting - 14: "WAN-Error-Notify", - # PPP Session Control - 15: "Set-Link-Info"} - -_PPTP_general_error_code = {0: "None", - 1: "Not-Connected", - 2: "Bad-Format", - 3: "Bad-Value", - 4: "No-Resource", - 5: "Bad-Call ID", - 6: "PAC-Error"} - - -class PPTP(Packet): - name = "PPTP" - fields_desc = [FieldLenField("len", None, fmt="H", length_of="data", - adjust=lambda p, x: x + 12), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 1, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - StrLenField("data", "", length_from=lambda p: p.len - 12)] - - registered_options = {} - - @classmethod - def register_variant(cls): - cls.registered_options[cls.ctrl_msg_type.default] = cls - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt: - o = orb(_pkt[9]) - return cls.registered_options.get(o, cls) - return cls - - -_PPTP_FRAMING_CAPABILITIES_FLAGS = ["Asynchronous Framing supported", - "Synchronous Framing supported"] - -_PPTP_BEARER_CAPABILITIES_FLAGS = ["Analog access supported", - "Digital access supported"] - - -class PPTPStartControlConnectionRequest(PPTP): - name = "PPTP Start Control Connection Request" - fields_desc = [LenField("len", 156), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 1, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - ShortField("protocol_version", 1), - XShortField("reserved_1", 0x0000), - FlagsField("framing_capabilities", 0, 32, - _PPTP_FRAMING_CAPABILITIES_FLAGS), - FlagsField("bearer_capabilities", 0, 32, - _PPTP_BEARER_CAPABILITIES_FLAGS), - ShortField("maximum_channels", 65535), - ShortField("firmware_revision", 256), - StrFixedLenField("host_name", "linux", 64), - StrFixedLenField("vendor_string", "", 64)] - - -_PPTP_start_control_connection_result = {1: "OK", - 2: "General error", - 3: "Command channel already exists", - 4: "Not authorized", - 5: "Unsupported protocol version"} - - -class PPTPStartControlConnectionReply(PPTP): - name = "PPTP Start Control Connection Reply" - fields_desc = [LenField("len", 156), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 2, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - ShortField("protocol_version", 1), - ByteEnumField("result_code", 1, - _PPTP_start_control_connection_result), - ByteEnumField("error_code", 0, _PPTP_general_error_code), - FlagsField("framing_capabilities", 0, 32, - _PPTP_FRAMING_CAPABILITIES_FLAGS), - FlagsField("bearer_capabilities", 0, 32, - _PPTP_BEARER_CAPABILITIES_FLAGS), - ShortField("maximum_channels", 65535), - ShortField("firmware_revision", 256), - StrFixedLenField("host_name", "linux", 64), - StrFixedLenField("vendor_string", "", 64)] - - def answers(self, other): - return isinstance(other, PPTPStartControlConnectionRequest) - - -_PPTP_stop_control_connection_reason = {1: "None", - 2: "Stop-Protocol", - 3: "Stop-Local-Shutdown"} - - -class PPTPStopControlConnectionRequest(PPTP): - name = "PPTP Stop Control Connection Request" - fields_desc = [LenField("len", 16), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 3, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - ByteEnumField("reason", 1, - _PPTP_stop_control_connection_reason), - XByteField("reserved_1", 0x00), - XShortField("reserved_2", 0x0000)] - - -_PPTP_stop_control_connection_result = {1: "OK", - 2: "General error"} - - -class PPTPStopControlConnectionReply(PPTP): - name = "PPTP Stop Control Connection Reply" - fields_desc = [LenField("len", 16), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 4, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - ByteEnumField("result_code", 1, - _PPTP_stop_control_connection_result), - ByteEnumField("error_code", 0, _PPTP_general_error_code), - XShortField("reserved_2", 0x0000)] - - def answers(self, other): - return isinstance(other, PPTPStopControlConnectionRequest) - - -class PPTPEchoRequest(PPTP): - name = "PPTP Echo Request" - fields_desc = [LenField("len", 16), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 5, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - IntField("identifier", None)] - - -_PPTP_echo_result = {1: "OK", - 2: "General error"} - - -class PPTPEchoReply(PPTP): - name = "PPTP Echo Reply" - fields_desc = [LenField("len", 20), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 6, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - IntField("identifier", None), - ByteEnumField("result_code", 1, _PPTP_echo_result), - ByteEnumField("error_code", 0, _PPTP_general_error_code), - XShortField("reserved_1", 0x0000)] - - def answers(self, other): - return isinstance(other, PPTPEchoRequest) and other.identifier == self.identifier # noqa: E501 - - -_PPTP_bearer_type = {1: "Analog channel", - 2: "Digital channel", - 3: "Any type of channel"} - -_PPTP_framing_type = {1: "Asynchronous framing", - 2: "Synchronous framing", - 3: "Any type of framing"} - - -class PPTPOutgoingCallRequest(PPTP): - name = "PPTP Outgoing Call Request" - fields_desc = [LenField("len", 168), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 7, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - ShortField("call_id", 1), - ShortField("call_serial_number", 0), - IntField("minimum_bps", 32768), - IntField("maximum_bps", 2147483648), - IntEnumField("bearer_type", 3, _PPTP_bearer_type), - IntEnumField("framing_type", 3, _PPTP_framing_type), - ShortField("pkt_window_size", 16), - ShortField("pkt_proc_delay", 0), - ShortField('phone_number_len', 0), - XShortField("reserved_1", 0x0000), - StrFixedLenField("phone_number", '', 64), - StrFixedLenField("subaddress", '', 64)] - - -_PPTP_result_code = {1: "Connected", - 2: "General error", - 3: "No Carrier", - 4: "Busy", - 5: "No dial tone", - 6: "Time-out", - 7: "Do not accept"} - - -class PPTPOutgoingCallReply(PPTP): - name = "PPTP Outgoing Call Reply" - fields_desc = [LenField("len", 32), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 8, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - ShortField("call_id", 1), - ShortField("peer_call_id", 1), - ByteEnumField("result_code", 1, _PPTP_result_code), - ByteEnumField("error_code", 0, _PPTP_general_error_code), - ShortField("cause_code", 0), - IntField("connect_speed", 100000000), - ShortField("pkt_window_size", 16), - ShortField("pkt_proc_delay", 0), - IntField("channel_id", 0)] - - def answers(self, other): - return isinstance(other, PPTPOutgoingCallRequest) and other.call_id == self.peer_call_id # noqa: E501 - - -class PPTPIncomingCallRequest(PPTP): - name = "PPTP Incoming Call Request" - fields_desc = [LenField("len", 220), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 9, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - ShortField("call_id", 1), - ShortField("call_serial_number", 1), - IntEnumField("bearer_type", 3, _PPTP_bearer_type), - IntField("channel_id", 0), - ShortField("dialed_number_len", 0), - ShortField("dialing_number_len", 0), - StrFixedLenField("dialed_number", "", 64), - StrFixedLenField("dialing_number", "", 64), - StrFixedLenField("subaddress", "", 64)] - - -class PPTPIncomingCallReply(PPTP): - name = "PPTP Incoming Call Reply" - fields_desc = [LenField("len", 148), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 10, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - ShortField("call_id", 1), - ShortField("peer_call_id", 1), - ByteEnumField("result_code", 1, _PPTP_result_code), - ByteEnumField("error_code", 0, _PPTP_general_error_code), - ShortField("pkt_window_size", 64), - ShortField("pkt_transmit_delay", 0), - XShortField("reserved_1", 0x0000)] - - def answers(self, other): - return isinstance(other, PPTPIncomingCallRequest) and other.call_id == self.peer_call_id # noqa: E501 - - -class PPTPIncomingCallConnected(PPTP): - name = "PPTP Incoming Call Connected" - fields_desc = [LenField("len", 28), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 11, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - ShortField("peer_call_id", 1), - XShortField("reserved_1", 0x0000), - IntField("connect_speed", 100000000), - ShortField("pkt_window_size", 64), - ShortField("pkt_transmit_delay", 0), - IntEnumField("framing_type", 1, _PPTP_framing_type)] - - def answers(self, other): - return isinstance(other, PPTPIncomingCallReply) and other.call_id == self.peer_call_id # noqa: E501 - - -class PPTPCallClearRequest(PPTP): - name = "PPTP Call Clear Request" - fields_desc = [LenField("len", 16), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 12, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - ShortField("call_id", 1), - XShortField("reserved_1", 0x0000)] - - -_PPTP_call_disconnect_result = {1: "Lost Carrier", - 2: "General error", - 3: "Admin Shutdown", - 4: "Request"} - - -class PPTPCallDisconnectNotify(PPTP): - name = "PPTP Call Disconnect Notify" - fields_desc = [LenField("len", 148), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 13, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - ShortField("call_id", 1), - ByteEnumField("result_code", 1, - _PPTP_call_disconnect_result), - ByteEnumField("error_code", 0, _PPTP_general_error_code), - ShortField("cause_code", 0), - XShortField("reserved_1", 0x0000), - StrFixedLenField("call_statistic", "", 128)] - - -class PPTPWANErrorNotify(PPTP): - name = "PPTP WAN Error Notify" - fields_desc = [LenField("len", 40), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 14, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - ShortField("peer_call_id", 1), - XShortField("reserved_1", 0x0000), - IntField("crc_errors", 0), - IntField("framing_errors", 0), - IntField("hardware_overruns", 0), - IntField("buffer_overruns", 0), - IntField("time_out_errors", 0), - IntField("alignment_errors", 0)] - - -class PPTPSetLinkInfo(PPTP): - name = "PPTP Set Link Info" - fields_desc = [LenField("len", 24), - ShortEnumField("type", 1, _PPTP_msg_type), - XIntField("magic_cookie", _PPTP_MAGIC_COOKIE), - ShortEnumField("ctrl_msg_type", 15, _PPTP_ctrl_msg_type), - XShortField("reserved_0", 0x0000), - ShortField("peer_call_id", 1), - XShortField("reserved_1", 0x0000), - XIntField("send_accm", 0x00000000), - XIntField("receive_accm", 0x00000000)] - - -bind_layers(TCP, PPTP, sport=1723) -bind_layers(TCP, PPTP, dport=1723) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/radius.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/radius.py deleted file mode 100644 index 949c9a72cb..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/radius.py +++ /dev/null @@ -1,1156 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Vincent Mauge -# This program is published under a GPLv2 license - -""" -RADIUS (Remote Authentication Dial In User Service) -""" - -import struct -import hashlib -import hmac -from scapy.compat import orb, raw -from scapy.packet import Packet, Padding, bind_layers -from scapy.fields import ByteField, ByteEnumField, IntField, StrLenField,\ - XStrLenField, XStrFixedLenField, FieldLenField, PacketLenField,\ - PacketListField, IPField, MultiEnumField -from scapy.layers.inet import UDP -from scapy.layers.eap import EAP -from scapy.utils import issubtype -from scapy.config import conf -from scapy.error import Scapy_Exception - - -# https://www.iana.org/assignments/radius-types/radius-types.xhtml -_radius_attribute_types = { - 1: "User-Name", - 2: "User-Password", - 3: "CHAP-Password", - 4: "NAS-IP-Address", - 5: "NAS-Port", - 6: "Service-Type", - 7: "Framed-Protocol", - 8: "Framed-IP-Address", - 9: "Framed-IP-Netmask", - 10: "Framed-Routing", - 11: "Filter-Id", - 12: "Framed-MTU", - 13: "Framed-Compression", - 14: "Login-IP-Host", - 15: "Login-Service", - 16: "Login-TCP-Port", - 17: "Unassigned", - 18: "Reply-Message", - 19: "Callback-Number", - 20: "Callback-Id", - 21: "Unassigned", - 22: "Framed-Route", - 23: "Framed-IPX-Network", - 24: "State", - 25: "Class", - 26: "Vendor-Specific", - 27: "Session-Timeout", - 28: "Idle-Timeout", - 29: "Termination-Action", - 30: "Called-Station-Id", - 31: "Calling-Station-Id", - 32: "NAS-Identifier", - 33: "Proxy-State", - 34: "Login-LAT-Service", - 35: "Login-LAT-Node", - 36: "Login-LAT-Group", - 37: "Framed-AppleTalk-Link", - 38: "Framed-AppleTalk-Network", - 39: "Framed-AppleTalk-Zone", - 40: "Acct-Status-Type", - 41: "Acct-Delay-Time", - 42: "Acct-Input-Octets", - 43: "Acct-Output-Octets", - 44: "Acct-Session-Id", - 45: "Acct-Authentic", - 46: "Acct-Session-Time", - 47: "Acct-Input-Packets", - 48: "Acct-Output-Packets", - 49: "Acct-Terminate-Cause", - 50: "Acct-Multi-Session-Id", - 51: "Acct-Link-Count", - 52: "Acct-Input-Gigawords", - 53: "Acct-Output-Gigawords", - 54: "Unassigned", - 55: "Event-Timestamp", - 56: "Egress-VLANID", - 57: "Ingress-Filters", - 58: "Egress-VLAN-Name", - 59: "User-Priority-Table", - 60: "CHAP-Challenge", - 61: "NAS-Port-Type", - 62: "Port-Limit", - 63: "Login-LAT-Port", - 64: "Tunnel-Type", - 65: "Tunnel-Medium-Type", - 66: "Tunnel-Client-Endpoint", - 67: "Tunnel-Server-Endpoint", - 68: "Acct-Tunnel-Connection", - 69: "Tunnel-Password", - 70: "ARAP-Password", - 71: "ARAP-Features", - 72: "ARAP-Zone-Access", - 73: "ARAP-Security", - 74: "ARAP-Security-Data", - 75: "Password-Retry", - 76: "Prompt", - 77: "Connect-Info", - 78: "Configuration-Token", - 79: "EAP-Message", - 80: "Message-Authenticator", - 81: "Tunnel-Private-Group-ID", - 82: "Tunnel-Assignment-ID", - 83: "Tunnel-Preference", - 84: "ARAP-Challenge-Response", - 85: "Acct-Interim-Interval", - 86: "Acct-Tunnel-Packets-Lost", - 87: "NAS-Port-Id", - 88: "Framed-Pool", - 89: "CUI", - 90: "Tunnel-Client-Auth-ID", - 91: "Tunnel-Server-Auth-ID", - 92: "NAS-Filter-Rule", - 93: "Unassigned", - 94: "Originating-Line-Info", - 95: "NAS-IPv6-Address", - 96: "Framed-Interface-Id", - 97: "Framed-IPv6-Prefix", - 98: "Login-IPv6-Host", - 99: "Framed-IPv6-Route", - 100: "Framed-IPv6-Pool", - 101: "Error-Cause", - 102: "EAP-Key-Name", - 103: "Digest-Response", - 104: "Digest-Realm", - 105: "Digest-Nonce", - 106: "Digest-Response-Auth", - 107: "Digest-Nextnonce", - 108: "Digest-Method", - 109: "Digest-URI", - 110: "Digest-Qop", - 111: "Digest-Algorithm", - 112: "Digest-Entity-Body-Hash", - 113: "Digest-CNonce", - 114: "Digest-Nonce-Count", - 115: "Digest-Username", - 116: "Digest-Opaque", - 117: "Digest-Auth-Param", - 118: "Digest-AKA-Auts", - 119: "Digest-Domain", - 120: "Digest-Stale", - 121: "Digest-HA1", - 122: "SIP-AOR", - 123: "Delegated-IPv6-Prefix", - 124: "MIP6-Feature-Vector", - 125: "MIP6-Home-Link-Prefix", - 126: "Operator-Name", - 127: "Location-Information", - 128: "Location-Data", - 129: "Basic-Location-Policy-Rules", - 130: "Extended-Location-Policy-Rules", - 131: "Location-Capable", - 132: "Requested-Location-Info", - 133: "Framed-Management-Protocol", - 134: "Management-Transport-Protection", - 135: "Management-Policy-Id", - 136: "Management-Privilege-Level", - 137: "PKM-SS-Cert", - 138: "PKM-CA-Cert", - 139: "PKM-Config-Settings", - 140: "PKM-Cryptosuite-List", - 141: "PKM-SAID", - 142: "PKM-SA-Descriptor", - 143: "PKM-Auth-Key", - 144: "DS-Lite-Tunnel-Name", - 145: "Mobile-Node-Identifier", - 146: "Service-Selection", - 147: "PMIP6-Home-LMA-IPv6-Address", - 148: "PMIP6-Visited-LMA-IPv6-Address", - 149: "PMIP6-Home-LMA-IPv4-Address", - 150: "PMIP6-Visited-LMA-IPv4-Address", - 151: "PMIP6-Home-HN-Prefix", - 152: "PMIP6-Visited-HN-Prefix", - 153: "PMIP6-Home-Interface-ID", - 154: "PMIP6-Visited-Interface-ID", - 155: "PMIP6-Home-IPv4-HoA", - 156: "PMIP6-Visited-IPv4-HoA", - 157: "PMIP6-Home-DHCP4-Server-Address", - 158: "PMIP6-Visited-DHCP4-Server-Address", - 159: "PMIP6-Home-DHCP6-Server-Address", - 160: "PMIP6-Visited-DHCP6-Server-Address", - 161: "PMIP6-Home-IPv4-Gateway", - 162: "PMIP6-Visited-IPv4-Gateway", - 163: "EAP-Lower-Layer", - 164: "GSS-Acceptor-Service-Name", - 165: "GSS-Acceptor-Host-Name", - 166: "GSS-Acceptor-Service-Specifics", - 167: "GSS-Acceptor-Realm-Name", - 168: "Framed-IPv6-Address", - 169: "DNS-Server-IPv6-Address", - 170: "Route-IPv6-Information", - 171: "Delegated-IPv6-Prefix-Pool", - 172: "Stateful-IPv6-Address-Pool", - 173: "IPv6-6rd-Configuration", - 174: "Allowed-Called-Station-Id", - 175: "EAP-Peer-Id", - 176: "EAP-Server-Id", - 177: "Mobility-Domain-Id", - 178: "Preauth-Timeout", - 179: "Network-Id-Name", - 180: "EAPoL-Announcement", - 181: "WLAN-HESSID", - 182: "WLAN-Venue-Info", - 183: "WLAN-Venue-Language", - 184: "WLAN-Venue-Name", - 185: "WLAN-Reason-Code", - 186: "WLAN-Pairwise-Cipher", - 187: "WLAN-Group-Cipher", - 188: "WLAN-AKM-Suite", - 189: "WLAN-Group-Mgmt-Cipher", - 190: "WLAN-RF-Band", - 191: "Unassigned", -} - - -class RadiusAttribute(Packet): - """ - Implements a RADIUS attribute (RFC 2865). Every specific RADIUS attribute - class should inherit from this one. - """ - - name = "Radius Attribute" - fields_desc = [ - ByteEnumField("type", 1, _radius_attribute_types), - FieldLenField("len", None, "value", "B", - adjust=lambda pkt, x: len(pkt.value) + 2), - StrLenField("value", "", length_from=lambda pkt: pkt.len - 2) - ] - - registered_attributes = {} - - @classmethod - def register_variant(cls): - """ - Registers the RADIUS attributes defined in this module. - """ - - if hasattr(cls, "val"): - cls.registered_attributes[cls.val] = cls - else: - cls.registered_attributes[cls.type.default] = cls - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - """ - Returns the right RadiusAttribute class for the given data. - """ - - if _pkt: - attr_type = orb(_pkt[0]) - return cls.registered_attributes.get(attr_type, cls) - return cls - - def haslayer(self, cls): - if cls == "RadiusAttribute": - if isinstance(self, RadiusAttribute): - return True - elif issubtype(cls, RadiusAttribute): - if isinstance(self, cls): - return True - return super(RadiusAttribute, self).haslayer(cls) - - def getlayer(self, cls, nb=1, _track=None, _subclass=True, **flt): - return super(RadiusAttribute, self).getlayer(cls, nb=nb, _track=_track, - _subclass=True, **flt) - - def post_build(self, p, pay): - length = self.len - if length is None: - length = len(p) - p = p[:1] + struct.pack("!B", length) + p[2:] - return p - - def guess_payload_class(self, _): - return Padding - - -class _SpecificRadiusAttr(RadiusAttribute): - """ - Class from which every "specific" RADIUS attribute defined in this module - inherits. - """ - - __slots__ = ["val"] - - def __init__(self, _pkt="", post_transform=None, _internal=0, _underlayer=None, **fields): # noqa: E501 - super(_SpecificRadiusAttr, self).__init__( - _pkt, - post_transform, - _internal, - _underlayer - ) - self.fields["type"] = self.val - name_parts = self.__class__.__name__.split('RadiusAttr_') - if len(name_parts) < 2: - raise Scapy_Exception( - "Invalid class name: {}".format(self.__class__.__name__) - ) - self.name = name_parts[1].replace('_', '-') - - -# -# RADIUS attributes which values are 4 bytes integers -# - -class _RadiusAttrIntValue(_SpecificRadiusAttr): - """ - Implements a RADIUS attribute which value field is 4 bytes long integer. - """ - - fields_desc = [ - ByteEnumField("type", 5, _radius_attribute_types), - ByteField("len", 6), - IntField("value", 0) - ] - - -class RadiusAttr_NAS_Port(_RadiusAttrIntValue): - """RFC 2865""" - val = 5 - - -class RadiusAttr_Framed_MTU(_RadiusAttrIntValue): - """RFC 2865""" - val = 12 - - -class RadiusAttr_Login_TCP_Port(_RadiusAttrIntValue): - """RFC 2865""" - val = 16 - - -class RadiusAttr_Session_Timeout(_RadiusAttrIntValue): - """RFC 2865""" - val = 27 - - -class RadiusAttr_Idle_Timeout(_RadiusAttrIntValue): - """RFC 2865""" - val = 28 - - -class RadiusAttr_Framed_AppleTalk_Link(_RadiusAttrIntValue): - """RFC 2865""" - val = 37 - - -class RadiusAttr_Framed_AppleTalk_Network(_RadiusAttrIntValue): - """RFC 2865""" - val = 38 - - -class RadiusAttr_Acct_Delay_Time(_RadiusAttrIntValue): - """RFC 2866""" - val = 41 - - -class RadiusAttr_Acct_Input_Octets(_RadiusAttrIntValue): - """RFC 2866""" - val = 42 - - -class RadiusAttr_Acct_Output_Octets(_RadiusAttrIntValue): - """RFC 2866""" - val = 43 - - -class RadiusAttr_Acct_Session_Time(_RadiusAttrIntValue): - """RFC 2866""" - val = 46 - - -class RadiusAttr_Acct_Input_Packets(_RadiusAttrIntValue): - """RFC 2866""" - val = 47 - - -class RadiusAttr_Acct_Output_Packets(_RadiusAttrIntValue): - """RFC 2866""" - val = 48 - - -class RadiusAttr_Acct_Link_Count(_RadiusAttrIntValue): - """RFC 2866""" - val = 51 - - -class RadiusAttr_Acct_Input_Gigawords(_RadiusAttrIntValue): - """RFC 2869""" - val = 52 - - -class RadiusAttr_Acct_Output_Gigawords(_RadiusAttrIntValue): - """RFC 2869""" - val = 53 - - -class RadiusAttr_Egress_VLANID(_RadiusAttrIntValue): - """RFC 4675""" - val = 56 - - -class RadiusAttr_Port_Limit(_RadiusAttrIntValue): - """RFC 2865""" - val = 62 - - -class RadiusAttr_ARAP_Security(_RadiusAttrIntValue): - """RFC 2869""" - val = 73 - - -class RadiusAttr_Password_Retry(_RadiusAttrIntValue): - """RFC 2869""" - val = 75 - - -class RadiusAttr_Tunnel_Preference(_RadiusAttrIntValue): - """RFC 2868""" - val = 83 - - -class RadiusAttr_Acct_Interim_Interval(_RadiusAttrIntValue): - """RFC 2869""" - val = 85 - - -class RadiusAttr_Acct_Tunnel_Packets_Lost(_RadiusAttrIntValue): - """RFC 2867""" - val = 86 - - -class RadiusAttr_Management_Privilege_Level(_RadiusAttrIntValue): - """RFC 5607""" - val = 136 - - -class RadiusAttr_Mobility_Domain_Id(_RadiusAttrIntValue): - """RFC 7268""" - val = 177 - - -class RadiusAttr_Preauth_Timeout(_RadiusAttrIntValue): - """RFC 7268""" - val = 178 - - -class RadiusAttr_WLAN_Venue_Info(_RadiusAttrIntValue): - """RFC 7268""" - val = 182 - - -class RadiusAttr_WLAN_Reason_Code(_RadiusAttrIntValue): - """RFC 7268""" - val = 185 - - -class RadiusAttr_WLAN_Pairwise_Cipher(_RadiusAttrIntValue): - """RFC 7268""" - val = 186 - - -class RadiusAttr_WLAN_Group_Cipher(_RadiusAttrIntValue): - """RFC 7268""" - val = 187 - - -class RadiusAttr_WLAN_AKM_Suite(_RadiusAttrIntValue): - """RFC 7268""" - val = 188 - - -class RadiusAttr_WLAN_Group_Mgmt_Cipher(_RadiusAttrIntValue): - """RFC 7268""" - val = 189 - - -class RadiusAttr_WLAN_RF_Band(_RadiusAttrIntValue): - """RFC 7268""" - val = 190 - - -# -# RADIUS attributes which values are string (displayed as hex) -# - -class _RadiusAttrHexStringVal(_SpecificRadiusAttr): - """ - Implements a RADIUS attribute which value field is a string that will be - as a hex string. - """ - - __slots__ = ["val"] - - def __init__(self, _pkt="", post_transform=None, _internal=0, _underlayer=None, **fields): # noqa: E501 - super(_RadiusAttrHexStringVal, self).__init__( - _pkt, - post_transform, - _internal, - _underlayer - ) - self.fields["type"] = self.val - name_parts = self.__class__.__name__.split('RadiusAttr_') - if len(name_parts) < 2: - raise Scapy_Exception( - "Invalid class name: {}".format(self.__class__.__name__) - ) - self.name = name_parts[1].replace('_', '-') - - fields_desc = [ - ByteEnumField("type", 24, _radius_attribute_types), - FieldLenField( - "len", - None, - "value", - "B", - adjust=lambda p, x: len(p.value) + 2 - ), - XStrLenField("value", "", length_from=lambda p: p.len - 2 if p.len else 0) # noqa: E501 - ] - - -class RadiusAttr_State(_RadiusAttrHexStringVal): - """RFC 2865""" - val = 24 - - -def prepare_packed_data(radius_packet, packed_req_authenticator): - """ - Pack RADIUS data prior computing the authentication MAC - """ - - packed_hdr = struct.pack("!B", radius_packet.code) - packed_hdr += struct.pack("!B", radius_packet.id) - packed_hdr += struct.pack("!H", radius_packet.len) - - packed_attrs = b'' - for attr in radius_packet.attributes: - packed_attrs += raw(attr) - - return packed_hdr + packed_req_authenticator + packed_attrs - - -class RadiusAttr_Message_Authenticator(_RadiusAttrHexStringVal): - """RFC 2869""" - val = 80 - - fields_desc = [ - ByteEnumField("type", 24, _radius_attribute_types), - FieldLenField( - "len", - 18, - "value", - "B", - ), - XStrFixedLenField("value", "\x00" * 16, length=16) - ] - - @staticmethod - def compute_message_authenticator(radius_packet, packed_req_authenticator, - shared_secret): - """ - Computes the "Message-Authenticator" of a given RADIUS packet. - (RFC 2869 - Page 33) - """ - - attr = radius_packet[RadiusAttr_Message_Authenticator] - attr.value = bytearray(attr.len - 2) - data = prepare_packed_data(radius_packet, packed_req_authenticator) - radius_hmac = hmac.new(shared_secret, data, hashlib.md5) - - return radius_hmac.digest() - -# -# RADIUS attributes which values are IPv4 prefixes -# - - -class _RadiusAttrIPv4AddrVal(_SpecificRadiusAttr): - """ - Implements a RADIUS attribute which value field is an IPv4 address. - """ - - __slots__ = ["val"] - - fields_desc = [ - ByteEnumField("type", 4, _radius_attribute_types), - ByteField("len", 6), - IPField("value", "0.0.0.0") - ] - - -class RadiusAttr_NAS_IP_Address(_RadiusAttrIPv4AddrVal): - """RFC 2865""" - val = 4 - - -class RadiusAttr_Framed_IP_Address(_RadiusAttrIPv4AddrVal): - """RFC 2865""" - val = 8 - - -class RadiusAttr_Framed_IP_Netmask(_RadiusAttrIPv4AddrVal): - """RFC 2865""" - val = 9 - - -class RadiusAttr_Login_IP_Host(_RadiusAttrIPv4AddrVal): - """RFC 2865""" - val = 14 - - -class RadiusAttr_Framed_IPX_Network(_RadiusAttrIPv4AddrVal): - """RFC 2865""" - val = 23 - - -class RadiusAttr_PMIP6_Home_LMA_IPv4_Address(_RadiusAttrIPv4AddrVal): - """RFC 6572""" - val = 149 - - -class RadiusAttr_PMIP6_Visited_LMA_IPv4_Address(_RadiusAttrIPv4AddrVal): - """RFC 6572""" - val = 150 - - -class RadiusAttr_PMIP6_Home_DHCP4_Server_Address(_RadiusAttrIPv4AddrVal): - """RFC 6572""" - val = 157 - - -class RadiusAttr_PMIP6_Visited_DHCP4_Server_Address(_RadiusAttrIPv4AddrVal): - """RFC 6572""" - val = 158 - - -class RadiusAttr_PMIP6_Home_IPv4_Gateway(_RadiusAttrIPv4AddrVal): - """RFC 6572""" - val = 161 - - -class RadiusAttr_PMIP6_Visited_IPv4_Gateway(_RadiusAttrIPv4AddrVal): - """RFC 6572""" - val = 162 - - -# See IANA registry "RADIUS Types" -_radius_attrs_values = { - # Service-Type - 6: - { - 1: "Login", - 2: "Framed", - 3: "Callback Login", - 4: "Callback Framed", - 5: "Outbound", - 6: "Administrative", - 7: "NAS Prompt", - 8: "Authenticate Only", - 9: "Callback NAS Prompt", - 10: "Call Check", - 11: "Callback Administrative", - 12: "Voice", - 13: "Fax", - 14: "Modem Relay", - 15: "IAPP-Register", - 16: "IAPP-AP-Check", - 17: "Authorize Only", - 18: "Framed-Management", - 19: "Additional-Authorization" - }, - - # Framed-Protocol - 7: - { - 1: "PPP", - 2: "SLIP", - 3: "AppleTalk Remote Access Protocol (ARAP)", - 4: "Gandalf proprietary SingleLink/MultiLink protocol", - 5: "Xylogics proprietary IPX/SLIP", - 6: "X.75 Synchronous", - 7: "GPRS PDP Context" - }, - - # Framed-Routing - 10: - { - 0: "None", - 1: "Send routing packets", - 2: "Listen for routing packets", - 3: "Send and Listen" - }, - - # Framed-Compression - 13: - { - 0: "None", - 1: "VJ TCP/IP header compression", - 2: "IPX header compression", - 3: "Stac-LZS compression" - }, - - # Login-Service - 15: - { - 0: "Telnet", - 1: "Rlogin", - 2: "TCP Clear", - 3: "PortMaster (proprietary)", - 4: "LAT", - 5: "X25-PAD", - 6: "X25-T3POS", - 7: "Unassigned", - 8: "TCP Clear Quiet (suppresses any NAS-generated connect string)" - }, - - # Termination-Action - 29: - { - 0: "Default", - 1: "RADIUS-Request" - }, - - # Acct-Status-Type - 40: - { - 1: "Start", - 2: "Stop", - 3: "Interim-Update", - 4: "Unassigned", - 5: "Unassigned", - 6: "Unassigned", - 7: "Accounting-On", - 8: "Accounting-Off", - 9: "Tunnel-Start", - 10: "Tunnel-Stop", - 11: "Tunnel-Reject", - 12: "Tunnel-Link-Start", - 13: "Tunnel-Link-Stop", - 14: "Tunnel-Link-Reject", - 15: "Failed" - }, - - # Acct-Authentic - 45: - { - 1: "RADIUS", - 2: "Local", - 3: "Remote", - 4: "Diameter" - }, - - # Acct-Terminate-Cause - 49: - { - 1: "User Request", - 2: "Lost Carrier", - 3: "Lost Service", - 4: "Idle Timeout", - 5: "Session Timeout", - 6: "Admin Reset", - 7: "Admin Reboot", - 8: "Port Error", - 9: "NAS Error", - 10: "NAS Request", - 11: "NAS Reboot", - 12: "Port Unneeded", - 13: "Port Preempted", - 14: "Port Suspended", - 15: "Service Unavailable", - 16: "Callback", - 17: "User Error", - 18: "Host Request", - 19: "Supplicant Restart", - 20: "Reauthentication Failure", - 21: "Port Reinitialized", - 22: "Port Administratively Disabled", - 23: "Lost Power", - }, - - # NAS-Port-Type - 61: - { - 0: "Async", - 1: "Sync", - 2: "ISDN Sync", - 3: "ISDN Async V.120", - 4: "ISDN Async V.110", - 5: "Virtual", - 6: "PIAFS", - 7: "HDLC Clear Channel", - 8: "X.25", - 9: "X.75", - 10: "G.3 Fax", - 11: "SDSL - Symmetric DSL", - 12: "ADSL-CAP - Asymmetric DSL, Carrierless Amplitude Phase Modulation", # noqa: E501 - 13: "ADSL-DMT - Asymmetric DSL, Discrete Multi-Tone", - 14: "IDSL - ISDN Digital Subscriber Line", - 15: "Ethernet", - 16: "xDSL - Digital Subscriber Line of unknown type", - 17: "Cable", - 18: "Wireles - Other", - 19: "Wireless - IEEE 802.11", - 20: "Token-Ring", - 21: "FDDI", - 22: "Wireless - CDMA2000", - 23: "Wireless - UMTS", - 24: "Wireless - 1X-EV", - 25: "IAPP", - 26: "FTTP - Fiber to the Premises", - 27: "Wireless - IEEE 802.16", - 28: "Wireless - IEEE 802.20", - 29: "Wireless - IEEE 802.22", - 30: "PPPoA - PPP over ATM", - 31: "PPPoEoA - PPP over Ethernet over ATM", - 32: "PPPoEoE - PPP over Ethernet over Ethernet", - 33: "PPPoEoVLAN - PPP over Ethernet over VLAN", - 34: "PPPoEoQinQ - PPP over Ethernet over IEEE 802.1QinQ", - 35: "xPON - Passive Optical Network", - 36: "Wireless - XGP", - 37: "WiMAX Pre-Release 8 IWK Function", - 38: "WIMAX-WIFI-IWK: WiMAX WIFI Interworking", - 39: "WIMAX-SFF: Signaling Forwarding Function for LTE/3GPP2", - 40: "WIMAX-HA-LMA: WiMAX HA and or LMA function", - 41: "WIMAX-DHCP: WIMAX DHCP service", - 42: "WIMAX-LBS: WiMAX location based service", - 43: "WIMAX-WVS: WiMAX voice service" - }, - - # Tunnel-Type - 64: - { - 1: "Point-to-Point Tunneling Protocol (PPTP)", - 2: "Layer Two Forwarding (L2F)", - 3: "Layer Two Tunneling Protocol (L2TP)", - 4: "Ascend Tunnel Management Protocol (ATMP)", - 5: "Virtual Tunneling Protocol (VTP)", - 6: "IP Authentication Header in the Tunnel-mode (AH)", - 7: "IP-in-IP Encapsulation (IP-IP)", - 8: "Minimal IP-in-IP Encapsulation (MIN-IP-IP)", - 9: "IP Encapsulating Security Payload in the Tunnel-mode (ESP)", - 10: "Generic Route Encapsulation (GRE)", - 11: "Bay Dial Virtual Services (DVS)", - 12: "IP-in-IP Tunneling", - 13: "Virtual LANs (VLAN)" - }, - - # Tunnel-Medium-Type - 65: - { - 1: "IPv4 (IP version 4)", - 2: "IPv6 (IP version 6)", - 3: "NSAP", - 4: "HDLC (8-bit multidrop)", - 5: "BBN 1822", - 6: "802", - 7: "E.163 (POTS)", - 8: "E.164 (SMDS, Frame Relay, ATM)", - 9: "F.69 (Telex)", - 10: "X.121 (X.25, Frame Relay)", - 11: "IPX", - 12: "Appletalk", - 13: "Decnet IV", - 14: "Banyan Vine", - 15: "E.164 with NSAP format subaddress" - }, - - # ARAP-Zone-Access - 72: - { - 1: "Only allow access to default zone", - 2: "Use zone filter inclusively", - 3: "Not used", - 4: "Use zone filter exclusively" - }, - - # Prompt - 76: - { - 0: "No Echo", - 1: "Echo" - }, - - # Error-Cause Attribute - 101: - { - 201: "Residual Session Context Removed", - 202: "Invalid EAP Packet (Ignored)", - 401: "Unsupported Attribute", - 402: "Missing Attribute", - 403: "NAS Identification Mismatch", - 404: "Invalid Request", - 405: "Unsupported Service", - 406: "Unsupported Extension", - 407: "Invalid Attribute Value", - 501: "Administratively Prohibited", - 502: "Request Not Routable (Proxy)", - 503: "Session Context Not Found", - 504: "Session Context Not Removable", - 505: "Other Proxy Processing Error", - 506: "Resources Unavailable", - 507: "Request Initiated", - 508: "Multiple Session Selection Unsupported", - 509: "Location-Info-Required", - 601: "Response Too Big" - }, - - # Operator Namespace Identifier - Attribute 126 - 126: - { - 0x30: "TADIG", - 0x31: "REALM", - 0x32: "E212", - 0x33: "ICC", - 0xFF: "Reserved" - }, - - # Basic-Location-Policy-Rules - 129: - { - 0: "Retransmission allowed", - }, - - # Location-Capable - 131: - { - 1: "CIVIC_LOCATION", - 2: "GEO_LOCATION", - 4: "USERS_LOCATION", - 8: "NAS_LOCATION" - }, - - # Framed-Management-Protocol - 133: - { - 1: "SNMP", - 2: "Web-based", - 3: "NETCONF", - 4: "FTP", - 5: "TFTP", - 6: "SFTP", - 7: "RCP", - 8: "SCP" - }, - - # Management-Transport-Protection - 134: - { - 1: "No-Protection", - 2: "Integrity-Protection", - 3: "Integrity-Confidentiality-Protection", - }, -} - - -class _RadiusAttrIntEnumVal(_SpecificRadiusAttr): - """ - Implements a RADIUS attribute which value field is 4 bytes long integer. - """ - - __slots__ = ["val"] - - fields_desc = [ - ByteEnumField("type", 6, _radius_attribute_types), - ByteField("len", 6), - MultiEnumField( - "value", - 0, - _radius_attrs_values, - depends_on=lambda p: p.type, - fmt="I" - ) - ] - - -class RadiusAttr_Service_Type(_RadiusAttrIntEnumVal): - """RFC 2865""" - val = 6 - - -class RadiusAttr_Framed_Protocol(_RadiusAttrIntEnumVal): - """RFC 2865""" - val = 7 - - -class RadiusAttr_NAS_Port_Type(_RadiusAttrIntEnumVal): - """RFC 2865""" - val = 61 - - -class _EAPPacketField(PacketLenField): - - """ - Handles EAP-Message attribute value (the actual EAP packet). - """ - - def m2i(self, pkt, m): - ret = None - eap_packet_len = struct.unpack("!H", m[2:4])[0] - if eap_packet_len < 254: - # If the EAP packet has not been fragmented, build a Scapy EAP - # packet from the data. - ret = EAP(m) - else: - ret = conf.raw_layer(m) - return ret - - -class RadiusAttr_EAP_Message(RadiusAttribute): - """ - Implements the "EAP-Message" attribute (RFC 3579). - """ - - name = "EAP-Message" - fields_desc = [ - ByteEnumField("type", 79, _radius_attribute_types), - FieldLenField( - "len", - None, - "value", - "B", - adjust=lambda pkt, x: len(pkt.value) + 2 - ), - _EAPPacketField("value", "", EAP, length_from=lambda p: p.len - 2) - ] - - -class RadiusAttr_Vendor_Specific(RadiusAttribute): - """ - Implements the "Vendor-Specific" attribute, as described in RFC 2865. - """ - - name = "Vendor-Specific" - fields_desc = [ - ByteEnumField("type", 26, _radius_attribute_types), - FieldLenField( - "len", - None, - "value", - "B", - adjust=lambda pkt, x: len(pkt.value) + 8 - ), - IntField("vendor_id", 0), - ByteField("vendor_type", 0), - FieldLenField( - "vendor_len", - None, - "value", - "B", - adjust=lambda p, x: len(p.value) + 2 - ), - StrLenField("value", "", length_from=lambda p: p.vendor_len - 2) - ] - - -# See IANA RADIUS Packet Type Codes registry -_packet_codes = { - 1: "Access-Request", - 2: "Access-Accept", - 3: "Access-Reject", - 4: "Accounting-Request", - 5: "Accounting-Response", - 6: "Accounting-Status (now Interim Accounting)", - 7: "Password-Request", - 8: "Password-Ack", - 9: "Password-Reject", - 10: "Accounting-Message", - 11: "Access-Challenge", - 12: "Status-Server (experimental)", - 13: "Status-Client (experimental)", - 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", - 28: "Reserved", - 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", - 52: "Protocol-Error", - 250: "Experimental Use", - 251: "Experimental Use", - 252: "Experimental Use", - 253: "Experimental Use", - 254: "Reserved", - 255: "Reserved" -} - - -class Radius(Packet): - """ - Implements a RADIUS packet (RFC 2865). - """ - - name = "RADIUS" - fields_desc = [ - ByteEnumField("code", 1, _packet_codes), - ByteField("id", 0), - FieldLenField( - "len", - None, - "attributes", - "H", - adjust=lambda pkt, x: len(pkt.attributes) + 20 - ), - XStrFixedLenField("authenticator", "", 16), - PacketListField( - "attributes", - [], - RadiusAttribute, - length_from=lambda pkt: pkt.len - 20 - ) - ] - - def compute_authenticator(self, packed_request_auth, shared_secret): - """ - Computes the authenticator field (RFC 2865 - Section 3) - """ - - data = prepare_packed_data(self, packed_request_auth) - radius_mac = hashlib.md5(data + shared_secret) - return radius_mac.digest() - - def post_build(self, p, pay): - p += pay - length = self.len - if length is None: - length = len(p) - p = p[:2] + struct.pack("!H", length) + p[4:] - return p - - -bind_layers(UDP, Radius, sport=1812) -bind_layers(UDP, Radius, dport=1812) -bind_layers(UDP, Radius, sport=1813) -bind_layers(UDP, Radius, dport=1813) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/rip.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/rip.py deleted file mode 100644 index 27ba712532..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/rip.py +++ /dev/null @@ -1,80 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -RIP (Routing Information Protocol). -""" - -from scapy.packet import Packet, bind_layers, bind_bottom_up -from scapy.fields import ByteEnumField, ByteField, ConditionalField, \ - IPField, IntEnumField, IntField, ShortEnumField, ShortField, \ - StrFixedLenField, StrLenField -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", # noqa: E501 - 5: "sun", 6: "trigReq", 7: "trigResp", 8: "trigAck", # noqa: E501 - 9: "updateReq", 10: "updateResp", 11: "updateAck"}), # noqa: E501 - ByteField("version", 1), - ShortField("null", 0), - ] - - def guess_payload_class(self, payload): - if payload[:2] == b"\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"}), # noqa: E501 - 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] == b"\x00\x01": - self.md5datalen = len(s) - 4 - - return s - - -bind_bottom_up(UDP, RIP, dport=520) -bind_bottom_up(UDP, RIP, sport=520) -bind_layers(UDP, RIP, sport=520, dport=520) -bind_layers(RIP, RIPEntry,) -bind_layers(RIPEntry, RIPEntry,) -bind_layers(RIPAuth, RIPEntry,) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/rtp.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/rtp.py deleted file mode 100644 index 859833083b..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/rtp.py +++ /dev/null @@ -1,51 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -RTP (Real-time Transport Protocol). -""" - -from scapy.packet import Packet, bind_layers -from scapy.fields import BitEnumField, BitField, BitFieldLenField, \ - FieldLenField, FieldListField, IntField, ShortField - -_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 RTPExtension(Packet): - name = "RTP extension" - fields_desc = [ShortField("header_id", 0), - FieldLenField("header_len", None, count_of="header", fmt="H"), # noqa: E501 - FieldListField('header', [], IntField("hdr", 0), count_from=lambda pkt: pkt.header_len)] # noqa: E501 - - -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_type', 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)] # noqa: E501 - - -bind_layers(RTP, RTPExtension, extension=1) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/sctp.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/sctp.py deleted file mode 100644 index e6634b90c1..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/sctp.py +++ /dev/null @@ -1,672 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Copyright (C) 6WIND -# This program is published under a GPLv2 license - -""" -SCTP (Stream Control Transmission Protocol). -""" - -from __future__ import absolute_import -import struct - -from scapy.compat import orb, raw -from scapy.volatile import RandBin -from scapy.config import conf -from scapy.packet import Packet, bind_layers -from scapy.fields import BitField, ByteEnumField, ConditionalField, Field, \ - FieldLenField, FieldListField, IPField, IntEnumField, IntField, \ - PacketListField, PadField, ShortEnumField, ShortField, StrLenField, \ - XByteField, XIntField, XShortField -from scapy.layers.inet import IP -from scapy.layers.inet6 import IP6Field -from scapy.layers.inet6 import IPv6 - -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 ^ (orb(c))) & 0xFF] - crc = (~crc) & 0xffffffff - # reverse endianness - return struct.unpack(">I", struct.pack("> 16) & 0xffff - print s1,s2 - - for c in buf: - print orb(c) - s1 = (s1 + orb(c)) % BASE - s2 = (s2 + s1) % BASE - print s1,s2 - return (s2 << 16) + s1 - -def sctp_checksum(buf): - return update_adler32(1, buf) -""" - -hmactypes = { - 0: "Reserved1", - 1: "SHA-1", - 2: "Reserved2", - 3: "SHA-256", -} - -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", - 15: "SCTPChunkAuthentication", - 0x80: "SCTPChunkAddressConfAck", - 0xc1: "SCTPChunkAddressConf", -} - -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", - 15: "authentication", - 0x80: "address-configuration-ack", - 0xc1: "address-configuration", -} - -sctpchunkparamtypescls = { - 1: "SCTPChunkParamHearbeatInfo", - 5: "SCTPChunkParamIPv4Addr", - 6: "SCTPChunkParamIPv6Addr", - 7: "SCTPChunkParamStateCookie", - 8: "SCTPChunkParamUnrocognizedParam", - 9: "SCTPChunkParamCookiePreservative", - 11: "SCTPChunkParamHostname", - 12: "SCTPChunkParamSupportedAddrTypes", - 0x8000: "SCTPChunkParamECNCapable", - 0x8002: "SCTPChunkParamRandom", - 0x8003: "SCTPChunkParamChunkList", - 0x8004: "SCTPChunkParamRequestedHMACFunctions", - 0x8008: "SCTPChunkParamSupportedExtensions", - 0xc000: "SCTPChunkParamFwdTSN", - 0xc001: "SCTPChunkParamAddIPAddr", - 0xc002: "SCTPChunkParamDelIPAddr", - 0xc003: "SCTPChunkParamErrorIndication", - 0xc004: "SCTPChunkParamSetPrimaryAddr", - 0xc005: "SCTPChunkParamSuccessIndication", - 0xc006: "SCTPChunkParamAdaptationLayer", -} - -sctpchunkparamtypes = { - 1: "heartbeat-info", - 5: "IPv4", - 6: "IPv6", - 7: "state-cookie", - 8: "unrecognized-param", - 9: "cookie-preservative", - 11: "hostname", - 12: "addrtypes", - 0x8000: "ecn-capable", - 0x8002: "random", - 0x8003: "chunk-list", - 0x8004: "requested-HMAC-functions", - 0x8008: "supported-extensions", - 0xc000: "fwd-tsn-supported", - 0xc001: "add-IP", - 0xc002: "del-IP", - 0xc003: "error-indication", - 0xc004: "set-primary-addr", - 0xc005: "success-indication", - 0xc006: "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 = orb(p[0]) - return globals().get(sctpchunktypescls.get(t, "Raw"), conf.raw_layer) # noqa: E501 - - -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(raw(p)) - p = p[:8] + struct.pack(">I", crc) + p[12:] - return p - -# SCTP Chunk variable params - - -class ChunkParamField(PacketListField): - 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) # noqa: E501 - - def m2i(self, p, m): - cls = conf.raw_layer - if len(m) >= 4: - t = orb(m[0]) * 256 + orb(m[1]) - cls = globals().get(sctpchunkparamtypescls.get(t, "Raw"), conf.raw_layer) # noqa: E501 - 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", "", - 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", "", - 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", "", - 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", "", - 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), # noqa: E501 - length_from=lambda pkt: pkt.len - 4), # noqa: E501 - 4, padwith=b"\x00"), ] - - -class SCTPChunkParamECNCapable(_SCTPChunkParam, Packet): - fields_desc = [ShortEnumField("type", 0x8000, sctpchunkparamtypes), - ShortField("len", 4), ] - - -class SCTPChunkParamRandom(_SCTPChunkParam, Packet): - fields_desc = [ShortEnumField("type", 0x8002, sctpchunkparamtypes), - FieldLenField("len", None, length_of="random", - adjust=lambda pkt, x:x + 4), - PadField(StrLenField("random", RandBin(32), - length_from=lambda pkt: pkt.len - 4), - 4, padwith=b"\x00"), ] - - -class SCTPChunkParamChunkList(_SCTPChunkParam, Packet): - fields_desc = [ShortEnumField("type", 0x8003, sctpchunkparamtypes), - FieldLenField("len", None, length_of="chunk_list", - adjust=lambda pkt, x:x + 4), - PadField(FieldListField("chunk_list", None, - ByteEnumField("chunk", None, sctpchunktypes), # noqa: E501 - length_from=lambda pkt: pkt.len - 4), # noqa: E501 - 4, padwith=b"\x00"), ] - - -class SCTPChunkParamRequestedHMACFunctions(_SCTPChunkParam, Packet): - fields_desc = [ShortEnumField("type", 0x8004, sctpchunkparamtypes), - FieldLenField("len", None, length_of="HMAC_functions_list", - adjust=lambda pkt, x:x + 4), - PadField(FieldListField("HMAC_functions_list", ["SHA-1"], - ShortEnumField("HMAC_function", 1, hmactypes), # noqa: E501 - length_from=lambda pkt: pkt.len - 4), # noqa: E501 - 4, padwith=b"\x00"), ] - - -class SCTPChunkParamSupportedExtensions(_SCTPChunkParam, Packet): - fields_desc = [ShortEnumField("type", 0x8008, sctpchunkparamtypes), - FieldLenField("len", None, length_of="supported_extensions", - adjust=lambda pkt, x:x + 4), - PadField(FieldListField("supported_extensions", - ["authentication", - "address-configuration", - "address-configuration-ack"], - ByteEnumField("supported_extensions", # noqa: E501 - None, sctpchunktypes), - length_from=lambda pkt: pkt.len - 4), # noqa: E501 - 4, padwith=b"\x00"), ] - - -class SCTPChunkParamFwdTSN(_SCTPChunkParam, Packet): - fields_desc = [ShortEnumField("type", 0xc000, sctpchunkparamtypes), - ShortField("len", 4), ] - - -class SCTPChunkParamAddIPAddr(_SCTPChunkParam, Packet): - fields_desc = [ShortEnumField("type", 0xc001, sctpchunkparamtypes), - FieldLenField("len", None, length_of="addr", - adjust=lambda pkt, x:x + 12), - XIntField("correlation_id", None), - ShortEnumField("addr_type", 5, sctpchunkparamtypes), - FieldLenField("addr_len", None, length_of="addr", - adjust=lambda pkt, x:x + 4), - ConditionalField( - IPField("addr", "127.0.0.1"), - lambda p: p.addr_type == 5), - ConditionalField( - IP6Field("addr", "::1"), - lambda p: p.addr_type == 6), ] - - -class SCTPChunkParamDelIPAddr(SCTPChunkParamAddIPAddr): - type = 0xc002 - - -class SCTPChunkParamErrorIndication(_SCTPChunkParam, Packet): - fields_desc = [ShortEnumField("type", 0xc003, sctpchunkparamtypes), - FieldLenField("len", None, length_of="error_causes", - adjust=lambda pkt, x:x + 8), - XIntField("correlation_id", None), - PadField(StrLenField("error_causes", "", - length_from=lambda pkt: pkt.len - 4), - 4, padwith=b"\x00"), ] - - -class SCTPChunkParamSetPrimaryAddr(SCTPChunkParamAddIPAddr): - type = 0xc004 - - -class SCTPChunkParamSuccessIndication(_SCTPChunkParam, Packet): - fields_desc = [ShortEnumField("type", 0xc005, sctpchunkparamtypes), - ShortField("len", 8), - XIntField("correlation_id", None), ] - - -class SCTPChunkParamAdaptationLayer(_SCTPChunkParam, Packet): - fields_desc = [ShortEnumField("type", 0xc006, sctpchunkparamtypes), - ShortField("len", 8), - XIntField("indication", None), ] - -# SCTP Chunks - - -# Dictionary taken from: http://www.iana.org/assignments/sctp-parameters/sctp-parameters.xhtml # noqa: E501 -SCTP_PAYLOAD_PROTOCOL_INDENTIFIERS = { - 0: 'Reserved', - 1: 'IUA', - 2: 'M2UA', - 3: 'M3UA', - 4: 'SUA', - 5: 'M2PA', - 6: 'V5UA', - 7: 'H.248', - 8: 'BICC/Q.2150.3', - 9: 'TALI', - 10: 'DUA', - 11: 'ASAP', - 12: 'ENRP', - 13: 'H.323', - 14: 'Q.IPC/Q.2150.3', - 15: 'SIMCO', - 16: 'DDP Segment Chunk', - 17: 'DDP Stream Session Control', - 18: 'S1AP', - 19: 'RUA', - 20: 'HNBAP', - 21: 'ForCES-HP', - 22: 'ForCES-MP', - 23: 'ForCES-LP', - 24: 'SBc-AP', - 25: 'NBAP', - 26: 'Unassigned', - 27: 'X2AP', - 28: 'IRCP', - 29: 'LCS-AP', - 30: 'MPICH2', - 31: 'SABP', - 32: 'FGP', - 33: 'PPP', - 34: 'CALCAPP', - 35: 'SSP', - 36: 'NPMP-CONTROL', - 37: 'NPMP-DATA', - 38: 'ECHO', - 39: 'DISCARD', - 40: 'DAYTIME', - 41: 'CHARGEN', - 42: '3GPP RNA', - 43: '3GPP M2AP', - 44: '3GPP M3AP', - 45: 'SSH/SCTP', - 46: 'Diameter/SCTP', - 47: 'Diameter/DTLS/SCTP', - 48: 'R14P', - 49: 'Unassigned', - 50: 'WebRTC DCEP', - 51: 'WebRTC String', - 52: 'WebRTC Binary Partial', - 53: 'WebRTC Binary', - 54: 'WebRTC String Partial', - 55: '3GPP PUA', - 56: 'WebRTC String Empty', - 57: 'WebRTC Binary Empty' -} - - -class SCTPChunkData(_SCTPChunkGuessPayload, Packet): - # TODO : add a padding function in post build if this layer is used to generate SCTP chunk data # noqa: E501 - 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), # noqa: E501 - XIntField("tsn", None), - XShortField("stream_id", None), - XShortField("stream_seq", None), - IntEnumField("proto_id", None, SCTP_PAYLOAD_PROTOCOL_INDENTIFIERS), # noqa: E501 - PadField(StrLenField("data", None, length_from=lambda pkt: pkt.len - 16), # noqa: E501 - 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), # noqa: E501 - 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), # noqa: E501 - ] - - -class SCTPChunkInitAck(SCTPChunkInit): - type = 2 - - -class GapAckField(Field): - def __init__(self, name, default): - Field.__init__(self, name, default, "4s") - - def i2m(self, pkt, x): - if x is None: - return b"\0\0\0\0" - sta, end = [int(e) for e in 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 isinstance(x, 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), # noqa: E501 - FieldListField("dup_tsn_list", [], XIntField("dup_tsn", None), count_from=lambda pkt:pkt.n_dup_tsn), # noqa: E501 - ] - - 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), # noqa: E501 - ChunkParamField("params", None, length_from=lambda pkt:pkt.len - 4), # noqa: E501 - ] - - -class SCTPChunkHeartbeatAck(SCTPChunkHeartbeatReq): - type = 5 - - -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), # noqa: E501 - PadField(StrLenField("error_causes", "", length_from=lambda pkt: pkt.len - 4), # noqa: E501 - 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), # noqa: E501 - PadField(StrLenField("error_causes", "", length_from=lambda pkt: pkt.len - 4), # noqa: E501 - 4, padwith=b"\x00"), - ] - - -class SCTPChunkCookieEcho(SCTPChunkError): - fields_desc = [ByteEnumField("type", 10, sctpchunktypes), - XByteField("flags", None), - FieldLenField("len", None, length_of="cookie", adjust=lambda pkt, x:x + 4), # noqa: E501 - PadField(StrLenField("cookie", "", length_from=lambda pkt: pkt.len - 4), # noqa: E501 - 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", 14, sctpchunktypes), - BitField("reserved", None, 7), - BitField("TCB", 0, 1), - ShortField("len", 4), - ] - - -class SCTPChunkAuthentication(_SCTPChunkGuessPayload, Packet): - fields_desc = [ByteEnumField("type", 15, sctpchunktypes), - XByteField("flags", None), - FieldLenField("len", None, length_of="HMAC", - adjust=lambda pkt, x:x + 8), - ShortField("shared_key_id", None), - ShortField("HMAC_function", None), - PadField(StrLenField("HMAC", "", length_from=lambda pkt: pkt.len - 8), # noqa: E501 - 4, padwith=b"\x00"), - ] - - -class SCTPChunkAddressConf(_SCTPChunkGuessPayload, Packet): - fields_desc = [ByteEnumField("type", 0xc1, sctpchunktypes), - XByteField("flags", None), - FieldLenField("len", None, length_of="params", - adjust=lambda pkt, x:x + 8), - IntField("seq", 0), - ChunkParamField("params", None, length_from=lambda pkt:pkt.len - 8), # noqa: E501 - ] - - -class SCTPChunkAddressConfAck(SCTPChunkAddressConf): - type = 0x80 - - -bind_layers(IP, SCTP, proto=IPPROTO_SCTP) -bind_layers(IPv6, SCTP, nh=IPPROTO_SCTP) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/sebek.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/sebek.py deleted file mode 100644 index c54e6728f2..0000000000 --- a/scripts/external_libs/scapy-2.4.3/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 -## 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-2.4.3/scapy/layers/sixlowpan.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/sixlowpan.py deleted file mode 100644 index d2996d5690..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/sixlowpan.py +++ /dev/null @@ -1,799 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Cesar A. Bernardini -# Intern at INRIA Grand Nancy Est -# Copyright (C) Gabriel Potter -# This program is published under a GPLv2 license -""" -6LoWPAN Protocol Stack -====================== - -This implementation follows the next documents: - * Transmission of IPv6 Packets over IEEE 802.15.4 Networks - * Compression Format for IPv6 Datagrams in Low Power and Lossy - networks (6LoWPAN): draft-ietf-6lowpan-hc-15 - * RFC 4291 - - |-----------------------| -Application | Application Protocols | - |-----------------------| -Transport | UDP | TCP | - |-----------------------| -Network | IPv6 | (Only IPv6) - |-----------------------| - | LoWPAN | (in the middle between network and data link layer) # noqa: E501 - |-----------------------| -Data Link Layer | IEEE 802.15.4 MAC | - |-----------------------| -Physical | IEEE 802.15.4 PHY | - |-----------------------| - -The Internet Control Message protocol v6 (ICMPv6) is used for control -messaging. - -Adaptation between full IPv6 and the LoWPAN format is performed by routers at -the edge of 6LoWPAN islands. - -A LoWPAN support addressing; a direct mapping between the link-layer address -and the IPv6 address is used for achieving compression. - - - -Known Issues: - * Unimplemented context information - * Next header compression techniques - * Unimplemented LoWPANBroadcast - -""" - -import socket -import struct - -from scapy.compat import chb, orb, raw - -from scapy.packet import Packet, bind_layers -from scapy.fields import BitField, ByteField, BitEnumField, BitFieldLenField, \ - XShortField, FlagsField, ConditionalField, FieldLenField - -from scapy.layers.dot15d4 import Dot15d4Data -from scapy.layers.inet6 import IPv6, IP6Field -from scapy.layers.inet import UDP - -from scapy.utils import lhex -from scapy.config import conf -from scapy.error import warning - -from scapy.packet import Raw -from scapy.pton_ntop import inet_pton, inet_ntop -from scapy.volatile import RandShort - -LINK_LOCAL_PREFIX = b"\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" # noqa: E501 - - -class IP6FieldLenField(IP6Field): - __slots__ = ["length_of"] - - def __init__(self, name, default, size, length_of=None): - IP6Field.__init__(self, name, default) - self.length_of = length_of - - def addfield(self, pkt, s, val): - """Add an internal value to a string""" - tmp_len = self.length_of(pkt) - if tmp_len == 0: - return s - internal = self.i2m(pkt, val)[-tmp_len:] - return s + struct.pack("!%ds" % tmp_len, internal) - - def getfield(self, pkt, s): - tmp_len = self.length_of(pkt) - assert tmp_len >= 0 and tmp_len <= 16 - if tmp_len <= 0: - return s, b"" - return (s[tmp_len:], - self.m2i(pkt, b"\x00" * (16 - tmp_len) + s[:tmp_len])) - - -class BitVarSizeField(BitField): - __slots__ = ["length_f"] - - def __init__(self, name, default, calculate_length=None): - BitField.__init__(self, name, default, 0) - self.length_f = calculate_length - - def addfield(self, pkt, s, val): - self.size = self.length_f(pkt) - return BitField.addfield(self, pkt, s, val) - - def getfield(self, pkt, s): - self.size = self.length_f(pkt) - return BitField.getfield(self, pkt, s) - - -class SixLoWPANAddrField(FieldLenField): - """Special field to store 6LoWPAN addresses - - 6LoWPAN Addresses have a variable length depending on other parameters. - This special field allows to save them, and encode/decode no matter which - encoding parameters they have. - """ - - def i2repr(self, pkt, x): - return lhex(self.i2h(pkt, x)) - - def addfield(self, pkt, s, val): - """Add an internal value to a string""" - if self.length_of(pkt) == 8: - return s + struct.pack(self.fmt[0] + "B", val) - if self.length_of(pkt) == 16: - return s + struct.pack(self.fmt[0] + "H", val) - if self.length_of(pkt) == 32: - return s + struct.pack(self.fmt[0] + "2H", val) # TODO: fix! - if self.length_of(pkt) == 48: - return s + struct.pack(self.fmt[0] + "3H", val) # TODO: fix! - elif self.length_of(pkt) == 64: - return s + struct.pack(self.fmt[0] + "Q", val) - elif self.length_of(pkt) == 128: - # TODO: FIX THE PACKING!! - return s + struct.pack(self.fmt[0] + "16s", raw(val)) - else: - return s - - def getfield(self, pkt, s): - if self.length_of(pkt) == 8: - return s[1:], self.m2i(pkt, struct.unpack(self.fmt[0] + "B", s[:1])[0]) # noqa: E501 - elif self.length_of(pkt) == 16: - return s[2:], self.m2i(pkt, struct.unpack(self.fmt[0] + "H", s[:2])[0]) # noqa: E501 - elif self.length_of(pkt) == 32: - return s[4:], self.m2i(pkt, struct.unpack(self.fmt[0] + "2H", s[:2], s[2:4])[0]) # noqa: E501 - elif self.length_of(pkt) == 48: - return s[6:], self.m2i(pkt, struct.unpack(self.fmt[0] + "3H", s[:2], s[2:4], s[4:6])[0]) # noqa: E501 - elif self.length_of(pkt) == 64: - return s[8:], self.m2i(pkt, struct.unpack(self.fmt[0] + "Q", s[:8])[0]) # noqa: E501 - elif self.length_of(pkt) == 128: - return s[16:], self.m2i(pkt, struct.unpack(self.fmt[0] + "16s", s[:16])[0]) # noqa: E501 - - -class LoWPANUncompressedIPv6(Packet): - name = "6LoWPAN Uncompressed IPv6" - fields_desc = [ - BitField("_type", 0x0, 8) - ] - - def default_payload_class(self, pay): - return IPv6 - - -class LoWPANMesh(Packet): - name = "6LoWPAN Mesh Packet" - fields_desc = [ - BitField("reserved", 0x2, 2), - BitEnumField("_v", 0x0, 1, [False, True]), - BitEnumField("_f", 0x0, 1, [False, True]), - BitField("_hopsLeft", 0x0, 4), - SixLoWPANAddrField("_sourceAddr", 0x0, length_of=lambda pkt: pkt._v and 2 or 8), # noqa: E501 - SixLoWPANAddrField("_destinyAddr", 0x0, length_of=lambda pkt: pkt._f and 2 or 8), # noqa: E501 - ] - - def guess_payload_class(self, payload): - # check first 2 bytes if they are ZERO it's not a 6LoWPAN packet - pass - -############################################################################### -# Fragmentation -# -# Section 5.3 - September 2007 -############################################################################### - - -class LoWPANFragmentationFirst(Packet): - name = "6LoWPAN First Fragmentation Packet" - fields_desc = [ - BitField("reserved", 0x18, 5), - BitField("datagramSize", 0x0, 11), - XShortField("datagramTag", 0x0), - ] - - -class LoWPANFragmentationSubsequent(Packet): - name = "6LoWPAN Subsequent Fragmentation Packet" - fields_desc = [ - BitField("reserved", 0x1C, 5), - BitField("datagramSize", 0x0, 11), - XShortField("datagramTag", RandShort()), - ByteField("datagramOffset", 0x0), # VALUE PRINTED IN OCTETS, wireshark does in bits (128 bits == 16 octets) # noqa: E501 - ] - - -IPHC_DEFAULT_VERSION = 6 -IPHC_DEFAULT_TF = 0 -IPHC_DEFAULT_FL = 0 - - -def source_addr_mode2(pkt): - """source_addr_mode - - This function depending on the arguments returns the amount of bits to be - used by the source address. - - Keyword arguments: - pkt -- packet object instance - """ - if pkt.sac == 0x0: - if pkt.sam == 0x0: - return 16 - elif pkt.sam == 0x1: - return 8 - elif pkt.sam == 0x2: - return 2 - elif pkt.sam == 0x3: - return 0 - else: - if pkt.sam == 0x0: - return 0 - elif pkt.sam == 0x1: - return 8 - elif pkt.sam == 0x2: - return 2 - elif pkt.sam == 0x3: - return 0 - - -def destiny_addr_mode(pkt): - """destiny_addr_mode - - This function depending on the arguments returns the amount of bits to be - used by the destiny address. - - Keyword arguments: - pkt -- packet object instance - """ - if pkt.m == 0 and pkt.dac == 0: - if pkt.dam == 0x0: - return 16 - elif pkt.dam == 0x1: - return 8 - elif pkt.dam == 0x2: - return 2 - else: - return 0 - elif pkt.m == 0 and pkt.dac == 1: - if pkt.dam == 0x0: - raise Exception('reserved') - elif pkt.dam == 0x1: - return 8 - elif pkt.dam == 0x2: - return 2 - else: - return 0 - elif pkt.m == 1 and pkt.dac == 0: - if pkt.dam == 0x0: - return 16 - elif pkt.dam == 0x1: - return 6 - elif pkt.dam == 0x2: - return 4 - elif pkt.dam == 0x3: - return 1 - elif pkt.m == 1 and pkt.dac == 1: - if pkt.dam == 0x0: - return 6 - elif pkt.dam == 0x1: - raise Exception('reserved') - elif pkt.dam == 0x2: - raise Exception('reserved') - elif pkt.dam == 0x3: - raise Exception('reserved') - - -def nhc_port(pkt): - if not pkt.nh: - return 0, 0 - if pkt.header_compression & 0x3 == 0x3: - return 4, 4 - elif pkt.header_compression & 0x2 == 0x2: - return 8, 16 - elif pkt.header_compression & 0x1 == 0x1: - return 16, 8 - else: - return 16, 16 - - -def pad_trafficclass(pkt): - """ - This function depending on the arguments returns the amount of bits to be - used by the padding of the traffic class. - - Keyword arguments: - pkt -- packet object instance - """ - if pkt.tf == 0x0: - return 4 - elif pkt.tf == 0x1: - return 2 - elif pkt.tf == 0x2: - return 0 - else: - return 0 - - -def flowlabel_len(pkt): - """ - This function depending on the arguments returns the amount of bits to be - used by the padding of the traffic class. - - Keyword arguments: - pkt -- packet object instance - """ - if pkt.tf == 0x0: - return 20 - elif pkt.tf == 0x1: - return 20 - else: - return 0 - - -def _tf_last_attempt(pkt): - if pkt.tf == 0: - return 2, 6, 4, 20 - elif pkt.tf == 1: - return 2, 0, 2, 20 - elif pkt.tf == 2: - return 2, 6, 0, 0 - else: - return 0, 0, 0, 0 - - -def _extract_dot15d4address(pkt, source=True): - """This function extracts the source/destination address of a 6LoWPAN - from its upper Dot15d4Data (802.15.4 data) layer. - - params: - - source: if True, the address is the source one. Otherwise, it is the - destination. - returns: the packed & processed address - """ - underlayer = pkt.underlayer - while underlayer is not None and not isinstance(underlayer, Dot15d4Data): # noqa: E501 - underlayer = underlayer.underlayer - if type(underlayer) == Dot15d4Data: - addr = underlayer.src_addr if source else underlayer.dest_addr - if underlayer.underlayer.fcf_destaddrmode == 3: - tmp_ip = LINK_LOCAL_PREFIX[0:8] + struct.pack(">Q", addr) # noqa: E501 - # Turn off the bit 7. - tmp_ip = tmp_ip[0:8] + struct.pack("B", (orb(tmp_ip[8]) ^ 0x2)) + tmp_ip[9:16] # noqa: E501 - elif underlayer.underlayer.fcf_destaddrmode == 2: - tmp_ip = LINK_LOCAL_PREFIX[0:8] + \ - b"\x00\x00\x00\xff\xfe\x00" + \ - struct.pack(">Q", addr)[6:] - return tmp_ip - else: - # Most of the times, it's necessary the IEEE 802.15.4 data to extract this address # noqa: E501 - raise Exception('Unimplemented: IP Header is contained into IEEE 802.15.4 frame, in this case it\'s not available.') # noqa: E501 - - -class LoWPAN_IPHC(Packet): - """6LoWPAN IPv6 header compressed packets - - It follows the implementation of draft-ietf-6lowpan-hc-15. - """ - # the LOWPAN_IPHC encoding utilizes 13 bits, 5 dispatch type - name = "LoWPAN IP Header Compression Packet" - _address_modes = ["Unspecified", "1", "16-bits inline", "Compressed"] - _state_mode = ["Stateless", "Stateful"] - fields_desc = [ - # dispatch - BitField("_reserved", 0x03, 3), - BitField("tf", 0x0, 2), - BitEnumField("nh", 0x0, 1, ["Inline", "Compressed"]), - BitField("hlim", 0x0, 2), - BitEnumField("cid", 0x0, 1, [False, True]), - BitEnumField("sac", 0x0, 1, _state_mode), - BitEnumField("sam", 0x0, 2, _address_modes), - BitEnumField("m", 0x0, 1, [False, True]), - BitEnumField("dac", 0x0, 1, _state_mode), - BitEnumField("dam", 0x0, 2, _address_modes), - ConditionalField( - ByteField("_contextIdentifierExtension", 0x0), - lambda pkt: pkt.cid == 0x1 - ), - # TODO: THIS IS WRONG!!!!! - BitVarSizeField("tc_ecn", 0, calculate_length=lambda pkt: _tf_last_attempt(pkt)[0]), # noqa: E501 - BitVarSizeField("tc_dscp", 0, calculate_length=lambda pkt: _tf_last_attempt(pkt)[1]), # noqa: E501 - BitVarSizeField("_padd", 0, calculate_length=lambda pkt: _tf_last_attempt(pkt)[2]), # noqa: E501 - BitVarSizeField("flowlabel", 0, calculate_length=lambda pkt: _tf_last_attempt(pkt)[3]), # noqa: E501 - - # NH - ConditionalField( - ByteField("_nhField", 0x0), - lambda pkt: not pkt.nh - ), - # HLIM: Hop Limit: if it's 0 - ConditionalField( - ByteField("_hopLimit", 0x0), - lambda pkt: pkt.hlim == 0x0 - ), - IP6FieldLenField("sourceAddr", "::", 0, length_of=source_addr_mode2), - IP6FieldLenField("destinyAddr", "::", 0, length_of=destiny_addr_mode), # problem when it's 0 # noqa: E501 - - # LoWPAN_UDP Header Compression ######################################## # noqa: E501 - # TODO: IMPROVE!!!!! - ConditionalField( - FlagsField("header_compression", 0, 8, ["A", "B", "C", "D", "E", "C", "PS", "PD"]), # noqa: E501 - lambda pkt: pkt.nh - ), - ConditionalField( - BitFieldLenField("udpSourcePort", 0x0, 16, length_of=lambda pkt: nhc_port(pkt)[0]), # noqa: E501 - # ShortField("udpSourcePort", 0x0), - lambda pkt: pkt.nh and pkt.header_compression & 0x2 == 0x0 - ), - ConditionalField( - BitFieldLenField("udpDestinyPort", 0x0, 16, length_of=lambda pkt: nhc_port(pkt)[1]), # noqa: E501 - lambda pkt: pkt.nh and pkt.header_compression & 0x1 == 0x0 - ), - ConditionalField( - XShortField("udpChecksum", 0x0), - lambda pkt: pkt.nh and pkt.header_compression & 0x4 == 0x0 - ), - - ] - - def post_dissect(self, data): - """dissect the IPv6 package compressed into this IPHC packet. - - The packet payload needs to be decompressed and depending on the - arguments, several conversions should be done. - """ - - # uncompress payload - packet = IPv6() - packet.version = IPHC_DEFAULT_VERSION - packet.tc, packet.fl = self._getTrafficClassAndFlowLabel() - if not self.nh: - packet.nh = self._nhField - # HLIM: Hop Limit - if self.hlim == 0: - packet.hlim = self._hopLimit - elif self.hlim == 0x1: - packet.hlim = 1 - elif self.hlim == 0x2: - packet.hlim = 64 - else: - packet.hlim = 255 - # TODO: Payload length can be inferred from lower layers from either the # noqa: E501 - # 6LoWPAN Fragmentation header or the IEEE802.15.4 header - - packet.src = self.decompressSourceAddr(packet) - packet.dst = self.decompressDestinyAddr(packet) - - if self.nh == 1: - # The Next Header field is compressed and the next header is - # encoded using LOWPAN_NHC - - packet.nh = 0x11 # UDP - udp = UDP() - if self.header_compression and \ - self.header_compression & 0x4 == 0x0: - udp.chksum = self.udpChecksum - - s, d = nhc_port(self) - if s == 16: - udp.sport = self.udpSourcePort - elif s == 8: - udp.sport = 0xF000 + s - elif s == 4: - udp.sport = 0xF0B0 + s - if d == 16: - udp.dport = self.udpDestinyPort - elif d == 8: - udp.dport = 0xF000 + d - elif d == 4: - udp.dport = 0xF0B0 + d - - packet.payload = udp / data - data = raw(packet) - # else self.nh == 0 not necessary - elif self._nhField & 0xE0 == 0xE0: # IPv6 Extension Header Decompression # noqa: E501 - warning('Unimplemented: IPv6 Extension Header decompression') # noqa: E501 - packet.payload = conf.raw_layer(data) - data = raw(packet) - else: - packet.payload = conf.raw_layer(data) - data = raw(packet) - - return Packet.post_dissect(self, data) - - def decompressDestinyAddr(self, packet): - try: - tmp_ip = inet_pton(socket.AF_INET6, self.destinyAddr) - except socket.error: - tmp_ip = b"\x00" * 16 - - if self.m == 0 and self.dac == 0: - if self.dam == 0: - pass - elif self.dam == 1: - tmp_ip = LINK_LOCAL_PREFIX[0:8] + tmp_ip[-8:] - elif self.dam == 2: - tmp_ip = LINK_LOCAL_PREFIX[0:8] + b"\x00\x00\x00\xff\xfe\x00" + tmp_ip[-2:] # noqa: E501 - elif self.dam == 3: - # TODO May need some extra changes, we are copying - # (self.m == 0 and self.dac == 1) - tmp_ip = _extract_dot15d4address(self, source=False) - - elif self.m == 0 and self.dac == 1: - if self.dam == 0: - raise Exception('Reserved') - elif self.dam == 0x3: - tmp_ip = _extract_dot15d4address(self, source=False) - elif self.dam not in [0x1, 0x2]: - warning("Unknown destiny address compression mode !") - elif self.m == 1 and self.dac == 0: - if self.dam == 0: - raise Exception("unimplemented") - elif self.dam == 1: - tmp = b"\xff" + chb(tmp_ip[16 - destiny_addr_mode(self)]) - tmp_ip = tmp + b"\x00" * 9 + tmp_ip[-5:] - elif self.dam == 2: - tmp = b"\xff" + chb(tmp_ip[16 - destiny_addr_mode(self)]) - tmp_ip = tmp + b"\x00" * 11 + tmp_ip[-3:] - else: # self.dam == 3: - tmp_ip = b"\xff\x02" + b"\x00" * 13 + tmp_ip[-1:] - elif self.m == 1 and self.dac == 1: - if self.dam == 0x0: - raise Exception("Unimplemented: I didn't understand the 6lowpan specification") # noqa: E501 - else: # all the others values - raise Exception("Reserved value by specification.") - - self.destinyAddr = inet_ntop(socket.AF_INET6, tmp_ip) - return self.destinyAddr - - def compressSourceAddr(self, ipv6): - tmp_ip = inet_pton(socket.AF_INET6, ipv6.src) - - if self.sac == 0: - if self.sam == 0x0: - tmp_ip = tmp_ip - elif self.sam == 0x1: - tmp_ip = tmp_ip[8:16] - elif self.sam == 0x2: - tmp_ip = tmp_ip[14:16] - else: # self.sam == 0x3: - pass - else: # self.sac == 1 - if self.sam == 0x0: - tmp_ip = b"\x00" * 16 - elif self.sam == 0x1: - tmp_ip = tmp_ip[8:16] - elif self.sam == 0x2: - tmp_ip = tmp_ip[14:16] - - self.sourceAddr = inet_ntop(socket.AF_INET6, b"\x00" * (16 - len(tmp_ip)) + tmp_ip) # noqa: E501 - return self.sourceAddr - - def compressDestinyAddr(self, ipv6): - tmp_ip = inet_pton(socket.AF_INET6, ipv6.dst) - - if self.m == 0 and self.dac == 0: - if self.dam == 0x0: - tmp_ip = tmp_ip - elif self.dam == 0x1: - tmp_ip = b"\x00" * 8 + tmp_ip[8:16] - elif self.dam == 0x2: - tmp_ip = b"\x00" * 14 + tmp_ip[14:16] - elif self.m == 0 and self.dac == 1: - if self.dam == 0x1: - tmp_ip = b"\x00" * 8 + tmp_ip[8:16] - elif self.dam == 0x2: - tmp_ip = b"\x00" * 14 + tmp_ip[14:16] - elif self.m == 1 and self.dac == 0: - if self.dam == 0x1: - tmp_ip = b"\x00" * 10 + tmp_ip[1:2] + tmp_ip[11:16] - elif self.dam == 0x2: - tmp_ip = b"\x00" * 12 + tmp_ip[1:2] + tmp_ip[13:16] - elif self.dam == 0x3: - tmp_ip = b"\x00" * 15 + tmp_ip[15:16] - elif self.m == 1 and self.dac == 1: - raise Exception('Unimplemented') - - self.destinyAddr = inet_ntop(socket.AF_INET6, tmp_ip) - - def decompressSourceAddr(self, packet): - try: - tmp_ip = inet_pton(socket.AF_INET6, self.sourceAddr) - except socket.error: - tmp_ip = b"\x00" * 16 - - if self.sac == 0: - if self.sam == 0x0: - pass - elif self.sam == 0x1: - tmp_ip = LINK_LOCAL_PREFIX[0:8] + tmp_ip[16 - source_addr_mode2(self):16] # noqa: E501 - elif self.sam == 0x2: - tmp = LINK_LOCAL_PREFIX[0:8] + b"\x00\x00\x00\xff\xfe\x00" - tmp_ip = tmp + tmp_ip[16 - source_addr_mode2(self):16] - elif self.sam == 0x3: # EXTRACT ADDRESS FROM Dot15d4 - tmp_ip = _extract_dot15d4address(self, source=True) - else: - warning("Unknown source address compression mode !") - else: # self.sac == 1: - if self.sam == 0x0: - pass - elif self.sam == 0x2: - # TODO: take context IID - tmp = LINK_LOCAL_PREFIX[0:8] + b"\x00\x00\x00\xff\xfe\x00" - tmp_ip = tmp + tmp_ip[16 - source_addr_mode2(self):16] - elif self.sam == 0x3: - tmp_ip = LINK_LOCAL_PREFIX[0:8] + b"\x00" * 8 # TODO: CONTEXT ID # noqa: E501 - else: - raise Exception('Unimplemented') - self.sourceAddr = inet_ntop(socket.AF_INET6, tmp_ip) - return self.sourceAddr - - def guess_payload_class(self, payload): - if self.underlayer and isinstance(self.underlayer, (LoWPANFragmentationFirst, LoWPANFragmentationSubsequent)): # noqa: E501 - return Raw - return IPv6 - - def do_build(self): - if not isinstance(self.payload, IPv6): - return Packet.do_build(self) - ipv6 = self.payload - - self._reserved = 0x03 - - # NEW COMPRESSION TECHNIQUE! - # a ) Compression Techniques - - # 1. Set Traffic Class - if self.tf == 0x0: - self.tc_ecn = ipv6.tc >> 6 - self.tc_dscp = ipv6.tc & 0x3F - self.flowlabel = ipv6.fl - elif self.tf == 0x1: - self.tc_ecn = ipv6.tc >> 6 - self.flowlabel = ipv6.fl - elif self.tf == 0x2: - self.tc_ecn = ipv6.tc >> 6 - self.tc_dscp = ipv6.tc & 0x3F - else: # self.tf == 0x3: - pass # no field is set - - # 2. Next Header - if self.nh == 0x0: - self.nh = 0 # ipv6.nh - elif self.nh == 0x1: - self.nh = 0 # disable compression - # The Next Header field is compressed and the next header is encoded using LOWPAN_NHC, which is discussed in Section 4.1. # noqa: E501 - warning('Next header compression is not implemented yet ! Will be ignored') # noqa: E501 - - # 3. HLim - if self.hlim == 0x0: - self._hopLimit = ipv6.hlim - else: # if hlim is 1, 2 or 3, there are nothing to do! - pass - - # 4. Context (which context to use...) - if self.cid == 0x0: - pass - else: - # TODO: Context Unimplemented yet in my class - self._contextIdentifierExtension = 0 - - # 5. Compress Source Addr - self.compressSourceAddr(ipv6) - self.compressDestinyAddr(ipv6) - - return Packet.do_build(self) - - def do_build_payload(self): - if self.header_compression and\ - self.header_compression & 240 == 240: # TODO: UDP header IMPROVE - return raw(self.payload)[40 + 16:] - else: - return raw(self.payload)[40:] - - def _getTrafficClassAndFlowLabel(self): - """Page 6, draft feb 2011 """ - if self.tf == 0x0: - return (self.tc_ecn << 6) + self.tc_dscp, self.flowlabel - elif self.tf == 0x1: - return (self.tc_ecn << 6), self.flowlabel - elif self.tf == 0x2: - return (self.tc_ecn << 6) + self.tc_dscp, 0 - else: - return 0, 0 - -# Old compression (deprecated) - - -class LoWPAN_HC1(Raw): - name = "LoWPAN_HC1 Compressed IPv6 (Not supported)" - - -class SixLoWPAN(Packet): - name = "SixLoWPAN(Packet)" - - @classmethod - def dispatch_hook(cls, _pkt=b"", *args, **kargs): - """Depending on the payload content, the frame type we should interpretate""" # noqa: E501 - if _pkt and len(_pkt) >= 1: - if orb(_pkt[0]) == 0x41: - return LoWPANUncompressedIPv6 - if orb(_pkt[0]) == 0x42: - return LoWPAN_HC1 - if orb(_pkt[0]) >> 3 == 0x18: - return LoWPANFragmentationFirst - elif orb(_pkt[0]) >> 3 == 0x1C: - return LoWPANFragmentationSubsequent - elif orb(_pkt[0]) >> 6 == 0x02: - return LoWPANMesh - elif orb(_pkt[0]) >> 6 == 0x01: - return LoWPAN_IPHC - return cls - - -# fragmentate IPv6 -MAX_SIZE = 96 - - -def sixlowpan_fragment(packet, datagram_tag=1): - """Split a packet into different links to transmit as 6lowpan packets. - Usage example: - >>> ipv6 = ..... (very big packet) - >>> pkts = sixlowpan_fragment(ipv6, datagram_tag=0x17) - >>> send = [Dot15d4()/Dot15d4Data()/x for x in pkts] - >>> wireshark(send) - """ - if not packet.haslayer(IPv6): - raise Exception("SixLoWPAN only fragments IPv6 packets !") - - str_packet = raw(packet[IPv6]) - - if len(str_packet) <= MAX_SIZE: - return [packet] - - def chunks(l, n): - return [l[i:i + n] for i in range(0, len(l), n)] - - new_packet = chunks(str_packet, MAX_SIZE) - - new_packet[0] = LoWPANFragmentationFirst(datagramTag=datagram_tag, datagramSize=len(str_packet)) / new_packet[0] # noqa: E501 - i = 1 - while i < len(new_packet): - new_packet[i] = LoWPANFragmentationSubsequent(datagramTag=datagram_tag, datagramSize=len(str_packet), datagramOffset=MAX_SIZE // 8 * i) / new_packet[i] # noqa: E501 - i += 1 - - return new_packet - - -def sixlowpan_defragment(packet_list): - results = {} - for p in packet_list: - cls = None - if LoWPANFragmentationFirst in p: - cls = LoWPANFragmentationFirst - elif LoWPANFragmentationSubsequent in p: - cls = LoWPANFragmentationSubsequent - if cls: - tag = p[cls].datagramTag - results[tag] = results.get(tag, b"") + p[cls].payload.load # noqa: E501 - return {tag: SixLoWPAN(x) for tag, x in results.items()} - - -bind_layers(SixLoWPAN, LoWPANFragmentationFirst,) -bind_layers(SixLoWPAN, LoWPANFragmentationSubsequent,) -bind_layers(SixLoWPAN, LoWPANMesh,) -bind_layers(SixLoWPAN, LoWPAN_IPHC,) -bind_layers(LoWPANMesh, LoWPANFragmentationFirst,) -bind_layers(LoWPANMesh, LoWPANFragmentationSubsequent,) -# TODO: I have several doubts about the Broadcast LoWPAN -# bind_layers( LoWPANBroadcast, LoWPANHC1CompressedIPv6, ) -# bind_layers( SixLoWPAN, LoWPANBroadcast, ) -# bind_layers( LoWPANMesh, LoWPANBroadcast, ) -# bind_layers( LoWPANBroadcast, LoWPANFragmentationFirst, ) -# bind_layers( LoWPANBroadcast, LoWPANFragmentationSubsequent, ) - -# TODO: find a way to chose between ZigbeeNWK and SixLoWPAN (cf. dot15d4.py) -# Currently: use conf.dot15d4_protocol value -# bind_layers(Dot15d4Data, SixLoWPAN) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/skinny.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/skinny.py deleted file mode 100644 index 7f8f074a89..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/skinny.py +++ /dev/null @@ -1,162 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Skinny Call Control Protocol (SCCP) -""" - -from scapy.packet import Packet, bind_layers -from scapy.fields import LEIntField, LEIntEnumField -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) -bind_layers(TCP, Skinny, dport=2000, sport=2000) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/smb.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/smb.py deleted file mode 100644 index 4dc42f1229..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/smb.py +++ /dev/null @@ -1,377 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -SMB (Server Message Block), also known as CIFS. -""" - -from scapy.packet import Packet, bind_layers -from scapy.fields import BitField, ByteEnumField, ByteField, FlagsField, \ - LEFieldLenField, LEIntField, LELongField, LEShortField, ShortField, \ - StrFixedLenField, StrLenField, StrNullField -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", b"\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"}), # noqa: E501 - 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"}), # noqa: E501 - 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", b"\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 Negotiate Protocol Request Tail - - -class SMBNegociate_Protocol_Request_Tail(Packet): - name = "SMB Negotiate 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", b"\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. # noqa: E501 - LEIntField("ServerTimeHigh", 0xD6228000), - LEIntField("ServerTimeLow", 0x1C4EF94), - LEShortField("ServerTimeZone", 0x3c), - ByteField("EncryptionKeyLength", 0), - LEFieldLenField("ByteCount", None, "SecurityBlob", adjust=lambda pkt, x: x - 16), # noqa: E501 - BitField("GUID", 0, 128), - StrLenField("SecurityBlob", "", length_from=lambda x: x.ByteCount + 16)] # noqa: E501 - -# SMBNegociate Protocol Response No Security -# When using no security, with EncryptionKeyLength=8, you must have an EncryptionKey before the DomainName # noqa: E501 - - -class SMBNegociate_Protocol_Response_No_Security(Packet): - name = "SMBNegociate Protocol Response No Security" - fields_desc = [StrFixedLenField("Start", b"\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. # noqa: E501 - 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", b"\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. # noqa: E501 - 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", b"\xffSMB", 4), - ByteEnumField("Command", 0x73, {0x73: "SMB_COM_SESSION_SETUP_ANDX"}), # noqa: E501 - 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"}), # noqa: E501 - 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), # noqa: E501 - 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", b"\xffSMB", 4), - ByteEnumField("Command", 0x73, {0x73: "SMB_COM_SESSION_SETUP_ANDX"}), # noqa: E501 - 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"}), # noqa: E501 - 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) # noqa: E501 -bind_layers(NBTSession, SMBNegociate_Protocol_Response_No_Security, ExtendedSecurity=0, EncryptionKeyLength=8) # noqa: E501 -bind_layers(NBTSession, SMBNegociate_Protocol_Response_No_Security_No_Key, ExtendedSecurity=0, EncryptionKeyLength=0) # noqa: E501 -bind_layers(NBTSession, SMBSession_Setup_AndX_Request, ) -bind_layers(NBTSession, SMBSession_Setup_AndX_Response, ) -bind_layers(SMBNegociate_Protocol_Request_Header, SMBNegociate_Protocol_Request_Tail, ) # noqa: E501 -bind_layers(SMBNegociate_Protocol_Request_Tail, SMBNegociate_Protocol_Request_Tail, ) # noqa: E501 diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/snmp.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/snmp.py deleted file mode 100644 index 6505995db5..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/snmp.py +++ /dev/null @@ -1,299 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -SNMP (Simple Network Management Protocol). -""" - -from __future__ import print_function -from scapy.packet import bind_layers, bind_bottom_up -from scapy.asn1packet import ASN1_Packet -from scapy.asn1fields import ASN1F_INTEGER, ASN1F_IPADDRESS, ASN1F_OID, \ - ASN1F_SEQUENCE, ASN1F_SEQUENCE_OF, ASN1F_STRING, ASN1F_TIME_TICKS, \ - ASN1F_enum_INTEGER, ASN1F_field, ASN1F_CHOICE -from scapy.asn1.asn1 import ASN1_Class_UNIVERSAL, ASN1_Codecs, ASN1_NULL, \ - ASN1_SEQUENCE -from scapy.asn1.ber import BERcodec_SEQUENCE -from scapy.sendrecv import sr1 -from scapy.volatile import RandShort, IntAutoTime -from scapy.layers.inet import UDP, IP, ICMP - -# Import needed to initialize conf.mib -from scapy.asn1.mib import conf # noqa: F401 - -########## -# 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: "resource_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) # noqa: E501 - ) - - -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) # noqa: E501 - ) - - -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), # noqa: E501 - ASN1F_INTEGER("error_index", 0), - ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) # noqa: E501 - ) - - -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) # noqa: E501 - ) - - -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), # noqa: E501 - ASN1F_INTEGER("specific_trap", 0), - ASN1F_TIME_TICKS("time_stamp", IntAutoTime()), # noqa: E501 - ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) # noqa: E501 - ) - - -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) # noqa: E501 - ) - - -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), # noqa: E501 - ASN1F_INTEGER("error_index", 0), - ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) # noqa: E501 - ) - - -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), # noqa: E501 - ASN1F_INTEGER("error_index", 0), - ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) # noqa: E501 - ) - - -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"}), # noqa: E501 - ASN1F_STRING("community", "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_bottom_up(UDP, SNMP, sport=161) -bind_bottom_up(UDP, SNMP, dport=161) -bind_bottom_up(UDP, SNMP, sport=162) -bind_bottom_up(UDP, SNMP, dport=162) -bind_layers(UDP, SNMP, sport=161, dport=161) - - -def snmpwalk(dst, oid="1", community="public"): - try: - while True: - 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) # noqa: E501 - if r is None: - print("No answers") - break - if ICMP in r: - print(repr(r)) - 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-2.4.3/scapy/layers/tftp.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tftp.py deleted file mode 100644 index e8c75c77a3..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tftp.py +++ /dev/null @@ -1,488 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -TFTP (Trivial File Transfer Protocol). -""" - -from __future__ import absolute_import -import os -import random - -from scapy.packet import Packet, bind_layers, split_bottom_up, bind_bottom_up -from scapy.fields import PacketListField, ShortEnumField, ShortField, \ - StrNullField -from scapy.automaton import ATMT, Automaton -from scapy.layers.inet import UDP, IP -from scapy.modules.six.moves import range -from scapy.config import conf -from scapy.volatile import RandShort - - -TFTP_operations = {1: "RRQ", 2: "WRQ", 3: "DATA", 4: "ACK", 5: "ERROR", 6: "OACK"} # noqa: E501 - - -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)] # noqa: E501 - - -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): # noqa: E501 - 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 = b"" - - self.l3 = IP(dst=self.server) / UDP(sport=self.my_tid, dport=self.port) / TFTP() # noqa: E501 - self.last_packet = self.l3 / TFTP_RRQ(filename=self.filename, mode="octet") # noqa: E501 - 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 = b"" - 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() # noqa: E501 - self.last_packet = self.l3 / TFTP_WRQ(filename=self.filename, mode="octet") # noqa: E501 - 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) # noqa: E501 - 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 = b"" - 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.getlayer(TFTP_Options) - self.l3 = IP(src=ip.dst, dst=ip.src) / UDP(sport=self.my_tid, dport=pkt.sport) / TFTP() # noqa: E501 - 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) # noqa: E501 - 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): - split_bottom_up(UDP, TFTP, dport=self.my_tid) - return self.filename, self.filedata - - -class TFTP_RRQ_server(Automaton): - def parse_args(self, store=None, joker=None, dir=None, ip=None, sport=None, serve_one=False, **kargs): # noqa: E501 - 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() # noqa: E501 - self.filename = pkt[TFTP_RRQ].filename.decode("utf-8", "ignore") - 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 # noqa: E501 - 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) # noqa: E501 - 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])) # noqa: E501 - - @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]) # noqa: E501 - - @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-2.4.3/scapy/layers/tls/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/__init__.py deleted file mode 100644 index 60b48ef466..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/__init__.py +++ /dev/null @@ -1,99 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -Tools for handling TLS sessions and digital certificates. -Use load_layer('tls') to load them to the main namespace. - -Prerequisites: - - - You may need to 'pip install cryptography' for the module to be loaded. - - -Main features: - - - X.509 certificates parsing/building. - - - RSA & ECDSA keys sign/verify methods. - - - TLS records and sublayers (handshake...) parsing/building. Works with - versions SSLv2 to TLS 1.2. This may be enhanced by a TLS context. For - instance, if Scapy reads a ServerHello with version TLS 1.2 and a cipher - suite using AES, it will assume the presence of IVs prepending the data. - See test/tls.uts for real examples. - - - TLS encryption/decryption capabilities with many ciphersuites, including - some which may be deemed dangerous. Once again, the TLS context enables - Scapy to transparently send/receive protected data if it learnt the - session secrets. Note that if Scapy acts as one side of the handshake - (e.g. reads all server-related packets and builds all client-related - packets), it will indeed compute the session secrets. - - - TLS client & server basic automatons, provided for testing and tweaking - purposes. These make for a very primitive TLS stack. - - - Additionally, a basic test PKI (key + certificate for a CA, a client and - a server) is provided in tls/examples/pki_test. - - -Unit tests: - - - Various cryptography checks. - - - Reading a TLS handshake between a Firefox client and a GitHub server. - - - Reading TLS 1.3 handshakes from test vectors of a draft RFC. - - - Reading a SSLv2 handshake between s_client and s_server, without PFS. - - - Test our TLS server against s_client with different cipher suites. - - - Test our TLS client against our TLS server (s_server is unscriptable). - - -TODO list (may it be carved away by good souls): - - - Features to add (or wait for) in the cryptography library: - - - X448 from RFC 7748 (no support in openssl yet); - - - the compressed EC point format. - - - - About the automatons: - - - Add resumption support, through session IDs or session tickets. - - - Add various checks for discrepancies between client and server. - Is the ServerHello ciphersuite ok? What about the SKE params? Etc. - - - Add some examples which illustrate how the automatons could be used. - Typically, we could showcase this with Heartbleed. - - - Allow the server to store both one RSA key and one ECDSA key, and - select the right one to use according to the ClientHello suites. - - - Find a way to shutdown the automatons sockets properly without - simultaneously breaking the unit tests. - - - - Miscellaneous: - - - Enhance PSK and session ticket support. - - - Define several Certificate Transparency objects. - - - Add the extended master secret and encrypt-then-mac logic. - - - Mostly unused features : DSS, fixed DH, SRP, char2 curves... -""" - -from scapy.config import conf - -if not conf.crypto_valid: - import logging - log_loading = logging.getLogger("scapy.loading") - log_loading.info("Can't import python-cryptography v1.7+. " - "Disabled PKI & TLS crypto-related features.") diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/all.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/all.py deleted file mode 100644 index c1307b039f..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/all.py +++ /dev/null @@ -1,26 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -Aggregate top level objects from all TLS modules. -""" - -# flake8: noqa: F403 - -from scapy.layers.tls.cert import * # noqa: F401 - -from scapy.layers.tls.automaton_cli import * # noqa: F401 -from scapy.layers.tls.automaton_srv import * # noqa: F401 -from scapy.layers.tls.extensions import * # noqa: F401 -from scapy.layers.tls.handshake import * # noqa: F401 -from scapy.layers.tls.handshake_sslv2 import * # noqa: F401 -from scapy.layers.tls.keyexchange import * # noqa: F401 -from scapy.layers.tls.keyexchange_tls13 import * # noqa: F401 -from scapy.layers.tls.record import * # noqa: F401 -from scapy.layers.tls.record_sslv2 import * # noqa: F401 -from scapy.layers.tls.record_tls13 import * # noqa: F401 -from scapy.layers.tls.session import * # noqa: F401 - -from scapy.layers.tls.crypto.all import * # noqa: F401 diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/automaton.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/automaton.py deleted file mode 100644 index 7d8f0fd457..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/automaton.py +++ /dev/null @@ -1,229 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -The _TLSAutomaton class provides methods common to both TLS client and server. -""" - -import struct - -from scapy.automaton import Automaton -from scapy.config import conf -from scapy.error import log_interactive -from scapy.packet import Raw -from scapy.layers.tls.basefields import _tls_type -from scapy.layers.tls.cert import Cert, PrivKey -from scapy.layers.tls.record import TLS -from scapy.layers.tls.record_sslv2 import SSLv2 -from scapy.layers.tls.record_tls13 import TLS13 - - -class _TLSAutomaton(Automaton): - """ - SSLv3 and TLS 1.0-1.2 typically need a 2-RTT handshake: - - Client Server - | --------->>> | C1 - ClientHello - | <<<--------- | S1 - ServerHello - | <<<--------- | S1 - Certificate - | <<<--------- | S1 - ServerKeyExchange - | <<<--------- | S1 - ServerHelloDone - | --------->>> | C2 - ClientKeyExchange - | --------->>> | C2 - ChangeCipherSpec - | --------->>> | C2 - Finished [encrypted] - | <<<--------- | S2 - ChangeCipherSpec - | <<<--------- | S2 - Finished [encrypted] - - We call these successive groups of messages: - ClientFlight1, ServerFlight1, ClientFlight2 and ServerFlight2. - - We want to send our messages from the same flight all at once through the - socket. This is achieved by managing a list of records in 'buffer_out'. - We may put several messages (i.e. what RFC 5246 calls the record fragments) - in the same record when possible, but we may need several records for the - same flight, as with ClientFlight2. - - However, note that the flights from the opposite side may be spread wildly - across TLS records and TCP packets. This is why we use a 'get_next_msg' - method for feeding a list of received messages, 'buffer_in'. Raw data - which has not yet been interpreted as a TLS record is kept in 'remain_in'. - """ - - def parse_args(self, mycert=None, mykey=None, **kargs): - - super(_TLSAutomaton, self).parse_args(**kargs) - - self.socket = None - self.remain_in = b"" - self.buffer_in = [] # these are 'fragments' inside records - self.buffer_out = [] # these are records - - self.cur_session = None - self.cur_pkt = None # this is usually the latest parsed packet - - if mycert: - self.mycert = Cert(mycert) - else: - self.mycert = None - - if mykey: - self.mykey = PrivKey(mykey) - else: - self.mykey = None - - self.verbose = kargs.get("verbose", True) - - def get_next_msg(self, socket_timeout=2, retry=2): - """ - The purpose of the function is to make next message(s) available in - self.buffer_in. If the list is not empty, nothing is done. If not, in - order to fill it, the function uses the data already available in - self.remain_in from a previous call and waits till there are enough to - dissect a TLS packet. Once dissected, the content of the TLS packet - (carried messages, or 'fragments') is appended to self.buffer_in. - - We have to grab enough data to dissect a TLS packet. We start by - reading the first 2 bytes. Unless we get anything different from - \\x14\\x03, \\x15\\x03, \\x16\\x03 or \\x17\\x03 (which might indicate - an SSLv2 record, whose first 2 bytes encode the length), we retrieve - 3 more bytes in order to get the length of the TLS record, and - finally we can retrieve the remaining of the record. - """ - if self.buffer_in: - # A message is already available. - return - - self.socket.settimeout(socket_timeout) - is_sslv2_msg = False - still_getting_len = True - grablen = 2 - while retry and (still_getting_len or len(self.remain_in) < grablen): - if not is_sslv2_msg and grablen == 5 and len(self.remain_in) >= 5: - grablen = struct.unpack('!H', self.remain_in[3:5])[0] + 5 - still_getting_len = False - elif grablen == 2 and len(self.remain_in) >= 2: - byte0 = struct.unpack("B", self.remain_in[:1])[0] - byte1 = struct.unpack("B", self.remain_in[1:2])[0] - if (byte0 in _tls_type) and (byte1 == 3): - # Retry following TLS scheme. This will cause failure - # for SSLv2 packets with length 0x1{4-7}03. - grablen = 5 - else: - # Extract the SSLv2 length. - is_sslv2_msg = True - still_getting_len = False - if byte0 & 0x80: - grablen = 2 + 0 + ((byte0 & 0x7f) << 8) + byte1 - else: - grablen = 2 + 1 + ((byte0 & 0x3f) << 8) + byte1 - elif not is_sslv2_msg and grablen == 5 and len(self.remain_in) >= 5: # noqa: E501 - grablen = struct.unpack('!H', self.remain_in[3:5])[0] + 5 - - if grablen == len(self.remain_in): - break - - try: - tmp = self.socket.recv(grablen - len(self.remain_in)) - if not tmp: - retry -= 1 - else: - self.remain_in += tmp - except Exception: - self.vprint("Could not join host ! Retrying...") - retry -= 1 - - if len(self.remain_in) < 2 or len(self.remain_in) != grablen: - # Remote peer is not willing to respond - return - - p = TLS(self.remain_in, tls_session=self.cur_session) - self.cur_session = p.tls_session - self.remain_in = b"" - if isinstance(p, SSLv2) and not p.msg: - p.msg = Raw("") - if self.cur_session.tls_version is None or \ - self.cur_session.tls_version < 0x0304: - self.buffer_in += p.msg - else: - if isinstance(p, TLS13): - self.buffer_in += p.inner.msg - else: - # should be TLS13ServerHello only - self.buffer_in += p.msg - - while p.payload: - if isinstance(p.payload, Raw): - self.remain_in += p.payload.load - p = p.payload - elif isinstance(p.payload, TLS): - p = p.payload - if self.cur_session.tls_version is None or \ - self.cur_session.tls_version < 0x0304: - self.buffer_in += p.msg - else: - self.buffer_in += p.inner.msg - - def raise_on_packet(self, pkt_cls, state, get_next_msg=True): - """ - If the next message to be processed has type 'pkt_cls', raise 'state'. - If there is no message waiting to be processed, we try to get one with - the default 'get_next_msg' parameters. - """ - # Maybe we already parsed the expected packet, maybe not. - if get_next_msg: - self.get_next_msg() - if (not self.buffer_in or - not isinstance(self.buffer_in[0], pkt_cls)): - return - self.cur_pkt = self.buffer_in[0] - self.buffer_in = self.buffer_in[1:] - raise state() - - def add_record(self, is_sslv2=None, is_tls13=None): - """ - Add a new TLS or SSLv2 or TLS 1.3 record to the packets buffered out. - """ - if is_sslv2 is None and is_tls13 is None: - v = (self.cur_session.tls_version or - self.cur_session.advertised_tls_version) - if v in [0x0200, 0x0002]: - is_sslv2 = True - elif v >= 0x0304: - is_tls13 = True - if is_sslv2: - self.buffer_out.append(SSLv2(tls_session=self.cur_session)) - elif is_tls13: - self.buffer_out.append(TLS13(tls_session=self.cur_session)) - else: - self.buffer_out.append(TLS(tls_session=self.cur_session)) - - def add_msg(self, pkt): - """ - Add a TLS message (e.g. TLSClientHello or TLSApplicationData) - inside the latest record to be sent through the socket. - We believe a good automaton should not use the first test. - """ - if not self.buffer_out: - self.add_record() - r = self.buffer_out[-1] - if isinstance(r, TLS13): - self.buffer_out[-1].inner.msg.append(pkt) - else: - self.buffer_out[-1].msg.append(pkt) - - def flush_records(self): - """ - Send all buffered records and update the session accordingly. - """ - s = b"".join(p.raw_stateful() for p in self.buffer_out) - self.socket.send(s) - self.buffer_out = [] - - def vprint(self, s=""): - if self.verbose: - if conf.interactive: - log_interactive.info("> %s", s) - else: - print("> %s" % s) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/automaton_cli.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/automaton_cli.py deleted file mode 100644 index 765ee5e3bd..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/automaton_cli.py +++ /dev/null @@ -1,946 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -TLS client automaton. This makes for a primitive TLS stack. -Obviously you need rights for network access. - -We support versions SSLv2 to TLS 1.2, along with many features. -There is no session resumption mechanism for now. - -In order to run a client to tcp/50000 with one cipher suite of your choice: -> from scapy.all import * -> ch = TLSClientHello(ciphers=) -> t = TLSClientAutomaton(dport=50000, client_hello=ch) -> t.run() -""" - -from __future__ import print_function -import socket - -from scapy.pton_ntop import inet_pton -from scapy.utils import randstring, repr_hex -from scapy.automaton import ATMT -from scapy.layers.tls.automaton import _TLSAutomaton -from scapy.layers.tls.basefields import _tls_version, _tls_version_options -from scapy.layers.tls.session import tlsSession -from scapy.layers.tls.extensions import TLS_Ext_SupportedGroups, \ - TLS_Ext_SupportedVersions, TLS_Ext_SignatureAlgorithms -from scapy.layers.tls.handshake import TLSCertificate, TLSCertificateRequest, \ - TLSCertificateVerify, TLSClientHello, TLSClientKeyExchange, \ - TLSEncryptedExtensions, TLSFinished, TLSServerHello, TLSServerHelloDone, \ - TLSServerKeyExchange, TLS13Certificate, TLS13ServerHello -from scapy.layers.tls.handshake_sslv2 import SSLv2ClientHello, \ - SSLv2ServerHello, SSLv2ClientMasterKey, SSLv2ServerVerify, \ - SSLv2ClientFinished, SSLv2ServerFinished, SSLv2ClientCertificate, \ - SSLv2RequestCertificate -from scapy.layers.tls.keyexchange_tls13 import TLS_Ext_KeyShare_CH, \ - KeyShareEntry -from scapy.layers.tls.record import TLSAlert, TLSChangeCipherSpec, \ - TLSApplicationData -from scapy.modules import six -from scapy.packet import Raw -from scapy.compat import bytes_encode - - -class TLSClientAutomaton(_TLSAutomaton): - """ - A simple TLS test client automaton. Try to overload some states or - conditions and see what happens on the other side. - - Rather than with an interruption, the best way to stop this client is by - typing 'quit'. This won't be a message sent to the server. - - _'mycert' and 'mykey' may be provided as filenames. They will be used in - the handshake, should the server ask for client authentication. - _'server_name' does not need to be set. - _'client_hello' may hold a TLSClientHello or SSLv2ClientHello to be sent - to the server. This is particularly useful for extensions tweaking. - _'version' is a quicker way to advertise a protocol version ("sslv2", - "tls1", "tls12", etc.) It may be overridden by the previous 'client_hello'. - _'data' is a list of raw data to be sent to the server once the handshake - has been completed. Both 'stop_server' and 'quit' will work this way. - """ - - def parse_args(self, server="127.0.0.1", dport=4433, server_name=None, - mycert=None, mykey=None, - client_hello=None, version=None, - data=None, - **kargs): - - super(TLSClientAutomaton, self).parse_args(mycert=mycert, - mykey=mykey, - **kargs) - tmp = socket.getaddrinfo(server, dport) - self.remote_name = None - try: - if ':' in server: - inet_pton(socket.AF_INET6, server) - else: - inet_pton(socket.AF_INET, server) - except Exception: - self.remote_name = socket.getfqdn(server) - if self.remote_name != server: - tmp = socket.getaddrinfo(self.remote_name, dport) - - if server_name: - self.remote_name = server_name - self.remote_family = tmp[0][0] - self.remote_ip = tmp[0][4][0] - self.remote_port = dport - self.local_ip = None - self.local_port = None - self.socket = None - - self.client_hello = client_hello - self.advertised_tls_version = None - if version: - v = _tls_version_options.get(version, None) - if not v: - self.vprint("Unrecognized TLS version option.") - else: - self.advertised_tls_version = v - - self.linebreak = False - if isinstance(data, bytes): - self.data_to_send = [data] - elif isinstance(data, six.string_types): - self.data_to_send = [bytes_encode(data)] - elif isinstance(data, list): - self.data_to_send = list(bytes_encode(d) for d in reversed(data)) - else: - self.data_to_send = [] - - def vprint_sessioninfo(self): - if self.verbose: - s = self.cur_session - v = _tls_version[s.tls_version] - self.vprint("Version : %s" % v) - cs = s.wcs.ciphersuite.name - self.vprint("Cipher suite : %s" % cs) - if s.tls_version >= 0x0304: - ms = s.tls13_master_secret - else: - ms = s.master_secret - self.vprint("Master secret : %s" % repr_hex(ms)) - if s.server_certs: - self.vprint("Server certificate chain: %r" % s.server_certs) - self.vprint() - - @ATMT.state(initial=True) - def INITIAL(self): - self.vprint("Starting TLS client automaton.") - raise self.INIT_TLS_SESSION() - - @ATMT.state() - def INIT_TLS_SESSION(self): - self.cur_session = tlsSession(connection_end="client") - self.cur_session.client_certs = self.mycert - self.cur_session.client_key = self.mykey - v = self.advertised_tls_version - if v: - self.cur_session.advertised_tls_version = v - else: - default_version = self.cur_session.advertised_tls_version - self.advertised_tls_version = default_version - raise self.CONNECT() - - @ATMT.state() - def CONNECT(self): - s = socket.socket(self.remote_family, socket.SOCK_STREAM) - self.vprint() - self.vprint("Trying to connect on %s:%d" % (self.remote_ip, - self.remote_port)) - s.connect((self.remote_ip, self.remote_port)) - self.socket = s - self.local_ip, self.local_port = self.socket.getsockname()[:2] - self.vprint() - if self.cur_session.advertised_tls_version in [0x0200, 0x0002]: - raise self.SSLv2_PREPARE_CLIENTHELLO() - elif self.cur_session.advertised_tls_version >= 0x0304: - raise self.TLS13_START() - else: - raise self.PREPARE_CLIENTFLIGHT1() - - # TLS handshake # - - @ATMT.state() - def PREPARE_CLIENTFLIGHT1(self): - self.add_record() - - @ATMT.condition(PREPARE_CLIENTFLIGHT1) - def should_add_ClientHello(self): - self.add_msg(self.client_hello or TLSClientHello()) - raise self.ADDED_CLIENTHELLO() - - @ATMT.state() - def ADDED_CLIENTHELLO(self): - pass - - @ATMT.condition(ADDED_CLIENTHELLO) - def should_send_ClientFlight1(self): - self.flush_records() - raise self.SENT_CLIENTFLIGHT1() - - @ATMT.state() - def SENT_CLIENTFLIGHT1(self): - raise self.WAITING_SERVERFLIGHT1() - - @ATMT.state() - def WAITING_SERVERFLIGHT1(self): - self.get_next_msg() - raise self.RECEIVED_SERVERFLIGHT1() - - @ATMT.state() - def RECEIVED_SERVERFLIGHT1(self): - pass - - @ATMT.condition(RECEIVED_SERVERFLIGHT1, prio=1) - def should_handle_ServerHello(self): - """ - XXX We should check the ServerHello attributes for discrepancies with - our own ClientHello. - """ - self.raise_on_packet(TLSServerHello, - self.HANDLED_SERVERHELLO) - - @ATMT.state() - def HANDLED_SERVERHELLO(self): - pass - - @ATMT.condition(RECEIVED_SERVERFLIGHT1, prio=2) - def missing_ServerHello(self): - raise self.MISSING_SERVERHELLO() - - @ATMT.state() - def MISSING_SERVERHELLO(self): - self.vprint("Missing TLS ServerHello message!") - raise self.CLOSE_NOTIFY() - - @ATMT.condition(HANDLED_SERVERHELLO, prio=1) - def should_handle_ServerCertificate(self): - if not self.cur_session.prcs.key_exchange.anonymous: - self.raise_on_packet(TLSCertificate, - self.HANDLED_SERVERCERTIFICATE) - raise self.HANDLED_SERVERCERTIFICATE() - - @ATMT.state() - def HANDLED_SERVERCERTIFICATE(self): - pass - - @ATMT.condition(HANDLED_SERVERHELLO, prio=2) - def missing_ServerCertificate(self): - raise self.MISSING_SERVERCERTIFICATE() - - @ATMT.state() - def MISSING_SERVERCERTIFICATE(self): - self.vprint("Missing TLS Certificate message!") - raise self.CLOSE_NOTIFY() - - @ATMT.state() - def HANDLED_CERTIFICATEREQUEST(self): - self.vprint("Server asked for a certificate...") - if not self.mykey or not self.mycert: - self.vprint("No client certificate to send!") - self.vprint("Will try and send an empty Certificate message...") - - @ATMT.condition(HANDLED_SERVERCERTIFICATE, prio=1) - def should_handle_ServerKeyExchange_from_ServerCertificate(self): - """ - XXX We should check the ServerKeyExchange attributes for discrepancies - with our own ClientHello, along with the ServerHello and Certificate. - """ - self.raise_on_packet(TLSServerKeyExchange, - self.HANDLED_SERVERKEYEXCHANGE) - - @ATMT.state(final=True) - def MISSING_SERVERKEYEXCHANGE(self): - pass - - @ATMT.condition(HANDLED_SERVERCERTIFICATE, prio=2) - def missing_ServerKeyExchange(self): - if not self.cur_session.prcs.key_exchange.no_ske: - raise self.MISSING_SERVERKEYEXCHANGE() - - @ATMT.state() - def HANDLED_SERVERKEYEXCHANGE(self): - pass - - def should_handle_CertificateRequest(self): - """ - XXX We should check the CertificateRequest attributes for discrepancies - with the cipher suite, etc. - """ - self.raise_on_packet(TLSCertificateRequest, - self.HANDLED_CERTIFICATEREQUEST) - - @ATMT.condition(HANDLED_SERVERKEYEXCHANGE, prio=2) - def should_handle_CertificateRequest_from_ServerKeyExchange(self): - self.should_handle_CertificateRequest() - - @ATMT.condition(HANDLED_SERVERCERTIFICATE, prio=3) - def should_handle_CertificateRequest_from_ServerCertificate(self): - self.should_handle_CertificateRequest() - - def should_handle_ServerHelloDone(self): - self.raise_on_packet(TLSServerHelloDone, - self.HANDLED_SERVERHELLODONE) - - @ATMT.condition(HANDLED_SERVERKEYEXCHANGE, prio=1) - def should_handle_ServerHelloDone_from_ServerKeyExchange(self): - return self.should_handle_ServerHelloDone() - - @ATMT.condition(HANDLED_CERTIFICATEREQUEST, prio=4) - def should_handle_ServerHelloDone_from_CertificateRequest(self): - return self.should_handle_ServerHelloDone() - - @ATMT.condition(HANDLED_SERVERCERTIFICATE, prio=4) - def should_handle_ServerHelloDone_from_ServerCertificate(self): - return self.should_handle_ServerHelloDone() - - @ATMT.state() - def HANDLED_SERVERHELLODONE(self): - raise self.PREPARE_CLIENTFLIGHT2() - - @ATMT.state() - def PREPARE_CLIENTFLIGHT2(self): - self.add_record() - - @ATMT.condition(PREPARE_CLIENTFLIGHT2, prio=1) - def should_add_ClientCertificate(self): - """ - If the server sent a CertificateRequest, we send a Certificate message. - If no certificate is available, an empty Certificate message is sent: - - this is a SHOULD in RFC 4346 (Section 7.4.6) - - this is a MUST in RFC 5246 (Section 7.4.6) - - XXX We may want to add a complete chain. - """ - hs_msg = [type(m) for m in self.cur_session.handshake_messages_parsed] - if TLSCertificateRequest not in hs_msg: - return - certs = [] - if self.mycert: - certs = [self.mycert] - self.add_msg(TLSCertificate(certs=certs)) - raise self.ADDED_CLIENTCERTIFICATE() - - @ATMT.state() - def ADDED_CLIENTCERTIFICATE(self): - pass - - def should_add_ClientKeyExchange(self): - self.add_msg(TLSClientKeyExchange()) - raise self.ADDED_CLIENTKEYEXCHANGE() - - @ATMT.condition(PREPARE_CLIENTFLIGHT2, prio=2) - def should_add_ClientKeyExchange_from_ClientFlight2(self): - return self.should_add_ClientKeyExchange() - - @ATMT.condition(ADDED_CLIENTCERTIFICATE) - def should_add_ClientKeyExchange_from_ClientCertificate(self): - return self.should_add_ClientKeyExchange() - - @ATMT.state() - def ADDED_CLIENTKEYEXCHANGE(self): - pass - - @ATMT.condition(ADDED_CLIENTKEYEXCHANGE, prio=1) - def should_add_ClientVerify(self): - """ - XXX Section 7.4.7.1 of RFC 5246 states that the CertificateVerify - message is only sent following a client certificate that has signing - capability (i.e. not those containing fixed DH params). - We should verify that before adding the message. We should also handle - the case when the Certificate message was empty. - """ - hs_msg = [type(m) for m in self.cur_session.handshake_messages_parsed] - if (TLSCertificateRequest not in hs_msg or - self.mycert is None or - self.mykey is None): - return - self.add_msg(TLSCertificateVerify()) - raise self.ADDED_CERTIFICATEVERIFY() - - @ATMT.state() - def ADDED_CERTIFICATEVERIFY(self): - pass - - @ATMT.condition(ADDED_CERTIFICATEVERIFY) - def should_add_ChangeCipherSpec_from_CertificateVerify(self): - self.add_record() - self.add_msg(TLSChangeCipherSpec()) - raise self.ADDED_CHANGECIPHERSPEC() - - @ATMT.condition(ADDED_CLIENTKEYEXCHANGE, prio=2) - def should_add_ChangeCipherSpec_from_ClientKeyExchange(self): - self.add_record() - self.add_msg(TLSChangeCipherSpec()) - raise self.ADDED_CHANGECIPHERSPEC() - - @ATMT.state() - def ADDED_CHANGECIPHERSPEC(self): - pass - - @ATMT.condition(ADDED_CHANGECIPHERSPEC) - def should_add_ClientFinished(self): - self.add_record() - self.add_msg(TLSFinished()) - raise self.ADDED_CLIENTFINISHED() - - @ATMT.state() - def ADDED_CLIENTFINISHED(self): - pass - - @ATMT.condition(ADDED_CLIENTFINISHED) - def should_send_ClientFlight2(self): - self.flush_records() - raise self.SENT_CLIENTFLIGHT2() - - @ATMT.state() - def SENT_CLIENTFLIGHT2(self): - raise self.WAITING_SERVERFLIGHT2() - - @ATMT.state() - def WAITING_SERVERFLIGHT2(self): - self.get_next_msg() - raise self.RECEIVED_SERVERFLIGHT2() - - @ATMT.state() - def RECEIVED_SERVERFLIGHT2(self): - pass - - @ATMT.condition(RECEIVED_SERVERFLIGHT2) - def should_handle_ChangeCipherSpec(self): - self.raise_on_packet(TLSChangeCipherSpec, - self.HANDLED_CHANGECIPHERSPEC) - - @ATMT.state() - def HANDLED_CHANGECIPHERSPEC(self): - pass - - @ATMT.condition(HANDLED_CHANGECIPHERSPEC) - def should_handle_Finished(self): - self.raise_on_packet(TLSFinished, - self.HANDLED_SERVERFINISHED) - - @ATMT.state() - def HANDLED_SERVERFINISHED(self): - self.vprint("TLS handshake completed!") - self.vprint_sessioninfo() - self.vprint("You may send data or use 'quit'.") - - # end of TLS handshake # - - @ATMT.condition(HANDLED_SERVERFINISHED) - def should_wait_ClientData(self): - raise self.WAIT_CLIENTDATA() - - @ATMT.state() - def WAIT_CLIENTDATA(self): - pass - - @ATMT.condition(WAIT_CLIENTDATA, prio=1) - def add_ClientData(self): - """ - The user may type in: - GET / HTTP/1.1\r\nHost: testserver.com\r\n\r\n - Special characters are handled so that it becomes a valid HTTP request. - """ - if not self.data_to_send: - data = six.moves.input().replace('\\r', '\r').replace('\\n', '\n').encode() # noqa: E501 - else: - data = self.data_to_send.pop() - if data == b"quit": - return - if self.linebreak: - data += b"\n" - self.add_record() - self.add_msg(TLSApplicationData(data=data)) - raise self.ADDED_CLIENTDATA() - - @ATMT.condition(WAIT_CLIENTDATA, prio=2) - def no_more_ClientData(self): - raise self.CLOSE_NOTIFY() - - @ATMT.state() - def ADDED_CLIENTDATA(self): - pass - - @ATMT.condition(ADDED_CLIENTDATA) - def should_send_ClientData(self): - self.flush_records() - raise self.SENT_CLIENTDATA() - - @ATMT.state() - def SENT_CLIENTDATA(self): - raise self.WAITING_SERVERDATA() - - @ATMT.state() - def WAITING_SERVERDATA(self): - self.get_next_msg(0.3, 1) - raise self.RECEIVED_SERVERDATA() - - @ATMT.state() - def RECEIVED_SERVERDATA(self): - pass - - @ATMT.condition(RECEIVED_SERVERDATA, prio=1) - def should_handle_ServerData(self): - if not self.buffer_in: - raise self.WAIT_CLIENTDATA() - p = self.buffer_in[0] - if isinstance(p, TLSApplicationData): - print("> Received: %r" % p.data) - elif isinstance(p, TLSAlert): - print("> Received: %r" % p) - raise self.CLOSE_NOTIFY() - else: - print("> Received: %r" % p) - self.buffer_in = self.buffer_in[1:] - raise self.HANDLED_SERVERDATA() - - @ATMT.state() - def HANDLED_SERVERDATA(self): - raise self.WAIT_CLIENTDATA() - - @ATMT.state() - def CLOSE_NOTIFY(self): - self.vprint() - self.vprint("Trying to send a TLSAlert to the server...") - - @ATMT.condition(CLOSE_NOTIFY) - def close_session(self): - self.add_record() - self.add_msg(TLSAlert(level=1, descr=0)) - try: - self.flush_records() - except Exception: - self.vprint("Could not send termination Alert, maybe the server stopped?") # noqa: E501 - raise self.FINAL() - - # SSLv2 handshake # - - @ATMT.state() - def SSLv2_PREPARE_CLIENTHELLO(self): - pass - - @ATMT.condition(SSLv2_PREPARE_CLIENTHELLO) - def sslv2_should_add_ClientHello(self): - self.add_record(is_sslv2=True) - p = self.client_hello or SSLv2ClientHello(challenge=randstring(16)) - self.add_msg(p) - raise self.SSLv2_ADDED_CLIENTHELLO() - - @ATMT.state() - def SSLv2_ADDED_CLIENTHELLO(self): - pass - - @ATMT.condition(SSLv2_ADDED_CLIENTHELLO) - def sslv2_should_send_ClientHello(self): - self.flush_records() - raise self.SSLv2_SENT_CLIENTHELLO() - - @ATMT.state() - def SSLv2_SENT_CLIENTHELLO(self): - raise self.SSLv2_WAITING_SERVERHELLO() - - @ATMT.state() - def SSLv2_WAITING_SERVERHELLO(self): - self.get_next_msg() - raise self.SSLv2_RECEIVED_SERVERHELLO() - - @ATMT.state() - def SSLv2_RECEIVED_SERVERHELLO(self): - pass - - @ATMT.condition(SSLv2_RECEIVED_SERVERHELLO, prio=1) - def sslv2_should_handle_ServerHello(self): - self.raise_on_packet(SSLv2ServerHello, - self.SSLv2_HANDLED_SERVERHELLO) - - @ATMT.state() - def SSLv2_HANDLED_SERVERHELLO(self): - pass - - @ATMT.condition(SSLv2_RECEIVED_SERVERHELLO, prio=2) - def sslv2_missing_ServerHello(self): - raise self.SSLv2_MISSING_SERVERHELLO() - - @ATMT.state() - def SSLv2_MISSING_SERVERHELLO(self): - self.vprint("Missing SSLv2 ServerHello message!") - raise self.SSLv2_CLOSE_NOTIFY() - - @ATMT.condition(SSLv2_HANDLED_SERVERHELLO) - def sslv2_should_add_ClientMasterKey(self): - self.add_record(is_sslv2=True) - self.add_msg(SSLv2ClientMasterKey()) - raise self.SSLv2_ADDED_CLIENTMASTERKEY() - - @ATMT.state() - def SSLv2_ADDED_CLIENTMASTERKEY(self): - pass - - @ATMT.condition(SSLv2_ADDED_CLIENTMASTERKEY) - def sslv2_should_send_ClientMasterKey(self): - self.flush_records() - raise self.SSLv2_SENT_CLIENTMASTERKEY() - - @ATMT.state() - def SSLv2_SENT_CLIENTMASTERKEY(self): - raise self.SSLv2_WAITING_SERVERVERIFY() - - @ATMT.state() - def SSLv2_WAITING_SERVERVERIFY(self): - # We give the server 0.5 second to send his ServerVerify. - # Else we assume that he's waiting for our ClientFinished. - self.get_next_msg(0.5, 0) - raise self.SSLv2_RECEIVED_SERVERVERIFY() - - @ATMT.state() - def SSLv2_RECEIVED_SERVERVERIFY(self): - pass - - @ATMT.condition(SSLv2_RECEIVED_SERVERVERIFY, prio=1) - def sslv2_should_handle_ServerVerify(self): - self.raise_on_packet(SSLv2ServerVerify, - self.SSLv2_HANDLED_SERVERVERIFY, - get_next_msg=False) - - @ATMT.state() - def SSLv2_HANDLED_SERVERVERIFY(self): - pass - - def sslv2_should_add_ClientFinished(self): - hs_msg = [type(m) for m in self.cur_session.handshake_messages_parsed] - if SSLv2ClientFinished in hs_msg: - return - self.add_record(is_sslv2=True) - self.add_msg(SSLv2ClientFinished()) - raise self.SSLv2_ADDED_CLIENTFINISHED() - - @ATMT.condition(SSLv2_HANDLED_SERVERVERIFY, prio=1) - def sslv2_should_add_ClientFinished_from_ServerVerify(self): - return self.sslv2_should_add_ClientFinished() - - @ATMT.condition(SSLv2_HANDLED_SERVERVERIFY, prio=2) - def sslv2_should_wait_ServerFinished_from_ServerVerify(self): - raise self.SSLv2_WAITING_SERVERFINISHED() - - @ATMT.condition(SSLv2_RECEIVED_SERVERVERIFY, prio=2) - def sslv2_should_add_ClientFinished_from_NoServerVerify(self): - return self.sslv2_should_add_ClientFinished() - - @ATMT.condition(SSLv2_RECEIVED_SERVERVERIFY, prio=3) - def sslv2_missing_ServerVerify(self): - raise self.SSLv2_MISSING_SERVERVERIFY() - - @ATMT.state(final=True) - def SSLv2_MISSING_SERVERVERIFY(self): - self.vprint("Missing SSLv2 ServerVerify message!") - raise self.SSLv2_CLOSE_NOTIFY() - - @ATMT.state() - def SSLv2_ADDED_CLIENTFINISHED(self): - pass - - @ATMT.condition(SSLv2_ADDED_CLIENTFINISHED) - def sslv2_should_send_ClientFinished(self): - self.flush_records() - raise self.SSLv2_SENT_CLIENTFINISHED() - - @ATMT.state() - def SSLv2_SENT_CLIENTFINISHED(self): - hs_msg = [type(m) for m in self.cur_session.handshake_messages_parsed] - if SSLv2ServerVerify in hs_msg: - raise self.SSLv2_WAITING_SERVERFINISHED() - else: - self.get_next_msg() - raise self.SSLv2_RECEIVED_SERVERVERIFY() - - @ATMT.state() - def SSLv2_WAITING_SERVERFINISHED(self): - self.get_next_msg() - raise self.SSLv2_RECEIVED_SERVERFINISHED() - - @ATMT.state() - def SSLv2_RECEIVED_SERVERFINISHED(self): - pass - - @ATMT.condition(SSLv2_RECEIVED_SERVERFINISHED, prio=1) - def sslv2_should_handle_ServerFinished(self): - self.raise_on_packet(SSLv2ServerFinished, - self.SSLv2_HANDLED_SERVERFINISHED) - - # SSLv2 client authentication # - - @ATMT.condition(SSLv2_RECEIVED_SERVERFINISHED, prio=2) - def sslv2_should_handle_RequestCertificate(self): - self.raise_on_packet(SSLv2RequestCertificate, - self.SSLv2_HANDLED_REQUESTCERTIFICATE) - - @ATMT.state() - def SSLv2_HANDLED_REQUESTCERTIFICATE(self): - self.vprint("Server asked for a certificate...") - if not self.mykey or not self.mycert: - self.vprint("No client certificate to send!") - raise self.SSLv2_CLOSE_NOTIFY() - - @ATMT.condition(SSLv2_HANDLED_REQUESTCERTIFICATE) - def sslv2_should_add_ClientCertificate(self): - self.add_record(is_sslv2=True) - self.add_msg(SSLv2ClientCertificate(certdata=self.mycert)) - raise self.SSLv2_ADDED_CLIENTCERTIFICATE() - - @ATMT.state() - def SSLv2_ADDED_CLIENTCERTIFICATE(self): - pass - - @ATMT.condition(SSLv2_ADDED_CLIENTCERTIFICATE) - def sslv2_should_send_ClientCertificate(self): - self.flush_records() - raise self.SSLv2_SENT_CLIENTCERTIFICATE() - - @ATMT.state() - def SSLv2_SENT_CLIENTCERTIFICATE(self): - raise self.SSLv2_WAITING_SERVERFINISHED() - - # end of SSLv2 client authentication # - - @ATMT.state() - def SSLv2_HANDLED_SERVERFINISHED(self): - self.vprint("SSLv2 handshake completed!") - self.vprint_sessioninfo() - self.vprint("You may send data or use 'quit'.") - - @ATMT.condition(SSLv2_RECEIVED_SERVERFINISHED, prio=3) - def sslv2_missing_ServerFinished(self): - raise self.SSLv2_MISSING_SERVERFINISHED() - - @ATMT.state() - def SSLv2_MISSING_SERVERFINISHED(self): - self.vprint("Missing SSLv2 ServerFinished message!") - raise self.SSLv2_CLOSE_NOTIFY() - - # end of SSLv2 handshake # - - @ATMT.condition(SSLv2_HANDLED_SERVERFINISHED) - def sslv2_should_wait_ClientData(self): - raise self.SSLv2_WAITING_CLIENTDATA() - - @ATMT.state() - def SSLv2_WAITING_CLIENTDATA(self): - pass - - @ATMT.condition(SSLv2_WAITING_CLIENTDATA, prio=1) - def sslv2_add_ClientData(self): - if not self.data_to_send: - data = six.moves.input().replace('\\r', '\r').replace('\\n', '\n').encode() # noqa: E501 - else: - data = self.data_to_send.pop() - self.vprint("> Read from list: %s" % data) - if data == "quit": - return - if self.linebreak: - data += "\n" - self.add_record(is_sslv2=True) - self.add_msg(Raw(data)) - raise self.SSLv2_ADDED_CLIENTDATA() - - @ATMT.condition(SSLv2_WAITING_CLIENTDATA, prio=2) - def sslv2_no_more_ClientData(self): - raise self.SSLv2_CLOSE_NOTIFY() - - @ATMT.state() - def SSLv2_ADDED_CLIENTDATA(self): - pass - - @ATMT.condition(SSLv2_ADDED_CLIENTDATA) - def sslv2_should_send_ClientData(self): - self.flush_records() - raise self.SSLv2_SENT_CLIENTDATA() - - @ATMT.state() - def SSLv2_SENT_CLIENTDATA(self): - raise self.SSLv2_WAITING_SERVERDATA() - - @ATMT.state() - def SSLv2_WAITING_SERVERDATA(self): - self.get_next_msg(0.3, 1) - raise self.SSLv2_RECEIVED_SERVERDATA() - - @ATMT.state() - def SSLv2_RECEIVED_SERVERDATA(self): - pass - - @ATMT.condition(SSLv2_RECEIVED_SERVERDATA) - def sslv2_should_handle_ServerData(self): - if not self.buffer_in: - raise self.SSLv2_WAITING_CLIENTDATA() - p = self.buffer_in[0] - print("> Received: %r" % p.load) - if p.load.startswith(b"goodbye"): - raise self.SSLv2_CLOSE_NOTIFY() - self.buffer_in = self.buffer_in[1:] - raise self.SSLv2_HANDLED_SERVERDATA() - - @ATMT.state() - def SSLv2_HANDLED_SERVERDATA(self): - raise self.SSLv2_WAITING_CLIENTDATA() - - @ATMT.state() - def SSLv2_CLOSE_NOTIFY(self): - """ - There is no proper way to end an SSLv2 session. - We try and send a 'goodbye' message as a substitute. - """ - self.vprint() - self.vprint("Trying to send a 'goodbye' to the server...") - - @ATMT.condition(SSLv2_CLOSE_NOTIFY) - def sslv2_close_session(self): - self.add_record() - self.add_msg(Raw('goodbye')) - try: - self.flush_records() - except Exception: - self.vprint("Could not send our goodbye. The server probably stopped.") # noqa: E501 - self.socket.close() - raise self.FINAL() - - # TLS 1.3 handshake # - - @ATMT.state() - def TLS13_START(self): - pass - - @ATMT.condition(TLS13_START) - def tls13_should_add_ClientHello(self): - # we have to use the legacy, plaintext TLS record here - self.add_record(is_tls13=False) - if self.client_hello: - p = self.client_hello - else: - # When trying to connect to a public TLS 1.3 server, - # you will most likely need to provide an SNI extension. - # sn = ServerName(servername="") - ext = [TLS_Ext_SupportedGroups(groups=["secp256r1"]), - # TLS_Ext_ServerName(servernames=[sn]), - TLS_Ext_KeyShare_CH(client_shares=[KeyShareEntry(group=23)]), # noqa: E501 - TLS_Ext_SupportedVersions(versions=["TLS 1.3-d18"]), - TLS_Ext_SignatureAlgorithms(sig_algs=["sha256+rsapss", - "sha256+rsa"])] - p = TLSClientHello(ciphers=0x1301, ext=ext) - self.add_msg(p) - raise self.TLS13_ADDED_CLIENTHELLO() - - @ATMT.state() - def TLS13_ADDED_CLIENTHELLO(self): - pass - - @ATMT.condition(TLS13_ADDED_CLIENTHELLO) - def tls13_should_send_ClientHello(self): - self.flush_records() - raise self.TLS13_SENT_CLIENTHELLO() - - @ATMT.state() - def TLS13_SENT_CLIENTHELLO(self): - raise self.TLS13_WAITING_SERVERHELLO() - - @ATMT.state() - def TLS13_WAITING_SERVERHELLO(self): - self.get_next_msg() - - @ATMT.condition(TLS13_WAITING_SERVERHELLO) - def tls13_should_handle_ServerHello(self): - self.raise_on_packet(TLS13ServerHello, - self.TLS13_WAITING_ENCRYPTEDEXTENSIONS) - - @ATMT.state() - def TLS13_WAITING_ENCRYPTEDEXTENSIONS(self): - self.get_next_msg() - - @ATMT.condition(TLS13_WAITING_ENCRYPTEDEXTENSIONS) - def tls13_should_handle_EncryptedExtensions(self): - self.raise_on_packet(TLSEncryptedExtensions, - self.TLS13_WAITING_CERTIFICATE) - - @ATMT.state() - def TLS13_WAITING_CERTIFICATE(self): - self.get_next_msg() - - @ATMT.condition(TLS13_WAITING_CERTIFICATE, prio=1) - def tls13_should_handle_Certificate(self): - self.raise_on_packet(TLS13Certificate, - self.TLS13_WAITING_CERTIFICATEVERIFY) - - @ATMT.condition(TLS13_WAITING_CERTIFICATE, prio=2) - def tls13_should_handle_CertificateRequest(self): - hs_msg = [type(m) for m in self.cur_session.handshake_messages_parsed] - if TLSCertificateRequest in hs_msg: - self.vprint("TLSCertificateRequest already received!") - self.raise_on_packet(TLSCertificateRequest, - self.TLS13_WAITING_CERTIFICATE) - - @ATMT.condition(TLS13_WAITING_CERTIFICATE, prio=3) - def tls13_should_handle_ServerFinished_from_EncryptedExtensions(self): - self.raise_on_packet(TLSFinished, - self.TLS13_CONNECTED) - - @ATMT.condition(TLS13_WAITING_CERTIFICATE, prio=4) - def tls13_missing_Certificate(self): - self.vprint("Missing TLS 1.3 message after EncryptedExtensions!") - raise self.FINAL() - - @ATMT.state() - def TLS13_WAITING_CERTIFICATEVERIFY(self): - self.get_next_msg() - - @ATMT.condition(TLS13_WAITING_CERTIFICATEVERIFY) - def tls13_should_handle_CertificateVerify(self): - self.raise_on_packet(TLSCertificateVerify, - self.TLS13_WAITING_SERVERFINISHED) - - @ATMT.state() - def TLS13_WAITING_SERVERFINISHED(self): - self.get_next_msg() - - @ATMT.condition(TLS13_WAITING_SERVERFINISHED) - def tls13_should_handle_ServerFinished_from_CertificateVerify(self): - self.raise_on_packet(TLSFinished, - self.TLS13_PREPARE_CLIENTFLIGHT2) - - @ATMT.state() - def TLS13_PREPARE_CLIENTFLIGHT2(self): - self.add_record(is_tls13=True) - # raise self.FINAL() - - @ATMT.condition(TLS13_PREPARE_CLIENTFLIGHT2) - def tls13_should_add_ClientFinished(self): - self.add_msg(TLSFinished()) - raise self.TLS13_ADDED_CLIENTFINISHED() - - @ATMT.state() - def TLS13_ADDED_CLIENTFINISHED(self): - pass - - @ATMT.condition(TLS13_ADDED_CLIENTFINISHED) - def tls13_should_send_ClientFlight2(self): - self.flush_records() - raise self.TLS13_SENT_CLIENTFLIGHT2() - - @ATMT.state() - def TLS13_SENT_CLIENTFLIGHT2(self): - raise self.HANDLED_SERVERFINISHED() - - @ATMT.state(final=True) - def FINAL(self): - # We might call shutdown, but it may happen that the server - # did not wait for us to shutdown after answering our data query. - # self.socket.shutdown(1) - self.vprint("Closing client socket...") - self.socket.close() - self.vprint("Ending TLS client automaton.") diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/automaton_srv.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/automaton_srv.py deleted file mode 100644 index 27fc5af414..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/automaton_srv.py +++ /dev/null @@ -1,885 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -TLS server automaton. This makes for a primitive TLS stack. -Obviously you need rights for network access. - -We support versions SSLv2 to TLS 1.2, along with many features. -There is no session resumption mechanism for now. - -In order to run a server listening on tcp/4433: -> from scapy.all import * -> t = TLSServerAutomaton(mycert='', mykey='') -> t.run() -""" - -from __future__ import print_function -import socket - -from scapy.packet import Raw -from scapy.pton_ntop import inet_pton -from scapy.utils import randstring, repr_hex -from scapy.automaton import ATMT -from scapy.layers.tls.automaton import _TLSAutomaton -from scapy.layers.tls.cert import PrivKeyRSA, PrivKeyECDSA -from scapy.layers.tls.basefields import _tls_version -from scapy.layers.tls.session import tlsSession -from scapy.layers.tls.handshake import TLSCertificate, TLSCertificateRequest, \ - TLSCertificateVerify, TLSClientHello, TLSClientKeyExchange, TLSFinished, \ - TLSServerHello, TLSServerHelloDone, TLSServerKeyExchange -from scapy.layers.tls.handshake_sslv2 import SSLv2ClientCertificate, \ - SSLv2ClientFinished, SSLv2ClientHello, SSLv2ClientMasterKey, \ - SSLv2RequestCertificate, SSLv2ServerFinished, SSLv2ServerHello, \ - SSLv2ServerVerify -from scapy.layers.tls.record import TLSAlert, TLSChangeCipherSpec, \ - TLSApplicationData -from scapy.layers.tls.crypto.suites import _tls_cipher_suites_cls, \ - get_usable_ciphersuites - - -class TLSServerAutomaton(_TLSAutomaton): - """ - A simple TLS test server automaton. Try to overload some states or - conditions and see what happens on the other side. - - Because of socket and automaton limitations, for now, the best way to - interrupt the server is by sending him 'stop_server'. Interruptions with - Ctrl-Z should work, but this might leave a loose listening socket behind. - - In case the server receives a TLSAlert (whatever its type), or a 'goodbye' - message in a SSLv2 version, he will close the client session with a - similar message, and start waiting for new client connections. - - _'mycert' and 'mykey' may be provided as filenames. They are needed for any - server authenticated handshake. - _'preferred_ciphersuite' allows the automaton to choose a cipher suite when - offered in the ClientHello. If absent, another one will be chosen. - _'client_auth' means the client has to provide a certificate. - _'is_echo_server' means that everything received will be sent back. - _'max_client_idle_time' is the maximum silence duration from the client. - Once this limit has been reached, the client (if still here) is dropped, - and we wait for a new connection. - """ - - def parse_args(self, server="127.0.0.1", sport=4433, - mycert=None, mykey=None, - preferred_ciphersuite=None, - client_auth=False, - is_echo_server=True, - max_client_idle_time=60, - **kargs): - - super(TLSServerAutomaton, self).parse_args(mycert=mycert, - mykey=mykey, - **kargs) - try: - if ':' in server: - inet_pton(socket.AF_INET6, server) - else: - inet_pton(socket.AF_INET, server) - tmp = socket.getaddrinfo(server, sport) - except Exception: - tmp = socket.getaddrinfo(socket.getfqdn(server), sport) - - self.serversocket = None - self.ip_family = tmp[0][0] - self.local_ip = tmp[0][4][0] - self.local_port = sport - self.remote_ip = None - self.remote_port = None - - self.preferred_ciphersuite = preferred_ciphersuite - self.client_auth = client_auth - self.is_echo_server = is_echo_server - self.max_client_idle_time = max_client_idle_time - - def vprint_sessioninfo(self): - if self.verbose: - s = self.cur_session - v = _tls_version[s.tls_version] - self.vprint("Version : %s" % v) - cs = s.wcs.ciphersuite.name - self.vprint("Cipher suite : %s" % cs) - ms = s.master_secret - self.vprint("Master secret : %s" % repr_hex(ms)) - if s.client_certs: - self.vprint("Client certificate chain: %r" % s.client_certs) - self.vprint() - - def http_sessioninfo(self): - header = "HTTP/1.1 200 OK\r\n" - header += "Server: Scapy TLS Extension\r\n" - header += "Content-type: text/html\r\n" - header += "Content-length: %d\r\n\r\n" - s = "----- Scapy TLS Server Automaton -----\n\n" - s += "Information on current TLS session:\n\n" - s += "Local end : %s:%d\n" % (self.local_ip, self.local_port) - s += "Remote end : %s:%d\n" % (self.remote_ip, self.remote_port) - v = _tls_version[self.cur_session.tls_version] - s += "Version : %s\n" % v - cs = self.cur_session.wcs.ciphersuite.name - s += "Cipher suite : %s\n" % cs - ms = self.cur_session.master_secret - s += "Master secret : %s\n" % repr_hex(ms) - body = "
%s
\r\n\r\n" % s - answer = (header + body) % len(body) - return answer - - @ATMT.state(initial=True) - def INITIAL(self): - self.vprint("Starting TLS server automaton.") - self.vprint("Receiving 'stop_server' will cause a graceful exit.") - self.vprint("Interrupting with Ctrl-Z might leave a loose socket hanging.") # noqa: E501 - raise self.BIND() - - @ATMT.state() - def BIND(self): - s = socket.socket(self.ip_family, socket.SOCK_STREAM) - self.serversocket = s - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - try: - s.bind((self.local_ip, self.local_port)) - s.listen(1) - except Exception as e: - m = "Unable to bind on %s:%d! (%s)" % ( - self.local_ip, - self.local_port, - e - ) - self.vprint() - self.vprint(m) - self.vprint("Maybe some server is already listening there?") - self.vprint() - raise self.FINAL() - raise self.WAITING_CLIENT() - - @ATMT.state() - def WAITING_CLIENT(self): - self.buffer_out = [] - self.buffer_in = [] - self.vprint() - self.vprint("Waiting for a new client on %s:%d" % (self.local_ip, - self.local_port)) - self.socket, addr = self.serversocket.accept() - if not isinstance(addr, tuple): - addr = self.socket.getpeername() - if len(addr) > 2: - addr = (addr[0], addr[1]) - self.remote_ip, self.remote_port = addr - self.vprint("Accepted connection from %s:%d" % (self.remote_ip, - self.remote_port)) - self.vprint() - raise self.INIT_TLS_SESSION() - - @ATMT.state() - def INIT_TLS_SESSION(self): - """ - XXX We should offer the right key according to the client's suites. For - now server_rsa_key is only used for RSAkx, but we should try to replace - every server_key with both server_rsa_key and server_ecdsa_key. - """ - self.cur_session = tlsSession(connection_end="server") - self.cur_session.server_certs = [self.mycert] - self.cur_session.server_key = self.mykey - if isinstance(self.mykey, PrivKeyRSA): - self.cur_session.server_rsa_key = self.mykey - # elif isinstance(self.mykey, PrivKeyECDSA): - # self.cur_session.server_ecdsa_key = self.mykey - raise self.WAITING_CLIENTFLIGHT1() - - @ATMT.state() - def WAITING_CLIENTFLIGHT1(self): - self.get_next_msg() - raise self.RECEIVED_CLIENTFLIGHT1() - - @ATMT.state() - def RECEIVED_CLIENTFLIGHT1(self): - pass - - # TLS handshake # - - @ATMT.condition(RECEIVED_CLIENTFLIGHT1, prio=1) - def should_handle_ClientHello(self): - self.raise_on_packet(TLSClientHello, - self.HANDLED_CLIENTHELLO) - - @ATMT.state() - def HANDLED_CLIENTHELLO(self): - raise self.PREPARE_SERVERFLIGHT1() - - @ATMT.condition(HANDLED_CLIENTHELLO) - def should_check_ciphersuites(self): - """ - We extract cipher suites candidates from the client's proposition. - """ - if isinstance(self.mykey, PrivKeyRSA): - kx = "RSA" - elif isinstance(self.mykey, PrivKeyECDSA): - kx = "ECDSA" - if get_usable_ciphersuites(self.cur_pkt.ciphers, kx): - return - raise self.NO_USABLE_CIPHERSUITE() - - @ATMT.state() - def NO_USABLE_CIPHERSUITE(self): - self.vprint("No usable cipher suite!") - raise self.CLOSE_NOTIFY() - - @ATMT.condition(RECEIVED_CLIENTFLIGHT1, prio=3) - def missing_ClientHello(self): - raise self.MISSING_CLIENTHELLO() - - @ATMT.state(final=True) - def MISSING_CLIENTHELLO(self): - self.vprint("Missing ClientHello message!") - raise self.CLOSE_NOTIFY() - - @ATMT.state() - def PREPARE_SERVERFLIGHT1(self): - self.add_record() - - @ATMT.condition(PREPARE_SERVERFLIGHT1) - def should_add_ServerHello(self): - """ - Selecting a cipher suite should be no trouble as we already caught - the None case previously. - - Also, we do not manage extensions at all. - """ - if isinstance(self.mykey, PrivKeyRSA): - kx = "RSA" - elif isinstance(self.mykey, PrivKeyECDSA): - kx = "ECDSA" - usable_suites = get_usable_ciphersuites(self.cur_pkt.ciphers, kx) - c = usable_suites[0] - if self.preferred_ciphersuite in usable_suites: - c = self.preferred_ciphersuite - self.add_msg(TLSServerHello(cipher=c)) - raise self.ADDED_SERVERHELLO() - - @ATMT.state() - def ADDED_SERVERHELLO(self): - pass - - @ATMT.condition(ADDED_SERVERHELLO) - def should_add_Certificate(self): - c = self.buffer_out[-1].msg[0].cipher - if not _tls_cipher_suites_cls[c].kx_alg.anonymous: - self.add_msg(TLSCertificate(certs=self.cur_session.server_certs)) - raise self.ADDED_CERTIFICATE() - - @ATMT.state() - def ADDED_CERTIFICATE(self): - pass - - @ATMT.condition(ADDED_CERTIFICATE) - def should_add_ServerKeyExchange(self): - c = self.buffer_out[-1].msg[0].cipher - if not _tls_cipher_suites_cls[c].kx_alg.no_ske: - self.add_msg(TLSServerKeyExchange()) - raise self.ADDED_SERVERKEYEXCHANGE() - - @ATMT.state() - def ADDED_SERVERKEYEXCHANGE(self): - pass - - @ATMT.condition(ADDED_SERVERKEYEXCHANGE) - def should_add_CertificateRequest(self): - if self.client_auth: - self.add_msg(TLSCertificateRequest()) - raise self.ADDED_CERTIFICATEREQUEST() - - @ATMT.state() - def ADDED_CERTIFICATEREQUEST(self): - pass - - @ATMT.condition(ADDED_CERTIFICATEREQUEST) - def should_add_ServerHelloDone(self): - self.add_msg(TLSServerHelloDone()) - raise self.ADDED_SERVERHELLODONE() - - @ATMT.state() - def ADDED_SERVERHELLODONE(self): - pass - - @ATMT.condition(ADDED_SERVERHELLODONE) - def should_send_ServerFlight1(self): - self.flush_records() - raise self.WAITING_CLIENTFLIGHT2() - - @ATMT.state() - def WAITING_CLIENTFLIGHT2(self): - self.get_next_msg() - raise self.RECEIVED_CLIENTFLIGHT2() - - @ATMT.state() - def RECEIVED_CLIENTFLIGHT2(self): - pass - - @ATMT.condition(RECEIVED_CLIENTFLIGHT2, prio=1) - def should_handle_ClientCertificate(self): - self.raise_on_packet(TLSCertificate, - self.HANDLED_CLIENTCERTIFICATE) - - @ATMT.condition(RECEIVED_CLIENTFLIGHT2, prio=2) - def no_ClientCertificate(self): - if self.client_auth: - raise self.MISSING_CLIENTCERTIFICATE() - raise self.HANDLED_CLIENTCERTIFICATE() - - @ATMT.state() - def MISSING_CLIENTCERTIFICATE(self): - self.vprint("Missing ClientCertificate!") - raise self.CLOSE_NOTIFY() - - @ATMT.state() - def HANDLED_CLIENTCERTIFICATE(self): - if self.client_auth: - self.vprint("Received client certificate chain...") - - @ATMT.condition(HANDLED_CLIENTCERTIFICATE, prio=1) - def should_handle_ClientKeyExchange(self): - self.raise_on_packet(TLSClientKeyExchange, - self.HANDLED_CLIENTKEYEXCHANGE) - - @ATMT.state() - def HANDLED_CLIENTKEYEXCHANGE(self): - pass - - @ATMT.condition(HANDLED_CLIENTCERTIFICATE, prio=2) - def should_handle_Alert_from_ClientCertificate(self): - self.raise_on_packet(TLSAlert, - self.HANDLED_ALERT_FROM_CLIENTCERTIFICATE) - - @ATMT.state() - def HANDLED_ALERT_FROM_CLIENTCERTIFICATE(self): - self.vprint("Received Alert message instead of ClientKeyExchange!") - raise self.CLOSE_NOTIFY() - - @ATMT.condition(HANDLED_CLIENTCERTIFICATE, prio=3) - def missing_ClientKeyExchange(self): - raise self.MISSING_CLIENTKEYEXCHANGE() - - @ATMT.state() - def MISSING_CLIENTKEYEXCHANGE(self): - self.vprint("Missing ClientKeyExchange!") - raise self.CLOSE_NOTIFY() - - @ATMT.condition(HANDLED_CLIENTKEYEXCHANGE, prio=1) - def should_handle_CertificateVerify(self): - self.raise_on_packet(TLSCertificateVerify, - self.HANDLED_CERTIFICATEVERIFY) - - @ATMT.condition(HANDLED_CLIENTKEYEXCHANGE, prio=2) - def no_CertificateVerify(self): - if self.client_auth: - raise self.MISSING_CERTIFICATEVERIFY() - raise self.HANDLED_CERTIFICATEVERIFY() - - @ATMT.state() - def MISSING_CERTIFICATEVERIFY(self): - self.vprint("Missing CertificateVerify!") - raise self.CLOSE_NOTIFY() - - @ATMT.state() - def HANDLED_CERTIFICATEVERIFY(self): - pass - - @ATMT.condition(HANDLED_CERTIFICATEVERIFY, prio=1) - def should_handle_ChangeCipherSpec(self): - self.raise_on_packet(TLSChangeCipherSpec, - self.HANDLED_CHANGECIPHERSPEC) - - @ATMT.state() - def HANDLED_CHANGECIPHERSPEC(self): - pass - - @ATMT.condition(HANDLED_CERTIFICATEVERIFY, prio=2) - def should_handle_Alert_from_ClientKeyExchange(self): - self.raise_on_packet(TLSAlert, - self.HANDLED_ALERT_FROM_CLIENTKEYEXCHANGE) - - @ATMT.state() - def HANDLED_ALERT_FROM_CLIENTKEYEXCHANGE(self): - self.vprint("Received Alert message instead of ChangeCipherSpec!") - raise self.CLOSE_NOTIFY() - - @ATMT.condition(HANDLED_CERTIFICATEVERIFY, prio=3) - def missing_ChangeCipherSpec(self): - raise self.MISSING_CHANGECIPHERSPEC() - - @ATMT.state() - def MISSING_CHANGECIPHERSPEC(self): - self.vprint("Missing ChangeCipherSpec!") - raise self.CLOSE_NOTIFY() - - @ATMT.condition(HANDLED_CHANGECIPHERSPEC, prio=1) - def should_handle_ClientFinished(self): - self.raise_on_packet(TLSFinished, - self.HANDLED_CLIENTFINISHED) - - @ATMT.state() - def HANDLED_CLIENTFINISHED(self): - raise self.PREPARE_SERVERFLIGHT2() - - @ATMT.condition(HANDLED_CHANGECIPHERSPEC, prio=2) - def should_handle_Alert_from_ClientFinished(self): - self.raise_on_packet(TLSAlert, - self.HANDLED_ALERT_FROM_CHANGECIPHERSPEC) - - @ATMT.state() - def HANDLED_ALERT_FROM_CHANGECIPHERSPEC(self): - self.vprint("Received Alert message instead of Finished!") - raise self.CLOSE_NOTIFY() - - @ATMT.condition(HANDLED_CHANGECIPHERSPEC, prio=3) - def missing_ClientFinished(self): - raise self.MISSING_CLIENTFINISHED() - - @ATMT.state() - def MISSING_CLIENTFINISHED(self): - self.vprint("Missing Finished!") - raise self.CLOSE_NOTIFY() - - @ATMT.state() - def PREPARE_SERVERFLIGHT2(self): - self.add_record() - - @ATMT.condition(PREPARE_SERVERFLIGHT2) - def should_add_ChangeCipherSpec(self): - self.add_msg(TLSChangeCipherSpec()) - raise self.ADDED_CHANGECIPHERSPEC() - - @ATMT.state() - def ADDED_CHANGECIPHERSPEC(self): - pass - - @ATMT.condition(ADDED_CHANGECIPHERSPEC) - def should_add_ServerFinished(self): - self.add_record() - self.add_msg(TLSFinished()) - raise self.ADDED_SERVERFINISHED() - - @ATMT.state() - def ADDED_SERVERFINISHED(self): - pass - - @ATMT.condition(ADDED_SERVERFINISHED) - def should_send_ServerFlight2(self): - self.flush_records() - raise self.SENT_SERVERFLIGHT2() - - @ATMT.state() - def SENT_SERVERFLIGHT2(self): - self.vprint("TLS handshake completed!") - self.vprint_sessioninfo() - if self.is_echo_server: - self.vprint("Will now act as a simple echo server.") - raise self.WAITING_CLIENTDATA() - - # end of TLS handshake # - - @ATMT.state() - def WAITING_CLIENTDATA(self): - self.get_next_msg(self.max_client_idle_time, 1) - raise self.RECEIVED_CLIENTDATA() - - @ATMT.state() - def RECEIVED_CLIENTDATA(self): - pass - - @ATMT.condition(RECEIVED_CLIENTDATA) - def should_handle_ClientData(self): - if not self.buffer_in: - self.vprint("Client idle time maxed out.") - raise self.CLOSE_NOTIFY() - p = self.buffer_in[0] - self.buffer_in = self.buffer_in[1:] - - recv_data = b"" - if isinstance(p, TLSApplicationData): - print("> Received: %r" % p.data) - recv_data = p.data - lines = recv_data.split(b"\n") - for l in lines: - if l.startswith(b"stop_server"): - raise self.CLOSE_NOTIFY_FINAL() - elif isinstance(p, TLSAlert): - print("> Received: %r" % p) - raise self.CLOSE_NOTIFY() - else: - print("> Received: %r" % p) - - if recv_data.startswith(b"GET / HTTP/1.1"): - p = TLSApplicationData(data=self.http_sessioninfo()) - - if self.is_echo_server or recv_data.startswith(b"GET / HTTP/1.1"): - self.add_record() - self.add_msg(p) - raise self.ADDED_SERVERDATA() - - raise self.HANDLED_CLIENTDATA() - - @ATMT.state() - def HANDLED_CLIENTDATA(self): - raise self.WAITING_CLIENTDATA() - - @ATMT.state() - def ADDED_SERVERDATA(self): - pass - - @ATMT.condition(ADDED_SERVERDATA) - def should_send_ServerData(self): - self.flush_records() - raise self.SENT_SERVERDATA() - - @ATMT.state() - def SENT_SERVERDATA(self): - raise self.WAITING_CLIENTDATA() - - @ATMT.state() - def CLOSE_NOTIFY(self): - self.vprint() - self.vprint("Sending a TLSAlert to the client...") - - @ATMT.condition(CLOSE_NOTIFY) - def close_session(self): - self.add_record() - self.add_msg(TLSAlert(level=1, descr=0)) - try: - self.flush_records() - except Exception: - self.vprint("Could not send termination Alert, maybe the client left?") # noqa: E501 - self.buffer_out = [] - self.socket.close() - raise self.WAITING_CLIENT() - - @ATMT.state() - def CLOSE_NOTIFY_FINAL(self): - self.vprint() - self.vprint("Sending a TLSAlert to the client...") - - @ATMT.condition(CLOSE_NOTIFY_FINAL) - def close_session_final(self): - self.add_record() - self.add_msg(TLSAlert(level=1, descr=0)) - try: - self.flush_records() - except Exception: - self.vprint("Could not send termination Alert, maybe the client left?") # noqa: E501 - # We might call shutdown, but unit tests with s_client fail with this. - # self.socket.shutdown(1) - self.socket.close() - raise self.FINAL() - - # SSLv2 handshake # - - @ATMT.condition(RECEIVED_CLIENTFLIGHT1, prio=2) - def sslv2_should_handle_ClientHello(self): - self.raise_on_packet(SSLv2ClientHello, - self.SSLv2_HANDLED_CLIENTHELLO) - - @ATMT.state() - def SSLv2_HANDLED_CLIENTHELLO(self): - pass - - @ATMT.condition(SSLv2_HANDLED_CLIENTHELLO) - def sslv2_should_add_ServerHello(self): - self.add_record(is_sslv2=True) - cert = self.mycert - ciphers = [0x010080, 0x020080, 0x030080, 0x040080, - 0x050080, 0x060040, 0x0700C0] - connection_id = randstring(16) - p = SSLv2ServerHello(cert=cert, - ciphers=ciphers, - connection_id=connection_id) - self.add_msg(p) - raise self.SSLv2_ADDED_SERVERHELLO() - - @ATMT.state() - def SSLv2_ADDED_SERVERHELLO(self): - pass - - @ATMT.condition(SSLv2_ADDED_SERVERHELLO) - def sslv2_should_send_ServerHello(self): - self.flush_records() - raise self.SSLv2_SENT_SERVERHELLO() - - @ATMT.state() - def SSLv2_SENT_SERVERHELLO(self): - raise self.SSLv2_WAITING_CLIENTMASTERKEY() - - @ATMT.state() - def SSLv2_WAITING_CLIENTMASTERKEY(self): - self.get_next_msg() - raise self.SSLv2_RECEIVED_CLIENTMASTERKEY() - - @ATMT.state() - def SSLv2_RECEIVED_CLIENTMASTERKEY(self): - pass - - @ATMT.condition(SSLv2_RECEIVED_CLIENTMASTERKEY, prio=1) - def sslv2_should_handle_ClientMasterKey(self): - self.raise_on_packet(SSLv2ClientMasterKey, - self.SSLv2_HANDLED_CLIENTMASTERKEY) - - @ATMT.condition(SSLv2_RECEIVED_CLIENTMASTERKEY, prio=2) - def missing_ClientMasterKey(self): - raise self.SSLv2_MISSING_CLIENTMASTERKEY() - - @ATMT.state() - def SSLv2_MISSING_CLIENTMASTERKEY(self): - self.vprint("Missing SSLv2 ClientMasterKey!") - raise self.SSLv2_CLOSE_NOTIFY() - - @ATMT.state() - def SSLv2_HANDLED_CLIENTMASTERKEY(self): - raise self.SSLv2_RECEIVED_CLIENTFINISHED() - - @ATMT.state() - def SSLv2_RECEIVED_CLIENTFINISHED(self): - pass - - @ATMT.condition(SSLv2_RECEIVED_CLIENTFINISHED, prio=1) - def sslv2_should_handle_ClientFinished(self): - self.raise_on_packet(SSLv2ClientFinished, - self.SSLv2_HANDLED_CLIENTFINISHED) - - @ATMT.state() - def SSLv2_HANDLED_CLIENTFINISHED(self): - pass - - @ATMT.condition(SSLv2_HANDLED_CLIENTFINISHED, prio=1) - def sslv2_should_add_ServerVerify_from_ClientFinished(self): - hs_msg = [type(m) for m in self.cur_session.handshake_messages_parsed] - if SSLv2ServerVerify in hs_msg: - return - self.add_record(is_sslv2=True) - p = SSLv2ServerVerify(challenge=self.cur_session.sslv2_challenge) - self.add_msg(p) - raise self.SSLv2_ADDED_SERVERVERIFY() - - @ATMT.condition(SSLv2_RECEIVED_CLIENTFINISHED, prio=2) - def sslv2_should_add_ServerVerify_from_NoClientFinished(self): - hs_msg = [type(m) for m in self.cur_session.handshake_messages_parsed] - if SSLv2ServerVerify in hs_msg: - return - self.add_record(is_sslv2=True) - p = SSLv2ServerVerify(challenge=self.cur_session.sslv2_challenge) - self.add_msg(p) - raise self.SSLv2_ADDED_SERVERVERIFY() - - @ATMT.condition(SSLv2_RECEIVED_CLIENTFINISHED, prio=3) - def sslv2_missing_ClientFinished(self): - raise self.SSLv2_MISSING_CLIENTFINISHED() - - @ATMT.state() - def SSLv2_MISSING_CLIENTFINISHED(self): - self.vprint("Missing SSLv2 ClientFinished!") - raise self.SSLv2_CLOSE_NOTIFY() - - @ATMT.state() - def SSLv2_ADDED_SERVERVERIFY(self): - pass - - @ATMT.condition(SSLv2_ADDED_SERVERVERIFY) - def sslv2_should_send_ServerVerify(self): - self.flush_records() - raise self.SSLv2_SENT_SERVERVERIFY() - - @ATMT.state() - def SSLv2_SENT_SERVERVERIFY(self): - hs_msg = [type(m) for m in self.cur_session.handshake_messages_parsed] - if SSLv2ClientFinished in hs_msg: - raise self.SSLv2_HANDLED_CLIENTFINISHED() - else: - raise self.SSLv2_RECEIVED_CLIENTFINISHED() - - # SSLv2 client authentication # - - @ATMT.condition(SSLv2_HANDLED_CLIENTFINISHED, prio=2) - def sslv2_should_add_RequestCertificate(self): - hs_msg = [type(m) for m in self.cur_session.handshake_messages_parsed] - if not self.client_auth or SSLv2RequestCertificate in hs_msg: - return - self.add_record(is_sslv2=True) - self.add_msg(SSLv2RequestCertificate(challenge=randstring(16))) - raise self.SSLv2_ADDED_REQUESTCERTIFICATE() - - @ATMT.state() - def SSLv2_ADDED_REQUESTCERTIFICATE(self): - pass - - @ATMT.condition(SSLv2_ADDED_REQUESTCERTIFICATE) - def sslv2_should_send_RequestCertificate(self): - self.flush_records() - raise self.SSLv2_SENT_REQUESTCERTIFICATE() - - @ATMT.state() - def SSLv2_SENT_REQUESTCERTIFICATE(self): - raise self.SSLv2_WAITING_CLIENTCERTIFICATE() - - @ATMT.state() - def SSLv2_WAITING_CLIENTCERTIFICATE(self): - self.get_next_msg() - raise self.SSLv2_RECEIVED_CLIENTCERTIFICATE() - - @ATMT.state() - def SSLv2_RECEIVED_CLIENTCERTIFICATE(self): - pass - - @ATMT.condition(SSLv2_RECEIVED_CLIENTCERTIFICATE, prio=1) - def sslv2_should_handle_ClientCertificate(self): - self.raise_on_packet(SSLv2ClientCertificate, - self.SSLv2_HANDLED_CLIENTCERTIFICATE) - - @ATMT.condition(SSLv2_RECEIVED_CLIENTCERTIFICATE, prio=2) - def sslv2_missing_ClientCertificate(self): - raise self.SSLv2_MISSING_CLIENTCERTIFICATE() - - @ATMT.state() - def SSLv2_MISSING_CLIENTCERTIFICATE(self): - self.vprint("Missing SSLv2 ClientCertificate!") - raise self.SSLv2_CLOSE_NOTIFY() - - @ATMT.state() - def SSLv2_HANDLED_CLIENTCERTIFICATE(self): - self.vprint("Received client certificate...") - # We could care about the client CA, but we don't. - raise self.SSLv2_HANDLED_CLIENTFINISHED() - - # end of SSLv2 client authentication # - - @ATMT.condition(SSLv2_HANDLED_CLIENTFINISHED, prio=3) - def sslv2_should_add_ServerFinished(self): - self.add_record(is_sslv2=True) - self.add_msg(SSLv2ServerFinished(sid=randstring(16))) - raise self.SSLv2_ADDED_SERVERFINISHED() - - @ATMT.state() - def SSLv2_ADDED_SERVERFINISHED(self): - pass - - @ATMT.condition(SSLv2_ADDED_SERVERFINISHED) - def sslv2_should_send_ServerFinished(self): - self.flush_records() - raise self.SSLv2_SENT_SERVERFINISHED() - - @ATMT.state() - def SSLv2_SENT_SERVERFINISHED(self): - self.vprint("SSLv2 handshake completed!") - self.vprint_sessioninfo() - if self.is_echo_server: - self.vprint("Will now act as a simple echo server.") - raise self.SSLv2_WAITING_CLIENTDATA() - - # end of SSLv2 handshake # - - @ATMT.state() - def SSLv2_WAITING_CLIENTDATA(self): - self.get_next_msg(self.max_client_idle_time, 1) - raise self.SSLv2_RECEIVED_CLIENTDATA() - - @ATMT.state() - def SSLv2_RECEIVED_CLIENTDATA(self): - pass - - @ATMT.condition(SSLv2_RECEIVED_CLIENTDATA) - def sslv2_should_handle_ClientData(self): - if not self.buffer_in: - self.vprint("Client idle time maxed out.") - raise self.SSLv2_CLOSE_NOTIFY() - p = self.buffer_in[0] - self.buffer_in = self.buffer_in[1:] - if hasattr(p, "load"): - cli_data = p.load - print("> Received: %r" % cli_data) - if cli_data.startswith(b"goodbye"): - self.vprint() - self.vprint("Seems like the client left...") - raise self.WAITING_CLIENT() - else: - cli_data = str(p) - print("> Received: %r" % p) - - lines = cli_data.split(b"\n") - for l in lines: - if l.startswith(b"stop_server"): - raise self.SSLv2_CLOSE_NOTIFY_FINAL() - - if cli_data.startswith(b"GET / HTTP/1.1"): - p = Raw(self.http_sessioninfo()) - - if self.is_echo_server or cli_data.startswith(b"GET / HTTP/1.1"): - self.add_record(is_sslv2=True) - self.add_msg(p) - raise self.SSLv2_ADDED_SERVERDATA() - - raise self.SSLv2_HANDLED_CLIENTDATA() - - @ATMT.state() - def SSLv2_HANDLED_CLIENTDATA(self): - raise self.SSLv2_WAITING_CLIENTDATA() - - @ATMT.state() - def SSLv2_ADDED_SERVERDATA(self): - pass - - @ATMT.condition(SSLv2_ADDED_SERVERDATA) - def sslv2_should_send_ServerData(self): - self.flush_records() - raise self.SSLv2_SENT_SERVERDATA() - - @ATMT.state() - def SSLv2_SENT_SERVERDATA(self): - raise self.SSLv2_WAITING_CLIENTDATA() - - @ATMT.state() - def SSLv2_CLOSE_NOTIFY(self): - """ - There is no proper way to end an SSLv2 session. - We try and send a 'goodbye' message as a substitute. - """ - self.vprint() - self.vprint("Trying to send 'goodbye' to the client...") - - @ATMT.condition(SSLv2_CLOSE_NOTIFY) - def sslv2_close_session(self): - self.add_record() - self.add_msg(Raw('goodbye')) - try: - self.flush_records() - except Exception: - self.vprint("Could not send our goodbye. The client probably left.") # noqa: E501 - self.buffer_out = [] - self.socket.close() - raise self.WAITING_CLIENT() - - @ATMT.state() - def SSLv2_CLOSE_NOTIFY_FINAL(self): - """ - There is no proper way to end an SSLv2 session. - We try and send a 'goodbye' message as a substitute. - """ - self.vprint() - self.vprint("Trying to send 'goodbye' to the client...") - - @ATMT.condition(SSLv2_CLOSE_NOTIFY_FINAL) - def sslv2_close_session_final(self): - self.add_record() - self.add_msg(Raw('goodbye')) - try: - self.flush_records() - except Exception: - self.vprint("Could not send our goodbye. The client probably left.") # noqa: E501 - self.socket.close() - raise self.FINAL() - - @ATMT.state(final=True) - def FINAL(self): - self.vprint("Closing server socket...") - self.serversocket.close() - self.vprint("Ending TLS server automaton.") diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/basefields.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/basefields.py deleted file mode 100644 index 752b562ec1..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/basefields.py +++ /dev/null @@ -1,262 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -TLS base fields, used for record parsing/building. As several operations depend -upon the TLS version or ciphersuite, the packet has to provide a TLS context. -""" -import struct - -from scapy.fields import ByteField, ShortEnumField, ShortField, StrField -import scapy.modules.six as six -from scapy.compat import orb - -_tls_type = {20: "change_cipher_spec", - 21: "alert", - 22: "handshake", - 23: "application_data"} - -_tls_version = {0x0002: "SSLv2", - 0x0200: "SSLv2", - 0x0300: "SSLv3", - 0x0301: "TLS 1.0", - 0x0302: "TLS 1.1", - 0x0303: "TLS 1.2", - 0x7f12: "TLS 1.3-d18", - 0x7f13: "TLS 1.3-d19", - 0x0304: "TLS 1.3"} - -_tls_version_options = {"sslv2": 0x0002, - "sslv3": 0x0300, - "tls1": 0x0301, - "tls10": 0x0301, - "tls11": 0x0302, - "tls12": 0x0303, - "tls13-d18": 0x7f12, - "tls13-d19": 0x7f13, - "tls13": 0x0304} - - -def _tls13_version_filter(version, legacy_version): - if version < 0x0304: - return version - else: - return legacy_version - - -class _TLSClientVersionField(ShortEnumField): - """ - We use the advertised_tls_version if it has been defined, - and the legacy 0x0303 for TLS 1.3 packets. - """ - - def i2h(self, pkt, x): - if x is None: - v = pkt.tls_session.advertised_tls_version - if v: - return _tls13_version_filter(v, 0x0303) - return "" - return x - - def i2m(self, pkt, x): - if x is None: - v = pkt.tls_session.advertised_tls_version - if v: - return _tls13_version_filter(v, 0x0303) - return b"" - return x - - -class _TLSVersionField(ShortEnumField): - """ - We use the tls_version if it has been defined, else the advertised version. - Also, the legacy 0x0301 is used for TLS 1.3 packets. - """ - - def i2h(self, pkt, x): - if x is None: - v = pkt.tls_session.tls_version - if v: - return _tls13_version_filter(v, 0x0301) - else: - adv_v = pkt.tls_session.advertised_tls_version - return _tls13_version_filter(adv_v, 0x0301) - return x - - def i2m(self, pkt, x): - if x is None: - v = pkt.tls_session.tls_version - if v: - return _tls13_version_filter(v, 0x0301) - else: - adv_v = pkt.tls_session.advertised_tls_version - return _tls13_version_filter(adv_v, 0x0301) - return x - - -class _TLSLengthField(ShortField): - def i2repr(self, pkt, x): - s = super(_TLSLengthField, self).i2repr(pkt, x) - if pkt.deciphered_len is not None: - dx = pkt.deciphered_len - ds = super(_TLSLengthField, self).i2repr(pkt, dx) - s += " [deciphered_len= %s]" % ds - return s - - -class _TLSIVField(StrField): - """ - As stated in Section 6.2.3.2. RFC 4346, TLS 1.1 implements an explicit IV - mechanism. For that reason, the behavior of the field is dependent on the - TLS version found in the packet if available or otherwise (on build, if - not overloaded, it is provided by the session). The size of the IV and - its value are obviously provided by the session. As a side note, for the - first packets exchanged by peers, NULL being the default enc alg, it is - empty (except if forced to a specific value). Also note that the field is - kept empty (unless forced to a specific value) when the cipher is a stream - cipher (and NULL is considered a stream cipher). - """ - - def i2len(self, pkt, i): - if i is not None: - return len(i) - tmp_len = 0 - cipher_type = pkt.tls_session.rcs.cipher.type - if cipher_type == "block": - if pkt.tls_session.tls_version >= 0x0302: - tmp_len = pkt.tls_session.rcs.cipher.block_size - elif cipher_type == "aead": - tmp_len = pkt.tls_session.rcs.cipher.nonce_explicit_len - return tmp_len - - def i2m(self, pkt, x): - return x or b"" - - def addfield(self, pkt, s, val): - return s + self.i2m(pkt, val) - - def getfield(self, pkt, s): - tmp_len = 0 - cipher_type = pkt.tls_session.rcs.cipher.type - if cipher_type == "block": - if pkt.tls_session.tls_version >= 0x0302: - tmp_len = pkt.tls_session.rcs.cipher.block_size - elif cipher_type == "aead": - tmp_len = pkt.tls_session.rcs.cipher.nonce_explicit_len - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - - def i2repr(self, pkt, x): - return repr(self.i2m(pkt, x)) - - -class _TLSMACField(StrField): - def i2len(self, pkt, i): - if i is not None: - return len(i) - return pkt.tls_session.wcs.mac_len - - def i2m(self, pkt, x): - if x is None: - return b"" - return x - - def addfield(self, pkt, s, val): - # We add nothing here. This is done in .post_build() if needed. - return s - - def getfield(self, pkt, s): - if (pkt.tls_session.rcs.cipher.type != "aead" and - False in six.itervalues(pkt.tls_session.rcs.cipher.ready)): - # XXX Find a more proper way to handle the still-encrypted case - return s, b"" - tmp_len = pkt.tls_session.rcs.mac_len - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - - def i2repr(self, pkt, x): - # XXX Provide status when dissection has been performed successfully? - return repr(self.i2m(pkt, x)) - - -class _TLSPadField(StrField): - def i2len(self, pkt, i): - if i is not None: - return len(i) - return 0 - - def i2m(self, pkt, x): - if x is None: - return b"" - return x - - def addfield(self, pkt, s, val): - # We add nothing here. This is done in .post_build() if needed. - return s - - def getfield(self, pkt, s): - if pkt.tls_session.consider_read_padding(): - # This should work with SSLv3 and also TLS versions. - # Note that we need to retrieve pkt.padlen beforehand, - # because it's possible that the padding is followed by some data - # from another TLS record (hence the last byte from s would not be - # the last byte from the current record padding). - tmp_len = orb(s[pkt.padlen - 1]) - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - return s, None - - def i2repr(self, pkt, x): - # XXX Provide status when dissection has been performed successfully? - return repr(self.i2m(pkt, x)) - - -class _TLSPadLenField(ByteField): - def addfield(self, pkt, s, val): - # We add nothing here. This is done in .post_build() if needed. - return s - - def getfield(self, pkt, s): - if pkt.tls_session.consider_read_padding(): - return ByteField.getfield(self, pkt, s) - return s, None - - -# SSLv2 fields - -class _SSLv2LengthField(_TLSLengthField): - def i2repr(self, pkt, x): - s = super(_SSLv2LengthField, self).i2repr(pkt, x) - if pkt.with_padding: - x |= 0x8000 - # elif pkt.with_escape: #XXX no complete support for 'escape' yet - # x |= 0x4000 - s += " [with padding: %s]" % hex(x) - return s - - def getfield(self, pkt, s): - msglen = struct.unpack('!H', s[:2])[0] - pkt.with_padding = (msglen & 0x8000) == 0 - if pkt.with_padding: - msglen_clean = msglen & 0x3fff - else: - msglen_clean = msglen & 0x7fff - return s[2:], msglen_clean - - -class _SSLv2MACField(_TLSMACField): - pass - - -class _SSLv2PadField(_TLSPadField): - def getfield(self, pkt, s): - if pkt.padlen is not None: - tmp_len = pkt.padlen - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - return s, None - - -class _SSLv2PadLenField(_TLSPadLenField): - def getfield(self, pkt, s): - if pkt.with_padding: - return ByteField.getfield(self, pkt, s) - return s, None diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/cert.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/cert.py deleted file mode 100644 index dafca99280..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/cert.py +++ /dev/null @@ -1,1005 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2008 Arnaud Ebalard -# -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -High-level methods for PKI objects (X.509 certificates, CRLs, asymmetric keys). -Supports both RSA and ECDSA objects. - -The classes below are wrappers for the ASN.1 objects defined in x509.py. -By collecting their attributes, we bypass the ASN.1 structure, hence -there is no direct method for exporting a new full DER-encoded version -of a Cert instance after its serial has been modified (for example). -If you need to modify an import, just use the corresponding ASN1_Packet. - -For instance, here is what you could do in order to modify the serial of -'cert' and then resign it with whatever 'key': - f = open('cert.der') - c = X509_Cert(f.read()) - c.tbsCertificate.serialNumber = 0x4B1D - k = PrivKey('key.pem') - new_x509_cert = k.resignCert(c) -No need for obnoxious openssl tweaking anymore. :) -""" - -from __future__ import absolute_import -from __future__ import print_function -import base64 -import os -import time - -from scapy.config import conf, crypto_validator -import scapy.modules.six as six -from scapy.modules.six.moves import range -from scapy.error import warning -from scapy.utils import binrepr -from scapy.asn1.asn1 import ASN1_BIT_STRING -from scapy.asn1.mib import hash_by_oid -from scapy.layers.x509 import (X509_SubjectPublicKeyInfo, - RSAPublicKey, RSAPrivateKey, - ECDSAPublicKey, ECDSAPrivateKey, - RSAPrivateKey_OpenSSL, ECDSAPrivateKey_OpenSSL, - X509_Cert, X509_CRL) -from scapy.layers.tls.crypto.pkcs1 import pkcs_os2ip, _get_hash, \ - _EncryptAndVerifyRSA, _DecryptAndSignRSA -from scapy.compat import raw, bytes_encode -if conf.crypto_valid: - from cryptography.hazmat.backends import default_backend - from cryptography.hazmat.primitives import serialization - from cryptography.hazmat.primitives.asymmetric import rsa, ec -if conf.crypto_valid_recent: - from cryptography.hazmat.backends.openssl.ec import InvalidSignature - - -# Maximum allowed size in bytes for a certificate file, to avoid -# loading huge file when importing a cert -_MAX_KEY_SIZE = 50 * 1024 -_MAX_CERT_SIZE = 50 * 1024 -_MAX_CRL_SIZE = 10 * 1024 * 1024 # some are that big - - -##################################################################### -# Some helpers -##################################################################### - -@conf.commands.register -def der2pem(der_string, obj="UNKNOWN"): - """Convert DER octet string to PEM format (with optional header)""" - # Encode a byte string in PEM format. Header advertizes type. - pem_string = ("-----BEGIN %s-----\n" % obj).encode() - base64_string = base64.b64encode(der_string) - chunks = [base64_string[i:i + 64] for i in range(0, len(base64_string), 64)] # noqa: E501 - pem_string += b'\n'.join(chunks) - pem_string += ("\n-----END %s-----\n" % obj).encode() - return pem_string - - -@conf.commands.register -def pem2der(pem_string): - """Convert PEM string to DER format""" - # Encode all lines between the first '-----\n' and the 2nd-to-last '-----'. - pem_string = pem_string.replace(b"\r", b"") - first_idx = pem_string.find(b"-----\n") + 6 - if pem_string.find(b"-----BEGIN", first_idx) != -1: - raise Exception("pem2der() expects only one PEM-encoded object") - last_idx = pem_string.rfind(b"-----", 0, pem_string.rfind(b"-----")) - base64_string = pem_string[first_idx:last_idx] - base64_string.replace(b"\n", b"") - der_string = base64.b64decode(base64_string) - return der_string - - -def split_pem(s): - """ - Split PEM objects. Useful to process concatenated certificates. - """ - pem_strings = [] - while s != b"": - start_idx = s.find(b"-----BEGIN") - if start_idx == -1: - break - end_idx = s.find(b"-----END") - end_idx = s.find(b"\n", end_idx) + 1 - pem_strings.append(s[start_idx:end_idx]) - s = s[end_idx:] - return pem_strings - - -class _PKIObj(object): - def __init__(self, frmt, der, pem): - # Note that changing attributes of the _PKIObj does not update these - # values (e.g. modifying k.modulus does not change k.der). - # XXX use __setattr__ for this - self.frmt = frmt - self.der = der - self.pem = pem - - def __str__(self): - return self.der - - -class _PKIObjMaker(type): - def __call__(cls, obj_path, obj_max_size, pem_marker=None): - # This enables transparent DER and PEM-encoded data imports. - # Note that when importing a PEM file with multiple objects (like ECDSA - # private keys output by openssl), it will concatenate every object in - # order to create a 'der' attribute. When converting a 'multi' DER file - # into a PEM file, though, the PEM attribute will not be valid, - # because we do not try to identify the class of each object. - error_msg = "Unable to import data" - - if obj_path is None: - raise Exception(error_msg) - obj_path = bytes_encode(obj_path) - - if (b'\x00' not in obj_path) and os.path.isfile(obj_path): - _size = os.path.getsize(obj_path) - if _size > obj_max_size: - raise Exception(error_msg) - try: - f = open(obj_path, "rb") - _raw = f.read() - f.close() - except Exception: - raise Exception(error_msg) - else: - _raw = obj_path - - try: - if b"-----BEGIN" in _raw: - frmt = "PEM" - pem = _raw - der_list = split_pem(_raw) - der = b''.join(map(pem2der, der_list)) - else: - frmt = "DER" - der = _raw - pem = "" - if pem_marker is not None: - pem = der2pem(_raw, pem_marker) - # type identification may be needed for pem_marker - # in such case, the pem attribute has to be updated - except Exception: - raise Exception(error_msg) - - p = _PKIObj(frmt, der, pem) - return p - - -##################################################################### -# PKI objects wrappers -##################################################################### - -############### -# Public Keys # -############### - -class _PubKeyFactory(_PKIObjMaker): - """ - Metaclass for PubKey creation. - It casts the appropriate class on the fly, then fills in - the appropriate attributes with import_from_asn1pkt() submethod. - """ - def __call__(cls, key_path=None): - - if key_path is None: - obj = type.__call__(cls) - if cls is PubKey: - cls = PubKeyRSA - obj.__class__ = cls - obj.frmt = "original" - obj.fill_and_store() - return obj - - # This deals with the rare RSA 'kx export' call. - if isinstance(key_path, tuple): - obj = type.__call__(cls) - obj.__class__ = PubKeyRSA - obj.frmt = "tuple" - obj.import_from_tuple(key_path) - return obj - - # Now for the usual calls, key_path may be the path to either: - # _an X509_SubjectPublicKeyInfo, as processed by openssl; - # _an RSAPublicKey; - # _an ECDSAPublicKey. - obj = _PKIObjMaker.__call__(cls, key_path, _MAX_KEY_SIZE) - try: - spki = X509_SubjectPublicKeyInfo(obj.der) - pubkey = spki.subjectPublicKey - if isinstance(pubkey, RSAPublicKey): - obj.__class__ = PubKeyRSA - obj.import_from_asn1pkt(pubkey) - elif isinstance(pubkey, ECDSAPublicKey): - obj.__class__ = PubKeyECDSA - try: - obj.import_from_der(obj.der) - except ImportError: - pass - else: - raise - marker = b"PUBLIC KEY" - except Exception: - try: - pubkey = RSAPublicKey(obj.der) - obj.__class__ = PubKeyRSA - obj.import_from_asn1pkt(pubkey) - marker = b"RSA PUBLIC KEY" - except Exception: - # We cannot import an ECDSA public key without curve knowledge - raise Exception("Unable to import public key") - - if obj.frmt == "DER": - obj.pem = der2pem(obj.der, marker) - return obj - - -class PubKey(six.with_metaclass(_PubKeyFactory, object)): - """ - Parent class for both PubKeyRSA and PubKeyECDSA. - Provides a common verifyCert() method. - """ - - def verifyCert(self, cert): - """ Verifies either a Cert or an X509_Cert. """ - tbsCert = cert.tbsCertificate - sigAlg = tbsCert.signature - h = hash_by_oid[sigAlg.algorithm.val] - sigVal = raw(cert.signatureValue) - return self.verify(raw(tbsCert), sigVal, h=h, t='pkcs') - - -class PubKeyRSA(PubKey, _EncryptAndVerifyRSA): - """ - Wrapper for RSA keys based on _EncryptAndVerifyRSA from crypto/pkcs1.py - Use the 'key' attribute to access original object. - """ - @crypto_validator - def fill_and_store(self, modulus=None, modulusLen=None, pubExp=None): - pubExp = pubExp or 65537 - if not modulus: - real_modulusLen = modulusLen or 2048 - private_key = rsa.generate_private_key(public_exponent=pubExp, - key_size=real_modulusLen, - backend=default_backend()) - self.pubkey = private_key.public_key() - else: - real_modulusLen = len(binrepr(modulus)) - if modulusLen and real_modulusLen != modulusLen: - warning("modulus and modulusLen do not match!") - pubNum = rsa.RSAPublicNumbers(n=modulus, e=pubExp) - self.pubkey = pubNum.public_key(default_backend()) - # Lines below are only useful for the legacy part of pkcs1.py - pubNum = self.pubkey.public_numbers() - self._modulusLen = real_modulusLen - self._modulus = pubNum.n - self._pubExp = pubNum.e - - @crypto_validator - def import_from_tuple(self, tup): - # this is rarely used - e, m, mLen = tup - if isinstance(m, bytes): - m = pkcs_os2ip(m) - if isinstance(e, bytes): - e = pkcs_os2ip(e) - self.fill_and_store(modulus=m, pubExp=e) - self.pem = self.pubkey.public_bytes( - encoding=serialization.Encoding.PEM, - format=serialization.PublicFormat.SubjectPublicKeyInfo) - self.der = pem2der(self.pem) - - def import_from_asn1pkt(self, pubkey): - modulus = pubkey.modulus.val - pubExp = pubkey.publicExponent.val - self.fill_and_store(modulus=modulus, pubExp=pubExp) - - def encrypt(self, msg, t="pkcs", h="sha256", mgf=None, L=None): - # no ECDSA encryption support, hence no ECDSA specific keywords here - return _EncryptAndVerifyRSA.encrypt(self, msg, t=t, h=h, mgf=mgf, L=L) - - def verify(self, msg, sig, t="pkcs", h="sha256", mgf=None, L=None): - return _EncryptAndVerifyRSA.verify( - self, msg, sig, t=t, h=h, mgf=mgf, L=L) - - -class PubKeyECDSA(PubKey): - """ - Wrapper for ECDSA keys based on the cryptography library. - Use the 'key' attribute to access original object. - """ - @crypto_validator - def fill_and_store(self, curve=None): - curve = curve or ec.SECP256R1 - private_key = ec.generate_private_key(curve(), default_backend()) - self.pubkey = private_key.public_key() - - @crypto_validator - def import_from_der(self, pubkey): - # No lib support for explicit curves nor compressed points. - self.pubkey = serialization.load_der_public_key(pubkey, - backend=default_backend()) # noqa: E501 - - def encrypt(self, msg, h="sha256", **kwargs): - # cryptography lib does not support ECDSA encryption - raise Exception("No ECDSA encryption support") - - @crypto_validator - def verify(self, msg, sig, h="sha256", **kwargs): - # 'sig' should be a DER-encoded signature, as per RFC 3279 - if conf.crypto_valid_recent: - try: - self.pubkey.verify(sig, msg, ec.ECDSA(_get_hash(h))) - return True - except InvalidSignature: - return False - else: - verifier = self.pubkey.verifier(sig, ec.ECDSA(_get_hash(h))) - verifier.update(msg) - return verifier.verify() - - -################ -# Private Keys # -################ - -class _PrivKeyFactory(_PKIObjMaker): - """ - Metaclass for PrivKey creation. - It casts the appropriate class on the fly, then fills in - the appropriate attributes with import_from_asn1pkt() submethod. - """ - def __call__(cls, key_path=None): - """ - key_path may be the path to either: - _an RSAPrivateKey_OpenSSL (as generated by openssl); - _an ECDSAPrivateKey_OpenSSL (as generated by openssl); - _an RSAPrivateKey; - _an ECDSAPrivateKey. - """ - if key_path is None: - obj = type.__call__(cls) - if cls is PrivKey: - cls = PrivKeyECDSA - obj.__class__ = cls - obj.frmt = "original" - obj.fill_and_store() - return obj - - obj = _PKIObjMaker.__call__(cls, key_path, _MAX_KEY_SIZE) - multiPEM = False - try: - privkey = RSAPrivateKey_OpenSSL(obj.der) - privkey = privkey.privateKey - obj.__class__ = PrivKeyRSA - marker = b"PRIVATE KEY" - except Exception: - try: - privkey = ECDSAPrivateKey_OpenSSL(obj.der) - privkey = privkey.privateKey - obj.__class__ = PrivKeyECDSA - marker = b"EC PRIVATE KEY" - multiPEM = True - except Exception: - try: - privkey = RSAPrivateKey(obj.der) - obj.__class__ = PrivKeyRSA - marker = b"RSA PRIVATE KEY" - except Exception: - try: - privkey = ECDSAPrivateKey(obj.der) - obj.__class__ = PrivKeyECDSA - marker = b"EC PRIVATE KEY" - except Exception: - raise Exception("Unable to import private key") - try: - obj.import_from_asn1pkt(privkey) - except ImportError: - pass - - if obj.frmt == "DER": - if multiPEM: - # this does not restore the EC PARAMETERS header - obj.pem = der2pem(raw(privkey), marker) - else: - obj.pem = der2pem(obj.der, marker) - return obj - - -class _Raw_ASN1_BIT_STRING(ASN1_BIT_STRING): - """A ASN1_BIT_STRING that ignores BER encoding""" - def __bytes__(self): - return self.val_readable - __str__ = __bytes__ - - -class PrivKey(six.with_metaclass(_PrivKeyFactory, object)): - """ - Parent class for both PrivKeyRSA and PrivKeyECDSA. - Provides common signTBSCert() and resignCert() methods. - """ - - def signTBSCert(self, tbsCert, h="sha256"): - """ - Note that this will always copy the signature field from the - tbsCertificate into the signatureAlgorithm field of the result, - regardless of the coherence between its contents (which might - indicate ecdsa-with-SHA512) and the result (e.g. RSA signing MD2). - - There is a small inheritance trick for the computation of sigVal - below: in order to use a sign() method which would apply - to both PrivKeyRSA and PrivKeyECDSA, the sign() methods of the - subclasses accept any argument, be it from the RSA or ECDSA world, - and then they keep the ones they're interested in. - Here, t will be passed eventually to pkcs1._DecryptAndSignRSA.sign(). - """ - sigAlg = tbsCert.signature - h = h or hash_by_oid[sigAlg.algorithm.val] - sigVal = self.sign(raw(tbsCert), h=h, t='pkcs') - c = X509_Cert() - c.tbsCertificate = tbsCert - c.signatureAlgorithm = sigAlg - c.signatureValue = _Raw_ASN1_BIT_STRING(sigVal, readable=True) - return c - - def resignCert(self, cert): - """ Rewrite the signature of either a Cert or an X509_Cert. """ - return self.signTBSCert(cert.tbsCertificate) - - def verifyCert(self, cert): - """ Verifies either a Cert or an X509_Cert. """ - tbsCert = cert.tbsCertificate - sigAlg = tbsCert.signature - h = hash_by_oid[sigAlg.algorithm.val] - sigVal = raw(cert.signatureValue) - return self.verify(raw(tbsCert), sigVal, h=h, t='pkcs') - - -class PrivKeyRSA(PrivKey, _EncryptAndVerifyRSA, _DecryptAndSignRSA): - """ - Wrapper for RSA keys based on _DecryptAndSignRSA from crypto/pkcs1.py - Use the 'key' attribute to access original object. - """ - @crypto_validator - def fill_and_store(self, modulus=None, modulusLen=None, pubExp=None, - prime1=None, prime2=None, coefficient=None, - exponent1=None, exponent2=None, privExp=None): - pubExp = pubExp or 65537 - if None in [modulus, prime1, prime2, coefficient, privExp, - exponent1, exponent2]: - # note that the library requires every parameter - # in order to call RSAPrivateNumbers(...) - # if one of these is missing, we generate a whole new key - real_modulusLen = modulusLen or 2048 - self.key = rsa.generate_private_key(public_exponent=pubExp, - key_size=real_modulusLen, - backend=default_backend()) - self.pubkey = self.key.public_key() - else: - real_modulusLen = len(binrepr(modulus)) - if modulusLen and real_modulusLen != modulusLen: - warning("modulus and modulusLen do not match!") - pubNum = rsa.RSAPublicNumbers(n=modulus, e=pubExp) - privNum = rsa.RSAPrivateNumbers(p=prime1, q=prime2, - dmp1=exponent1, dmq1=exponent2, - iqmp=coefficient, d=privExp, - public_numbers=pubNum) - self.key = privNum.private_key(default_backend()) - self.pubkey = self.key.public_key() - - # Lines below are only useful for the legacy part of pkcs1.py - pubNum = self.pubkey.public_numbers() - self._modulusLen = real_modulusLen - self._modulus = pubNum.n - self._pubExp = pubNum.e - - def import_from_asn1pkt(self, privkey): - modulus = privkey.modulus.val - pubExp = privkey.publicExponent.val - privExp = privkey.privateExponent.val - prime1 = privkey.prime1.val - prime2 = privkey.prime2.val - exponent1 = privkey.exponent1.val - exponent2 = privkey.exponent2.val - coefficient = privkey.coefficient.val - self.fill_and_store(modulus=modulus, pubExp=pubExp, - privExp=privExp, prime1=prime1, prime2=prime2, - exponent1=exponent1, exponent2=exponent2, - coefficient=coefficient) - - def verify(self, msg, sig, t="pkcs", h="sha256", mgf=None, L=None): - # Let's copy this from PubKeyRSA instead of adding another baseclass :) - return _EncryptAndVerifyRSA.verify( - self, msg, sig, t=t, h=h, mgf=mgf, L=L) - - def sign(self, data, t="pkcs", h="sha256", mgf=None, L=None): - return _DecryptAndSignRSA.sign(self, data, t=t, h=h, mgf=mgf, L=L) - - -class PrivKeyECDSA(PrivKey): - """ - Wrapper for ECDSA keys based on SigningKey from ecdsa library. - Use the 'key' attribute to access original object. - """ - @crypto_validator - def fill_and_store(self, curve=None): - curve = curve or ec.SECP256R1 - self.key = ec.generate_private_key(curve(), default_backend()) - self.pubkey = self.key.public_key() - - @crypto_validator - def import_from_asn1pkt(self, privkey): - self.key = serialization.load_der_private_key(raw(privkey), None, - backend=default_backend()) # noqa: E501 - self.pubkey = self.key.public_key() - - @crypto_validator - def verify(self, msg, sig, h="sha256", **kwargs): - # 'sig' should be a DER-encoded signature, as per RFC 3279 - if conf.crypto_valid_recent: - try: - self.pubkey.verify(sig, msg, ec.ECDSA(_get_hash(h))) - return True - except InvalidSignature: - return False - else: - verifier = self.pubkey.verifier(sig, ec.ECDSA(_get_hash(h))) - verifier.update(msg) - return verifier.verify() - - @crypto_validator - def sign(self, data, h="sha256", **kwargs): - if conf.crypto_valid_recent: - return self.key.sign(data, ec.ECDSA(_get_hash(h))) - else: - signer = self.key.signer(ec.ECDSA(_get_hash(h))) - signer.update(data) - return signer.finalize() - - -################ -# Certificates # -################ - -class _CertMaker(_PKIObjMaker): - """ - Metaclass for Cert creation. It is not necessary as it was for the keys, - but we reuse the model instead of creating redundant constructors. - """ - def __call__(cls, cert_path): - obj = _PKIObjMaker.__call__(cls, cert_path, - _MAX_CERT_SIZE, "CERTIFICATE") - obj.__class__ = Cert - try: - cert = X509_Cert(obj.der) - except Exception: - raise Exception("Unable to import certificate") - obj.import_from_asn1pkt(cert) - return obj - - -class Cert(six.with_metaclass(_CertMaker, object)): - """ - Wrapper for the X509_Cert from layers/x509.py. - Use the 'x509Cert' attribute to access original object. - """ - - def import_from_asn1pkt(self, cert): - error_msg = "Unable to import certificate" - - self.x509Cert = cert - - tbsCert = cert.tbsCertificate - self.tbsCertificate = tbsCert - - if tbsCert.version: - self.version = tbsCert.version.val + 1 - else: - self.version = 1 - self.serial = tbsCert.serialNumber.val - self.sigAlg = tbsCert.signature.algorithm.oidname - self.issuer = tbsCert.get_issuer() - self.issuer_str = tbsCert.get_issuer_str() - self.issuer_hash = hash(self.issuer_str) - self.subject = tbsCert.get_subject() - self.subject_str = tbsCert.get_subject_str() - self.subject_hash = hash(self.subject_str) - self.authorityKeyID = None - - self.notBefore_str = tbsCert.validity.not_before.pretty_time - notBefore = tbsCert.validity.not_before.val - if notBefore[-1] == "Z": - notBefore = notBefore[:-1] - try: - _format = tbsCert.validity.not_before._format - self.notBefore = time.strptime(notBefore, _format) - except Exception: - raise Exception(error_msg) - self.notBefore_str_simple = time.strftime("%x", self.notBefore) - - self.notAfter_str = tbsCert.validity.not_after.pretty_time - notAfter = tbsCert.validity.not_after.val - if notAfter[-1] == "Z": - notAfter = notAfter[:-1] - try: - _format = tbsCert.validity.not_after._format - self.notAfter = time.strptime(notAfter, _format) - except Exception: - raise Exception(error_msg) - self.notAfter_str_simple = time.strftime("%x", self.notAfter) - - self.pubKey = PubKey(raw(tbsCert.subjectPublicKeyInfo)) - - if tbsCert.extensions: - for extn in tbsCert.extensions: - if extn.extnID.oidname == "basicConstraints": - self.cA = False - if extn.extnValue.cA: - self.cA = not (extn.extnValue.cA.val == 0) - elif extn.extnID.oidname == "keyUsage": - self.keyUsage = extn.extnValue.get_keyUsage() - elif extn.extnID.oidname == "extKeyUsage": - self.extKeyUsage = extn.extnValue.get_extendedKeyUsage() - elif extn.extnID.oidname == "authorityKeyIdentifier": - self.authorityKeyID = extn.extnValue.keyIdentifier.val - - self.signatureValue = raw(cert.signatureValue) - self.signatureLen = len(self.signatureValue) - - def isIssuerCert(self, other): - """ - True if 'other' issued 'self', i.e.: - - self.issuer == other.subject - - self is signed by other - """ - if self.issuer_hash != other.subject_hash: - return False - return other.pubKey.verifyCert(self) - - def isSelfSigned(self): - """ - Return True if the certificate is self-signed: - - issuer and subject are the same - - the signature of the certificate is valid. - """ - if self.issuer_hash == self.subject_hash: - return self.isIssuerCert(self) - return False - - def encrypt(self, msg, t="pkcs", h="sha256", mgf=None, L=None): - # no ECDSA *encryption* support, hence only RSA specific keywords here - return self.pubKey.encrypt(msg, t=t, h=h, mgf=mgf, L=L) - - def verify(self, msg, sig, t="pkcs", h="sha256", mgf=None, L=None): - return self.pubKey.verify(msg, sig, t=t, h=h, mgf=mgf, L=L) - - def remainingDays(self, now=None): - """ - Based on the value of notAfter field, returns the number of - days the certificate will still be valid. The date used for the - comparison is the current and local date, as returned by - time.localtime(), except if 'now' argument is provided another - one. 'now' argument can be given as either a time tuple or a string - representing the date. Accepted format for the string version - are: - - - '%b %d %H:%M:%S %Y %Z' e.g. 'Jan 30 07:38:59 2008 GMT' - - '%m/%d/%y' e.g. '01/30/08' (less precise) - - If the certificate is no more valid at the date considered, then - a negative value is returned representing the number of days - since it has expired. - - The number of days is returned as a float to deal with the unlikely - case of certificates that are still just valid. - """ - if now is None: - now = time.localtime() - elif isinstance(now, str): - try: - if '/' in now: - now = time.strptime(now, '%m/%d/%y') - else: - now = time.strptime(now, '%b %d %H:%M:%S %Y %Z') - except Exception: - warning("Bad time string provided, will use localtime() instead.") # noqa: E501 - now = time.localtime() - - now = time.mktime(now) - nft = time.mktime(self.notAfter) - diff = (nft - now) / (24. * 3600) - return diff - - def isRevoked(self, crl_list): - """ - Given a list of trusted CRL (their signature has already been - verified with trusted anchors), this function returns True if - the certificate is marked as revoked by one of those CRL. - - Note that if the Certificate was on hold in a previous CRL and - is now valid again in a new CRL and bot are in the list, it - will be considered revoked: this is because _all_ CRLs are - checked (not only the freshest) and revocation status is not - handled. - - Also note that the check on the issuer is performed on the - Authority Key Identifier if available in _both_ the CRL and the - Cert. Otherwise, the issuers are simply compared. - """ - for c in crl_list: - if (self.authorityKeyID is not None and - c.authorityKeyID is not None and - self.authorityKeyID == c.authorityKeyID): - return self.serial in (x[0] for x in c.revoked_cert_serials) - elif self.issuer == c.issuer: - return self.serial in (x[0] for x in c.revoked_cert_serials) - return False - - def export(self, filename, fmt="DER"): - """ - Export certificate in 'fmt' format (DER or PEM) to file 'filename' - """ - f = open(filename, "wb") - if fmt == "DER": - f.write(self.der) - elif fmt == "PEM": - f.write(self.pem) - f.close() - - def show(self): - print("Serial: %s" % self.serial) - print("Issuer: " + self.issuer_str) - print("Subject: " + self.subject_str) - print("Validity: %s to %s" % (self.notBefore_str, self.notAfter_str)) - - def __repr__(self): - return "[X.509 Cert. Subject:%s, Issuer:%s]" % (self.subject_str, self.issuer_str) # noqa: E501 - - -################################ -# Certificate Revocation Lists # -################################ - -class _CRLMaker(_PKIObjMaker): - """ - Metaclass for CRL creation. It is not necessary as it was for the keys, - but we reuse the model instead of creating redundant constructors. - """ - def __call__(cls, cert_path): - obj = _PKIObjMaker.__call__(cls, cert_path, _MAX_CRL_SIZE, "X509 CRL") - obj.__class__ = CRL - try: - crl = X509_CRL(obj.der) - except Exception: - raise Exception("Unable to import CRL") - obj.import_from_asn1pkt(crl) - return obj - - -class CRL(six.with_metaclass(_CRLMaker, object)): - """ - Wrapper for the X509_CRL from layers/x509.py. - Use the 'x509CRL' attribute to access original object. - """ - - def import_from_asn1pkt(self, crl): - error_msg = "Unable to import CRL" - - self.x509CRL = crl - - tbsCertList = crl.tbsCertList - self.tbsCertList = raw(tbsCertList) - - if tbsCertList.version: - self.version = tbsCertList.version.val + 1 - else: - self.version = 1 - self.sigAlg = tbsCertList.signature.algorithm.oidname - self.issuer = tbsCertList.get_issuer() - self.issuer_str = tbsCertList.get_issuer_str() - self.issuer_hash = hash(self.issuer_str) - - self.lastUpdate_str = tbsCertList.this_update.pretty_time - lastUpdate = tbsCertList.this_update.val - if lastUpdate[-1] == "Z": - lastUpdate = lastUpdate[:-1] - try: - self.lastUpdate = time.strptime(lastUpdate, "%y%m%d%H%M%S") - except Exception: - raise Exception(error_msg) - self.lastUpdate_str_simple = time.strftime("%x", self.lastUpdate) - - self.nextUpdate = None - self.nextUpdate_str_simple = None - if tbsCertList.next_update: - self.nextUpdate_str = tbsCertList.next_update.pretty_time - nextUpdate = tbsCertList.next_update.val - if nextUpdate[-1] == "Z": - nextUpdate = nextUpdate[:-1] - try: - self.nextUpdate = time.strptime(nextUpdate, "%y%m%d%H%M%S") - except Exception: - raise Exception(error_msg) - self.nextUpdate_str_simple = time.strftime("%x", self.nextUpdate) - - if tbsCertList.crlExtensions: - for extension in tbsCertList.crlExtensions: - if extension.extnID.oidname == "cRLNumber": - self.number = extension.extnValue.cRLNumber.val - - revoked = [] - if tbsCertList.revokedCertificates: - for cert in tbsCertList.revokedCertificates: - serial = cert.serialNumber.val - date = cert.revocationDate.val - if date[-1] == "Z": - date = date[:-1] - try: - time.strptime(date, "%y%m%d%H%M%S") - except Exception: - raise Exception(error_msg) - revoked.append((serial, date)) - self.revoked_cert_serials = revoked - - self.signatureValue = raw(crl.signatureValue) - self.signatureLen = len(self.signatureValue) - - def isIssuerCert(self, other): - # This is exactly the same thing as in Cert method. - if self.issuer_hash != other.subject_hash: - return False - return other.pubKey.verifyCert(self) - - def verify(self, anchors): - # Return True iff the CRL is signed by one of the provided anchors. - return any(self.isIssuerCert(a) for a in anchors) - - def show(self): - print("Version: %d" % self.version) - print("sigAlg: " + self.sigAlg) - print("Issuer: " + self.issuer_str) - print("lastUpdate: %s" % self.lastUpdate_str) - print("nextUpdate: %s" % self.nextUpdate_str) - - -###################### -# Certificate chains # -###################### - -class Chain(list): - """ - Basically, an enhanced array of Cert. - """ - - def __init__(self, certList, cert0=None): - """ - Construct a chain of certificates starting with a self-signed - certificate (or any certificate submitted by the user) - and following issuer/subject matching and signature validity. - If there is exactly one chain to be constructed, it will be, - but if there are multiple potential chains, there is no guarantee - that the retained one will be the longest one. - As Cert and CRL classes both share an isIssuerCert() method, - the trailing element of a Chain may alternatively be a CRL. - - Note that we do not check AKID/{SKID/issuer/serial} matching, - nor the presence of keyCertSign in keyUsage extension (if present). - """ - list.__init__(self, ()) - if cert0: - self.append(cert0) - else: - for root_candidate in certList: - if root_candidate.isSelfSigned(): - self.append(root_candidate) - certList.remove(root_candidate) - break - - if len(self) > 0: - while certList: - tmp_len = len(self) - for c in certList: - if c.isIssuerCert(self[-1]): - self.append(c) - certList.remove(c) - break - if len(self) == tmp_len: - # no new certificate appended to self - break - - def verifyChain(self, anchors, untrusted=None): - """ - Perform verification of certificate chains for that certificate. - A list of anchors is required. The certificates in the optional - untrusted list may be used as additional elements to the final chain. - On par with chain instantiation, only one chain constructed with the - untrusted candidates will be retained. Eventually, dates are checked. - """ - untrusted = untrusted or [] - for a in anchors: - chain = Chain(self + untrusted, a) - if len(chain) == 1: # anchor only - continue - # check that the chain does not exclusively rely on untrusted - if any(c in chain[1:] for c in self): - for c in chain: - if c.remainingDays() < 0: - break - if c is chain[-1]: # we got to the end of the chain - return chain - return None - - def verifyChainFromCAFile(self, cafile, untrusted_file=None): - """ - Does the same job as .verifyChain() but using the list of anchors - from the cafile. As for .verifyChain(), a list of untrusted - certificates can be passed (as a file, this time). - """ - try: - f = open(cafile, "rb") - ca_certs = f.read() - f.close() - except Exception: - raise Exception("Could not read from cafile") - - anchors = [Cert(c) for c in split_pem(ca_certs)] - - untrusted = None - if untrusted_file: - try: - f = open(untrusted_file, "rb") - untrusted_certs = f.read() - f.close() - except Exception: - raise Exception("Could not read from untrusted_file") - untrusted = [Cert(c) for c in split_pem(untrusted_certs)] - - return self.verifyChain(anchors, untrusted) - - def verifyChainFromCAPath(self, capath, untrusted_file=None): - """ - Does the same job as .verifyChainFromCAFile() but using the list - of anchors in capath directory. The directory should (only) contain - certificates files in PEM format. As for .verifyChainFromCAFile(), - a list of untrusted certificates can be passed as a file - (concatenation of the certificates in PEM format). - """ - try: - anchors = [] - for cafile in os.listdir(capath): - anchors.append(Cert(open(os.path.join(capath, cafile), "rb").read())) # noqa: E501 - except Exception: - raise Exception("capath provided is not a valid cert path") - - untrusted = None - if untrusted_file: - try: - f = open(untrusted_file, "rb") - untrusted_certs = f.read() - f.close() - except Exception: - raise Exception("Could not read from untrusted_file") - untrusted = [Cert(c) for c in split_pem(untrusted_certs)] - - return self.verifyChain(anchors, untrusted) - - def __repr__(self): - llen = len(self) - 1 - if llen < 0: - return "" - c = self[0] - s = "__ " - if not c.isSelfSigned(): - s += "%s [Not Self Signed]\n" % c.subject_str - else: - s += "%s [Self Signed]\n" % c.subject_str - idx = 1 - while idx <= llen: - c = self[idx] - s += "%s_ %s" % (" " * idx * 2, c.subject_str) - if idx != llen: - s += "\n" - idx += 1 - return s diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/__init__.py deleted file mode 100644 index 063697b25d..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016 Maxence Tury -# This program is published under a GPLv2 license - -""" -Cryptographic capabilities for TLS. -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/all.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/all.py deleted file mode 100644 index ea7d405c8b..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/all.py +++ /dev/null @@ -1,12 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -Aggregate some TLS crypto objects. -""" - -# flake8: noqa: F403 - -from scapy.layers.tls.crypto.suites import * # noqa: F401 diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/cipher_aead.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/cipher_aead.py deleted file mode 100644 index faf35b98b7..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/cipher_aead.py +++ /dev/null @@ -1,420 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -Authenticated Encryption with Associated Data ciphers. - -RFC 5288 introduces new ciphersuites for TLS 1.2 which are based on AES in -Galois/Counter Mode (GCM). RFC 6655 in turn introduces AES_CCM ciphersuites. -The related AEAD algorithms are defined in RFC 5116. Later on, RFC 7905 -introduced cipher suites based on a ChaCha20-Poly1305 construction. -""" - -from __future__ import absolute_import -import struct - -from scapy.config import conf -from scapy.layers.tls.crypto.pkcs1 import pkcs_i2osp, pkcs_os2ip -from scapy.layers.tls.crypto.common import CipherError -from scapy.utils import strxor -import scapy.modules.six as six - -if conf.crypto_valid: - from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes # noqa: E501 - from cryptography.hazmat.backends import default_backend - from cryptography.exceptions import InvalidTag -if conf.crypto_valid_advanced: - from cryptography.hazmat.primitives.ciphers.aead import (AESCCM, - ChaCha20Poly1305) -else: - class AESCCM: - pass - -_tls_aead_cipher_algs = {} - - -class _AEADCipherMetaclass(type): - """ - Cipher classes are automatically registered through this metaclass. - Furthermore, their name attribute is extracted from their class name. - """ - def __new__(cls, ciph_name, bases, dct): - if not ciph_name.startswith("_AEADCipher"): - dct["name"] = ciph_name[7:] # remove leading "Cipher_" - the_class = super(_AEADCipherMetaclass, cls).__new__(cls, ciph_name, - bases, dct) - if not ciph_name.startswith("_AEADCipher"): - _tls_aead_cipher_algs[ciph_name[7:]] = the_class - return the_class - - -class AEADTagError(Exception): - """ - Raised when MAC verification fails. - """ - pass - - -class _AEADCipher(six.with_metaclass(_AEADCipherMetaclass, object)): - """ - The hasattr(self, "pc_cls") tests correspond to the legacy API of the - crypto library. With cryptography v2.0, both CCM and GCM should follow - the else case. - - Note that the "fixed_iv" in TLS RFCs is called "salt" in the AEAD RFC 5116. - """ - type = "aead" - fixed_iv_len = 4 - nonce_explicit_len = 8 - - def __init__(self, key=None, fixed_iv=None, nonce_explicit=None): - """ - 'key' and 'fixed_iv' are to be provided as strings, whereas the internal # noqa: E501 - 'nonce_explicit' is an integer (it is simpler for incrementation). - !! The whole 'nonce' may be called IV in certain RFCs. - """ - self.ready = {"key": True, "fixed_iv": True, "nonce_explicit": True} - if key is None: - self.ready["key"] = False - key = b"\0" * self.key_len - if fixed_iv is None: - self.ready["fixed_iv"] = False - fixed_iv = b"\0" * self.fixed_iv_len - if nonce_explicit is None: - self.ready["nonce_explicit"] = False - nonce_explicit = 0 - - if isinstance(nonce_explicit, str): - nonce_explicit = pkcs_os2ip(nonce_explicit) - - # we use super() in order to avoid any deadlock with __setattr__ - super(_AEADCipher, self).__setattr__("key", key) - super(_AEADCipher, self).__setattr__("fixed_iv", fixed_iv) - super(_AEADCipher, self).__setattr__("nonce_explicit", nonce_explicit) - - if hasattr(self, "pc_cls"): - if isinstance(self.pc_cls, AESCCM): - self._cipher = Cipher(self.pc_cls(key), - self.pc_cls_mode(self._get_nonce()), - backend=default_backend(), - tag_length=self.tag_len) - else: - self._cipher = Cipher(self.pc_cls(key), - self.pc_cls_mode(self._get_nonce()), - backend=default_backend()) - else: - self._cipher = self.cipher_cls(key) - - def __setattr__(self, name, val): - if name == "key": - if self._cipher is not None: - if hasattr(self, "pc_cls"): - self._cipher.algorithm.key = val - else: - self._cipher._key = val - self.ready["key"] = True - elif name == "fixed_iv": - self.ready["fixed_iv"] = True - elif name == "nonce_explicit": - if isinstance(val, str): - val = pkcs_os2ip(val) - self.ready["nonce_explicit"] = True - super(_AEADCipher, self).__setattr__(name, val) - - def _get_nonce(self): - return (self.fixed_iv + - pkcs_i2osp(self.nonce_explicit, self.nonce_explicit_len)) - - def _update_nonce_explicit(self): - """ - Increment the explicit nonce while avoiding any overflow. - """ - ne = self.nonce_explicit + 1 - self.nonce_explicit = ne % 2**(self.nonce_explicit_len * 8) - - def auth_encrypt(self, P, A, seq_num=None): - """ - Encrypt the data then prepend the explicit part of the nonce. The - authentication tag is directly appended with the most recent crypto - API. Additional data may be authenticated without encryption (as A). - - The 'seq_num' should never be used here, it is only a safeguard needed - because one cipher (ChaCha20Poly1305) using TLS 1.2 logic in record.py - actually is a _AEADCipher_TLS13 (even though others are not). - """ - if False in six.itervalues(self.ready): - raise CipherError(P, A) - - if hasattr(self, "pc_cls"): - self._cipher.mode._initialization_vector = self._get_nonce() - self._cipher.mode._tag = None - encryptor = self._cipher.encryptor() - encryptor.authenticate_additional_data(A) - res = encryptor.update(P) + encryptor.finalize() - res += encryptor.tag - else: - res = self._cipher.encrypt(self._get_nonce(), P, A) - - nonce_explicit = pkcs_i2osp(self.nonce_explicit, - self.nonce_explicit_len) - self._update_nonce_explicit() - return nonce_explicit + res - - def auth_decrypt(self, A, C, seq_num=None, add_length=True): - """ - Decrypt the data and authenticate the associated data (i.e. A). - If the verification fails, an AEADTagError is raised. It is the user's - responsibility to catch it if deemed useful. If we lack the key, we - raise a CipherError which contains the encrypted input. - - Note that we add the TLSCiphertext length to A although we're supposed - to add the TLSCompressed length. Fortunately, they are the same, - but the specifications actually messed up here. :'( - - The 'add_length' switch should always be True for TLS, but we provide - it anyway (mostly for test cases, hum). - - The 'seq_num' should never be used here, it is only a safeguard needed - because one cipher (ChaCha20Poly1305) using TLS 1.2 logic in record.py - actually is a _AEADCipher_TLS13 (even though others are not). - """ - nonce_explicit_str, C, mac = (C[:self.nonce_explicit_len], - C[self.nonce_explicit_len:-self.tag_len], - C[-self.tag_len:]) - - if False in six.itervalues(self.ready): - raise CipherError(nonce_explicit_str, C, mac) - - self.nonce_explicit = pkcs_os2ip(nonce_explicit_str) - if add_length: - A += struct.pack("!H", len(C)) - - if hasattr(self, "pc_cls"): - self._cipher.mode._initialization_vector = self._get_nonce() - self._cipher.mode._tag = mac - decryptor = self._cipher.decryptor() - decryptor.authenticate_additional_data(A) - P = decryptor.update(C) - try: - decryptor.finalize() - except InvalidTag: - raise AEADTagError(nonce_explicit_str, P, mac) - else: - try: - P = self._cipher.decrypt(self._get_nonce(), C + mac, A) - except InvalidTag: - raise AEADTagError(nonce_explicit_str, - "", - mac) - return nonce_explicit_str, P, mac - - def snapshot(self): - c = self.__class__(self.key, self.fixed_iv, self.nonce_explicit) - c.ready = self.ready.copy() - return c - - -if conf.crypto_valid: - class Cipher_AES_128_GCM(_AEADCipher): - # XXX use the new AESGCM if available - # if conf.crypto_valid_advanced: - # cipher_cls = AESGCM - # else: - pc_cls = algorithms.AES - pc_cls_mode = modes.GCM - key_len = 16 - tag_len = 16 - - class Cipher_AES_256_GCM(Cipher_AES_128_GCM): - key_len = 32 - - -if conf.crypto_valid_advanced: - class Cipher_AES_128_CCM(_AEADCipher): - cipher_cls = AESCCM - key_len = 16 - tag_len = 16 - - class Cipher_AES_256_CCM(Cipher_AES_128_CCM): - key_len = 32 - - class Cipher_AES_128_CCM_8(Cipher_AES_128_CCM): - tag_len = 8 - - class Cipher_AES_256_CCM_8(Cipher_AES_128_CCM_8): - key_len = 32 - - -class _AEADCipher_TLS13(six.with_metaclass(_AEADCipherMetaclass, object)): - """ - The hasattr(self, "pc_cls") enable support for the legacy implementation - of GCM in the cryptography library. They should not be used, and might - eventually be removed, with cryptography v2.0. XXX - """ - type = "aead" - - def __init__(self, key=None, fixed_iv=None, nonce_explicit=None): - """ - 'key' and 'fixed_iv' are to be provided as strings. This IV never - changes: it is either the client_write_IV or server_write_IV. - - Note that 'nonce_explicit' is never used. It is only a safeguard for a - call in session.py to the TLS 1.2/ChaCha20Poly1305 case (see RFC 7905). - """ - self.ready = {"key": True, "fixed_iv": True} - if key is None: - self.ready["key"] = False - key = b"\0" * self.key_len - if fixed_iv is None: - self.ready["fixed_iv"] = False - fixed_iv = b"\0" * self.fixed_iv_len - - # we use super() in order to avoid any deadlock with __setattr__ - super(_AEADCipher_TLS13, self).__setattr__("key", key) - super(_AEADCipher_TLS13, self).__setattr__("fixed_iv", fixed_iv) - - if hasattr(self, "pc_cls"): - if isinstance(self.pc_cls, AESCCM): - self._cipher = Cipher(self.pc_cls(key), - self.pc_cls_mode(fixed_iv), - backend=default_backend(), - tag_length=self.tag_len) - else: - self._cipher = Cipher(self.pc_cls(key), - self.pc_cls_mode(fixed_iv), - backend=default_backend()) - else: - if self.cipher_cls == ChaCha20Poly1305: - # ChaCha20Poly1305 doesn't have a tag_length argument... - self._cipher = self.cipher_cls(key) - else: - self._cipher = self.cipher_cls(key, tag_length=self.tag_len) - - def __setattr__(self, name, val): - if name == "key": - if self._cipher is not None: - if hasattr(self, "pc_cls"): - self._cipher.algorithm.key = val - else: - self._cipher._key = val - self.ready["key"] = True - elif name == "fixed_iv": - self.ready["fixed_iv"] = True - super(_AEADCipher_TLS13, self).__setattr__(name, val) - - def _get_nonce(self, seq_num): - padlen = self.fixed_iv_len - len(seq_num) - padded_seq_num = b"\x00" * padlen + seq_num - return strxor(padded_seq_num, self.fixed_iv) - - def auth_encrypt(self, P, A, seq_num): - """ - Encrypt the data, and append the computed authentication code. - The additional data for TLS 1.3 is the record header. - - Note that the cipher's authentication tag must be None when encrypting. - """ - if False in six.itervalues(self.ready): - raise CipherError(P, A) - - if hasattr(self, "pc_cls"): - self._cipher.mode._tag = None - self._cipher.mode._initialization_vector = self._get_nonce(seq_num) - encryptor = self._cipher.encryptor() - encryptor.authenticate_additional_data(A) - res = encryptor.update(P) + encryptor.finalize() - res += encryptor.tag - else: - if (conf.crypto_valid_advanced and - isinstance(self._cipher, AESCCM)): - res = self._cipher.encrypt(self._get_nonce(seq_num), P, A, - tag_length=self.tag_len) - else: - res = self._cipher.encrypt(self._get_nonce(seq_num), P, A) - return res - - def auth_decrypt(self, A, C, seq_num): - """ - Decrypt the data and verify the authentication code (in this order). - If the verification fails, an AEADTagError is raised. It is the user's - responsibility to catch it if deemed useful. If we lack the key, we - raise a CipherError which contains the encrypted input. - """ - C, mac = C[:-self.tag_len], C[-self.tag_len:] - if False in six.itervalues(self.ready): - raise CipherError(C, mac) - - if hasattr(self, "pc_cls"): - self._cipher.mode._initialization_vector = self._get_nonce(seq_num) - self._cipher.mode._tag = mac - decryptor = self._cipher.decryptor() - decryptor.authenticate_additional_data(A) - P = decryptor.update(C) - try: - decryptor.finalize() - except InvalidTag: - raise AEADTagError(P, mac) - else: - try: - if (conf.crypto_valid_advanced and - isinstance(self._cipher, AESCCM)): - P = self._cipher.decrypt(self._get_nonce(seq_num), C + mac, A, # noqa: E501 - tag_length=self.tag_len) - else: - if (conf.crypto_valid_advanced and - isinstance(self, Cipher_CHACHA20_POLY1305)): - A += struct.pack("!H", len(C)) - P = self._cipher.decrypt(self._get_nonce(seq_num), C + mac, A) # noqa: E501 - except InvalidTag: - raise AEADTagError("", mac) - return P, mac - - def snapshot(self): - c = self.__class__(self.key, self.fixed_iv) - c.ready = self.ready.copy() - return c - - -if conf.crypto_valid_advanced: - class Cipher_CHACHA20_POLY1305_TLS13(_AEADCipher_TLS13): - cipher_cls = ChaCha20Poly1305 - key_len = 32 - tag_len = 16 - fixed_iv_len = 12 - nonce_explicit_len = 0 - - class Cipher_CHACHA20_POLY1305(Cipher_CHACHA20_POLY1305_TLS13): - """ - This TLS 1.2 cipher actually uses TLS 1.3 logic, as per RFC 7905. - Changes occur at the record layer (in record.py). - """ - pass - - -if conf.crypto_valid: - class Cipher_AES_128_GCM_TLS13(_AEADCipher_TLS13): - # XXX use the new AESGCM if available - # if conf.crypto_valid_advanced: - # cipher_cls = AESGCM - # else: - pc_cls = algorithms.AES - pc_cls_mode = modes.GCM - key_len = 16 - fixed_iv_len = 12 - tag_len = 16 - - class Cipher_AES_256_GCM_TLS13(Cipher_AES_128_GCM_TLS13): - key_len = 32 - - -if conf.crypto_valid_advanced: - class Cipher_AES_128_CCM_TLS13(_AEADCipher_TLS13): - cipher_cls = AESCCM - key_len = 16 - tag_len = 16 - fixed_iv_len = 12 - - class Cipher_AES_128_CCM_8_TLS13(Cipher_AES_128_CCM_TLS13): - tag_len = 8 diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/cipher_block.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/cipher_block.py deleted file mode 100644 index b85b29d8bc..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/cipher_block.py +++ /dev/null @@ -1,219 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -Block ciphers. -""" - -from __future__ import absolute_import -from scapy.config import conf -from scapy.layers.tls.crypto.common import CipherError -import scapy.modules.six as six - -if conf.crypto_valid: - from cryptography.utils import register_interface - from cryptography.hazmat.primitives.ciphers import (Cipher, algorithms, modes, # noqa: E501 - BlockCipherAlgorithm, - CipherAlgorithm) - from cryptography.hazmat.backends.openssl.backend import (backend, - GetCipherByName) - - -_tls_block_cipher_algs = {} - - -class _BlockCipherMetaclass(type): - """ - Cipher classes are automatically registered through this metaclass. - Furthermore, their name attribute is extracted from their class name. - """ - def __new__(cls, ciph_name, bases, dct): - if ciph_name != "_BlockCipher": - dct["name"] = ciph_name[7:] # remove leading "Cipher_" - the_class = super(_BlockCipherMetaclass, cls).__new__(cls, ciph_name, - bases, dct) - if ciph_name != "_BlockCipher": - _tls_block_cipher_algs[ciph_name[7:]] = the_class - return the_class - - -class _BlockCipher(six.with_metaclass(_BlockCipherMetaclass, object)): - type = "block" - - def __init__(self, key=None, iv=None): - self.ready = {"key": True, "iv": True} - if key is None: - self.ready["key"] = False - if hasattr(self, "expanded_key_len"): - key_len = self.expanded_key_len - else: - key_len = self.key_len - key = b"\0" * key_len - if not iv: - self.ready["iv"] = False - iv = b"\0" * self.block_size - - # we use super() in order to avoid any deadlock with __setattr__ - super(_BlockCipher, self).__setattr__("key", key) - super(_BlockCipher, self).__setattr__("iv", iv) - - self._cipher = Cipher(self.pc_cls(key), - self.pc_cls_mode(iv), - backend=backend) - - def __setattr__(self, name, val): - if name == "key": - if self._cipher is not None: - self._cipher.algorithm.key = val - self.ready["key"] = True - elif name == "iv": - if self._cipher is not None: - self._cipher.mode._initialization_vector = val - self.ready["iv"] = True - super(_BlockCipher, self).__setattr__(name, val) - - def encrypt(self, data): - """ - Encrypt the data. Also, update the cipher iv. This is needed for SSLv3 - and TLS 1.0. For TLS 1.1/1.2, it is overwritten in TLS.post_build(). - """ - if False in six.itervalues(self.ready): - raise CipherError(data) - encryptor = self._cipher.encryptor() - tmp = encryptor.update(data) + encryptor.finalize() - self.iv = tmp[-self.block_size:] - return tmp - - def decrypt(self, data): - """ - Decrypt the data. Also, update the cipher iv. This is needed for SSLv3 - and TLS 1.0. For TLS 1.1/1.2, it is overwritten in TLS.pre_dissect(). - If we lack the key, we raise a CipherError which contains the input. - """ - if False in six.itervalues(self.ready): - raise CipherError(data) - decryptor = self._cipher.decryptor() - tmp = decryptor.update(data) + decryptor.finalize() - self.iv = data[-self.block_size:] - return tmp - - def snapshot(self): - c = self.__class__(self.key, self.iv) - c.ready = self.ready.copy() - return c - - -if conf.crypto_valid: - class Cipher_AES_128_CBC(_BlockCipher): - pc_cls = algorithms.AES - pc_cls_mode = modes.CBC - block_size = 16 - key_len = 16 - - class Cipher_AES_256_CBC(Cipher_AES_128_CBC): - key_len = 32 - - class Cipher_CAMELLIA_128_CBC(_BlockCipher): - pc_cls = algorithms.Camellia - pc_cls_mode = modes.CBC - block_size = 16 - key_len = 16 - - class Cipher_CAMELLIA_256_CBC(Cipher_CAMELLIA_128_CBC): - key_len = 32 - - -# Mostly deprecated ciphers - -if conf.crypto_valid: - class Cipher_DES_CBC(_BlockCipher): - pc_cls = algorithms.TripleDES - pc_cls_mode = modes.CBC - block_size = 8 - key_len = 8 - - class Cipher_DES40_CBC(Cipher_DES_CBC): - """ - This is an export cipher example. The key length has been weakened to 5 - random bytes (i.e. 5 bytes will be extracted from the master_secret). - Yet, we still need to know the original length which will actually be - fed into the encryption algorithm. This is what expanded_key_len - is for, and it gets used in PRF.postprocess_key_for_export(). - We never define this attribute with non-export ciphers. - """ - expanded_key_len = 8 - key_len = 5 - - class Cipher_3DES_EDE_CBC(_BlockCipher): - pc_cls = algorithms.TripleDES - pc_cls_mode = modes.CBC - block_size = 8 - key_len = 24 - - class Cipher_IDEA_CBC(_BlockCipher): - pc_cls = algorithms.IDEA - pc_cls_mode = modes.CBC - block_size = 8 - key_len = 16 - - class Cipher_SEED_CBC(_BlockCipher): - pc_cls = algorithms.SEED - pc_cls_mode = modes.CBC - block_size = 16 - key_len = 16 - - -_sslv2_block_cipher_algs = {} - -if conf.crypto_valid: - _sslv2_block_cipher_algs.update({ - "IDEA_128_CBC": Cipher_IDEA_CBC, - "DES_64_CBC": Cipher_DES_CBC, - "DES_192_EDE3_CBC": Cipher_3DES_EDE_CBC - }) - - -# We need some black magic for RC2, which is not registered by default -# to the openssl backend of the cryptography library. -# If the current version of openssl does not support rc2, the RC2 ciphers are -# silently not declared, and the corresponding suites will have 'usable' False. - -if conf.crypto_valid: - @register_interface(BlockCipherAlgorithm) - @register_interface(CipherAlgorithm) - class _ARC2(object): - name = "RC2" - block_size = 64 - key_sizes = frozenset([128]) - - def __init__(self, key): - self.key = algorithms._verify_key_size(self, key) - - @property - def key_size(self): - return len(self.key) * 8 - - _gcbn_format = "{cipher.name}-{mode.name}" - if GetCipherByName(_gcbn_format)(backend, _ARC2, modes.CBC) != \ - backend._ffi.NULL: - - class Cipher_RC2_CBC(_BlockCipher): - pc_cls = _ARC2 - pc_cls_mode = modes.CBC - block_size = 8 - key_len = 16 - - class Cipher_RC2_CBC_40(Cipher_RC2_CBC): - expanded_key_len = 16 - key_len = 5 - - backend.register_cipher_adapter(Cipher_RC2_CBC.pc_cls, - Cipher_RC2_CBC.pc_cls_mode, - GetCipherByName(_gcbn_format)) - - _sslv2_block_cipher_algs["RC2_128_CBC"] = Cipher_RC2_CBC - - -_tls_block_cipher_algs.update(_sslv2_block_cipher_algs) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/cipher_stream.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/cipher_stream.py deleted file mode 100644 index 8a207a1dca..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/cipher_stream.py +++ /dev/null @@ -1,133 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -Stream ciphers. -""" - -from __future__ import absolute_import -from scapy.config import conf -from scapy.layers.tls.crypto.common import CipherError -import scapy.modules.six as six - -if conf.crypto_valid: - from cryptography.hazmat.primitives.ciphers import Cipher, algorithms - from cryptography.hazmat.backends import default_backend - - -_tls_stream_cipher_algs = {} - - -class _StreamCipherMetaclass(type): - """ - Cipher classes are automatically registered through this metaclass. - Furthermore, their name attribute is extracted from their class name. - """ - def __new__(cls, ciph_name, bases, dct): - if ciph_name != "_StreamCipher": - dct["name"] = ciph_name[7:] # remove leading "Cipher_" - the_class = super(_StreamCipherMetaclass, cls).__new__(cls, ciph_name, - bases, dct) - if ciph_name != "_StreamCipher": - _tls_stream_cipher_algs[ciph_name[7:]] = the_class - return the_class - - -class _StreamCipher(six.with_metaclass(_StreamCipherMetaclass, object)): - type = "stream" - - def __init__(self, key=None): - """ - Note that we have to keep the encryption/decryption state in unique - encryptor and decryptor objects. This differs from _BlockCipher. - - In order to do connection state snapshots, we need to be able to - recreate past cipher contexts. This is why we feed _enc_updated_with - and _dec_updated_with every time encrypt() or decrypt() is called. - """ - self.ready = {"key": True} - if key is None: - self.ready["key"] = False - if hasattr(self, "expanded_key_len"): - tmp_len = self.expanded_key_len - else: - tmp_len = self.key_len - key = b"\0" * tmp_len - - # we use super() in order to avoid any deadlock with __setattr__ - super(_StreamCipher, self).__setattr__("key", key) - - self._cipher = Cipher(self.pc_cls(key), - mode=None, - backend=default_backend()) - self.encryptor = self._cipher.encryptor() - self.decryptor = self._cipher.decryptor() - self._enc_updated_with = b"" - self._dec_updated_with = b"" - - def __setattr__(self, name, val): - """ - We have to keep the encryptor/decryptor for a long time, - however they have to be updated every time the key is changed. - """ - if name == "key": - if self._cipher is not None: - self._cipher.algorithm.key = val - self.encryptor = self._cipher.encryptor() - self.decryptor = self._cipher.decryptor() - self.ready["key"] = True - super(_StreamCipher, self).__setattr__(name, val) - - def encrypt(self, data): - if False in six.itervalues(self.ready): - raise CipherError(data) - self._enc_updated_with += data - return self.encryptor.update(data) - - def decrypt(self, data): - if False in six.itervalues(self.ready): - raise CipherError(data) - self._dec_updated_with += data - return self.decryptor.update(data) - - def snapshot(self): - c = self.__class__(self.key) - c.ready = self.ready.copy() - c.encryptor.update(self._enc_updated_with) - c.decryptor.update(self._dec_updated_with) - c._enc_updated_with = self._enc_updated_with - c._dec_updated_with = self._dec_updated_with - return c - - -if conf.crypto_valid: - class Cipher_RC4_128(_StreamCipher): - pc_cls = algorithms.ARC4 - key_len = 16 - - class Cipher_RC4_40(Cipher_RC4_128): - expanded_key_len = 16 - key_len = 5 - - -class Cipher_NULL(_StreamCipher): - key_len = 0 - - def __init__(self, key=None): - self.ready = {"key": True} - self._cipher = None - # we use super() in order to avoid any deadlock with __setattr__ - super(Cipher_NULL, self).__setattr__("key", key) - - def snapshot(self): - c = self.__class__(self.key) - c.ready = self.ready.copy() - return c - - def encrypt(self, data): - return data - - def decrypt(self, data): - return data diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/ciphers.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/ciphers.py deleted file mode 100644 index f2755b2c55..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/ciphers.py +++ /dev/null @@ -1,18 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016 Maxence Tury -# This program is published under a GPLv2 license - -""" -TLS ciphers. -""" - -# in order to avoid circular dependencies. -from scapy.layers.tls.crypto.cipher_aead import _tls_aead_cipher_algs -from scapy.layers.tls.crypto.cipher_block import _tls_block_cipher_algs -from scapy.layers.tls.crypto.cipher_stream import _tls_stream_cipher_algs - -_tls_cipher_algs = {} -_tls_cipher_algs.update(_tls_block_cipher_algs) -_tls_cipher_algs.update(_tls_stream_cipher_algs) -_tls_cipher_algs.update(_tls_aead_cipher_algs) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/common.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/common.py deleted file mode 100644 index 9653824ebc..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/common.py +++ /dev/null @@ -1,14 +0,0 @@ -# This file is part of Scapy -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -TLS ciphers. -""" - - -class CipherError(Exception): - """ - Raised when .decrypt() or .auth_decrypt() fails. - """ - pass diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/compression.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/compression.py deleted file mode 100644 index 049f4db092..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/compression.py +++ /dev/null @@ -1,88 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016 Maxence Tury -# This program is published under a GPLv2 license - -""" -TLS compression. -""" - -from __future__ import absolute_import -import zlib - -from scapy.error import warning -import scapy.modules.six as six - - -_tls_compression_algs = {} -_tls_compression_algs_cls = {} - - -class _GenericCompMetaclass(type): - """ - Compression classes are automatically registered through this metaclass. - """ - def __new__(cls, name, bases, dct): - the_class = super(_GenericCompMetaclass, cls).__new__(cls, name, - bases, dct) - comp_name = dct.get("name") - val = dct.get("val") - if comp_name: - _tls_compression_algs[val] = comp_name - _tls_compression_algs_cls[val] = the_class - return the_class - - -class _GenericComp(six.with_metaclass(_GenericCompMetaclass, object)): - pass - - -class Comp_NULL(_GenericComp): - """ - The default and advised compression method for TLS: doing nothing. - """ - name = "null" - val = 0 - - def compress(self, s): - return s - - def decompress(self, s): - return s - - -class Comp_Deflate(_GenericComp): - """ - DEFLATE algorithm, specified for TLS by RFC 3749. - """ - name = "deflate" - val = 1 - - def compress(self, s): - tmp = self.compress_state.compress(s) - tmp += self.compress_state.flush(zlib.Z_FULL_FLUSH) - return tmp - - def decompress(self, s): - return self.decompress_state.decompress(s) - - def __init__(self): - self.compress_state = zlib.compressobj() - self.decompress_state = zlib.decompressobj() - - -class Comp_LZS(_GenericComp): - """ - Lempel-Zic-Stac (LZS) algorithm, specified for TLS by RFC 3943. - XXX No support for now. - """ - name = "LZS" - val = 64 - - def compress(self, s): - warning("LZS Compression algorithm is not implemented yet") - return s - - def decompress(self, s): - warning("LZS Compression algorithm is not implemented yet") - return s diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/groups.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/groups.py deleted file mode 100644 index 955e06ccdc..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/groups.py +++ /dev/null @@ -1,696 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -This is a register for DH groups from RFC 3526 and RFC 4306. -At this time the groups from RFC 7919 have not been registered by openssl, -thus they cannot be imported from the cryptography library. - -We also provide TLS identifiers for these DH groups and also the ECDH groups. -(Note that the equivalent of _ffdh_groups for ECDH is ec._CURVE_TYPES.) -""" - -from __future__ import absolute_import - -from scapy.config import conf -from scapy.utils import long_converter -import scapy.modules.six as six -if conf.crypto_valid: - from cryptography.hazmat.backends import default_backend - -# We have to start by a dirty hack in order to allow long generators, -# which some versions of openssl love to use... - -if conf.crypto_valid: - from cryptography.hazmat.primitives.asymmetric.dh import DHParameterNumbers - - try: - # We test with dummy values whether the size limitation has been removed. # noqa: E501 - pn_test = DHParameterNumbers(2, 7) - except ValueError: - # We get rid of the limitation through the cryptography v1.9 __init__. - - def DHParameterNumbers__init__hack(self, p, g, q=None): - if ( - not isinstance(p, six.integer_types) or - not isinstance(g, six.integer_types) - ): - raise TypeError("p and g must be integers") - if q is not None and not isinstance(q, six.integer_types): - raise TypeError("q must be integer or None") - - self._p = p - self._g = g - self._q = q - - DHParameterNumbers.__init__ = DHParameterNumbers__init__hack - - # End of hack. - - -_ffdh_groups = {} - - -class _FFDHParamsMetaclass(type): - def __new__(cls, ffdh_name, bases, dct): - the_class = super(_FFDHParamsMetaclass, cls).__new__(cls, ffdh_name, - bases, dct) - if conf.crypto_valid and ffdh_name != "_FFDHParams": - pn = DHParameterNumbers(the_class.m, the_class.g) - params = pn.parameters(default_backend()) - _ffdh_groups[ffdh_name] = [params, the_class.mLen] - return the_class - - -class _FFDHParams(six.with_metaclass(_FFDHParamsMetaclass)): - pass - - -class modp768(_FFDHParams): - g = 0x02 - m = long_converter(""" - FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08 - 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B - 302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9 - A63A3620 FFFFFFFF FFFFFFFF""") - mLen = 768 - - -class modp1024(_FFDHParams): # From RFC 4306 - g = 0x02 - m = long_converter(""" - FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08 - 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B - 302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9 - A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 - 49286651 ECE65381 FFFFFFFF FFFFFFFF""") - mLen = 1024 - - -class modp1536(_FFDHParams): # From RFC 3526 - g = 0x02 - m = long_converter(""" - FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 - 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD - EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 - E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED - EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D - C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F - 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D - 670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF""") - mLen = 1536 - - -class modp2048(_FFDHParams): # From RFC 3526 - g = 0x02 - m = long_converter(""" - FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 - 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD - EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 - E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED - EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D - C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F - 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D - 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B - E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 - DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 - 15728E5A 8AACAA68 FFFFFFFF FFFFFFFF""") - mLen = 2048 - - -class modp3072(_FFDHParams): # From RFC 3526 - g = 0x02 - m = long_converter(""" - FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 - 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD - EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 - E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED - EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D - C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F - 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D - 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B - E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 - DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 - 15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64 - ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7 - ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B - F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C - BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 - 43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF""") - mLen = 3072 - - -class modp4096(_FFDHParams): # From RFC 3526 - g = 0x02 - m = long_converter(""" - FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 - 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD - EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 - E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED - EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D - C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F - 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D - 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B - E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 - DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 - 15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64 - ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7 - ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B - F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C - BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 - 43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 - 88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA - 2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6 - 287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED - 1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9 - 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199 - FFFFFFFF FFFFFFFF""") - mLen = 4096 - - -class modp6144(_FFDHParams): # From RFC 3526 - g = 0x02 - m = long_converter(""" - FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08 - 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B - 302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9 - A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 - 49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 - FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D - 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C - 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718 - 3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D - 04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D - B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 - 1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C - BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC - E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 88719A10 BDBA5B26 - 99C32718 6AF4E23C 1A946834 B6150BDA 2583E9CA 2AD44CE8 DBBBC2DB - 04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2 - 233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127 - D5B05AA9 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492 - 36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD F8FF9406 - AD9E530E E5DB382F 413001AE B06A53ED 9027D831 179727B0 865A8918 - DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B DB7F1447 E6CC254B 33205151 - 2BD7AF42 6FB8F401 378CD2BF 5983CA01 C64B92EC F032EA15 D1721D03 - F482D7CE 6E74FEF6 D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F - BEC7E8F3 23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA - CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 06A1D58B - B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C DA56C9EC 2EF29632 - 387FE8D7 6E3C0468 043E8F66 3F4860EE 12BF2D5B 0B7474D6 E694F91E - 6DCC4024 FFFFFFFF FFFFFFFF""") - mLen = 6144 - - -class modp8192(_FFDHParams): # From RFC 3526 - g = 0x02 - m = long_converter(""" - FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 - 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD - EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 - E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED - EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D - C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F - 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D - 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B - E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 - DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 - 15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64 - ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7 - ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B - F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C - BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 - 43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 - 88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA - 2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6 - 287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED - 1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9 - 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492 - 36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD - F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831 - 179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B - DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF - 5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6 - D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3 - 23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA - CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 - 06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C - DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE - 12BF2D5B 0B7474D6 E694F91E 6DBE1159 74A3926F 12FEE5E4 - 38777CB6 A932DF8C D8BEC4D0 73B931BA 3BC832B6 8D9DD300 - 741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C 5AE4F568 - 3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9 - 22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B - 4BCBC886 2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A - 062B3CF5 B3A278A6 6D2A13F8 3F44F82D DF310EE0 74AB6A36 - 4597E899 A0255DC1 64F31CC5 0846851D F9AB4819 5DED7EA1 - B1D510BD 7EE74D73 FAF36BC3 1ECFA268 359046F4 EB879F92 - 4009438B 481C6CD7 889A002E D5EE382B C9190DA6 FC026E47 - 9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71 - 60C980DD 98EDD3DF FFFFFFFF FFFFFFFF""") - mLen = 8192 - - -class ffdhe2048(_FFDHParams): # From RFC 7919 - g = 0x02 - m = long_converter(""" - FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1 - D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9 - 7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561 - 2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935 - 984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735 - 30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB - B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19 - 0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61 - 9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73 - 3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA - 886B4238 61285C97 FFFFFFFF FFFFFFFF - """) - mLen = 2048 - - -class ffdhe3072(_FFDHParams): # From RFC 7919 - g = 0x02 - m = long_converter(""" - FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1 - D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9 - 7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561 - 2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935 - 984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735 - 30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB - B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19 - 0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61 - 9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73 - 3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA - 886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238 - 61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C - AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3 - 64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D - ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF - 3C1B20EE 3FD59D7C 25E41D2B 66C62E37 FFFFFFFF FFFFFFFF - """) - mLen = 3072 - - -class ffdhe4096(_FFDHParams): # From RFC 7919 - g = 0x02 - m = long_converter(""" - FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1 - D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9 - 7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561 - 2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935 - 984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735 - 30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB - B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19 - 0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61 - 9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73 - 3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA - 886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238 - 61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C - AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3 - 64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D - ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF - 3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB - 7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004 - 87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832 - A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A - 1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF - 8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E655F6A - FFFFFFFF FFFFFFFF - """) - mLen = 4096 - - -class ffdhe6144(_FFDHParams): # From RFC 7919 - g = 0x02 - m = long_converter(""" - FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1 - D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9 - 7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561 - 2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935 - 984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735 - 30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB - B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19 - 0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61 - 9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73 - 3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA - 886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238 - 61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C - AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3 - 64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D - ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF - 3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB - 7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004 - 87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832 - A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A - 1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF - 8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E0DD902 - 0BFD64B6 45036C7A 4E677D2C 38532A3A 23BA4442 CAF53EA6 - 3BB45432 9B7624C8 917BDD64 B1C0FD4C B38E8C33 4C701C3A - CDAD0657 FCCFEC71 9B1F5C3E 4E46041F 388147FB 4CFDB477 - A52471F7 A9A96910 B855322E DB6340D8 A00EF092 350511E3 - 0ABEC1FF F9E3A26E 7FB29F8C 183023C3 587E38DA 0077D9B4 - 763E4E4B 94B2BBC1 94C6651E 77CAF992 EEAAC023 2A281BF6 - B3A739C1 22611682 0AE8DB58 47A67CBE F9C9091B 462D538C - D72B0374 6AE77F5E 62292C31 1562A846 505DC82D B854338A - E49F5235 C95B9117 8CCF2DD5 CACEF403 EC9D1810 C6272B04 - 5B3B71F9 DC6B80D6 3FDD4A8E 9ADB1E69 62A69526 D43161C1 - A41D570D 7938DAD4 A40E329C D0E40E65 FFFFFFFF FFFFFFFF - """) - mLen = 6144 - - -class ffdhe8192(_FFDHParams): # From RFC 7919 - g = 0x02 - m = long_converter(""" - FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1 - D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9 - 7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561 - 2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935 - 984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735 - 30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB - B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19 - 0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61 - 9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73 - 3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA - 886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238 - 61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C - AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3 - 64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D - ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF - 3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB - 7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004 - 87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832 - A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A - 1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF - 8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E0DD902 - 0BFD64B6 45036C7A 4E677D2C 38532A3A 23BA4442 CAF53EA6 - 3BB45432 9B7624C8 917BDD64 B1C0FD4C B38E8C33 4C701C3A - CDAD0657 FCCFEC71 9B1F5C3E 4E46041F 388147FB 4CFDB477 - A52471F7 A9A96910 B855322E DB6340D8 A00EF092 350511E3 - 0ABEC1FF F9E3A26E 7FB29F8C 183023C3 587E38DA 0077D9B4 - 763E4E4B 94B2BBC1 94C6651E 77CAF992 EEAAC023 2A281BF6 - B3A739C1 22611682 0AE8DB58 47A67CBE F9C9091B 462D538C - D72B0374 6AE77F5E 62292C31 1562A846 505DC82D B854338A - E49F5235 C95B9117 8CCF2DD5 CACEF403 EC9D1810 C6272B04 - 5B3B71F9 DC6B80D6 3FDD4A8E 9ADB1E69 62A69526 D43161C1 - A41D570D 7938DAD4 A40E329C CFF46AAA 36AD004C F600C838 - 1E425A31 D951AE64 FDB23FCE C9509D43 687FEB69 EDD1CC5E - 0B8CC3BD F64B10EF 86B63142 A3AB8829 555B2F74 7C932665 - CB2C0F1C C01BD702 29388839 D2AF05E4 54504AC7 8B758282 - 2846C0BA 35C35F5C 59160CC0 46FD8251 541FC68C 9C86B022 - BB709987 6A460E74 51A8A931 09703FEE 1C217E6C 3826E52C - 51AA691E 0E423CFC 99E9E316 50C1217B 624816CD AD9A95F9 - D5B80194 88D9C0A0 A1FE3075 A577E231 83F81D4A 3F2FA457 - 1EFC8CE0 BA8A4FE8 B6855DFE 72B0A66E DED2FBAB FBE58A30 - FAFABE1C 5D71A87E 2F741EF8 C1FE86FE A6BBFDE5 30677F0D - 97D11D49 F7A8443D 0822E506 A9F4614E 011E2A94 838FF88C - D68C8BB7 C5C6424C FFFFFFFF FFFFFFFF - """) - mLen = 8192 - - -_tls_named_ffdh_groups = {256: "ffdhe2048", 257: "ffdhe3072", - 258: "ffdhe4096", 259: "ffdhe6144", - 260: "ffdhe8192"} - -_tls_named_curves = {1: "sect163k1", 2: "sect163r1", 3: "sect163r2", - 4: "sect193r1", 5: "sect193r2", 6: "sect233k1", - 7: "sect233r1", 8: "sect239k1", 9: "sect283k1", - 10: "sect283r1", 11: "sect409k1", 12: "sect409r1", - 13: "sect571k1", 14: "sect571r1", 15: "secp160k1", - 16: "secp160r1", 17: "secp160r2", 18: "secp192k1", - 19: "secp192r1", 20: "secp224k1", 21: "secp224r1", - 22: "secp256k1", 23: "secp256r1", 24: "secp384r1", - 25: "secp521r1", 26: "brainpoolP256r1", - 27: "brainpoolP384r1", 28: "brainpoolP512r1", - 29: "x25519", 30: "x448", - 0xff01: "arbitrary_explicit_prime_curves", - 0xff02: "arbitrary_explicit_char2_curves"} - -_tls_named_groups = {} -_tls_named_groups.update(_tls_named_ffdh_groups) -_tls_named_groups.update(_tls_named_curves) - - -# Below lies ghost code since the shift from 'ecdsa' to 'cryptography' lib. -# Part of the code has been kept, but commented out, in case anyone would like -# to improve ECC support in 'cryptography' (namely for the compressed point -# format and additional curves). -# -# Recommended curve parameters from www.secg.org/SEC2-Ver-1.0.pdf -# and www.ecc-brainpool.org/download/Domain-parameters.pdf -# -# -# import math -# -# from scapy.utils import long_converter, binrepr -# from scapy.layers.tls.crypto.pkcs1 import pkcs_i2osp, pkcs_os2ip -# -# -# def encode_point(point, point_format=0): -# """ -# Return a string representation of the Point p, according to point_format. -# """ -# pLen = len(binrepr(point.curve().p())) -# x = pkcs_i2osp(point.x(), math.ceil(pLen/8)) -# y = pkcs_i2osp(point.y(), math.ceil(pLen/8)) -# if point_format == 0: -# frmt = b'\x04' -# elif point_format == 1: -# frmt = chr(2 + y%2) -# y = '' -# else: -# raise Exception("No support for point_format %d" % point_format) -# return frmt + x + y -# -# -# try: -# import ecdsa -# ecdsa_support = True -# except ImportError: -# import logging -# log_loading = logging.getLogger("scapy.loading") -# log_loading.info("Can't import python ecdsa lib. No curves.") -# -# -# if ecdsa_support: -# -# from ecdsa.ellipticcurve import CurveFp, Point -# from ecdsa.curves import Curve -# from ecdsa.numbertheory import square_root_mod_prime -# -# -# def extract_coordinates(g, curve): -# """ -# Return the coordinates x and y as integers, -# regardless of the point format of string g. -# Second expected parameter is a CurveFp. -# """ -# p = curve.p() -# point_format = g[0] -# point = g[1:] -# if point_format == b'\x04': -# point_len = len(point) -# if point_len % 2 != 0: -# raise Exception("Point length is not even.") -# x_bytes = point[:point_len>>1] -# x = pkcs_os2ip(x_bytes) % p -# y_bytes = point[point_len>>1:] -# y = pkcs_os2ip(y_bytes) % p -# elif point_format in [b'\x02', b'\x03']: -# x_bytes = point -# x = pkcs_os2ip(x_bytes) % p -# # perform the y coordinate computation with self.tls_ec -# y_square = (x*x*x + curve.a()*x + curve.b()) % p -# y = square_root_mod_prime(y_square, p) -# y_parity = ord(point_format) % 2 # \x02 means even, \x03 means odd # noqa: E501 -# if y % 2 != y_parity: -# y = -y % p -# else: -# raise Exception("Point starts with %s. This encoding " -# "is not recognized." % repr(point_format)) -# if not curve.contains_point(x, y): -# raise Exception("The point we extracted does not belong on the curve!") # noqa: E501 -# return x, y -# -# def import_curve(p, a, b, g, r, name="dummyName", oid=(1, 3, 132, 0, 0xff)): # noqa: E501 -# """ -# Create an ecdsa.curves.Curve from the usual parameters. -# Arguments may be either octet strings or integers, -# except g which we expect to be an octet string. -# """ -# if isinstance(p, str): -# p = pkcs_os2ip(p) -# if isinstance(a, str): -# a = pkcs_os2ip(a) -# if isinstance(b, str): -# b = pkcs_os2ip(b) -# if isinstance(r, str): -# r = pkcs_os2ip(r) -# curve = CurveFp(p, a, b) -# x, y = extract_coordinates(g, curve) -# generator = Point(curve, x, y, r) -# return Curve(name, curve, generator, oid) - -# Named curves - -# We always provide _a as a positive integer. - -# _p = long_converter(""" -# ffffffff ffffffff ffffffff fffffffe ffffac73""") -# _a = 0 -# _b = 7 -# _Gx = long_converter(""" -# 3b4c382c e37aa192 a4019e76 3036f4f5 dd4d7ebb""") -# _Gy = long_converter(""" -# 938cf935 318fdced 6bc28286 531733c3 f03c4fee""") -# _r = long_converter("""01 -# 00000000 00000000 0001b8fa 16dfab9a ca16b6b3""") -# curve = CurveFp(_p, _a, _b) -# generator = Point(curve, _Gx, _Gy, _r) -# SECP160k1 = Curve("SECP160k1", curve, generator, -# (1, 3, 132, 0, 9), "secp160k1") - -# _p = long_converter(""" -# ffffffff ffffffff ffffffff ffffffff 7fffffff""") -# _a = -3 % _p -# _b = long_converter(""" -# 1c97befc 54bd7a8b 65acf89f 81d4d4ad c565fa45""") -# _Gx = long_converter(""" -# 4a96b568 8ef57328 46646989 68c38bb9 13cbfc82""") -# _Gy = long_converter(""" -# 23a62855 3168947d 59dcc912 04235137 7ac5fb32""") -# _r = long_converter("""01 -# 00000000 00000000 0001f4c8 f927aed3 ca752257""") -# curve = CurveFp(_p, _a, _b) -# generator = Point(curve, _Gx, _Gy, _r) -# SECP160r1 = Curve("SECP160r1", curve, generator, -# (1, 3, 132, 0, 8), "secp160r1") - -# _p = long_converter(""" -# ffffffff ffffffff ffffffff fffffffe ffffac73""") -# _a = -3 % _p -# _b = long_converter(""" -# b4e134d3 fb59eb8b ab572749 04664d5a f50388ba""") -# _Gx = long_converter(""" -# 52dcb034 293a117e 1f4ff11b 30f7199d 3144ce6d""") -# _Gy = long_converter(""" -# feaffef2 e331f296 e071fa0d f9982cfe a7d43f2e""") -# _r = long_converter("""01 -# 00000000 00000000 0000351e e786a818 f3a1a16b""") -# curve = CurveFp(_p, _a, _b) -# generator = Point(curve, _Gx, _Gy, _r) -# SECP160r2 = Curve("SECP160r2", curve, generator, -# (1, 3, 132, 0, 30), "secp160r2") - -# _p = long_converter(""" -# ffffffff ffffffff ffffffff ffffffff fffffffe ffffee37""") -# _a = 0 -# _b = 3 -# _Gx = long_converter(""" -# db4ff10e c057e9ae 26b07d02 80b7f434 1da5d1b1 eae06c7d""") -# _Gy = long_converter(""" -# 9b2f2f6d 9c5628a7 844163d0 15be8634 4082aa88 d95e2f9d""") -# _r = long_converter(""" -# ffffffff ffffffff fffffffe 26f2fc17 0f69466a 74defd8d""") -# curve = CurveFp(_p, _a, _b) -# generator = Point(curve, _Gx, _Gy, _r) -# SECP192k1 = Curve("SECP192k1", curve, generator, -# (1, 3, 132, 0, 31), "secp192k1") - -# _p = long_converter(""" -# ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe -# ffffe56d""") -# _a = 0 -# _b = 5 -# _Gx = long_converter(""" -# a1455b33 4df099df 30fc28a1 69a467e9 e47075a9 0f7e650e -# b6b7a45c""") -# _Gy = long_converter(""" -# 7e089fed 7fba3442 82cafbd6 f7e319f7 c0b0bd59 e2ca4bdb -# 556d61a5""") -# _r = long_converter("""01 -# 00000000 00000000 00000000 0001dce8 d2ec6184 caf0a971 -# 769fb1f7""") -# curve = CurveFp(_p, _a, _b) -# generator = Point(curve, _Gx, _Gy, _r) -# SECP224k1 = Curve("SECP224k1", curve, generator, -# (1, 3, 132, 0, 32), "secp224k1") - -# _p = long_converter(""" -# A9FB57DB A1EEA9BC 3E660A90 9D838D72 6E3BF623 D5262028 -# 2013481D 1F6E5377""") -# _a = long_converter(""" -# 7D5A0975 FC2C3057 EEF67530 417AFFE7 FB8055C1 26DC5C6C -# E94A4B44 F330B5D9""") -# _b = long_converter(""" -# 26DC5C6C E94A4B44 F330B5D9 BBD77CBF 95841629 5CF7E1CE -# 6BCCDC18 FF8C07B6""") -# _Gx = long_converter(""" -# 8BD2AEB9 CB7E57CB 2C4B482F FC81B7AF B9DE27E1 E3BD23C2 -# 3A4453BD 9ACE3262""") -# _Gy = long_converter(""" -# 547EF835 C3DAC4FD 97F8461A 14611DC9 C2774513 2DED8E54 -# 5C1D54C7 2F046997""") -# _r = long_converter(""" -# A9FB57DB A1EEA9BC 3E660A90 9D838D71 8C397AA3 B561A6F7 -# 901E0E82 974856A7""") -# curve = CurveFp(_p, _a, _b) -# generator = Point(curve, _Gx, _Gy, _r) -# BRNP256r1 = Curve("BRNP256r1", curve, generator, -# (1, 3, 36, 3, 3, 2, 8, 1, 1, 7), "brainpoolP256r1") - -# _p = long_converter(""" -# 8CB91E82 A3386D28 0F5D6F7E 50E641DF 152F7109 ED5456B4 -# 12B1DA19 7FB71123 ACD3A729 901D1A71 87470013 3107EC53""") -# _a = long_converter(""" -# 7BC382C6 3D8C150C 3C72080A CE05AFA0 C2BEA28E 4FB22787 -# 139165EF BA91F90F 8AA5814A 503AD4EB 04A8C7DD 22CE2826""") -# _b = long_converter(""" -# 04A8C7DD 22CE2826 8B39B554 16F0447C 2FB77DE1 07DCD2A6 -# 2E880EA5 3EEB62D5 7CB43902 95DBC994 3AB78696 FA504C11""") -# _Gx = long_converter(""" -# 1D1C64F0 68CF45FF A2A63A81 B7C13F6B 8847A3E7 7EF14FE3 -# DB7FCAFE 0CBD10E8 E826E034 36D646AA EF87B2E2 47D4AF1E""") -# _Gy = long_converter(""" -# 8ABE1D75 20F9C2A4 5CB1EB8E 95CFD552 62B70B29 FEEC5864 -# E19C054F F9912928 0E464621 77918111 42820341 263C5315""") -# _r = long_converter(""" -# 8CB91E82 A3386D28 0F5D6F7E 50E641DF 152F7109 ED5456B3 -# 1F166E6C AC0425A7 CF3AB6AF 6B7FC310 3B883202 E9046565""") -# curve = CurveFp(_p, _a, _b) -# generator = Point(curve, _Gx, _Gy, _r) -# BRNP384r1 = Curve("BRNP384r1", curve, generator, -# (1, 3, 36, 3, 3, 2, 8, 1, 1, 11), "brainpoolP384r1") - -# _p = long_converter(""" -# AADD9DB8 DBE9C48B 3FD4E6AE 33C9FC07 CB308DB3 B3C9D20E -# D6639CCA 70330871 7D4D9B00 9BC66842 AECDA12A E6A380E6 -# 2881FF2F 2D82C685 28AA6056 583A48F3""") -# _a = long_converter(""" -# 7830A331 8B603B89 E2327145 AC234CC5 94CBDD8D 3DF91610 -# A83441CA EA9863BC 2DED5D5A A8253AA1 0A2EF1C9 8B9AC8B5 -# 7F1117A7 2BF2C7B9 E7C1AC4D 77FC94CA""") -# _b = long_converter(""" -# 3DF91610 A83441CA EA9863BC 2DED5D5A A8253AA1 0A2EF1C9 -# 8B9AC8B5 7F1117A7 2BF2C7B9 E7C1AC4D 77FC94CA DC083E67 -# 984050B7 5EBAE5DD 2809BD63 8016F723""") -# _Gx = long_converter(""" -# 81AEE4BD D82ED964 5A21322E 9C4C6A93 85ED9F70 B5D916C1 -# B43B62EE F4D0098E FF3B1F78 E2D0D48D 50D1687B 93B97D5F -# 7C6D5047 406A5E68 8B352209 BCB9F822""") -# _Gy = long_converter(""" -# 7DDE385D 566332EC C0EABFA9 CF7822FD F209F700 24A57B1A -# A000C55B 881F8111 B2DCDE49 4A5F485E 5BCA4BD8 8A2763AE -# D1CA2B2F A8F05406 78CD1E0F 3AD80892""") -# _r = long_converter(""" -# AADD9DB8 DBE9C48B 3FD4E6AE 33C9FC07 CB308DB3 B3C9D20E -# D6639CCA 70330870 553E5C41 4CA92619 41866119 7FAC1047 -# 1DB1D381 085DDADD B5879682 9CA90069""") -# curve = CurveFp(_p, _a, _b) -# generator = Point(curve, _Gx, _Gy, _r) -# BRNP512r1 = Curve("BRNP512r1", curve, generator, -# (1, 3, 36, 3, 3, 2, 8, 1, 1, 13), "brainpoolP512r1") diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/h_mac.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/h_mac.py deleted file mode 100644 index 5235e4c84b..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/h_mac.py +++ /dev/null @@ -1,118 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016 Maxence Tury -# This program is published under a GPLv2 license - -""" -HMAC classes. -""" - -from __future__ import absolute_import -import hmac - -from scapy.layers.tls.crypto.hash import _tls_hash_algs -import scapy.modules.six as six -from scapy.compat import bytes_encode - -_SSLv3_PAD1_MD5 = b"\x36" * 48 -_SSLv3_PAD1_SHA1 = b"\x36" * 40 -_SSLv3_PAD2_MD5 = b"\x5c" * 48 -_SSLv3_PAD2_SHA1 = b"\x5c" * 40 - -_tls_hmac_algs = {} - - -class _GenericHMACMetaclass(type): - """ - HMAC classes are automatically registered through this metaclass. - Furthermore, their name attribute is extracted from their class name. - - Note that, when used with TLS, the HMAC key length equates the output of - the associated hash function (see RFC 5246, appendix C). - Also, we do not need to instantiate the associated hash function. - """ - def __new__(cls, hmac_name, bases, dct): - hash_name = hmac_name[5:] # remove leading "Hmac_" - if hmac_name != "_GenericHMAC": - dct["name"] = "HMAC-%s" % hash_name - dct["hash_alg"] = _tls_hash_algs[hash_name] - dct["hmac_len"] = _tls_hash_algs[hash_name].hash_len - dct["key_len"] = dct["hmac_len"] - the_class = super(_GenericHMACMetaclass, cls).__new__(cls, hmac_name, - bases, dct) - if hmac_name != "_GenericHMAC": - _tls_hmac_algs[dct["name"]] = the_class - return the_class - - -class HMACError(Exception): - """ - Raised when HMAC verification fails. - """ - pass - - -class _GenericHMAC(six.with_metaclass(_GenericHMACMetaclass, object)): - def __init__(self, key=None): - if key is None: - self.key = b"" - else: - self.key = bytes_encode(key) - - def digest(self, tbd): - if self.key is None: - raise HMACError - tbd = bytes_encode(tbd) - return hmac.new(self.key, tbd, self.hash_alg.hash_cls).digest() - - def digest_sslv3(self, tbd): - if self.key is None: - raise HMACError - - h = self.hash_alg() - if h.name == "SHA": - pad1 = _SSLv3_PAD1_SHA1 - pad2 = _SSLv3_PAD2_SHA1 - elif h.name == "MD5": - pad1 = _SSLv3_PAD1_MD5 - pad2 = _SSLv3_PAD2_MD5 - else: - raise HMACError("Provided hash does not work with SSLv3.") - - return h.digest(self.key + pad2 + - h.digest(self.key + pad1 + tbd)) - - -class Hmac_NULL(_GenericHMAC): - hmac_len = 0 - key_len = 0 - - def digest(self, tbd): - return b"" - - def digest_sslv3(self, tbd): - return b"" - - -class Hmac_MD5(_GenericHMAC): - pass - - -class Hmac_SHA(_GenericHMAC): - pass - - -class Hmac_SHA224(_GenericHMAC): - pass - - -class Hmac_SHA256(_GenericHMAC): - pass - - -class Hmac_SHA384(_GenericHMAC): - pass - - -class Hmac_SHA512(_GenericHMAC): - pass diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/hash.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/hash.py deleted file mode 100644 index 056201a11a..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/hash.py +++ /dev/null @@ -1,72 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016 Maxence Tury -# This program is published under a GPLv2 license - -""" -Hash classes. -""" - -from __future__ import absolute_import -from hashlib import md5, sha1, sha224, sha256, sha384, sha512 -import scapy.modules.six as six - - -_tls_hash_algs = {} - - -class _GenericHashMetaclass(type): - """ - Hash classes are automatically registered through this metaclass. - Furthermore, their name attribute is extracted from their class name. - """ - def __new__(cls, hash_name, bases, dct): - if hash_name != "_GenericHash": - dct["name"] = hash_name[5:] # remove leading "Hash_" - the_class = super(_GenericHashMetaclass, cls).__new__(cls, hash_name, - bases, dct) - if hash_name != "_GenericHash": - _tls_hash_algs[hash_name[5:]] = the_class - return the_class - - -class _GenericHash(six.with_metaclass(_GenericHashMetaclass, object)): - def digest(self, tbd): - return self.hash_cls(tbd).digest() - - -class Hash_NULL(_GenericHash): - hash_len = 0 - - def digest(self, tbd): - return b"" - - -class Hash_MD5(_GenericHash): - hash_cls = md5 - hash_len = 16 - - -class Hash_SHA(_GenericHash): - hash_cls = sha1 - hash_len = 20 - - -class Hash_SHA224(_GenericHash): - hash_cls = sha224 - hash_len = 28 - - -class Hash_SHA256(_GenericHash): - hash_cls = sha256 - hash_len = 32 - - -class Hash_SHA384(_GenericHash): - hash_cls = sha384 - hash_len = 48 - - -class Hash_SHA512(_GenericHash): - hash_cls = sha512 - hash_len = 64 diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/hkdf.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/hkdf.py deleted file mode 100644 index f9c69c4931..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/hkdf.py +++ /dev/null @@ -1,63 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -Stateless HKDF for TLS 1.3. -""" - -import struct - -from scapy.config import conf -from scapy.layers.tls.crypto.pkcs1 import _get_hash - -if conf.crypto_valid: - from cryptography.hazmat.backends import default_backend - from cryptography.hazmat.primitives.kdf.hkdf import HKDF, HKDFExpand - from cryptography.hazmat.primitives.hashes import Hash - from cryptography.hazmat.primitives.hmac import HMAC - - -class TLS13_HKDF(object): - def __init__(self, hash_name="sha256"): - self.hash = _get_hash(hash_name) - - def extract(self, salt, ikm): - h = self.hash - hkdf = HKDF(h, h.digest_size, salt, None, default_backend()) - if ikm is None: - ikm = b"\x00" * h.digest_size - return hkdf._extract(ikm) - - def expand(self, prk, info, L): - h = self.hash - hkdf = HKDFExpand(h, L, info, default_backend()) - return hkdf.derive(prk) - - def expand_label(self, secret, label, hash_value, length): - hkdf_label = struct.pack("!H", length) - hkdf_label += struct.pack("B", 6 + len(label)) - hkdf_label += b"tls13 " - hkdf_label += label - hkdf_label += struct.pack("B", len(hash_value)) - hkdf_label += hash_value - return self.expand(secret, hkdf_label, length) - - def derive_secret(self, secret, label, messages): - h = Hash(self.hash, backend=default_backend()) - h.update(messages) - hash_messages = h.finalize() - hash_len = self.hash.digest_size - return self.expand_label(secret, label, hash_messages, hash_len) - - def compute_verify_data(self, basekey, handshake_context): - hash_len = self.hash.digest_size - finished_key = self.expand_label(basekey, b"finished", b"", hash_len) - - h = Hash(self.hash, backend=default_backend()) - h.update(handshake_context) - hash_value = h.finalize() - - hm = HMAC(finished_key, self.hash, default_backend()) - hm.update(hash_value) - return hm.finalize() diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/kx_algs.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/kx_algs.py deleted file mode 100644 index 47b8c493b7..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/kx_algs.py +++ /dev/null @@ -1,199 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -Key Exchange algorithms as listed in appendix C of RFC 4346. - -XXX No support yet for PSK (also, no static DH, DSS, SRP or KRB). -""" - -from __future__ import absolute_import -from scapy.layers.tls.keyexchange import (ServerDHParams, - ServerRSAParams, - ClientDiffieHellmanPublic, - ClientECDiffieHellmanPublic, - _tls_server_ecdh_cls_guess, - EncryptedPreMasterSecret) -import scapy.modules.six as six - - -_tls_kx_algs = {} - - -class _GenericKXMetaclass(type): - """ - We could try to set server_kx_msg and client_kx_msg while parsing - the class name... :) - """ - def __new__(cls, kx_name, bases, dct): - if kx_name != "_GenericKX": - dct["name"] = kx_name[3:] # remove leading "KX_" - the_class = super(_GenericKXMetaclass, cls).__new__(cls, kx_name, - bases, dct) - if kx_name != "_GenericKX": - the_class.export = kx_name.endswith("_EXPORT") - the_class.anonymous = "_anon" in kx_name - the_class.no_ske = not ("DHE" in kx_name or "_anon" in kx_name) - the_class.no_ske &= not the_class.export - _tls_kx_algs[kx_name[3:]] = the_class - return the_class - - -class _GenericKX(six.with_metaclass(_GenericKXMetaclass)): - pass - - -class KX_NULL(_GenericKX): - descr = "No key exchange" - server_kx_msg_cls = lambda _, m: None - client_kx_msg_cls = None - - -class KX_SSLv2(_GenericKX): - descr = "SSLv2 dummy key exchange class" - server_kx_msg_cls = lambda _, m: None - client_kx_msg_cls = None - - -class KX_TLS13(_GenericKX): - descr = "TLS 1.3 dummy key exchange class" - server_kx_msg_cls = lambda _, m: None - client_kx_msg_cls = None - - -# Standard RSA-authenticated key exchange - -class KX_RSA(_GenericKX): - descr = "RSA encryption" - server_kx_msg_cls = lambda _, m: None - client_kx_msg_cls = EncryptedPreMasterSecret - -# class KX_DH_RSA(_GenericKX): -# descr = "DH with RSA-based certificates" -# server_kx_msg_cls = lambda _,m: None -# client_kx_msg_cls = None - - -class KX_DHE_RSA(_GenericKX): - descr = "Ephemeral DH with RSA signature" - server_kx_msg_cls = lambda _, m: ServerDHParams - client_kx_msg_cls = ClientDiffieHellmanPublic - -# class KX_ECDH_RSA(_GenericKX): -# descr = "ECDH RSA key exchange" -# server_kx_msg_cls = lambda _,m: None -# client_kx_msg_cls = None - - -class KX_ECDHE_RSA(_GenericKX): - descr = "Ephemeral ECDH with RSA signature" - server_kx_msg_cls = lambda _, m: _tls_server_ecdh_cls_guess(m) - client_kx_msg_cls = ClientECDiffieHellmanPublic - - -class KX_RSA_EXPORT(KX_RSA): - descr = "RSA encryption, export version" - server_kx_msg_cls = lambda _, m: ServerRSAParams - -# class KX_DH_RSA_EXPORT(KX_DH_RSA): -# descr = "DH with RSA-based certificates - Export version" - - -class KX_DHE_RSA_EXPORT(KX_DHE_RSA): - descr = "Ephemeral DH with RSA signature, export version" - - -# Standard ECDSA-authenticated key exchange - -# class KX_ECDH_ECDSA(_GenericKX): -# descr = "ECDH ECDSA key exchange" -# server_kx_msg_cls = lambda _,m: None -# client_kx_msg_cls = None - -class KX_ECDHE_ECDSA(_GenericKX): - descr = "Ephemeral ECDH with ECDSA signature" - server_kx_msg_cls = lambda _, m: _tls_server_ecdh_cls_guess(m) - client_kx_msg_cls = ClientECDiffieHellmanPublic - - -# Classes below are offered without any guarantee. -# They may offer some parsing capabilities, -# but surely won't be able to handle a proper TLS negotiation. -# Uncomment them at your own risk. - -# Standard DSS-authenticated key exchange - -# class KX_DH_DSS(_GenericKX): -# descr = "DH with DSS-based certificates" -# server_kx_msg_cls = lambda _,m: ServerDHParams -# client_kx_msg_cls = ClientDiffieHellmanPublic - -# class KX_DHE_DSS(_GenericKX): -# descr = "Ephemeral DH with DSS signature" -# server_kx_msg_cls = lambda _,m: ServerDHParams -# client_kx_msg_cls = ClientDiffieHellmanPublic - -# class KX_DH_DSS_EXPORT(KX_DH_DSS): -# descr = "DH with DSS-based certificates - Export version" - -# class KX_DHE_DSS_EXPORT(KX_DHE_DSS): -# descr = "Ephemeral DH with DSS signature, export version" - - -# PSK-based key exchange - -# class KX_PSK(_GenericKX): # RFC 4279 -# descr = "PSK key exchange" -# server_kx_msg_cls = lambda _,m: ServerPSKParams -# client_kx_msg_cls = None - -# class KX_RSA_PSK(_GenericKX): # RFC 4279 -# descr = "RSA PSK key exchange" -# server_kx_msg_cls = lambda _,m: ServerPSKParams -# client_kx_msg_cls = None - -# class KX_DHE_PSK(_GenericKX): # RFC 4279 -# descr = "Ephemeral DH with PSK key exchange" -# server_kx_msg_cls = lambda _,m: ServerPSKParams -# client_kx_msg_cls = ClientDiffieHellmanPublic - -# class KX_ECDHE_PSK(_GenericKX): # RFC 5489 -# descr = "Ephemeral ECDH PSK key exchange" -# server_kx_msg_cls = lambda _,m: _tls_server_ecdh_cls_guess(m) -# client_kx_msg_cls = ClientDiffieHellmanPublic - - -# SRP-based key exchange - -# - - -# Kerberos-based key exchange - -# class KX_KRB5(_GenericKX): -# descr = "Kerberos 5 key exchange" -# server_kx_msg_cls = lambda _,m: None # No SKE with kerberos -# client_kx_msg_cls = None - -# class KX_KRB5_EXPORT(KX_KRB5): -# descr = "Kerberos 5 key exchange - Export version" - - -# Unauthenticated key exchange (opportunistic encryption) - -class KX_DH_anon(_GenericKX): - descr = "Anonymous DH, no signatures" - server_kx_msg_cls = lambda _, m: ServerDHParams - client_kx_msg_cls = ClientDiffieHellmanPublic - - -class KX_ECDH_anon(_GenericKX): - descr = "ECDH anonymous key exchange" - server_kx_msg_cls = lambda _, m: _tls_server_ecdh_cls_guess(m) - client_kx_msg_cls = ClientECDiffieHellmanPublic - - -class KX_DH_anon_EXPORT(KX_DH_anon): - descr = "Anonymous DH, no signatures - Export version" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/pkcs1.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/pkcs1.py deleted file mode 100644 index df9581029d..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/pkcs1.py +++ /dev/null @@ -1,226 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2008 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -PKCS #1 methods as defined in RFC 3447. - -We cannot rely solely on the cryptography library, because the openssl package -used by the cryptography library may not implement the md5-sha1 hash, as with -Ubuntu or OSX. This is why we reluctantly keep some legacy crypto here. -""" - -from __future__ import absolute_import -from scapy.compat import bytes_encode, hex_bytes, bytes_hex -import scapy.modules.six as six - -from scapy.config import conf, crypto_validator -from scapy.error import warning -if conf.crypto_valid: - from cryptography import utils - from cryptography.exceptions import InvalidSignature, UnsupportedAlgorithm - from cryptography.hazmat.backends import default_backend - from cryptography.hazmat.primitives import hashes - from cryptography.hazmat.primitives.asymmetric import padding - from cryptography.hazmat.primitives.hashes import HashAlgorithm - - -##################################################################### -# Some helpers -##################################################################### - -def pkcs_os2ip(s): - """ - OS2IP conversion function from RFC 3447. - - Input : s octet string to be converted - Output: n corresponding nonnegative integer - """ - return int(bytes_hex(s), 16) - - -def pkcs_i2osp(n, sLen): - """ - I2OSP conversion function from RFC 3447. - The length parameter allows the function to perform the padding needed. - Note that the user is responsible for providing a sufficient xLen. - - Input : n nonnegative integer to be converted - sLen intended length of the resulting octet string - Output: s corresponding octet string - """ - # if n >= 256**sLen: - # raise Exception("Integer too large for provided sLen %d" % sLen) - fmt = "%%0%dx" % (2 * sLen) - return hex_bytes(fmt % n) - - -def pkcs_ilen(n): - """ - This is a log base 256 which determines the minimum octet string - length for unequivocal representation of integer n by pkcs_i2osp. - """ - i = 0 - while n > 0: - n >>= 8 - i += 1 - return i - - -@crypto_validator -def _legacy_pkcs1_v1_5_encode_md5_sha1(M, emLen): - """ - Legacy method for PKCS1 v1.5 encoding with MD5-SHA1 hash. - """ - M = bytes_encode(M) - md5_hash = hashes.Hash(_get_hash("md5"), backend=default_backend()) - md5_hash.update(M) - sha1_hash = hashes.Hash(_get_hash("sha1"), backend=default_backend()) - sha1_hash.update(M) - H = md5_hash.finalize() + sha1_hash.finalize() - if emLen < 36 + 11: - warning("pkcs_emsa_pkcs1_v1_5_encode: " - "intended encoded message length too short") - return None - PS = b'\xff' * (emLen - 36 - 3) - return b'\x00' + b'\x01' + PS + b'\x00' + H - - -##################################################################### -# Hash and padding helpers -##################################################################### - -_get_hash = None -if conf.crypto_valid: - - # first, we add the "md5-sha1" hash from openssl to python-cryptography - @utils.register_interface(HashAlgorithm) - class MD5_SHA1(object): - name = "md5-sha1" - digest_size = 36 - block_size = 64 - - _hashes = { - "md5": hashes.MD5, - "sha1": hashes.SHA1, - "sha224": hashes.SHA224, - "sha256": hashes.SHA256, - "sha384": hashes.SHA384, - "sha512": hashes.SHA512, - "md5-sha1": MD5_SHA1 - } - - def _get_hash(hashStr): - try: - return _hashes[hashStr]() - except KeyError: - raise KeyError("Unknown hash function %s" % hashStr) - - def _get_padding(padStr, mgf=padding.MGF1, h=hashes.SHA256, label=None): - if padStr == "pkcs": - return padding.PKCS1v15() - elif padStr == "pss": - # Can't find where this is written, but we have to use the digest - # size instead of the automatic padding.PSS.MAX_LENGTH. - return padding.PSS(mgf=mgf(h), salt_length=h.digest_size) - elif padStr == "oaep": - return padding.OAEP(mgf=mgf(h), algorithm=h, label=label) - else: - warning("Key.encrypt(): Unknown padding type (%s)", padStr) - return None - - -##################################################################### -# Asymmetric Cryptography wrappers -##################################################################### - -# Make sure that default values are consistent across the whole TLS module, -# lest they be explicitly set to None between cert.py and pkcs1.py. - -class _EncryptAndVerifyRSA(object): - - @crypto_validator - def encrypt(self, m, t="pkcs", h="sha256", mgf=None, L=None): - mgf = mgf or padding.MGF1 - h = _get_hash(h) - pad = _get_padding(t, mgf, h, L) - return self.pubkey.encrypt(m, pad) - - @crypto_validator - def verify(self, M, S, t="pkcs", h="sha256", mgf=None, L=None): - M = bytes_encode(M) - mgf = mgf or padding.MGF1 - h = _get_hash(h) - pad = _get_padding(t, mgf, h, L) - try: - try: - self.pubkey.verify(S, M, pad, h) - except UnsupportedAlgorithm: - if t != "pkcs" and h != "md5-sha1": - raise UnsupportedAlgorithm("RSA verification with %s" % h) - self._legacy_verify_md5_sha1(M, S) - return True - except InvalidSignature: - return False - - def _legacy_verify_md5_sha1(self, M, S): - k = self._modulusLen // 8 - if len(S) != k: - warning("invalid signature (len(S) != k)") - return False - s = pkcs_os2ip(S) - n = self._modulus - if isinstance(s, int) and six.PY2: - s = long(s) # noqa: F821 - if (six.PY2 and not isinstance(s, long)) or s > n - 1: # noqa: F821 - warning("Key._rsaep() expects a long between 0 and n-1") - return None - m = pow(s, self._pubExp, n) - EM = pkcs_i2osp(m, k) - EMPrime = _legacy_pkcs1_v1_5_encode_md5_sha1(M, k) - if EMPrime is None: - warning("Key._rsassa_pkcs1_v1_5_verify(): unable to encode.") - return False - return EM == EMPrime - - -class _DecryptAndSignRSA(object): - - @crypto_validator - def decrypt(self, C, t="pkcs", h="sha256", mgf=None, L=None): - mgf = mgf or padding.MGF1 - h = _get_hash(h) - pad = _get_padding(t, mgf, h, L) - return self.key.decrypt(C, pad) - - @crypto_validator - def sign(self, M, t="pkcs", h="sha256", mgf=None, L=None): - M = bytes_encode(M) - mgf = mgf or padding.MGF1 - h = _get_hash(h) - pad = _get_padding(t, mgf, h, L) - try: - return self.key.sign(M, pad, h) - except UnsupportedAlgorithm: - if t != "pkcs" and h != "md5-sha1": - raise UnsupportedAlgorithm("RSA signature with %s" % h) - return self._legacy_sign_md5_sha1(M) - - def _legacy_sign_md5_sha1(self, M): - M = bytes_encode(M) - k = self._modulusLen // 8 - EM = _legacy_pkcs1_v1_5_encode_md5_sha1(M, k) - if EM is None: - warning("Key._rsassa_pkcs1_v1_5_sign(): unable to encode") - return None - m = pkcs_os2ip(EM) - n = self._modulus - if isinstance(m, int) and six.PY2: - m = long(m) # noqa: F821 - if (six.PY2 and not isinstance(m, long)) or m > n - 1: # noqa: F821 - warning("Key._rsaep() expects a long between 0 and n-1") - return None - privExp = self.key.private_numbers().d - s = pow(m, privExp, n) - return pkcs_i2osp(s, k) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/prf.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/prf.py deleted file mode 100644 index 5f7692ded6..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/prf.py +++ /dev/null @@ -1,352 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -TLS Pseudorandom Function. -""" - -from __future__ import absolute_import -from scapy.error import warning -from scapy.utils import strxor - -from scapy.layers.tls.crypto.hash import _tls_hash_algs -from scapy.layers.tls.crypto.h_mac import _tls_hmac_algs -from scapy.modules.six.moves import range -from scapy.compat import bytes_encode - - -# Data expansion functions - -def _tls_P_hash(secret, seed, req_len, hm): - """ - Provides the implementation of P_hash function defined in - section 5 of RFC 4346 (and section 5 of RFC 5246). Two - parameters have been added (hm and req_len): - - - secret : the key to be used. If RFC 4868 is to be believed, - the length must match hm.key_len. Actually, - python hmac takes care of formatting every key. - - seed : the seed to be used. - - req_len : the length of data to be generated by iterating - the specific HMAC function (hm). This prevents - multiple calls to the function. - - hm : the hmac function class to use for iteration (either - Hmac_MD5 or Hmac_SHA1 in TLS <= 1.1 or - Hmac_SHA256 or Hmac_SHA384 in TLS 1.2) - """ - hash_len = hm.hash_alg.hash_len - n = (req_len + hash_len - 1) // hash_len - seed = bytes_encode(seed) - - res = b"" - a = hm(secret).digest(seed) # A(1) - - while n > 0: - res += hm(secret).digest(a + seed) - a = hm(secret).digest(a) - n -= 1 - - return res[:req_len] - - -def _tls_P_MD5(secret, seed, req_len): - return _tls_P_hash(secret, seed, req_len, _tls_hmac_algs["HMAC-MD5"]) - - -def _tls_P_SHA1(secret, seed, req_len): - return _tls_P_hash(secret, seed, req_len, _tls_hmac_algs["HMAC-SHA"]) - - -def _tls_P_SHA256(secret, seed, req_len): - return _tls_P_hash(secret, seed, req_len, _tls_hmac_algs["HMAC-SHA256"]) - - -def _tls_P_SHA384(secret, seed, req_len): - return _tls_P_hash(secret, seed, req_len, _tls_hmac_algs["HMAC-SHA384"]) - - -def _tls_P_SHA512(secret, seed, req_len): - return _tls_P_hash(secret, seed, req_len, _tls_hmac_algs["HMAC-SHA512"]) - - -# PRF functions, according to the protocol version - -def _sslv2_PRF(secret, seed, req_len): - hash_md5 = _tls_hash_algs["MD5"]() - rounds = (req_len + hash_md5.hash_len - 1) // hash_md5.hash_len - - res = b"" - if rounds == 1: - res += hash_md5.digest(secret + seed) - else: - r = 0 - while r < rounds: - label = str(r).encode("utf8") - res += hash_md5.digest(secret + label + seed) - r += 1 - - return res[:req_len] - - -def _ssl_PRF(secret, seed, req_len): - """ - Provides the implementation of SSLv3 PRF function: - - SSLv3-PRF(secret, seed) = - MD5(secret || SHA-1("A" || secret || seed)) || - MD5(secret || SHA-1("BB" || secret || seed)) || - MD5(secret || SHA-1("CCC" || secret || seed)) || ... - - req_len should not be more than 26 x 16 = 416. - """ - if req_len > 416: - warning("_ssl_PRF() is not expected to provide more than 416 bytes") - return "" - - d = [b"A", b"B", b"C", b"D", b"E", b"F", b"G", b"H", b"I", b"J", b"K", b"L", # noqa: E501 - b"M", b"N", b"O", b"P", b"Q", b"R", b"S", b"T", b"U", b"V", b"W", b"X", # noqa: E501 - b"Y", b"Z"] - res = b"" - hash_sha1 = _tls_hash_algs["SHA"]() - hash_md5 = _tls_hash_algs["MD5"]() - rounds = (req_len + hash_md5.hash_len - 1) // hash_md5.hash_len - - for i in range(rounds): - label = d[i] * (i + 1) - tmp = hash_sha1.digest(label + secret + seed) - res += hash_md5.digest(secret + tmp) - - return res[:req_len] - - -def _tls_PRF(secret, label, seed, req_len): - """ - Provides the implementation of TLS PRF function as defined in - section 5 of RFC 4346: - - PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR - P_SHA-1(S2, label + seed) - - Parameters are: - - - secret: the secret used by the HMAC in the 2 expansion - functions (S1 and S2 are the halves of this secret). - - label: specific label as defined in various sections of the RFC - depending on the use of the generated PRF keystream - - seed: the seed used by the expansion functions. - - req_len: amount of keystream to be generated - """ - tmp_len = (len(secret) + 1) // 2 - S1 = secret[:tmp_len] - S2 = secret[-tmp_len:] - - a1 = _tls_P_MD5(S1, label + seed, req_len) - a2 = _tls_P_SHA1(S2, label + seed, req_len) - - return strxor(a1, a2) - - -def _tls12_SHA256PRF(secret, label, seed, req_len): - """ - Provides the implementation of TLS 1.2 PRF function as - defined in section 5 of RFC 5246: - - PRF(secret, label, seed) = P_SHA256(secret, label + seed) - - Parameters are: - - - secret: the secret used by the HMAC in the 2 expansion - functions (S1 and S2 are the halves of this secret). - - label: specific label as defined in various sections of the RFC - depending on the use of the generated PRF keystream - - seed: the seed used by the expansion functions. - - req_len: amount of keystream to be generated - """ - return _tls_P_SHA256(secret, label + seed, req_len) - - -def _tls12_SHA384PRF(secret, label, seed, req_len): - return _tls_P_SHA384(secret, label + seed, req_len) - - -def _tls12_SHA512PRF(secret, label, seed, req_len): - return _tls_P_SHA512(secret, label + seed, req_len) - - -class PRF(object): - """ - The PRF used by SSL/TLS varies based on the version of the protocol and - (for TLS 1.2) possibly the Hash algorithm of the negotiated cipher suite. - The various uses of the PRF (key derivation, computation of verify_data, - computation of pre_master_secret values) for the different versions of the - protocol also changes. In order to abstract those elements, the common - _tls_PRF() object is provided. It is expected to be initialised in the - context of the connection state using the tls_version and the cipher suite. - """ - - def __init__(self, hash_name="SHA256", tls_version=0x0303): - self.tls_version = tls_version - self.hash_name = hash_name - - if tls_version < 0x0300: # SSLv2 - self.prf = _sslv2_PRF - elif tls_version == 0x0300: # SSLv3 - self.prf = _ssl_PRF - elif (tls_version == 0x0301 or # TLS 1.0 - tls_version == 0x0302): # TLS 1.1 - self.prf = _tls_PRF - elif tls_version == 0x0303: # TLS 1.2 - if hash_name == "SHA384": - self.prf = _tls12_SHA384PRF - elif hash_name == "SHA512": - self.prf = _tls12_SHA512PRF - else: - self.prf = _tls12_SHA256PRF - else: - warning("Unknown TLS version") - - def compute_master_secret(self, pre_master_secret, - client_random, server_random): - """ - Return the 48-byte master_secret, computed from pre_master_secret, - client_random and server_random. See RFC 5246, section 6.3. - """ - seed = client_random + server_random - if self.tls_version < 0x0300: - return None - elif self.tls_version == 0x0300: - return self.prf(pre_master_secret, seed, 48) - else: - return self.prf(pre_master_secret, b"master secret", seed, 48) - - def derive_key_block(self, master_secret, server_random, - client_random, req_len): - """ - Perform the derivation of master_secret into a key_block of req_len - requested length. See RFC 5246, section 6.3. - """ - seed = server_random + client_random - if self.tls_version <= 0x0300: - return self.prf(master_secret, seed, req_len) - else: - return self.prf(master_secret, b"key expansion", seed, req_len) - - def compute_verify_data(self, con_end, read_or_write, - handshake_msg, master_secret): - """ - Return verify_data based on handshake messages, connection end, - master secret, and read_or_write position. See RFC 5246, section 7.4.9. - - Every TLS 1.2 cipher suite has a verify_data of length 12. Note also: - "This PRF with the SHA-256 hash function is used for all cipher - suites defined in this document and in TLS documents published - prior to this document when TLS 1.2 is negotiated." - Cipher suites using SHA-384 were defined later on. - """ - if self.tls_version < 0x0300: - return None - elif self.tls_version == 0x0300: - - if read_or_write == "write": - d = {"client": b"CLNT", "server": b"SRVR"} - else: - d = {"client": b"SRVR", "server": b"CLNT"} - label = d[con_end] - - sslv3_md5_pad1 = b"\x36" * 48 - sslv3_md5_pad2 = b"\x5c" * 48 - sslv3_sha1_pad1 = b"\x36" * 40 - sslv3_sha1_pad2 = b"\x5c" * 40 - - md5 = _tls_hash_algs["MD5"]() - sha1 = _tls_hash_algs["SHA"]() - - md5_hash = md5.digest(master_secret + sslv3_md5_pad2 + - md5.digest(handshake_msg + label + - master_secret + sslv3_md5_pad1)) - sha1_hash = sha1.digest(master_secret + sslv3_sha1_pad2 + - sha1.digest(handshake_msg + label + - master_secret + sslv3_sha1_pad1)) # noqa: E501 - verify_data = md5_hash + sha1_hash - - else: - - if read_or_write == "write": - d = {"client": "client", "server": "server"} - else: - d = {"client": "server", "server": "client"} - label = ("%s finished" % d[con_end]).encode() - - if self.tls_version <= 0x0302: - s1 = _tls_hash_algs["MD5"]().digest(handshake_msg) - s2 = _tls_hash_algs["SHA"]().digest(handshake_msg) - verify_data = self.prf(master_secret, label, s1 + s2, 12) - else: - if self.hash_name in ["MD5", "SHA"]: - h = _tls_hash_algs["SHA256"]() - else: - h = _tls_hash_algs[self.hash_name]() - s = h.digest(handshake_msg) - verify_data = self.prf(master_secret, label, s, 12) - - return verify_data - - def postprocess_key_for_export(self, key, client_random, server_random, - con_end, read_or_write, req_len): - """ - Postprocess cipher key for EXPORT ciphersuite, i.e. weakens it. - An export key generation example is given in section 6.3.1 of RFC 2246. - See also page 86 of EKR's book. - """ - s = con_end + read_or_write - s = (s == "clientwrite" or s == "serverread") - - if self.tls_version < 0x0300: - return None - elif self.tls_version == 0x0300: - if s: - tbh = key + client_random + server_random - else: - tbh = key + server_random + client_random - export_key = _tls_hash_algs["MD5"]().digest(tbh)[:req_len] - else: - if s: - tag = b"client write key" - else: - tag = b"server write key" - export_key = self.prf(key, - tag, - client_random + server_random, - req_len) - return export_key - - def generate_iv_for_export(self, client_random, server_random, - con_end, read_or_write, req_len): - """ - Generate IV for EXPORT ciphersuite, i.e. weakens it. - An export IV generation example is given in section 6.3.1 of RFC 2246. - See also page 86 of EKR's book. - """ - s = con_end + read_or_write - s = (s == "clientwrite" or s == "serverread") - - if self.tls_version < 0x0300: - return None - elif self.tls_version == 0x0300: - if s: - tbh = client_random + server_random - else: - tbh = server_random + client_random - iv = _tls_hash_algs["MD5"]().digest(tbh)[:req_len] - else: - iv_block = self.prf("", - b"IV block", - client_random + server_random, - 2 * req_len) - if s: - iv = iv_block[:req_len] - else: - iv = iv_block[req_len:] - return iv diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/suites.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/suites.py deleted file mode 100644 index 2f6eeff6dd..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/crypto/suites.py +++ /dev/null @@ -1,1317 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -TLS cipher suites. - -A comprehensive list of specified cipher suites can be consulted at: -https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml -""" - -from __future__ import absolute_import -from scapy.layers.tls.crypto.kx_algs import _tls_kx_algs -from scapy.layers.tls.crypto.hash import _tls_hash_algs -from scapy.layers.tls.crypto.h_mac import _tls_hmac_algs -from scapy.layers.tls.crypto.ciphers import _tls_cipher_algs -import scapy.modules.six as six - - -def get_algs_from_ciphersuite_name(ciphersuite_name): - """ - Return the 3-tuple made of the Key Exchange Algorithm class, the Cipher - class and the HMAC class, through the parsing of the ciphersuite name. - """ - tls1_3 = False - if ciphersuite_name.startswith("TLS"): - s = ciphersuite_name[4:] - - if s.endswith("CCM") or s.endswith("CCM_8"): - kx_name, s = s.split("_WITH_") - kx_alg = _tls_kx_algs.get(kx_name) - hash_alg = _tls_hash_algs.get("SHA256") - cipher_alg = _tls_cipher_algs.get(s) - hmac_alg = None - - else: - if "WITH" in s: - kx_name, s = s.split("_WITH_") - kx_alg = _tls_kx_algs.get(kx_name) - else: - tls1_3 = True - kx_alg = _tls_kx_algs.get("TLS13") - - hash_name = s.split('_')[-1] - hash_alg = _tls_hash_algs.get(hash_name) - - cipher_name = s[:-(len(hash_name) + 1)] - if tls1_3: - cipher_name += "_TLS13" - cipher_alg = _tls_cipher_algs.get(cipher_name) - - hmac_alg = None - if cipher_alg is not None and cipher_alg.type != "aead": - hmac_name = "HMAC-%s" % hash_name - hmac_alg = _tls_hmac_algs.get(hmac_name) - - elif ciphersuite_name.startswith("SSL"): - s = ciphersuite_name[7:] - kx_alg = _tls_kx_algs.get("SSLv2") - cipher_name, hash_name = s.split("_WITH_") - cipher_alg = _tls_cipher_algs.get(cipher_name.rstrip("_EXPORT40")) - kx_alg.export = cipher_name.endswith("_EXPORT40") - hmac_alg = _tls_hmac_algs.get("HMAC-NULL") - hash_alg = _tls_hash_algs.get(hash_name) - - return kx_alg, cipher_alg, hmac_alg, hash_alg, tls1_3 - - -_tls_cipher_suites = {} -_tls_cipher_suites_cls = {} - - -class _GenericCipherSuiteMetaclass(type): - """ - Cipher suite classes are automatically registered through this metaclass. - Their name attribute equates their respective class name. - - We also pre-compute every expected length of the key block to be generated, - which may vary according to the current tls_version. The default is set to - the TLS 1.2 length, and the value should be set at class instantiation. - - Regarding the AEAD cipher suites, note that the 'hmac_alg' attribute will - be set to None. Yet, we always need a 'hash_alg' for the PRF. - """ - def __new__(cls, cs_name, bases, dct): - cs_val = dct.get("val") - - if cs_name != "_GenericCipherSuite": - kx, c, hm, h, tls1_3 = get_algs_from_ciphersuite_name(cs_name) - - if c is None or h is None or (kx is None and not tls1_3): - dct["usable"] = False - else: - dct["usable"] = True - dct["name"] = cs_name - dct["kx_alg"] = kx - dct["cipher_alg"] = c - dct["hmac_alg"] = hm - dct["hash_alg"] = h - - if not tls1_3: - kb_len = 2 * c.key_len - - if c.type == "stream" or c.type == "block": - kb_len += 2 * hm.key_len - - kb_len_v1_0 = kb_len - if c.type == "block": - kb_len_v1_0 += 2 * c.block_size - # no explicit IVs added for TLS 1.1+ - elif c.type == "aead": - kb_len_v1_0 += 2 * c.fixed_iv_len - kb_len += 2 * c.fixed_iv_len - - dct["_key_block_len_v1_0"] = kb_len_v1_0 - dct["key_block_len"] = kb_len - - _tls_cipher_suites[cs_val] = cs_name - the_class = super(_GenericCipherSuiteMetaclass, cls).__new__(cls, - cs_name, - bases, - dct) - if cs_name != "_GenericCipherSuite": - _tls_cipher_suites_cls[cs_val] = the_class - return the_class - - -class _GenericCipherSuite(six.with_metaclass(_GenericCipherSuiteMetaclass, object)): # noqa: E501 - def __init__(self, tls_version=0x0303): - """ - Most of the attributes are fixed and have already been set by the - metaclass, but we still have to provide tls_version differentiation. - - For now, the key_block_len remains the only application if this. - Indeed for TLS 1.1+, when using a block cipher, there are no implicit - IVs derived from the master secret. Note that an overlong key_block_len - would not affect the secret generation (the trailing bytes would - simply be discarded), but we still provide this for completeness. - """ - super(_GenericCipherSuite, self).__init__() - if tls_version <= 0x301: - self.key_block_len = self._key_block_len_v1_0 - - -class TLS_NULL_WITH_NULL_NULL(_GenericCipherSuite): - val = 0x0000 - - -class TLS_RSA_WITH_NULL_MD5(_GenericCipherSuite): - val = 0x0001 - - -class TLS_RSA_WITH_NULL_SHA(_GenericCipherSuite): - val = 0x0002 - - -class TLS_RSA_EXPORT_WITH_RC4_40_MD5(_GenericCipherSuite): - val = 0x0003 - - -class TLS_RSA_WITH_RC4_128_MD5(_GenericCipherSuite): - val = 0x0004 - - -class TLS_RSA_WITH_RC4_128_SHA(_GenericCipherSuite): - val = 0x0005 - - -class TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5(_GenericCipherSuite): - val = 0x0006 - - -class TLS_RSA_WITH_IDEA_CBC_SHA(_GenericCipherSuite): - val = 0x0007 - - -class TLS_RSA_EXPORT_WITH_DES40_CBC_SHA(_GenericCipherSuite): - val = 0x0008 - - -class TLS_RSA_WITH_DES_CBC_SHA(_GenericCipherSuite): - val = 0x0009 - - -class TLS_RSA_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0x000A - - -class TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA(_GenericCipherSuite): - val = 0x000B - - -class TLS_DH_DSS_WITH_DES_CBC_SHA(_GenericCipherSuite): - val = 0x000C - - -class TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0x000D - - -class TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA(_GenericCipherSuite): - val = 0x000E - - -class TLS_DH_RSA_WITH_DES_CBC_SHA(_GenericCipherSuite): - val = 0x000F - - -class TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0x0010 - - -class TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA(_GenericCipherSuite): - val = 0x0011 - - -class TLS_DHE_DSS_WITH_DES_CBC_SHA(_GenericCipherSuite): - val = 0x0012 - - -class TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0x0013 - - -class TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA(_GenericCipherSuite): - val = 0x0014 - - -class TLS_DHE_RSA_WITH_DES_CBC_SHA(_GenericCipherSuite): - val = 0x0015 - - -class TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0x0016 - - -class TLS_DH_anon_EXPORT_WITH_RC4_40_MD5(_GenericCipherSuite): - val = 0x0017 - - -class TLS_DH_anon_WITH_RC4_128_MD5(_GenericCipherSuite): - val = 0x0018 - - -class TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA(_GenericCipherSuite): - val = 0x0019 - - -class TLS_DH_anon_WITH_DES_CBC_SHA(_GenericCipherSuite): - val = 0x001A - - -class TLS_DH_anon_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0x001B - - -class TLS_KRB5_WITH_DES_CBC_SHA(_GenericCipherSuite): - val = 0x001E - - -class TLS_KRB5_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0x001F - - -class TLS_KRB5_WITH_RC4_128_SHA(_GenericCipherSuite): - val = 0x0020 - - -class TLS_KRB5_WITH_IDEA_CBC_SHA(_GenericCipherSuite): - val = 0x0021 - - -class TLS_KRB5_WITH_DES_CBC_MD5(_GenericCipherSuite): - val = 0x0022 - - -class TLS_KRB5_WITH_3DES_EDE_CBC_MD5(_GenericCipherSuite): - val = 0x0023 - - -class TLS_KRB5_WITH_RC4_128_MD5(_GenericCipherSuite): - val = 0x0024 - - -class TLS_KRB5_WITH_IDEA_CBC_MD5(_GenericCipherSuite): - val = 0x0025 - - -class TLS_KRB5_EXPORT_WITH_DES40_CBC_SHA(_GenericCipherSuite): - val = 0x0026 - - -class TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA(_GenericCipherSuite): - val = 0x0027 - - -class TLS_KRB5_EXPORT_WITH_RC4_40_SHA(_GenericCipherSuite): - val = 0x0028 - - -class TLS_KRB5_EXPORT_WITH_DES40_CBC_MD5(_GenericCipherSuite): - val = 0x0029 - - -class TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5(_GenericCipherSuite): - val = 0x002A - - -class TLS_KRB5_EXPORT_WITH_RC4_40_MD5(_GenericCipherSuite): - val = 0x002B - - -class TLS_PSK_WITH_NULL_SHA(_GenericCipherSuite): - val = 0x002C - - -class TLS_DHE_PSK_WITH_NULL_SHA(_GenericCipherSuite): - val = 0x002D - - -class TLS_RSA_PSK_WITH_NULL_SHA(_GenericCipherSuite): - val = 0x002E - - -class TLS_RSA_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0x002F - - -class TLS_DH_DSS_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0x0030 - - -class TLS_DH_RSA_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0x0031 - - -class TLS_DHE_DSS_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0x0032 - - -class TLS_DHE_RSA_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0x0033 - - -class TLS_DH_anon_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0x0034 - - -class TLS_RSA_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0x0035 - - -class TLS_DH_DSS_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0x0036 - - -class TLS_DH_RSA_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0x0037 - - -class TLS_DHE_DSS_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0x0038 - - -class TLS_DHE_RSA_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0x0039 - - -class TLS_DH_anon_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0x003A - - -class TLS_RSA_WITH_NULL_SHA256(_GenericCipherSuite): - val = 0x003B - - -class TLS_RSA_WITH_AES_128_CBC_SHA256(_GenericCipherSuite): - val = 0x003C - - -class TLS_RSA_WITH_AES_256_CBC_SHA256(_GenericCipherSuite): - val = 0x003D - - -class TLS_DH_DSS_WITH_AES_128_CBC_SHA256(_GenericCipherSuite): - val = 0x003E - - -class TLS_DH_RSA_WITH_AES_128_CBC_SHA256(_GenericCipherSuite): - val = 0x003F - - -class TLS_DHE_DSS_WITH_AES_128_CBC_SHA256(_GenericCipherSuite): - val = 0x0040 - - -class TLS_RSA_WITH_CAMELLIA_128_CBC_SHA(_GenericCipherSuite): - val = 0x0041 - - -class TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA(_GenericCipherSuite): - val = 0x0042 - - -class TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA(_GenericCipherSuite): - val = 0x0043 - - -class TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA(_GenericCipherSuite): - val = 0x0044 - - -class TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA(_GenericCipherSuite): - val = 0x0045 - - -class TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA(_GenericCipherSuite): - val = 0x0046 - - -class TLS_DHE_RSA_WITH_AES_128_CBC_SHA256(_GenericCipherSuite): - val = 0x0067 - - -class TLS_DH_DSS_WITH_AES_256_CBC_SHA256(_GenericCipherSuite): - val = 0x0068 - - -class TLS_DH_RSA_WITH_AES_256_CBC_SHA256(_GenericCipherSuite): - val = 0x0069 - - -class TLS_DHE_DSS_WITH_AES_256_CBC_SHA256(_GenericCipherSuite): - val = 0x006A - - -class TLS_DHE_RSA_WITH_AES_256_CBC_SHA256(_GenericCipherSuite): - val = 0x006B - - -class TLS_DH_anon_WITH_AES_128_CBC_SHA256(_GenericCipherSuite): - val = 0x006C - - -class TLS_DH_anon_WITH_AES_256_CBC_SHA256(_GenericCipherSuite): - val = 0x006D - - -class TLS_RSA_WITH_CAMELLIA_256_CBC_SHA(_GenericCipherSuite): - val = 0x0084 - - -class TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA(_GenericCipherSuite): - val = 0x0085 - - -class TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA(_GenericCipherSuite): - val = 0x0086 - - -class TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA(_GenericCipherSuite): - val = 0x0087 - - -class TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA(_GenericCipherSuite): - val = 0x0088 - - -class TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA(_GenericCipherSuite): - val = 0x0089 - - -class TLS_PSK_WITH_RC4_128_SHA(_GenericCipherSuite): - val = 0x008A - - -class TLS_PSK_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0x008B - - -class TLS_PSK_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0x008C - - -class TLS_PSK_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0x008D - - -class TLS_DHE_PSK_WITH_RC4_128_SHA(_GenericCipherSuite): - val = 0x008E - - -class TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0x008F - - -class TLS_DHE_PSK_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0x0090 - - -class TLS_DHE_PSK_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0x0091 - - -class TLS_RSA_PSK_WITH_RC4_128_SHA(_GenericCipherSuite): - val = 0x0092 - - -class TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0x0093 - - -class TLS_RSA_PSK_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0x0094 - - -class TLS_RSA_PSK_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0x0095 - - -class TLS_RSA_WITH_SEED_CBC_SHA(_GenericCipherSuite): - val = 0x0096 - - -class TLS_DH_DSS_WITH_SEED_CBC_SHA(_GenericCipherSuite): - val = 0x0097 - - -class TLS_DH_RSA_WITH_SEED_CBC_SHA(_GenericCipherSuite): - val = 0x0098 - - -class TLS_DHE_DSS_WITH_SEED_CBC_SHA(_GenericCipherSuite): - val = 0x0099 - - -class TLS_DHE_RSA_WITH_SEED_CBC_SHA(_GenericCipherSuite): - val = 0x009A - - -class TLS_DH_anon_WITH_SEED_CBC_SHA(_GenericCipherSuite): - val = 0x009B - - -class TLS_RSA_WITH_AES_128_GCM_SHA256(_GenericCipherSuite): - val = 0x009C - - -class TLS_RSA_WITH_AES_256_GCM_SHA384(_GenericCipherSuite): - val = 0x009D - - -class TLS_DHE_RSA_WITH_AES_128_GCM_SHA256(_GenericCipherSuite): - val = 0x009E - - -class TLS_DHE_RSA_WITH_AES_256_GCM_SHA384(_GenericCipherSuite): - val = 0x009F - - -class TLS_DH_RSA_WITH_AES_128_GCM_SHA256(_GenericCipherSuite): - val = 0x00A0 - - -class TLS_DH_RSA_WITH_AES_256_GCM_SHA384(_GenericCipherSuite): - val = 0x00A1 - - -class TLS_DHE_DSS_WITH_AES_128_GCM_SHA256(_GenericCipherSuite): - val = 0x00A2 - - -class TLS_DHE_DSS_WITH_AES_256_GCM_SHA384(_GenericCipherSuite): - val = 0x00A3 - - -class TLS_DH_DSS_WITH_AES_128_GCM_SHA256(_GenericCipherSuite): - val = 0x00A4 - - -class TLS_DH_DSS_WITH_AES_256_GCM_SHA384(_GenericCipherSuite): - val = 0x00A5 - - -class TLS_DH_anon_WITH_AES_128_GCM_SHA256(_GenericCipherSuite): - val = 0x00A6 - - -class TLS_DH_anon_WITH_AES_256_GCM_SHA384(_GenericCipherSuite): - val = 0x00A7 - - -class TLS_PSK_WITH_AES_128_GCM_SHA256(_GenericCipherSuite): - val = 0x00A8 - - -class TLS_PSK_WITH_AES_256_GCM_SHA384(_GenericCipherSuite): - val = 0x00A9 - - -class TLS_DHE_PSK_WITH_AES_128_GCM_SHA256(_GenericCipherSuite): - val = 0x00AA - - -class TLS_DHE_PSK_WITH_AES_256_GCM_SHA384(_GenericCipherSuite): - val = 0x00AB - - -class TLS_RSA_PSK_WITH_AES_128_GCM_SHA256(_GenericCipherSuite): - val = 0x00AC - - -class TLS_RSA_PSK_WITH_AES_256_GCM_SHA384(_GenericCipherSuite): - val = 0x00AD - - -class TLS_PSK_WITH_AES_128_CBC_SHA256(_GenericCipherSuite): - val = 0x00AE - - -class TLS_PSK_WITH_AES_256_CBC_SHA384(_GenericCipherSuite): - val = 0x00AF - - -class TLS_PSK_WITH_NULL_SHA256(_GenericCipherSuite): - val = 0x00B0 - - -class TLS_PSK_WITH_NULL_SHA384(_GenericCipherSuite): - val = 0x00B1 - - -class TLS_DHE_PSK_WITH_AES_128_CBC_SHA256(_GenericCipherSuite): - val = 0x00B2 - - -class TLS_DHE_PSK_WITH_AES_256_CBC_SHA384(_GenericCipherSuite): - val = 0x00B3 - - -class TLS_DHE_PSK_WITH_NULL_SHA256(_GenericCipherSuite): - val = 0x00B4 - - -class TLS_DHE_PSK_WITH_NULL_SHA384(_GenericCipherSuite): - val = 0x00B5 - - -class TLS_RSA_PSK_WITH_AES_128_CBC_SHA256(_GenericCipherSuite): - val = 0x00B6 - - -class TLS_RSA_PSK_WITH_AES_256_CBC_SHA384(_GenericCipherSuite): - val = 0x00B7 - - -class TLS_RSA_PSK_WITH_NULL_SHA256(_GenericCipherSuite): - val = 0x00B8 - - -class TLS_RSA_PSK_WITH_NULL_SHA384(_GenericCipherSuite): - val = 0x00B9 - - -class TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256(_GenericCipherSuite): - val = 0x00BA - - -class TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256(_GenericCipherSuite): - val = 0x00BB - - -class TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256(_GenericCipherSuite): - val = 0x00BC - - -class TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256(_GenericCipherSuite): - val = 0x00BD - - -class TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256(_GenericCipherSuite): - val = 0x00BE - - -class TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256(_GenericCipherSuite): - val = 0x00BF - - -class TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256(_GenericCipherSuite): - val = 0x00C0 - - -class TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256(_GenericCipherSuite): - val = 0x00C1 - - -class TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256(_GenericCipherSuite): - val = 0x00C2 - - -class TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256(_GenericCipherSuite): - val = 0x00C3 - - -class TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256(_GenericCipherSuite): - val = 0x00C4 - - -class TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256(_GenericCipherSuite): - val = 0x00C5 - -# class TLS_EMPTY_RENEGOTIATION_INFO_CSV(_GenericCipherSuite): -# val = 0x00FF - -# class TLS_FALLBACK_SCSV(_GenericCipherSuite): -# val = 0x5600 - - -class TLS_ECDH_ECDSA_WITH_NULL_SHA(_GenericCipherSuite): - val = 0xC001 - - -class TLS_ECDH_ECDSA_WITH_RC4_128_SHA(_GenericCipherSuite): - val = 0xC002 - - -class TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0xC003 - - -class TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0xC004 - - -class TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0xC005 - - -class TLS_ECDHE_ECDSA_WITH_NULL_SHA(_GenericCipherSuite): - val = 0xC006 - - -class TLS_ECDHE_ECDSA_WITH_RC4_128_SHA(_GenericCipherSuite): - val = 0xC007 - - -class TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0xC008 - - -class TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0xC009 - - -class TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0xC00A - - -class TLS_ECDH_RSA_WITH_NULL_SHA(_GenericCipherSuite): - val = 0xC00B - - -class TLS_ECDH_RSA_WITH_RC4_128_SHA(_GenericCipherSuite): - val = 0xC00C - - -class TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0xC00D - - -class TLS_ECDH_RSA_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0xC00E - - -class TLS_ECDH_RSA_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0xC00F - - -class TLS_ECDHE_RSA_WITH_NULL_SHA(_GenericCipherSuite): - val = 0xC010 - - -class TLS_ECDHE_RSA_WITH_RC4_128_SHA(_GenericCipherSuite): - val = 0xC011 - - -class TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0xC012 - - -class TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0xC013 - - -class TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0xC014 - - -class TLS_ECDH_anon_WITH_NULL_SHA(_GenericCipherSuite): - val = 0xC015 - - -class TLS_ECDH_anon_WITH_RC4_128_SHA(_GenericCipherSuite): - val = 0xC016 - - -class TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0xC017 - - -class TLS_ECDH_anon_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0xC018 - - -class TLS_ECDH_anon_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0xC019 - - -class TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0xC01A - - -class TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0xC01B - - -class TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0xC01C - - -class TLS_SRP_SHA_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0xC01D - - -class TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0xC01E - - -class TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0xC01F - - -class TLS_SRP_SHA_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0xC020 - - -class TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0xC021 - - -class TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0xC022 - - -class TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256(_GenericCipherSuite): - val = 0xC023 - - -class TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384(_GenericCipherSuite): - val = 0xC024 - - -class TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256(_GenericCipherSuite): - val = 0xC025 - - -class TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384(_GenericCipherSuite): - val = 0xC026 - - -class TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256(_GenericCipherSuite): - val = 0xC027 - - -class TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384(_GenericCipherSuite): - val = 0xC028 - - -class TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256(_GenericCipherSuite): - val = 0xC029 - - -class TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384(_GenericCipherSuite): - val = 0xC02A - - -class TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC02B - - -class TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC02C - - -class TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC02D - - -class TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC02E - - -class TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC02F - - -class TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC030 - - -class TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC031 - - -class TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC032 - - -class TLS_ECDHE_PSK_WITH_RC4_128_SHA(_GenericCipherSuite): - val = 0xC033 - - -class TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA(_GenericCipherSuite): - val = 0xC034 - - -class TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA(_GenericCipherSuite): - val = 0xC035 - - -class TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA(_GenericCipherSuite): - val = 0xC036 - - -class TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256(_GenericCipherSuite): - val = 0xC037 - - -class TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384(_GenericCipherSuite): - val = 0xC038 - - -class TLS_ECDHE_PSK_WITH_NULL_SHA(_GenericCipherSuite): - val = 0xC039 - - -class TLS_ECDHE_PSK_WITH_NULL_SHA256(_GenericCipherSuite): - val = 0xC03A - - -class TLS_ECDHE_PSK_WITH_NULL_SHA384(_GenericCipherSuite): - val = 0xC03B - -# suites 0xC03C-C071 use ARIA - - -class TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256(_GenericCipherSuite): - val = 0xC072 - - -class TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384(_GenericCipherSuite): - val = 0xC073 - - -class TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256(_GenericCipherSuite): - val = 0xC074 - - -class TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384(_GenericCipherSuite): - val = 0xC075 - - -class TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256(_GenericCipherSuite): - val = 0xC076 - - -class TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384(_GenericCipherSuite): - val = 0xC077 - - -class TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256(_GenericCipherSuite): - val = 0xC078 - - -class TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384(_GenericCipherSuite): - val = 0xC079 - - -class TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC07A - - -class TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC07B - - -class TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC07C - - -class TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC07D - - -class TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC07E - - -class TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC07F - - -class TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC080 - - -class TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC081 - - -class TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC082 - - -class TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC083 - - -class TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC084 - - -class TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC085 - - -class TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC086 - - -class TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC087 - - -class TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC088 - - -class TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC089 - - -class TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC08A - - -class TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC08B - - -class TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC08C - - -class TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC08D - - -class TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC08E - - -class TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC08F - - -class TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC090 - - -class TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC091 - - -class TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256(_GenericCipherSuite): - val = 0xC092 - - -class TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384(_GenericCipherSuite): - val = 0xC093 - - -class TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256(_GenericCipherSuite): - val = 0xC094 - - -class TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384(_GenericCipherSuite): - val = 0xC095 - - -class TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256(_GenericCipherSuite): - val = 0xC096 - - -class TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384(_GenericCipherSuite): - val = 0xC097 - - -class TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256(_GenericCipherSuite): - val = 0xC098 - - -class TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384(_GenericCipherSuite): - val = 0xC099 - - -class TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256(_GenericCipherSuite): - val = 0xC09A - - -class TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384(_GenericCipherSuite): - val = 0xC09B - - -class TLS_RSA_WITH_AES_128_CCM(_GenericCipherSuite): - val = 0xC09C - - -class TLS_RSA_WITH_AES_256_CCM(_GenericCipherSuite): - val = 0xC09D - - -class TLS_DHE_RSA_WITH_AES_128_CCM(_GenericCipherSuite): - val = 0xC09E - - -class TLS_DHE_RSA_WITH_AES_256_CCM(_GenericCipherSuite): - val = 0xC09F - - -class TLS_RSA_WITH_AES_128_CCM_8(_GenericCipherSuite): - val = 0xC0A0 - - -class TLS_RSA_WITH_AES_256_CCM_8(_GenericCipherSuite): - val = 0xC0A1 - - -class TLS_DHE_RSA_WITH_AES_128_CCM_8(_GenericCipherSuite): - val = 0xC0A2 - - -class TLS_DHE_RSA_WITH_AES_256_CCM_8(_GenericCipherSuite): - val = 0xC0A3 - - -class TLS_PSK_WITH_AES_128_CCM(_GenericCipherSuite): - val = 0xC0A4 - - -class TLS_PSK_WITH_AES_256_CCM(_GenericCipherSuite): - val = 0xC0A5 - - -class TLS_DHE_PSK_WITH_AES_128_CCM(_GenericCipherSuite): - val = 0xC0A6 - - -class TLS_DHE_PSK_WITH_AES_256_CCM(_GenericCipherSuite): - val = 0xC0A7 - - -class TLS_PSK_WITH_AES_128_CCM_8(_GenericCipherSuite): - val = 0xC0A8 - - -class TLS_PSK_WITH_AES_256_CCM_8(_GenericCipherSuite): - val = 0xC0A9 - - -class TLS_DHE_PSK_WITH_AES_128_CCM_8(_GenericCipherSuite): - val = 0xC0AA - - -class TLS_DHE_PSK_WITH_AES_256_CCM_8(_GenericCipherSuite): - val = 0xC0AB - - -class TLS_ECDHE_ECDSA_WITH_AES_128_CCM(_GenericCipherSuite): - val = 0xC0AC - - -class TLS_ECDHE_ECDSA_WITH_AES_256_CCM(_GenericCipherSuite): - val = 0xC0AD - - -class TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8(_GenericCipherSuite): - val = 0xC0AE - - -class TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8(_GenericCipherSuite): - val = 0xC0AF - -# the next 3 suites are from draft-agl-tls-chacha20poly1305-04 - - -class TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD(_GenericCipherSuite): - val = 0xCC13 - - -class TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD(_GenericCipherSuite): - val = 0xCC14 - - -class TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD(_GenericCipherSuite): - val = 0xCC15 - - -class TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256(_GenericCipherSuite): - val = 0xCCA8 - - -class TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256(_GenericCipherSuite): - val = 0xCCA9 - - -class TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256(_GenericCipherSuite): - val = 0xCCAA - - -class TLS_PSK_WITH_CHACHA20_POLY1305_SHA256(_GenericCipherSuite): - val = 0xCCAB - - -class TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256(_GenericCipherSuite): - val = 0xCCAC - - -class TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256(_GenericCipherSuite): - val = 0xCCAD - - -class TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256(_GenericCipherSuite): - val = 0xCCAE - - -class TLS_AES_128_GCM_SHA256(_GenericCipherSuite): - val = 0x1301 - - -class TLS_AES_256_GCM_SHA384(_GenericCipherSuite): - val = 0x1302 - - -class TLS_CHACHA20_POLY1305_SHA256(_GenericCipherSuite): - val = 0x1303 - - -class TLS_AES_128_CCM_SHA256(_GenericCipherSuite): - val = 0x1304 - - -class TLS_AES_128_CCM_8_SHA256(_GenericCipherSuite): - val = 0x1305 - - -class SSL_CK_RC4_128_WITH_MD5(_GenericCipherSuite): - val = 0x010080 - - -class SSL_CK_RC4_128_EXPORT40_WITH_MD5(_GenericCipherSuite): - val = 0x020080 - - -class SSL_CK_RC2_128_CBC_WITH_MD5(_GenericCipherSuite): - val = 0x030080 - - -class SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5(_GenericCipherSuite): - val = 0x040080 - - -class SSL_CK_IDEA_128_CBC_WITH_MD5(_GenericCipherSuite): - val = 0x050080 - - -class SSL_CK_DES_64_CBC_WITH_MD5(_GenericCipherSuite): - val = 0x060040 - - -class SSL_CK_DES_192_EDE3_CBC_WITH_MD5(_GenericCipherSuite): - val = 0x0700C0 - - -_tls_cipher_suites[0x00ff] = "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" -_tls_cipher_suites[0x5600] = "TLS_FALLBACK_SCSV" - - -def get_usable_ciphersuites(l, kx): - """ - From a list of proposed ciphersuites, this function returns a list of - usable cipher suites, i.e. for which key exchange, cipher and hash - algorithms are known to be implemented and usable in current version of the - TLS extension. The order of the cipher suites in the list returned by the - function matches the one of the proposal. - """ - res = [] - for c in l: - if c in _tls_cipher_suites_cls: - ciph = _tls_cipher_suites_cls[c] - if ciph.usable: - # XXX select among RSA and ECDSA cipher suites - # according to the key(s) the server was given - if ciph.kx_alg.anonymous or kx in ciph.kx_alg.name: - res.append(c) - return res diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/extensions.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/extensions.py deleted file mode 100644 index b488d06f48..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/extensions.py +++ /dev/null @@ -1,772 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -TLS handshake extensions. -""" - -from __future__ import print_function - -import struct - -from scapy.fields import ByteEnumField, ByteField, EnumField, FieldLenField, \ - FieldListField, IntField, PacketField, PacketListField, ShortEnumField, \ - ShortField, StrFixedLenField, StrLenField, XStrLenField -from scapy.packet import Packet, Raw, Padding -from scapy.layers.x509 import X509_Extensions -from scapy.layers.tls.basefields import _tls_version -from scapy.layers.tls.keyexchange import (SigAndHashAlgsLenField, - SigAndHashAlgsField, _tls_hash_sig) -from scapy.layers.tls.session import _GenericTLSSessionInheritance -from scapy.layers.tls.crypto.groups import _tls_named_groups -from scapy.themes import AnsiColorTheme -from scapy.compat import raw -from scapy.config import conf - - -_tls_ext = {0: "server_name", # RFC 4366 - 1: "max_fragment_length", # RFC 4366 - 2: "client_certificate_url", # RFC 4366 - 3: "trusted_ca_keys", # RFC 4366 - 4: "truncated_hmac", # RFC 4366 - 5: "status_request", # RFC 4366 - 6: "user_mapping", # RFC 4681 - 7: "client_authz", # RFC 5878 - 8: "server_authz", # RFC 5878 - 9: "cert_type", # RFC 6091 - # 10: "elliptic_curves", # RFC 4492 - 10: "supported_groups", - 11: "ec_point_formats", # RFC 4492 - 13: "signature_algorithms", # RFC 5246 - 0x0f: "heartbeat", # RFC 6520 - 0x10: "alpn", # RFC 7301 - 0x12: "signed_certificate_timestamp", # RFC 6962 - 0x13: "client_certificate_type", # RFC 7250 - 0x14: "server_certificate_type", # RFC 7250 - 0x15: "padding", # RFC 7685 - 0x16: "encrypt_then_mac", # RFC 7366 - 0x17: "extended_master_secret", # RFC 7627 - 0x1c: "record_size_limit", # RFC 8449 - 0x23: "session_ticket", # RFC 5077 - 0x29: "pre_shared_key", - 0x2a: "early_data_indication", - 0x2b: "supported_versions", - 0x2c: "cookie", - 0x2d: "psk_key_exchange_modes", - 0x2f: "certificate_authorities", - 0x30: "oid_filters", - 0x31: "post_handshake_auth", - 0x32: "signature_algorithms_cert", - 0x33: "key_share", - 0x3374: "next_protocol_negotiation", - # RFC-draft-agl-tls-nextprotoneg-03 - 0xff01: "renegotiation_info" # RFC 5746 - } - - -class TLS_Ext_Unknown(_GenericTLSSessionInheritance): - """ - We put this here rather than in extensions.py in order to avoid - circular imports... - """ - name = "TLS Extension - Scapy Unknown" - fields_desc = [ShortEnumField("type", None, _tls_ext), - FieldLenField("len", None, fmt="!H", length_of="val"), - StrLenField("val", "", - length_from=lambda pkt: pkt.len)] - - def post_build(self, p, pay): - if self.len is None: - tmp_len = len(p) - 4 - p = p[:2] + struct.pack("!H", tmp_len) + p[4:] - return p + pay - - -############################################################################### -# ClientHello/ServerHello extensions # -############################################################################### - -# We provide these extensions mostly for packet manipulation purposes. -# For now, most of them are not considered by our automaton. - -class TLS_Ext_PrettyPacketList(TLS_Ext_Unknown): - """ - Dummy extension used for server_name/ALPN/NPN for a lighter representation: - the final field is showed as a 1-line list rather than as lots of packets. - XXX Define a new condition for packet lists in Packet._show_or_dump? - """ - - def _show_or_dump(self, dump=False, indent=3, - lvl="", label_lvl="", first_call=True): - """ Reproduced from packet.py """ - ct = AnsiColorTheme() if dump else conf.color_theme - s = "%s%s %s %s \n" % (label_lvl, ct.punct("###["), - ct.layer_name(self.name), ct.punct("]###")) - for f in self.fields_desc[:-1]: - ncol = ct.field_name - vcol = ct.field_value - fvalue = self.getfieldval(f.name) - begn = "%s %-10s%s " % (label_lvl + lvl, ncol(f.name), - ct.punct("="),) - reprval = f.i2repr(self, fvalue) - if isinstance(reprval, str): - reprval = reprval.replace("\n", "\n" + " " * (len(label_lvl) + - len(lvl) + - len(f.name) + - 4)) - s += "%s%s\n" % (begn, vcol(reprval)) - f = self.fields_desc[-1] - ncol = ct.field_name - vcol = ct.field_value - fvalue = self.getfieldval(f.name) - begn = "%s %-10s%s " % (label_lvl + lvl, ncol(f.name), ct.punct("="),) - reprval = f.i2repr(self, fvalue) - if isinstance(reprval, str): - reprval = reprval.replace("\n", "\n" + " " * (len(label_lvl) + - len(lvl) + - len(f.name) + - 4)) - s += "%s%s\n" % (begn, vcol(reprval)) - if self.payload: - s += self.payload._show_or_dump(dump=dump, indent=indent, - lvl=lvl + (" " * indent * self.show_indent), # noqa: E501 - label_lvl=label_lvl, first_call=False) # noqa: E501 - - if first_call and not dump: - print(s) - else: - return s - - -_tls_server_name_types = {0: "host_name"} - - -class ServerName(Packet): - name = "HostName" - fields_desc = [ByteEnumField("nametype", 0, _tls_server_name_types), - FieldLenField("namelen", None, length_of="servername"), - StrLenField("servername", "", - length_from=lambda pkt: pkt.namelen)] - - def guess_payload_class(self, p): - return Padding - - -class ServerListField(PacketListField): - def i2repr(self, pkt, x): - res = [p.servername for p in x] - return "[%s]" % b", ".join(res) - - -class ServerLenField(FieldLenField): - """ - There is no length when there are no servernames (as in a ServerHello). - """ - - def addfield(self, pkt, s, val): - if not val: - if not pkt.servernames: - return s - return super(ServerLenField, self).addfield(pkt, s, val) - - -class TLS_Ext_ServerName(TLS_Ext_PrettyPacketList): # RFC 4366 - name = "TLS Extension - Server Name" - fields_desc = [ShortEnumField("type", 0, _tls_ext), - FieldLenField("len", None, length_of="servernames", - adjust=lambda pkt, x: x + 2), - ServerLenField("servernameslen", None, - length_of="servernames"), - ServerListField("servernames", [], ServerName, - length_from=lambda pkt: pkt.servernameslen)] - - -class TLS_Ext_MaxFragLen(TLS_Ext_Unknown): # RFC 4366 - name = "TLS Extension - Max Fragment Length" - fields_desc = [ShortEnumField("type", 1, _tls_ext), - ShortField("len", None), - ByteEnumField("maxfraglen", 4, {1: "2^9", - 2: "2^10", - 3: "2^11", - 4: "2^12"})] - - -class TLS_Ext_ClientCertURL(TLS_Ext_Unknown): # RFC 4366 - name = "TLS Extension - Client Certificate URL" - fields_desc = [ShortEnumField("type", 2, _tls_ext), - ShortField("len", None)] - - -_tls_trusted_authority_types = {0: "pre_agreed", - 1: "key_sha1_hash", - 2: "x509_name", - 3: "cert_sha1_hash"} - - -class TAPreAgreed(Packet): - name = "Trusted authority - pre_agreed" - fields_desc = [ByteEnumField("idtype", 0, _tls_trusted_authority_types)] - - def guess_payload_class(self, p): - return Padding - - -class TAKeySHA1Hash(Packet): - name = "Trusted authority - key_sha1_hash" - fields_desc = [ByteEnumField("idtype", 1, _tls_trusted_authority_types), - StrFixedLenField("id", None, 20)] - - def guess_payload_class(self, p): - return Padding - - -class TAX509Name(Packet): - """ - XXX Section 3.4 of RFC 4366. Implement a more specific DNField - rather than current StrLenField. - """ - name = "Trusted authority - x509_name" - fields_desc = [ByteEnumField("idtype", 2, _tls_trusted_authority_types), - FieldLenField("dnlen", None, length_of="dn"), - StrLenField("dn", "", length_from=lambda pkt: pkt.dnlen)] - - def guess_payload_class(self, p): - return Padding - - -class TACertSHA1Hash(Packet): - name = "Trusted authority - cert_sha1_hash" - fields_desc = [ByteEnumField("idtype", 3, _tls_trusted_authority_types), - StrFixedLenField("id", None, 20)] - - def guess_payload_class(self, p): - return Padding - - -_tls_trusted_authority_cls = {0: TAPreAgreed, - 1: TAKeySHA1Hash, - 2: TAX509Name, - 3: TACertSHA1Hash} - - -class _TAListField(PacketListField): - """ - Specific version that selects the right Trusted Authority (previous TA*) - class to be used for dissection based on idtype. - """ - - def m2i(self, pkt, m): - idtype = ord(m[0]) - cls = self.cls - if idtype in _tls_trusted_authority_cls: - cls = _tls_trusted_authority_cls[idtype] - return cls(m) - - -class TLS_Ext_TrustedCAInd(TLS_Ext_Unknown): # RFC 4366 - name = "TLS Extension - Trusted CA Indication" - fields_desc = [ShortEnumField("type", 3, _tls_ext), - ShortField("len", None), - FieldLenField("talen", None, length_of="ta"), - _TAListField("ta", [], Raw, - length_from=lambda pkt: pkt.talen)] - - -class TLS_Ext_TruncatedHMAC(TLS_Ext_Unknown): # RFC 4366 - name = "TLS Extension - Truncated HMAC" - fields_desc = [ShortEnumField("type", 4, _tls_ext), - ShortField("len", None)] - - -class ResponderID(Packet): - name = "Responder ID structure" - fields_desc = [FieldLenField("respidlen", None, length_of="respid"), - StrLenField("respid", "", - length_from=lambda pkt: pkt.respidlen)] - - def guess_payload_class(self, p): - return Padding - - -class OCSPStatusRequest(Packet): - """ - This is the structure defined in RFC 6066, not in RFC 6960! - """ - name = "OCSPStatusRequest structure" - fields_desc = [FieldLenField("respidlen", None, length_of="respid"), - PacketListField("respid", [], ResponderID, - length_from=lambda pkt: pkt.respidlen), - FieldLenField("reqextlen", None, length_of="reqext"), - PacketField("reqext", "", X509_Extensions)] - - def guess_payload_class(self, p): - return Padding - - -_cert_status_type = {1: "ocsp"} -_cert_status_req_cls = {1: OCSPStatusRequest} - - -class _StatusReqField(PacketListField): - def m2i(self, pkt, m): - idtype = pkt.stype - cls = self.cls - if idtype in _cert_status_req_cls: - cls = _cert_status_req_cls[idtype] - return cls(m) - - -class TLS_Ext_CSR(TLS_Ext_Unknown): # RFC 4366 - name = "TLS Extension - Certificate Status Request" - fields_desc = [ShortEnumField("type", 5, _tls_ext), - ShortField("len", None), - ByteEnumField("stype", None, _cert_status_type), - _StatusReqField("req", [], Raw, - length_from=lambda pkt: pkt.len - 1)] - - -class TLS_Ext_UserMapping(TLS_Ext_Unknown): # RFC 4681 - name = "TLS Extension - User Mapping" - fields_desc = [ShortEnumField("type", 6, _tls_ext), - ShortField("len", None), - FieldLenField("umlen", None, fmt="B", length_of="um"), - FieldListField("um", [], - ByteField("umtype", 0), - length_from=lambda pkt: pkt.umlen)] - - -class TLS_Ext_ClientAuthz(TLS_Ext_Unknown): # RFC 5878 - """ XXX Unsupported """ - name = "TLS Extension - Client Authz" - fields_desc = [ShortEnumField("type", 7, _tls_ext), - ShortField("len", None), - ] - - -class TLS_Ext_ServerAuthz(TLS_Ext_Unknown): # RFC 5878 - """ XXX Unsupported """ - name = "TLS Extension - Server Authz" - fields_desc = [ShortEnumField("type", 8, _tls_ext), - ShortField("len", None), - ] - - -_tls_cert_types = {0: "X.509", 1: "OpenPGP"} - - -class TLS_Ext_ClientCertType(TLS_Ext_Unknown): # RFC 5081 - name = "TLS Extension - Certificate Type (client version)" - fields_desc = [ShortEnumField("type", 9, _tls_ext), - ShortField("len", None), - FieldLenField("ctypeslen", None, length_of="ctypes"), - FieldListField("ctypes", [0, 1], - ByteEnumField("certtypes", None, - _tls_cert_types), - length_from=lambda pkt: pkt.ctypeslen)] - - -class TLS_Ext_ServerCertType(TLS_Ext_Unknown): # RFC 5081 - name = "TLS Extension - Certificate Type (server version)" - fields_desc = [ShortEnumField("type", 9, _tls_ext), - ShortField("len", None), - ByteEnumField("ctype", None, _tls_cert_types)] - - -def _TLS_Ext_CertTypeDispatcher(m, *args, **kargs): - """ - We need to select the correct one on dissection. We use the length for - that, as 1 for client version would emply an empty list. - """ - tmp_len = struct.unpack("!H", m[2:4])[0] - if tmp_len == 1: - cls = TLS_Ext_ServerCertType - else: - cls = TLS_Ext_ClientCertType - return cls(m, *args, **kargs) - - -class TLS_Ext_SupportedGroups(TLS_Ext_Unknown): - """ - This extension was known as 'Supported Elliptic Curves' before TLS 1.3 - merged both group selection mechanisms for ECDH and FFDH. - """ - name = "TLS Extension - Supported Groups" - fields_desc = [ShortEnumField("type", 10, _tls_ext), - ShortField("len", None), - FieldLenField("groupslen", None, length_of="groups"), - FieldListField("groups", [], - ShortEnumField("ng", None, - _tls_named_groups), - length_from=lambda pkt: pkt.groupslen)] - - -class TLS_Ext_SupportedEllipticCurves(TLS_Ext_SupportedGroups): # RFC 4492 - pass - - -_tls_ecpoint_format = {0: "uncompressed", - 1: "ansiX962_compressed_prime", - 2: "ansiX962_compressed_char2"} - - -class TLS_Ext_SupportedPointFormat(TLS_Ext_Unknown): # RFC 4492 - name = "TLS Extension - Supported Point Format" - fields_desc = [ShortEnumField("type", 11, _tls_ext), - ShortField("len", None), - FieldLenField("ecpllen", None, fmt="B", length_of="ecpl"), - FieldListField("ecpl", [0], - ByteEnumField("nc", None, - _tls_ecpoint_format), - length_from=lambda pkt: pkt.ecpllen)] - - -class TLS_Ext_SignatureAlgorithms(TLS_Ext_Unknown): # RFC 5246 - name = "TLS Extension - Signature Algorithms" - fields_desc = [ShortEnumField("type", 13, _tls_ext), - ShortField("len", None), - SigAndHashAlgsLenField("sig_algs_len", None, - length_of="sig_algs"), - SigAndHashAlgsField("sig_algs", [], - EnumField("hash_sig", None, - _tls_hash_sig), - length_from=lambda pkt: pkt.sig_algs_len)] # noqa: E501 - - -class TLS_Ext_Heartbeat(TLS_Ext_Unknown): # RFC 6520 - name = "TLS Extension - Heartbeat" - fields_desc = [ShortEnumField("type", 0x0f, _tls_ext), - ShortField("len", None), - ByteEnumField("heartbeat_mode", 2, - {1: "peer_allowed_to_send", - 2: "peer_not_allowed_to_send"})] - - -class ProtocolName(Packet): - name = "Protocol Name" - fields_desc = [FieldLenField("len", None, fmt='B', length_of="protocol"), - StrLenField("protocol", "", - length_from=lambda pkt: pkt.len)] - - def guess_payload_class(self, p): - return Padding - - -class ProtocolListField(PacketListField): - def i2repr(self, pkt, x): - res = [p.protocol for p in x] - return "[%s]" % b", ".join(res) - - -class TLS_Ext_ALPN(TLS_Ext_PrettyPacketList): # RFC 7301 - name = "TLS Extension - Application Layer Protocol Negotiation" - fields_desc = [ShortEnumField("type", 0x10, _tls_ext), - ShortField("len", None), - FieldLenField("protocolslen", None, length_of="protocols"), - ProtocolListField("protocols", [], ProtocolName, - length_from=lambda pkt:pkt.protocolslen)] - - -class TLS_Ext_Padding(TLS_Ext_Unknown): # RFC 7685 - name = "TLS Extension - Padding" - fields_desc = [ShortEnumField("type", 0x15, _tls_ext), - FieldLenField("len", None, length_of="padding"), - StrLenField("padding", "", - length_from=lambda pkt: pkt.len)] - - -class TLS_Ext_EncryptThenMAC(TLS_Ext_Unknown): # RFC 7366 - name = "TLS Extension - Encrypt-then-MAC" - fields_desc = [ShortEnumField("type", 0x16, _tls_ext), - ShortField("len", None)] - - -class TLS_Ext_ExtendedMasterSecret(TLS_Ext_Unknown): # RFC 7627 - name = "TLS Extension - Extended Master Secret" - fields_desc = [ShortEnumField("type", 0x17, _tls_ext), - ShortField("len", None)] - - -class TLS_Ext_SessionTicket(TLS_Ext_Unknown): # RFC 5077 - """ - RFC 5077 updates RFC 4507 according to most implementations, which do not - use another (useless) 'ticketlen' field after the global 'len' field. - """ - name = "TLS Extension - Session Ticket" - fields_desc = [ShortEnumField("type", 0x23, _tls_ext), - FieldLenField("len", None, length_of="ticket"), - StrLenField("ticket", "", - length_from=lambda pkt: pkt.len)] - - -class TLS_Ext_KeyShare(TLS_Ext_Unknown): - name = "TLS Extension - Key Share (dummy class)" - fields_desc = [ShortEnumField("type", 0x28, _tls_ext), - ShortField("len", None)] - - -class TLS_Ext_PreSharedKey(TLS_Ext_Unknown): - name = "TLS Extension - Pre Shared Key (dummy class)" - fields_desc = [ShortEnumField("type", 0x29, _tls_ext), - ShortField("len", None)] - - -class TLS_Ext_EarlyDataIndication(TLS_Ext_Unknown): - name = "TLS Extension - Early Data" - fields_desc = [ShortEnumField("type", 0x2a, _tls_ext), - ShortField("len", None)] - - -class TLS_Ext_EarlyDataIndicationTicket(TLS_Ext_Unknown): - name = "TLS Extension - Ticket Early Data Info" - fields_desc = [ShortEnumField("type", 0x2a, _tls_ext), - ShortField("len", None), - IntField("max_early_data_size", 0)] - - -_tls_ext_early_data_cls = {1: TLS_Ext_EarlyDataIndication, - 4: TLS_Ext_EarlyDataIndicationTicket, - 8: TLS_Ext_EarlyDataIndication} - - -class TLS_Ext_SupportedVersions(TLS_Ext_Unknown): - name = "TLS Extension - Supported Versions (dummy class)" - fields_desc = [ShortEnumField("type", 0x2b, _tls_ext), - ShortField("len", None)] - - -class TLS_Ext_SupportedVersion_CH(TLS_Ext_Unknown): - name = "TLS Extension - Supported Versions (for ClientHello)" - fields_desc = [ShortEnumField("type", 0x2b, _tls_ext), - ShortField("len", None), - FieldLenField("versionslen", None, fmt='B', - length_of="versions"), - FieldListField("versions", [], - ShortEnumField("version", None, - _tls_version), - length_from=lambda pkt: pkt.versionslen)] - - -class TLS_Ext_SupportedVersion_SH(TLS_Ext_Unknown): - name = "TLS Extension - Supported Versions (for ServerHello)" - fields_desc = [ShortEnumField("type", 0x2b, _tls_ext), - ShortField("len", None), - ShortEnumField("version", None, _tls_version)] - - -_tls_ext_supported_version_cls = {1: TLS_Ext_SupportedVersion_CH, - 2: TLS_Ext_SupportedVersion_SH} - - -class TLS_Ext_Cookie(TLS_Ext_Unknown): - name = "TLS Extension - Cookie" - fields_desc = [ShortEnumField("type", 0x2c, _tls_ext), - ShortField("len", None), - FieldLenField("cookielen", None, length_of="cookie"), - XStrLenField("cookie", "", - length_from=lambda pkt: pkt.cookielen)] - - -_tls_psk_kx_modes = {0: "psk_ke", 1: "psk_dhe_ke"} - - -class TLS_Ext_PSKKeyExchangeModes(TLS_Ext_Unknown): - name = "TLS Extension - PSK Key Exchange Modes" - fields_desc = [ShortEnumField("type", 0x2d, _tls_ext), - ShortField("len", None), - FieldLenField("kxmodeslen", None, fmt='B', - length_of="kxmodes"), - FieldListField("kxmodes", [], - ByteEnumField("kxmode", None, - _tls_psk_kx_modes), - length_from=lambda pkt: pkt.kxmodeslen)] - - -class TLS_Ext_TicketEarlyDataInfo(TLS_Ext_Unknown): - name = "TLS Extension - Ticket Early Data Info" - fields_desc = [ShortEnumField("type", 0x2e, _tls_ext), - ShortField("len", None), - IntField("max_early_data_size", 0)] - - -class TLS_Ext_NPN(TLS_Ext_PrettyPacketList): - """ - Defined in RFC-draft-agl-tls-nextprotoneg-03. Deprecated in favour of ALPN. - """ - name = "TLS Extension - Next Protocol Negotiation" - fields_desc = [ShortEnumField("type", 0x3374, _tls_ext), - FieldLenField("len", None, length_of="protocols"), - ProtocolListField("protocols", [], ProtocolName, - length_from=lambda pkt:pkt.len)] - - -class TLS_Ext_PostHandshakeAuth(TLS_Ext_Unknown): # RFC 8446 - name = "TLS Extension - Post Handshake Auth" - fields_desc = [ShortEnumField("type", 0x31, _tls_ext), - ShortField("len", None)] - - -class TLS_Ext_SignatureAlgorithmsCert(TLS_Ext_Unknown): # RFC 8446 - name = "TLS Extension - Signature Algorithms Cert" - fields_desc = [ShortEnumField("type", 0x31, _tls_ext), - ShortField("len", None), - SigAndHashAlgsLenField("sig_algs_len", None, - length_of="sig_algs"), - SigAndHashAlgsField("sig_algs", [], - EnumField("hash_sig", None, - _tls_hash_sig), - length_from=lambda pkt: pkt.sig_algs_len)] # noqa: E501 - - -class TLS_Ext_RenegotiationInfo(TLS_Ext_Unknown): # RFC 5746 - name = "TLS Extension - Renegotiation Indication" - fields_desc = [ShortEnumField("type", 0xff01, _tls_ext), - ShortField("len", None), - FieldLenField("reneg_conn_len", None, fmt='B', - length_of="renegotiated_connection"), - StrLenField("renegotiated_connection", "", - length_from=lambda pkt: pkt.reneg_conn_len)] - - -class TLS_Ext_RecordSizeLimit(TLS_Ext_Unknown): # RFC 8449 - name = "TLS Extension - Record Size Limit" - fields_desc = [ShortEnumField("type", 0x1c, _tls_ext), - ShortField("len", None), - ShortField("record_size_limit", None)] - - -_tls_ext_cls = {0: TLS_Ext_ServerName, - 1: TLS_Ext_MaxFragLen, - 2: TLS_Ext_ClientCertURL, - 3: TLS_Ext_TrustedCAInd, - 4: TLS_Ext_TruncatedHMAC, - 5: TLS_Ext_CSR, - 6: TLS_Ext_UserMapping, - 7: TLS_Ext_ClientAuthz, - 8: TLS_Ext_ServerAuthz, - 9: _TLS_Ext_CertTypeDispatcher, - # 10: TLS_Ext_SupportedEllipticCurves, - 10: TLS_Ext_SupportedGroups, - 11: TLS_Ext_SupportedPointFormat, - 13: TLS_Ext_SignatureAlgorithms, - 0x0f: TLS_Ext_Heartbeat, - 0x10: TLS_Ext_ALPN, - 0x15: TLS_Ext_Padding, - 0x16: TLS_Ext_EncryptThenMAC, - 0x17: TLS_Ext_ExtendedMasterSecret, - 0x1c: TLS_Ext_RecordSizeLimit, - 0x23: TLS_Ext_SessionTicket, - # 0x28: TLS_Ext_KeyShare, - 0x29: TLS_Ext_PreSharedKey, - 0x2a: TLS_Ext_EarlyDataIndication, - 0x2b: TLS_Ext_SupportedVersions, - 0x2c: TLS_Ext_Cookie, - 0x2d: TLS_Ext_PSKKeyExchangeModes, - # 0x2e: TLS_Ext_TicketEarlyDataInfo, - 0x31: TLS_Ext_PostHandshakeAuth, - 0x32: TLS_Ext_SignatureAlgorithmsCert, - 0x33: TLS_Ext_KeyShare, - # 0x2f: TLS_Ext_CertificateAuthorities, #XXX - # 0x30: TLS_Ext_OIDFilters, #XXX - 0x3374: TLS_Ext_NPN, - 0xff01: TLS_Ext_RenegotiationInfo - } - - -class _ExtensionsLenField(FieldLenField): - def getfield(self, pkt, s): - """ - We try to compute a length, usually from a msglen parsed earlier. - If this length is 0, we consider 'selection_present' (from RFC 5246) - to be False. This means that there should not be any length field. - However, with TLS 1.3, zero lengths are always explicit. - """ - ext = pkt.get_field(self.length_of) - tmp_len = ext.length_from(pkt) - if tmp_len is None or tmp_len <= 0: - v = pkt.tls_session.tls_version - if v is None or v < 0x0304: - return s, None - return super(_ExtensionsLenField, self).getfield(pkt, s) - - def addfield(self, pkt, s, i): - """ - There is a hack with the _ExtensionsField.i2len. It works only because - we expect _ExtensionsField.i2m to return a string of the same size (if - not of the same value) upon successive calls (e.g. through i2len here, - then i2m when directly building the _ExtensionsField). - - XXX A proper way to do this would be to keep the extensions built from - the i2len call here, instead of rebuilding them later on. - """ - if i is None: - if self.length_of is not None: - fld, fval = pkt.getfield_and_val(self.length_of) - - tmp = pkt.tls_session.frozen - pkt.tls_session.frozen = True - f = fld.i2len(pkt, fval) - pkt.tls_session.frozen = tmp - - i = self.adjust(pkt, f) - if i == 0: # for correct build if no ext and not explicitly 0 - return s - return s + struct.pack(self.fmt, i) - - -class _ExtensionsField(StrLenField): - islist = 1 - holds_packets = 1 - - def i2len(self, pkt, i): - if i is None: - return 0 - return len(self.i2m(pkt, i)) - - def getfield(self, pkt, s): - tmp_len = self.length_from(pkt) - if tmp_len is None: - return s, [] - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - - def i2m(self, pkt, i): - if i is None: - return b"" - if isinstance(pkt, _GenericTLSSessionInheritance): - if not pkt.tls_session.frozen: - s = b"" - for ext in i: - if isinstance(ext, _GenericTLSSessionInheritance): - ext.tls_session = pkt.tls_session - s += ext.raw_stateful() - else: - s += raw(ext) - return s - return b"".join(map(raw, i)) - - def m2i(self, pkt, m): - res = [] - while len(m) >= 4: - t = struct.unpack("!H", m[:2])[0] - tmp_len = struct.unpack("!H", m[2:4])[0] - cls = _tls_ext_cls.get(t, TLS_Ext_Unknown) - if cls is TLS_Ext_KeyShare: - # TLS_Ext_KeyShare can be : - # - TLS_Ext_KeyShare_CH if the message is a ClientHello - # - TLS_Ext_KeyShare_SH if the message is a ServerHello - # and all parameters are accepted by the serveur - # - TLS_Ext_KeyShare_HRR if message is a ServerHello and - # the client has not provided a sufficient "key_share" - # extension - from scapy.layers.tls.keyexchange_tls13 import _tls_ext_keyshare_cls # noqa: E501 - cls = _tls_ext_keyshare_cls.get(pkt.msgtype, TLS_Ext_Unknown) - elif cls is TLS_Ext_PreSharedKey: - from scapy.layers.tls.keyexchange_tls13 import _tls_ext_presharedkey_cls # noqa: E501 - cls = _tls_ext_presharedkey_cls.get(pkt.msgtype, TLS_Ext_Unknown) # noqa: E501 - elif cls is TLS_Ext_SupportedVersions: - cls = _tls_ext_supported_version_cls.get(pkt.msgtype, TLS_Ext_Unknown) # noqa: E501 - elif cls is TLS_Ext_EarlyDataIndication: - cls = _tls_ext_early_data_cls.get(pkt.msgtype, TLS_Ext_Unknown) - res.append(cls(m[:tmp_len + 4], tls_session=pkt.tls_session)) - m = m[tmp_len + 4:] - return res diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/handshake.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/handshake.py deleted file mode 100644 index 19fa57139f..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/handshake.py +++ /dev/null @@ -1,1467 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -TLS handshake fields & logic. - -This module covers the handshake TLS subprotocol, except for the key exchange -mechanisms which are addressed with keyexchange.py. -""" - -from __future__ import absolute_import -import math -import struct - -from scapy.error import log_runtime, warning -from scapy.fields import ByteEnumField, ByteField, EnumField, Field, \ - FieldLenField, IntField, PacketField, PacketListField, ShortField, \ - StrFixedLenField, StrLenField, ThreeBytesField, UTCTimeField - -from scapy.compat import hex_bytes, orb, raw -from scapy.config import conf -from scapy.modules import six -from scapy.packet import Packet, Raw, Padding -from scapy.utils import randstring, repr_hex -from scapy.layers.x509 import OCSP_Response -from scapy.layers.tls.cert import Cert -from scapy.layers.tls.basefields import (_tls_version, _TLSVersionField, - _TLSClientVersionField) -from scapy.layers.tls.extensions import (_ExtensionsLenField, _ExtensionsField, - _cert_status_type, TLS_Ext_SupportedVersion_CH, # noqa: E501 - TLS_Ext_SignatureAlgorithms, - TLS_Ext_SupportedVersion_SH, - TLS_Ext_EarlyDataIndication) -from scapy.layers.tls.keyexchange import (_TLSSignature, _TLSServerParamsField, - _TLSSignatureField, ServerRSAParams, - SigAndHashAlgsField, _tls_hash_sig, - SigAndHashAlgsLenField) -from scapy.layers.tls.session import (_GenericTLSSessionInheritance, - readConnState, writeConnState) -from scapy.layers.tls.crypto.compression import (_tls_compression_algs, - _tls_compression_algs_cls, - Comp_NULL, _GenericComp, - _GenericCompMetaclass) -from scapy.layers.tls.crypto.suites import (_tls_cipher_suites, - _tls_cipher_suites_cls, - _GenericCipherSuite, - _GenericCipherSuiteMetaclass) - - -############################################################################### -# Generic TLS Handshake message # -############################################################################### - -_tls_handshake_type = {0: "hello_request", 1: "client_hello", - 2: "server_hello", 3: "hello_verify_request", - 4: "session_ticket", 6: "hello_retry_request", - 8: "encrypted_extensions", 11: "certificate", - 12: "server_key_exchange", 13: "certificate_request", - 14: "server_hello_done", 15: "certificate_verify", - 16: "client_key_exchange", 20: "finished", - 21: "certificate_url", 22: "certificate_status", - 23: "supplemental_data", 24: "key_update"} - - -class _TLSHandshake(_GenericTLSSessionInheritance): - """ - Inherited by other Handshake classes to get post_build(). - Also used as a fallback for unknown TLS Handshake packets. - """ - name = "TLS Handshake Generic message" - fields_desc = [ByteEnumField("msgtype", None, _tls_handshake_type), - ThreeBytesField("msglen", None), - StrLenField("msg", "", - length_from=lambda pkt: pkt.msglen)] - - def post_build(self, p, pay): - tmp_len = len(p) - if self.msglen is None: - l2 = tmp_len - 4 - p = struct.pack("!I", (orb(p[0]) << 24) | l2) + p[4:] - return p + pay - - def guess_payload_class(self, p): - return conf.padding_layer - - def tls_session_update(self, msg_str): - """ - Covers both post_build- and post_dissection- context updates. - """ - self.tls_session.handshake_messages.append(msg_str) - self.tls_session.handshake_messages_parsed.append(self) - - -############################################################################### -# HelloRequest # -############################################################################### - -class TLSHelloRequest(_TLSHandshake): - name = "TLS Handshake - Hello Request" - fields_desc = [ByteEnumField("msgtype", 0, _tls_handshake_type), - ThreeBytesField("msglen", None)] - - def tls_session_update(self, msg_str): - """ - Message should not be added to the list of handshake messages - that will be hashed in the finished and certificate verify messages. - """ - return - - -############################################################################### -# ClientHello fields # -############################################################################### - -class _GMTUnixTimeField(UTCTimeField): - """ - "The current time and date in standard UNIX 32-bit format (seconds since - the midnight starting Jan 1, 1970, GMT, ignoring leap seconds)." - """ - - def i2h(self, pkt, x): - if x is not None: - return x - return 0 - - -class _TLSRandomBytesField(StrFixedLenField): - def i2repr(self, pkt, x): - if x is None: - return repr(x) - return repr_hex(self.i2h(pkt, x)) - - -class _SessionIDField(StrLenField): - """ - opaque SessionID<0..32>; section 7.4.1.2 of RFC 4346 - """ - pass - - -class _CipherSuitesField(StrLenField): - __slots__ = ["itemfmt", "itemsize", "i2s", "s2i"] - islist = 1 - - def __init__(self, name, default, dico, length_from=None, itemfmt="!H"): - StrLenField.__init__(self, name, default, length_from=length_from) - self.itemfmt = itemfmt - self.itemsize = struct.calcsize(itemfmt) - i2s = self.i2s = {} - s2i = self.s2i = {} - for k in six.iterkeys(dico): - i2s[k] = dico[k] - s2i[dico[k]] = k - - def any2i_one(self, pkt, x): - if (isinstance(x, _GenericCipherSuite) or - isinstance(x, _GenericCipherSuiteMetaclass)): - x = x.val - if isinstance(x, bytes): - x = self.s2i[x] - return x - - def i2repr_one(self, pkt, x): - fmt = "0x%%0%dx" % self.itemsize - return self.i2s.get(x, fmt % x) - - def any2i(self, pkt, x): - if x is None: - return None - if not isinstance(x, list): - x = [x] - return [self.any2i_one(pkt, z) for z in x] - - def i2repr(self, pkt, x): - if x is None: - return "None" - tmp_len = [self.i2repr_one(pkt, z) for z in x] - if len(tmp_len) == 1: - tmp_len = tmp_len[0] - else: - tmp_len = "[%s]" % ", ".join(tmp_len) - return tmp_len - - def i2m(self, pkt, val): - if val is None: - val = [] - return b"".join(struct.pack(self.itemfmt, x) for x in val) - - def m2i(self, pkt, m): - res = [] - itemlen = struct.calcsize(self.itemfmt) - while m: - res.append(struct.unpack(self.itemfmt, m[:itemlen])[0]) - m = m[itemlen:] - return res - - def i2len(self, pkt, i): - if i is None: - return 0 - return len(i) * self.itemsize - - -class _CompressionMethodsField(_CipherSuitesField): - - def any2i_one(self, pkt, x): - if (isinstance(x, _GenericComp) or - isinstance(x, _GenericCompMetaclass)): - x = x.val - if isinstance(x, str): - x = self.s2i[x] - return x - - -############################################################################### -# ClientHello # -############################################################################### - -class TLSClientHello(_TLSHandshake): - """ - TLS ClientHello, with abilities to handle extensions. - - The Random structure follows the RFC 5246: while it is 32-byte long, - many implementations use the first 4 bytes as a gmt_unix_time, and then - the remaining 28 byts should be completely random. This was designed in - order to (sort of) mitigate broken RNGs. If you prefer to show the full - 32 random bytes without any GMT time, just comment in/out the lines below. - """ - name = "TLS Handshake - Client Hello" - fields_desc = [ByteEnumField("msgtype", 1, _tls_handshake_type), - ThreeBytesField("msglen", None), - _TLSClientVersionField("version", None, _tls_version), - - # _TLSRandomBytesField("random_bytes", None, 32), - _GMTUnixTimeField("gmt_unix_time", None), - _TLSRandomBytesField("random_bytes", None, 28), - - FieldLenField("sidlen", None, fmt="B", length_of="sid"), - _SessionIDField("sid", "", - length_from=lambda pkt: pkt.sidlen), - - FieldLenField("cipherslen", None, fmt="!H", - length_of="ciphers"), - _CipherSuitesField("ciphers", None, - _tls_cipher_suites, itemfmt="!H", - length_from=lambda pkt: pkt.cipherslen), - - FieldLenField("complen", None, fmt="B", length_of="comp"), - _CompressionMethodsField("comp", [0], - _tls_compression_algs, - itemfmt="B", - length_from=lambda pkt: pkt.complen), # noqa: E501 - - _ExtensionsLenField("extlen", None, length_of="ext"), - _ExtensionsField("ext", None, - length_from=lambda pkt: (pkt.msglen - - (pkt.sidlen or 0) - # noqa: E501 - (pkt.cipherslen or 0) - # noqa: E501 - (pkt.complen or 0) - # noqa: E501 - 40))] - - def post_build(self, p, pay): - if self.random_bytes is None: - p = p[:10] + randstring(28) + p[10 + 28:] - - # if no ciphersuites were provided, we add a few usual, supported - # ciphersuites along with the appropriate extensions - if self.ciphers is None: - cipherstart = 39 + (self.sidlen or 0) - s = b"001ac02bc023c02fc027009e0067009c003cc009c0130033002f000a" - p = p[:cipherstart] + hex_bytes(s) + p[cipherstart + 2:] - if self.ext is None: - ext_len = b'\x00\x2c' - ext_reneg = b'\xff\x01\x00\x01\x00' - ext_sn = b'\x00\x00\x00\x0f\x00\r\x00\x00\nsecdev.org' - ext_sigalg = b'\x00\r\x00\x08\x00\x06\x04\x03\x04\x01\x02\x01' - ext_supgroups = b'\x00\n\x00\x04\x00\x02\x00\x17' - p += ext_len + ext_reneg + ext_sn + ext_sigalg + ext_supgroups - - return super(TLSClientHello, self).post_build(p, pay) - - def tls_session_update(self, msg_str): - """ - Either for parsing or building, we store the client_random - along with the raw string representing this handshake message. - """ - super(TLSClientHello, self).tls_session_update(msg_str) - - s = self.tls_session - s.advertised_tls_version = self.version - self.random_bytes = msg_str[10:38] - s.client_random = (struct.pack('!I', self.gmt_unix_time) + - self.random_bytes) - - # No distinction between a TLS 1.2 ClientHello and a TLS - # 1.3 ClientHello when dissecting : TLS 1.3 CH will be - # parsed as TLSClientHello - if self.ext: - for e in self.ext: - if isinstance(e, TLS_Ext_SupportedVersion_CH): - s.advertised_tls_version = e.versions[0] - - if isinstance(e, TLS_Ext_SignatureAlgorithms): - s.advertised_sig_algs = e.sig_algs - - -class TLS13ClientHello(TLSClientHello): - """ - TLS 1.3 ClientHello, with abilities to handle extensions. - - The Random structure is 32 random bytes without any GMT time - """ - name = "TLS 1.3 Handshake - Client Hello" - fields_desc = [ByteEnumField("msgtype", 1, _tls_handshake_type), - ThreeBytesField("msglen", None), - _TLSClientVersionField("version", None, _tls_version), - - _TLSRandomBytesField("random_bytes", None, 32), - - FieldLenField("sidlen", None, fmt="B", length_of="sid"), - _SessionIDField("sid", "", - length_from=lambda pkt: pkt.sidlen), - - FieldLenField("cipherslen", None, fmt="!H", - length_of="ciphers"), - _CipherSuitesField("ciphers", None, - _tls_cipher_suites, itemfmt="!H", - length_from=lambda pkt: pkt.cipherslen), - - FieldLenField("complen", None, fmt="B", length_of="comp"), - _CompressionMethodsField("comp", [0], - _tls_compression_algs, - itemfmt="B", - length_from=lambda pkt: pkt.complen), # noqa: E501 - - _ExtensionsLenField("extlen", None, length_of="ext"), - _ExtensionsField("ext", None, - length_from=lambda pkt: (pkt.msglen - - (pkt.sidlen or 0) - # noqa: E501 - (pkt.cipherslen or 0) - # noqa: E501 - (pkt.complen or 0) - # noqa: E501 - 40))] - - def post_build(self, p, pay): - if self.random_bytes is None: - p = p[:6] + randstring(32) + p[6 + 32:] - return super(TLS13ClientHello, self).post_build(p, pay) - - def tls_session_update(self, msg_str): - """ - Either for parsing or building, we store the client_random - along with the raw string representing this handshake message. - """ - super(TLS13ClientHello, self).tls_session_update(msg_str) - s = self.tls_session - - if self.sidlen and self.sidlen > 0: - s.sid = self.sid - self.random_bytes = msg_str[10:38] - s.client_random = self.random_bytes - if self.ext: - for e in self.ext: - if isinstance(e, TLS_Ext_SupportedVersion_CH): - self.tls_session.advertised_tls_version = e.versions[0] - if isinstance(e, TLS_Ext_SignatureAlgorithms): - s.advertised_sig_algs = e.sig_algs - - -############################################################################### -# ServerHello # -############################################################################### - - -class TLSServerHello(_TLSHandshake): - """ - TLS ServerHello, with abilities to handle extensions. - - The Random structure follows the RFC 5246: while it is 32-byte long, - many implementations use the first 4 bytes as a gmt_unix_time, and then - the remaining 28 byts should be completely random. This was designed in - order to (sort of) mitigate broken RNGs. If you prefer to show the full - 32 random bytes without any GMT time, just comment in/out the lines below. - """ - name = "TLS Handshake - Server Hello" - fields_desc = [ByteEnumField("msgtype", 2, _tls_handshake_type), - ThreeBytesField("msglen", None), - _TLSVersionField("version", None, _tls_version), - - # _TLSRandomBytesField("random_bytes", None, 32), - _GMTUnixTimeField("gmt_unix_time", None), - _TLSRandomBytesField("random_bytes", None, 28), - - FieldLenField("sidlen", None, length_of="sid", fmt="B"), - _SessionIDField("sid", "", - length_from=lambda pkt: pkt.sidlen), - - EnumField("cipher", None, _tls_cipher_suites), - _CompressionMethodsField("comp", [0], - _tls_compression_algs, - itemfmt="B", - length_from=lambda pkt: 1), - - _ExtensionsLenField("extlen", None, length_of="ext"), - _ExtensionsField("ext", None, - length_from=lambda pkt: (pkt.msglen - - (pkt.sidlen or 0) - # noqa: E501 - 38))] - # 40)) ] - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 6: - version = struct.unpack("!H", _pkt[4:6])[0] - if version == 0x0304 or version > 0x7f00: - return TLS13ServerHello - return TLSServerHello - - def post_build(self, p, pay): - if self.random_bytes is None: - p = p[:10] + randstring(28) + p[10 + 28:] - return super(TLSServerHello, self).post_build(p, pay) - - def tls_session_update(self, msg_str): - """ - Either for parsing or building, we store the server_random - along with the raw string representing this handshake message. - We also store the session_id, the cipher suite (if recognized), - the compression method, and finally we instantiate the pending write - and read connection states. Usually they get updated later on in the - negotiation when we learn the session keys, and eventually they - are committed once a ChangeCipherSpec has been sent/received. - """ - super(TLSServerHello, self).tls_session_update(msg_str) - - self.tls_session.tls_version = self.version - self.random_bytes = msg_str[10:38] - self.tls_session.server_random = (struct.pack('!I', - self.gmt_unix_time) + - self.random_bytes) - self.tls_session.sid = self.sid - - cs_cls = None - if self.cipher: - cs_val = self.cipher - if cs_val not in _tls_cipher_suites_cls: - warning("Unknown cipher suite %d from ServerHello" % cs_val) - # we do not try to set a default nor stop the execution - else: - cs_cls = _tls_cipher_suites_cls[cs_val] - - comp_cls = Comp_NULL - if self.comp: - comp_val = self.comp[0] - if comp_val not in _tls_compression_algs_cls: - err = "Unknown compression alg %d from ServerHello" % comp_val - warning(err) - comp_val = 0 - comp_cls = _tls_compression_algs_cls[comp_val] - - connection_end = self.tls_session.connection_end - self.tls_session.pwcs = writeConnState(ciphersuite=cs_cls, - compression_alg=comp_cls, - connection_end=connection_end, - tls_version=self.version) - self.tls_session.prcs = readConnState(ciphersuite=cs_cls, - compression_alg=comp_cls, - connection_end=connection_end, - tls_version=self.version) - - -_tls_13_server_hello_fields = [ - ByteEnumField("msgtype", 2, _tls_handshake_type), - ThreeBytesField("msglen", None), - _TLSVersionField("version", 0x0303, _tls_version), - _TLSRandomBytesField("random_bytes", None, 32), - FieldLenField("sidlen", None, length_of="sid", fmt="B"), - _SessionIDField("sid", "", - length_from=lambda pkt: pkt.sidlen), - EnumField("cipher", None, _tls_cipher_suites), - _CompressionMethodsField("comp", [0], - _tls_compression_algs, - itemfmt="B", - length_from=lambda pkt: 1), - _ExtensionsLenField("extlen", None, length_of="ext"), - _ExtensionsField("ext", None, - length_from=lambda pkt: (pkt.msglen - - 38)) -] - - -class TLS13ServerHello(_TLSHandshake): - """ TLS 1.3 ServerHello """ - name = "TLS 1.3 Handshake - Server Hello" - fields_desc = _tls_13_server_hello_fields - - def post_build(self, p, pay): - if self.random_bytes is None: - p = p[:6] + randstring(32) + p[6 + 32:] - return super(TLS13ServerHello, self).post_build(p, pay) - - def tls_session_update(self, msg_str): - """ - Either for parsing or building, we store the server_random along with - the raw string representing this handshake message. We also store the - cipher suite (if recognized), and finally we instantiate the write and - read connection states. - """ - super(TLS13ServerHello, self).tls_session_update(msg_str) - - s = self.tls_session - if self.ext: - for e in self.ext: - if isinstance(e, TLS_Ext_SupportedVersion_SH): - s.tls_version = e.version - break - s.server_random = self.random_bytes - s.ciphersuite = self.cipher - - cs_cls = None - if self.cipher: - cs_val = self.cipher - if cs_val not in _tls_cipher_suites_cls: - warning("Unknown cipher suite %d from ServerHello" % cs_val) - # we do not try to set a default nor stop the execution - else: - cs_cls = _tls_cipher_suites_cls[cs_val] - - connection_end = s.connection_end - - if connection_end == "server": - s.pwcs = writeConnState(ciphersuite=cs_cls, - connection_end=connection_end, - tls_version=s.tls_version) - s.triggered_pwcs_commit = True - elif connection_end == "client": - s.prcs = readConnState(ciphersuite=cs_cls, - connection_end=connection_end, - tls_version=s.tls_version) - s.triggered_prcs_commit = True - - if s.tls13_early_secret is None: - # In case the connState was not pre-initialized, we could not - # compute the early secrets at the ClientHello, so we do it here. - s.compute_tls13_early_secrets() - s.compute_tls13_handshake_secrets() - if connection_end == "server": - shts = s.tls13_derived_secrets["server_handshake_traffic_secret"] - s.pwcs.tls13_derive_keys(shts) - elif connection_end == "client": - shts = s.tls13_derived_secrets["server_handshake_traffic_secret"] - s.prcs.tls13_derive_keys(shts) - - -############################################################################### -# HelloRetryRequest # -############################################################################### - -class TLS13HelloRetryRequest(_TLSHandshake): - name = "TLS 1.3 Handshake - Hello Retry Request" - - fields_desc = _tls_13_server_hello_fields - - -############################################################################### -# EncryptedExtensions # -############################################################################### - - -class TLSEncryptedExtensions(_TLSHandshake): - name = "TLS 1.3 Handshake - Encrypted Extensions" - fields_desc = [ByteEnumField("msgtype", 8, _tls_handshake_type), - ThreeBytesField("msglen", None), - _ExtensionsLenField("extlen", None, length_of="ext"), - _ExtensionsField("ext", None, - length_from=lambda pkt: pkt.msglen - 2)] - - def post_build_tls_session_update(self, msg_str): - self.tls_session_update(msg_str) - - s = self.tls_session - connection_end = s.connection_end - - # Check if the server early_data extension is present in - # EncryptedExtensions message (if so, early data was accepted by the - # server) - early_data_accepted = False - if self.ext: - for e in self.ext: - if isinstance(e, TLS_Ext_EarlyDataIndication): - early_data_accepted = True - - # If the serveur did not accept early_data, we change prcs traffic - # encryption keys. Otherwise, the the keys will be updated after the - # EndOfEarlyData message - if connection_end == "server": - if not early_data_accepted: - s.prcs = writeConnState(ciphersuite=type(s.wcs.ciphersuite), - connection_end=connection_end, - tls_version=s.tls_version) - - s.triggered_prcs_commit = True - chts = s.tls13_derived_secrets["client_handshake_traffic_secret"] # noqa: E501 - s.prcs.tls13_derive_keys(chts) - - s.rcs = self.tls_session.prcs - s.triggered_prcs_commit = False - - def post_dissection_tls_session_update(self, msg_str): - self.tls_session_update(msg_str) - s = self.tls_session - connection_end = s.connection_end - - # Check if the server early_data extension is present in - # EncryptedExtensions message (if so, early data was accepted by the - # server) - early_data_accepted = False - if self.ext: - for e in self.ext: - if isinstance(e, TLS_Ext_EarlyDataIndication): - early_data_accepted = True - - # If the serveur did not accept early_data, we change pwcs traffic - # encryption key. Otherwise, the the keys will be updated after the - # EndOfEarlyData message - if connection_end == "client": - if not early_data_accepted: - s.pwcs = writeConnState(ciphersuite=type(s.rcs.ciphersuite), - connection_end=connection_end, - tls_version=s.tls_version) - - s.triggered_pwcs_commit = True - chts = s.tls13_derived_secrets["client_handshake_traffic_secret"] # noqa: E501 - s.pwcs.tls13_derive_keys(chts) - - s.wcs = self.tls_session.pwcs - s.triggered_pwcs_commit = False -############################################################################### -# Certificate # -############################################################################### - -# XXX It might be appropriate to rewrite this mess with basic 3-byte FieldLenField. # noqa: E501 - - -class _ASN1CertLenField(FieldLenField): - """ - This is mostly a 3-byte FieldLenField. - """ - def __init__(self, name, default, length_of=None, adjust=lambda pkt, x: x): - self.length_of = length_of - self.adjust = adjust - Field.__init__(self, name, default, fmt="!I") - - def i2m(self, pkt, x): - if x is None: - if self.length_of is not None: - fld, fval = pkt.getfield_and_val(self.length_of) - f = fld.i2len(pkt, fval) - x = self.adjust(pkt, f) - return x - - def addfield(self, pkt, s, val): - return s + struct.pack(self.fmt, self.i2m(pkt, val))[1:4] - - def getfield(self, pkt, s): - return s[3:], self.m2i(pkt, struct.unpack(self.fmt, b"\x00" + s[:3])[0]) # noqa: E501 - - -class _ASN1CertListField(StrLenField): - islist = 1 - - def i2len(self, pkt, i): - if i is None: - return 0 - return len(self.i2m(pkt, i)) - - def getfield(self, pkt, s): - """ - Extract Certs in a loop. - XXX We should provide safeguards when trying to parse a Cert. - """ - tmp_len = None - if self.length_from is not None: - tmp_len = self.length_from(pkt) - - lst = [] - ret = b"" - m = s - if tmp_len is not None: - m, ret = s[:tmp_len], s[tmp_len:] - while m: - clen = struct.unpack("!I", b'\x00' + m[:3])[0] - lst.append((clen, Cert(m[3:3 + clen]))) - m = m[3 + clen:] - return m + ret, lst - - def i2m(self, pkt, i): - def i2m_one(i): - if isinstance(i, str): - return i - if isinstance(i, Cert): - s = i.der - tmp_len = struct.pack("!I", len(s))[1:4] - return tmp_len + s - - (tmp_len, s) = i - if isinstance(s, Cert): - s = s.der - return struct.pack("!I", tmp_len)[1:4] + s - - if i is None: - return b"" - if isinstance(i, str): - return i - if isinstance(i, Cert): - i = [i] - return b"".join(i2m_one(x) for x in i) - - def any2i(self, pkt, x): - return x - - -class _ASN1CertField(StrLenField): - def i2len(self, pkt, i): - if i is None: - return 0 - return len(self.i2m(pkt, i)) - - def getfield(self, pkt, s): - tmp_len = None - if self.length_from is not None: - tmp_len = self.length_from(pkt) - ret = b"" - m = s - if tmp_len is not None: - m, ret = s[:tmp_len], s[tmp_len:] - clen = struct.unpack("!I", b'\x00' + m[:3])[0] - len_cert = (clen, Cert(m[3:3 + clen])) - m = m[3 + clen:] - return m + ret, len_cert - - def i2m(self, pkt, i): - def i2m_one(i): - if isinstance(i, str): - return i - if isinstance(i, Cert): - s = i.der - tmp_len = struct.pack("!I", len(s))[1:4] - return tmp_len + s - - (tmp_len, s) = i - if isinstance(s, Cert): - s = s.der - return struct.pack("!I", tmp_len)[1:4] + s - - if i is None: - return b"" - return i2m_one(i) - - def any2i(self, pkt, x): - return x - - -class TLSCertificate(_TLSHandshake): - """ - XXX We do not support RFC 5081, i.e. OpenPGP certificates. - """ - name = "TLS Handshake - Certificate" - fields_desc = [ByteEnumField("msgtype", 11, _tls_handshake_type), - ThreeBytesField("msglen", None), - _ASN1CertLenField("certslen", None, length_of="certs"), - _ASN1CertListField("certs", [], - length_from=lambda pkt: pkt.certslen)] - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt: - tls_session = kargs.get("tls_session", None) - if tls_session and (tls_session.tls_version or 0) >= 0x0304: - return TLS13Certificate - return TLSCertificate - - def post_dissection_tls_session_update(self, msg_str): - self.tls_session_update(msg_str) - connection_end = self.tls_session.connection_end - if connection_end == "client": - self.tls_session.server_certs = [x[1] for x in self.certs] - else: - self.tls_session.client_certs = [x[1] for x in self.certs] - - -class _ASN1CertAndExt(_GenericTLSSessionInheritance): - name = "Certificate and Extensions" - fields_desc = [_ASN1CertField("cert", ""), - FieldLenField("extlen", None, length_of="ext"), - _ExtensionsField("ext", [], - length_from=lambda pkt: pkt.extlen)] - - def extract_padding(self, s): - return b"", s - - -class _ASN1CertAndExtListField(PacketListField): - def m2i(self, pkt, m): - return self.cls(m, tls_session=pkt.tls_session) - - -class TLS13Certificate(_TLSHandshake): - name = "TLS 1.3 Handshake - Certificate" - fields_desc = [ByteEnumField("msgtype", 11, _tls_handshake_type), - ThreeBytesField("msglen", None), - FieldLenField("cert_req_ctxt_len", None, fmt="B", - length_of="cert_req_ctxt"), - StrLenField("cert_req_ctxt", "", - length_from=lambda pkt: pkt.cert_req_ctxt_len), - _ASN1CertLenField("certslen", None, length_of="certs"), - _ASN1CertAndExtListField("certs", [], _ASN1CertAndExt, - length_from=lambda pkt: pkt.certslen)] # noqa: E501 - - def post_dissection_tls_session_update(self, msg_str): - self.tls_session_update(msg_str) - connection_end = self.tls_session.connection_end - if connection_end == "client": - if self.certs: - sc = [x.cert[1] for x in self.certs] - self.tls_session.server_certs = sc - else: - if self.certs: - cc = [x.cert[1] for x in self.certs] - self.tls_session.client_certs = cc - - -############################################################################### -# ServerKeyExchange # -############################################################################### - -class TLSServerKeyExchange(_TLSHandshake): - name = "TLS Handshake - Server Key Exchange" - fields_desc = [ByteEnumField("msgtype", 12, _tls_handshake_type), - ThreeBytesField("msglen", None), - _TLSServerParamsField("params", None, - length_from=lambda pkt: pkt.msglen), - _TLSSignatureField("sig", None, - length_from=lambda pkt: pkt.msglen - len(pkt.params))] # noqa: E501 - - def build(self, *args, **kargs): - """ - We overload build() method in order to provide a valid default value - for params based on TLS session if not provided. This cannot be done by - overriding i2m() because the method is called on a copy of the packet. - - The 'params' field is built according to key_exchange.server_kx_msg_cls - which should have been set after receiving a cipher suite in a - previous ServerHello. Usual cases are: - - None: for RSA encryption or fixed FF/ECDH. This should never happen, - as no ServerKeyExchange should be generated in the first place. - - ServerDHParams: for ephemeral FFDH. In that case, the parameter to - server_kx_msg_cls does not matter. - - ServerECDH*Params: for ephemeral ECDH. There are actually three - classes, which are dispatched by _tls_server_ecdh_cls_guess on - the first byte retrieved. The default here is b"\03", which - corresponds to ServerECDHNamedCurveParams (implicit curves). - - When the Server*DHParams are built via .fill_missing(), the session - server_kx_privkey will be updated accordingly. - """ - fval = self.getfieldval("params") - if fval is None: - s = self.tls_session - if s.pwcs: - if s.pwcs.key_exchange.export: - cls = ServerRSAParams(tls_session=s) - else: - cls = s.pwcs.key_exchange.server_kx_msg_cls(b"\x03") - cls = cls(tls_session=s) - try: - cls.fill_missing() - except Exception: - if conf.debug_dissector: - raise - pass - else: - cls = Raw() - self.params = cls - - fval = self.getfieldval("sig") - if fval is None: - s = self.tls_session - if s.pwcs: - if not s.pwcs.key_exchange.anonymous: - p = self.params - if p is None: - p = b"" - m = s.client_random + s.server_random + raw(p) - cls = _TLSSignature(tls_session=s) - cls._update_sig(m, s.server_key) - else: - cls = Raw() - else: - cls = Raw() - self.sig = cls - - return _TLSHandshake.build(self, *args, **kargs) - - def post_dissection(self, pkt): - """ - While previously dissecting Server*DHParams, the session - server_kx_pubkey should have been updated. - - XXX Add a 'fixed_dh' OR condition to the 'anonymous' test. - """ - s = self.tls_session - if s.prcs and s.prcs.key_exchange.no_ske: - pkt_info = pkt.firstlayer().summary() - log_runtime.info("TLS: useless ServerKeyExchange [%s]", pkt_info) - if (s.prcs and - not s.prcs.key_exchange.anonymous and - s.client_random and s.server_random and - s.server_certs and len(s.server_certs) > 0): - m = s.client_random + s.server_random + raw(self.params) - sig_test = self.sig._verify_sig(m, s.server_certs[0]) - if not sig_test: - pkt_info = pkt.firstlayer().summary() - log_runtime.info("TLS: invalid ServerKeyExchange signature [%s]", pkt_info) # noqa: E501 - - -############################################################################### -# CertificateRequest # -############################################################################### - -_tls_client_certificate_types = {1: "rsa_sign", - 2: "dss_sign", - 3: "rsa_fixed_dh", - 4: "dss_fixed_dh", - 5: "rsa_ephemeral_dh_RESERVED", - 6: "dss_ephemeral_dh_RESERVED", - 20: "fortezza_dms_RESERVED", - 64: "ecdsa_sign", - 65: "rsa_fixed_ecdh", - 66: "ecdsa_fixed_ecdh"} - - -class _CertTypesField(_CipherSuitesField): - pass - - -class _CertAuthoritiesField(StrLenField): - """ - XXX Rework this with proper ASN.1 parsing. - """ - islist = 1 - - def getfield(self, pkt, s): - tmp_len = self.length_from(pkt) - return s[tmp_len:], self.m2i(pkt, s[:tmp_len]) - - def m2i(self, pkt, m): - res = [] - while len(m) > 1: - tmp_len = struct.unpack("!H", m[:2])[0] - if len(m) < tmp_len + 2: - res.append((tmp_len, m[2:])) - break - dn = m[2:2 + tmp_len] - res.append((tmp_len, dn)) - m = m[2 + tmp_len:] - return res - - def i2m(self, pkt, i): - return b"".join(map(lambda x_y: struct.pack("!H", x_y[0]) + x_y[1], i)) - - def addfield(self, pkt, s, val): - return s + self.i2m(pkt, val) - - def i2len(self, pkt, val): - if val is None: - return 0 - else: - return len(self.i2m(pkt, val)) - - -class TLSCertificateRequest(_TLSHandshake): - name = "TLS Handshake - Certificate Request" - fields_desc = [ByteEnumField("msgtype", 13, _tls_handshake_type), - ThreeBytesField("msglen", None), - FieldLenField("ctypeslen", None, fmt="B", - length_of="ctypes"), - _CertTypesField("ctypes", [1, 64], - _tls_client_certificate_types, - itemfmt="!B", - length_from=lambda pkt: pkt.ctypeslen), - SigAndHashAlgsLenField("sig_algs_len", None, - length_of="sig_algs"), - SigAndHashAlgsField("sig_algs", [0x0403, 0x0401, 0x0201], - EnumField("hash_sig", None, _tls_hash_sig), # noqa: E501 - length_from=lambda pkt: pkt.sig_algs_len), # noqa: E501 - FieldLenField("certauthlen", None, fmt="!H", - length_of="certauth"), - _CertAuthoritiesField("certauth", [], - length_from=lambda pkt: pkt.certauthlen)] # noqa: E501 - - -class TLS13CertificateRequest(_TLSHandshake): - name = "TLS 1.3 Handshake - Certificate Request" - fields_desc = [ByteEnumField("msgtype", 13, _tls_handshake_type), - ThreeBytesField("msglen", None), - FieldLenField("cert_req_ctxt_len", None, fmt="B", - length_of="cert_req_ctxt"), - StrLenField("cert_req_ctxt", "", - length_from=lambda pkt: pkt.cert_req_ctxt_len), - _ExtensionsLenField("extlen", None, length_of="ext"), - _ExtensionsField("ext", None, - length_from=lambda pkt: pkt.msglen - - pkt.cert_req_ctxt_len - 3)] -############################################################################### -# ServerHelloDone # -############################################################################### - - -class TLSServerHelloDone(_TLSHandshake): - name = "TLS Handshake - Server Hello Done" - fields_desc = [ByteEnumField("msgtype", 14, _tls_handshake_type), - ThreeBytesField("msglen", None)] - - -############################################################################### -# CertificateVerify # -############################################################################### - -class TLSCertificateVerify(_TLSHandshake): - name = "TLS Handshake - Certificate Verify" - fields_desc = [ByteEnumField("msgtype", 15, _tls_handshake_type), - ThreeBytesField("msglen", None), - _TLSSignatureField("sig", None, - length_from=lambda pkt: pkt.msglen)] - - def build(self, *args, **kargs): - sig = self.getfieldval("sig") - if sig is None: - s = self.tls_session - m = b"".join(s.handshake_messages) - if s.tls_version >= 0x0304: - if s.connection_end == "client": - context_string = b"TLS 1.3, client CertificateVerify" - elif s.connection_end == "server": - context_string = b"TLS 1.3, server CertificateVerify" - m = b"\x20" * 64 + context_string + b"\x00" + s.wcs.hash.digest(m) # noqa: E501 - self.sig = _TLSSignature(tls_session=s) - if s.connection_end == "client": - self.sig._update_sig(m, s.client_key) - elif s.connection_end == "server": - # should be TLS 1.3 only - self.sig._update_sig(m, s.server_key) - return _TLSHandshake.build(self, *args, **kargs) - - def post_dissection(self, pkt): - s = self.tls_session - m = b"".join(s.handshake_messages) - if s.tls_version >= 0x0304: - if s.connection_end == "client": - context_string = b"TLS 1.3, server CertificateVerify" - elif s.connection_end == "server": - context_string = b"TLS 1.3, client CertificateVerify" - m = b"\x20" * 64 + context_string + b"\x00" + s.rcs.hash.digest(m) - - if s.connection_end == "server": - if s.client_certs and len(s.client_certs) > 0: - sig_test = self.sig._verify_sig(m, s.client_certs[0]) - if not sig_test: - pkt_info = pkt.firstlayer().summary() - log_runtime.info("TLS: invalid CertificateVerify signature [%s]", pkt_info) # noqa: E501 - elif s.connection_end == "client": - # should be TLS 1.3 only - if s.server_certs and len(s.server_certs) > 0: - sig_test = self.sig._verify_sig(m, s.server_certs[0]) - if not sig_test: - pkt_info = pkt.firstlayer().summary() - log_runtime.info("TLS: invalid CertificateVerify signature [%s]", pkt_info) # noqa: E501 - - -############################################################################### -# ClientKeyExchange # -############################################################################### - -class _TLSCKExchKeysField(PacketField): - __slots__ = ["length_from"] - holds_packet = 1 - - def __init__(self, name, length_from=None, remain=0): - self.length_from = length_from - PacketField.__init__(self, name, None, None, remain=remain) - - def m2i(self, pkt, m): - """ - The client_kx_msg may be either None, EncryptedPreMasterSecret - (for RSA encryption key exchange), ClientDiffieHellmanPublic, - or ClientECDiffieHellmanPublic. When either one of them gets - dissected, the session context is updated accordingly. - """ - tmp_len = self.length_from(pkt) - tbd, rem = m[:tmp_len], m[tmp_len:] - - s = pkt.tls_session - cls = None - - if s.prcs and s.prcs.key_exchange: - cls = s.prcs.key_exchange.client_kx_msg_cls - - if cls is None: - return Raw(tbd) / Padding(rem) - - return cls(tbd, tls_session=s) / Padding(rem) - - -class TLSClientKeyExchange(_TLSHandshake): - """ - This class mostly works like TLSServerKeyExchange and its 'params' field. - """ - name = "TLS Handshake - Client Key Exchange" - fields_desc = [ByteEnumField("msgtype", 16, _tls_handshake_type), - ThreeBytesField("msglen", None), - _TLSCKExchKeysField("exchkeys", - length_from=lambda pkt: pkt.msglen)] - - def build(self, *args, **kargs): - fval = self.getfieldval("exchkeys") - if fval is None: - s = self.tls_session - if s.prcs: - cls = s.prcs.key_exchange.client_kx_msg_cls - cls = cls(tls_session=s) - else: - cls = Raw() - self.exchkeys = cls - return _TLSHandshake.build(self, *args, **kargs) - - -############################################################################### -# Finished # -############################################################################### - -class _VerifyDataField(StrLenField): - def getfield(self, pkt, s): - if pkt.tls_session.tls_version == 0x0300: - sep = 36 - elif pkt.tls_session.tls_version >= 0x0304: - sep = pkt.tls_session.rcs.hash.hash_len - else: - sep = 12 - return s[sep:], s[:sep] - - -class TLSFinished(_TLSHandshake): - name = "TLS Handshake - Finished" - fields_desc = [ByteEnumField("msgtype", 20, _tls_handshake_type), - ThreeBytesField("msglen", None), - _VerifyDataField("vdata", None)] - - def build(self, *args, **kargs): - fval = self.getfieldval("vdata") - if fval is None: - s = self.tls_session - handshake_msg = b"".join(s.handshake_messages) - con_end = s.connection_end - if s.tls_version < 0x0304: - ms = s.master_secret - self.vdata = s.wcs.prf.compute_verify_data(con_end, "write", - handshake_msg, ms) - else: - self.vdata = s.compute_tls13_verify_data(con_end, "write") - return _TLSHandshake.build(self, *args, **kargs) - - def post_dissection(self, pkt): - s = self.tls_session - if not s.frozen: - handshake_msg = b"".join(s.handshake_messages) - if s.tls_version < 0x0304 and s.master_secret is not None: - ms = s.master_secret - con_end = s.connection_end - verify_data = s.rcs.prf.compute_verify_data(con_end, "read", - handshake_msg, ms) - if self.vdata != verify_data: - pkt_info = pkt.firstlayer().summary() - log_runtime.info("TLS: invalid Finished received [%s]", pkt_info) # noqa: E501 - elif s.tls_version >= 0x0304: - con_end = s.connection_end - verify_data = s.compute_tls13_verify_data(con_end, "read") - if self.vdata != verify_data: - pkt_info = pkt.firstlayer().summary() - log_runtime.info("TLS: invalid Finished received [%s]", pkt_info) # noqa: E501 - - def post_build_tls_session_update(self, msg_str): - self.tls_session_update(msg_str) - s = self.tls_session - if s.tls_version >= 0x0304: - s.pwcs = writeConnState(ciphersuite=type(s.wcs.ciphersuite), - connection_end=s.connection_end, - tls_version=s.tls_version) - s.triggered_pwcs_commit = True - if s.connection_end == "server": - s.compute_tls13_traffic_secrets() - elif s.connection_end == "client": - s.compute_tls13_traffic_secrets_end() - s.compute_tls13_resumption_secret() - - def post_dissection_tls_session_update(self, msg_str): - self.tls_session_update(msg_str) - s = self.tls_session - if s.tls_version >= 0x0304: - s.prcs = readConnState(ciphersuite=type(s.rcs.ciphersuite), - connection_end=s.connection_end, - tls_version=s.tls_version) - s.triggered_prcs_commit = True - if s.connection_end == "client": - s.compute_tls13_traffic_secrets() - elif s.connection_end == "server": - s.compute_tls13_traffic_secrets_end() - s.compute_tls13_resumption_secret() - - -# Additional handshake messages - -############################################################################### -# HelloVerifyRequest # -############################################################################### - -class TLSHelloVerifyRequest(_TLSHandshake): - """ - Defined for DTLS, see RFC 6347. - """ - name = "TLS Handshake - Hello Verify Request" - fields_desc = [ByteEnumField("msgtype", 21, _tls_handshake_type), - ThreeBytesField("msglen", None), - FieldLenField("cookielen", None, - fmt="B", length_of="cookie"), - StrLenField("cookie", "", - length_from=lambda pkt: pkt.cookielen)] - - -############################################################################### -# CertificateURL # -############################################################################### - -_tls_cert_chain_types = {0: "individual_certs", - 1: "pkipath"} - - -class URLAndOptionalHash(Packet): - name = "URLAndOptionHash structure for TLSCertificateURL" - fields_desc = [FieldLenField("urllen", None, length_of="url"), - StrLenField("url", "", - length_from=lambda pkt: pkt.urllen), - FieldLenField("hash_present", None, - fmt="B", length_of="hash", - adjust=lambda pkt, x: int(math.ceil(x / 20.))), # noqa: E501 - StrLenField("hash", "", - length_from=lambda pkt: 20 * pkt.hash_present)] - - def guess_payload_class(self, p): - return Padding - - -class TLSCertificateURL(_TLSHandshake): - """ - Defined in RFC 4366. PkiPath structure of section 8 is not implemented yet. - """ - name = "TLS Handshake - Certificate URL" - fields_desc = [ByteEnumField("msgtype", 21, _tls_handshake_type), - ThreeBytesField("msglen", None), - ByteEnumField("certchaintype", None, _tls_cert_chain_types), - FieldLenField("uahlen", None, length_of="uah"), - PacketListField("uah", [], URLAndOptionalHash, - length_from=lambda pkt: pkt.uahlen)] - - -############################################################################### -# CertificateStatus # -############################################################################### - -class ThreeBytesLenField(FieldLenField): - def __init__(self, name, default, length_of=None, adjust=lambda pkt, x: x): - FieldLenField.__init__(self, name, default, length_of=length_of, - fmt='!I', adjust=adjust) - - def i2repr(self, pkt, x): - if x is None: - return 0 - return repr(self.i2h(pkt, x)) - - def addfield(self, pkt, s, val): - return s + struct.pack(self.fmt, self.i2m(pkt, val))[1:4] - - def getfield(self, pkt, s): - return s[3:], self.m2i(pkt, struct.unpack(self.fmt, b"\x00" + s[:3])[0]) # noqa: E501 - - -_cert_status_cls = {1: OCSP_Response} - - -class _StatusField(PacketField): - def m2i(self, pkt, m): - idtype = pkt.status_type - cls = self.cls - if idtype in _cert_status_cls: - cls = _cert_status_cls[idtype] - return cls(m) - - -class TLSCertificateStatus(_TLSHandshake): - name = "TLS Handshake - Certificate Status" - fields_desc = [ByteEnumField("msgtype", 22, _tls_handshake_type), - ThreeBytesField("msglen", None), - ByteEnumField("status_type", 1, _cert_status_type), - ThreeBytesLenField("responselen", None, - length_of="response"), - _StatusField("response", None, Raw)] - - -############################################################################### -# SupplementalData # -############################################################################### - -class SupDataEntry(Packet): - name = "Supplemental Data Entry - Generic" - fields_desc = [ShortField("sdtype", None), - FieldLenField("len", None, length_of="data"), - StrLenField("data", "", - length_from=lambda pkt:pkt.len)] - - def guess_payload_class(self, p): - return Padding - - -class UserMappingData(Packet): - name = "User Mapping Data" - fields_desc = [ByteField("version", None), - FieldLenField("len", None, length_of="data"), - StrLenField("data", "", - length_from=lambda pkt: pkt.len)] - - def guess_payload_class(self, p): - return Padding - - -class SupDataEntryUM(Packet): - name = "Supplemental Data Entry - User Mapping" - fields_desc = [ShortField("sdtype", None), - FieldLenField("len", None, length_of="data", - adjust=lambda pkt, x: x + 2), - FieldLenField("dlen", None, length_of="data"), - PacketListField("data", [], UserMappingData, - length_from=lambda pkt:pkt.dlen)] - - def guess_payload_class(self, p): - return Padding - - -class TLSSupplementalData(_TLSHandshake): - name = "TLS Handshake - Supplemental Data" - fields_desc = [ByteEnumField("msgtype", 23, _tls_handshake_type), - ThreeBytesField("msglen", None), - ThreeBytesLenField("sdatalen", None, length_of="sdata"), - PacketListField("sdata", [], SupDataEntry, - length_from=lambda pkt: pkt.sdatalen)] - - -############################################################################### -# NewSessionTicket # -############################################################################### - -class TLSNewSessionTicket(_TLSHandshake): - """ - XXX When knowing the right secret, we should be able to read the ticket. - """ - name = "TLS Handshake - New Session Ticket" - fields_desc = [ByteEnumField("msgtype", 4, _tls_handshake_type), - ThreeBytesField("msglen", None), - IntField("lifetime", 0xffffffff), - FieldLenField("ticketlen", None, length_of="ticket"), - StrLenField("ticket", "", - length_from=lambda pkt: pkt.ticketlen)] - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - s = kargs.get("tls_session", None) - if s and s.tls_version and s.tls_version >= 0x0304: - return TLS13NewSessionTicket - return TLSNewSessionTicket - - def post_dissection_tls_session_update(self, msg_str): - self.tls_session_update(msg_str) - if self.tls_session.connection_end == "client": - self.tls_session.client_session_ticket = self.ticket - - -class TLS13NewSessionTicket(_TLSHandshake): - """ - Uncomment the TicketField line for parsing a RFC 5077 ticket. - """ - name = "TLS 1.3 Handshake - New Session Ticket" - fields_desc = [ByteEnumField("msgtype", 4, _tls_handshake_type), - ThreeBytesField("msglen", None), - IntField("ticket_lifetime", 0xffffffff), - IntField("ticket_age_add", 0), - FieldLenField("noncelen", None, fmt="B", - length_of="ticket_nonce"), - StrLenField("ticket_nonce", "", - length_from=lambda pkt: pkt.noncelen), - FieldLenField("ticketlen", None, length_of="ticket"), - # TicketField("ticket", "", - StrLenField("ticket", "", - length_from=lambda pkt: pkt.ticketlen), - _ExtensionsLenField("extlen", None, length_of="ext"), - _ExtensionsField("ext", None, - length_from=lambda pkt: (pkt.msglen - - (pkt.ticketlen or 0) - # noqa: E501 - pkt.noncelen or 0) - 13)] # noqa: E501 - - def post_dissection_tls_session_update(self, msg_str): - self.tls_session_update(msg_str) - if self.tls_session.connection_end == "client": - self.tls_session.client_session_ticket = self.ticket - - -############################################################################### -# EndOfEarlyData # -############################################################################### - -class TLS13EndOfEarlyData(_TLSHandshake): - name = "TLS 1.3 Handshake - End Of Early Data" - - fields_desc = [ByteEnumField("msgtype", 5, _tls_handshake_type), - ThreeBytesField("msglen", None)] - - -############################################################################### -# KeyUpdate # -############################################################################### -_key_update_request = {0: "update_not_requested", 1: "update_requested"} - - -class TLS13KeyUpdate(_TLSHandshake): - name = "TLS 1.3 Handshake - Key Update" - fields_desc = [ByteEnumField("msgtype", 24, _tls_handshake_type), - ThreeBytesField("msglen", None), - ByteEnumField("request_update", 0, _key_update_request)] - - -############################################################################### -# All handshake messages defined in this module # -############################################################################### - -_tls_handshake_cls = {0: TLSHelloRequest, 1: TLSClientHello, - 2: TLSServerHello, 3: TLSHelloVerifyRequest, - 4: TLSNewSessionTicket, - 8: TLSEncryptedExtensions, 11: TLSCertificate, - 12: TLSServerKeyExchange, 13: TLSCertificateRequest, - 14: TLSServerHelloDone, 15: TLSCertificateVerify, - 16: TLSClientKeyExchange, 20: TLSFinished, - 21: TLSCertificateURL, 22: TLSCertificateStatus, - 23: TLSSupplementalData} - -_tls13_handshake_cls = {1: TLS13ClientHello, 2: TLS13ServerHello, - 4: TLS13NewSessionTicket, 5: TLS13EndOfEarlyData, - 8: TLSEncryptedExtensions, 11: TLS13Certificate, - 13: TLS13CertificateRequest, 15: TLSCertificateVerify, - 20: TLSFinished, 24: TLS13KeyUpdate} diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/handshake_sslv2.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/handshake_sslv2.py deleted file mode 100644 index f83d7310f1..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/handshake_sslv2.py +++ /dev/null @@ -1,548 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -SSLv2 handshake fields & logic. -""" - -import struct - -from scapy.config import conf -from scapy.error import log_runtime, warning -from scapy.utils import randstring -from scapy.fields import ByteEnumField, ByteField, EnumField, FieldLenField, \ - ShortEnumField, StrLenField, XStrField, XStrLenField - -from scapy.packet import Padding -from scapy.layers.tls.cert import Cert -from scapy.layers.tls.basefields import _tls_version, _TLSVersionField -from scapy.layers.tls.handshake import _CipherSuitesField -from scapy.layers.tls.keyexchange import _TLSSignatureField, _TLSSignature -from scapy.layers.tls.session import (_GenericTLSSessionInheritance, - readConnState, writeConnState) -from scapy.layers.tls.crypto.suites import (_tls_cipher_suites, - _tls_cipher_suites_cls, - get_usable_ciphersuites, - SSL_CK_DES_192_EDE3_CBC_WITH_MD5) - - -############################################################################### -# Generic SSLv2 Handshake message # -############################################################################### - -_sslv2_handshake_type = {0: "error", 1: "client_hello", - 2: "client_master_key", 3: "client_finished", - 4: "server_hello", 5: "server_verify", - 6: "server_finished", 7: "request_certificate", - 8: "client_certificate"} - - -class _SSLv2Handshake(_GenericTLSSessionInheritance): - """ - Inherited by other Handshake classes to get post_build(). - Also used as a fallback for unknown TLS Handshake packets. - """ - name = "SSLv2 Handshake Generic message" - fields_desc = [ByteEnumField("msgtype", None, _sslv2_handshake_type)] - - def guess_payload_class(self, p): - return Padding - - def tls_session_update(self, msg_str): - """ - Covers both post_build- and post_dissection- context updates. - """ - self.tls_session.handshake_messages.append(msg_str) - self.tls_session.handshake_messages_parsed.append(self) - - -############################################################################### -# Error # -############################################################################### - -_tls_error_code = {1: "no_cipher", 2: "no_certificate", - 4: "bad_certificate", 6: "unsupported_certificate_type"} - - -class SSLv2Error(_SSLv2Handshake): - """ - SSLv2 Error. - """ - name = "SSLv2 Handshake - Error" - fields_desc = [ByteEnumField("msgtype", 0, _sslv2_handshake_type), - ShortEnumField("code", None, _tls_error_code)] - - -############################################################################### -# ClientHello # -############################################################################### - -class _SSLv2CipherSuitesField(_CipherSuitesField): - def __init__(self, name, default, dico, length_from=None): - _CipherSuitesField.__init__(self, name, default, dico, - length_from=length_from) - self.itemfmt = b"" - self.itemsize = 3 - - def i2m(self, pkt, val): - if val is None: - val2 = [] - val2 = [(x >> 16, x & 0x00ffff) for x in val] - return b"".join([struct.pack(">BH", x[0], x[1]) for x in val2]) - - def m2i(self, pkt, m): - res = [] - while m: - res.append(struct.unpack("!I", b"\x00" + m[:3])[0]) - m = m[3:] - return res - - -class SSLv2ClientHello(_SSLv2Handshake): - """ - SSLv2 ClientHello. - """ - name = "SSLv2 Handshake - Client Hello" - fields_desc = [ByteEnumField("msgtype", 1, _sslv2_handshake_type), - _TLSVersionField("version", 0x0002, _tls_version), - - FieldLenField("cipherslen", None, fmt="!H", - length_of="ciphers"), - FieldLenField("sidlen", None, fmt="!H", - length_of="sid"), - FieldLenField("challengelen", None, fmt="!H", - length_of="challenge"), - - XStrLenField("sid", b"", - length_from=lambda pkt:pkt.sidlen), - _SSLv2CipherSuitesField("ciphers", - [SSL_CK_DES_192_EDE3_CBC_WITH_MD5], - _tls_cipher_suites, - length_from=lambda pkt: pkt.cipherslen), # noqa: E501 - XStrLenField("challenge", b"", - length_from=lambda pkt:pkt.challengelen)] - - def tls_session_update(self, msg_str): - super(SSLv2ClientHello, self).tls_session_update(msg_str) - self.tls_session.advertised_tls_version = self.version - self.tls_session.sslv2_common_cs = self.ciphers - self.tls_session.sslv2_challenge = self.challenge - - -############################################################################### -# ServerHello # -############################################################################### - -class _SSLv2CertDataField(StrLenField): - def getfield(self, pkt, s): - tmp_len = 0 - if self.length_from is not None: - tmp_len = self.length_from(pkt) - try: - certdata = Cert(s[:tmp_len]) - except Exception: - if conf.debug_dissector: - raise - certdata = s[:tmp_len] - return s[tmp_len:], certdata - - def i2len(self, pkt, i): - if isinstance(i, Cert): - return len(i.der) - return len(i) - - def i2m(self, pkt, i): - if isinstance(i, Cert): - return i.der - return i - - -class SSLv2ServerHello(_SSLv2Handshake): - """ - SSLv2 ServerHello. - """ - name = "SSLv2 Handshake - Server Hello" - fields_desc = [ByteEnumField("msgtype", 4, _sslv2_handshake_type), - - ByteField("sid_hit", 0), - ByteEnumField("certtype", 1, {1: "x509_cert"}), - _TLSVersionField("version", 0x0002, _tls_version), - - FieldLenField("certlen", None, fmt="!H", - length_of="cert"), - FieldLenField("cipherslen", None, fmt="!H", - length_of="ciphers"), - FieldLenField("connection_idlen", None, fmt="!H", - length_of="connection_id"), - - _SSLv2CertDataField("cert", b"", - length_from=lambda pkt: pkt.certlen), - _SSLv2CipherSuitesField("ciphers", [], _tls_cipher_suites, - length_from=lambda pkt: pkt.cipherslen), # noqa: E501 - XStrLenField("connection_id", b"", - length_from=lambda pkt: pkt.connection_idlen)] - - def tls_session_update(self, msg_str): - """ - XXX Something should be done about the session ID here. - """ - super(SSLv2ServerHello, self).tls_session_update(msg_str) - - s = self.tls_session - client_cs = s.sslv2_common_cs - css = [cs for cs in client_cs if cs in self.ciphers] - s.sslv2_common_cs = css - s.sslv2_connection_id = self.connection_id - s.tls_version = self.version - if self.cert is not None: - s.server_certs = [self.cert] - - -############################################################################### -# ClientMasterKey # -############################################################################### - -class _SSLv2CipherSuiteField(EnumField): - def __init__(self, name, default, dico): - EnumField.__init__(self, name, default, dico) - - def i2m(self, pkt, val): - if val is None: - return b"" - val2 = (val >> 16, val & 0x00ffff) - return struct.pack(">BH", val2[0], val2[1]) - - def addfield(self, pkt, s, val): - return s + self.i2m(pkt, val) - - def m2i(self, pkt, m): - return struct.unpack("!I", b"\x00" + m[:3])[0] - - def getfield(self, pkt, s): - return s[3:], self.m2i(pkt, s) - - -class _SSLv2EncryptedKeyField(XStrLenField): - def i2repr(self, pkt, x): - s = super(_SSLv2EncryptedKeyField, self).i2repr(pkt, x) - if pkt.decryptedkey is not None: - dx = pkt.decryptedkey - ds = super(_SSLv2EncryptedKeyField, self).i2repr(pkt, dx) - s += " [decryptedkey= %s]" % ds - return s - - -class SSLv2ClientMasterKey(_SSLv2Handshake): - """ - SSLv2 ClientMasterKey. - """ - __slots__ = ["decryptedkey"] - name = "SSLv2 Handshake - Client Master Key" - fields_desc = [ByteEnumField("msgtype", 2, _sslv2_handshake_type), - _SSLv2CipherSuiteField("cipher", None, _tls_cipher_suites), - - FieldLenField("clearkeylen", None, fmt="!H", - length_of="clearkey"), - FieldLenField("encryptedkeylen", None, fmt="!H", - length_of="encryptedkey"), - FieldLenField("keyarglen", None, fmt="!H", - length_of="keyarg"), - - XStrLenField("clearkey", "", - length_from=lambda pkt: pkt.clearkeylen), - _SSLv2EncryptedKeyField("encryptedkey", "", - length_from=lambda pkt: pkt.encryptedkeylen), # noqa: E501 - XStrLenField("keyarg", "", - length_from=lambda pkt: pkt.keyarglen)] - - def __init__(self, *args, **kargs): - """ - When post_building, the packets fields are updated (this is somewhat - non-standard). We might need these fields later, but calling __str__ - on a new packet (i.e. not dissected from a raw string) applies - post_build to an object different from the original one... unless - we hackishly always set self.explicit to 1. - """ - self.decryptedkey = kargs.pop("decryptedkey", b"") - super(SSLv2ClientMasterKey, self).__init__(*args, **kargs) - self.explicit = 1 - - def pre_dissect(self, s): - clearkeylen = struct.unpack("!H", s[4:6])[0] - encryptedkeylen = struct.unpack("!H", s[6:8])[0] - encryptedkeystart = 10 + clearkeylen - encryptedkey = s[encryptedkeystart:encryptedkeystart + encryptedkeylen] - if self.tls_session.server_rsa_key: - self.decryptedkey = \ - self.tls_session.server_rsa_key.decrypt(encryptedkey) - else: - self.decryptedkey = None - return s - - def post_build(self, pkt, pay): - cs_val = None - if self.cipher is None: - common_cs = self.tls_session.sslv2_common_cs - cs_vals = get_usable_ciphersuites(common_cs, "SSLv2") - if len(cs_vals) == 0: - warning("No known common cipher suite between SSLv2 Hellos.") - cs_val = 0x0700c0 - cipher = b"\x07\x00\xc0" - else: - cs_val = cs_vals[0] # XXX choose the best one - cipher = struct.pack(">BH", cs_val >> 16, cs_val & 0x00ffff) - cs_cls = _tls_cipher_suites_cls[cs_val] - self.cipher = cs_val - else: - cipher = pkt[1:4] - cs_val = struct.unpack("!I", b"\x00" + cipher)[0] - if cs_val not in _tls_cipher_suites_cls: - warning("Unknown ciphersuite %d from ClientMasterKey" % cs_val) - cs_cls = None - else: - cs_cls = _tls_cipher_suites_cls[cs_val] - - if cs_cls: - if (self.encryptedkey == b"" and - len(self.tls_session.server_certs) > 0): - # else, the user is responsible for export slicing & encryption - key = randstring(cs_cls.cipher_alg.key_len) - - if self.clearkey == b"" and cs_cls.kx_alg.export: - self.clearkey = key[:-5] - - if self.decryptedkey == b"": - if cs_cls.kx_alg.export: - self.decryptedkey = key[-5:] - else: - self.decryptedkey = key - - pubkey = self.tls_session.server_certs[0].pubKey - self.encryptedkey = pubkey.encrypt(self.decryptedkey) - - if self.keyarg == b"" and cs_cls.cipher_alg.type == "block": - self.keyarg = randstring(cs_cls.cipher_alg.block_size) - - clearkey = self.clearkey or b"" - if self.clearkeylen is None: - self.clearkeylen = len(clearkey) - clearkeylen = struct.pack("!H", self.clearkeylen) - - encryptedkey = self.encryptedkey or b"" - if self.encryptedkeylen is None: - self.encryptedkeylen = len(encryptedkey) - encryptedkeylen = struct.pack("!H", self.encryptedkeylen) - - keyarg = self.keyarg or b"" - if self.keyarglen is None: - self.keyarglen = len(keyarg) - keyarglen = struct.pack("!H", self.keyarglen) - - s = (pkt[:1] + cipher + - clearkeylen + encryptedkeylen + keyarglen + - clearkey + encryptedkey + keyarg) - return s + pay - - def tls_session_update(self, msg_str): - super(SSLv2ClientMasterKey, self).tls_session_update(msg_str) - - s = self.tls_session - cs_val = self.cipher - if cs_val not in _tls_cipher_suites_cls: - warning("Unknown cipher suite %d from ClientMasterKey" % cs_val) - cs_cls = None - else: - cs_cls = _tls_cipher_suites_cls[cs_val] - - tls_version = s.tls_version or 0x0002 - connection_end = s.connection_end - wcs_seq_num = s.wcs.seq_num - s.pwcs = writeConnState(ciphersuite=cs_cls, - connection_end=connection_end, - seq_num=wcs_seq_num, - tls_version=tls_version) - rcs_seq_num = s.rcs.seq_num - s.prcs = readConnState(ciphersuite=cs_cls, - connection_end=connection_end, - seq_num=rcs_seq_num, - tls_version=tls_version) - - if self.decryptedkey is not None: - s.master_secret = self.clearkey + self.decryptedkey - s.compute_sslv2_km_and_derive_keys() - - if s.pwcs.cipher.type == "block": - s.pwcs.cipher.iv = self.keyarg - if s.prcs.cipher.type == "block": - s.prcs.cipher.iv = self.keyarg - - s.triggered_prcs_commit = True - s.triggered_pwcs_commit = True - - -############################################################################### -# ServerVerify # -############################################################################### - -class SSLv2ServerVerify(_SSLv2Handshake): - """ - In order to parse a ServerVerify, the exact message string should be - fed to the class. This is how SSLv2 defines the challenge length... - """ - name = "SSLv2 Handshake - Server Verify" - fields_desc = [ByteEnumField("msgtype", 5, _sslv2_handshake_type), - XStrField("challenge", "")] - - def build(self, *args, **kargs): - fval = self.getfieldval("challenge") - if fval is None: - self.challenge = self.tls_session.sslv2_challenge - return super(SSLv2ServerVerify, self).build(*args, **kargs) - - def post_dissection(self, pkt): - s = self.tls_session - if s.sslv2_challenge is not None: - if self.challenge != s.sslv2_challenge: - pkt_info = pkt.firstlayer().summary() - log_runtime.info("TLS: invalid ServerVerify received [%s]", pkt_info) # noqa: E501 - - -############################################################################### -# RequestCertificate # -############################################################################### - -class SSLv2RequestCertificate(_SSLv2Handshake): - """ - In order to parse a RequestCertificate, the exact message string should be - fed to the class. This is how SSLv2 defines the challenge length... - """ - name = "SSLv2 Handshake - Request Certificate" - fields_desc = [ByteEnumField("msgtype", 7, _sslv2_handshake_type), - ByteEnumField("authtype", 1, {1: "md5_with_rsa"}), - XStrField("challenge", "")] - - def tls_session_update(self, msg_str): - super(SSLv2RequestCertificate, self).tls_session_update(msg_str) - self.tls_session.sslv2_challenge_clientcert = self.challenge - - -############################################################################### -# ClientCertificate # -############################################################################### - -class SSLv2ClientCertificate(_SSLv2Handshake): - """ - SSLv2 ClientCertificate. - """ - name = "SSLv2 Handshake - Client Certificate" - fields_desc = [ByteEnumField("msgtype", 8, _sslv2_handshake_type), - - ByteEnumField("certtype", 1, {1: "x509_cert"}), - FieldLenField("certlen", None, fmt="!H", - length_of="certdata"), - FieldLenField("responselen", None, fmt="!H", - length_of="responsedata"), - - _SSLv2CertDataField("certdata", b"", - length_from=lambda pkt: pkt.certlen), - _TLSSignatureField("responsedata", None, - length_from=lambda pkt: pkt.responselen)] - - def build(self, *args, **kargs): - s = self.tls_session - sig = self.getfieldval("responsedata") - test = (sig is None and - s.sslv2_key_material is not None and - s.sslv2_challenge_clientcert is not None and - len(s.server_certs) > 0) - if test: - s = self.tls_session - m = (s.sslv2_key_material + - s.sslv2_challenge_clientcert + - s.server_certs[0].der) - self.responsedata = _TLSSignature(tls_session=s) - self.responsedata._update_sig(m, s.client_key) - else: - self.responsedata = b"" - return super(SSLv2ClientCertificate, self).build(*args, **kargs) - - def post_dissection_tls_session_update(self, msg_str): - self.tls_session_update(msg_str) - - s = self.tls_session - test = (len(s.client_certs) > 0 and - s.sslv2_key_material is not None and - s.sslv2_challenge_clientcert is not None and - len(s.server_certs) > 0) - if test: - m = (s.sslv2_key_material + - s.sslv2_challenge_clientcert + - s.server_certs[0].der) - sig_test = self.responsedata._verify_sig(m, s.client_certs[0]) - if not sig_test: - pkt_info = self.firstlayer().summary() - log_runtime.info("TLS: invalid client CertificateVerify signature [%s]", pkt_info) # noqa: E501 - - def tls_session_update(self, msg_str): - super(SSLv2ClientCertificate, self).tls_session_update(msg_str) - if self.certdata: - self.tls_session.client_certs = [self.certdata] - - -############################################################################### -# Finished # -############################################################################### - -class SSLv2ClientFinished(_SSLv2Handshake): - """ - In order to parse a ClientFinished, the exact message string should be fed - to the class. SSLv2 does not offer any other way to know the c_id length. - """ - name = "SSLv2 Handshake - Client Finished" - fields_desc = [ByteEnumField("msgtype", 3, _sslv2_handshake_type), - XStrField("connection_id", "")] - - def build(self, *args, **kargs): - fval = self.getfieldval("connection_id") - if fval == b"": - self.connection_id = self.tls_session.sslv2_connection_id - return super(SSLv2ClientFinished, self).build(*args, **kargs) - - def post_dissection(self, pkt): - s = self.tls_session - if s.sslv2_connection_id is not None: - if self.connection_id != s.sslv2_connection_id: - pkt_info = pkt.firstlayer().summary() - log_runtime.info("TLS: invalid client Finished received [%s]", pkt_info) # noqa: E501 - - -class SSLv2ServerFinished(_SSLv2Handshake): - """ - In order to parse a ServerFinished, the exact message string should be fed - to the class. SSLv2 does not offer any other way to know the sid length. - """ - name = "SSLv2 Handshake - Server Finished" - fields_desc = [ByteEnumField("msgtype", 6, _sslv2_handshake_type), - XStrField("sid", "")] - - def build(self, *args, **kargs): - fval = self.getfieldval("sid") - if fval == b"": - self.sid = self.tls_session.sid - return super(SSLv2ServerFinished, self).build(*args, **kargs) - - def post_dissection_tls_session_update(self, msg_str): - self.tls_session_update(msg_str) - self.tls_session.sid = self.sid - - -############################################################################### -# All handshake messages defined in this module # -############################################################################### - -_sslv2_handshake_cls = {0: SSLv2Error, 1: SSLv2ClientHello, - 2: SSLv2ClientMasterKey, 3: SSLv2ClientFinished, - 4: SSLv2ServerHello, 5: SSLv2ServerVerify, - 6: SSLv2ServerFinished, 7: SSLv2RequestCertificate, - 8: SSLv2ClientCertificate} diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/keyexchange.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/keyexchange.py deleted file mode 100644 index 5c0709ddb1..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/keyexchange.py +++ /dev/null @@ -1,950 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -TLS key exchange logic. -""" - -from __future__ import absolute_import -import math -import struct - -from scapy.config import conf, crypto_validator -from scapy.error import warning -from scapy.fields import ByteEnumField, ByteField, EnumField, FieldLenField, \ - FieldListField, PacketField, ShortEnumField, ShortField, \ - StrFixedLenField, StrLenField -from scapy.compat import orb -from scapy.packet import Packet, Raw, Padding -from scapy.layers.tls.cert import PubKeyRSA, PrivKeyRSA -from scapy.layers.tls.session import _GenericTLSSessionInheritance -from scapy.layers.tls.basefields import _tls_version, _TLSClientVersionField -from scapy.layers.tls.crypto.pkcs1 import pkcs_i2osp, pkcs_os2ip -from scapy.layers.tls.crypto.groups import _ffdh_groups, _tls_named_curves -import scapy.modules.six as six - -if conf.crypto_valid: - from cryptography.hazmat.backends import default_backend - from cryptography.hazmat.primitives import serialization - from cryptography.hazmat.primitives.asymmetric import dh, ec - - -############################################################################### -# Common Fields # -############################################################################### - -_tls_hash_sig = {0x0000: "none+anon", 0x0001: "none+rsa", - 0x0002: "none+dsa", 0x0003: "none+ecdsa", - 0x0100: "md5+anon", 0x0101: "md5+rsa", - 0x0102: "md5+dsa", 0x0103: "md5+ecdsa", - 0x0200: "sha1+anon", 0x0201: "sha1+rsa", - 0x0202: "sha1+dsa", 0x0203: "sha1+ecdsa", - 0x0300: "sha224+anon", 0x0301: "sha224+rsa", - 0x0302: "sha224+dsa", 0x0303: "sha224+ecdsa", - 0x0400: "sha256+anon", 0x0401: "sha256+rsa", - 0x0402: "sha256+dsa", 0x0403: "sha256+ecdsa", - 0x0500: "sha384+anon", 0x0501: "sha384+rsa", - 0x0502: "sha384+dsa", 0x0503: "sha384+ecdsa", - 0x0600: "sha512+anon", 0x0601: "sha512+rsa", - 0x0602: "sha512+dsa", 0x0603: "sha512+ecdsa", - 0x0804: "sha256+rsaepss", - 0x0805: "sha384+rsaepss", - 0x0806: "sha512+rsaepss", - 0x0807: "ed25519", - 0x0808: "ed448", - 0x0809: "sha256+rsapss"} - - -def phantom_mode(pkt): - """ - We expect this. If tls_version is not set, this means we did not process - any complete ClientHello, so we're most probably reading/building a - signature_algorithms extension, hence we cannot be in phantom_mode. - However, if the tls_version has been set, we test for TLS 1.2. - """ - if not pkt.tls_session: - return False - if not pkt.tls_session.tls_version: - return False - return pkt.tls_session.tls_version < 0x0303 - - -def phantom_decorate(f, get_or_add): - """ - Decorator for version-dependent fields. - If get_or_add is True (means get), we return s, self.phantom_value. - If it is False (means add), we return s. - """ - def wrapper(*args): - self, pkt, s = args[:3] - if phantom_mode(pkt): - if get_or_add: - return s, self.phantom_value - return s - return f(*args) - return wrapper - - -class SigAndHashAlgField(EnumField): - """Used in _TLSSignature.""" - phantom_value = None - getfield = phantom_decorate(EnumField.getfield, True) - addfield = phantom_decorate(EnumField.addfield, False) - - -class SigAndHashAlgsLenField(FieldLenField): - """Used in TLS_Ext_SignatureAlgorithms and TLSCertificateResquest.""" - phantom_value = 0 - getfield = phantom_decorate(FieldLenField.getfield, True) - addfield = phantom_decorate(FieldLenField.addfield, False) - - -class SigAndHashAlgsField(FieldListField): - """Used in TLS_Ext_SignatureAlgorithms and TLSCertificateResquest.""" - phantom_value = [] - getfield = phantom_decorate(FieldListField.getfield, True) - addfield = phantom_decorate(FieldListField.addfield, False) - - -class SigLenField(FieldLenField): - """There is a trick for SSLv2, which uses implicit lengths...""" - - def getfield(self, pkt, s): - v = pkt.tls_session.tls_version - if v and v < 0x0300: - return s, None - return super(SigLenField, self).getfield(pkt, s) - - def addfield(self, pkt, s, val): - """With SSLv2 you will never be able to add a sig_len.""" - v = pkt.tls_session.tls_version - if v and v < 0x0300: - return s - return super(SigLenField, self).addfield(pkt, s, val) - - -class SigValField(StrLenField): - """There is a trick for SSLv2, which uses implicit lengths...""" - - def getfield(self, pkt, m): - s = pkt.tls_session - if s.tls_version and s.tls_version < 0x0300: - if len(s.client_certs) > 0: - sig_len = s.client_certs[0].pubKey.pubkey.key_size // 8 - else: - warning("No client certificate provided. " - "We're making a wild guess about the signature size.") - sig_len = 256 - return m[sig_len:], self.m2i(pkt, m[:sig_len]) - return super(SigValField, self).getfield(pkt, m) - - -class _TLSSignature(_GenericTLSSessionInheritance): - """ - Prior to TLS 1.2, digitally-signed structure implicitly used the - concatenation of a MD5 hash and a SHA-1 hash. - Then TLS 1.2 introduced explicit SignatureAndHashAlgorithms, - i.e. couples of (hash_alg, sig_alg). See RFC 5246, section 7.4.1.4.1. - - By default, the _TLSSignature implements the TLS 1.2 scheme, - but if it is provided a TLS context with a tls_version < 0x0303 - at initialization, it will fall back to the implicit signature. - Even more, the 'sig_len' field won't be used with SSLv2. - - #XXX 'sig_alg' should be set in __init__ depending on the context. - """ - name = "TLS Digital Signature" - fields_desc = [SigAndHashAlgField("sig_alg", 0x0401, _tls_hash_sig), - SigLenField("sig_len", None, fmt="!H", - length_of="sig_val"), - SigValField("sig_val", None, - length_from=lambda pkt: pkt.sig_len)] - - def __init__(self, *args, **kargs): - super(_TLSSignature, self).__init__(*args, **kargs) - if (self.tls_session and - self.tls_session.tls_version and - self.tls_session.tls_version < 0x0303): - self.sig_alg = None - - def _update_sig(self, m, key): - """ - Sign 'm' with the PrivKey 'key' and update our own 'sig_val'. - Note that, even when 'sig_alg' is not None, we use the signature scheme - of the PrivKey (neither do we care to compare the both of them). - """ - if self.sig_alg is None: - if self.tls_session.tls_version >= 0x0300: - self.sig_val = key.sign(m, t='pkcs', h='md5-sha1') - else: - self.sig_val = key.sign(m, t='pkcs', h='md5') - else: - h, sig = _tls_hash_sig[self.sig_alg].split('+') - if sig.endswith('pss'): - t = "pss" - else: - t = "pkcs" - self.sig_val = key.sign(m, t=t, h=h) - - def _verify_sig(self, m, cert): - """ - Verify that our own 'sig_val' carries the signature of 'm' by the - key associated to the Cert 'cert'. - """ - if self.sig_val: - if self.sig_alg: - h, sig = _tls_hash_sig[self.sig_alg].split('+') - if sig.endswith('pss'): - t = "pss" - else: - t = "pkcs" - return cert.verify(m, self.sig_val, t=t, h=h) - else: - if self.tls_session.tls_version >= 0x0300: - return cert.verify(m, self.sig_val, t='pkcs', h='md5-sha1') - else: - return cert.verify(m, self.sig_val, t='pkcs', h='md5') - return False - - def guess_payload_class(self, p): - return Padding - - -class _TLSSignatureField(PacketField): - """ - Used for 'digitally-signed struct' in several ServerKeyExchange, - and also in CertificateVerify. We can handle the anonymous case. - """ - __slots__ = ["length_from"] - - def __init__(self, name, default, length_from=None, remain=0): - self.length_from = length_from - PacketField.__init__(self, name, default, _TLSSignature, remain=remain) - - def m2i(self, pkt, m): - tmp_len = self.length_from(pkt) - if tmp_len == 0: - return None - return _TLSSignature(m, tls_session=pkt.tls_session) - - def getfield(self, pkt, s): - i = self.m2i(pkt, s) - if i is None: - return s, None - remain = b"" - if conf.padding_layer in i: - r = i[conf.padding_layer] - del r.underlayer.payload - remain = r.load - return remain, i - - -class _TLSServerParamsField(PacketField): - """ - This is a dispatcher for the Server*DHParams below, used in - TLSServerKeyExchange and based on the key_exchange.server_kx_msg_cls. - When this cls is None, it means that we should not see a ServerKeyExchange, - so we grab everything within length_from and make it available using Raw. - - When the context has not been set (e.g. when no ServerHello was parsed or - dissected beforehand), we (kinda) clumsily set the cls by trial and error. - XXX We could use Serv*DHParams.check_params() once it has been implemented. - """ - __slots__ = ["length_from"] - - def __init__(self, name, default, length_from=None, remain=0): - self.length_from = length_from - PacketField.__init__(self, name, default, None, remain=remain) - - def m2i(self, pkt, m): - s = pkt.tls_session - tmp_len = self.length_from(pkt) - if s.prcs: - cls = s.prcs.key_exchange.server_kx_msg_cls(m) - if cls is None: - return None, Raw(m[:tmp_len]) / Padding(m[tmp_len:]) - return cls(m, tls_session=s) - else: - try: - p = ServerDHParams(m, tls_session=s) - if pkcs_os2ip(p.load[:2]) not in _tls_hash_sig: - raise Exception - return p - except Exception: - cls = _tls_server_ecdh_cls_guess(m) - p = cls(m, tls_session=s) - if pkcs_os2ip(p.load[:2]) not in _tls_hash_sig: - return None, Raw(m[:tmp_len]) / Padding(m[tmp_len:]) - return p - - -############################################################################### -# Server Key Exchange parameters & value # -############################################################################### - -# Finite Field Diffie-Hellman - -class ServerDHParams(_GenericTLSSessionInheritance): - """ - ServerDHParams for FFDH-based key exchanges, as defined in RFC 5246/7.4.3. - - Either with .fill_missing() or .post_dissection(), the server_kx_privkey or - server_kx_pubkey of the TLS context are updated according to the - parsed/assembled values. It is the user's responsibility to store and - restore the original values if he wants to keep them. For instance, this - could be done between the writing of a ServerKeyExchange and the receiving - of a ClientKeyExchange (which includes secret generation). - """ - name = "Server FFDH parameters" - fields_desc = [FieldLenField("dh_plen", None, length_of="dh_p"), - StrLenField("dh_p", "", - length_from=lambda pkt: pkt.dh_plen), - FieldLenField("dh_glen", None, length_of="dh_g"), - StrLenField("dh_g", "", - length_from=lambda pkt: pkt.dh_glen), - FieldLenField("dh_Yslen", None, length_of="dh_Ys"), - StrLenField("dh_Ys", "", - length_from=lambda pkt: pkt.dh_Yslen)] - - @crypto_validator - def fill_missing(self): - """ - We do not want TLSServerKeyExchange.build() to overload and recompute - things every time it is called. This method can be called specifically - to have things filled in a smart fashion. - - Note that we do not expect default_params.g to be more than 0xff. - """ - s = self.tls_session - - default_params = _ffdh_groups['modp2048'][0].parameter_numbers() - default_mLen = _ffdh_groups['modp2048'][1] - - if not self.dh_p: - self.dh_p = pkcs_i2osp(default_params.p, default_mLen // 8) - if self.dh_plen is None: - self.dh_plen = len(self.dh_p) - - if not self.dh_g: - self.dh_g = pkcs_i2osp(default_params.g, 1) - if self.dh_glen is None: - self.dh_glen = 1 - - p = pkcs_os2ip(self.dh_p) - g = pkcs_os2ip(self.dh_g) - real_params = dh.DHParameterNumbers(p, g).parameters(default_backend()) - - if not self.dh_Ys: - s.server_kx_privkey = real_params.generate_private_key() - pubkey = s.server_kx_privkey.public_key() - y = pubkey.public_numbers().y - self.dh_Ys = pkcs_i2osp(y, pubkey.key_size // 8) - # else, we assume that the user wrote the server_kx_privkey by himself - if self.dh_Yslen is None: - self.dh_Yslen = len(self.dh_Ys) - - if not s.client_kx_ffdh_params: - s.client_kx_ffdh_params = real_params - - @crypto_validator - def register_pubkey(self): - """ - XXX Check that the pubkey received is in the group. - """ - p = pkcs_os2ip(self.dh_p) - g = pkcs_os2ip(self.dh_g) - pn = dh.DHParameterNumbers(p, g) - - y = pkcs_os2ip(self.dh_Ys) - public_numbers = dh.DHPublicNumbers(y, pn) - - s = self.tls_session - s.server_kx_pubkey = public_numbers.public_key(default_backend()) - - if not s.client_kx_ffdh_params: - s.client_kx_ffdh_params = pn.parameters(default_backend()) - - def post_dissection(self, r): - try: - self.register_pubkey() - except ImportError: - pass - - def guess_payload_class(self, p): - """ - The signature after the params gets saved as Padding. - This way, the .getfield() which _TLSServerParamsField inherits - from PacketField will return the signature remain as expected. - """ - return Padding - - -# Elliptic Curve Diffie-Hellman - -_tls_ec_curve_types = {1: "explicit_prime", - 2: "explicit_char2", - 3: "named_curve"} - -_tls_ec_basis_types = {0: "ec_basis_trinomial", 1: "ec_basis_pentanomial"} - - -class ECCurvePkt(Packet): - name = "Elliptic Curve" - fields_desc = [FieldLenField("alen", None, length_of="a", fmt="B"), - StrLenField("a", "", length_from=lambda pkt: pkt.alen), - FieldLenField("blen", None, length_of="b", fmt="B"), - StrLenField("b", "", length_from=lambda pkt: pkt.blen)] - - -# Char2 Curves - -class ECTrinomialBasis(Packet): - name = "EC Trinomial Basis" - val = 0 - fields_desc = [FieldLenField("klen", None, length_of="k", fmt="B"), - StrLenField("k", "", length_from=lambda pkt: pkt.klen)] - - def guess_payload_class(self, p): - return Padding - - -class ECPentanomialBasis(Packet): - name = "EC Pentanomial Basis" - val = 1 - fields_desc = [FieldLenField("k1len", None, length_of="k1", fmt="B"), - StrLenField("k1", "", length_from=lambda pkt: pkt.k1len), - FieldLenField("k2len", None, length_of="k2", fmt="B"), - StrLenField("k2", "", length_from=lambda pkt: pkt.k2len), - FieldLenField("k3len", None, length_of="k3", fmt="B"), - StrLenField("k3", "", length_from=lambda pkt: pkt.k3len)] - - def guess_payload_class(self, p): - return Padding - - -_tls_ec_basis_cls = {0: ECTrinomialBasis, 1: ECPentanomialBasis} - - -class _ECBasisTypeField(ByteEnumField): - __slots__ = ["basis_type_of"] - - def __init__(self, name, default, enum, basis_type_of, remain=0): - self.basis_type_of = basis_type_of - EnumField.__init__(self, name, default, enum, "B") - - def i2m(self, pkt, x): - if x is None: - fld, fval = pkt.getfield_and_val(self.basis_type_of) - x = fld.i2basis_type(pkt, fval) - return x - - -class _ECBasisField(PacketField): - __slots__ = ["clsdict", "basis_type_from"] - - def __init__(self, name, default, basis_type_from, clsdict, remain=0): - self.clsdict = clsdict - self.basis_type_from = basis_type_from - PacketField.__init__(self, name, default, None, remain=remain) - - def m2i(self, pkt, m): - basis = self.basis_type_from(pkt) - cls = self.clsdict[basis] - return cls(m) - - def i2basis_type(self, pkt, x): - val = 0 - try: - val = x.val - except Exception: - pass - return val - - -# Distinct ECParameters -## -# To support the different ECParameters structures defined in Sect. 5.4 of -# RFC 4492, we define 3 separates classes for implementing the 3 associated -# ServerECDHParams: ServerECDHNamedCurveParams, ServerECDHExplicitPrimeParams -# and ServerECDHExplicitChar2Params (support for this one is only partial). -# The most frequent encounter of the 3 is (by far) ServerECDHNamedCurveParams. - -class ServerECDHExplicitPrimeParams(_GenericTLSSessionInheritance): - """ - We provide parsing abilities for ExplicitPrimeParams, but there is no - support from the cryptography library, hence no context operations. - """ - name = "Server ECDH parameters - Explicit Prime" - fields_desc = [ByteEnumField("curve_type", 1, _tls_ec_curve_types), - FieldLenField("plen", None, length_of="p", fmt="B"), - StrLenField("p", "", length_from=lambda pkt: pkt.plen), - PacketField("curve", None, ECCurvePkt), - FieldLenField("baselen", None, length_of="base", fmt="B"), - StrLenField("base", "", - length_from=lambda pkt: pkt.baselen), - FieldLenField("orderlen", None, - length_of="order", fmt="B"), - StrLenField("order", "", - length_from=lambda pkt: pkt.orderlen), - FieldLenField("cofactorlen", None, - length_of="cofactor", fmt="B"), - StrLenField("cofactor", "", - length_from=lambda pkt: pkt.cofactorlen), - FieldLenField("pointlen", None, - length_of="point", fmt="B"), - StrLenField("point", "", - length_from=lambda pkt: pkt.pointlen)] - - def fill_missing(self): - """ - Note that if it is not set by the user, the cofactor will always - be 1. It is true for most, but not all, TLS elliptic curves. - """ - if self.curve_type is None: - self.curve_type = _tls_ec_curve_types["explicit_prime"] - - def guess_payload_class(self, p): - return Padding - - -class ServerECDHExplicitChar2Params(_GenericTLSSessionInheritance): - """ - We provide parsing abilities for Char2Params, but there is no - support from the cryptography library, hence no context operations. - """ - name = "Server ECDH parameters - Explicit Char2" - fields_desc = [ByteEnumField("curve_type", 2, _tls_ec_curve_types), - ShortField("m", None), - _ECBasisTypeField("basis_type", None, - _tls_ec_basis_types, "basis"), - _ECBasisField("basis", ECTrinomialBasis(), - lambda pkt: pkt.basis_type, - _tls_ec_basis_cls), - PacketField("curve", ECCurvePkt(), ECCurvePkt), - FieldLenField("baselen", None, length_of="base", fmt="B"), - StrLenField("base", "", - length_from=lambda pkt: pkt.baselen), - ByteField("order", None), - ByteField("cofactor", None), - FieldLenField("pointlen", None, - length_of="point", fmt="B"), - StrLenField("point", "", - length_from=lambda pkt: pkt.pointlen)] - - def fill_missing(self): - if self.curve_type is None: - self.curve_type = _tls_ec_curve_types["explicit_char2"] - - def guess_payload_class(self, p): - return Padding - - -class ServerECDHNamedCurveParams(_GenericTLSSessionInheritance): - name = "Server ECDH parameters - Named Curve" - fields_desc = [ByteEnumField("curve_type", 3, _tls_ec_curve_types), - ShortEnumField("named_curve", None, _tls_named_curves), - FieldLenField("pointlen", None, - length_of="point", fmt="B"), - StrLenField("point", None, - length_from=lambda pkt: pkt.pointlen)] - - @crypto_validator - def fill_missing(self): - """ - We do not want TLSServerKeyExchange.build() to overload and recompute - things every time it is called. This method can be called specifically - to have things filled in a smart fashion. - - XXX We should account for the point_format (before 'point' filling). - """ - s = self.tls_session - - if self.curve_type is None: - self.curve_type = _tls_ec_curve_types["named_curve"] - - if self.named_curve is None: - curve = ec.SECP256R1() - s.server_kx_privkey = ec.generate_private_key(curve, - default_backend()) - self.named_curve = next((cid for cid, name in six.iteritems(_tls_named_curves) # noqa: E501 - if name == curve.name), 0) - else: - curve_name = _tls_named_curves.get(self.named_curve) - if curve_name is None: - # this fallback is arguable - curve = ec.SECP256R1() - else: - curve_cls = ec._CURVE_TYPES.get(curve_name) - if curve_cls is None: - # this fallback is arguable - curve = ec.SECP256R1() - else: - curve = curve_cls() - s.server_kx_privkey = ec.generate_private_key(curve, - default_backend()) - - if self.point is None: - pubkey = s.server_kx_privkey.public_key() - try: - # cryptography >= 2.5 - self.point = pubkey.public_bytes( - serialization.Encoding.X962, - serialization.PublicFormat.UncompressedPoint - ) - except TypeError: - # older versions - self.key_exchange = pubkey.public_numbers().encode_point() - # else, we assume that the user wrote the server_kx_privkey by himself - if self.pointlen is None: - self.pointlen = len(self.point) - - if not s.client_kx_ecdh_params: - s.client_kx_ecdh_params = curve - - @crypto_validator - def register_pubkey(self): - """ - XXX Support compressed point format. - XXX Check that the pubkey received is on the curve. - """ - # point_format = 0 - # if self.point[0] in [b'\x02', b'\x03']: - # point_format = 1 - - curve_name = _tls_named_curves[self.named_curve] - curve = ec._CURVE_TYPES[curve_name]() - import_point = ec.EllipticCurvePublicNumbers.from_encoded_point - pubnum = import_point(curve, self.point) - s = self.tls_session - s.server_kx_pubkey = pubnum.public_key(default_backend()) - - if not s.client_kx_ecdh_params: - s.client_kx_ecdh_params = curve - - def post_dissection(self, r): - try: - self.register_pubkey() - except ImportError: - pass - - def guess_payload_class(self, p): - return Padding - - -_tls_server_ecdh_cls = {1: ServerECDHExplicitPrimeParams, - 2: ServerECDHExplicitChar2Params, - 3: ServerECDHNamedCurveParams} - - -def _tls_server_ecdh_cls_guess(m): - if not m: - return None - curve_type = orb(m[0]) - return _tls_server_ecdh_cls.get(curve_type, None) - - -# RSA Encryption (export) - -class ServerRSAParams(_GenericTLSSessionInheritance): - """ - Defined for RSA_EXPORT kx : it enables servers to share RSA keys shorter - than their principal {>512}-bit key, when it is not allowed for kx. - - This should not appear in standard RSA kx negotiation, as the key - has already been advertised in the Certificate message. - """ - name = "Server RSA_EXPORT parameters" - fields_desc = [FieldLenField("rsamodlen", None, length_of="rsamod"), - StrLenField("rsamod", "", - length_from=lambda pkt: pkt.rsamodlen), - FieldLenField("rsaexplen", None, length_of="rsaexp"), - StrLenField("rsaexp", "", - length_from=lambda pkt: pkt.rsaexplen)] - - @crypto_validator - def fill_missing(self): - k = PrivKeyRSA() - k.fill_and_store(modulusLen=512) - self.tls_session.server_tmp_rsa_key = k - pubNum = k.pubkey.public_numbers() - - if not self.rsamod: - self.rsamod = pkcs_i2osp(pubNum.n, k.pubkey.key_size // 8) - if self.rsamodlen is None: - self.rsamodlen = len(self.rsamod) - - rsaexplen = math.ceil(math.log(pubNum.e) / math.log(2) / 8.) - if not self.rsaexp: - self.rsaexp = pkcs_i2osp(pubNum.e, rsaexplen) - if self.rsaexplen is None: - self.rsaexplen = len(self.rsaexp) - - @crypto_validator - def register_pubkey(self): - mLen = self.rsamodlen - m = self.rsamod - e = self.rsaexp - self.tls_session.server_tmp_rsa_key = PubKeyRSA((e, m, mLen)) - - def post_dissection(self, pkt): - try: - self.register_pubkey() - except ImportError: - pass - - def guess_payload_class(self, p): - return Padding - - -# Pre-Shared Key - -class ServerPSKParams(Packet): - """ - XXX We provide some parsing abilities for ServerPSKParams, but the - context operations have not been implemented yet. See RFC 4279. - Note that we do not cover the (EC)DHE_PSK key exchange, - which should contain a Server*DHParams after 'psk_identity_hint'. - """ - name = "Server PSK parameters" - fields_desc = [FieldLenField("psk_identity_hint_len", None, - length_of="psk_identity_hint", fmt="!H"), - StrLenField("psk_identity_hint", "", - length_from=lambda pkt: pkt.psk_identity_hint_len)] # noqa: E501 - - def fill_missing(self): - pass - - def post_dissection(self, pkt): - pass - - def guess_payload_class(self, p): - return Padding - - -############################################################################### -# Client Key Exchange value # -############################################################################### - -# FFDH/ECDH - -class ClientDiffieHellmanPublic(_GenericTLSSessionInheritance): - """ - If the user provides a value for dh_Yc attribute, we assume he will set - the pms and ms accordingly and trigger the key derivation on his own. - - XXX As specified in 7.4.7.2. of RFC 4346, we should distinguish the needs - for implicit or explicit value depending on availability of DH parameters - in *client* certificate. For now we can only do ephemeral/explicit DH. - """ - name = "Client DH Public Value" - fields_desc = [FieldLenField("dh_Yclen", None, length_of="dh_Yc"), - StrLenField("dh_Yc", "", - length_from=lambda pkt: pkt.dh_Yclen)] - - @crypto_validator - def fill_missing(self): - s = self.tls_session - params = s.client_kx_ffdh_params - s.client_kx_privkey = params.generate_private_key() - pubkey = s.client_kx_privkey.public_key() - y = pubkey.public_numbers().y - self.dh_Yc = pkcs_i2osp(y, pubkey.key_size // 8) - - if s.client_kx_privkey and s.server_kx_pubkey: - pms = s.client_kx_privkey.exchange(s.server_kx_pubkey) - s.pre_master_secret = pms - s.compute_ms_and_derive_keys() - - def post_build(self, pkt, pay): - if not self.dh_Yc: - try: - self.fill_missing() - except ImportError: - pass - if self.dh_Yclen is None: - self.dh_Yclen = len(self.dh_Yc) - return pkcs_i2osp(self.dh_Yclen, 2) + self.dh_Yc + pay - - def post_dissection(self, m): - """ - First we update the client DHParams. Then, we try to update the server - DHParams generated during Server*DHParams building, with the shared - secret. Finally, we derive the session keys and update the context. - """ - s = self.tls_session - - # if there are kx params and keys, we assume the crypto library is ok - if s.client_kx_ffdh_params: - y = pkcs_os2ip(self.dh_Yc) - param_numbers = s.client_kx_ffdh_params.parameter_numbers() - public_numbers = dh.DHPublicNumbers(y, param_numbers) - s.client_kx_pubkey = public_numbers.public_key(default_backend()) - - if s.server_kx_privkey and s.client_kx_pubkey: - ZZ = s.server_kx_privkey.exchange(s.client_kx_pubkey) - s.pre_master_secret = ZZ - s.compute_ms_and_derive_keys() - - def guess_payload_class(self, p): - return Padding - - -class ClientECDiffieHellmanPublic(_GenericTLSSessionInheritance): - """ - Note that the 'len' field is 1 byte longer than with the previous class. - """ - name = "Client ECDH Public Value" - fields_desc = [FieldLenField("ecdh_Yclen", None, - length_of="ecdh_Yc", fmt="B"), - StrLenField("ecdh_Yc", "", - length_from=lambda pkt: pkt.ecdh_Yclen)] - - @crypto_validator - def fill_missing(self): - s = self.tls_session - params = s.client_kx_ecdh_params - s.client_kx_privkey = ec.generate_private_key(params, - default_backend()) - pubkey = s.client_kx_privkey.public_key() - x = pubkey.public_numbers().x - y = pubkey.public_numbers().y - self.ecdh_Yc = (b"\x04" + - pkcs_i2osp(x, params.key_size // 8) + - pkcs_i2osp(y, params.key_size // 8)) - - if s.client_kx_privkey and s.server_kx_pubkey: - pms = s.client_kx_privkey.exchange(ec.ECDH(), s.server_kx_pubkey) - s.pre_master_secret = pms - s.compute_ms_and_derive_keys() - - def post_build(self, pkt, pay): - if not self.ecdh_Yc: - try: - self.fill_missing() - except ImportError: - pass - if self.ecdh_Yclen is None: - self.ecdh_Yclen = len(self.ecdh_Yc) - return pkcs_i2osp(self.ecdh_Yclen, 1) + self.ecdh_Yc + pay - - def post_dissection(self, m): - s = self.tls_session - - # if there are kx params and keys, we assume the crypto library is ok - if s.client_kx_ecdh_params: - import_point = ec.EllipticCurvePublicNumbers.from_encoded_point - pub_num = import_point(s.client_kx_ecdh_params, self.ecdh_Yc) - s.client_kx_pubkey = pub_num.public_key(default_backend()) - - if s.server_kx_privkey and s.client_kx_pubkey: - ZZ = s.server_kx_privkey.exchange(ec.ECDH(), s.client_kx_pubkey) - s.pre_master_secret = ZZ - s.compute_ms_and_derive_keys() - - -# RSA Encryption (standard & export) - -class _UnEncryptedPreMasterSecret(Raw): - """ - When the content of an EncryptedPreMasterSecret could not be deciphered, - we use this class to represent the encrypted data. - """ - name = "RSA Encrypted PreMaster Secret (protected)" - - def __init__(self, *args, **kargs): - kargs.pop('tls_session', None) - return super(_UnEncryptedPreMasterSecret, self).__init__(*args, **kargs) # noqa: E501 - - -class EncryptedPreMasterSecret(_GenericTLSSessionInheritance): - """ - Pay attention to implementation notes in section 7.4.7.1 of RFC 5246. - """ - name = "RSA Encrypted PreMaster Secret" - fields_desc = [_TLSClientVersionField("client_version", None, - _tls_version), - StrFixedLenField("random", None, 46)] - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if 'tls_session' in kargs: - s = kargs['tls_session'] - if s.server_tmp_rsa_key is None and s.server_rsa_key is None: - return _UnEncryptedPreMasterSecret - return EncryptedPreMasterSecret - - def pre_dissect(self, m): - s = self.tls_session - tbd = m - if s.tls_version >= 0x0301: - if len(m) < 2: # Should not happen - return m - tmp_len = struct.unpack("!H", m[:2])[0] - if len(m) != tmp_len + 2: - err = "TLS 1.0+, but RSA Encrypted PMS with no explicit length" - warning(err) - else: - tbd = m[2:] - if s.server_tmp_rsa_key is not None: - # priority is given to the tmp_key, if there is one - decrypted = s.server_tmp_rsa_key.decrypt(tbd) - pms = decrypted[-48:] - elif s.server_rsa_key is not None: - decrypted = s.server_rsa_key.decrypt(tbd) - pms = decrypted[-48:] - else: - # the dispatch_hook is supposed to prevent this case - pms = b"\x00" * 48 - err = "No server RSA key to decrypt Pre Master Secret. Skipping." - warning(err) - - s.pre_master_secret = pms - s.compute_ms_and_derive_keys() - - return pms - - def post_build(self, pkt, pay): - """ - We encrypt the premaster secret (the 48 bytes) with either the server - certificate or the temporary RSA key provided in a server key exchange - message. After that step, we add the 2 bytes to provide the length, as - described in implementation notes at the end of section 7.4.7.1. - """ - enc = pkt - - s = self.tls_session - s.pre_master_secret = enc - s.compute_ms_and_derive_keys() - - if s.server_tmp_rsa_key is not None: - enc = s.server_tmp_rsa_key.encrypt(pkt, t="pkcs") - elif s.server_certs is not None and len(s.server_certs) > 0: - enc = s.server_certs[0].encrypt(pkt, t="pkcs") - else: - warning("No material to encrypt Pre Master Secret") - - tmp_len = b"" - if s.tls_version >= 0x0301: - tmp_len = struct.pack("!H", len(enc)) - return tmp_len + enc + pay - - def guess_payload_class(self, p): - return Padding - - -# Pre-Shared Key - -class ClientPSKIdentity(Packet): - """ - XXX We provide parsing abilities for ServerPSKParams, but the context - operations have not been implemented yet. See RFC 4279. - Note that we do not cover the (EC)DHE_PSK nor the RSA_PSK key exchange, - which should contain either an EncryptedPMS or a ClientDiffieHellmanPublic. - """ - name = "Server PSK parameters" - fields_desc = [FieldLenField("psk_identity_len", None, - length_of="psk_identity", fmt="!H"), - StrLenField("psk_identity", "", - length_from=lambda pkt: pkt.psk_identity_len)] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/keyexchange_tls13.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/keyexchange_tls13.py deleted file mode 100644 index c464127cf0..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/keyexchange_tls13.py +++ /dev/null @@ -1,308 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -TLS 1.3 key exchange logic. -""" - -import struct - -from scapy.config import conf, crypto_validator -from scapy.error import log_runtime -from scapy.fields import FieldLenField, IntField, PacketField, \ - PacketListField, ShortEnumField, ShortField, StrFixedLenField, \ - StrLenField -from scapy.packet import Packet, Padding -from scapy.layers.tls.extensions import TLS_Ext_Unknown, _tls_ext -from scapy.layers.tls.crypto.groups import _tls_named_ffdh_groups, \ - _tls_named_curves, _ffdh_groups, \ - _tls_named_groups -import scapy.modules.six as six - -if conf.crypto_valid: - from cryptography.hazmat.backends import default_backend - from cryptography.hazmat.primitives import serialization - from cryptography.hazmat.primitives.asymmetric import dh, ec -if conf.crypto_valid_advanced: - from cryptography.hazmat.primitives.asymmetric import x25519 - - -class KeyShareEntry(Packet): - """ - When building from scratch, we create a DH private key, and when - dissecting, we create a DH public key. Default group is secp256r1. - """ - __slots__ = ["privkey", "pubkey"] - name = "Key Share Entry" - fields_desc = [ShortEnumField("group", None, _tls_named_groups), - FieldLenField("kxlen", None, length_of="key_exchange"), - StrLenField("key_exchange", "", - length_from=lambda pkt: pkt.kxlen)] - - def __init__(self, *args, **kargs): - self.privkey = None - self.pubkey = None - super(KeyShareEntry, self).__init__(*args, **kargs) - - def do_build(self): - """ - We need this hack, else 'self' would be replaced by __iter__.next(). - """ - tmp = self.explicit - self.explicit = True - b = super(KeyShareEntry, self).do_build() - self.explicit = tmp - return b - - @crypto_validator - def create_privkey(self): - """ - This is called by post_build() for key creation. - """ - if self.group in _tls_named_ffdh_groups: - params = _ffdh_groups[_tls_named_ffdh_groups[self.group]][0] - privkey = params.generate_private_key() - self.privkey = privkey - pubkey = privkey.public_key() - self.key_exchange = pubkey.public_numbers().y - elif self.group in _tls_named_curves: - if _tls_named_curves[self.group] == "x25519": - if conf.crypto_valid_advanced: - privkey = x25519.X25519PrivateKey.generate() - self.privkey = privkey - pubkey = privkey.public_key() - self.key_exchange = pubkey.public_bytes() - elif _tls_named_curves[self.group] != "x448": - curve = ec._CURVE_TYPES[_tls_named_curves[self.group]]() - privkey = ec.generate_private_key(curve, default_backend()) - self.privkey = privkey - pubkey = privkey.public_key() - try: - # cryptography >= 2.5 - self.key_exchange = pubkey.public_bytes( - serialization.Encoding.X962, - serialization.PublicFormat.UncompressedPoint - ) - except TypeError: - # older versions - self.key_exchange = pubkey.public_numbers().encode_point() - - def post_build(self, pkt, pay): - if self.group is None: - self.group = 23 # secp256r1 - - if not self.key_exchange: - try: - self.create_privkey() - except ImportError: - pass - - if self.kxlen is None: - self.kxlen = len(self.key_exchange) - - group = struct.pack("!H", self.group) - kxlen = struct.pack("!H", self.kxlen) - return group + kxlen + self.key_exchange + pay - - @crypto_validator - def register_pubkey(self): - if self.group in _tls_named_ffdh_groups: - params = _ffdh_groups[_tls_named_ffdh_groups[self.group]][0] - pn = params.parameter_numbers() - public_numbers = dh.DHPublicNumbers(self.key_exchange, pn) - self.pubkey = public_numbers.public_key(default_backend()) - elif self.group in _tls_named_curves: - if _tls_named_curves[self.group] == "x25519": - if conf.crypto_valid_advanced: - import_point = x25519.X25519PublicKey.from_public_bytes - self.pubkey = import_point(self.key_exchange) - elif _tls_named_curves[self.group] != "x448": - curve = ec._CURVE_TYPES[_tls_named_curves[self.group]]() - import_point = ec.EllipticCurvePublicKey.from_encoded_point - public_numbers = import_point(curve, self.key_exchange).public_numbers() # noqa: E501 - self.pubkey = public_numbers.public_key(default_backend()) - - def post_dissection(self, r): - try: - self.register_pubkey() - except ImportError: - pass - - def extract_padding(self, s): - return "", s - - -class TLS_Ext_KeyShare_CH(TLS_Ext_Unknown): - name = "TLS Extension - Key Share (for ClientHello)" - fields_desc = [ShortEnumField("type", 0x33, _tls_ext), - ShortField("len", None), - FieldLenField("client_shares_len", None, - length_of="client_shares"), - PacketListField("client_shares", [], KeyShareEntry, - length_from=lambda pkt: pkt.client_shares_len)] # noqa: E501 - - def post_build(self, pkt, pay): - if not self.tls_session.frozen: - privshares = self.tls_session.tls13_client_privshares - for kse in self.client_shares: - if kse.privkey: - if _tls_named_curves[kse.group] in privshares: - pkt_info = pkt.firstlayer().summary() - log_runtime.info("TLS: group %s used twice in the same ClientHello [%s]", kse.group, pkt_info) # noqa: E501 - break - privshares[_tls_named_groups[kse.group]] = kse.privkey - return super(TLS_Ext_KeyShare_CH, self).post_build(pkt, pay) - - def post_dissection(self, r): - if not self.tls_session.frozen: - for kse in self.client_shares: - if kse.pubkey: - pubshares = self.tls_session.tls13_client_pubshares - if _tls_named_curves[kse.group] in pubshares: - pkt_info = r.firstlayer().summary() - log_runtime.info("TLS: group %s used twice in the same ClientHello [%s]", kse.group, pkt_info) # noqa: E501 - break - pubshares[_tls_named_curves[kse.group]] = kse.pubkey - return super(TLS_Ext_KeyShare_CH, self).post_dissection(r) - - -class TLS_Ext_KeyShare_HRR(TLS_Ext_Unknown): - name = "TLS Extension - Key Share (for HelloRetryRequest)" - fields_desc = [ShortEnumField("type", 0x33, _tls_ext), - ShortField("len", None), - ShortEnumField("selected_group", None, _tls_named_groups)] - - -class TLS_Ext_KeyShare_SH(TLS_Ext_Unknown): - name = "TLS Extension - Key Share (for ServerHello)" - fields_desc = [ShortEnumField("type", 0x33, _tls_ext), - ShortField("len", None), - PacketField("server_share", None, KeyShareEntry)] - - def post_build(self, pkt, pay): - if not self.tls_session.frozen and self.server_share.privkey: - # if there is a privkey, we assume the crypto library is ok - privshare = self.tls_session.tls13_server_privshare - if len(privshare) > 0: - pkt_info = pkt.firstlayer().summary() - log_runtime.info("TLS: overwriting previous server key share [%s]", pkt_info) # noqa: E501 - group_name = _tls_named_groups[self.server_share.group] - privshare[group_name] = self.server_share.privkey - - if group_name in self.tls_session.tls13_client_pubshares: - privkey = self.server_share.privkey - pubkey = self.tls_session.tls13_client_pubshares[group_name] - if group_name in six.itervalues(_tls_named_ffdh_groups): - pms = privkey.exchange(pubkey) - elif group_name in six.itervalues(_tls_named_curves): - if group_name == "x25519": - pms = privkey.exchange(pubkey) - else: - pms = privkey.exchange(ec.ECDH(), pubkey) - self.tls_session.tls13_dhe_secret = pms - return super(TLS_Ext_KeyShare_SH, self).post_build(pkt, pay) - - def post_dissection(self, r): - if not self.tls_session.frozen and self.server_share.pubkey: - # if there is a pubkey, we assume the crypto library is ok - pubshare = self.tls_session.tls13_server_pubshare - if pubshare: - pkt_info = r.firstlayer().summary() - log_runtime.info("TLS: overwriting previous server key share [%s]", pkt_info) # noqa: E501 - group_name = _tls_named_groups[self.server_share.group] - pubshare[group_name] = self.server_share.pubkey - - if group_name in self.tls_session.tls13_client_privshares: - pubkey = self.server_share.pubkey - privkey = self.tls_session.tls13_client_privshares[group_name] - if group_name in six.itervalues(_tls_named_ffdh_groups): - pms = privkey.exchange(pubkey) - elif group_name in six.itervalues(_tls_named_curves): - if group_name == "x25519": - pms = privkey.exchange(pubkey) - else: - pms = privkey.exchange(ec.ECDH(), pubkey) - self.tls_session.tls13_dhe_secret = pms - elif group_name in self.tls_session.tls13_server_privshare: - pubkey = self.tls_session.tls13_client_pubshares[group_name] - privkey = self.tls_session.tls13_server_privshare[group_name] - if group_name in six.itervalues(_tls_named_ffdh_groups): - pms = privkey.exchange(pubkey) - elif group_name in six.itervalues(_tls_named_curves): - if group_name == "x25519": - pms = privkey.exchange(pubkey) - else: - pms = privkey.exchange(ec.ECDH(), pubkey) - self.tls_session.tls13_dhe_secret = pms - return super(TLS_Ext_KeyShare_SH, self).post_dissection(r) - - -_tls_ext_keyshare_cls = {1: TLS_Ext_KeyShare_CH, - 2: TLS_Ext_KeyShare_SH} - - -class Ticket(Packet): - name = "Recommended Ticket Construction (from RFC 5077)" - fields_desc = [StrFixedLenField("key_name", None, 16), - StrFixedLenField("iv", None, 16), - FieldLenField("encstatelen", None, length_of="encstate"), - StrLenField("encstate", "", - length_from=lambda pkt: pkt.encstatelen), - StrFixedLenField("mac", None, 32)] - - -class TicketField(PacketField): - __slots__ = ["length_from"] - - def __init__(self, name, default, length_from=None, **kargs): - self.length_from = length_from - PacketField.__init__(self, name, default, Ticket, **kargs) - - def m2i(self, pkt, m): - tmp_len = self.length_from(pkt) - tbd, rem = m[:tmp_len], m[tmp_len:] - return self.cls(tbd) / Padding(rem) - - -class PSKIdentity(Packet): - name = "PSK Identity" - fields_desc = [FieldLenField("identity_len", None, - length_of="identity"), - TicketField("identity", "", - length_from=lambda pkt: pkt.identity_len), - IntField("obfuscated_ticket_age", 0)] - - -class PSKBinderEntry(Packet): - name = "PSK Binder Entry" - fields_desc = [FieldLenField("binder_len", None, fmt="B", - length_of="binder"), - StrLenField("binder", "", - length_from=lambda pkt: pkt.binder_len)] - - -class TLS_Ext_PreSharedKey_CH(TLS_Ext_Unknown): - # XXX define post_build and post_dissection methods - name = "TLS Extension - Pre Shared Key (for ClientHello)" - fields_desc = [ShortEnumField("type", 0x28, _tls_ext), - ShortField("len", None), - FieldLenField("identities_len", None, - length_of="identities"), - PacketListField("identities", [], PSKIdentity, - length_from=lambda pkt: pkt.identities_len), - FieldLenField("binders_len", None, - length_of="binders"), - PacketListField("binders", [], PSKBinderEntry, - length_from=lambda pkt: pkt.binders_len)] - - -class TLS_Ext_PreSharedKey_SH(TLS_Ext_Unknown): - name = "TLS Extension - Pre Shared Key (for ServerHello)" - fields_desc = [ShortEnumField("type", 0x29, _tls_ext), - ShortField("len", None), - ShortField("selected_identity", None)] - - -_tls_ext_presharedkey_cls = {1: TLS_Ext_PreSharedKey_CH, - 2: TLS_Ext_PreSharedKey_SH} diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/record.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/record.py deleted file mode 100644 index cde4a47791..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/record.py +++ /dev/null @@ -1,768 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -Common TLS fields & bindings. - -This module covers the record layer, along with the ChangeCipherSpec, Alert and -ApplicationData submessages. For the Handshake type, see tls_handshake.py. - -See the TLS class documentation for more information. -""" - -import struct - -from scapy.config import conf -from scapy.error import log_runtime -from scapy.fields import ByteEnumField, PacketListField, StrField -from scapy.compat import raw, chb, orb -from scapy.utils import randstring -from scapy.packet import Raw, Padding, bind_layers -from scapy.layers.inet import TCP -from scapy.layers.tls.session import _GenericTLSSessionInheritance -from scapy.layers.tls.handshake import (_tls_handshake_cls, _TLSHandshake, - _tls13_handshake_cls, TLS13ServerHello) -from scapy.layers.tls.basefields import (_TLSVersionField, _tls_version, - _TLSIVField, _TLSMACField, - _TLSPadField, _TLSPadLenField, - _TLSLengthField, _tls_type) -from scapy.layers.tls.crypto.pkcs1 import pkcs_i2osp -from scapy.layers.tls.crypto.cipher_aead import AEADTagError -from scapy.layers.tls.crypto.cipher_stream import Cipher_NULL -from scapy.layers.tls.crypto.common import CipherError -from scapy.layers.tls.crypto.h_mac import HMACError -import scapy.modules.six as six -if conf.crypto_valid_advanced: - from scapy.layers.tls.crypto.cipher_aead import Cipher_CHACHA20_POLY1305 - -# Util - - -def _tls_version_check(version, min): - """Returns if version >= min, or False if version == None""" - if version is None: - return False - return version >= min - -############################################################################### -# TLS Record Protocol # -############################################################################### - - -class _TLSEncryptedContent(Raw): - """ - When the content of a TLS record (more precisely, a TLSCiphertext) could - not be deciphered, we use this class to represent the encrypted data. - The MAC will still be parsed from the whole message, even though it could - not been verified. When present (depending on cipher type and protocol - version), the nonce_explicit, IV and/or padding will also be parsed. - """ - name = "Encrypted Content" - - -class _TLSMsgListField(PacketListField): - """ - This is the actual content of the TLS record. As a TLS record may pack - multiple sublayer messages (notably, several handshake messages), - we inherit from PacketListField. - """ - - def __init__(self, name, default, length_from=None): - if not length_from: - length_from = self._get_length - super(_TLSMsgListField, self).__init__(name, default, cls=None, - length_from=length_from) - - def _get_length(self, pkt): - if pkt.deciphered_len is None: - return pkt.len - return pkt.deciphered_len - - def m2i(self, pkt, m): - """ - Try to parse one of the TLS subprotocols (ccs, alert, handshake or - application_data). This is used inside a loop managed by .getfield(). - """ - cls = Raw - if pkt.type == 22: - if len(m) >= 1: - msgtype = orb(m[0]) - if ((pkt.tls_session.advertised_tls_version == 0x0304) or - (pkt.tls_session.tls_version and - pkt.tls_session.tls_version == 0x0304)): - cls = _tls13_handshake_cls.get(msgtype, Raw) - else: - cls = _tls_handshake_cls.get(msgtype, Raw) - - elif pkt.type == 20: - cls = TLSChangeCipherSpec - elif pkt.type == 21: - cls = TLSAlert - elif pkt.type == 23: - cls = TLSApplicationData - - if cls is Raw: - return Raw(m) - else: - try: - return cls(m, tls_session=pkt.tls_session) - except Exception: - if conf.debug_dissector: - raise - return Raw(m) - - def getfield(self, pkt, s): - """ - If the decryption of the content did not fail with a CipherError, - we begin a loop on the clear content in order to get as much messages - as possible, of the type advertised in the record header. This is - notably important for several TLS handshake implementations, which - may for instance pack a server_hello, a certificate, a - server_key_exchange and a server_hello_done, all in one record. - Each parsed message may update the TLS context through their method - .post_dissection_tls_session_update(). - - If the decryption failed with a CipherError, presumably because we - missed the session keys, we signal it by returning a - _TLSEncryptedContent packet which simply contains the ciphered data. - """ - tmp_len = self.length_from(pkt) - lst = [] - ret = b"" - remain = s - if tmp_len is not None: - remain, ret = s[:tmp_len], s[tmp_len:] - - if remain == b"": - if (((pkt.tls_session.tls_version or 0x0303) > 0x0200) and - hasattr(pkt, "type") and pkt.type == 23): - return ret, [TLSApplicationData(data=b"")] - else: - return ret, [Raw(load=b"")] - - if False in six.itervalues(pkt.tls_session.rcs.cipher.ready): - return ret, _TLSEncryptedContent(remain) - else: - while remain: - raw_msg = remain - p = self.m2i(pkt, remain) - if Padding in p: - pad = p[Padding] - remain = pad.load - del pad.underlayer.payload - if len(remain) != 0: - raw_msg = raw_msg[:-len(remain)] - else: - remain = b"" - - if isinstance(p, _GenericTLSSessionInheritance): - if not p.tls_session.frozen: - p.post_dissection_tls_session_update(raw_msg) - - lst.append(p) - return remain + ret, lst - - def i2m(self, pkt, p): - """ - Update the context with information from the built packet. - If no type was given at the record layer, we try to infer it. - """ - cur = b"" - if isinstance(p, _GenericTLSSessionInheritance): - if pkt.type is None: - if isinstance(p, TLSChangeCipherSpec): - pkt.type = 20 - elif isinstance(p, TLSAlert): - pkt.type = 21 - elif isinstance(p, _TLSHandshake): - pkt.type = 22 - elif isinstance(p, TLSApplicationData): - pkt.type = 23 - p.tls_session = pkt.tls_session - if not pkt.tls_session.frozen: - cur = p.raw_stateful() - p.post_build_tls_session_update(cur) - else: - cur = raw(p) - else: - pkt.type = 23 - cur = raw(p) - return cur - - def addfield(self, pkt, s, val): - """ - Reconstruct the header because the TLS type may have been updated. - Then, append the content. - """ - res = b"" - for p in val: - res += self.i2m(pkt, p) - if (isinstance(pkt, _GenericTLSSessionInheritance) and - _tls_version_check(pkt.tls_session.tls_version, 0x0304) and - not isinstance(pkt, TLS13ServerHello)): - return s + res - if not pkt.type: - pkt.type = 0 - hdr = struct.pack("!B", pkt.type) + s[1:5] - return hdr + res - - -class TLS(_GenericTLSSessionInheritance): - """ - The generic TLS Record message, based on section 6.2 of RFC 5246. - - When reading a TLS message, we try to parse as much as we can. - In .pre_dissect(), according to the type of the current cipher algorithm - (self.tls_session.rcs.cipher.type), we extract the 'iv', 'mac', 'pad' and - 'padlen'. Some of these fields may remain blank: for instance, when using - a stream cipher, there is no IV nor any padding. The 'len' should always - hold the length of the ciphered message; for the plaintext version, you - should rely on the additional 'deciphered_len' attribute. - - XXX Fix 'deciphered_len' which should not be defined when failing with - AEAD decryption. This is related to the 'decryption_success' below. - Also, follow this behaviour in record_sslv2.py and record_tls13.py - - Once we have isolated the ciphered message aggregate (which should be one - or several TLS messages of the same type), we try to decipher it. Either we - succeed and store the clear data in 'msg', or we graciously fail with a - CipherError and store the ciphered data in 'msg'. - - Unless the user manually provides the session secrets through the passing - of a 'tls_session', obviously the ciphered messages will not be deciphered. - Indeed, the need for a proper context may also present itself when trying - to parse clear handshake messages. - - For instance, suppose you sniffed the beginning of a DHE-RSA negotiation: - t1 = TLS() - t2 = TLS() - t3 = TLS(, - tls_session=t1.tls_session) - (Note that to do things properly, here 't1.tls_session' should actually be - 't1.tls_session.mirror()'. See session.py for explanations.) - - As no context was passed to t2, neither was any client_random. Hence Scapy - will not be able to verify the signature of the server_key_exchange inside - t2. However, it should be able to do so for t3, thanks to the tls_session. - The consequence of not having a complete TLS context is even more obvious - when trying to parse ciphered content, as we described before. - - Thus, in order to parse TLS-protected communications with Scapy: - _either Scapy reads every message from one side of the TLS connection and - builds every message from the other side (as such, it should know the - secrets needed for the generation of the pre_master_secret), while passing - the same tls_session context (this is how our automaton.py mostly works); - _or, if Scapy did not build any TLS message, it has to create a TLS context - and feed it with secrets retrieved by whatever technique. Note that the - knowing the private key of the server certificate will not be sufficient - if a PFS ciphersuite was used. However, if you got a master_secret somehow, - use it with tls_session.(w|r)cs.derive_keys() and leave the rest to Scapy. - - When building a TLS message with raw_stateful, we expect the tls_session to - have the right parameters for ciphering. Else, .post_build() might fail. - """ - __slots__ = ["deciphered_len"] - name = "TLS" - fields_desc = [ByteEnumField("type", None, _tls_type), - _TLSVersionField("version", None, _tls_version), - _TLSLengthField("len", None), - _TLSIVField("iv", None), - _TLSMsgListField("msg", []), - _TLSMACField("mac", None), - _TLSPadField("pad", None), - _TLSPadLenField("padlen", None)] - - def __init__(self, *args, **kargs): - self.deciphered_len = kargs.get("deciphered_len", None) - super(TLS, self).__init__(*args, **kargs) - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - """ - If the TLS class was called on raw SSLv2 data, we want to return an - SSLv2 record instance. We acknowledge the risk of SSLv2 packets with a - msglen of 0x1403, 0x1503, 0x1603 or 0x1703 which will never be casted - as SSLv2 records but TLS ones instead, but hey, we can't be held - responsible for low-minded extensibility choices. - """ - if _pkt and len(_pkt) >= 2: - byte0 = orb(_pkt[0]) - byte1 = orb(_pkt[1]) - if (byte0 not in _tls_type) or (byte1 != 3): - from scapy.layers.tls.record_sslv2 import SSLv2 - return SSLv2 - else: - s = kargs.get("tls_session", None) - if s and _tls_version_check(s.tls_version, 0x0304): - if s.rcs and not isinstance(s.rcs.cipher, Cipher_NULL): - from scapy.layers.tls.record_tls13 import TLS13 - return TLS13 - if _pkt and len(_pkt) < 5: - # Layer detected as TLS but too small to be a real packet (len<5). - # Those packets are usually customly implemented - # Scapy should not try to decode them - return conf.raw_layer - return TLS - - # Parsing methods - - def _tls_auth_decrypt(self, hdr, s): - """ - Provided with the record header and AEAD-ciphered data, return the - sliced and clear tuple (nonce, TLSCompressed.fragment, mac). Note that - we still return the slicing of the original input in case of decryption - failure. Also, if the integrity check fails, a warning will be issued, - but we still return the sliced (unauthenticated) plaintext. - """ - try: - read_seq_num = struct.pack("!Q", self.tls_session.rcs.seq_num) - self.tls_session.rcs.seq_num += 1 - # self.type and self.version have not been parsed yet, - # this is why we need to look into the provided hdr. - add_data = read_seq_num + hdr[:3] - # Last two bytes of add_data are appended by the return function - return self.tls_session.rcs.cipher.auth_decrypt(add_data, s, - read_seq_num) - except CipherError as e: - return e.args - except AEADTagError as e: - pkt_info = self.firstlayer().summary() - log_runtime.info("TLS: record integrity check failed [%s]", pkt_info) # noqa: E501 - return e.args - - def _tls_decrypt(self, s): - """ - Provided with stream- or block-ciphered data, return the clear version. - The cipher should have been updated with the right IV early on, - which should not be at the beginning of the input. - In case of decryption failure, a CipherError will be raised with - the slicing of the original input as first argument. - """ - return self.tls_session.rcs.cipher.decrypt(s) - - def _tls_hmac_verify(self, hdr, msg, mac): - """ - Provided with the record header, the TLSCompressed.fragment and the - HMAC, return True if the HMAC is correct. If we could not compute the - HMAC because the key was missing, there is no sense in verifying - anything, thus we also return True. - - Meant to be used with a block cipher or a stream cipher. - It would fail with an AEAD cipher, because rcs.hmac would be None. - See RFC 5246, section 6.2.3. - """ - read_seq_num = struct.pack("!Q", self.tls_session.rcs.seq_num) - self.tls_session.rcs.seq_num += 1 - - mac_len = self.tls_session.rcs.mac_len - if mac_len == 0: # should be TLS_NULL_WITH_NULL_NULL - return True - if len(mac) != mac_len: - return False - - alg = self.tls_session.rcs.hmac - version = struct.unpack("!H", hdr[1:3])[0] - try: - if version > 0x300: - h = alg.digest(read_seq_num + hdr + msg) - elif version == 0x300: - h = alg.digest_sslv3(read_seq_num + hdr[:1] + hdr[3:5] + msg) - else: - raise Exception("Unrecognized version.") - except HMACError: - h = mac - return h == mac - - def _tls_decompress(self, s): - """ - Provided with the TLSCompressed.fragment, - return the TLSPlaintext.fragment. - """ - alg = self.tls_session.rcs.compression - return alg.decompress(s) - - def pre_dissect(self, s): - """ - Decrypt, verify and decompress the message, - i.e. apply the previous methods according to the reading cipher type. - If the decryption was successful, 'len' will be the length of the - TLSPlaintext.fragment. Else, it should be the length of the - _TLSEncryptedContent. - """ - if len(s) < 5: - raise Exception("Invalid record: header is too short.") - - msglen = struct.unpack('!H', s[3:5])[0] - hdr, efrag, r = s[:5], s[5:5 + msglen], s[msglen + 5:] - - iv = mac = pad = b"" - self.padlen = None - decryption_success = False - - cipher_type = self.tls_session.rcs.cipher.type - - if cipher_type == 'block': - version = struct.unpack("!H", s[1:3])[0] - - # Decrypt - try: - if version >= 0x0302: - # Explicit IV for TLS 1.1 and 1.2 - block_size = self.tls_session.rcs.cipher.block_size - iv, efrag = efrag[:block_size], efrag[block_size:] - self.tls_session.rcs.cipher.iv = iv - pfrag = self._tls_decrypt(efrag) - else: - # Implicit IV for SSLv3 and TLS 1.0 - pfrag = self._tls_decrypt(efrag) - except CipherError as e: - # This will end up dissected as _TLSEncryptedContent. - cfrag = e.args[0] - else: - decryption_success = True - # Excerpt below better corresponds to TLS 1.1 IV definition, - # but the result is the same as with TLS 1.2 anyway. - # This leading *IV* has been decrypted by _tls_decrypt with a - # random IV, hence it does not correspond to anything. - # What actually matters is that we got the first encrypted block # noqa: E501 - # in order to decrypt the second block (first data block). - # if version >= 0x0302: - # block_size = self.tls_session.rcs.cipher.block_size - # iv, pfrag = pfrag[:block_size], pfrag[block_size:] - # l = struct.unpack('!H', hdr[3:5])[0] - # hdr = hdr[:3] + struct.pack('!H', l-block_size) - - # Extract padding ('pad' actually includes the trailing padlen) - padlen = orb(pfrag[-1]) + 1 - mfrag, pad = pfrag[:-padlen], pfrag[-padlen:] - self.padlen = padlen - - # Extract MAC - tmp_len = self.tls_session.rcs.mac_len - if tmp_len != 0: - cfrag, mac = mfrag[:-tmp_len], mfrag[-tmp_len:] - else: - cfrag, mac = mfrag, b"" - - # Verify integrity - chdr = hdr[:3] + struct.pack('!H', len(cfrag)) - is_mac_ok = self._tls_hmac_verify(chdr, cfrag, mac) - if not is_mac_ok: - pkt_info = self.firstlayer().summary() - log_runtime.info("TLS: record integrity check failed [%s]", pkt_info) # noqa: E501 - - elif cipher_type == 'stream': - # Decrypt - try: - pfrag = self._tls_decrypt(efrag) - except CipherError as e: - # This will end up dissected as _TLSEncryptedContent. - cfrag = e.args[0] - else: - decryption_success = True - mfrag = pfrag - - # Extract MAC - tmp_len = self.tls_session.rcs.mac_len - if tmp_len != 0: - cfrag, mac = mfrag[:-tmp_len], mfrag[-tmp_len:] - else: - cfrag, mac = mfrag, b"" - - # Verify integrity - chdr = hdr[:3] + struct.pack('!H', len(cfrag)) - is_mac_ok = self._tls_hmac_verify(chdr, cfrag, mac) - if not is_mac_ok: - pkt_info = self.firstlayer().summary() - log_runtime.info("TLS: record integrity check failed [%s]", pkt_info) # noqa: E501 - - elif cipher_type == 'aead': - # Authenticated encryption - # crypto/cipher_aead.py prints a warning for integrity failure - if (conf.crypto_valid_advanced and - isinstance(self.tls_session.rcs.cipher, Cipher_CHACHA20_POLY1305)): # noqa: E501 - iv = b"" - cfrag, mac = self._tls_auth_decrypt(hdr, efrag) - else: - iv, cfrag, mac = self._tls_auth_decrypt(hdr, efrag) - decryption_success = True # see XXX above - - frag = self._tls_decompress(cfrag) - - if decryption_success: - self.deciphered_len = len(frag) - else: - self.deciphered_len = None - - reconstructed_body = iv + frag + mac + pad - - return hdr + reconstructed_body + r - - def post_dissect(self, s): - """ - Commit the pending r/w state if it has been triggered (e.g. by an - underlying TLSChangeCipherSpec or a SSLv2ClientMasterKey). We update - nothing if the prcs was not set, as this probably means that we're - working out-of-context (and we need to keep the default rcs). - """ - if (self.tls_session.tls_version and - self.tls_session.tls_version <= 0x0303): - if self.tls_session.triggered_prcs_commit: - if self.tls_session.prcs is not None: - self.tls_session.rcs = self.tls_session.prcs - self.tls_session.prcs = None - self.tls_session.triggered_prcs_commit = False - if self.tls_session.triggered_pwcs_commit: - if self.tls_session.pwcs is not None: - self.tls_session.wcs = self.tls_session.pwcs - self.tls_session.pwcs = None - self.tls_session.triggered_pwcs_commit = False - return s - - def do_dissect_payload(self, s): - """ - Try to dissect the following data as a TLS message. - Note that overloading .guess_payload_class() would not be enough, - as the TLS session to be used would get lost. - """ - if s: - try: - p = TLS(s, _internal=1, _underlayer=self, - tls_session=self.tls_session) - except KeyboardInterrupt: - raise - except Exception: - p = conf.raw_layer(s, _internal=1, _underlayer=self) - self.add_payload(p) - - # Building methods - - def _tls_compress(self, s): - """ - Provided with the TLSPlaintext.fragment, - return the TLSCompressed.fragment. - """ - alg = self.tls_session.wcs.compression - return alg.compress(s) - - def _tls_auth_encrypt(self, s): - """ - Return the TLSCiphertext.fragment for AEAD ciphers, i.e. the whole - GenericAEADCipher. Also, the additional data is computed right here. - """ - write_seq_num = struct.pack("!Q", self.tls_session.wcs.seq_num) - self.tls_session.wcs.seq_num += 1 - add_data = (write_seq_num + - pkcs_i2osp(self.type, 1) + - pkcs_i2osp(self.version, 2) + - pkcs_i2osp(len(s), 2)) - return self.tls_session.wcs.cipher.auth_encrypt(s, add_data, - write_seq_num) - - def _tls_hmac_add(self, hdr, msg): - """ - Provided with the record header (concatenation of the TLSCompressed - type, version and length fields) and the TLSCompressed.fragment, - return the concatenation of the TLSCompressed.fragment and the HMAC. - - Meant to be used with a block cipher or a stream cipher. - It would fail with an AEAD cipher, because wcs.hmac would be None. - See RFC 5246, section 6.2.3. - """ - write_seq_num = struct.pack("!Q", self.tls_session.wcs.seq_num) - self.tls_session.wcs.seq_num += 1 - - alg = self.tls_session.wcs.hmac - version = struct.unpack("!H", hdr[1:3])[0] - if version > 0x300: - h = alg.digest(write_seq_num + hdr + msg) - elif version == 0x300: - h = alg.digest_sslv3(write_seq_num + hdr[:1] + hdr[3:5] + msg) - else: - raise Exception("Unrecognized version.") - return msg + h - - def _tls_pad(self, s): - """ - Provided with the concatenation of the TLSCompressed.fragment and the - HMAC, append the right padding and return it as a whole. - This is the TLS-style padding: while SSL allowed for random padding, - TLS (misguidedly) specifies the repetition of the same byte all over, - and this byte must be equal to len() - 1. - - Meant to be used with a block cipher only. - """ - padding = b"" - block_size = self.tls_session.wcs.cipher.block_size - padlen = block_size - ((len(s) + 1) % block_size) - if padlen == block_size: - padlen = 0 - pad_pattern = chb(padlen) - padding = pad_pattern * (padlen + 1) - return s + padding - - def _tls_encrypt(self, s): - """ - Return the stream- or block-ciphered version of the concatenated input. - In case of GenericBlockCipher, no IV has been specifically prepended to - the output, so this might not be the whole TLSCiphertext.fragment yet. - """ - return self.tls_session.wcs.cipher.encrypt(s) - - def post_build(self, pkt, pay): - """ - Apply the previous methods according to the writing cipher type. - """ - # Compute the length of TLSPlaintext fragment - hdr, frag = pkt[:5], pkt[5:] - tmp_len = len(frag) - hdr = hdr[:3] + struct.pack("!H", tmp_len) - - # Compression - cfrag = self._tls_compress(frag) - tmp_len = len(cfrag) # Update the length as a result of compression - hdr = hdr[:3] + struct.pack("!H", tmp_len) - - cipher_type = self.tls_session.wcs.cipher.type - - if cipher_type == 'block': - # Integrity - mfrag = self._tls_hmac_add(hdr, cfrag) - - # Excerpt below better corresponds to TLS 1.1 IV definition, - # but the result is the same as with TLS 1.2 anyway. - # if self.version >= 0x0302: - # l = self.tls_session.wcs.cipher.block_size - # iv = randstring(l) - # mfrag = iv + mfrag - - # Add padding - pfrag = self._tls_pad(mfrag) - - # Encryption - if self.version >= 0x0302: - # Explicit IV for TLS 1.1 and 1.2 - tmp_len = self.tls_session.wcs.cipher.block_size - iv = randstring(tmp_len) - self.tls_session.wcs.cipher.iv = iv - efrag = self._tls_encrypt(pfrag) - efrag = iv + efrag - else: - # Implicit IV for SSLv3 and TLS 1.0 - efrag = self._tls_encrypt(pfrag) - - elif cipher_type == "stream": - # Integrity - mfrag = self._tls_hmac_add(hdr, cfrag) - # Encryption - efrag = self._tls_encrypt(mfrag) - - elif cipher_type == "aead": - # Authenticated encryption (with nonce_explicit as header) - efrag = self._tls_auth_encrypt(cfrag) - - if self.len is not None: - # The user gave us a 'len', let's respect this ultimately - hdr = hdr[:3] + struct.pack("!H", self.len) - else: - # Update header with the length of TLSCiphertext.fragment - hdr = hdr[:3] + struct.pack("!H", len(efrag)) - - # Now we commit the pending write state if it has been triggered (e.g. - # by an underlying TLSChangeCipherSpec or a SSLv2ClientMasterKey). We - # update nothing if the pwcs was not set. This probably means that - # we're working out-of-context (and we need to keep the default wcs). - if self.tls_session.triggered_pwcs_commit: - if self.tls_session.pwcs is not None: - self.tls_session.wcs = self.tls_session.pwcs - self.tls_session.pwcs = None - self.tls_session.triggered_pwcs_commit = False - - return hdr + efrag + pay - - -############################################################################### -# TLS ChangeCipherSpec # -############################################################################### - -_tls_changecipherspec_type = {1: "change_cipher_spec"} - - -class TLSChangeCipherSpec(_GenericTLSSessionInheritance): - """ - Note that, as they are not handshake messages, the ccs messages do not get - appended to the list of messages whose integrity gets verified through the - Finished messages. - """ - name = "TLS ChangeCipherSpec" - fields_desc = [ByteEnumField("msgtype", 1, _tls_changecipherspec_type)] - - def post_dissection_tls_session_update(self, msg_str): - self.tls_session.triggered_prcs_commit = True - - def post_build_tls_session_update(self, msg_str): - # Unlike for dissection case, we cannot commit pending write - # state as current write state. We need to delay this after - # the ChangeCipherSpec message has indeed been sent - self.tls_session.triggered_pwcs_commit = True - - -############################################################################### -# TLS Alert # -############################################################################### - -_tls_alert_level = {1: "warning", 2: "fatal"} - -_tls_alert_description = { - 0: "close_notify", 10: "unexpected_message", - 20: "bad_record_mac", 21: "decryption_failed", - 22: "record_overflow", 30: "decompression_failure", - 40: "handshake_failure", 41: "no_certificate_RESERVED", - 42: "bad_certificate", 43: "unsupported_certificate", - 44: "certificate_revoked", 45: "certificate_expired", - 46: "certificate_unknown", 47: "illegal_parameter", - 48: "unknown_ca", 49: "access_denied", - 50: "decode_error", 51: "decrypt_error", - 60: "export_restriction_RESERVED", 70: "protocol_version", - 71: "insufficient_security", 80: "internal_error", - 90: "user_canceled", 100: "no_renegotiation", - 110: "unsupported_extension", 111: "certificate_unobtainable", - 112: "unrecognized_name", 113: "bad_certificate_status_response", - 114: "bad_certificate_hash_value", 115: "unknown_psk_identity"} - - -class TLSAlert(_GenericTLSSessionInheritance): - name = "TLS Alert" - fields_desc = [ByteEnumField("level", None, _tls_alert_level), - ByteEnumField("descr", None, _tls_alert_description)] - - def post_dissection_tls_session_update(self, msg_str): - pass - - def post_build_tls_session_update(self, msg_str): - pass - - -############################################################################### -# TLS Application Data # -############################################################################### - -class TLSApplicationData(_GenericTLSSessionInheritance): - name = "TLS Application Data" - fields_desc = [StrField("data", "")] - - def post_dissection_tls_session_update(self, msg_str): - pass - - def post_build_tls_session_update(self, msg_str): - pass - - -############################################################################### -# Bindings # -############################################################################### - -bind_layers(TCP, TLS, sport=443) -bind_layers(TCP, TLS, dport=443) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/record_sslv2.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/record_sslv2.py deleted file mode 100644 index 501fbd4a1c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/record_sslv2.py +++ /dev/null @@ -1,270 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -SSLv2 Record. -""" - -import struct - -from scapy.config import conf -from scapy.error import log_runtime -from scapy.compat import orb, raw -from scapy.packet import Raw -from scapy.layers.tls.session import _GenericTLSSessionInheritance -from scapy.layers.tls.record import _TLSMsgListField, TLS -from scapy.layers.tls.handshake_sslv2 import _sslv2_handshake_cls -from scapy.layers.tls.basefields import (_SSLv2LengthField, _SSLv2PadField, - _SSLv2PadLenField, _TLSMACField) - - -############################################################################### -# SSLv2 Record Protocol # -############################################################################### - -class _SSLv2MsgListField(_TLSMsgListField): - def __init__(self, name, default, length_from=None): - if not length_from: - length_from = lambda pkt: ((pkt.len & 0x7fff) - - (pkt.padlen or 0) - - len(pkt.mac)) - super(_SSLv2MsgListField, self).__init__(name, default, length_from) - - def m2i(self, pkt, m): - cls = Raw - if len(m) >= 1: - msgtype = orb(m[0]) - cls = _sslv2_handshake_cls.get(msgtype, Raw) - - if cls is Raw: - return Raw(m) - else: - return cls(m, tls_session=pkt.tls_session) - - def i2m(self, pkt, p): - cur = b"" - if isinstance(p, _GenericTLSSessionInheritance): - p.tls_session = pkt.tls_session - if not pkt.tls_session.frozen: - cur = p.raw_stateful() - p.post_build_tls_session_update(cur) - else: - cur = raw(p) - else: - cur = raw(p) - return cur - - def addfield(self, pkt, s, val): - res = b"" - for p in val: - res += self.i2m(pkt, p) - return s + res - - -class SSLv2(TLS): - """ - The encrypted_data is the encrypted version of mac+msg+pad. - """ - __slots__ = ["with_padding", "protected_record"] - name = "SSLv2" - fields_desc = [_SSLv2LengthField("len", None), - _SSLv2PadLenField("padlen", None), - _TLSMACField("mac", b""), - _SSLv2MsgListField("msg", []), - _SSLv2PadField("pad", "")] - - def __init__(self, *args, **kargs): - self.with_padding = kargs.get("with_padding", False) - self.protected_record = kargs.get("protected_record", None) - super(SSLv2, self).__init__(*args, **kargs) - - # Parsing methods - - def _sslv2_mac_verify(self, msg, mac): - secret = self.tls_session.rcs.cipher.key - if secret is None: - return True - - mac_len = self.tls_session.rcs.mac_len - if mac_len == 0: # should be TLS_NULL_WITH_NULL_NULL - return True - if len(mac) != mac_len: - return False - - read_seq_num = struct.pack("!I", self.tls_session.rcs.seq_num) - alg = self.tls_session.rcs.hash - h = alg.digest(secret + msg + read_seq_num) - return h == mac - - def pre_dissect(self, s): - if len(s) < 2: - raise Exception("Invalid record: header is too short.") - - msglen = struct.unpack("!H", s[:2])[0] - if msglen & 0x8000: - hdrlen = 2 - msglen_clean = msglen & 0x7fff - else: - hdrlen = 3 - msglen_clean = msglen & 0x3fff - - hdr = s[:hdrlen] - efrag = s[hdrlen:hdrlen + msglen_clean] - self.protected_record = s[:hdrlen + msglen_clean] - r = s[hdrlen + msglen_clean:] - - mac = pad = b"" - - # Decrypt (with implicit IV if block cipher) - mfrag = self._tls_decrypt(efrag) - - # Extract MAC - maclen = self.tls_session.rcs.mac_len - if maclen == 0: - mac, pfrag = b"", mfrag - else: - mac, pfrag = mfrag[:maclen], mfrag[maclen:] - - # Extract padding - padlen = 0 - if hdrlen == 3: - padlen = orb(s[2]) - if padlen == 0: - cfrag, pad = pfrag, b"" - else: - cfrag, pad = pfrag[:-padlen], pfrag[-padlen:] - - # Verify integrity - is_mac_ok = self._sslv2_mac_verify(cfrag + pad, mac) - if not is_mac_ok: - pkt_info = self.firstlayer().summary() - log_runtime.info("TLS: record integrity check failed [%s]", pkt_info) # noqa: E501 - - reconstructed_body = mac + cfrag + pad - return hdr + reconstructed_body + r - - def post_dissect(self, s): - """ - SSLv2 may force us to commit the write connState here. - """ - if self.tls_session.triggered_prcs_commit: - if self.tls_session.prcs is not None: - self.tls_session.rcs = self.tls_session.prcs - self.tls_session.prcs = None - self.tls_session.triggered_prcs_commit = False - if self.tls_session.triggered_pwcs_commit: - if self.tls_session.pwcs is not None: - self.tls_session.wcs = self.tls_session.pwcs - self.tls_session.pwcs = None - self.tls_session.triggered_pwcs_commit = False - - if self.tls_session.prcs is not None: - self.tls_session.prcs.seq_num += 1 - self.tls_session.rcs.seq_num += 1 - return s - - def do_dissect_payload(self, s): - if s: - try: - p = SSLv2(s, _internal=1, _underlayer=self, - tls_session=self.tls_session) - except KeyboardInterrupt: - raise - except Exception: - if conf.debug_dissect: - raise - p = conf.raw_layer(s, _internal=1, _underlayer=self) - self.add_payload(p) - - # Building methods - - def _sslv2_mac_add(self, msg): - secret = self.tls_session.wcs.cipher.key - if secret is None: - return msg - - write_seq_num = struct.pack("!I", self.tls_session.wcs.seq_num) - alg = self.tls_session.wcs.hash - h = alg.digest(secret + msg + write_seq_num) - return h + msg - - def _sslv2_pad(self, s): - padding = b"" - block_size = self.tls_session.wcs.cipher.block_size - padlen = block_size - (len(s) % block_size) - if padlen == block_size: - padlen = 0 - padding = b"\x00" * padlen - return s + padding - - def post_build(self, pkt, pay): - if self.protected_record is not None: - # we do not update the tls_session - return self.protected_record + pay - - if self.padlen is None: - cfrag = pkt[2:] - else: - cfrag = pkt[3:] - - if self.pad == b"" and self.tls_session.wcs.cipher.type == 'block': - pfrag = self._sslv2_pad(cfrag) - else: - pad = self.pad or b"" - pfrag = cfrag + pad - - padlen = self.padlen - if padlen is None: - padlen = len(pfrag) - len(cfrag) - hdr = pkt[:2] - if padlen > 0: - hdr += struct.pack("B", padlen) - - # Integrity - if self.mac == b"": - mfrag = self._sslv2_mac_add(pfrag) - else: - mfrag = self.mac + pfrag - - # Encryption - efrag = self._tls_encrypt(mfrag) - - if self.len is not None: - tmp_len = self.len - if not self.with_padding: - tmp_len |= 0x8000 - hdr = struct.pack("!H", tmp_len) + hdr[2:] - else: - # Update header with the length of TLSCiphertext.fragment - msglen_new = len(efrag) - if padlen: - if msglen_new > 0x3fff: - raise Exception("Invalid record: encrypted data too long.") - else: - if msglen_new > 0x7fff: - raise Exception("Invalid record: encrypted data too long.") - msglen_new |= 0x8000 - hdr = struct.pack("!H", msglen_new) + hdr[2:] - - # Now we commit the pending write state if it has been triggered (e.g. - # by an underlying TLSChangeCipherSpec or a SSLv2ClientMasterKey). We - # update nothing if the pwcs was not set. This probably means that - # we're working out-of-context (and we need to keep the default wcs). - # SSLv2 may force us to commit the reading connState here. - if self.tls_session.triggered_pwcs_commit: - if self.tls_session.pwcs is not None: - self.tls_session.wcs = self.tls_session.pwcs - self.tls_session.pwcs = None - self.tls_session.triggered_pwcs_commit = False - if self.tls_session.triggered_prcs_commit: - if self.tls_session.prcs is not None: - self.tls_session.rcs = self.tls_session.prcs - self.tls_session.prcs = None - self.tls_session.triggered_prcs_commit = False - - if self.tls_session.pwcs is not None: - self.tls_session.pwcs.seq_num += 1 - self.tls_session.wcs.seq_num += 1 - - return hdr + efrag + pay diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/record_tls13.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/record_tls13.py deleted file mode 100644 index 7e2211092e..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/record_tls13.py +++ /dev/null @@ -1,223 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -Common TLS 1.3 fields & bindings. - -This module covers the record layer, along with the ChangeCipherSpec, Alert and -ApplicationData submessages. For the Handshake type, see tls_handshake.py. - -See the TLS class documentation for more information. -""" - -import struct - -from scapy.config import conf -from scapy.error import log_runtime, warning -from scapy.compat import raw, orb -from scapy.fields import ByteEnumField, PacketField, XStrField -from scapy.layers.tls.session import _GenericTLSSessionInheritance -from scapy.layers.tls.basefields import _TLSVersionField, _tls_version, \ - _TLSMACField, _TLSLengthField, _tls_type -from scapy.layers.tls.record import _TLSMsgListField, TLS -from scapy.layers.tls.crypto.cipher_aead import AEADTagError -from scapy.layers.tls.crypto.cipher_stream import Cipher_NULL -from scapy.layers.tls.crypto.common import CipherError -from scapy.layers.tls.crypto.pkcs1 import pkcs_i2osp - - -############################################################################### -# TLS Record Protocol # -############################################################################### - - -class TLSInnerPlaintext(_GenericTLSSessionInheritance): - name = "TLS Inner Plaintext" - fields_desc = [_TLSMsgListField("msg", []), - ByteEnumField("type", None, _tls_type), - XStrField("pad", "")] - - def pre_dissect(self, s): - """ - We need to parse the padding and type as soon as possible, - else we won't be able to parse the message list... - """ - if len(s) < 1: - raise Exception("Invalid InnerPlaintext (too short).") - - tmp_len = len(s) - 1 - if s[-1] != b"\x00": - msg_len = tmp_len - else: - n = 1 - while s[-n] != b"\x00" and n < tmp_len: - n += 1 - msg_len = tmp_len - n - self.fields_desc[0].length_from = lambda pkt: msg_len - - self.type = struct.unpack("B", s[msg_len:msg_len + 1])[0] - - return s - - -class _TLSInnerPlaintextField(PacketField): - def __init__(self, name, default, *args, **kargs): - super(_TLSInnerPlaintextField, self).__init__(name, - default, - TLSInnerPlaintext) - - def m2i(self, pkt, m): - return self.cls(m, tls_session=pkt.tls_session) - - def getfield(self, pkt, s): - tag_len = pkt.tls_session.rcs.mac_len - frag_len = pkt.len - tag_len - if frag_len < 1: - warning("InnerPlaintext should at least contain a byte type!") - return s, None - remain, i = super(_TLSInnerPlaintextField, self).getfield(pkt, s[:frag_len]) # noqa: E501 - # remain should be empty here - return remain + s[frag_len:], i - - def i2m(self, pkt, p): - if isinstance(p, _GenericTLSSessionInheritance): - p.tls_session = pkt.tls_session - if not pkt.tls_session.frozen: - return p.raw_stateful() - return raw(p) - - -class TLS13(_GenericTLSSessionInheritance): - __slots__ = ["deciphered_len"] - name = "TLS 1.3" - fields_desc = [ByteEnumField("type", 0x17, _tls_type), - _TLSVersionField("version", 0x0303, _tls_version), - _TLSLengthField("len", None), - _TLSInnerPlaintextField("inner", TLSInnerPlaintext()), - _TLSMACField("auth_tag", None)] - - def __init__(self, *args, **kargs): - self.deciphered_len = kargs.get("deciphered_len", None) - super(TLS13, self).__init__(*args, **kargs) - - # Parsing methods - - def _tls_auth_decrypt(self, s): - """ - Provided with the record header and AEAD-ciphered data, return the - sliced and clear tuple (TLSInnerPlaintext, tag). Note that - we still return the slicing of the original input in case of decryption - failure. Also, if the integrity check fails, a warning will be issued, - but we still return the sliced (unauthenticated) plaintext. - """ - rcs = self.tls_session.rcs - read_seq_num = struct.pack("!Q", rcs.seq_num) - rcs.seq_num += 1 - add_data = (pkcs_i2osp(self.type, 1) + - pkcs_i2osp(self.version, 2) + - pkcs_i2osp(len(s), 2)) - try: - return rcs.cipher.auth_decrypt(add_data, s, read_seq_num) - except CipherError as e: - return e.args - except AEADTagError as e: - pkt_info = self.firstlayer().summary() - log_runtime.info("TLS: record integrity check failed [%s]", pkt_info) # noqa: E501 - return e.args - - def pre_dissect(self, s): - """ - Decrypt, verify and decompress the message. - """ - # We commit the pending read state if it has been triggered. - if self.tls_session.triggered_prcs_commit: - if self.tls_session.prcs is not None: - self.tls_session.rcs = self.tls_session.prcs - self.tls_session.prcs = None - self.tls_session.triggered_prcs_commit = False - if len(s) < 5: - raise Exception("Invalid record: header is too short.") - - self.type = orb(s[0]) - if (isinstance(self.tls_session.rcs.cipher, Cipher_NULL) or - self.type == 0x14): - self.deciphered_len = None - return s - else: - msglen = struct.unpack('!H', s[3:5])[0] - hdr, efrag, r = s[:5], s[5:5 + msglen], s[msglen + 5:] - frag, auth_tag = self._tls_auth_decrypt(efrag) - self.deciphered_len = len(frag) - return hdr + frag + auth_tag + r - - def post_dissect(self, s): - """ - Commit the pending read state if it has been triggered. We update - nothing if the prcs was not set, as this probably means that we're - working out-of-context (and we need to keep the default rcs). - """ - if self.tls_session.triggered_prcs_commit: - if self.tls_session.prcs is not None: - self.tls_session.rcs = self.tls_session.prcs - self.tls_session.prcs = None - self.tls_session.triggered_prcs_commit = False - return s - - def do_dissect_payload(self, s): - """ - Try to dissect the following data as a TLS message. - Note that overloading .guess_payload_class() would not be enough, - as the TLS session to be used would get lost. - """ - if s: - try: - p = TLS(s, _internal=1, _underlayer=self, - tls_session=self.tls_session) - except KeyboardInterrupt: - raise - except Exception: - p = conf.raw_layer(s, _internal=1, _underlayer=self) - self.add_payload(p) - - # Building methods - - def _tls_auth_encrypt(self, s): - """ - Return the TLSCiphertext.encrypted_record for AEAD ciphers. - """ - wcs = self.tls_session.wcs - write_seq_num = struct.pack("!Q", wcs.seq_num) - wcs.seq_num += 1 - add_data = (pkcs_i2osp(self.type, 1) + - pkcs_i2osp(self.version, 2) + - pkcs_i2osp(len(s) + wcs.cipher.tag_len, 2)) - - return wcs.cipher.auth_encrypt(s, add_data, write_seq_num) - - def post_build(self, pkt, pay): - """ - Apply the previous methods according to the writing cipher type. - """ - # Compute the length of TLSPlaintext fragment - hdr, frag = pkt[:5], pkt[5:] - if not isinstance(self.tls_session.wcs.cipher, Cipher_NULL): - frag = self._tls_auth_encrypt(frag) - - if self.len is not None: - # The user gave us a 'len', let's respect this ultimately - hdr = hdr[:3] + struct.pack("!H", self.len) - else: - # Update header with the length of TLSCiphertext.inner - hdr = hdr[:3] + struct.pack("!H", len(frag)) - - # Now we commit the pending write state if it has been triggered. We - # update nothing if the pwcs was not set. This probably means that - # we're working out-of-context (and we need to keep the default wcs). - if self.tls_session.triggered_pwcs_commit: - if self.tls_session.pwcs is not None: - self.tls_session.wcs = self.tls_session.pwcs - self.tls_session.pwcs = None - self.tls_session.triggered_pwcs_commit = False - - return hdr + frag + pay diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/session.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/session.py deleted file mode 100644 index 6966d91ffc..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/session.py +++ /dev/null @@ -1,1024 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -TLS session handler. -""" - -import socket -import struct - -from scapy.config import conf -from scapy.compat import raw -import scapy.modules.six as six -from scapy.error import log_runtime, warning -from scapy.packet import Packet -from scapy.utils import repr_hex, strxor -from scapy.layers.tls.crypto.compression import Comp_NULL -from scapy.layers.tls.crypto.hkdf import TLS13_HKDF -from scapy.layers.tls.crypto.prf import PRF - -# Note the following import may happen inside connState.__init__() -# in order to avoid to avoid cyclical dependencies. -# from scapy.layers.tls.crypto.suites import TLS_NULL_WITH_NULL_NULL - - -############################################################################### -# Connection states # -############################################################################### - -class connState(object): - """ - From RFC 5246, section 6.1: - A TLS connection state is the operating environment of the TLS Record - Protocol. It specifies a compression algorithm, an encryption - algorithm, and a MAC algorithm. In addition, the parameters for - these algorithms are known: the MAC key and the bulk encryption keys - for the connection in both the read and the write directions. - Logically, there are always four connection states outstanding: the - current read and write states, and the pending read and write states. - All records are processed under the current read and write states. - The security parameters for the pending states can be set by the TLS - Handshake Protocol, and the ChangeCipherSpec can selectively make - either of the pending states current, in which case the appropriate - current state is disposed of and replaced with the pending state; the - pending state is then reinitialized to an empty state. It is illegal - to make a state that has not been initialized with security - parameters a current state. The initial current state always - specifies that no encryption, compression, or MAC will be used. - - (For practical reasons, Scapy scraps these two last lines, through the - implementation of dummy ciphers and MAC with TLS_NULL_WITH_NULL_NULL.) - - These attributes and behaviours are mostly mapped in this class. - Also, note that Scapy may make a current state out of a pending state - which has been initialized with dummy security parameters. We need - this in order to know when the content of a TLS message is encrypted, - whether we possess the right keys to decipher/verify it or not. - For instance, when Scapy parses a CKE without knowledge of any secret, - and then a CCS, it needs to know that the following Finished - is encrypted and signed according to a new cipher suite, even though - it cannot decipher the message nor verify its integrity. - """ - - def __init__(self, - connection_end="server", - read_or_write="read", - seq_num=0, - compression_alg=Comp_NULL, - ciphersuite=None, - tls_version=0x0303): - - self.tls_version = tls_version - - # It is the user's responsibility to keep the record seq_num - # under 2**64-1. If this value gets maxed out, the TLS class in - # record.py will crash when trying to encode it with struct.pack(). - self.seq_num = seq_num - - self.connection_end = connection_end - self.row = read_or_write - - if ciphersuite is None: - from scapy.layers.tls.crypto.suites import TLS_NULL_WITH_NULL_NULL - ciphersuite = TLS_NULL_WITH_NULL_NULL - self.ciphersuite = ciphersuite(tls_version=tls_version) - - if not self.ciphersuite.usable: - warning("TLS ciphersuite not usable. Is the cryptography Python module installed ?") # noqa: E501 - return - - self.compression = compression_alg() - self.key_exchange = ciphersuite.kx_alg() - self.cipher = ciphersuite.cipher_alg() - self.hash = ciphersuite.hash_alg() - - if tls_version > 0x0200: - if ciphersuite.cipher_alg.type == "aead": - self.hmac = None - self.mac_len = self.cipher.tag_len - else: - self.hmac = ciphersuite.hmac_alg() - self.mac_len = self.hmac.hmac_len - else: - self.hmac = ciphersuite.hmac_alg() # should be Hmac_NULL - self.mac_len = self.hash.hash_len - - if tls_version >= 0x0304: - self.hkdf = TLS13_HKDF(self.hash.name.lower()) - else: - self.prf = PRF(ciphersuite.hash_alg.name, tls_version) - - def debug_repr(self, name, secret): - if conf.debug_tls and secret: - log_runtime.debug("TLS: %s %s %s: %s", - self.connection_end, - self.row, - name, - repr_hex(secret)) - - def derive_keys(self, - client_random=b"", - server_random=b"", - master_secret=b""): - # XXX Can this be called over a non-usable suite? What happens then? - - cs = self.ciphersuite - - # Derive the keys according to the cipher type and protocol version - key_block = self.prf.derive_key_block(master_secret, - server_random, - client_random, - cs.key_block_len) - - # When slicing the key_block, keep the right half of the material - skip_first = False - if ((self.connection_end == "client" and self.row == "read") or - (self.connection_end == "server" and self.row == "write")): - skip_first = True - - pos = 0 - cipher_alg = cs.cipher_alg - - # MAC secret (for block and stream ciphers) - if (cipher_alg.type == "stream") or (cipher_alg.type == "block"): - start = pos - if skip_first: - start += cs.hmac_alg.key_len - end = start + cs.hmac_alg.key_len - mac_secret = key_block[start:end] - self.debug_repr("mac_secret", mac_secret) - pos += 2 * cs.hmac_alg.key_len - else: - mac_secret = None - - # Cipher secret - start = pos - if skip_first: - start += cipher_alg.key_len - end = start + cipher_alg.key_len - cipher_secret = key_block[start:end] - if cs.kx_alg.export: - reqLen = cipher_alg.expanded_key_len - cipher_secret = self.prf.postprocess_key_for_export(cipher_secret, - client_random, - server_random, - self.connection_end, # noqa: E501 - self.row, - reqLen) - self.debug_repr("cipher_secret", cipher_secret) - pos += 2 * cipher_alg.key_len - - # Implicit IV (for block and AEAD ciphers) - start = pos - if cipher_alg.type == "block": - if skip_first: - start += cipher_alg.block_size - end = start + cipher_alg.block_size - elif cipher_alg.type == "aead": - if skip_first: - start += cipher_alg.fixed_iv_len - end = start + cipher_alg.fixed_iv_len - - # Now we have the secrets, we can instantiate the algorithms - if cs.hmac_alg is None: # AEAD - self.hmac = None - self.mac_len = cipher_alg.tag_len - else: - self.hmac = cs.hmac_alg(mac_secret) - self.mac_len = self.hmac.hmac_len - - if cipher_alg.type == "stream": - cipher = cipher_alg(cipher_secret) - elif cipher_alg.type == "block": - # We set an IV every time, even though it does not matter for - # TLS 1.1+ as it requires an explicit IV. Indeed the cipher.iv - # would get updated in TLS.post_build() or TLS.pre_dissect(). - iv = key_block[start:end] - if cs.kx_alg.export: - reqLen = cipher_alg.block_size - iv = self.prf.generate_iv_for_export(client_random, - server_random, - self.connection_end, - self.row, - reqLen) - cipher = cipher_alg(cipher_secret, iv) - self.debug_repr("block iv", iv) - elif cipher_alg.type == "aead": - fixed_iv = key_block[start:end] - nonce_explicit_init = 0 - # If you ever wanted to set a random nonce_explicit, use this: - # exp_bit_len = cipher_alg.nonce_explicit_len * 8 - # nonce_explicit_init = random.randint(0, 2**exp_bit_len - 1) - cipher = cipher_alg(cipher_secret, fixed_iv, nonce_explicit_init) - self.debug_repr("aead fixed iv", fixed_iv) - self.cipher = cipher - - def sslv2_derive_keys(self, key_material): - """ - There is actually only one key, the CLIENT-READ-KEY or -WRITE-KEY. - - Note that skip_first is opposite from the one with SSLv3 derivation. - - Also, if needed, the IV should be set elsewhere. - """ - skip_first = True - if ((self.connection_end == "client" and self.row == "read") or - (self.connection_end == "server" and self.row == "write")): - skip_first = False - - cipher_alg = self.ciphersuite.cipher_alg - - start = 0 - if skip_first: - start += cipher_alg.key_len - end = start + cipher_alg.key_len - cipher_secret = key_material[start:end] - self.cipher = cipher_alg(cipher_secret) - self.debug_repr("cipher_secret", cipher_secret) - - def tls13_derive_keys(self, key_material): - cipher_alg = self.ciphersuite.cipher_alg - key_len = cipher_alg.key_len - iv_len = cipher_alg.fixed_iv_len - write_key = self.hkdf.expand_label(key_material, b"key", b"", key_len) - write_iv = self.hkdf.expand_label(key_material, b"iv", b"", iv_len) - self.cipher = cipher_alg(write_key, write_iv) - - def snapshot(self): - """ - This is used mostly as a way to keep the cipher state and the seq_num. - """ - snap = connState(connection_end=self.connection_end, - read_or_write=self.row, - seq_num=self.seq_num, - compression_alg=type(self.compression), - ciphersuite=type(self.ciphersuite), - tls_version=self.tls_version) - snap.cipher = self.cipher.snapshot() - if self.hmac: - snap.hmac.key = self.hmac.key - return snap - - def __repr__(self): - res = "Connection end : %s\n" % self.connection_end.upper() - res += "Cipher suite : %s (0x%04x)\n" % (self.ciphersuite.name, - self.ciphersuite.val) - res += "Compression : %s (0x%02x)\n" % (self.compression.name, - self.compression.val) - tabsize = 4 - return res.expandtabs(tabsize) - - -class readConnState(connState): - def __init__(self, **kargs): - connState.__init__(self, read_or_write="read", **kargs) - - -class writeConnState(connState): - def __init__(self, **kargs): - connState.__init__(self, read_or_write="write", **kargs) - - -############################################################################### -# TLS session # -############################################################################### - -class tlsSession(object): - """ - This is our TLS context, which gathers information from both sides of the - TLS connection. These sides are represented by a readConnState instance and - a writeConnState instance. Along with overarching network attributes, a - tlsSession object also holds negotiated, shared information, such as the - key exchange parameters and the master secret (when available). - - The default connection_end is "server". This corresponds to the expected - behaviour for static exchange analysis (with a ClientHello parsed first). - """ - - def __init__(self, - ipsrc=None, ipdst=None, - sport=None, dport=None, sid=None, - connection_end="server", - wcs=None, rcs=None): - - # Use this switch to prevent additions to the 'handshake_messages'. - self.frozen = False - - # Network settings - self.ipsrc = ipsrc - self.ipdst = ipdst - self.sport = sport - self.dport = dport - self.sid = sid - - # Our TCP socket. None until we send (or receive) a packet. - self.sock = None - - # Connection states - self.connection_end = connection_end - - if wcs is None: - # Instantiate wcs with dummy values. - self.wcs = writeConnState(connection_end=connection_end) - self.wcs.derive_keys() - else: - self.wcs = wcs - - if rcs is None: - # Instantiate rcs with dummy values. - self.rcs = readConnState(connection_end=connection_end) - self.rcs.derive_keys() - else: - self.rcs = rcs - - # The pending write/read states are updated by the building/parsing - # of various TLS packets. They get committed to self.wcs/self.rcs - # once Scapy builds/parses a ChangeCipherSpec message, or for certain - # other messages in case of TLS 1.3. - self.pwcs = None - self.triggered_pwcs_commit = False - self.prcs = None - self.triggered_prcs_commit = False - - # Certificates and private keys - - # The server certificate chain, as a list of Cert instances. - # Either we act as server and it has to be provided, or it is expected - # to be sent by the server through a Certificate message. - # The server certificate should be self.server_certs[0]. - self.server_certs = [] - - # The server private key, as a PrivKey instance, when acting as server. - # XXX It would be nice to be able to provide both an RSA and an ECDSA - # key in order for the same Scapy server to support both families of - # cipher suites. See INIT_TLS_SESSION() in automaton_srv.py. - # (For now server_key holds either one of both types for DHE - # authentication, while server_rsa_key is used only for RSAkx.) - self.server_key = None - self.server_rsa_key = None - # self.server_ecdsa_key = None - - # Back in the dreadful EXPORT days, US servers were forbidden to use - # RSA keys longer than 512 bits for RSAkx. When their usual RSA key - # was longer than this, they had to create a new key and send it via - # a ServerRSAParams message. When receiving such a message, - # Scapy stores this key in server_tmp_rsa_key as a PubKey instance. - self.server_tmp_rsa_key = None - - # When client authentication is performed, we need at least a - # client certificate chain. If we act as client, we also have - # to provide the key associated with the first certificate. - self.client_certs = [] - self.client_key = None - - # Ephemeral key exchange parameters - - # These are the group/curve parameters, needed to hold the information - # e.g. from receiving an SKE to sending a CKE. Usually, only one of - # these attributes will be different from None. - self.client_kx_ffdh_params = None - self.client_kx_ecdh_params = None - - # These are PrivateKeys and PublicKeys from the appropriate FFDH/ECDH - # cryptography module, i.e. these are not raw bytes. Usually, only one - # in two will be different from None, e.g. when being a TLS client you - # will need the client_kx_privkey (the serialized public key is not - # actually registered) and you will receive a server_kx_pubkey. - self.client_kx_privkey = None - self.client_kx_pubkey = None - self.server_kx_privkey = None - self.server_kx_pubkey = None - - # When using TLS 1.3, the tls13_client_pubshares will contain every - # potential key share (equate the 'client_kx_pubkey' before) the client - # offered, indexed by the id of the FFDH/ECDH group. These dicts - # effectively replace the four previous attributes. - self.tls13_client_privshares = {} - self.tls13_client_pubshares = {} - self.tls13_server_privshare = {} - self.tls13_server_pubshare = {} - - # Negotiated session parameters - - # The advertised TLS version found in the ClientHello (and - # EncryptedPreMasterSecret if used). If acting as server, it is set to - # the value advertised by the client in its ClientHello. - # The default value corresponds to TLS 1.2 (and TLS 1.3, incidentally). - self.advertised_tls_version = 0x0303 - - # The agreed-upon TLS version found in the ServerHello. - self.tls_version = None - - # These attributes should eventually be known to both sides (SSLv3-TLS 1.2). # noqa: E501 - self.client_random = None - self.server_random = None - self.pre_master_secret = None - self.master_secret = None - - # A session ticket received by the client. - self.client_session_ticket = None - - # These attributes should only be used with SSLv2 connections. - # We need to keep the KEY-MATERIAL here because it may be reused. - self.sslv2_common_cs = [] - self.sslv2_connection_id = None - self.sslv2_challenge = None - self.sslv2_challenge_clientcert = None - self.sslv2_key_material = None - - # These attributes should only be used with TLS 1.3 connections. - self.tls13_psk_secret = None - self.tls13_early_secret = None - self.tls13_dhe_secret = None - self.tls13_handshake_secret = None - self.tls13_master_secret = None - self.tls13_derived_secrets = {} - - # Handshake messages needed for Finished computation/validation. - # No record layer headers, no HelloRequests, no ChangeCipherSpecs. - self.handshake_messages = [] - self.handshake_messages_parsed = [] - - # All exchanged TLS packets. - # XXX no support for now - # self.exchanged_pkts = [] - - def __setattr__(self, name, val): - if name == "connection_end": - if hasattr(self, "rcs") and self.rcs: - self.rcs.connection_end = val - if hasattr(self, "wcs") and self.wcs: - self.wcs.connection_end = val - if hasattr(self, "prcs") and self.prcs: - self.prcs.connection_end = val - if hasattr(self, "pwcs") and self.pwcs: - self.pwcs.connection_end = val - super(tlsSession, self).__setattr__(name, val) - - # Mirroring - - def mirror(self): - """ - This function takes a tlsSession object and swaps the IP addresses, - ports, connection ends and connection states. The triggered_commit are - also swapped (though it is probably overkill, it is cleaner this way). - - It is useful for static analysis of a series of messages from both the - client and the server. In such a situation, it should be used every - time the message being read comes from a different side than the one - read right before, as the reading state becomes the writing state, and - vice versa. For instance you could do: - - client_hello = open('client_hello.raw').read() - - - m1 = TLS(client_hello) - m2 = TLS(server_hello, tls_session=m1.tls_session.mirror()) - m3 = TLS(server_cert, tls_session=m2.tls_session) - m4 = TLS(client_keyexchange, tls_session=m3.tls_session.mirror()) - """ - - self.ipdst, self.ipsrc = self.ipsrc, self.ipdst - self.dport, self.sport = self.sport, self.dport - - self.rcs, self.wcs = self.wcs, self.rcs - if self.rcs: - self.rcs.row = "read" - if self.wcs: - self.wcs.row = "write" - - self.prcs, self.pwcs = self.pwcs, self.prcs - if self.prcs: - self.prcs.row = "read" - if self.pwcs: - self.pwcs.row = "write" - - self.triggered_prcs_commit, self.triggered_pwcs_commit = \ - self.triggered_pwcs_commit, self.triggered_prcs_commit - - if self.connection_end == "client": - self.connection_end = "server" - elif self.connection_end == "server": - self.connection_end = "client" - - return self - - # Secrets management for SSLv3 to TLS 1.2 - - def compute_master_secret(self): - if self.pre_master_secret is None: - warning("Missing pre_master_secret while computing master_secret!") - if self.client_random is None: - warning("Missing client_random while computing master_secret!") - if self.server_random is None: - warning("Missing server_random while computing master_secret!") - - ms = self.pwcs.prf.compute_master_secret(self.pre_master_secret, - self.client_random, - self.server_random) - self.master_secret = ms - if conf.debug_tls: - log_runtime.debug("TLS: master secret: %s", repr_hex(ms)) - - def compute_ms_and_derive_keys(self): - self.compute_master_secret() - self.prcs.derive_keys(client_random=self.client_random, - server_random=self.server_random, - master_secret=self.master_secret) - self.pwcs.derive_keys(client_random=self.client_random, - server_random=self.server_random, - master_secret=self.master_secret) - - # Secrets management for SSLv2 - - def compute_sslv2_key_material(self): - if self.master_secret is None: - warning("Missing master_secret while computing key_material!") - if self.sslv2_challenge is None: - warning("Missing challenge while computing key_material!") - if self.sslv2_connection_id is None: - warning("Missing connection_id while computing key_material!") - - km = self.pwcs.prf.derive_key_block(self.master_secret, - self.sslv2_challenge, - self.sslv2_connection_id, - 2 * self.pwcs.cipher.key_len) - self.sslv2_key_material = km - if conf.debug_tls: - log_runtime.debug("TLS: master secret: %s", repr_hex(self.master_secret)) # noqa: E501 - log_runtime.debug("TLS: key material: %s", repr_hex(km)) - - def compute_sslv2_km_and_derive_keys(self): - self.compute_sslv2_key_material() - self.prcs.sslv2_derive_keys(key_material=self.sslv2_key_material) - self.pwcs.sslv2_derive_keys(key_material=self.sslv2_key_material) - - # Secrets management for TLS 1.3 - - def compute_tls13_early_secrets(self, external=False): - """ - This function computes the Early Secret, the binder_key, - the client_early_traffic_secret and the - early_exporter_master_secret (See RFC8446, section 7.1). - - The parameter external is used for the computation of the - binder_key : - - For external PSK provisioned outside out of TLS, the parameter - external must be True. - - For resumption PSK, the parameter external must be False. - - If no argument is specified, the label "res binder" will be - used by default. - - Ciphers key and IV are updated accordingly for 0-RTT data. - self.handshake_messages should be ClientHello only. - """ - - # if no hash algorithm is set, default to SHA-256 - if self.prcs and self.prcs.hkdf: - hkdf = self.prcs.hkdf - elif self.pwcs and self.pwcs.hkdf: - hkdf = self.pwcs.hkdf - else: - hkdf = TLS13_HKDF("sha256") - - if self.tls13_early_secret is None: - self.tls13_early_secret = hkdf.extract(None, - self.tls13_psk_secret) - - if "binder_key" not in self.tls13_derived_secrets: - if external: - bk = hkdf.derive_secret(self.tls13_early_secret, - b"ext binder", - b"") - else: - bk = hkdf.derive_secret(self.tls13_early_secret, - b"res binder", - b"") - - self.tls13_derived_secrets["binder_key"] = bk - - cets = hkdf.derive_secret(self.tls13_early_secret, - b"c e traffic", - b"".join(self.handshake_messages)) - - self.tls13_derived_secrets["client_early_traffic_secret"] = cets - ees = hkdf.derive_secret(self.tls13_early_secret, - b"e exp master", - b"".join(self.handshake_messages)) - self.tls13_derived_secrets["early_exporter_secret"] = ees - - if self.connection_end == "server": - if self.prcs: - self.prcs.tls13_derive_keys(cets) - elif self.connection_end == "client": - if self.pwcs: - self.pwcs.tls13_derive_keys(cets) - - def compute_tls13_handshake_secrets(self): - """ - Ciphers key and IV are updated accordingly for Handshake data. - self.handshake_messages should be ClientHello...ServerHello. - """ - if self.prcs: - hkdf = self.prcs.hkdf - elif self.pwcs: - hkdf = self.pwcs.hkdf - else: - warning("No HKDF. This is abnormal.") - return - - if self.tls13_early_secret is None: - self.tls13_early_secret = hkdf.extract(None, - self.tls13_psk_secret) - - secret = hkdf.derive_secret(self.tls13_early_secret, b"derived", b"") - self.tls13_handshake_secret = hkdf.extract(secret, self.tls13_dhe_secret) # noqa: E501 - - chts = hkdf.derive_secret(self.tls13_handshake_secret, - b"c hs traffic", - b"".join(self.handshake_messages)) - self.tls13_derived_secrets["client_handshake_traffic_secret"] = chts - - shts = hkdf.derive_secret(self.tls13_handshake_secret, - b"s hs traffic", - b"".join(self.handshake_messages)) - self.tls13_derived_secrets["server_handshake_traffic_secret"] = shts - - def compute_tls13_traffic_secrets(self): - """ - Ciphers key and IV are updated accordingly for Application data. - self.handshake_messages should be ClientHello...ServerFinished. - """ - if self.prcs and self.prcs.hkdf: - hkdf = self.prcs.hkdf - elif self.pwcs and self.pwcs.hkdf: - hkdf = self.pwcs.hkdf - else: - warning("No HKDF. This is abnormal.") - return - - tmp = hkdf.derive_secret(self.tls13_handshake_secret, - b"derived", - b"") - self.tls13_master_secret = hkdf.extract(tmp, None) - - cts0 = hkdf.derive_secret(self.tls13_master_secret, - b"c ap traffic", - b"".join(self.handshake_messages)) - self.tls13_derived_secrets["client_traffic_secrets"] = [cts0] - - sts0 = hkdf.derive_secret(self.tls13_master_secret, - b"s ap traffic", - b"".join(self.handshake_messages)) - self.tls13_derived_secrets["server_traffic_secrets"] = [sts0] - - es = hkdf.derive_secret(self.tls13_master_secret, - b"exp master", - b"".join(self.handshake_messages)) - self.tls13_derived_secrets["exporter_secret"] = es - - if self.connection_end == "server": - # self.prcs.tls13_derive_keys(cts0) - self.pwcs.tls13_derive_keys(sts0) - elif self.connection_end == "client": - # self.pwcs.tls13_derive_keys(cts0) - self.prcs.tls13_derive_keys(sts0) - - def compute_tls13_traffic_secrets_end(self): - cts0 = self.tls13_derived_secrets["client_traffic_secrets"][0] - if self.connection_end == "server": - self.prcs.tls13_derive_keys(cts0) - elif self.connection_end == "client": - self.pwcs.tls13_derive_keys(cts0) - - def compute_tls13_verify_data(self, connection_end, read_or_write): - shts = "server_handshake_traffic_secret" - chts = "client_handshake_traffic_secret" - if read_or_write == "read": - hkdf = self.rcs.hkdf - if connection_end == "client": - basekey = self.tls13_derived_secrets[shts] - elif connection_end == "server": - basekey = self.tls13_derived_secrets[chts] - elif read_or_write == "write": - hkdf = self.wcs.hkdf - if connection_end == "client": - basekey = self.tls13_derived_secrets[chts] - elif connection_end == "server": - basekey = self.tls13_derived_secrets[shts] - - if not hkdf or not basekey: - warning("Missing arguments for verify_data computation!") - return None - # XXX this join() works in standard cases, but does it in all of them? - handshake_context = b"".join(self.handshake_messages) - return hkdf.compute_verify_data(basekey, handshake_context) - - def compute_tls13_resumption_secret(self): - """ - self.handshake_messages should be ClientHello...ClientFinished. - """ - if self.connection_end == "server": - hkdf = self.prcs.hkdf - elif self.connection_end == "client": - hkdf = self.pwcs.hkdf - rs = hkdf.derive_secret(self.tls13_master_secret, - b"res master", - b"".join(self.handshake_messages)) - self.tls13_derived_secrets["resumption_secret"] = rs - - def compute_tls13_next_traffic_secrets(self, connection_end, read_or_write): # noqa : E501 - """ - Ciphers key and IV are updated accordingly. - """ - if self.rcs.hkdf: - hkdf = self.rcs.hkdf - hl = hkdf.hash.digest_size - elif self.wcs.hkdf: - hkdf = self.wcs.hkdf - hl = hkdf.hash.digest_size - - if read_or_write == "read": - if connection_end == "client": - cts = self.tls13_derived_secrets["client_traffic_secrets"] - ctsN = cts[-1] - ctsN_1 = hkdf.expand_label(ctsN, b"traffic upd", b"", hl) - cts.append(ctsN_1) - self.prcs.tls13_derive_keys(ctsN_1) - elif connection_end == "server": - sts = self.tls13_derived_secrets["server_traffic_secrets"] - stsN = sts[-1] - stsN_1 = hkdf.expand_label(stsN, b"traffic upd", b"", hl) - sts.append(stsN_1) - - self.prcs.tls13_derive_keys(stsN_1) - - elif read_or_write == "write": - if connection_end == "client": - cts = self.tls13_derived_secrets["client_traffic_secrets"] - ctsN = cts[-1] - ctsN_1 = hkdf.expand_label(ctsN, b"traffic upd", b"", hl) - cts.append(ctsN_1) - self.pwcs.tls13_derive_keys(ctsN_1) - elif connection_end == "server": - sts = self.tls13_derived_secrets["server_traffic_secrets"] - stsN = sts[-1] - stsN_1 = hkdf.expand_label(stsN, b"traffic upd", b"", hl) - sts.append(stsN_1) - - self.pwcs.tls13_derive_keys(stsN_1) - - # Tests for record building/parsing - - def consider_read_padding(self): - # Return True if padding is needed. Used by TLSPadField. - return (self.rcs.cipher.type == "block" and - not (False in six.itervalues(self.rcs.cipher.ready))) - - def consider_write_padding(self): - # Return True if padding is needed. Used by TLSPadField. - return self.wcs.cipher.type == "block" - - def use_explicit_iv(self, version, cipher_type): - # Return True if an explicit IV is needed. Required for TLS 1.1+ - # when either a block or an AEAD cipher is used. - if cipher_type == "stream": - return False - return version >= 0x0302 - - # Python object management - - def hash(self): - s1 = struct.pack("!H", self.sport) - s2 = struct.pack("!H", self.dport) - family = socket.AF_INET - if ':' in self.ipsrc: - family = socket.AF_INET6 - s1 += socket.inet_pton(family, self.ipsrc) - s2 += socket.inet_pton(family, self.ipdst) - return strxor(s1, s2) - - def eq(self, other): - ok = False - if (self.sport == other.sport and self.dport == other.dport and - self.ipsrc == other.ipsrc and self.ipdst == other.ipdst): - ok = True - - if (not ok and - self.dport == other.sport and self.sport == other.dport and - self.ipdst == other.ipsrc and self.ipsrc == other.ipdst): - ok = True - - if ok: - if self.sid and other.sid: - return self.sid == other.sid - return True - - return False - - def __repr__(self): - sid = repr(self.sid) - if len(sid) > 12: - sid = sid[:11] + "..." - return "%s:%s > %s:%s" % (self.ipsrc, str(self.sport), - self.ipdst, str(self.dport)) - -############################################################################### -# Session singleton # -############################################################################### - - -class _GenericTLSSessionInheritance(Packet): - """ - Many classes inside the TLS module need to get access to session-related - information. For instance, an encrypted TLS record cannot be parsed without - some knowledge of the cipher suite being used and the secrets which have - been negotiated. Passing information is also essential to the handshake. - To this end, various TLS objects inherit from the present class. - """ - __slots__ = ["tls_session", "rcs_snap_init", "wcs_snap_init"] - name = "Dummy Generic TLS Packet" - fields_desc = [] - - def __init__(self, _pkt="", post_transform=None, _internal=0, - _underlayer=None, tls_session=None, **fields): - try: - setme = self.tls_session is None - except Exception: - setme = True - - if setme: - if tls_session is None: - self.tls_session = tlsSession() - else: - self.tls_session = tls_session - - self.rcs_snap_init = self.tls_session.rcs.snapshot() - self.wcs_snap_init = self.tls_session.wcs.snapshot() - - Packet.__init__(self, _pkt=_pkt, post_transform=post_transform, - _internal=_internal, _underlayer=_underlayer, - **fields) - - def __getattr__(self, attr): - """ - The tls_session should be found only through the normal mechanism. - """ - if attr == "tls_session": - return None - return super(_GenericTLSSessionInheritance, self).__getattr__(attr) - - def tls_session_update(self, msg_str): - """ - post_{build, dissection}_tls_session_update() are used to update the - tlsSession context. The default definitions below, along with - tls_session_update(), may prevent code duplication in some cases. - """ - pass - - def post_build_tls_session_update(self, msg_str): - self.tls_session_update(msg_str) - - def post_dissection_tls_session_update(self, msg_str): - self.tls_session_update(msg_str) - - def copy(self): - pkt = Packet.copy(self) - pkt.tls_session = self.tls_session - return pkt - - def clone_with(self, payload=None, **kargs): - pkt = Packet.clone_with(self, payload=payload, **kargs) - pkt.tls_session = self.tls_session - return pkt - - def raw_stateful(self): - return super(_GenericTLSSessionInheritance, self).__bytes__() - - def str_stateful(self): - return self.raw_stateful() - - def __bytes__(self): - """ - The __bytes__ call has to leave the connection states unchanged. - We also have to delete raw_packet_cache in order to access post_build. - - For performance, the pending connStates are not snapshotted. - This should not be an issue, but maybe pay attention to this. - - The previous_freeze_state prevents issues with calling a raw() calling - in turn another raw(), which would unfreeze the session too soon. - """ - s = self.tls_session - rcs_snap = s.rcs.snapshot() - wcs_snap = s.wcs.snapshot() - rpc_snap = self.raw_packet_cache - rpcf_snap = self.raw_packet_cache_fields - - s.wcs = self.rcs_snap_init - - self.raw_packet_cache = None - previous_freeze_state = s.frozen - s.frozen = True - built_packet = super(_GenericTLSSessionInheritance, self).__bytes__() - s.frozen = previous_freeze_state - - s.rcs = rcs_snap - s.wcs = wcs_snap - self.raw_packet_cache = rpc_snap - self.raw_packet_cache_fields = rpcf_snap - - return built_packet - __str__ = __bytes__ - - def show2(self): - """ - Rebuild the TLS packet with the same context, and then .show() it. - We need self.__class__ to call the subclass in a dynamic way. - - Howether we do not want the tls_session.{r,w}cs.seq_num to be updated. - We have to bring back the init states (it's possible the cipher context - has been updated because of parsing) but also to keep the current state - and restore it afterwards (the raw() call may also update the states). - """ - s = self.tls_session - rcs_snap = s.rcs.snapshot() - wcs_snap = s.wcs.snapshot() - - s.rcs = self.rcs_snap_init - - built_packet = raw(self) - s.frozen = True - self.__class__(built_packet, tls_session=s).show() - s.frozen = False - - s.rcs = rcs_snap - s.wcs = wcs_snap - - # Uncomment this when the automata update IPs and ports properly - # def mysummary(self): - # return "TLS %s" % repr(self.tls_session) - - -############################################################################### -# Multiple TLS sessions # -############################################################################### - -class _tls_sessions(object): - def __init__(self): - self.sessions = {} - - def add(self, session): - s = self.find(session) - if s: - log_runtime.info("TLS: previous session shall not be overwritten") - return - - h = session.hash() - if h in self.sessions: - self.sessions[h].append(session) - else: - self.sessions[h] = [session] - - def rem(self, session): - s = self.find(session) - if s: - log_runtime.info("TLS: previous session shall not be overwritten") - return - - h = session.hash() - self.sessions[h].remove(session) - - def find(self, session): - h = session.hash() - if h in self.sessions: - for k in self.sessions[h]: - if k.eq(session): - if conf.tls_verbose: - log_runtime.info("TLS: found session matching %s", k) - return k - if conf.tls_verbose: - log_runtime.info("TLS: did not find session matching %s", session) - return None - - def __repr__(self): - res = [("First endpoint", "Second endpoint", "Session ID")] - for l in six.itervalues(self.sessions): - for s in l: - src = "%s[%d]" % (s.ipsrc, s.sport) - dst = "%s[%d]" % (s.ipdst, s.dport) - sid = repr(s.sid) - if len(sid) > 12: - sid = sid[:11] + "..." - res.append((src, dst, sid)) - colwidth = (max([len(y) for y in x]) for x in zip(*res)) - fmt = " ".join(map(lambda x: "%%-%ds" % x, colwidth)) - return "\n".join(map(lambda x: fmt % x, res)) - - -conf.tls_sessions = _tls_sessions() -conf.tls_verbose = False diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/tools.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/tools.py deleted file mode 100644 index c7f0edaed9..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/tls/tools.py +++ /dev/null @@ -1,225 +0,0 @@ -# This file is part of Scapy -# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard -# 2015, 2016, 2017 Maxence Tury -# This program is published under a GPLv2 license - -""" -TLS helpers, provided as out-of-context methods. -""" - -from __future__ import absolute_import -import struct - -from scapy.compat import orb, chb -from scapy.error import warning -from scapy.fields import (ByteEnumField, ShortEnumField, - FieldLenField, StrLenField) -from scapy.packet import Packet - -from scapy.layers.tls.basefields import _tls_type, _tls_version - - -class TLSPlaintext(Packet): - name = "TLS Plaintext" - fields_desc = [ByteEnumField("type", None, _tls_type), - ShortEnumField("version", None, _tls_version), - FieldLenField("len", None, length_of="data", fmt="!H"), - StrLenField("data", "", - length_from=lambda pkt: pkt.len)] - - -class TLSCompressed(TLSPlaintext): - name = "TLS Compressed" - - -class TLSCiphertext(TLSPlaintext): - name = "TLS Ciphertext" - - -def _tls_compress(alg, p): - """ - Compress p (a TLSPlaintext instance) using compression algorithm instance - alg and return a TLSCompressed instance. - """ - c = TLSCompressed() - c.type = p.type - c.version = p.version - c.data = alg.compress(p.data) - c.len = len(c.data) - return c - - -def _tls_decompress(alg, c): - """ - Decompress c (a TLSCompressed instance) using compression algorithm - instance alg and return a TLSPlaintext instance. - """ - p = TLSPlaintext() - p.type = c.type - p.version = c.version - p.data = alg.decompress(c.data) - p.len = len(p.data) - return p - - -def _tls_mac_add(alg, c, write_seq_num): - """ - Compute the MAC using provided MAC alg instance over TLSCiphertext c using - current write sequence number write_seq_num. Computed MAC is then appended - to c.data and c.len is updated to reflect that change. It is the - caller responsibility to increment the sequence number after the operation. - The function has no return value. - """ - write_seq_num = struct.pack("!Q", write_seq_num) - h = alg.digest(write_seq_num + bytes(c)) - c.data += h - c.len += alg.hash_len - - -def _tls_mac_verify(alg, p, read_seq_num): - """ - Verify if the MAC in provided message (message resulting from decryption - and padding removal) is valid. Current read sequence number is used in - the verification process. - - If the MAC is valid: - - The function returns True - - The packet p is updated in the following way: trailing MAC value is - removed from p.data and length is updated accordingly. - - In case of error, False is returned, and p may have been modified. - - Also note that it is the caller's responsibility to update the read - sequence number after the operation. - """ - h_size = alg.hash_len - if p.len < h_size: - return False - received_h = p.data[-h_size:] - p.len -= h_size - p.data = p.data[:-h_size] - - read_seq_num = struct.pack("!Q", read_seq_num) - h = alg.digest(read_seq_num + bytes(p)) - return h == received_h - - -def _tls_add_pad(p, block_size): - """ - Provided with cipher block size parameter and current TLSCompressed packet - p (after MAC addition), the function adds required, deterministic padding - to p.data before encryption step, as it is defined for TLS (i.e. not - SSL and its allowed random padding). The function has no return value. - """ - padlen = -p.len % block_size - padding = chb(padlen) * (padlen + 1) - p.len += len(padding) - p.data += padding - - -def _tls_del_pad(p): - """ - Provided with a just decrypted TLSCiphertext (now a TLSPlaintext instance) - p, the function removes the trailing padding found in p.data. It also - performs some sanity checks on the padding (length, content, ...). False - is returned if one of the check fails. Otherwise, True is returned, - indicating that p.data and p.len have been updated. - """ - - if p.len < 1: - warning("Message format is invalid (padding)") - return False - - padlen = orb(p.data[-1]) - padsize = padlen + 1 - - if p.len < padsize: - warning("Invalid padding length") - return False - - if p.data[-padsize:] != chb(padlen) * padsize: - warning("Padding content is invalid %s", repr(p.data[-padsize:])) - return False - - p.data = p.data[:-padsize] - p.len -= padsize - - return True - - -def _tls_encrypt(alg, p): - """ - Provided with an already MACed TLSCompressed packet, and a stream or block - cipher alg, the function converts it into a TLSCiphertext (i.e. encrypts it - and updates length). The function returns a newly created TLSCiphertext - instance. - """ - c = TLSCiphertext() - c.type = p.type - c.version = p.version - c.data = alg.encrypt(p.data) - c.len = len(c.data) - return c - - -def _tls_decrypt(alg, c): - """ - Provided with a TLSCiphertext instance c, and a stream or block cipher alg, - the function decrypts c.data and returns a newly created TLSPlaintext. - """ - p = TLSPlaintext() - p.type = c.type - p.version = c.version - p.data = alg.decrypt(c.data) - p.len = len(p.data) - return p - - -def _tls_aead_auth_encrypt(alg, p, write_seq_num): - """ - Provided with a TLSCompressed instance p, the function applies AEAD - cipher alg to p.data and builds a new TLSCiphertext instance. Unlike - for block and stream ciphers, for which the authentication step is done - separately, AEAD alg does it simultaneously: this is the reason why - write_seq_num is passed to the function, to be incorporated in - authenticated data. Note that it is the caller's responsibility to increment # noqa: E501 - write_seq_num afterwards. - """ - P = bytes(p) - write_seq_num = struct.pack("!Q", write_seq_num) - A = write_seq_num + P[:5] - - c = TLSCiphertext() - c.type = p.type - c.version = p.version - c.data = alg.auth_encrypt(P, A, write_seq_num) - c.len = len(c.data) - return c - - -def _tls_aead_auth_decrypt(alg, c, read_seq_num): - """ - Provided with a TLSCiphertext instance c, the function applies AEAD - cipher alg auth_decrypt function to c.data (and additional data) - in order to authenticate the data and decrypt c.data. When those - steps succeed, the result is a newly created TLSCompressed instance. - On error, None is returned. Note that it is the caller's responsibility to - increment read_seq_num afterwards. - """ - # 'Deduce' TLSCompressed length from TLSCiphertext length - # There is actually no guaranty of this equality, but this is defined as - # such in TLS 1.2 specifications, and it works for GCM and CCM at least. - # - plen = c.len - getattr(alg, "nonce_explicit_len", 0) - alg.tag_len - read_seq_num = struct.pack("!Q", read_seq_num) - A = read_seq_num + struct.pack('!BHH', c.type, c.version, plen) - - p = TLSCompressed() - p.type = c.type - p.version = c.version - p.len = plen - p.data = alg.auth_decrypt(A, c.data, read_seq_num) - - if p.data is None: # Verification failed. - return None - return p diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/usb.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/usb.py deleted file mode 100644 index 736b2fd28b..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/usb.py +++ /dev/null @@ -1,244 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Copyright (C) Gabriel Potter -# This program is published under a GPLv2 license - -""" -Default USB frames & Basic implementation -""" - -# TODO: support USB headers for Linux and Darwin (usbmon/netmon) -# https://github.com/wireshark/wireshark/blob/master/epan/dissectors/packet-usb.c # noqa: E501 - -import re -import subprocess - -from scapy.config import conf -from scapy.consts import WINDOWS -from scapy.compat import chb, plain_str -from scapy.data import MTU, DLT_USBPCAP -from scapy.error import warning -from scapy.fields import ByteField, XByteField, ByteEnumField, LEShortField, \ - LEShortEnumField, LEIntField, LEIntEnumField, XLELongField, \ - LenField -from scapy.packet import Packet, bind_top_down -from scapy.supersocket import SuperSocket -from scapy.utils import PcapReader - -# USBpcap - -_usbd_status_codes = { - 0x00000000: "Success", - 0x40000000: "Pending", - 0xC0000000: "Halted", - 0x80000000: "Error" -} - -_transfer_types = { - 0x0: "Isochronous", - 0x1: "Interrupt", - 0x2: "Control" -} - -# From https://github.com/wireshark/wireshark/blob/master/epan/dissectors/packet-usb.c # noqa: E501 -_urb_functions = { - 0x0008: "URB_FUNCTION_CONTROL_TRANSFER", - 0x0009: "URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER", - 0x000A: "URB_FUNCTION_ISOCH_TRANSFER", - 0x000B: "URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE", - 0x000C: "URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE", - 0x000D: "URB_FUNCTION_SET_FEATURE_TO_DEVICE", - 0x000E: "URB_FUNCTION_SET_FEATURE_TO_INTERFACE", - 0x000F: "URB_FUNCTION_SET_FEATURE_TO_ENDPOINT", - 0x0010: "URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE", - 0x0011: "URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE", - 0x0012: "URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT", - 0x0013: "URB_FUNCTION_GET_STATUS_FROM_DEVICE", - 0x0014: "URB_FUNCTION_GET_STATUS_FROM_INTERFACE", - 0x0015: "URB_FUNCTION_GET_STATUS_FROM_ENDPOINT", - 0x0017: "URB_FUNCTION_VENDOR_DEVICE", - 0x0018: "URB_FUNCTION_VENDOR_INTERFACE", - 0x0019: "URB_FUNCTION_VENDOR_ENDPOINT", - 0x001A: "URB_FUNCTION_CLASS_DEVICE", - 0x001B: "URB_FUNCTION_CLASS_INTERFACE", - 0x001C: "URB_FUNCTION_CLASS_ENDPOINT", - 0x001F: "URB_FUNCTION_CLASS_OTHER", - 0x0020: "URB_FUNCTION_VENDOR_OTHER", - 0x0021: "URB_FUNCTION_GET_STATUS_FROM_OTHER", - 0x0022: "URB_FUNCTION_CLEAR_FEATURE_TO_OTHER", - 0x0023: "URB_FUNCTION_SET_FEATURE_TO_OTHER", - 0x0024: "URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT", - 0x0025: "URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT", - 0x0026: "URB_FUNCTION_GET_CONFIGURATION", - 0x0027: "URB_FUNCTION_GET_INTERFACE", - 0x0028: "URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE", - 0x0029: "URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE", - 0x002A: "URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR", - 0x0032: "URB_FUNCTION_CONTROL_TRANSFER_EX", - 0x0037: "URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER_USING_CHAINED_MDL", - 0x0002: "URB_FUNCTION_ABORT_PIPE", - 0x001E: "URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL", - 0x0030: "URB_FUNCTION_SYNC_RESET_PIPE", - 0x0031: "URB_FUNCTION_SYNC_CLEAR_STALL", -} - - -class USBpcap(Packet): - name = "USBpcap URB" - fields_desc = [ByteField("headerLen", None), - ByteField("res", 0), - XLELongField("irpId", 0), - LEIntEnumField("usbd_status", 0x0, _usbd_status_codes), - LEShortEnumField("function", 0, _urb_functions), - XByteField("info", 0), - LEShortField("bus", 0), - LEShortField("device", 0), - XByteField("endpoint", 0), - ByteEnumField("transfer", 0, _transfer_types), - LenField("dataLength", None, fmt=" -# Copyright (C) 6WIND -# This program is published under a GPLv2 license - -""" -VRRP (Virtual Router Redundancy Protocol). -""" - -from scapy.packet import Packet, bind_layers -from scapy.fields import BitField, ByteField, FieldLenField, FieldListField, \ - IPField, IntField, XShortField -from scapy.compat import chb, orb -from scapy.layers.inet import IP, in4_chksum, checksum -from scapy.layers.inet6 import IPv6, in6_chksum -from scapy.error import warning - -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] + chb(ck >> 8) + chb(ck & 0xff) + p[8:] - return p - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 9: - ver_n_type = orb(_pkt[0]) - if ver_n_type >= 48 and ver_n_type <= 57: # Version == 3 - return VRRPv3 - return VRRP - - -# RFC 5798 - Virtual Router Redundancy Protocol (VRRP) Version 3 -class VRRPv3(Packet): - fields_desc = [ - BitField("version", 3, 4), - BitField("type", 1, 4), - ByteField("vrid", 1), - ByteField("priority", 100), - FieldLenField("ipcount", None, count_of="addrlist", fmt="B"), - BitField("res", 0, 4), - BitField("adv", 100, 12), - XShortField("chksum", None), - # FIXME: addrlist should also allow IPv6 addresses :/ - FieldListField("addrlist", [], IPField("", "0.0.0.0"), - count_from=lambda pkt: pkt.ipcount)] - - def post_build(self, p, pay): - if self.chksum is None: - if isinstance(self.underlayer, IP): - ck = in4_chksum(112, self.underlayer, p) - elif isinstance(self.underlayer, IPv6): - ck = in6_chksum(112, self.underlayer, p) - else: - warning("No IP(v6) layer to compute checksum on VRRP. Leaving null") # noqa: E501 - ck = 0 - p = p[:6] + chb(ck >> 8) + chb(ck & 0xff) + p[8:] - return p - - @classmethod - def dispatch_hook(cls, _pkt=None, *args, **kargs): - if _pkt and len(_pkt) >= 16: - ver_n_type = orb(_pkt[0]) - if ver_n_type < 48 or ver_n_type > 57: # Version != 3 - return VRRP - return VRRPv3 - - -# IPv6 is supported only on VRRPv3 -# Warning: those layers need to be un-binded in the CARP contrib module. -# If you add/remove any, remember to also edit the one in CARP.py -bind_layers(IP, VRRP, proto=IPPROTO_VRRP) -bind_layers(IP, VRRPv3, proto=IPPROTO_VRRP) -bind_layers(IPv6, VRRPv3, nh=IPPROTO_VRRP) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/vxlan.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/vxlan.py deleted file mode 100755 index e6c1da98cd..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/vxlan.py +++ /dev/null @@ -1,98 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Virtual eXtensible Local Area Network (VXLAN) -- RFC 7348 - - -A Framework for Overlaying Virtualized Layer 2 Networks over Layer 3 Networks -http://tools.ietf.org/html/rfc7348 -https://www.ietf.org/id/draft-ietf-nvo3-vxlan-gpe-02.txt - -VXLAN Group Policy Option: -http://tools.ietf.org/html/draft-smith-vxlan-group-policy-00 -""" - -from scapy.packet import Packet, bind_layers, bind_bottom_up, bind_top_down -from scapy.layers.l2 import Ether -from scapy.layers.inet import IP, UDP -from scapy.layers.inet6 import IPv6 -from scapy.fields import FlagsField, XByteField, ThreeBytesField, \ - ConditionalField, ShortField, ByteEnumField, X3BytesField - -_GP_FLAGS = ["R", "R", "R", "A", "R", "R", "D", "R"] - - -class VXLAN(Packet): - name = "VXLAN" - - fields_desc = [ - FlagsField("flags", 0x8, 8, - ['OAM', 'R', 'NextProtocol', 'Instance', - 'V1', 'V2', 'R', 'G']), - ConditionalField( - ShortField("reserved0", 0), - lambda pkt: pkt.flags.NextProtocol, - ), - ConditionalField( - ByteEnumField('NextProtocol', 0, - {0: 'NotDefined', - 1: 'IPv4', - 2: 'IPv6', - 3: 'Ethernet', - 4: 'NSH'}), - lambda pkt: pkt.flags.NextProtocol, - ), - ConditionalField( - ThreeBytesField("reserved1", 0), - lambda pkt: (not pkt.flags.G) and (not pkt.flags.NextProtocol), - ), - ConditionalField( - FlagsField("gpflags", 0, 8, _GP_FLAGS), - lambda pkt: pkt.flags.G, - ), - ConditionalField( - ShortField("gpid", 0), - lambda pkt: pkt.flags.G, - ), - X3BytesField("vni", 0), - XByteField("reserved2", 0), - ] - - # Use default linux implementation port - overload_fields = { - UDP: {'dport': 8472}, - } - - def mysummary(self): - if self.flags.G: - return self.sprintf("VXLAN (vni=%VXLAN.vni% gpid=%VXLAN.gpid%)") - else: - return self.sprintf("VXLAN (vni=%VXLAN.vni%)") - - -bind_layers(UDP, VXLAN, dport=4789) # RFC standard vxlan port -bind_layers(UDP, VXLAN, dport=4790) # RFC standard vxlan-gpe port -bind_layers(UDP, VXLAN, dport=6633) # New IANA assigned port for use with NSH -bind_layers(UDP, VXLAN, dport=8472) # Linux implementation port -bind_layers(UDP, VXLAN, dport=48879) # Cisco ACI -bind_layers(UDP, VXLAN, sport=4789) -bind_layers(UDP, VXLAN, sport=4790) -bind_layers(UDP, VXLAN, sport=6633) -bind_layers(UDP, VXLAN, sport=8472) -# By default, set both ports to the RFC standard -bind_layers(UDP, VXLAN, sport=4789, dport=4789) - -# Dissection -bind_bottom_up(VXLAN, Ether, NextProtocol=0) -bind_bottom_up(VXLAN, IP, NextProtocol=1) -bind_bottom_up(VXLAN, IPv6, NextProtocol=2) -bind_bottom_up(VXLAN, Ether, NextProtocol=3) -bind_bottom_up(VXLAN, Ether, NextProtocol=None) -# Build -bind_top_down(VXLAN, Ether, flags=12, NextProtocol=0) -bind_top_down(VXLAN, IP, flags=12, NextProtocol=1) -bind_top_down(VXLAN, IPv6, flags=12, NextProtocol=2) -bind_top_down(VXLAN, Ether, flags=12, NextProtocol=3) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/x509.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/x509.py deleted file mode 100644 index 46a741863e..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/x509.py +++ /dev/null @@ -1,1364 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Enhanced by Maxence Tury -# This program is published under a GPLv2 license - -""" -X.509 certificates. -""" - -from scapy.asn1.mib import conf # loads conf.mib -from scapy.asn1.asn1 import ASN1_Codecs, ASN1_OID, \ - ASN1_IA5_STRING, ASN1_NULL, ASN1_PRINTABLE_STRING, \ - ASN1_UTC_TIME, ASN1_UTF8_STRING -from scapy.asn1.ber import BER_tagging_dec, BER_Decoding_Error -from scapy.asn1packet import ASN1_Packet -from scapy.asn1fields import ASN1F_BIT_STRING, ASN1F_BIT_STRING_ENCAPS, \ - ASN1F_BMP_STRING, ASN1F_BOOLEAN, ASN1F_CHOICE, ASN1F_ENUMERATED, \ - ASN1F_FLAGS, ASN1F_GENERALIZED_TIME, ASN1F_IA5_STRING, ASN1F_INTEGER, \ - ASN1F_ISO646_STRING, ASN1F_NULL, ASN1F_OID, ASN1F_PACKET, \ - ASN1F_PRINTABLE_STRING, ASN1F_SEQUENCE, ASN1F_SEQUENCE_OF, ASN1F_SET_OF, \ - ASN1F_STRING, ASN1F_T61_STRING, ASN1F_UNIVERSAL_STRING, ASN1F_UTC_TIME, \ - ASN1F_UTF8_STRING, ASN1F_badsequence, ASN1F_enum_INTEGER, ASN1F_field, \ - ASN1F_optional -from scapy.packet import Packet -from scapy.fields import PacketField -from scapy.volatile import ZuluTime, GeneralizedTime -from scapy.compat import plain_str - - -class ASN1P_OID(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_OID("oid", "0") - - -class ASN1P_INTEGER(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_INTEGER("number", 0) - - -class ASN1P_PRIVSEQ(ASN1_Packet): - # This class gets used in x509.uts - # It showcases the private high-tag decoding capacities of scapy. - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_IA5_STRING("str", ""), - ASN1F_STRING("int", 0), - explicit_tag=0, - flexible_tag=True) - - -####################### -# RSA packets # -####################### -# based on RFC 3447 - -# It could be interesting to use os.urandom and try to generate -# a new modulus each time RSAPublicKey is called with default values. -# (We might have to dig into scapy field initialization mechanisms...) -# NEVER rely on the key below, which is provided only for debugging purposes. -class RSAPublicKey(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_INTEGER("modulus", 10), - ASN1F_INTEGER("publicExponent", 3)) - - -class RSAOtherPrimeInfo(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_INTEGER("prime", 0), - ASN1F_INTEGER("exponent", 0), - ASN1F_INTEGER("coefficient", 0)) - - -class RSAPrivateKey(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_enum_INTEGER("version", 0, ["two-prime", "multi"]), - ASN1F_INTEGER("modulus", 10), - ASN1F_INTEGER("publicExponent", 3), - ASN1F_INTEGER("privateExponent", 3), - ASN1F_INTEGER("prime1", 2), - ASN1F_INTEGER("prime2", 5), - ASN1F_INTEGER("exponent1", 0), - ASN1F_INTEGER("exponent2", 3), - ASN1F_INTEGER("coefficient", 1), - ASN1F_optional( - ASN1F_SEQUENCE_OF("otherPrimeInfos", None, - RSAOtherPrimeInfo))) - -#################################### -# ECDSA packets # -#################################### -# based on RFC 3279 & 5480 & 5915 - - -class ECFieldID(ASN1_Packet): - # No characteristic-two-field support for now. - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_OID("fieldType", "prime-field"), - ASN1F_INTEGER("prime", 0)) - - -class ECCurve(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_STRING("a", ""), - ASN1F_STRING("b", ""), - ASN1F_optional( - ASN1F_BIT_STRING("seed", None))) - - -class ECSpecifiedDomain(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_enum_INTEGER("version", 1, {1: "ecpVer1"}), - ASN1F_PACKET("fieldID", ECFieldID(), ECFieldID), - ASN1F_PACKET("curve", ECCurve(), ECCurve), - ASN1F_STRING("base", ""), - ASN1F_INTEGER("order", 0), - ASN1F_optional( - ASN1F_INTEGER("cofactor", None))) - - -class ECParameters(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_CHOICE("curve", ASN1_OID("ansip384r1"), - ASN1F_OID, # for named curves - ASN1F_NULL, # for implicit curves - ECSpecifiedDomain) - - -class ECDSAPublicKey(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_BIT_STRING("ecPoint", "") - - -class ECDSAPrivateKey(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_enum_INTEGER("version", 1, {1: "ecPrivkeyVer1"}), - ASN1F_STRING("privateKey", ""), - ASN1F_optional( - ASN1F_PACKET("parameters", None, ECParameters, - explicit_tag=0xa0)), - ASN1F_optional( - ASN1F_PACKET("publicKey", None, - ECDSAPublicKey, - explicit_tag=0xa1))) - - -class ECDSASignature(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_INTEGER("r", 0), - ASN1F_INTEGER("s", 0)) - - -###################### -# X509 packets # -###################### -# based on RFC 5280 - - -# Names # - -class ASN1F_X509_DirectoryString(ASN1F_CHOICE): - # we include ASN1 bit strings for rare instances of x500 addresses - def __init__(self, name, default, **kwargs): - ASN1F_CHOICE.__init__(self, name, default, - ASN1F_PRINTABLE_STRING, ASN1F_UTF8_STRING, - ASN1F_IA5_STRING, ASN1F_T61_STRING, - ASN1F_UNIVERSAL_STRING, ASN1F_BIT_STRING, - **kwargs) - - -class X509_AttributeValue(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_CHOICE("value", ASN1_PRINTABLE_STRING("FR"), - ASN1F_PRINTABLE_STRING, ASN1F_UTF8_STRING, - ASN1F_IA5_STRING, ASN1F_T61_STRING, - ASN1F_UNIVERSAL_STRING) - - -class X509_Attribute(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_OID("type", "2.5.4.6"), - ASN1F_SET_OF("values", - [X509_AttributeValue()], - X509_AttributeValue)) - - -class X509_AttributeTypeAndValue(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_OID("type", "2.5.4.6"), - ASN1F_X509_DirectoryString("value", - ASN1_PRINTABLE_STRING("FR"))) - - -class X509_RDN(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SET_OF("rdn", [X509_AttributeTypeAndValue()], - X509_AttributeTypeAndValue) - - -class X509_OtherName(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_OID("type_id", "0"), - ASN1F_CHOICE("value", None, - ASN1F_IA5_STRING, ASN1F_ISO646_STRING, - ASN1F_BMP_STRING, ASN1F_UTF8_STRING, - explicit_tag=0xa0)) - - -class X509_RFC822Name(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_IA5_STRING("rfc822Name", "") - - -class X509_DNSName(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_IA5_STRING("dNSName", "") - -# XXX write me - - -class X509_X400Address(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_field("x400Address", "") - - -_default_directoryName = [ - X509_RDN(), - X509_RDN( - rdn=[X509_AttributeTypeAndValue( - type="2.5.4.10", - value=ASN1_PRINTABLE_STRING("Scapy, Inc."))]), - X509_RDN( - rdn=[X509_AttributeTypeAndValue( - type="2.5.4.3", - value=ASN1_PRINTABLE_STRING("Scapy Default Name"))]) -] - - -class X509_DirectoryName(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("directoryName", _default_directoryName, - X509_RDN) - - -class X509_EDIPartyName(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_optional( - ASN1F_X509_DirectoryString("nameAssigner", None, - explicit_tag=0xa0)), - ASN1F_X509_DirectoryString("partyName", None, - explicit_tag=0xa1)) - - -class X509_URI(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_IA5_STRING("uniformResourceIdentifier", "") - - -class X509_IPAddress(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_STRING("iPAddress", "") - - -class X509_RegisteredID(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_OID("registeredID", "") - - -class X509_GeneralName(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_CHOICE("generalName", X509_DirectoryName(), - ASN1F_PACKET("otherName", None, X509_OtherName, - implicit_tag=0xa0), - ASN1F_PACKET("rfc822Name", None, X509_RFC822Name, - implicit_tag=0x81), - ASN1F_PACKET("dNSName", None, X509_DNSName, - implicit_tag=0x82), - ASN1F_PACKET("x400Address", None, X509_X400Address, # noqa: E501 - explicit_tag=0xa3), - ASN1F_PACKET("directoryName", None, X509_DirectoryName, # noqa: E501 - explicit_tag=0xa4), - ASN1F_PACKET("ediPartyName", None, X509_EDIPartyName, # noqa: E501 - explicit_tag=0xa5), - ASN1F_PACKET("uniformResourceIdentifier", None, X509_URI, # noqa: E501 - implicit_tag=0x86), - ASN1F_PACKET("ipAddress", None, X509_IPAddress, - implicit_tag=0x87), - ASN1F_PACKET("registeredID", None, X509_RegisteredID, # noqa: E501 - implicit_tag=0x88)) - - -# Extensions # - -class X509_ExtAuthorityKeyIdentifier(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_optional( - ASN1F_STRING("keyIdentifier", b"\xff" * 20, - implicit_tag=0x80)), - ASN1F_optional( - ASN1F_SEQUENCE_OF("authorityCertIssuer", None, - X509_GeneralName, - implicit_tag=0xa1)), - ASN1F_optional( - ASN1F_INTEGER("authorityCertSerialNumber", None, - implicit_tag=0x82))) - - -class X509_ExtSubjectDirectoryAttributes(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("subjectDirectoryAttributes", - [X509_Attribute()], - X509_Attribute) - - -class X509_ExtSubjectKeyIdentifier(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_STRING("keyIdentifier", "xff" * 20) - - -class X509_ExtFullName(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("fullName", [X509_GeneralName()], - X509_GeneralName, implicit_tag=0xa0) - - -class X509_ExtNameRelativeToCRLIssuer(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_PACKET("nameRelativeToCRLIssuer", X509_RDN(), X509_RDN, - implicit_tag=0xa1) - - -class X509_ExtDistributionPointName(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_CHOICE("distributionPointName", None, - X509_ExtFullName, X509_ExtNameRelativeToCRLIssuer) - - -_reasons_mapping = ["unused", - "keyCompromise", - "cACompromise", - "affiliationChanged", - "superseded", - "cessationOfOperation", - "certificateHold", - "privilegeWithdrawn", - "aACompromise"] - - -class X509_ExtDistributionPoint(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_optional( - ASN1F_PACKET("distributionPoint", - X509_ExtDistributionPointName(), - X509_ExtDistributionPointName, - explicit_tag=0xa0)), - ASN1F_optional( - ASN1F_FLAGS("reasons", None, _reasons_mapping, - implicit_tag=0x81)), - ASN1F_optional( - ASN1F_SEQUENCE_OF("cRLIssuer", None, - X509_GeneralName, - implicit_tag=0xa2))) - - -_ku_mapping = ["digitalSignature", - "nonRepudiation", - "keyEncipherment", - "dataEncipherment", - "keyAgreement", - "keyCertSign", - "cRLSign", - "encipherOnly", - "decipherOnly"] - - -class X509_ExtKeyUsage(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_FLAGS("keyUsage", "101", _ku_mapping) - - def get_keyUsage(self): - return self.ASN1_root.get_flags(self) - - -class X509_ExtPrivateKeyUsagePeriod(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_optional( - ASN1F_GENERALIZED_TIME("notBefore", - str(GeneralizedTime(-600)), - implicit_tag=0x80)), - ASN1F_optional( - ASN1F_GENERALIZED_TIME("notAfter", - str(GeneralizedTime(+86400)), - implicit_tag=0x81))) - - -class X509_PolicyMapping(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_OID("issuerDomainPolicy", None), - ASN1F_OID("subjectDomainPolicy", None)) - - -class X509_ExtPolicyMappings(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("policyMappings", [], X509_PolicyMapping) - - -class X509_ExtBasicConstraints(ASN1_Packet): - # The cA field should not be optional, but some certs omit it for False. - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_optional( - ASN1F_BOOLEAN("cA", False)), - ASN1F_optional( - ASN1F_INTEGER("pathLenConstraint", None))) - - -class X509_ExtCRLNumber(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_INTEGER("cRLNumber", 0) - - -_cRL_reasons = ["unspecified", - "keyCompromise", - "cACompromise", - "affiliationChanged", - "superseded", - "cessationOfOperation", - "certificateHold", - "unused_reasonCode", - "removeFromCRL", - "privilegeWithdrawn", - "aACompromise"] - - -class X509_ExtReasonCode(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_ENUMERATED("cRLReason", 0, _cRL_reasons) - - -class X509_ExtDeltaCRLIndicator(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_INTEGER("deltaCRLIndicator", 0) - - -class X509_ExtIssuingDistributionPoint(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_optional( - ASN1F_PACKET("distributionPoint", - X509_ExtDistributionPointName(), - X509_ExtDistributionPointName, - explicit_tag=0xa0)), - ASN1F_BOOLEAN("onlyContainsUserCerts", False, - implicit_tag=0x81), - ASN1F_BOOLEAN("onlyContainsCACerts", False, - implicit_tag=0x82), - ASN1F_optional( - ASN1F_FLAGS("onlySomeReasons", None, - _reasons_mapping, - implicit_tag=0x83)), - ASN1F_BOOLEAN("indirectCRL", False, - implicit_tag=0x84), - ASN1F_BOOLEAN("onlyContainsAttributeCerts", False, - implicit_tag=0x85)) - - -class X509_ExtCertificateIssuer(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("certificateIssuer", [], X509_GeneralName) - - -class X509_ExtInvalidityDate(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_GENERALIZED_TIME("invalidityDate", str(ZuluTime(+86400))) - - -class X509_ExtSubjectAltName(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("subjectAltName", [], X509_GeneralName) - - -class X509_ExtIssuerAltName(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("issuerAltName", [], X509_GeneralName) - - -class X509_ExtGeneralSubtree(ASN1_Packet): - # 'minimum' is not optional in RFC 5280, yet it is in some implementations. - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_PACKET("base", X509_GeneralName(), X509_GeneralName), - ASN1F_optional( - ASN1F_INTEGER("minimum", None, implicit_tag=0x80)), - ASN1F_optional( - ASN1F_INTEGER("maximum", None, implicit_tag=0x81))) - - -class X509_ExtNameConstraints(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_optional( - ASN1F_SEQUENCE_OF("permittedSubtrees", None, - X509_ExtGeneralSubtree, - implicit_tag=0xa0)), - ASN1F_optional( - ASN1F_SEQUENCE_OF("excludedSubtrees", None, - X509_ExtGeneralSubtree, - implicit_tag=0xa1))) - - -class X509_ExtPolicyConstraints(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_optional( - ASN1F_INTEGER("requireExplicitPolicy", None, - implicit_tag=0x80)), - ASN1F_optional( - ASN1F_INTEGER("inhibitPolicyMapping", None, - implicit_tag=0x81))) - - -class X509_ExtExtendedKeyUsage(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("extendedKeyUsage", [], ASN1P_OID) - - def get_extendedKeyUsage(self): - eku_array = self.extendedKeyUsage - return [eku.oid.oidname for eku in eku_array] - - -class X509_ExtNoticeReference(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_CHOICE("organization", - ASN1_UTF8_STRING("Dummy Organization"), - ASN1F_IA5_STRING, ASN1F_ISO646_STRING, - ASN1F_BMP_STRING, ASN1F_UTF8_STRING), - ASN1F_SEQUENCE_OF("noticeNumbers", [], ASN1P_INTEGER)) - - -class X509_ExtUserNotice(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_optional( - ASN1F_PACKET("noticeRef", None, - X509_ExtNoticeReference)), - ASN1F_optional( - ASN1F_CHOICE("explicitText", - ASN1_UTF8_STRING("Dummy ExplicitText"), - ASN1F_IA5_STRING, ASN1F_ISO646_STRING, - ASN1F_BMP_STRING, ASN1F_UTF8_STRING))) - - -class X509_ExtPolicyQualifierInfo(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_OID("policyQualifierId", "1.3.6.1.5.5.7.2.1"), - ASN1F_CHOICE("qualifier", ASN1_IA5_STRING("cps_str"), - ASN1F_IA5_STRING, X509_ExtUserNotice)) - - -class X509_ExtPolicyInformation(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_OID("policyIdentifier", "2.5.29.32.0"), - ASN1F_optional( - ASN1F_SEQUENCE_OF("policyQualifiers", None, - X509_ExtPolicyQualifierInfo))) - - -class X509_ExtCertificatePolicies(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("certificatePolicies", - [X509_ExtPolicyInformation()], - X509_ExtPolicyInformation) - - -class X509_ExtCRLDistributionPoints(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("cRLDistributionPoints", - [X509_ExtDistributionPoint()], - X509_ExtDistributionPoint) - - -class X509_ExtInhibitAnyPolicy(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_INTEGER("skipCerts", 0) - - -class X509_ExtFreshestCRL(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("cRLDistributionPoints", - [X509_ExtDistributionPoint()], - X509_ExtDistributionPoint) - - -class X509_AccessDescription(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_OID("accessMethod", "0"), - ASN1F_PACKET("accessLocation", X509_GeneralName(), - X509_GeneralName)) - - -class X509_ExtAuthInfoAccess(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("authorityInfoAccess", - [X509_AccessDescription()], - X509_AccessDescription) - - -class X509_ExtQcStatement(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_OID("statementId", "0.4.0.1862.1.1"), - ASN1F_optional( - ASN1F_field("statementInfo", None))) - - -class X509_ExtQcStatements(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("qcStatements", - [X509_ExtQcStatement()], - X509_ExtQcStatement) - - -class X509_ExtSubjInfoAccess(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("subjectInfoAccess", - [X509_AccessDescription()], - X509_AccessDescription) - - -class X509_ExtNetscapeCertType(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_BIT_STRING("netscapeCertType", "") - - -class X509_ExtComment(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_CHOICE("comment", - ASN1_UTF8_STRING("Dummy comment."), - ASN1F_IA5_STRING, ASN1F_ISO646_STRING, - ASN1F_BMP_STRING, ASN1F_UTF8_STRING) - - -class X509_ExtDefault(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_field("value", None) - - -# oid-info.com shows that some extensions share multiple OIDs. -# Here we only reproduce those written in RFC5280. -_ext_mapping = { - "2.5.29.9": X509_ExtSubjectDirectoryAttributes, - "2.5.29.14": X509_ExtSubjectKeyIdentifier, - "2.5.29.15": X509_ExtKeyUsage, - "2.5.29.16": X509_ExtPrivateKeyUsagePeriod, - "2.5.29.17": X509_ExtSubjectAltName, - "2.5.29.18": X509_ExtIssuerAltName, - "2.5.29.19": X509_ExtBasicConstraints, - "2.5.29.20": X509_ExtCRLNumber, - "2.5.29.21": X509_ExtReasonCode, - "2.5.29.24": X509_ExtInvalidityDate, - "2.5.29.27": X509_ExtDeltaCRLIndicator, - "2.5.29.28": X509_ExtIssuingDistributionPoint, - "2.5.29.29": X509_ExtCertificateIssuer, - "2.5.29.30": X509_ExtNameConstraints, - "2.5.29.31": X509_ExtCRLDistributionPoints, - "2.5.29.32": X509_ExtCertificatePolicies, - "2.5.29.33": X509_ExtPolicyMappings, - "2.5.29.35": X509_ExtAuthorityKeyIdentifier, - "2.5.29.36": X509_ExtPolicyConstraints, - "2.5.29.37": X509_ExtExtendedKeyUsage, - "2.5.29.46": X509_ExtFreshestCRL, - "2.5.29.54": X509_ExtInhibitAnyPolicy, - "2.16.840.1.113730.1.1": X509_ExtNetscapeCertType, - "2.16.840.1.113730.1.13": X509_ExtComment, - "1.3.6.1.5.5.7.1.1": X509_ExtAuthInfoAccess, - "1.3.6.1.5.5.7.1.3": X509_ExtQcStatements, - "1.3.6.1.5.5.7.1.11": X509_ExtSubjInfoAccess -} - - -class ASN1F_EXT_SEQUENCE(ASN1F_SEQUENCE): - # We use explicit_tag=0x04 with extnValue as STRING encapsulation. - def __init__(self, **kargs): - seq = [ASN1F_OID("extnID", "2.5.29.19"), - ASN1F_optional( - ASN1F_BOOLEAN("critical", False)), - ASN1F_PACKET("extnValue", - X509_ExtBasicConstraints(), - X509_ExtBasicConstraints, - explicit_tag=0x04)] - ASN1F_SEQUENCE.__init__(self, *seq, **kargs) - - def dissect(self, pkt, s): - _, s = BER_tagging_dec(s, implicit_tag=self.implicit_tag, - explicit_tag=self.explicit_tag, - safe=self.flexible_tag) - codec = self.ASN1_tag.get_codec(pkt.ASN1_codec) - i, s, remain = codec.check_type_check_len(s) - extnID = self.seq[0] - critical = self.seq[1] - try: - oid, s = extnID.m2i(pkt, s) - extnID.set_val(pkt, oid) - s = critical.dissect(pkt, s) - encapsed = X509_ExtDefault - if oid.val in _ext_mapping: - encapsed = _ext_mapping[oid.val] - self.seq[2].cls = encapsed - self.seq[2].cls.ASN1_root.flexible_tag = True - # there are too many private extensions not to be flexible here - self.seq[2].default = encapsed() - s = self.seq[2].dissect(pkt, s) - if not self.flexible_tag and len(s) > 0: - err_msg = "extension sequence length issue" - raise BER_Decoding_Error(err_msg, remaining=s) - except ASN1F_badsequence: - raise Exception("could not parse extensions") - return remain - - -class X509_Extension(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_EXT_SEQUENCE() - - -class X509_Extensions(ASN1_Packet): - # we use this in OCSP status requests, in tls/handshake.py - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_optional( - ASN1F_SEQUENCE_OF("extensions", - None, X509_Extension)) - - -# Public key wrapper # - -class X509_AlgorithmIdentifier(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_OID("algorithm", "1.2.840.113549.1.1.11"), - ASN1F_optional( - ASN1F_CHOICE("parameters", ASN1_NULL(0), - ASN1F_NULL, ECParameters))) - - -class ASN1F_X509_SubjectPublicKeyInfoRSA(ASN1F_SEQUENCE): - def __init__(self, **kargs): - seq = [ASN1F_PACKET("signatureAlgorithm", - X509_AlgorithmIdentifier(), - X509_AlgorithmIdentifier), - ASN1F_BIT_STRING_ENCAPS("subjectPublicKey", - RSAPublicKey(), - RSAPublicKey)] - ASN1F_SEQUENCE.__init__(self, *seq, **kargs) - - -class ASN1F_X509_SubjectPublicKeyInfoECDSA(ASN1F_SEQUENCE): - def __init__(self, **kargs): - seq = [ASN1F_PACKET("signatureAlgorithm", - X509_AlgorithmIdentifier(), - X509_AlgorithmIdentifier), - ASN1F_PACKET("subjectPublicKey", ECDSAPublicKey(), - ECDSAPublicKey)] - ASN1F_SEQUENCE.__init__(self, *seq, **kargs) - - -class ASN1F_X509_SubjectPublicKeyInfo(ASN1F_SEQUENCE): - def __init__(self, **kargs): - seq = [ASN1F_PACKET("signatureAlgorithm", - X509_AlgorithmIdentifier(), - X509_AlgorithmIdentifier), - ASN1F_BIT_STRING("subjectPublicKey", None)] - ASN1F_SEQUENCE.__init__(self, *seq, **kargs) - - def m2i(self, pkt, x): - c, s = ASN1F_SEQUENCE.m2i(self, pkt, x) - keytype = pkt.fields["signatureAlgorithm"].algorithm.oidname - if "rsa" in keytype.lower(): - return ASN1F_X509_SubjectPublicKeyInfoRSA().m2i(pkt, x) - elif keytype == "ecPublicKey": - return ASN1F_X509_SubjectPublicKeyInfoECDSA().m2i(pkt, x) - else: - raise Exception("could not parse subjectPublicKeyInfo") - - def dissect(self, pkt, s): - c, x = self.m2i(pkt, s) - return x - - def build(self, pkt): - if "signatureAlgorithm" in pkt.fields: - ktype = pkt.fields['signatureAlgorithm'].algorithm.oidname - else: - ktype = pkt.default_fields["signatureAlgorithm"].algorithm.oidname - if "rsa" in ktype.lower(): - pkt.default_fields["subjectPublicKey"] = RSAPublicKey() - return ASN1F_X509_SubjectPublicKeyInfoRSA().build(pkt) - elif ktype == "ecPublicKey": - pkt.default_fields["subjectPublicKey"] = ECDSAPublicKey() - return ASN1F_X509_SubjectPublicKeyInfoECDSA().build(pkt) - else: - raise Exception("could not build subjectPublicKeyInfo") - - -class X509_SubjectPublicKeyInfo(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_X509_SubjectPublicKeyInfo() - - -# OpenSSL compatibility wrappers # - -# XXX As ECDSAPrivateKey already uses the structure from RFC 5958, -# and as we would prefer encapsulated RSA private keys to be parsed, -# this lazy implementation actually supports RSA encoding only. -# We'd rather call it RSAPrivateKey_OpenSSL than X509_PrivateKeyInfo. -class RSAPrivateKey_OpenSSL(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_enum_INTEGER("version", 0, ["v1", "v2"]), - ASN1F_PACKET("privateKeyAlgorithm", - X509_AlgorithmIdentifier(), - X509_AlgorithmIdentifier), - ASN1F_PACKET("privateKey", - RSAPrivateKey(), - RSAPrivateKey, - explicit_tag=0x04), - ASN1F_optional( - ASN1F_PACKET("parameters", None, ECParameters, - explicit_tag=0xa0)), - ASN1F_optional( - ASN1F_PACKET("publicKey", None, - ECDSAPublicKey, - explicit_tag=0xa1))) - -# We need this hack because ECParameters parsing below must return -# a Padding payload, and making the ASN1_Packet class have Padding -# instead of Raw payload would break things... - - -class _PacketFieldRaw(PacketField): - def getfield(self, pkt, s): - i = self.m2i(pkt, s) - remain = "" - if conf.raw_layer in i: - r = i[conf.raw_layer] - del(r.underlayer.payload) - remain = r.load - return remain, i - - -class ECDSAPrivateKey_OpenSSL(Packet): - name = "ECDSA Params + Private Key" - fields_desc = [_PacketFieldRaw("ecparam", - ECParameters(), - ECParameters), - PacketField("privateKey", - ECDSAPrivateKey(), - ECDSAPrivateKey)] - - -# TBSCertificate & Certificate # - -_default_issuer = [ - X509_RDN(), - X509_RDN( - rdn=[X509_AttributeTypeAndValue( - type="2.5.4.10", - value=ASN1_PRINTABLE_STRING("Scapy, Inc."))]), - X509_RDN( - rdn=[X509_AttributeTypeAndValue( - type="2.5.4.3", - value=ASN1_PRINTABLE_STRING("Scapy Default Issuer"))]) -] - -_default_subject = [ - X509_RDN(), - X509_RDN( - rdn=[X509_AttributeTypeAndValue( - type="2.5.4.10", - value=ASN1_PRINTABLE_STRING("Scapy, Inc."))]), - X509_RDN( - rdn=[X509_AttributeTypeAndValue( - type="2.5.4.3", - value=ASN1_PRINTABLE_STRING("Scapy Default Subject"))]) -] - - -class X509_Validity(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_CHOICE("not_before", - ASN1_UTC_TIME(str(ZuluTime(-600))), - ASN1F_UTC_TIME, ASN1F_GENERALIZED_TIME), - ASN1F_CHOICE("not_after", - ASN1_UTC_TIME(str(ZuluTime(+86400))), - ASN1F_UTC_TIME, ASN1F_GENERALIZED_TIME)) - - -_attrName_mapping = [ - ("countryName", "C"), - ("stateOrProvinceName", "ST"), - ("localityName", "L"), - ("organizationName", "O"), - ("organizationUnitName", "OU"), - ("commonName", "CN") -] -_attrName_specials = [name for name, symbol in _attrName_mapping] - - -class X509_TBSCertificate(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_optional( - ASN1F_enum_INTEGER("version", 0x2, ["v1", "v2", "v3"], - explicit_tag=0xa0)), - ASN1F_INTEGER("serialNumber", 1), - ASN1F_PACKET("signature", - X509_AlgorithmIdentifier(), - X509_AlgorithmIdentifier), - ASN1F_SEQUENCE_OF("issuer", _default_issuer, X509_RDN), - ASN1F_PACKET("validity", - X509_Validity(), - X509_Validity), - ASN1F_SEQUENCE_OF("subject", _default_subject, X509_RDN), - ASN1F_PACKET("subjectPublicKeyInfo", - X509_SubjectPublicKeyInfo(), - X509_SubjectPublicKeyInfo), - ASN1F_optional( - ASN1F_BIT_STRING("issuerUniqueID", None, - implicit_tag=0x81)), - ASN1F_optional( - ASN1F_BIT_STRING("subjectUniqueID", None, - implicit_tag=0x82)), - ASN1F_optional( - ASN1F_SEQUENCE_OF("extensions", - [X509_Extension()], - X509_Extension, - explicit_tag=0xa3))) - - def get_issuer(self): - attrs = self.issuer - attrsDict = {} - for attr in attrs: - # we assume there is only one name in each rdn ASN1_SET - attrsDict[attr.rdn[0].type.oidname] = plain_str(attr.rdn[0].value.val) # noqa: E501 - return attrsDict - - def get_issuer_str(self): - """ - Returns a one-line string containing every type/value - in a rather specific order. sorted() built-in ensures unicity. - """ - name_str = "" - attrsDict = self.get_issuer() - for attrType, attrSymbol in _attrName_mapping: - if attrType in attrsDict: - name_str += "/" + attrSymbol + "=" - name_str += attrsDict[attrType] - for attrType in sorted(attrsDict): - if attrType not in _attrName_specials: - name_str += "/" + attrType + "=" - name_str += attrsDict[attrType] - return name_str - - def get_subject(self): - attrs = self.subject - attrsDict = {} - for attr in attrs: - # we assume there is only one name in each rdn ASN1_SET - attrsDict[attr.rdn[0].type.oidname] = plain_str(attr.rdn[0].value.val) # noqa: E501 - return attrsDict - - def get_subject_str(self): - name_str = "" - attrsDict = self.get_subject() - for attrType, attrSymbol in _attrName_mapping: - if attrType in attrsDict: - name_str += "/" + attrSymbol + "=" - name_str += attrsDict[attrType] - for attrType in sorted(attrsDict): - if attrType not in _attrName_specials: - name_str += "/" + attrType + "=" - name_str += attrsDict[attrType] - return name_str - - -class ASN1F_X509_CertECDSA(ASN1F_SEQUENCE): - def __init__(self, **kargs): - seq = [ASN1F_PACKET("tbsCertificate", - X509_TBSCertificate(), - X509_TBSCertificate), - ASN1F_PACKET("signatureAlgorithm", - X509_AlgorithmIdentifier(), - X509_AlgorithmIdentifier), - ASN1F_BIT_STRING_ENCAPS("signatureValue", - ECDSASignature(), - ECDSASignature)] - ASN1F_SEQUENCE.__init__(self, *seq, **kargs) - - -class ASN1F_X509_Cert(ASN1F_SEQUENCE): - def __init__(self, **kargs): - seq = [ASN1F_PACKET("tbsCertificate", - X509_TBSCertificate(), - X509_TBSCertificate), - ASN1F_PACKET("signatureAlgorithm", - X509_AlgorithmIdentifier(), - X509_AlgorithmIdentifier), - ASN1F_BIT_STRING("signatureValue", - "defaultsignature" * 2)] - ASN1F_SEQUENCE.__init__(self, *seq, **kargs) - - def m2i(self, pkt, x): - c, s = ASN1F_SEQUENCE.m2i(self, pkt, x) - sigtype = pkt.fields["signatureAlgorithm"].algorithm.oidname - if "rsa" in sigtype.lower(): - return c, s - elif "ecdsa" in sigtype.lower(): - return ASN1F_X509_CertECDSA().m2i(pkt, x) - else: - raise Exception("could not parse certificate") - - def dissect(self, pkt, s): - c, x = self.m2i(pkt, s) - return x - - def build(self, pkt): - if "signatureAlgorithm" in pkt.fields: - sigtype = pkt.fields['signatureAlgorithm'].algorithm.oidname - else: - sigtype = pkt.default_fields["signatureAlgorithm"].algorithm.oidname # noqa: E501 - if "rsa" in sigtype.lower(): - return ASN1F_SEQUENCE.build(self, pkt) - elif "ecdsa" in sigtype.lower(): - pkt.default_fields["signatureValue"] = ECDSASignature() - return ASN1F_X509_CertECDSA().build(pkt) - else: - raise Exception("could not build certificate") - - -class X509_Cert(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_X509_Cert() - - -# TBSCertList & CRL # - -class X509_RevokedCertificate(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE(ASN1F_INTEGER("serialNumber", 1), - ASN1F_UTC_TIME("revocationDate", - str(ZuluTime(+86400))), - ASN1F_optional( - ASN1F_SEQUENCE_OF("crlEntryExtensions", - None, X509_Extension))) - - -class X509_TBSCertList(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_optional( - ASN1F_enum_INTEGER("version", 1, ["v1", "v2"])), - ASN1F_PACKET("signature", - X509_AlgorithmIdentifier(), - X509_AlgorithmIdentifier), - ASN1F_SEQUENCE_OF("issuer", _default_issuer, X509_RDN), - ASN1F_UTC_TIME("this_update", str(ZuluTime(-1))), - ASN1F_optional( - ASN1F_UTC_TIME("next_update", None)), - ASN1F_optional( - ASN1F_SEQUENCE_OF("revokedCertificates", None, - X509_RevokedCertificate)), - ASN1F_optional( - ASN1F_SEQUENCE_OF("crlExtensions", None, - X509_Extension, - explicit_tag=0xa0))) - - def get_issuer(self): - attrs = self.issuer - attrsDict = {} - for attr in attrs: - # we assume there is only one name in each rdn ASN1_SET - attrsDict[attr.rdn[0].type.oidname] = plain_str(attr.rdn[0].value.val) # noqa: E501 - return attrsDict - - def get_issuer_str(self): - """ - Returns a one-line string containing every type/value - in a rather specific order. sorted() built-in ensures unicity. - """ - name_str = "" - attrsDict = self.get_issuer() - for attrType, attrSymbol in _attrName_mapping: - if attrType in attrsDict: - name_str += "/" + attrSymbol + "=" - name_str += attrsDict[attrType] - for attrType in sorted(attrsDict): - if attrType not in _attrName_specials: - name_str += "/" + attrType + "=" - name_str += attrsDict[attrType] - return name_str - - -class ASN1F_X509_CRLECDSA(ASN1F_SEQUENCE): - def __init__(self, **kargs): - seq = [ASN1F_PACKET("tbsCertList", - X509_TBSCertList(), - X509_TBSCertList), - ASN1F_PACKET("signatureAlgorithm", - X509_AlgorithmIdentifier(), - X509_AlgorithmIdentifier), - ASN1F_BIT_STRING_ENCAPS("signatureValue", - ECDSASignature(), - ECDSASignature)] - ASN1F_SEQUENCE.__init__(self, *seq, **kargs) - - -class ASN1F_X509_CRL(ASN1F_SEQUENCE): - def __init__(self, **kargs): - seq = [ASN1F_PACKET("tbsCertList", - X509_TBSCertList(), - X509_TBSCertList), - ASN1F_PACKET("signatureAlgorithm", - X509_AlgorithmIdentifier(), - X509_AlgorithmIdentifier), - ASN1F_BIT_STRING("signatureValue", - "defaultsignature" * 2)] - ASN1F_SEQUENCE.__init__(self, *seq, **kargs) - - def m2i(self, pkt, x): - c, s = ASN1F_SEQUENCE.m2i(self, pkt, x) - sigtype = pkt.fields["signatureAlgorithm"].algorithm.oidname - if "rsa" in sigtype.lower(): - return c, s - elif "ecdsa" in sigtype.lower(): - return ASN1F_X509_CRLECDSA().m2i(pkt, x) - else: - raise Exception("could not parse certificate") - - def dissect(self, pkt, s): - c, x = self.m2i(pkt, s) - return x - - def build(self, pkt): - if "signatureAlgorithm" in pkt.fields: - sigtype = pkt.fields['signatureAlgorithm'].algorithm.oidname - else: - sigtype = pkt.default_fields["signatureAlgorithm"].algorithm.oidname # noqa: E501 - if "rsa" in sigtype.lower(): - return ASN1F_SEQUENCE.build(self, pkt) - elif "ecdsa" in sigtype.lower(): - pkt.default_fields["signatureValue"] = ECDSASignature() - return ASN1F_X509_CRLECDSA().build(pkt) - else: - raise Exception("could not build certificate") - - -class X509_CRL(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_X509_CRL() - - -############################# -# OCSP Status packets # -############################# -# based on RFC 6960 - -class OCSP_CertID(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_PACKET("hashAlgorithm", - X509_AlgorithmIdentifier(), - X509_AlgorithmIdentifier), - ASN1F_STRING("issuerNameHash", ""), - ASN1F_STRING("issuerKeyHash", ""), - ASN1F_INTEGER("serialNumber", 0)) - - -class OCSP_GoodInfo(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_NULL("info", 0) - - -class OCSP_RevokedInfo(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_GENERALIZED_TIME("revocationTime", ""), - ASN1F_optional( - ASN1F_PACKET("revocationReason", None, - X509_ExtReasonCode, - explicit_tag=0x80))) - - -class OCSP_UnknownInfo(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_NULL("info", 0) - - -class OCSP_CertStatus(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_CHOICE("certStatus", None, - ASN1F_PACKET("good", OCSP_GoodInfo(), - OCSP_GoodInfo, implicit_tag=0x80), - ASN1F_PACKET("revoked", OCSP_RevokedInfo(), - OCSP_RevokedInfo, implicit_tag=0xa1), - ASN1F_PACKET("unknown", OCSP_UnknownInfo(), - OCSP_UnknownInfo, implicit_tag=0x82)) - - -class OCSP_SingleResponse(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_PACKET("certID", OCSP_CertID(), OCSP_CertID), - ASN1F_PACKET("certStatus", OCSP_CertStatus(), - OCSP_CertStatus), - ASN1F_GENERALIZED_TIME("thisUpdate", ""), - ASN1F_optional( - ASN1F_GENERALIZED_TIME("nextUpdate", "", - explicit_tag=0xa0)), - ASN1F_optional( - ASN1F_SEQUENCE_OF("singleExtensions", None, - X509_Extension, - explicit_tag=0xa1))) - - -class OCSP_ByName(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE_OF("byName", [], X509_RDN) - - -class OCSP_ByKey(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_STRING("byKey", "") - - -class OCSP_ResponderID(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_CHOICE("responderID", None, - ASN1F_PACKET("byName", OCSP_ByName(), OCSP_ByName, - explicit_tag=0xa1), - ASN1F_PACKET("byKey", OCSP_ByKey(), OCSP_ByKey, - explicit_tag=0xa2)) - - -class OCSP_ResponseData(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_optional( - ASN1F_enum_INTEGER("version", 0, {0: "v1"}, - explicit_tag=0x80)), - ASN1F_PACKET("responderID", OCSP_ResponderID(), - OCSP_ResponderID), - ASN1F_GENERALIZED_TIME("producedAt", - str(GeneralizedTime())), - ASN1F_SEQUENCE_OF("responses", [], OCSP_SingleResponse), - ASN1F_optional( - ASN1F_SEQUENCE_OF("responseExtensions", None, - X509_Extension, - explicit_tag=0xa1))) - - -class ASN1F_OCSP_BasicResponseECDSA(ASN1F_SEQUENCE): - def __init__(self, **kargs): - seq = [ASN1F_PACKET("tbsResponseData", - OCSP_ResponseData(), - OCSP_ResponseData), - ASN1F_PACKET("signatureAlgorithm", - X509_AlgorithmIdentifier(), - X509_AlgorithmIdentifier), - ASN1F_BIT_STRING_ENCAPS("signature", - ECDSASignature(), - ECDSASignature), - ASN1F_optional( - ASN1F_SEQUENCE_OF("certs", None, X509_Cert, - explicit_tag=0xa0))] - ASN1F_SEQUENCE.__init__(self, *seq, **kargs) - - -class ASN1F_OCSP_BasicResponse(ASN1F_SEQUENCE): - def __init__(self, **kargs): - seq = [ASN1F_PACKET("tbsResponseData", - OCSP_ResponseData(), - OCSP_ResponseData), - ASN1F_PACKET("signatureAlgorithm", - X509_AlgorithmIdentifier(), - X509_AlgorithmIdentifier), - ASN1F_BIT_STRING("signature", - "defaultsignature" * 2), - ASN1F_optional( - ASN1F_SEQUENCE_OF("certs", None, X509_Cert, - explicit_tag=0xa0))] - ASN1F_SEQUENCE.__init__(self, *seq, **kargs) - - def m2i(self, pkt, x): - c, s = ASN1F_SEQUENCE.m2i(self, pkt, x) - sigtype = pkt.fields["signatureAlgorithm"].algorithm.oidname - if "rsa" in sigtype.lower(): - return c, s - elif "ecdsa" in sigtype.lower(): - return ASN1F_OCSP_BasicResponseECDSA().m2i(pkt, x) - else: - raise Exception("could not parse OCSP basic response") - - def dissect(self, pkt, s): - c, x = self.m2i(pkt, s) - return x - - def build(self, pkt): - if "signatureAlgorithm" in pkt.fields: - sigtype = pkt.fields['signatureAlgorithm'].algorithm.oidname - else: - sigtype = pkt.default_fields["signatureAlgorithm"].algorithm.oidname # noqa: E501 - if "rsa" in sigtype.lower(): - return ASN1F_SEQUENCE.build(self, pkt) - elif "ecdsa" in sigtype.lower(): - pkt.default_fields["signatureValue"] = ECDSASignature() - return ASN1F_OCSP_BasicResponseECDSA().build(pkt) - else: - raise Exception("could not build OCSP basic response") - - -class OCSP_ResponseBytes(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_OID("responseType", "1.3.6.1.5.5.7.48.1.1"), - ASN1F_OCSP_BasicResponse(explicit_tag=0x04)) - - -_responseStatus_mapping = ["successful", - "malformedRequest", - "internalError", - "tryLater", - "notUsed", - "sigRequired", - "unauthorized"] - - -class OCSP_Response(ASN1_Packet): - ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SEQUENCE( - ASN1F_ENUMERATED("responseStatus", 0, - _responseStatus_mapping), - ASN1F_optional( - ASN1F_PACKET("responseBytes", None, - OCSP_ResponseBytes, - explicit_tag=0xa0))) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/layers/zigbee.py b/scripts/external_libs/scapy-2.4.3/scapy/layers/zigbee.py deleted file mode 100644 index 4db2a5de6d..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/layers/zigbee.py +++ /dev/null @@ -1,1007 +0,0 @@ -# This program is published under a GPLv2 license -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Ryan Speers 2011-2012 -# Copyright (C) Roger Meyer : 2012-03-10 Added frames -# Copyright (C) Gabriel Potter : 2018 -# Intern at INRIA Grand Nancy Est -# This program is published under a GPLv2 license - -""" -ZigBee bindings for IEEE 802.15.4. -""" - -import struct - -from scapy.compat import orb -from scapy.packet import bind_layers, bind_bottom_up, Packet -from scapy.fields import BitField, ByteField, XLEIntField, ConditionalField, \ - ByteEnumField, EnumField, BitEnumField, FieldListField, FlagsField, \ - IntField, PacketListField, ShortField, StrField, StrFixedLenField, \ - StrLenField, XLEShortField, XStrField - -from scapy.layers.dot15d4 import dot15d4AddressField, Dot15d4Beacon, Dot15d4, \ - Dot15d4FCS -from scapy.layers.inet import UDP -from scapy.layers.ntp import TimeStampField - -# ZigBee Cluster Library Identifiers, Table 2.2 ZCL -_zcl_cluster_identifier = { - # Functional Domain: General - 0x0000: "basic", - 0x0001: "power_configuration", - 0x0002: "device_temperature_configuration", - 0x0003: "identify", - 0x0004: "groups", - 0x0005: "scenes", - 0x0006: "on_off", - 0x0007: "on_off_switch_configuration", - 0x0008: "level_control", - 0x0009: "alarms", - 0x000a: "time", - 0x000b: "rssi_location", - 0x000c: "analog_input", - 0x000d: "analog_output", - 0x000e: "analog_value", - 0x000f: "binary_input", - 0x0010: "binary_output", - 0x0011: "binary_value", - 0x0012: "multistate_input", - 0x0013: "multistate_output", - 0x0014: "multistate_value", - 0x0015: "commissioning", - # 0x0016 - 0x00ff reserved - # Functional Domain: Closures - 0x0100: "shade_configuration", - # 0x0101 - 0x01ff reserved - # Functional Domain: HVAC - 0x0200: "pump_configuration_and_control", - 0x0201: "thermostat", - 0x0202: "fan_control", - 0x0203: "dehumidification_control", - 0x0204: "thermostat_user_interface_configuration", - # 0x0205 - 0x02ff reserved - # Functional Domain: Lighting - 0x0300: "color_control", - 0x0301: "ballast_configuration", - # Functional Domain: Measurement and sensing - 0x0400: "illuminance_measurement", - 0x0401: "illuminance_level_sensing", - 0x0402: "temperature_measurement", - 0x0403: "pressure_measurement", - 0x0404: "flow_measurement", - 0x0405: "relative_humidity_measurement", - 0x0406: "occupancy_sensing", - # Functional Domain: Security and safethy - 0x0500: "ias_zone", - 0x0501: "ias_ace", - 0x0502: "ias_wd", - # Functional Domain: Protocol Interfaces - 0x0600: "generic_tunnel", - 0x0601: "bacnet_protocol_tunnel", - 0x0602: "analog_input_regular", - 0x0603: "analog_input_extended", - 0x0604: "analog_output_regular", - 0x0605: "analog_output_extended", - 0x0606: "analog_value_regular", - 0x0607: "analog_value_extended", - 0x0608: "binary_input_regular", - 0x0609: "binary_input_extended", - 0x060a: "binary_output_regular", - 0x060b: "binary_output_extended", - 0x060c: "binary_value_regular", - 0x060d: "binary_value_extended", - 0x060e: "multistate_input_regular", - 0x060f: "multistate_input_extended", - 0x0610: "multistate_output_regular", - 0x0611: "multistate_output_extended", - 0x0612: "multistate_value_regular", - 0x0613: "multistate_value", - # Smart Energy Profile Clusters - 0x0700: "price", - 0x0701: "demand_response_and_load_control", - 0x0702: "metering", - 0x0703: "messaging", - 0x0704: "smart_energy_tunneling", - 0x0705: "prepayment", - # Functional Domain: General - # Key Establishment - 0x0800: "key_establishment", -} - -# ZigBee stack profiles -_zcl_profile_identifier = { - 0x0000: "ZigBee_Stack_Profile_1", - 0x0101: "IPM_Industrial_Plant_Monitoring", - 0x0104: "HA_Home_Automation", - 0x0105: "CBA_Commercial_Building_Automation", - 0x0107: "TA_Telecom_Applications", - 0x0108: "HC_Health_Care", - 0x0109: "SE_Smart_Energy_Profile", -} - -# ZigBee Cluster Library, Table 2.8 ZCL Command Frames -_zcl_command_frames = { - 0x00: "read_attributes", - 0x01: "read_attributes_response", - 0x02: "write_attributes_response", - 0x03: "write_attributes_undivided", - 0x04: "write_attributes_response", - 0x05: "write_attributes_no_response", - 0x06: "configure_reporting", - 0x07: "configure_reporting_response", - 0x08: "read_reporting_configuration", - 0x09: "read_reporting_configuration_response", - 0x0a: "report_attributes", - 0x0b: "default_response", - 0x0c: "discover_attributes", - 0x0d: "discover_attributes_response", - # 0x0e - 0xff Reserved -} - -# ZigBee Cluster Library, Table 2.16 Enumerated Status Values -_zcl_enumerated_status_values = { - 0x00: "SUCCESS", - 0x02: "FAILURE", - # 0x02 - 0x7f Reserved - 0x80: "MALFORMED_COMMAND", - 0x81: "UNSUP_CLUSTER_COMMAND", - 0x82: "UNSUP_GENERAL_COMMAND", - 0x83: "UNSUP_MANUF_CLUSTER_COMMAND", - 0x84: "UNSUP_MANUF_GENERAL_COMMAND", - 0x85: "INVALID_FIELD", - 0x86: "UNSUPPORTED_ATTRIBUTE", - 0x87: "INVALID_VALUE", - 0x88: "READ_ONLY", - 0x89: "INSUFFICIENT_SPACE", - 0x8a: "DUPLICATE_EXISTS", - 0x8b: "NOT_FOUND", - 0x8c: "UNREPORTABLE_ATTRIBUTE", - 0x8d: "INVALID_DATA_TYPE", - # 0x8e - 0xbf Reserved - 0xc0: "HARDWARE_FAILURE", - 0xc1: "SOFTWARE_FAILURE", - 0xc2: "CALIBRATION_ERROR", - # 0xc3 - 0xff Reserved -} - -# ZigBee Cluster Library, Table 2.15 Data Types -_zcl_attribute_data_types = { - 0x00: "no_data", - # General data - 0x08: "8-bit_data", - 0x09: "16-bit_data", - 0x0a: "24-bit_data", - 0x0b: "32-bit_data", - 0x0c: "40-bit_data", - 0x0d: "48-bit_data", - 0x0e: "56-bit_data", - 0x0f: "64-bit_data", - # Logical - 0x10: "boolean", - # Bitmap - 0x18: "8-bit_bitmap", - 0x19: "16-bit_bitmap", - 0x1a: "24-bit_bitmap", - 0x1b: "32-bit_bitmap", - 0x1c: "40-bit_bitmap", - 0x1d: "48-bit_bitmap", - 0x1e: "56-bit_bitmap", - 0x1f: "64-bit_bitmap", - # Unsigned integer - 0x20: "Unsigned_8-bit_integer", - 0x21: "Unsigned_16-bit_integer", - 0x22: "Unsigned_24-bit_integer", - 0x23: "Unsigned_32-bit_integer", - 0x24: "Unsigned_40-bit_integer", - 0x25: "Unsigned_48-bit_integer", - 0x26: "Unsigned_56-bit_integer", - 0x27: "Unsigned_64-bit_integer", - # Signed integer - 0x28: "Signed_8-bit_integer", - 0x29: "Signed_16-bit_integer", - 0x2a: "Signed_24-bit_integer", - 0x2b: "Signed_32-bit_integer", - 0x2c: "Signed_40-bit_integer", - 0x2d: "Signed_48-bit_integer", - 0x2e: "Signed_56-bit_integer", - 0x2f: "Signed_64-bit_integer", - # Enumeration - 0x30: "8-bit_enumeration", - 0x31: "16-bit_enumeration", - # Floating point - 0x38: "semi_precision", - 0x39: "single_precision", - 0x3a: "double_precision", - # String - 0x41: "octet-string", - 0x42: "character_string", - 0x43: "long_octet_string", - 0x44: "long_character_string", - # Ordered sequence - 0x48: "array", - 0x4c: "structure", - # Collection - 0x50: "set", - 0x51: "bag", - # Time - 0xe0: "time_of_day", - 0xe1: "date", - 0xe2: "utc_time", - # Identifier - 0xe8: "cluster_id", - 0xe9: "attribute_id", - 0xea: "bacnet_oid", - # Miscellaneous - 0xf0: "ieee_address", - 0xf1: "128-bit_security_key", - # Unknown - 0xff: "unknown", -} - - -# ZigBee # - -class ZigbeeNWK(Packet): - name = "Zigbee Network Layer" - fields_desc = [ - BitField("discover_route", 0, 2), - BitField("proto_version", 2, 4), - BitEnumField("frametype", 0, 2, {0: 'data', 1: 'command'}), - FlagsField("flags", 0, 8, ['multicast', 'security', 'source_route', 'extended_dst', 'extended_src', 'reserved1', 'reserved2', 'reserved3']), # noqa: E501 - XLEShortField("destination", 0), - XLEShortField("source", 0), - ByteField("radius", 0), - ByteField("seqnum", 1), - - # ConditionalField(XLongField("ext_dst", 0), lambda pkt:pkt.flags & 8), - - ConditionalField(dot15d4AddressField("ext_dst", 0, adjust=lambda pkt, x: 8), lambda pkt:pkt.flags & 8), # noqa: E501 - ConditionalField(dot15d4AddressField("ext_src", 0, adjust=lambda pkt, x: 8), lambda pkt:pkt.flags & 16), # noqa: E501 - - ConditionalField(ByteField("relay_count", 1), lambda pkt:pkt.flags & 0x04), # noqa: E501 - ConditionalField(ByteField("relay_index", 0), lambda pkt:pkt.flags & 0x04), # noqa: E501 - ConditionalField(FieldListField("relays", [], XLEShortField("", 0x0000), count_from=lambda pkt:pkt.relay_count), lambda pkt:pkt.flags & 0x04), # noqa: E501 - ] - - def guess_payload_class(self, payload): - if self.flags & 0x02: - return ZigbeeSecurityHeader - elif self.frametype == 0: - return ZigbeeAppDataPayload - elif self.frametype == 1: - return ZigbeeNWKCommandPayload - else: - return Packet.guess_payload_class(self, payload) - - -class LinkStatusEntry(Packet): - name = "ZigBee Link Status Entry" - fields_desc = [ - # Neighbor network address (2 octets) - XLEShortField("neighbor_network_address", 0x0000), - # Link status (1 octet) - BitField("reserved1", 0, 1), - BitField("outgoing_cost", 0, 3), - BitField("reserved2", 0, 1), - BitField("incoming_cost", 0, 3), - ] - - -class ZigbeeNWKCommandPayload(Packet): - name = "Zigbee Network Layer Command Payload" - fields_desc = [ - ByteEnumField("cmd_identifier", 1, { - 1: "route request", - 2: "route reply", - 3: "network status", - 4: "leave", - 5: "route record", - 6: "rejoin request", - 7: "rejoin response", - 8: "link status", - 9: "network report", - 10: "network update" - # 0x0b - 0xff reserved - }), - - # - Route Request Command - # - # Command options (1 octet) - ConditionalField(BitField("reserved", 0, 1), lambda pkt: pkt.cmd_identifier == 1), # noqa: E501 - ConditionalField(BitField("multicast", 0, 1), lambda pkt: pkt.cmd_identifier == 1), # noqa: E501 - ConditionalField(BitField("dest_addr_bit", 0, 1), lambda pkt: pkt.cmd_identifier == 1), # noqa: E501 - ConditionalField( - BitEnumField("many_to_one", 0, 2, { - 0: "not_m2one", 1: "m2one_support_rrt", 2: "m2one_no_support_rrt", 3: "reserved"} # noqa: E501 - ), lambda pkt: pkt.cmd_identifier == 1), - ConditionalField(BitField("reserved", 0, 3), lambda pkt: pkt.cmd_identifier == 1), # noqa: E501 - # Route request identifier (1 octet) - ConditionalField(ByteField("route_request_identifier", 0), lambda pkt: pkt.cmd_identifier == 1), # noqa: E501 - # Destination address (2 octets) - ConditionalField(XLEShortField("destination_address", 0x0000), lambda pkt: pkt.cmd_identifier == 1), # noqa: E501 - # Path cost (1 octet) - ConditionalField(ByteField("path_cost", 0), lambda pkt: pkt.cmd_identifier == 1), # noqa: E501 - # Destination IEEE Address (0/8 octets), only present when dest_addr_bit has a value of 1 # noqa: E501 - ConditionalField(dot15d4AddressField("ext_dst", 0, adjust=lambda pkt, x: 8), # noqa: E501 - lambda pkt: (pkt.cmd_identifier == 1 and pkt.dest_addr_bit == 1)), # noqa: E501 - - # - Route Reply Command - # - # Command options (1 octet) - ConditionalField(BitField("reserved", 0, 1), lambda pkt: pkt.cmd_identifier == 2), # noqa: E501 - ConditionalField(BitField("multicast", 0, 1), lambda pkt: pkt.cmd_identifier == 2), # noqa: E501 - ConditionalField(BitField("responder_addr_bit", 0, 1), lambda pkt: pkt.cmd_identifier == 2), # noqa: E501 - ConditionalField(BitField("originator_addr_bit", 0, 1), lambda pkt: pkt.cmd_identifier == 2), # noqa: E501 - ConditionalField(BitField("reserved", 0, 4), lambda pkt: pkt.cmd_identifier == 2), # noqa: E501 - # Route request identifier (1 octet) - ConditionalField(ByteField("route_request_identifier", 0), lambda pkt: pkt.cmd_identifier == 2), # noqa: E501 - # Originator address (2 octets) - ConditionalField(XLEShortField("originator_address", 0x0000), lambda pkt: pkt.cmd_identifier == 2), # noqa: E501 - # Responder address (2 octets) - ConditionalField(XLEShortField("responder_address", 0x0000), lambda pkt: pkt.cmd_identifier == 2), # noqa: E501 - # Path cost (1 octet) - ConditionalField(ByteField("path_cost", 0), lambda pkt: pkt.cmd_identifier == 2), # noqa: E501 - # Originator IEEE address (0/8 octets) - ConditionalField(dot15d4AddressField("originator_addr", 0, adjust=lambda pkt, x: 8), # noqa: E501 - lambda pkt: (pkt.cmd_identifier == 2 and pkt.originator_addr_bit == 1)), # noqa: E501 - # Responder IEEE address (0/8 octets) - ConditionalField(dot15d4AddressField("responder_addr", 0, adjust=lambda pkt, x: 8), # noqa: E501 - lambda pkt: (pkt.cmd_identifier == 2 and pkt.responder_addr_bit == 1)), # noqa: E501 - - # - Network Status Command - # - # Status code (1 octet) - ConditionalField(ByteEnumField("status_code", 0, { - 0x00: "No route available", - 0x01: "Tree link failure", - 0x02: "Non-tree link failure", - 0x03: "Low battery level", - 0x04: "No routing capacity", - 0x05: "No indirect capacity", - 0x06: "Indirect transaction expiry", - 0x07: "Target device unavailable", - 0x08: "Target address unallocated", - 0x09: "Parent link failure", - 0x0a: "Validate route", - 0x0b: "Source route failure", - 0x0c: "Many-to-one route failure", - 0x0d: "Address conflict", - 0x0e: "Verify addresses", - 0x0f: "PAN identifier update", - 0x10: "Network address update", - 0x11: "Bad frame counter", - 0x12: "Bad key sequence number", - # 0x13 - 0xff Reserved - }), lambda pkt: pkt.cmd_identifier == 3), - # Destination address (2 octets) - ConditionalField(XLEShortField("destination_address", 0x0000), lambda pkt: pkt.cmd_identifier == 3), # noqa: E501 - - # - Leave Command - # - # Command options (1 octet) - # Bit 7: Remove children - ConditionalField(BitField("remove_children", 0, 1), lambda pkt: pkt.cmd_identifier == 4), # noqa: E501 - # Bit 6: Request - ConditionalField(BitField("request", 0, 1), lambda pkt: pkt.cmd_identifier == 4), # noqa: E501 - # Bit 5: Rejoin - ConditionalField(BitField("rejoin", 0, 1), lambda pkt: pkt.cmd_identifier == 4), # noqa: E501 - # Bit 0 - 4: Reserved - ConditionalField(BitField("reserved", 0, 5), lambda pkt: pkt.cmd_identifier == 4), # noqa: E501 - - # - Route Record Command - # - # Relay count (1 octet) - ConditionalField(ByteField("rr_relay_count", 0), lambda pkt: pkt.cmd_identifier == 5), # noqa: E501 - # Relay list (variable in length) - ConditionalField( - FieldListField("rr_relay_list", [], XLEShortField("", 0x0000), count_from=lambda pkt:pkt.rr_relay_count), # noqa: E501 - lambda pkt:pkt.cmd_identifier == 5), - - # - Rejoin Request Command - # - # Capability Information (1 octet) - ConditionalField(BitField("allocate_address", 0, 1), lambda pkt:pkt.cmd_identifier == 6), # Allocate Address # noqa: E501 - ConditionalField(BitField("security_capability", 0, 1), lambda pkt:pkt.cmd_identifier == 6), # Security Capability # noqa: E501 - ConditionalField(BitField("reserved2", 0, 1), lambda pkt:pkt.cmd_identifier == 6), # bit 5 is reserved # noqa: E501 - ConditionalField(BitField("reserved1", 0, 1), lambda pkt:pkt.cmd_identifier == 6), # bit 4 is reserved # noqa: E501 - ConditionalField(BitField("receiver_on_when_idle", 0, 1), lambda pkt:pkt.cmd_identifier == 6), # Receiver On When Idle # noqa: E501 - ConditionalField(BitField("power_source", 0, 1), lambda pkt:pkt.cmd_identifier == 6), # Power Source # noqa: E501 - ConditionalField(BitField("device_type", 0, 1), lambda pkt:pkt.cmd_identifier == 6), # Device Type # noqa: E501 - ConditionalField(BitField("alternate_pan_coordinator", 0, 1), lambda pkt:pkt.cmd_identifier == 6), # Alternate PAN Coordinator # noqa: E501 - - # - Rejoin Response Command - # - # Network address (2 octets) - ConditionalField(XLEShortField("network_address", 0xFFFF), lambda pkt:pkt.cmd_identifier == 7), # noqa: E501 - # Rejoin status (1 octet) - ConditionalField(ByteField("rejoin_status", 0), lambda pkt:pkt.cmd_identifier == 7), # noqa: E501 - - # - Link Status Command - # - # Command options (1 octet) - ConditionalField(BitField("reserved", 0, 1), lambda pkt:pkt.cmd_identifier == 8), # Reserved # noqa: E501 - ConditionalField(BitField("last_frame", 0, 1), lambda pkt:pkt.cmd_identifier == 8), # Last frame # noqa: E501 - ConditionalField(BitField("first_frame", 0, 1), lambda pkt:pkt.cmd_identifier == 8), # First frame # noqa: E501 - ConditionalField(BitField("entry_count", 0, 5), lambda pkt:pkt.cmd_identifier == 8), # Entry count # noqa: E501 - # Link status list (variable size) - ConditionalField( - PacketListField("link_status_list", [], LinkStatusEntry, count_from=lambda pkt:pkt.entry_count), # noqa: E501 - lambda pkt:pkt.cmd_identifier == 8), - - # - Network Report Command - # - # Command options (1 octet) - ConditionalField( - BitEnumField("report_command_identifier", 0, 3, {0: "PAN identifier conflict"}), # 0x01 - 0x07 Reserved # noqa: E501 - lambda pkt: pkt.cmd_identifier == 9), - ConditionalField(BitField("report_information_count", 0, 5), lambda pkt: pkt.cmd_identifier == 9), # noqa: E501 - # EPID: Extended PAN ID (8 octets) - ConditionalField(dot15d4AddressField("epid", 0, adjust=lambda pkt, x: 8), lambda pkt: pkt.cmd_identifier == 9), # noqa: E501 - # Report information (variable length) - # Only present if we have a PAN Identifier Conflict Report - ConditionalField( - FieldListField("PAN_ID_conflict_report", [], XLEShortField("", 0x0000), # noqa: E501 - count_from=lambda pkt:pkt.report_information_count), - lambda pkt:(pkt.cmd_identifier == 9 and pkt.report_command_identifier == 0) # noqa: E501 - ), - - # - Network Update Command - # - # Command options (1 octet) - ConditionalField( - BitEnumField("update_command_identifier", 0, 3, {0: "PAN Identifier Update"}), # 0x01 - 0x07 Reserved # noqa: E501 - lambda pkt: pkt.cmd_identifier == 10), - ConditionalField(BitField("update_information_count", 0, 5), lambda pkt: pkt.cmd_identifier == 10), # noqa: E501 - # EPID: Extended PAN ID (8 octets) - ConditionalField(dot15d4AddressField("epid", 0, adjust=lambda pkt, x: 8), lambda pkt: pkt.cmd_identifier == 10), # noqa: E501 - # Update Id (1 octet) - ConditionalField(ByteField("update_id", 0), lambda pkt: pkt.cmd_identifier == 10), # noqa: E501 - # Update Information (Variable) - # Only present if we have a PAN Identifier Update - # New PAN ID (2 octets) - ConditionalField(XLEShortField("new_PAN_ID", 0x0000), - lambda pkt: (pkt.cmd_identifier == 10 and pkt.update_command_identifier == 0)), # noqa: E501 - - # StrField("data", ""), - ] - - -def util_mic_len(pkt): - ''' Calculate the length of the attribute value field ''' - if (pkt.nwk_seclevel == 0): # no encryption, no mic - return 0 - elif (pkt.nwk_seclevel == 1): # MIC-32 - return 4 - elif (pkt.nwk_seclevel == 2): # MIC-64 - return 8 - elif (pkt.nwk_seclevel == 3): # MIC-128 - return 16 - elif (pkt.nwk_seclevel == 4): # ENC - return 0 - elif (pkt.nwk_seclevel == 5): # ENC-MIC-32 - return 4 - elif (pkt.nwk_seclevel == 6): # ENC-MIC-64 - return 8 - elif (pkt.nwk_seclevel == 7): # ENC-MIC-128 - return 16 - else: - return 0 - - -class ZigbeeSecurityHeader(Packet): - name = "Zigbee Security Header" - fields_desc = [ - # Security control (1 octet) - FlagsField("reserved1", 0, 2, ['reserved1', 'reserved2']), - BitField("extended_nonce", 1, 1), # set to 1 if the sender address field is present (source) # noqa: E501 - # Key identifier - BitEnumField("key_type", 1, 2, { - 0: 'data_key', - 1: 'network_key', - 2: 'key_transport_key', - 3: 'key_load_key' - }), - # Security level (3 bits) - BitEnumField("nwk_seclevel", 0, 3, { - 0: "None", - 1: "MIC-32", - 2: "MIC-64", - 3: "MIC-128", - 4: "ENC", - 5: "ENC-MIC-32", - 6: "ENC-MIC-64", - 7: "ENC-MIC-128" - }), - # Frame counter (4 octets) - XLEIntField("fc", 0), # provide frame freshness and prevent duplicate frames # noqa: E501 - # Source address (0/8 octets) - ConditionalField(dot15d4AddressField("source", 0, adjust=lambda pkt, x: 8), lambda pkt: pkt.extended_nonce), # noqa: E501 - # Key sequence number (0/1 octet): only present when key identifier is 1 (network key) # noqa: E501 - ConditionalField(ByteField("key_seqnum", 0), lambda pkt: pkt.getfieldval("key_type") == 1), # noqa: E501 - # Payload - # the length of the encrypted data is the payload length minus the MIC - StrField("data", ""), # noqa: E501 - # Message Integrity Code (0/variable in size), length depends on nwk_seclevel # noqa: E501 - XStrField("mic", ""), - ] - - def post_dissect(self, s): - # Get the mic dissected correctly - mic_length = util_mic_len(self) - if mic_length > 0: # Slice "data" into "data + mic" - _data, _mic = self.data[:-mic_length], self.data[-mic_length:] - self.data, self.mic = _data, _mic - return s - - -class ZigbeeAppDataPayload(Packet): - name = "Zigbee Application Layer Data Payload (General APS Frame Format)" - fields_desc = [ - # Frame control (1 octet) - FlagsField("frame_control", 2, 4, - ['reserved1', 'security', 'ack_req', 'extended_hdr']), - BitEnumField("delivery_mode", 0, 2, - {0: 'unicast', 1: 'indirect', - 2: 'broadcast', 3: 'group_addressing'}), - BitEnumField("aps_frametype", 0, 2, - {0: 'data', 1: 'command', 2: 'ack'}), - # Destination endpoint (0/1 octet) - ConditionalField( - ByteField("dst_endpoint", 10), - lambda pkt: (pkt.frame_control.ack_req or pkt.aps_frametype == 2) - ), - # Group address (0/2 octets) TODO - # Cluster identifier (0/2 octets) - ConditionalField( - # unsigned short (little-endian) - EnumField("cluster", 0, _zcl_cluster_identifier, fmt=" 9)) - ] - - -class ZigBeeBeacon(Packet): - name = "ZigBee Beacon Payload" - fields_desc = [ - # Protocol ID (1 octet) - ByteField("proto_id", 0), - # nwkcProtocolVersion (4 bits) - BitField("nwkc_protocol_version", 0, 4), - # Stack profile (4 bits) - BitField("stack_profile", 0, 4), - # End device capacity (1 bit) - BitField("end_device_capacity", 0, 1), - # Device depth (4 bits) - BitField("device_depth", 0, 4), - # Router capacity (1 bit) - BitField("router_capacity", 0, 1), - # Reserved (2 bits) - BitField("reserved", 0, 2), - # Extended PAN ID (8 octets) - dot15d4AddressField("extended_pan_id", 0, adjust=lambda pkt, x: 8), - # Tx offset (3 bytes) - # In ZigBee 2006 the Tx-Offset is optional, while in the 2007 and later versions, the Tx-Offset is a required value. # noqa: E501 - BitField("tx_offset", 0, 24), - # Update ID (1 octet) - ByteField("update_id", 0), - ] - - -# Inter-PAN Transmission # -class ZigbeeNWKStub(Packet): - name = "Zigbee Network Layer for Inter-PAN Transmission" - fields_desc = [ - # NWK frame control - BitField("reserved", 0, 2), # remaining subfields shall have a value of 0 # noqa: E501 - BitField("proto_version", 2, 4), - BitField("frametype", 0b11, 2), # 0b11 (3) is a reserved frame type - BitField("reserved", 0, 8), # remaining subfields shall have a value of 0 # noqa: E501 - ] - - def guess_payload_class(self, payload): - if self.frametype == 0b11: - return ZigbeeAppDataPayloadStub - else: - return Packet.guess_payload_class(self, payload) - - -class ZigbeeAppDataPayloadStub(Packet): - name = "Zigbee Application Layer Data Payload for Inter-PAN Transmission" - fields_desc = [ - FlagsField("frame_control", 0, 4, ['reserved1', 'security', 'ack_req', 'extended_hdr']), # noqa: E501 - BitEnumField("delivery_mode", 0, 2, {0: 'unicast', 2: 'broadcast', 3: 'group'}), # noqa: E501 - BitField("frametype", 3, 2), # value 0b11 (3) is a reserved frame type - # Group Address present only when delivery mode field has a value of 0b11 (group delivery mode) # noqa: E501 - ConditionalField( - XLEShortField("group_addr", 0x0), # 16-bit identifier of the group - lambda pkt: pkt.getfieldval("delivery_mode") == 0b11 - ), - # Cluster identifier - EnumField("cluster", 0, _zcl_cluster_identifier, fmt="= 4: - v = orb(_pkt[2]) - if v == 1: - return ZEP1 - elif v == 2: - return ZEP2 - return cls - - def guess_payload_class(self, payload): - if self.lqi_mode: - return Dot15d4 - else: - return Dot15d4FCS - - -class ZEP1(ZEP2): - name = "Zigbee Encapsulation Protocol (V1)" - fields_desc = [ - StrFixedLenField("preamble", "EX", length=2), - ByteField("ver", 0), - ByteField("channel", 0), - ShortField("device", 0), - ByteField("lqi_mode", 0), - ByteField("lqi_val", 0), - BitField("res", 0, 56), # 7 bytes reserved field - ByteField("len", 0), - ] - - -# Bindings # - -# TODO: find a way to chose between ZigbeeNWK and SixLoWPAN (cf. sixlowpan.py) -# Currently: use conf.dot15d4_protocol value -# bind_layers( Dot15d4Data, ZigbeeNWK) - -bind_layers(ZigbeeAppDataPayload, ZigbeeAppCommandPayload, frametype=1) -bind_layers(Dot15d4Beacon, ZigBeeBeacon) - -bind_bottom_up(UDP, ZEP2, sport=17754) -bind_bottom_up(UDP, ZEP2, sport=17754) -bind_layers(UDP, ZEP2, sport=17754, dport=17754) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/main.py b/scripts/external_libs/scapy-2.4.3/scapy/main.py deleted file mode 100644 index 80bd3a80bb..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/main.py +++ /dev/null @@ -1,684 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Main module for interactive startup. -""" - -from __future__ import absolute_import -from __future__ import print_function - -import sys -import os -import getopt -import code -import gzip -import glob -import importlib -import io -import logging -import types -import warnings -from random import choice - -# Never add any global import, in main.py, that would trigger a warning message # noqa: E501 -# before the console handlers gets added in interact() -from scapy.error import log_interactive, log_loading, log_scapy, \ - Scapy_Exception, ScapyColoredFormatter -import scapy.modules.six as six -from scapy.themes import DefaultTheme, BlackAndWhite, apply_ipython_style -from scapy.consts import WINDOWS - -IGNORED = list(six.moves.builtins.__dict__) - -GLOBKEYS = [] - -LAYER_ALIASES = { - "tls": "tls.all" -} - -QUOTES = [ - ("Craft packets like it is your last day on earth.", "Lao-Tze"), - ("Craft packets like I craft my beer.", "Jean De Clerck"), - ("Craft packets before they craft you.", "Socrate"), - ("Craft me if you can.", "IPv6 layer"), - ("To craft a packet, you have to be a packet, and learn how to swim in the " # noqa: E501 - "wires and in the waves.", "Jean-Claude Van Damme"), - ("We are in France, we say Skappee. OK? Merci.", "Sebastien Chabal"), - ("Wanna support scapy? Rate it on sectools! http://sectools.org/tool/scapy/", "Satoshi Nakamoto"), # noqa: E501 -] - - -def _probe_config_file(cf): - cf_path = os.path.join(os.path.expanduser("~"), cf) - try: - os.stat(cf_path) - except OSError: - return None - else: - return cf_path - - -def _read_config_file(cf, _globals=globals(), _locals=locals(), interactive=True): # noqa: E501 - """Read a config file: execute a python file while loading scapy, that may contain # noqa: E501 - some pre-configured values. - - If _globals or _locals are specified, they will be updated with the loaded vars. # noqa: E501 - This allows an external program to use the function. Otherwise, vars are only available # noqa: E501 - from inside the scapy console. - - params: - - _globals: the globals() vars - - _locals: the locals() vars - - interactive: specified whether or not errors should be printed using the scapy console or # noqa: E501 - raised. - - ex, content of a config.py file: - 'conf.verb = 42\n' - Manual loading: - >>> _read_config_file("./config.py")) - >>> conf.verb - 42 - """ - log_loading.debug("Loading config file [%s]", cf) - try: - with open(cf) as cfgf: - exec( - compile(cfgf.read(), cf, 'exec'), - _globals, _locals - ) - except IOError as e: - if interactive: - raise - log_loading.warning("Cannot read config file [%s] [%s]", cf, e) - except Exception: - if interactive: - raise - log_loading.exception("Error during evaluation of config file [%s]", cf) # noqa: E501 - - -def _validate_local(x): - """Returns whether or not a variable should be imported. - Will return False for any default modules (sys), or if - they are detected as private vars (starting with a _)""" - global IGNORED - return x[0] != "_" and x not in IGNORED - - -DEFAULT_PRESTART_FILE = _probe_config_file(".scapy_prestart.py") -DEFAULT_STARTUP_FILE = _probe_config_file(".scapy_startup.py") -SESSION = None - - -def _usage(): - print( - "Usage: scapy.py [-s sessionfile] [-c new_startup_file] " - "[-p new_prestart_file] [-C] [-P] [-H]\n" - "Args:\n" - "\t-H: header-less start\n" - "\t-C: do not read startup file\n" - "\t-P: do not read pre-startup file\n" - ) - sys.exit(0) - - -###################### -# Extension system # -###################### - - -def _load(module, globals_dict=None, symb_list=None): - """Loads a Python module to make variables, objects and functions -available globally. - - The idea is to load the module using importlib, then copy the -symbols to the global symbol table. - - """ - if globals_dict is None: - globals_dict = six.moves.builtins.__dict__ - try: - mod = importlib.import_module(module) - if '__all__' in mod.__dict__: - # import listed symbols - for name in mod.__dict__['__all__']: - if symb_list is not None: - symb_list.append(name) - globals_dict[name] = mod.__dict__[name] - else: - # only import non-private symbols - for name, sym in six.iteritems(mod.__dict__): - if _validate_local(name): - if symb_list is not None: - symb_list.append(name) - globals_dict[name] = sym - except Exception: - log_interactive.error("Loading module %s", module, exc_info=True) - - -def load_module(name, globals_dict=None, symb_list=None): - """Loads a Scapy module to make variables, objects and functions - available globally. - - """ - _load("scapy.modules." + name, - globals_dict=globals_dict, symb_list=symb_list) - - -def load_layer(name, globals_dict=None, symb_list=None): - """Loads a Scapy layer module to make variables, objects and functions - available globally. - - """ - _load("scapy.layers." + LAYER_ALIASES.get(name, name), - globals_dict=globals_dict, symb_list=symb_list) - - -def load_contrib(name, globals_dict=None, symb_list=None): - """Loads a Scapy contrib module to make variables, objects and - functions available globally. - - If no contrib module can be found with the given name, try to find - a layer module, since a contrib module may become a layer module. - - """ - try: - importlib.import_module("scapy.contrib." + name) - _load("scapy.contrib." + name, - globals_dict=globals_dict, symb_list=symb_list) - except ImportError as e: - # if layer not found in contrib, try in layers - try: - load_layer(name, - globals_dict=globals_dict, symb_list=symb_list) - except ImportError: - raise e # Let's raise the original error to avoid confusion - - -def list_contrib(name=None, ret=False, _debug=False): - """Show the list of all existing contribs. - Params: - - name: filter to search the contribs - - ret: whether the function should return a dict instead of printing it - """ - # _debug: checks that all contrib modules have correctly defined: - # # scapy.contrib.description = [...] - # # scapy.contrib.status = [...] - # # scapy.contrib.name = [...] (optional) - # or set the flag: - # # scapy.contrib.description = skip - # to skip the file - if name is None: - name = "*.py" - elif "*" not in name and "?" not in name and not name.endswith(".py"): - name += ".py" - results = [] - dir_path = os.path.join(os.path.dirname(__file__), "contrib") - if sys.version_info >= (3, 5): - name = os.path.join(dir_path, "**", name) - iterator = glob.iglob(name, recursive=True) - else: - name = os.path.join(dir_path, name) - iterator = glob.iglob(name) - for f in iterator: - mod = f.replace(os.path.sep, ".").partition("contrib.")[2] - if mod.startswith("__"): - continue - if mod.endswith(".py"): - mod = mod[:-3] - desc = {"description": None, "status": None, "name": mod} - with io.open(f, errors="replace") as fd: - for l in fd: - if l[0] != "#": - continue - p = l.find("scapy.contrib.") - if p >= 0: - p += 14 - q = l.find("=", p) - key = l[p:q].strip() - value = l[q + 1:].strip() - desc[key] = value - if desc["status"] == "skip": - break - if desc["description"] and desc["status"]: - results.append(desc) - break - if _debug: - if desc["status"] == "skip": - pass - elif not desc["description"] or not desc["status"]: - raise Scapy_Exception("Module %s is missing its " - "contrib infos !" % mod) - results.sort(key=lambda x: x["name"]) - if ret: - return results - else: - for desc in results: - print("%(name)-20s: %(description)-40s status=%(status)s" % desc) - - -############################## -# Session saving/restoring # -############################## - -def update_ipython_session(session): - """Updates IPython session with a custom one""" - try: - global get_ipython - get_ipython().user_ns.update(session) - except Exception: - pass - - -def save_session(fname=None, session=None, pickleProto=-1): - """Save current Scapy session to the file specified in the fname arg. - - params: - - fname: file to save the scapy session in - - session: scapy session to use. If None, the console one will be used - - pickleProto: pickle proto version (default: -1 = latest)""" - from scapy import utils - from scapy.config import conf, ConfClass - if fname is None: - fname = conf.session - if not fname: - conf.session = fname = utils.get_temp_file(keep=True) - log_interactive.info("Use [%s] as session file" % fname) - - if session is None: - try: - session = get_ipython().user_ns - except Exception: - session = six.moves.builtins.__dict__["scapy_session"] - - to_be_saved = session.copy() - if "__builtins__" in to_be_saved: - del(to_be_saved["__builtins__"]) - - for k in list(to_be_saved): - i = to_be_saved[k] - if hasattr(i, "__module__") and (k[0] == "_" or i.__module__.startswith("IPython")): # noqa: E501 - del(to_be_saved[k]) - if isinstance(i, ConfClass): - del(to_be_saved[k]) - elif isinstance(i, (type, type, types.ModuleType)): - if k[0] != "_": - log_interactive.error("[%s] (%s) can't be saved.", k, type(to_be_saved[k])) # noqa: E501 - del(to_be_saved[k]) - - try: - os.rename(fname, fname + ".bak") - except OSError: - pass - - f = gzip.open(fname, "wb") - six.moves.cPickle.dump(to_be_saved, f, pickleProto) - f.close() - del f - - -def load_session(fname=None): - """Load current Scapy session from the file specified in the fname arg. - This will erase any existing session. - - params: - - fname: file to load the scapy session from""" - from scapy.config import conf - if fname is None: - fname = conf.session - try: - s = six.moves.cPickle.load(gzip.open(fname, "rb")) - except IOError: - try: - s = six.moves.cPickle.load(open(fname, "rb")) - except IOError: - # Raise "No such file exception" - raise - - scapy_session = six.moves.builtins.__dict__["scapy_session"] - scapy_session.clear() - scapy_session.update(s) - update_ipython_session(scapy_session) - - log_loading.info("Loaded session [%s]" % fname) - - -def update_session(fname=None): - """Update current Scapy session from the file specified in the fname arg. - - params: - - fname: file to load the scapy session from""" - from scapy.config import conf - if fname is None: - fname = conf.session - try: - s = six.moves.cPickle.load(gzip.open(fname, "rb")) - except IOError: - s = six.moves.cPickle.load(open(fname, "rb")) - scapy_session = six.moves.builtins.__dict__["scapy_session"] - scapy_session.update(s) - update_ipython_session(scapy_session) - - -def init_session(session_name, mydict=None): - from scapy.config import conf - global SESSION - global GLOBKEYS - - scapy_builtins = {k: v for k, v in six.iteritems(importlib.import_module(".all", "scapy").__dict__) if _validate_local(k)} # noqa: E501 - six.moves.builtins.__dict__.update(scapy_builtins) - GLOBKEYS.extend(scapy_builtins) - GLOBKEYS.append("scapy_session") - scapy_builtins = None - - if session_name: - try: - os.stat(session_name) - except OSError: - log_loading.info("New session [%s]" % session_name) - else: - try: - try: - SESSION = six.moves.cPickle.load(gzip.open(session_name, "rb")) # noqa: E501 - except IOError: - SESSION = six.moves.cPickle.load(open(session_name, "rb")) - log_loading.info("Using session [%s]" % session_name) - except EOFError: - log_loading.error("Error opening session [%s]" % session_name) - except AttributeError: - log_loading.error("Error opening session [%s]. Attribute missing" % session_name) # noqa: E501 - - if SESSION: - if "conf" in SESSION: - conf.configure(SESSION["conf"]) - conf.session = session_name - SESSION["conf"] = conf - else: - conf.session = session_name - else: - conf.session = session_name - SESSION = {"conf": conf} - else: - SESSION = {"conf": conf} - - six.moves.builtins.__dict__["scapy_session"] = SESSION - - if mydict is not None: - six.moves.builtins.__dict__["scapy_session"].update(mydict) - update_ipython_session(mydict) - GLOBKEYS.extend(mydict) - -################ -# Main # -################ - - -def scapy_delete_temp_files(): - from scapy.config import conf - for f in conf.temp_files: - try: - os.unlink(f) - except Exception: - pass - del(conf.temp_files[:]) - - -def _prepare_quote(quote, author, max_len=78): - """This function processes a quote and returns a string that is ready -to be used in the fancy prompt. - - """ - quote = quote.split(' ') - max_len -= 6 - lines = [] - cur_line = [] - - def _len(line): - return sum(len(elt) for elt in line) + len(line) - 1 - while quote: - if not cur_line or (_len(cur_line) + len(quote[0]) - 1 <= max_len): - cur_line.append(quote.pop(0)) - continue - lines.append(' | %s' % ' '.join(cur_line)) - cur_line = [] - if cur_line: - lines.append(' | %s' % ' '.join(cur_line)) - cur_line = [] - lines.append(' | %s-- %s' % (" " * (max_len - len(author) - 5), author)) - return lines - - -def interact(mydict=None, argv=None, mybanner=None, loglevel=logging.INFO): - """Starts Scapy's console.""" - global SESSION - global GLOBKEYS - - try: - if WINDOWS: - # colorama is bundled within IPython. - # logging.StreamHandler will be overwritten when called, - # We can't wait for IPython to call it - import colorama - colorama.init() - # Success - console_handler = logging.StreamHandler() - console_handler.setFormatter( - ScapyColoredFormatter( - "%(levelname)s: %(message)s", - ) - ) - except ImportError: - # Failure: ignore colors in the logger - console_handler = logging.StreamHandler() - console_handler.setFormatter( - logging.Formatter( - "%(levelname)s: %(message)s", - ) - ) - log_scapy.addHandler(console_handler) - - # We're in interactive mode, let's throw the DeprecationWarnings - warnings.simplefilter("always") - - from scapy.config import conf - conf.interactive = True - conf.color_theme = DefaultTheme() - if loglevel is not None: - conf.logLevel = loglevel - - STARTUP_FILE = DEFAULT_STARTUP_FILE - PRESTART_FILE = DEFAULT_PRESTART_FILE - - session_name = None - - if argv is None: - argv = sys.argv - - try: - opts = getopt.getopt(argv[1:], "hs:Cc:Pp:d:H") - for opt, parm in opts[0]: - if opt == "-h": - _usage() - elif opt == "-H": - conf.fancy_prompt = False - conf.verb = 30 - elif opt == "-s": - session_name = parm - elif opt == "-c": - STARTUP_FILE = parm - elif opt == "-C": - STARTUP_FILE = None - elif opt == "-p": - PRESTART_FILE = parm - elif opt == "-P": - PRESTART_FILE = None - elif opt == "-d": - conf.logLevel = max(1, conf.logLevel - 10) - - if len(opts[1]) > 0: - raise getopt.GetoptError("Too many parameters : [%s]" % " ".join(opts[1])) # noqa: E501 - - except getopt.GetoptError as msg: - log_loading.error(msg) - sys.exit(1) - - # Reset sys.argv, otherwise IPython thinks it is for him - sys.argv = sys.argv[:1] - - init_session(session_name, mydict) - - if STARTUP_FILE: - _read_config_file(STARTUP_FILE, interactive=True) - if PRESTART_FILE: - _read_config_file(PRESTART_FILE, interactive=True) - - if not conf.interactive_shell or conf.interactive_shell.lower() in [ - "ipython", "auto" - ]: - try: - import IPython - from IPython import start_ipython - except ImportError: - log_loading.warning( - "IPython not available. Using standard Python shell " - "instead.\nAutoCompletion, History are disabled." - ) - if WINDOWS: - log_loading.warning( - "On Windows, colors are also disabled" - ) - conf.color_theme = BlackAndWhite() - IPYTHON = False - else: - IPYTHON = True - else: - IPYTHON = False - - if conf.fancy_prompt: - from scapy.utils import get_terminal_width - mini_banner = (get_terminal_width() or 84) <= 75 - - the_logo = [ - " ", - " aSPY//YASa ", - " apyyyyCY//////////YCa ", - " sY//////YSpcs scpCY//Pp ", - " ayp ayyyyyyySCP//Pp syY//C ", - " AYAsAYYYYYYYY///Ps cY//S", - " pCCCCY//p cSSps y//Y", - " SPPPP///a pP///AC//Y", - " A//A cyP////C", - " p///Ac sC///a", - " P////YCpc A//A", - " scccccp///pSP///p p//Y", - " sY/////////y caa S//P", - " cayCyayP//Ya pY/Ya", - " sY/PsY////YCc aC//Yp ", - " sc sccaCY//PCypaapyCP//YSs ", - " spCPY//////YPSps ", - " ccaacs ", - " ", - ] - - # Used on mini screens - the_logo_mini = [ - " .SYPACCCSASYY ", - "P /SCS/CCS ACS", - " /A AC", - " A/PS /SPPS", - " YP (SC", - " SPS/A. SC", - " Y/PACC PP", - " PY*AYC CAA", - " YYCY//SCYP ", - ] - - the_banner = [ - "", - "", - " |", - " | Welcome to Scapy", - " | Version %s" % conf.version, - " |", - " | https://github.com/secdev/scapy", - " |", - " | Have fun!", - " |", - ] - - if mini_banner: - the_logo = the_logo_mini - the_banner = [x[2:] for x in the_banner[3:-1]] - the_banner = [""] + the_banner + [""] - else: - quote, author = choice(QUOTES) - the_banner.extend(_prepare_quote(quote, author, max_len=39)) - the_banner.append(" |") - the_banner = "\n".join( - logo + banner for logo, banner in six.moves.zip_longest( - (conf.color_theme.logo(line) for line in the_logo), - (conf.color_theme.success(line) for line in the_banner), - fillvalue="" - ) - ) - else: - the_banner = "Welcome to Scapy (%s)" % conf.version - if mybanner is not None: - the_banner += "\n" - the_banner += mybanner - - if IPYTHON: - banner = the_banner + " using IPython %s\n" % IPython.__version__ - try: - from traitlets.config.loader import Config - except ImportError: - log_loading.warning( - "traitlets not available. Some Scapy shell features won't be " - "available." - ) - try: - start_ipython( - display_banner=False, - user_ns=SESSION, - exec_lines=["print(\"\"\"" + banner + "\"\"\")"] - ) - except Exception: - code.interact(banner=the_banner, local=SESSION) - else: - cfg = Config() - try: - get_ipython - except NameError: - # Set "classic" prompt style when launched from run_scapy(.bat) files # noqa: E501 - # Register and apply scapy color+prompt style - apply_ipython_style(shell=cfg.TerminalInteractiveShell) - cfg.TerminalInteractiveShell.confirm_exit = False - cfg.TerminalInteractiveShell.separate_in = u'' - if int(IPython.__version__[0]) >= 6: - cfg.TerminalInteractiveShell.term_title_format = "Scapy v%s" % conf.version # noqa: E501 - else: - cfg.TerminalInteractiveShell.term_title = False - cfg.HistoryAccessor.hist_file = conf.histfile - cfg.InteractiveShell.banner1 = banner - # configuration can thus be specified here. - try: - start_ipython(config=cfg, user_ns=SESSION) - except (AttributeError, TypeError): - code.interact(banner=the_banner, local=SESSION) - else: - code.interact(banner=the_banner, local=SESSION) - - if conf.session: - save_session(conf.session, SESSION) - - for k in GLOBKEYS: - try: - del(six.moves.builtins.__dict__[k]) - except Exception: - pass - - -if __name__ == "__main__": - interact() diff --git a/scripts/external_libs/scapy-2.4.3/scapy/modules/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/modules/__init__.py deleted file mode 100644 index a2226fa918..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/modules/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Package of extension modules that have to be loaded explicitly. -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/modules/ethertypes.py b/scripts/external_libs/scapy-2.4.3/scapy/modules/ethertypes.py deleted file mode 100644 index baa405cc03..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/modules/ethertypes.py +++ /dev/null @@ -1,138 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information - -""" -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)if_ether.h 8.1 (Berkeley) 6/10/93 - */ -""" - -# This file contains data automatically generated using -# scapy/tools/generate_ethertypes.py -# based on OpenBSD public source. - -DATA = b""" -# -# Ethernet frame types -# This file describes some of the various Ethernet -# protocol types that are used on Ethernet networks. -# -# This list could be found on: -# http://www.iana.org/assignments/ethernet-numbers -# http://www.iana.org/assignments/ieee-802-numbers -# -# ... #Comment -# -8023 0004 # IEEE 802.3 packet -PUP 0200 # Xerox PUP protocol - see 0A00 -PUPAT 0200 # PUP Address Translation - see 0A01 -NS 0600 # XNS -NSAT 0601 # XNS Address Translation (3Mb only) -DLOG1 0660 # DLOG (?) -DLOG2 0661 # DLOG (?) -IPv4 0800 # IP protocol -X75 0801 # X.75 Internet -NBS 0802 # NBS Internet -ECMA 0803 # ECMA Internet -CHAOS 0804 # CHAOSnet -X25 0805 # X.25 Level 3 -ARP 0806 # Address resolution protocol -FRARP 0808 # Frame Relay ARP (RFC1701) -VINES 0BAD # Banyan VINES -TRAIL 1000 # Trailer packet -DCA 1234 # DCA - Multicast -VALID 1600 # VALID system protocol -RCL 1995 # Datapoint Corporation (RCL lan protocol) -NBPCC 3C04 # 3Com NBP Connect complete not registered -NBPDG 3C07 # 3Com NBP Datagram (like XNS IDP) not registered -PCS 4242 # PCS Basic Block Protocol -IMLBL 4C42 # Information Modes Little Big LAN -MOPDL 6001 # DEC MOP dump/load -MOPRC 6002 # DEC MOP remote console -LAT 6004 # DEC LAT -SCA 6007 # DEC LAVC, SCA -AMBER 6008 # DEC AMBER -RAWFR 6559 # Raw Frame Relay (RFC1701) -UBDL 7000 # Ungermann-Bass download -UBNIU 7001 # Ungermann-Bass NIUs -UBNMC 7003 # Ungermann-Bass ??? (NMC to/from UB Bridge) -UBBST 7005 # Ungermann-Bass Bridge Spanning Tree -OS9 7007 # OS/9 Microware -RACAL 7030 # Racal-Interlan -HP 8005 # HP Probe -TIGAN 802F # Tigan, Inc. -DECAM 8048 # DEC Availability Manager for Distributed Systems DECamds (but someone at DEC says not) -VEXP 805B # Stanford V Kernel exp. -VPROD 805C # Stanford V Kernel prod. -ES 805D # Evans & Sutherland -VEECO 8067 # Veeco Integrated Auto. -ATT 8069 # AT&T -MATRA 807A # Matra -DDE 807B # Dansk Data Elektronik -MERIT 807C # Merit Internodal (or Univ of Michigan?) -ATALK 809B # AppleTalk -PACER 80C6 # Pacer Software -SNA 80D5 # IBM SNA Services over Ethernet -RETIX 80F2 # Retix -AARP 80F3 # AppleTalk AARP -VLAN 8100 # IEEE 802.1Q VLAN tagging (XXX conflicts) -BOFL 8102 # Wellfleet; BOFL (Breath OF Life) pkts [every 5-10 secs.] -HAYES 8130 # Hayes Microcomputers (XXX which?) -VGLAB 8131 # VG Laboratory Systems -IPX 8137 # Novell (old) NetWare IPX (ECONFIG E option) -MUMPS 813F # M/MUMPS data sharing -FLIP 8146 # Vrije Universiteit (NL) FLIP (Fast Local Internet Protocol) -NCD 8149 # Network Computing Devices -ALPHA 814A # Alpha Micro -SNMP 814C # SNMP over Ethernet (see RFC1089) -XTP 817D # Protocol Engines XTP -SGITW 817E # SGI/Time Warner prop. -STP 8181 # Scheduled Transfer STP, HIPPI-ST -IPv6 86DD # IP protocol version 6 -RDP 8739 # Control Technology Inc. RDP Without IP -MICP 873A # Control Technology Inc. Mcast Industrial Ctrl Proto. -IPAS 876C # IP Autonomous Systems (RFC1701) -SLOW 8809 # 803.3ad slow protocols (LACP/Marker) -PPP 880B # PPP (obsolete by PPPOE) -MPLS 8847 # MPLS Unicast -AXIS 8856 # Axis Communications AB proprietary bootstrap/config -PPPOE 8864 # PPP Over Ethernet Session Stage -PAE 888E # 802.1X Port Access Entity -AOE 88A2 # ATA over Ethernet -QINQ 88A8 # 802.1ad VLAN stacking -LLDP 88CC # Link Layer Discovery Protocol -PBB 88E7 # 802.1Q Provider Backbone Bridging -XNSSM 9001 # 3Com (Formerly Bridge Communications), XNS Systems Management -TCPSM 9002 # 3Com (Formerly Bridge Communications), TCP/IP Systems Management -DEBNI AAAA # DECNET? Used by VAX 6220 DEBNI -SONIX FAF5 # Sonix Arpeggio -VITAL FF00 # BBN VITAL-LanBridge cache wakeups -MAX FFFF # Maximum valid ethernet type, reserved -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/modules/geoip.py b/scripts/external_libs/scapy-2.4.3/scapy/modules/geoip.py deleted file mode 100644 index 7396fe9607..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/modules/geoip.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 -## This program is published under a GPLv2 license - -""" -GeoIP: find out the geographical location of IP addresses -""" - -from scapy.data import KnowledgeBase -from scapy.config import conf - -conf.IPCountry_base = "GeoIPCountry4Scapy.gz" -conf.countryLoc_base = "countryLoc.csv" - -########################## -## IP location database ## -########################## - -class IPCountryKnowledgeBase(KnowledgeBase): - """ -How to generate the base : -db = [] -for l in open("GeoIPCountryWhois.csv").readlines(): - s,e,c = l.split(",")[2:5] - db.append((int(s[1:-1]),int(e[1:-1]),c[1:-1])) -cPickle.dump(gzip.open("xxx","w"),db) -""" - def lazy_init(self): - self.base = load_object(self.filename) - - -class CountryLocKnowledgeBase(KnowledgeBase): - def lazy_init(self): - f=open(self.filename) - self.base = {} - while 1: - l = f.readline() - if not l: - break - l = l.strip().split(",") - if len(l) != 3: - continue - c,lat,long = l - - self.base[c] = (float(long),float(lat)) - f.close() - - - -@conf.commands.register -def locate_ip(ip): - """Get geographic coordinates from IP using geoip database""" - ip=map(int,ip.split(".")) - ip = ip[3]+(ip[2]<<8)+(ip[1]<<16)+(ip[0]<<24) - - cloc = country_loc_kdb.get_base() - db = IP_country_kdb.get_base() - - d=0 - f=len(db)-1 - while (f-d) > 1: - guess = (d+f)/2 - if ip > db[guess][0]: - d = guess - else: - f = guess - s,e,c = db[guess] - if s <= ip and ip <= e: - return cloc.get(c,None) - - - - - -conf.IP_country_kdb = IPCountryKnowledgeBase(conf.IPCountry_base) -conf.country_loc_kdb = CountryLocKnowledgeBase(conf.countryLoc_base) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/modules/krack/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/modules/krack/__init__.py deleted file mode 100644 index d31059eaa5..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/modules/krack/__init__.py +++ /dev/null @@ -1,28 +0,0 @@ -"""Module implementing Krack Attack on client, as a custom WPA Access Point - -More details on the attack can be found on https://www.krackattacks.com/ - -Example of use (from the scapy shell): ->>> load_module("krack") ->>> KrackAP( - iface="mon0", # A monitor interface - ap_mac='11:22:33:44:55:66', # MAC (BSSID) to use - ssid="TEST_KRACK", # SSID - passphrase="testtest", # Associated passphrase -).run() - -Then, on the target device, connect to "TEST_KRACK" using "testtest" as the -passphrase. -The output logs will indicate if one of the vulnerability have been triggered. - -Outputs for vulnerable devices: -- IV re-use!! Client seems to be vulnerable to handshake 3/4 replay - (CVE-2017-13077) -- Broadcast packet accepted twice!! (CVE-2017-13080) -- Client has installed an all zero encryption key (TK)!! - -For patched devices: -- Client is likely not vulnerable to CVE-2017-13080 -""" - -from scapy.modules.krack.automaton import KrackAP # noqa: F401 diff --git a/scripts/external_libs/scapy-2.4.3/scapy/modules/krack/automaton.py b/scripts/external_libs/scapy-2.4.3/scapy/modules/krack/automaton.py deleted file mode 100644 index 04c2ba23ed..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/modules/krack/automaton.py +++ /dev/null @@ -1,895 +0,0 @@ -import hmac -import hashlib -from itertools import count -import struct -import time - -from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC -from cryptography.hazmat.backends import default_backend - -from scapy.automaton import ATMT, Automaton -from scapy.base_classes import Net -from scapy.config import conf -from scapy.compat import raw, chb -from scapy.consts import WINDOWS -from scapy.error import log_runtime, Scapy_Exception -from scapy.layers.dot11 import RadioTap, Dot11, Dot11AssoReq, Dot11AssoResp, \ - Dot11Auth, Dot11Beacon, Dot11Elt, Dot11EltRates, Dot11EltRSN, \ - Dot11ProbeReq, Dot11ProbeResp, RSNCipherSuite, AKMSuite -from scapy.layers.eap import EAPOL -from scapy.layers.l2 import ARP, LLC, SNAP, Ether -from scapy.layers.dhcp import DHCP_am -from scapy.packet import Raw -from scapy.utils import hexdump, mac2str -from scapy.volatile import RandBin - - -from scapy.modules.krack.crypto import parse_data_pkt, parse_TKIP_hdr, \ - build_TKIP_payload, check_MIC_ICV, MICError, ICVError, build_MIC_ICV, \ - customPRF512, ARC4_encrypt - - -class DHCPOverWPA(DHCP_am): - """Wrapper over DHCP_am to send and recv inside a WPA channel""" - - def __init__(self, send_func, *args, **kwargs): - super(DHCPOverWPA, self).__init__(*args, **kwargs) - self.send_function = send_func - - def sniff(self, *args, **kwargs): - # Do not sniff, use a direct call to 'replay(pkt)' instead - return - - -class KrackAP(Automaton): - """Tiny WPA AP for detecting client vulnerable to KRACK attacks defined in: - "Key Reinstallation Attacks: Forcing Nonce Reuse in WPA2" - - Example of use: - KrackAP( - iface="mon0", # A monitor interface - ap_mac='11:22:33:44:55:66', # MAC to use - ssid="TEST_KRACK", # SSID - passphrase="testtest", # Associated passphrase - ).run() - - Then, on the target device, connect to "TEST_KRACK" using "testtest" as the - passphrase. - The output logs will indicate if one of the CVE have been triggered. - """ - - # Number of "GTK rekeying -> ARP replay" attempts. The vulnerability may not # noqa: E501 - # be detected the first time. Several attempt implies the client has been - # likely patched - ARP_MAX_RETRY = 50 - - def __init__(self, *args, **kargs): - kargs.setdefault("ll", conf.L2socket) - kargs.setdefault("monitor", True) - super(KrackAP, self).__init__(*args, **kargs) - - def parse_args(self, ap_mac, ssid, passphrase, - channel=None, - # KRACK attack options - double_3handshake=True, - encrypt_3handshake=True, - wait_3handshake=0, - double_gtk_refresh=True, - arp_target_ip=None, - arp_source_ip=None, - wait_gtk=10, - **kwargs): - """ - Mandatory arguments: - @iface: interface to use (must be in monitor mode) - @ap_mac: AP's MAC - @ssid: AP's SSID - @passphrase: AP's Passphrase (min 8 char.) - - Optional arguments: - @channel: used by the interface. Default 6, autodetected on windows - - Krack attacks options: - - - Msg 3/4 handshake replay: - double_3handshake: double the 3/4 handshake message - encrypt_3handshake: encrypt the second 3/4 handshake message - wait_3handshake: time to wait (in sec.) before sending the second 3/4 - - double GTK rekeying: - double_gtk_refresh: double the 1/2 GTK rekeying message - wait_gtk: time to wait (in sec.) before sending the GTK rekeying - arp_target_ip: Client IP to use in ARP req. (to detect attack success) - If None, use a DHCP server - arp_source_ip: Server IP to use in ARP req. (to detect attack success) - If None, use the DHCP server gateway address - """ - super(KrackAP, self).parse_args(**kwargs) - - # Main AP options - self.mac = ap_mac - self.ssid = ssid - self.passphrase = passphrase - if channel is None: - if WINDOWS: - try: - channel = kwargs.get("iface", conf.iface).channel() - except (Scapy_Exception, AttributeError): - channel = 6 - else: - channel = 6 - self.channel = channel - - # Internal structures - self.last_iv = None - self.client = None - self.seq_num = count() - self.replay_counter = count() - self.time_handshake_end = None - self.dhcp_server = DHCPOverWPA(send_func=self.send_ether_over_wpa, - pool=Net("192.168.42.128/25"), - network="192.168.42.0/24", - gw="192.168.42.1") - self.arp_sent = [] - self.arp_to_send = 0 - self.arp_retry = 0 - - # Bit 0: 3way handshake sent - # Bit 1: GTK rekeying sent - # Bit 2: ARP response obtained - self.krack_state = 0 - - # Krack options - self.double_3handshake = double_3handshake - self.encrypt_3handshake = encrypt_3handshake - self.wait_3handshake = wait_3handshake - self.double_gtk_refresh = double_gtk_refresh - self.arp_target_ip = arp_target_ip - if arp_source_ip is None: - # Use the DHCP server Gateway address - arp_source_ip = self.dhcp_server.gw - self.arp_source_ip = arp_source_ip - self.wait_gtk = wait_gtk - - # May take several seconds - self.install_PMK() - - def run(self, *args, **kwargs): - log_runtime.warning("AP started with ESSID: %s, BSSID: %s", - self.ssid, self.mac) - super(KrackAP, self).run(*args, **kwargs) - - # Key utils - - @staticmethod - def gen_nonce(size): - """Return a nonce of @size element of random bytes as a string""" - return raw(RandBin(size)) - - def install_PMK(self): - """Compute and install the PMK""" - self.pmk = PBKDF2HMAC( - algorithm=hashes.SHA1(), - length=32, - salt=self.ssid.encode(), - iterations=4096, - backend=default_backend(), - ).derive(self.passphrase.encode()) - - def install_unicast_keys(self, client_nonce): - """Use the client nonce @client_nonce to compute and install - PTK, KCK, KEK, TK, MIC (AP -> STA), MIC (STA -> AP) - """ - pmk = self.pmk - anonce = self.anonce - snonce = client_nonce - amac = mac2str(self.mac) - smac = mac2str(self.client) - - # Compute PTK - self.ptk = customPRF512(pmk, amac, smac, anonce, snonce) - - # Extract derivated keys - self.kck = self.ptk[:16] - self.kek = self.ptk[16:32] - self.tk = self.ptk[32:48] - self.mic_ap_to_sta = self.ptk[48:56] - self.mic_sta_to_ap = self.ptk[56:64] - - # Reset IV - self.client_iv = count() - - def install_GTK(self): - """Compute a new GTK and install it alongs - MIC (AP -> Group = broadcast + multicast) - """ - - # Compute GTK - self.gtk_full = self.gen_nonce(32) - self.gtk = self.gtk_full[:16] - - # Extract derivated keys - self.mic_ap_to_group = self.gtk_full[16:24] - - # Reset IV - self.group_iv = count() - - # Packet utils - - def build_ap_info_pkt(self, layer_cls, dest): - """Build a packet with info describing the current AP - For beacon / proberesp use - """ - return RadioTap() \ - / Dot11(addr1=dest, addr2=self.mac, addr3=self.mac) \ - / layer_cls(timestamp=0, beacon_interval=100, - cap='ESS+privacy') \ - / Dot11Elt(ID="SSID", info=self.ssid) \ - / Dot11EltRates(rates=[130, 132, 139, 150, 12, 18, 24, 36]) \ - / Dot11Elt(ID="DSset", info=chb(self.channel)) \ - / Dot11EltRSN(group_cipher_suite=RSNCipherSuite(cipher=0x2), - pairwise_cipher_suites=[RSNCipherSuite(cipher=0x2)], - akm_suites=[AKMSuite(suite=0x2)]) - - @staticmethod - def build_EAPOL_Key_8021X2004( - key_information, - replay_counter, - nonce, - data=None, - key_mic=None, - key_data_encrypt=None, - key_rsc=0, - key_id=0, - key_descriptor_type=2, # EAPOL RSN Key - ): - pkt = EAPOL(version="802.1X-2004", type="EAPOL-Key") - - key_iv = KrackAP.gen_nonce(16) - - assert key_rsc == 0 # Other values unsupported - assert key_id == 0 # Other values unsupported - payload = b"".join([ - chb(key_descriptor_type), - struct.pack(">H", key_information), - b'\x00\x20', # Key length - struct.pack(">Q", replay_counter), - nonce, - key_iv, - struct.pack(">Q", key_rsc), - struct.pack(">Q", key_id), - ]) - - # MIC field is set to 0's during MIC computation - offset_MIC = len(payload) - payload += b'\x00' * 0x10 - - if data is None and key_mic is None and key_data_encrypt is None: - # If key is unknown and there is no data, no MIC is needed - # Example: handshake 1/4 - payload += b'\x00' * 2 # Length - return pkt / Raw(load=payload) - - assert data is not None - assert key_mic is not None - assert key_data_encrypt is not None - - # Skip 256 first bytes - # REF: 802.11i 8.5.2 - # Key Descriptor Version 1: - # ... - # No padding shall be used. The encryption key is generated by - # concatenating the EAPOL-Key IV field and the KEK. The first 256 octets # noqa: E501 - # of the RC4 key stream shall be discarded following RC4 stream cipher - # initialization with the KEK, and encryption begins using the 257th key # noqa: E501 - # stream octet. - enc_data = ARC4_encrypt(key_iv + key_data_encrypt, data, skip=256) - - payload += struct.pack(">H", len(data)) - payload += enc_data - - # Compute MIC and set at the right place - temp_mic = pkt.copy() - temp_mic /= Raw(load=payload) - to_mic = raw(temp_mic[EAPOL]) - mic = hmac.new(key_mic, to_mic, hashlib.md5).digest() - final_payload = payload[:offset_MIC] + mic + payload[offset_MIC + len(mic):] # noqa: E501 - assert len(final_payload) == len(payload) - - return pkt / Raw(load=final_payload) - - def build_GTK_KDE(self): - """Build the Key Data Encapsulation for GTK - KeyID: 0 - Ref: 802.11i p81 - """ - return b''.join([ - b'\xdd', # Type KDE - chb(len(self.gtk_full) + 6), - b'\x00\x0f\xac', # OUI - b'\x01', # GTK KDE - b'\x00\x00', # KeyID - Tx - Reserved x2 - self.gtk_full, - ]) - - def send_wpa_enc(self, data, iv, seqnum, dest, mic_key, - key_idx=0, additionnal_flag=["from-DS"], - encrypt_key=None): - """Send an encrypted packet with content @data, using IV @iv, - sequence number @seqnum, MIC key @mic_key - """ - - if encrypt_key is None: - encrypt_key = self.tk - - rep = RadioTap() - rep /= Dot11( - addr1=dest, - addr2=self.mac, - addr3=self.mac, - FCfield="+".join(['protected'] + additionnal_flag), - SC=(next(self.seq_num) << 4), - subtype=0, - type="Data", - ) - - # Assume packet is send by our AP -> use self.mac as source - - # Encapsule in TKIP with MIC Michael and ICV - data_to_enc = build_MIC_ICV(raw(data), mic_key, self.mac, dest) - - # Header TKIP + payload - rep /= Raw(build_TKIP_payload(data_to_enc, iv, self.mac, encrypt_key)) - - self.send(rep) - return rep - - def send_wpa_to_client(self, data, **kwargs): - kwargs.setdefault("encrypt_key", self.tk) - return self.send_wpa_enc(data, next(self.client_iv), - next(self.seq_num), self.client, - self.mic_ap_to_sta, **kwargs) - - def send_wpa_to_group(self, data, dest="ff:ff:ff:ff:ff:ff", **kwargs): - kwargs.setdefault("encrypt_key", self.gtk) - return self.send_wpa_enc(data, next(self.group_iv), - next(self.seq_num), dest, - self.mic_ap_to_group, **kwargs) - - def send_ether_over_wpa(self, pkt, **kwargs): - """Send an Ethernet packet using the WPA channel - Extra arguments will be ignored, and are just left for compatibility - """ - - payload = LLC() / SNAP() / pkt[Ether].payload - dest = pkt.dst - if dest == "ff:ff:ff:ff:ff:ff": - self.send_wpa_to_group(payload, dest) - else: - assert dest == self.client - self.send_wpa_to_client(payload) - - def deal_common_pkt(self, pkt): - # Send to DHCP server - # LLC / SNAP to Ether - if SNAP in pkt: - ether_pkt = Ether(src=self.client, dst=self.mac) / pkt[SNAP].payload # noqa: E501 - self.dhcp_server.reply(ether_pkt) - - # If an ARP request is made, extract client IP and answer - if ARP in pkt and \ - pkt[ARP].op == 1 and pkt[ARP].pdst == self.dhcp_server.gw: - if self.arp_target_ip is None: - self.arp_target_ip = pkt[ARP].psrc - log_runtime.info("Detected IP: %s", self.arp_target_ip) - - # Reply - ARP_ans = LLC() / SNAP() / ARP( - op="is-at", - psrc=self.arp_source_ip, - pdst=self.arp_target_ip, - hwsrc=self.mac, - hwdst=self.client, - ) - self.send_wpa_to_client(ARP_ans) - - # States - - @ATMT.state(initial=True) - def WAIT_AUTH_REQUEST(self): - log_runtime.debug("State WAIT_AUTH_REQUEST") - - @ATMT.state() - def AUTH_RESPONSE_SENT(self): - log_runtime.debug("State AUTH_RESPONSE_SENT") - - @ATMT.state() - def ASSOC_RESPONSE_SENT(self): - log_runtime.debug("State ASSOC_RESPONSE_SENT") - - @ATMT.state() - def WPA_HANDSHAKE_STEP_1_SENT(self): - log_runtime.debug("State WPA_HANDSHAKE_STEP_1_SENT") - - @ATMT.state() - def WPA_HANDSHAKE_STEP_3_SENT(self): - log_runtime.debug("State WPA_HANDSHAKE_STEP_3_SENT") - - @ATMT.state() - def KRACK_DISPATCHER(self): - log_runtime.debug("State KRACK_DISPATCHER") - - @ATMT.state() - def ANALYZE_DATA(self): - log_runtime.debug("State ANALYZE_DATA") - - @ATMT.timeout(ANALYZE_DATA, 1) - def timeout_analyze_data(self): - raise self.KRACK_DISPATCHER() - - @ATMT.state() - def RENEW_GTK(self): - log_runtime.debug("State RENEW_GTK") - - @ATMT.state() - def WAIT_GTK_ACCEPT(self): - log_runtime.debug("State WAIT_GTK_ACCEPT") - - @ATMT.state() - def WAIT_ARP_REPLIES(self): - log_runtime.debug("State WAIT_ARP_REPLIES") - - @ATMT.state(final=1) - def EXIT(self): - log_runtime.debug("State EXIT") - - @ATMT.timeout(WAIT_GTK_ACCEPT, 1) - def timeout_wait_gtk_accept(self): - raise self.RENEW_GTK() - - @ATMT.timeout(WAIT_AUTH_REQUEST, 0.1) - def timeout_waiting(self): - raise self.WAIT_AUTH_REQUEST() - - @ATMT.action(timeout_waiting) - def send_beacon(self): - log_runtime.debug("Send a beacon") - rep = self.build_ap_info_pkt(Dot11Beacon, dest="ff:ff:ff:ff:ff:ff") - self.send(rep) - - @ATMT.receive_condition(WAIT_AUTH_REQUEST) - def probe_request_received(self, pkt): - # Avoid packet from other interfaces - if RadioTap not in pkt: - return - if Dot11ProbeReq in pkt and pkt[Dot11Elt::{'ID': 0}].info == self.ssid: - raise self.WAIT_AUTH_REQUEST().action_parameters(pkt) - - @ATMT.action(probe_request_received) - def send_probe_response(self, pkt): - rep = self.build_ap_info_pkt(Dot11ProbeResp, dest=pkt.addr2) - self.send(rep) - - @ATMT.receive_condition(WAIT_AUTH_REQUEST) - def authent_received(self, pkt): - # Avoid packet from other interfaces - if RadioTap not in pkt: - return - if Dot11Auth in pkt and pkt.addr1 == pkt.addr3 == self.mac: - raise self.AUTH_RESPONSE_SENT().action_parameters(pkt) - - @ATMT.action(authent_received) - def send_auth_response(self, pkt): - - # Save client MAC for later - self.client = pkt.addr2 - log_runtime.warning("Client %s connected!", self.client) - - # Launch DHCP Server - self.dhcp_server.run() - - rep = RadioTap() - rep /= Dot11(addr1=self.client, addr2=self.mac, addr3=self.mac) - rep /= Dot11Auth(seqnum=2, algo=pkt[Dot11Auth].algo, - status=pkt[Dot11Auth].status) - - self.send(rep) - - @ATMT.receive_condition(AUTH_RESPONSE_SENT) - def assoc_received(self, pkt): - if Dot11AssoReq in pkt and pkt.addr1 == pkt.addr3 == self.mac and \ - pkt[Dot11Elt::{'ID': 0}].info == self.ssid: - raise self.ASSOC_RESPONSE_SENT().action_parameters(pkt) - - @ATMT.action(assoc_received) - def send_assoc_response(self, pkt): - - # Get RSN info - temp_pkt = pkt[Dot11Elt::{"ID": 48}].copy() - temp_pkt.remove_payload() - self.RSN = raw(temp_pkt) - # Avoid 802.11w, etc. (deactivate RSN capabilities) - self.RSN = self.RSN[:-2] + b"\x00\x00" - - rep = RadioTap() - rep /= Dot11(addr1=self.client, addr2=self.mac, addr3=self.mac) - rep /= Dot11AssoResp() - rep /= Dot11EltRates(rates=[130, 132, 139, 150, 12, 18, 24, 36]) - - self.send(rep) - - @ATMT.condition(ASSOC_RESPONSE_SENT) - def assoc_sent(self): - raise self.WPA_HANDSHAKE_STEP_1_SENT() - - @ATMT.action(assoc_sent) - def send_wpa_handshake_1(self): - - self.anonce = self.gen_nonce(32) - - rep = RadioTap() - rep /= Dot11( - addr1=self.client, - addr2=self.mac, - addr3=self.mac, - FCfield='from-DS', - SC=(next(self.seq_num) << 4), - ) - rep /= LLC(dsap=0xaa, ssap=0xaa, ctrl=3) - rep /= SNAP(OUI=0, code=0x888e) # 802.1X Authentication - rep /= self.build_EAPOL_Key_8021X2004( - key_information=0x89, - replay_counter=next(self.replay_counter), - nonce=self.anonce, - ) - - self.send(rep) - - @ATMT.receive_condition(WPA_HANDSHAKE_STEP_1_SENT) - def wpa_handshake_1_sent(self, pkt): - # Avoid packet from other interfaces - if RadioTap not in pkt: - return - if EAPOL in pkt and pkt.addr1 == pkt.addr3 == self.mac and \ - pkt[EAPOL].load[1:2] == b"\x01": - # Key MIC: set, Secure / Error / Request / Encrypted / SMK - # message: not set - raise self.WPA_HANDSHAKE_STEP_3_SENT().action_parameters(pkt) - - @ATMT.action(wpa_handshake_1_sent) - def send_wpa_handshake_3(self, pkt): - - # Both nonce have been exchanged, install keys - client_nonce = pkt[EAPOL].load[13:13 + 0x20] - self.install_unicast_keys(client_nonce) - - # Check client MIC - - # Data: full message with MIC place replaced by 0s - # https://stackoverflow.com/questions/15133797/creating-wpa-message-integrity-code-mic-with-python - client_mic = pkt[EAPOL].load[77:77 + 16] - client_data = raw(pkt[EAPOL]).replace(client_mic, b"\x00" * len(client_mic)) # noqa: E501 - assert hmac.new(self.kck, client_data, hashlib.md5).digest() == client_mic # noqa: E501 - - rep = RadioTap() - rep /= Dot11( - addr1=self.client, - addr2=self.mac, - addr3=self.mac, - FCfield='from-DS', - SC=(next(self.seq_num) << 4), - ) - - rep /= LLC(dsap=0xaa, ssap=0xaa, ctrl=3) - rep /= SNAP(OUI=0, code=0x888e) # 802.1X Authentication - - self.install_GTK() - data = self.RSN - data += self.build_GTK_KDE() - - eap = self.build_EAPOL_Key_8021X2004( - key_information=0x13c9, - replay_counter=next(self.replay_counter), - nonce=self.anonce, - data=data, - key_mic=self.kck, - key_data_encrypt=self.kek, - ) - - self.send(rep / eap) - - @ATMT.receive_condition(WPA_HANDSHAKE_STEP_3_SENT) - def wpa_handshake_3_sent(self, pkt): - # Avoid packet from other interfaces - if RadioTap not in pkt: - return - if EAPOL in pkt and pkt.addr1 == pkt.addr3 == self.mac and \ - pkt[EAPOL].load[1:3] == b"\x03\x09": - self.time_handshake_end = time.time() - raise self.KRACK_DISPATCHER() - - @ATMT.condition(KRACK_DISPATCHER) - def krack_dispatch(self): - now = time.time() - # Handshake 3/4 replay - if self.double_3handshake and (self.krack_state & 1 == 0) and \ - (now - self.time_handshake_end) > self.wait_3handshake: - log_runtime.info("Trying to trigger CVE-2017-13077") - raise self.ANALYZE_DATA().action_parameters(send_3handshake=True) - - # GTK rekeying - if (self.krack_state & 2 == 0) and \ - (now - self.time_handshake_end) > self.wait_gtk: - raise self.ANALYZE_DATA().action_parameters(send_gtk=True) - - # Fallback in data analysis - raise self.ANALYZE_DATA().action_parameters() - - @ATMT.action(krack_dispatch) - def krack_proceed(self, send_3handshake=False, send_gtk=False): - if send_3handshake: - rep = RadioTap() - rep /= Dot11( - addr1=self.client, - addr2=self.mac, - addr3=self.mac, - FCfield='from-DS', - SC=(next(self.seq_num) << 4), - subtype=0, - type="Data", - ) - - rep /= LLC(dsap=0xaa, ssap=0xaa, ctrl=3) - rep /= SNAP(OUI=0, code=0x888e) # 802.1X Authentication - - data = self.RSN - data += self.build_GTK_KDE() - - eap_2 = self.build_EAPOL_Key_8021X2004( - # Key information 0x13c9: - # ARC4 HMAC-MD5, Pairwise Key, Install, KEY ACK, KEY MIC, Secure, # noqa: E501 - # Encrypted, SMK - key_information=0x13c9, - replay_counter=next(self.replay_counter), - nonce=self.anonce, - data=data, - key_mic=self.kck, - key_data_encrypt=self.kek, - ) - - rep /= eap_2 - - if self.encrypt_3handshake: - self.send_wpa_to_client(rep[LLC]) - else: - self.send(rep) - - self.krack_state |= 1 - - if send_gtk: - self.krack_state |= 2 - # Renew the GTK - self.install_GTK() - raise self.RENEW_GTK() - - @ATMT.receive_condition(ANALYZE_DATA) - def get_data(self, pkt): - # Avoid packet from other interfaces - if RadioTap not in pkt: - return - - # Skip retries - if pkt[Dot11].FCfield.retry: - return - - # Skip unencrypted frames (TKIP rely on encrypted packets) - if not pkt[Dot11].FCfield.protected: - return - - # Dot11.type 2: Data - if pkt.type == 2 and Raw in pkt and pkt.addr1 == self.mac: - # Do not check pkt.addr3, frame can be broadcast - raise self.KRACK_DISPATCHER().action_parameters(pkt) - - @ATMT.action(get_data) - def extract_iv(self, pkt): - # Get IV - TSC, _, _ = parse_TKIP_hdr(pkt) - iv = TSC[0] | (TSC[1] << 8) | (TSC[2] << 16) | (TSC[3] << 24) | \ - (TSC[4] << 32) | (TSC[5] << 40) - log_runtime.info("Got a packet with IV: %s", hex(iv)) - - if self.last_iv is None: - self.last_iv = iv - else: - if iv <= self.last_iv: - log_runtime.warning("IV re-use!! Client seems to be " - "vulnerable to handshake 3/4 replay " - "(CVE-2017-13077)" - ) - - data_clear = None - - # Normal decoding - data = parse_data_pkt(pkt, self.tk) - try: - data_clear = check_MIC_ICV(data, self.mic_sta_to_ap, pkt.addr2, - pkt.addr3) - except (ICVError, MICError): - pass - - # Decoding with a 0's TK - if data_clear is None: - data = parse_data_pkt(pkt, b"\x00" * len(self.tk)) - try: - mic_key = b"\x00" * len(self.mic_sta_to_ap) - data_clear = check_MIC_ICV(data, mic_key, pkt.addr2, pkt.addr3) - log_runtime.warning("Client has installed an all zero " - "encryption key (TK)!!") - except (ICVError, MICError): - pass - - if data_clear is None: - log_runtime.warning("Unable to decode the packet, something went " - "wrong") - log_runtime.debug(hexdump(pkt, dump=True)) - self.deal_common_pkt(pkt) - return - - log_runtime.debug(hexdump(data_clear, dump=True)) - pkt = LLC(data_clear) - log_runtime.debug(repr(pkt)) - self.deal_common_pkt(pkt) - - @ATMT.condition(RENEW_GTK) - def gtk_pkt_1(self): - raise self.WAIT_GTK_ACCEPT() - - @ATMT.action(gtk_pkt_1) - def send_renew_gtk(self): - - rep_to_enc = LLC(dsap=0xaa, ssap=0xaa, ctrl=3) - rep_to_enc /= SNAP(OUI=0, code=0x888e) # 802.1X Authentication - - data = self.build_GTK_KDE() - - eap = self.build_EAPOL_Key_8021X2004( - # Key information 0x1381: - # ARC4 HMAC-MD5, Group Key, KEY ACK, KEY MIC, Secure, Encrypted, - # SMK - key_information=0x1381, - replay_counter=next(self.replay_counter), - nonce=self.anonce, - data=data, - key_mic=self.kck, - key_data_encrypt=self.kek, - ) - - rep_to_enc /= eap - self.send_wpa_to_client(rep_to_enc) - - @ATMT.receive_condition(WAIT_GTK_ACCEPT) - def get_gtk_2(self, pkt): - # Avoid packet from other interfaces - if RadioTap not in pkt: - return - - # Skip retries - if pkt[Dot11].FCfield.retry: - return - - # Skip unencrypted frames (TKIP rely on encrypted packets) - if not pkt[Dot11].FCfield.protected: - return - - # Normal decoding - try: - data = parse_data_pkt(pkt, self.tk) - except ValueError: - return - try: - data_clear = check_MIC_ICV(data, self.mic_sta_to_ap, pkt.addr2, - pkt.addr3) - except (ICVError, MICError): - return - - pkt_clear = LLC(data_clear) - if EAPOL in pkt_clear and pkt.addr1 == pkt.addr3 == self.mac and \ - pkt_clear[EAPOL].load[1:3] == b"\x03\x01": - raise self.WAIT_ARP_REPLIES() - - @ATMT.action(get_gtk_2) - def send_arp_req(self): - - if self.krack_state & 4 == 0: - # Set the address for future uses - self.arp_target_ip = self.dhcp_server.leases.get(self.client, - self.arp_target_ip) # noqa: E501 - assert self.arp_target_ip is not None - - # Send the first ARP requests, for control test - log_runtime.info("Send ARP who-was from '%s' to '%s'", - self.arp_source_ip, - self.arp_target_ip) - arp_pkt = self.send_wpa_to_group( - LLC() / SNAP() / ARP(op="who-has", - psrc=self.arp_source_ip, - pdst=self.arp_target_ip, - hwsrc=self.mac), - dest='ff:ff:ff:ff:ff:ff', - ) - self.arp_sent.append(arp_pkt) - else: - if self.arp_to_send < len(self.arp_sent): - # Re-send the ARP requests already sent - self.send(self.arp_sent[self.arp_to_send]) - self.arp_to_send += 1 - else: - # Re-send GTK - self.arp_to_send = 0 - self.arp_retry += 1 - log_runtime.info("Trying to trigger CVE-2017-13080 %d/%d", - self.arp_retry, self.ARP_MAX_RETRY) - if self.arp_retry > self.ARP_MAX_RETRY: - # We retries 100 times to send GTK, then already sent ARPs - log_runtime.warning("Client is likely not vulnerable to " - "CVE-2017-13080") - raise self.EXIT() - - raise self.RENEW_GTK() - - @ATMT.timeout(WAIT_ARP_REPLIES, 0.5) - def resend_arp_req(self): - self.send_arp_req() - raise self.WAIT_ARP_REPLIES() - - @ATMT.receive_condition(WAIT_ARP_REPLIES) - def get_arp(self, pkt): - # Avoid packet from other interfaces - if RadioTap not in pkt: - return - - # Skip retries - if pkt[Dot11].FCfield.retry: - return - - # Skip unencrypted frames (TKIP rely on encrypted packets) - if not pkt[Dot11].FCfield.protected: - return - - # Dot11.type 2: Data - if pkt.type == 2 and Raw in pkt and pkt.addr1 == self.mac: - # Do not check pkt.addr3, frame can be broadcast - raise self.WAIT_ARP_REPLIES().action_parameters(pkt) - - @ATMT.action(get_arp) - def check_arp_reply(self, pkt): - data = parse_data_pkt(pkt, self.tk) - try: - data_clear = check_MIC_ICV(data, self.mic_sta_to_ap, pkt.addr2, - pkt.addr3) - except (ICVError, MICError): - return - - decoded_pkt = LLC(data_clear) - log_runtime.debug(hexdump(decoded_pkt, dump=True)) - log_runtime.debug(repr(decoded_pkt)) - self.deal_common_pkt(decoded_pkt) - if ARP not in decoded_pkt: - return - - # ARP.op 2: is-at - if decoded_pkt[ARP].op == 2 and \ - decoded_pkt[ARP].psrc == self.arp_target_ip and \ - decoded_pkt[ARP].pdst == self.arp_source_ip: - # Got the expected ARP - if self.krack_state & 4 == 0: - # First time, normal behavior - log_runtime.info("Got ARP reply, this is normal") - self.krack_state |= 4 - log_runtime.info("Trying to trigger CVE-2017-13080") - raise self.RENEW_GTK() - else: - # Second time, the packet has been accepted twice! - log_runtime.warning("Broadcast packet accepted twice!! " - "(CVE-2017-13080)") diff --git a/scripts/external_libs/scapy-2.4.3/scapy/modules/krack/crypto.py b/scripts/external_libs/scapy-2.4.3/scapy/modules/krack/crypto.py deleted file mode 100644 index 42cf76ab36..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/modules/krack/crypto.py +++ /dev/null @@ -1,376 +0,0 @@ -import hashlib -import hmac -from struct import unpack, pack -from zlib import crc32 - -from cryptography.hazmat.primitives.ciphers import Cipher, algorithms -from cryptography.hazmat.backends import default_backend - -import scapy.modules.six as six -from scapy.modules.six.moves import range -from scapy.compat import orb, chb -from scapy.layers.dot11 import Dot11TKIP -from scapy.utils import mac2str - -# ARC4 - - -def ARC4_encrypt(key, data, skip=0): - """Encrypt data @data with key @key, skipping @skip first bytes of the - keystream""" - - algorithm = algorithms.ARC4(key) - cipher = Cipher(algorithm, mode=None, backend=default_backend()) - encryptor = cipher.encryptor() - if skip: - encryptor.update(b"\x00" * skip) - return encryptor.update(data) - - -def ARC4_decrypt(key, data, skip=0): - """Decrypt data @data with key @key, skipping @skip first bytes of the - keystream""" - return ARC4_encrypt(key, data, skip) - -# Custom WPA PseudoRandomFunction - - -def customPRF512(key, amac, smac, anonce, snonce): - """Source https://stackoverflow.com/questions/12018920/""" - A = b"Pairwise key expansion" - B = b"".join(sorted([amac, smac]) + sorted([anonce, snonce])) - - blen = 64 - i = 0 - R = b'' - while i <= ((blen * 8 + 159) / 160): - hmacsha1 = hmac.new(key, A + chb(0x00) + B + chb(i), hashlib.sha1) - i += 1 - R = R + hmacsha1.digest() - return R[:blen] - -# TKIP - WEPSeed generation -# Tested against pyDot11: tkip.py - - -# 802.11i p.53-54 -_SBOXS = [ - [ - 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, - 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, - 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, - 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, - 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, - 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, - 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, - 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, - 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, - 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, - 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, - 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, - 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, - 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, - 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, - 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, - 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, - 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, - 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, - 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, - 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, - 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, - 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, - 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, - 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, - 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, - 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, - 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, - 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, - 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, - 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, - 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A - ], - [ - 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491, - 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC, - 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB, - 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B, - 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83, - 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A, - 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F, - 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA, - 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B, - 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713, - 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6, - 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85, - 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411, - 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B, - 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1, - 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF, - 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E, - 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6, - 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B, - 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD, - 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8, - 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2, - 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049, - 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810, - 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197, - 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F, - 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C, - 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927, - 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733, - 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5, - 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0, - 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C - ] -] - -# 802.11i Annex H -PHASE1_LOOP_CNT = 8 - - -def _MK16(b1, b2): - return (b1 << 8) | b2 - - -def _SBOX16(index): - return _SBOXS[0][index & 0xff] ^ _SBOXS[1][(index >> 8)] - - -def _CAST16(value): - return value & 0xffff - - -def _RotR1(value): - return ((value >> 1) & 0x7fff) | (value << 15) - - -def gen_TKIP_RC4_key(TSC, TA, TK): - """Implement TKIP WEPSeed generation - TSC: packet IV - TA: target addr bytes - TK: temporal key - """ - - assert len(TSC) == 6 - assert len(TA) == 6 - assert len(TK) == 16 - assert all(isinstance(x, six.integer_types) for x in TSC + TA + TK) - - # Phase 1 - # 802.11i p.54 - - # Phase 1 - Step 1 - TTAK = [] - TTAK.append(_MK16(TSC[3], TSC[2])) - TTAK.append(_MK16(TSC[5], TSC[4])) - TTAK.append(_MK16(TA[1], TA[0])) - TTAK.append(_MK16(TA[3], TA[2])) - TTAK.append(_MK16(TA[5], TA[4])) - - # Phase 1 - Step 2 - for i in range(PHASE1_LOOP_CNT): - j = 2 * (i & 1) - TTAK[0] = _CAST16(TTAK[0] + _SBOX16(TTAK[4] ^ _MK16(TK[1 + j], TK[0 + j]))) # noqa: E501 - TTAK[1] = _CAST16(TTAK[1] + _SBOX16(TTAK[0] ^ _MK16(TK[5 + j], TK[4 + j]))) # noqa: E501 - TTAK[2] = _CAST16(TTAK[2] + _SBOX16(TTAK[1] ^ _MK16(TK[9 + j], TK[8 + j]))) # noqa: E501 - TTAK[3] = _CAST16(TTAK[3] + _SBOX16(TTAK[2] ^ _MK16(TK[13 + j], TK[12 + j]))) # noqa: E501 - TTAK[4] = _CAST16(TTAK[4] + _SBOX16(TTAK[3] ^ _MK16(TK[1 + j], TK[0 + j])) + i) # noqa: E501 - - # Phase 2 - # 802.11i p.56 - - # Phase 2 - Step 1 - PPK = list(TTAK) - PPK.append(_CAST16(TTAK[4] + _MK16(TSC[1], TSC[0]))) - - # Phase 2 - Step 2 - PPK[0] = _CAST16(PPK[0] + _SBOX16(PPK[5] ^ _MK16(TK[1], TK[0]))) - PPK[1] = _CAST16(PPK[1] + _SBOX16(PPK[0] ^ _MK16(TK[3], TK[2]))) - PPK[2] = _CAST16(PPK[2] + _SBOX16(PPK[1] ^ _MK16(TK[5], TK[4]))) - PPK[3] = _CAST16(PPK[3] + _SBOX16(PPK[2] ^ _MK16(TK[7], TK[6]))) - PPK[4] = _CAST16(PPK[4] + _SBOX16(PPK[3] ^ _MK16(TK[9], TK[8]))) - PPK[5] = _CAST16(PPK[5] + _SBOX16(PPK[4] ^ _MK16(TK[11], TK[10]))) - - PPK[0] = _CAST16(PPK[0] + _RotR1(PPK[5] ^ _MK16(TK[13], TK[12]))) - PPK[1] = _CAST16(PPK[1] + _RotR1(PPK[0] ^ _MK16(TK[15], TK[14]))) - PPK[2] = _CAST16(PPK[2] + _RotR1(PPK[1])) - PPK[3] = _CAST16(PPK[3] + _RotR1(PPK[2])) - PPK[4] = _CAST16(PPK[4] + _RotR1(PPK[3])) - PPK[5] = _CAST16(PPK[5] + _RotR1(PPK[4])) - - # Phase 2 - Step 3 - WEPSeed = [] - WEPSeed.append(TSC[1]) - WEPSeed.append((TSC[1] | 0x20) & 0x7f) - WEPSeed.append(TSC[0]) - WEPSeed.append(((PPK[5] ^ _MK16(TK[1], TK[0])) >> 1) & 0xFF) - for i in range(6): - WEPSeed.append(PPK[i] & 0xFF) - WEPSeed.append(PPK[i] >> 8) - - assert len(WEPSeed) == 16 - - return b"".join(chb(x) for x in WEPSeed) - -# TKIP - Michael -# Tested against cryptopy (crypto.keyedHash.michael: Michael) - - -def _rotate_right32(value, shift): - return (value >> (shift % 32) | value << ((32 - shift) % 32)) & 0xFFFFFFFF - - -def _rotate_left32(value, shift): - return (value << (shift % 32) | value >> ((32 - shift) % 32)) & 0xFFFFFFFF - - -def _XSWAP(value): - """Swap 2 least significant bytes of @value""" - return ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8) - - -def _michael_b(m_l, m_r): - """Defined in 802.11i p.49""" - m_r = m_r ^ _rotate_left32(m_l, 17) - m_l = (m_l + m_r) % 2**32 - m_r = m_r ^ _XSWAP(m_l) - m_l = (m_l + m_r) % 2**32 - m_r = m_r ^ _rotate_left32(m_l, 3) - m_l = (m_l + m_r) % 2**32 - m_r = m_r ^ _rotate_right32(m_l, 2) - m_l = (m_l + m_r) % 2**32 - return m_l, m_r - - -def michael(key, to_hash): - """Defined in 802.11i p.48""" - - # Block size: 4 - nb_block, nb_extra_bytes = divmod(len(to_hash), 4) - # Add padding - data = to_hash + chb(0x5a) + b"\x00" * (7 - nb_extra_bytes) - - # Hash - m_l, m_r = unpack('> 40) & 0xFF, - (iv >> 32) & 0xFF, - (iv >> 24) & 0xFF, - (iv >> 16) & 0xFF, - (iv >> 8) & 0xFF, - iv & 0xFF - ) - bitfield = 1 << 5 # Extended IV - TKIP_hdr = chb(TSC1) + chb((TSC1 | 0x20) & 0x7f) + chb(TSC0) + chb(bitfield) # noqa: E501 - TKIP_hdr += chb(TSC2) + chb(TSC3) + chb(TSC4) + chb(TSC5) - - TA = [orb(e) for e in mac2str(mac)] - TSC = [TSC0, TSC1, TSC2, TSC3, TSC4, TSC5] - TK = [orb(x) for x in tk] - - rc4_key = gen_TKIP_RC4_key(TSC, TA, TK) - return TKIP_hdr + ARC4_encrypt(rc4_key, data) - - -def parse_data_pkt(pkt, tk): - """Extract data from a WPA packet @pkt with temporal key @tk""" - TSC, TA, data = parse_TKIP_hdr(pkt) - TK = [orb(x) for x in tk] - - rc4_key = gen_TKIP_RC4_key(TSC, TA, TK) - return ARC4_decrypt(rc4_key, data) - - -class ICVError(Exception): - """The expected ICV is not the computed one""" - pass - - -class MICError(Exception): - """The expected MIC is not the computed one""" - pass - - -def check_MIC_ICV(data, mic_key, source, dest): - """Check MIC, ICV & return the data from a decrypted TKIP packet""" - assert len(data) > 12 - - # DATA - MIC(DA - SA - Priority=0 - 0 - 0 - 0 - DATA) - ICV - # 802.11i p.47 - - ICV = data[-4:] - MIC = data[-12:-4] - data_clear = data[:-12] - - expected_ICV = pack(" -# This program is published under a GPLv2 license - -"""Clone of Nmap's first generation OS fingerprinting. - -This code works with the first-generation OS detection and -nmap-os-fingerprints, which has been removed from Nmap on November 3, -2007 (https://github.com/nmap/nmap/commit/50c49819), which means it is -outdated. - -To get the last published version of this outdated fingerprint -database, you can fetch it from -. - -""" - -from __future__ import absolute_import -import os -import re - -from scapy.data import KnowledgeBase -from scapy.config import conf -from scapy.arch import WINDOWS -from scapy.error import warning -from scapy.layers.inet import IP, TCP, UDP, ICMP, UDPerror, IPerror -from scapy.packet import NoPayload -from scapy.sendrecv import sr -from scapy.compat import plain_str, raw -import scapy.modules.six as six - - -if WINDOWS: - conf.nmap_base = os.environ["ProgramFiles"] + "\\nmap\\nmap-os-fingerprints" # noqa: E501 -else: - conf.nmap_base = "/usr/share/nmap/nmap-os-fingerprints" - - -###################### -# nmap OS fp stuff # -###################### - - -_NMAP_LINE = re.compile('^([^\\(]*)\\(([^\\)]*)\\)$') - - -class NmapKnowledgeBase(KnowledgeBase): - """A KnowledgeBase specialized in Nmap first-generation OS -fingerprints database. Loads from conf.nmap_base when self.filename is -None. - - """ - - def lazy_init(self): - try: - fdesc = open(conf.nmap_base - if self.filename is None else - self.filename, "rb") - except (IOError, TypeError): - warning("Cannot open nmap database [%s]", self.filename) - self.filename = None - return - - self.base = [] - name = None - sig = {} - for line in fdesc: - line = plain_str(line) - line = line.split('#', 1)[0].strip() - if not line: - continue - if line.startswith("Fingerprint "): - if name is not None: - self.base.append((name, sig)) - name = line[12:].strip() - sig = {} - continue - if line.startswith("Class "): - continue - line = _NMAP_LINE.search(line) - if line is None: - continue - test, values = line.groups() - sig[test] = dict(val.split('=', 1) for val in - (values.split('%') if values else [])) - if name is not None: - self.base.append((name, sig)) - fdesc.close() - - -nmap_kdb = NmapKnowledgeBase(None) - - -def nmap_tcppacket_sig(pkt): - res = {} - if pkt is not None: - res["DF"] = "Y" if pkt.flags.DF else "N" - res["W"] = "%X" % pkt.window - res["ACK"] = "S++" if pkt.ack == 2 else "S" if pkt.ack == 1 else "O" - res["Flags"] = str(pkt[TCP].flags)[::-1] - res["Ops"] = "".join(x[0][0] for x in pkt[TCP].options) - else: - res["Resp"] = "N" - return res - - -def nmap_udppacket_sig(snd, rcv): - res = {} - if rcv is None: - res["Resp"] = "N" - else: - res["DF"] = "Y" if rcv.flags.DF else "N" - res["TOS"] = "%X" % rcv.tos - res["IPLEN"] = "%X" % rcv.len - res["RIPTL"] = "%X" % rcv.payload.payload.len - res["RID"] = "E" if snd.id == rcv[IPerror].id else "F" - res["RIPCK"] = "E" if snd.chksum == rcv[IPerror].chksum else ( - "0" if rcv[IPerror].chksum == 0 else "F" - ) - res["UCK"] = "E" if snd.payload.chksum == rcv[UDPerror].chksum else ( - "0" if rcv[UDPerror].chksum == 0 else "F" - ) - res["ULEN"] = "%X" % rcv[UDPerror].len - res["DAT"] = "E" if ( - isinstance(rcv[UDPerror].payload, NoPayload) or - raw(rcv[UDPerror].payload) == raw(snd[UDP].payload) - ) else "F" - return res - - -def nmap_match_one_sig(seen, ref): - cnt = sum(val in ref.get(key, "").split("|") - for key, val in six.iteritems(seen)) - if cnt == 0 and seen.get("Resp") == "N": - return 0.7 - return float(cnt) / len(seen) - - -def nmap_sig(target, oport=80, cport=81, ucport=1): - res = {} - - tcpopt = [("WScale", 10), - ("NOP", None), - ("MSS", 256), - ("Timestamp", (123, 0))] - tests = [ - IP(dst=target, id=1) / - TCP(seq=1, sport=5001 + i, dport=oport if i < 4 else cport, - options=tcpopt, flags=flags) - for i, flags in enumerate(["CS", "", "SFUP", "A", "S", "A", "FPU"]) - ] - tests.append(IP(dst=target) / UDP(sport=5008, dport=ucport) / (300 * "i")) - - ans, unans = sr(tests, timeout=2) - ans.extend((x, None) for x in unans) - - for snd, rcv in ans: - if snd.sport == 5008: - res["PU"] = (snd, rcv) - else: - test = "T%i" % (snd.sport - 5000) - if rcv is not None and ICMP in rcv: - warning("Test %s answered by an ICMP", test) - rcv = None - res[test] = rcv - - return nmap_probes2sig(res) - - -def nmap_probes2sig(tests): - tests = tests.copy() - res = {} - if "PU" in tests: - res["PU"] = nmap_udppacket_sig(*tests["PU"]) - del tests["PU"] - for k in tests: - res[k] = nmap_tcppacket_sig(tests[k]) - return res - - -def nmap_search(sigs): - guess = 0, [] - for osval, fprint in nmap_kdb.get_base(): - score = 0.0 - for test, values in six.iteritems(fprint): - if test in sigs: - score += nmap_match_one_sig(sigs[test], values) - score /= len(sigs) - if score > guess[0]: - guess = score, [osval] - elif score == guess[0]: - guess[1].append(osval) - return guess - - -@conf.commands.register -def nmap_fp(target, oport=80, cport=81): - """nmap fingerprinting -nmap_fp(target, [oport=80,] [cport=81,]) -> list of best guesses with accuracy -""" - sigs = nmap_sig(target, oport, cport) - return nmap_search(sigs) - - -@conf.commands.register -def nmap_sig2txt(sig): - torder = ["TSeq", "T1", "T2", "T3", "T4", "T5", "T6", "T7", "PU"] - korder = ["Class", "gcd", "SI", "IPID", "TS", - "Resp", "DF", "W", "ACK", "Flags", "Ops", - "TOS", "IPLEN", "RIPTL", "RID", "RIPCK", "UCK", "ULEN", "DAT"] - txt = [] - for i in sig: - if i not in torder: - torder.append(i) - for test in torder: - testsig = sig.get(test) - if testsig is None: - continue - txt.append("%s(%s)" % (test, "%".join( - "%s=%s" % (key, testsig[key]) for key in korder if key in testsig - ))) - return "\n".join(txt) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/modules/p0f.py b/scripts/external_libs/scapy-2.4.3/scapy/modules/p0f.py deleted file mode 100644 index ad5891af0c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/modules/p0f.py +++ /dev/null @@ -1,623 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Clone of p0f passive OS fingerprinting -""" - -from __future__ import absolute_import -from __future__ import print_function -import time -import struct -import os -import socket -import random - -from scapy.data import KnowledgeBase, select_path -from scapy.config import conf -from scapy.compat import raw -from scapy.layers.inet import IP, TCP, TCPOptions -from scapy.packet import NoPayload, Packet -from scapy.error import warning, Scapy_Exception, log_runtime -from scapy.volatile import RandInt, RandByte, RandNum, RandShort, RandString -from scapy.sendrecv import sniff -from scapy.modules import six -from scapy.modules.six.moves import map, range -if conf.route is None: - # unused import, only to initialize conf.route - import scapy.route # noqa: F401 - -_p0fpaths = ["/etc/p0f", "/usr/share/p0f", "/opt/local"] - -conf.p0f_base = select_path(_p0fpaths, "p0f.fp") -conf.p0fa_base = select_path(_p0fpaths, "p0fa.fp") -conf.p0fr_base = select_path(_p0fpaths, "p0fr.fp") -conf.p0fo_base = select_path(_p0fpaths, "p0fo.fp") - - -############### -# p0f stuff # -############### - -# File format (according to p0f.fp) : -# -# wwww:ttt:D:ss:OOO...:QQ:OS:Details -# -# wwww - window size -# ttt - initial TTL -# D - don't fragment bit (0=unset, 1=set) -# ss - overall SYN packet size -# OOO - option value and order specification -# QQ - quirks list -# OS - OS genre -# details - OS description - -class p0fKnowledgeBase(KnowledgeBase): - def __init__(self, filename): - KnowledgeBase.__init__(self, filename) - # self.ttl_range=[255] - - def lazy_init(self): - try: - f = open(self.filename) - except IOError: - warning("Can't open base %s", self.filename) - return - try: - self.base = [] - for line in f: - if line[0] in ["#", "\n"]: - continue - line = tuple(line.split(":")) - if len(line) < 8: - continue - - def a2i(x): - if x.isdigit(): - return int(x) - return x - li = [a2i(e) for e in line[1:4]] - # if li[0] not in self.ttl_range: - # self.ttl_range.append(li[0]) - # self.ttl_range.sort() - self.base.append((line[0], li[0], li[1], li[2], line[4], - line[5], line[6], line[7][:-1])) - except Exception: - warning("Can't parse p0f database (new p0f version ?)") - self.base = None - f.close() - - -p0f_kdb, p0fa_kdb, p0fr_kdb, p0fo_kdb = None, None, None, None - - -def p0f_load_knowledgebases(): - global p0f_kdb, p0fa_kdb, p0fr_kdb, p0fo_kdb - p0f_kdb = p0fKnowledgeBase(conf.p0f_base) - p0fa_kdb = p0fKnowledgeBase(conf.p0fa_base) - p0fr_kdb = p0fKnowledgeBase(conf.p0fr_base) - p0fo_kdb = p0fKnowledgeBase(conf.p0fo_base) - - -p0f_load_knowledgebases() - - -def p0f_selectdb(flags): - # tested flags: S, R, A - if flags & 0x16 == 0x2: - # SYN - return p0f_kdb - elif flags & 0x16 == 0x12: - # SYN/ACK - return p0fa_kdb - elif flags & 0x16 in [0x4, 0x14]: - # RST RST/ACK - return p0fr_kdb - elif flags & 0x16 == 0x10: - # ACK - return p0fo_kdb - else: - return None - - -def packet2p0f(pkt): - pkt = pkt.copy() - pkt = pkt.__class__(raw(pkt)) - while pkt.haslayer(IP) and pkt.haslayer(TCP): - pkt = pkt.getlayer(IP) - if isinstance(pkt.payload, TCP): - break - pkt = pkt.payload - - if not isinstance(pkt, IP) or not isinstance(pkt.payload, TCP): - raise TypeError("Not a TCP/IP packet") - # if pkt.payload.flags & 0x7 != 0x02: #S,!F,!R - # raise TypeError("Not a SYN or SYN/ACK packet") - - db = p0f_selectdb(pkt.payload.flags) - - # t = p0f_kdb.ttl_range[:] - # t += [pkt.ttl] - # t.sort() - # ttl=t[t.index(pkt.ttl)+1] - ttl = pkt.ttl - - ss = len(pkt) - # from p0f/config.h : PACKET_BIG = 100 - if ss > 100: - if db == p0fr_kdb: - # p0fr.fp: "Packet size may be wildcarded. The meaning of - # wildcard is, however, hardcoded as 'size > - # PACKET_BIG'" - ss = '*' - else: - ss = 0 - if db == p0fo_kdb: - # p0fo.fp: "Packet size MUST be wildcarded." - ss = '*' - - ooo = "" - mss = -1 - qqT = False - qqP = False - # qqBroken = False - ilen = (pkt.payload.dataofs << 2) - 20 # from p0f.c - for option in pkt.payload.options: - ilen -= 1 - if option[0] == "MSS": - ooo += "M" + str(option[1]) + "," - mss = option[1] - # FIXME: qqBroken - ilen -= 3 - elif option[0] == "WScale": - ooo += "W" + str(option[1]) + "," - # FIXME: qqBroken - ilen -= 2 - elif option[0] == "Timestamp": - if option[1][0] == 0: - ooo += "T0," - else: - ooo += "T," - if option[1][1] != 0: - qqT = True - ilen -= 9 - elif option[0] == "SAckOK": - ooo += "S," - ilen -= 1 - elif option[0] == "NOP": - ooo += "N," - elif option[0] == "EOL": - ooo += "E," - if ilen > 0: - qqP = True - else: - if isinstance(option[0], str): - ooo += "?%i," % TCPOptions[1][option[0]] - else: - ooo += "?%i," % option[0] - # FIXME: ilen - ooo = ooo[:-1] - if ooo == "": - ooo = "." - - win = pkt.payload.window - if mss != -1: - if mss != 0 and win % mss == 0: - win = "S" + str(win / mss) - elif win % (mss + 40) == 0: - win = "T" + str(win / (mss + 40)) - win = str(win) - - qq = "" - - if db == p0fr_kdb: - if pkt.payload.flags & 0x10 == 0x10: - # p0fr.fp: "A new quirk, 'K', is introduced to denote - # RST+ACK packets" - qq += "K" - # The two next cases should also be only for p0f*r*, but although - # it's not documented (or I have not noticed), p0f seems to - # support the '0' and 'Q' quirks on any databases (or at the least - # "classical" p0f.fp). - if pkt.payload.seq == pkt.payload.ack: - # p0fr.fp: "A new quirk, 'Q', is used to denote SEQ number - # equal to ACK number." - qq += "Q" - if pkt.payload.seq == 0: - # p0fr.fp: "A new quirk, '0', is used to denote packets - # with SEQ number set to 0." - qq += "0" - if qqP: - qq += "P" - if pkt.id == 0: - qq += "Z" - if pkt.options != []: - qq += "I" - if pkt.payload.urgptr != 0: - qq += "U" - if pkt.payload.reserved != 0: - qq += "X" - if pkt.payload.ack != 0: - qq += "A" - if qqT: - qq += "T" - if db == p0fo_kdb: - if pkt.payload.flags & 0x20 != 0: - # U - # p0fo.fp: "PUSH flag is excluded from 'F' quirk checks" - qq += "F" - else: - if pkt.payload.flags & 0x28 != 0: - # U or P - qq += "F" - if db != p0fo_kdb and not isinstance(pkt.payload.payload, NoPayload): - # p0fo.fp: "'D' quirk is not checked for." - qq += "D" - # FIXME : "!" - broken options segment: not handled yet - - if qq == "": - qq = "." - - return (db, (win, ttl, pkt.flags.DF, ss, ooo, qq)) - - -def p0f_correl(x, y): - d = 0 - # wwww can be "*" or "%nn". "Tnn" and "Snn" should work fine with - # the x[0] == y[0] test. - d += (x[0] == y[0] or y[0] == "*" or (y[0][0] == "%" and x[0].isdigit() and (int(x[0]) % int(y[0][1:])) == 0)) # noqa: E501 - # ttl - d += (y[1] >= x[1] and y[1] - x[1] < 32) - for i in [2, 5]: - d += (x[i] == y[i] or y[i] == '*') - # '*' has a special meaning for ss - d += x[3] == y[3] - xopt = x[4].split(",") - yopt = y[4].split(",") - if len(xopt) == len(yopt): - same = True - for i in range(len(xopt)): - if not (xopt[i] == yopt[i] or - (len(yopt[i]) == 2 and len(xopt[i]) > 1 and - yopt[i][1] == "*" and xopt[i][0] == yopt[i][0]) or - (len(yopt[i]) > 2 and len(xopt[i]) > 1 and - yopt[i][1] == "%" and xopt[i][0] == yopt[i][0] and - int(xopt[i][1:]) % int(yopt[i][2:]) == 0)): - same = False - break - if same: - d += len(xopt) - return d - - -@conf.commands.register -def p0f(pkt): - """Passive OS fingerprinting: which OS emitted this TCP packet ? -p0f(packet) -> accuracy, [list of guesses] -""" - db, sig = packet2p0f(pkt) - if db: - pb = db.get_base() - else: - pb = [] - if not pb: - warning("p0f base empty.") - return [] - # s = len(pb[0][0]) - r = [] - max = len(sig[4].split(",")) + 5 - for b in pb: - d = p0f_correl(sig, b) - if d == max: - r.append((b[6], b[7], b[1] - pkt[IP].ttl)) - return r - - -def prnp0f(pkt): - """Calls p0f and returns a user-friendly output""" - # we should print which DB we use - try: - r = p0f(pkt) - except Exception: - return - if r == []: - r = ("UNKNOWN", "[" + ":".join(map(str, packet2p0f(pkt)[1])) + ":?:?]", None) # noqa: E501 - else: - r = r[0] - uptime = None - try: - uptime = pkt2uptime(pkt) - except Exception: - pass - if uptime == 0: - uptime = None - res = pkt.sprintf("%IP.src%:%TCP.sport% - " + r[0] + " " + r[1]) - if uptime is not None: - res += pkt.sprintf(" (up: " + str(uptime / 3600) + " hrs)\n -> %IP.dst%:%TCP.dport% (%TCP.flags%)") # noqa: E501 - else: - res += pkt.sprintf("\n -> %IP.dst%:%TCP.dport% (%TCP.flags%)") - if r[2] is not None: - res += " (distance " + str(r[2]) + ")" - print(res) - - -@conf.commands.register -def pkt2uptime(pkt, HZ=100): - """Calculate the date the machine which emitted the packet booted using TCP timestamp # noqa: E501 -pkt2uptime(pkt, [HZ=100])""" - if not isinstance(pkt, Packet): - raise TypeError("Not a TCP packet") - if isinstance(pkt, NoPayload): - raise TypeError("Not a TCP packet") - if not isinstance(pkt, TCP): - return pkt2uptime(pkt.payload) - for opt in pkt.options: - if opt[0] == "Timestamp": - # t = pkt.time - opt[1][0] * 1.0/HZ - # return time.ctime(t) - t = opt[1][0] / HZ - return t - raise TypeError("No timestamp option") - - -def p0f_impersonate(pkt, osgenre=None, osdetails=None, signature=None, - extrahops=0, mtu=1500, uptime=None): - """Modifies pkt so that p0f will think it has been sent by a -specific OS. If osdetails is None, then we randomly pick up a -personality matching osgenre. If osgenre and signature are also None, -we use a local signature (using p0f_getlocalsigs). If signature is -specified (as a tuple), we use the signature. - -For now, only TCP Syn packets are supported. -Some specifications of the p0f.fp file are not (yet) implemented.""" - pkt = pkt.copy() - # pkt = pkt.__class__(raw(pkt)) - while pkt.haslayer(IP) and pkt.haslayer(TCP): - pkt = pkt.getlayer(IP) - if isinstance(pkt.payload, TCP): - break - pkt = pkt.payload - - if not isinstance(pkt, IP) or not isinstance(pkt.payload, TCP): - raise TypeError("Not a TCP/IP packet") - - db = p0f_selectdb(pkt.payload.flags) - if osgenre: - pb = db.get_base() - if pb is None: - pb = [] - pb = [x for x in pb if x[6] == osgenre] - if osdetails: - pb = [x for x in pb if x[7] == osdetails] - elif signature: - pb = [signature] - else: - pb = p0f_getlocalsigs()[db] - if db == p0fr_kdb: - # 'K' quirk <=> RST+ACK - if pkt.payload.flags & 0x4 == 0x4: - pb = [x for x in pb if 'K' in x[5]] - else: - pb = [x for x in pb if 'K' not in x[5]] - if not pb: - raise Scapy_Exception("No match in the p0f database") - pers = pb[random.randint(0, len(pb) - 1)] - - # options (we start with options because of MSS) - # Take the options already set as "hints" to use in the new packet if we - # can. MSS, WScale and Timestamp can all be wildcarded in a signature, so - # we'll use the already-set values if they're valid integers. - orig_opts = dict(pkt.payload.options) - int_only = lambda val: val if isinstance(val, six.integer_types) else None - mss_hint = int_only(orig_opts.get('MSS')) - wscale_hint = int_only(orig_opts.get('WScale')) - ts_hint = [int_only(o) for o in orig_opts.get('Timestamp', (None, None))] - - options = [] - if pers[4] != '.': - for opt in pers[4].split(','): - if opt[0] == 'M': - # MSS might have a maximum size because of window size - # specification - if pers[0][0] == 'S': - maxmss = (2**16 - 1) // int(pers[0][1:]) - else: - maxmss = (2**16 - 1) - # disregard hint if out of range - if mss_hint and not 0 <= mss_hint <= maxmss: - mss_hint = None - # If we have to randomly pick up a value, we cannot use - # scapy RandXXX() functions, because the value has to be - # set in case we need it for the window size value. That's - # why we use random.randint() - if opt[1:] == '*': - if mss_hint is not None: - options.append(('MSS', mss_hint)) - else: - options.append(('MSS', random.randint(1, maxmss))) - elif opt[1] == '%': - coef = int(opt[2:]) - if mss_hint is not None and mss_hint % coef == 0: - options.append(('MSS', mss_hint)) - else: - options.append(( - 'MSS', coef * random.randint(1, maxmss // coef))) - else: - options.append(('MSS', int(opt[1:]))) - elif opt[0] == 'W': - if wscale_hint and not 0 <= wscale_hint < 2**8: - wscale_hint = None - if opt[1:] == '*': - if wscale_hint is not None: - options.append(('WScale', wscale_hint)) - else: - options.append(('WScale', RandByte())) - elif opt[1] == '%': - coef = int(opt[2:]) - if wscale_hint is not None and wscale_hint % coef == 0: - options.append(('WScale', wscale_hint)) - else: - options.append(( - 'WScale', coef * RandNum(min=1, max=(2**8 - 1) // coef))) # noqa: E501 - else: - options.append(('WScale', int(opt[1:]))) - elif opt == 'T0': - options.append(('Timestamp', (0, 0))) - elif opt == 'T': - # Determine first timestamp. - if uptime is not None: - ts_a = uptime - elif ts_hint[0] and 0 < ts_hint[0] < 2**32: - # Note: if first ts is 0, p0f registers it as "T0" not "T", - # hence we don't want to use the hint if it was 0. - ts_a = ts_hint[0] - else: - ts_a = random.randint(120, 100 * 60 * 60 * 24 * 365) - # Determine second timestamp. - if 'T' not in pers[5]: - ts_b = 0 - elif ts_hint[1] and 0 < ts_hint[1] < 2**32: - ts_b = ts_hint[1] - else: - # FIXME: RandInt() here does not work (bug (?) in - # TCPOptionsField.m2i often raises "OverflowError: - # long int too large to convert to int" in: - # oval = struct.pack(ofmt, *oval)" - # Actually, this is enough to often raise the error: - # struct.pack('I', RandInt()) - ts_b = random.randint(1, 2**32 - 1) - options.append(('Timestamp', (ts_a, ts_b))) - elif opt == 'S': - options.append(('SAckOK', '')) - elif opt == 'N': - options.append(('NOP', None)) - elif opt == 'E': - options.append(('EOL', None)) - elif opt[0] == '?': - if int(opt[1:]) in TCPOptions[0]: - optname = TCPOptions[0][int(opt[1:])][0] - optstruct = TCPOptions[0][int(opt[1:])][1] - options.append((optname, - struct.unpack(optstruct, - RandString(struct.calcsize(optstruct))._fix()))) # noqa: E501 - else: - options.append((int(opt[1:]), '')) - # FIXME: qqP not handled - else: - warning("unhandled TCP option " + opt) - pkt.payload.options = options - - # window size - if pers[0] == '*': - pkt.payload.window = RandShort() - elif pers[0].isdigit(): - pkt.payload.window = int(pers[0]) - elif pers[0][0] == '%': - coef = int(pers[0][1:]) - pkt.payload.window = coef * RandNum(min=1, max=(2**16 - 1) // coef) - elif pers[0][0] == 'T': - pkt.payload.window = mtu * int(pers[0][1:]) - elif pers[0][0] == 'S': - # needs MSS set - mss = [x for x in options if x[0] == 'MSS'] - if not mss: - raise Scapy_Exception("TCP window value requires MSS, and MSS option not set") # noqa: E501 - pkt.payload.window = mss[0][1] * int(pers[0][1:]) - else: - raise Scapy_Exception('Unhandled window size specification') - - # ttl - pkt.ttl = pers[1] - extrahops - # DF flag - pkt.flags |= (2 * pers[2]) - # FIXME: ss (packet size) not handled (how ? may be with D quirk - # if present) - # Quirks - if pers[5] != '.': - for qq in pers[5]: - # FIXME: not handled: P, I, X, ! - # T handled with the Timestamp option - if qq == 'Z': - pkt.id = 0 - elif qq == 'U': - pkt.payload.urgptr = RandShort() - elif qq == 'A': - pkt.payload.ack = RandInt() - elif qq == 'F': - if db == p0fo_kdb: - pkt.payload.flags |= 0x20 # U - else: - pkt.payload.flags |= random.choice([8, 32, 40]) # P/U/PU - elif qq == 'D' and db != p0fo_kdb: - pkt /= conf.raw_layer(load=RandString(random.randint(1, 10))) # XXX p0fo.fp # noqa: E501 - elif qq == 'Q': - pkt.payload.seq = pkt.payload.ack - # elif qq == '0': pkt.payload.seq = 0 - # if db == p0fr_kdb: - # '0' quirk is actually not only for p0fr.fp (see - # packet2p0f()) - if '0' in pers[5]: - pkt.payload.seq = 0 - elif pkt.payload.seq == 0: - pkt.payload.seq = RandInt() - - while pkt.underlayer: - pkt = pkt.underlayer - return pkt - - -def p0f_getlocalsigs(): - """This function returns a dictionary of signatures indexed by p0f -db (e.g., p0f_kdb, p0fa_kdb, ...) for the local TCP/IP stack. - -You need to have your firewall at least accepting the TCP packets -from/to a high port (30000 <= x <= 40000) on your loopback interface. - -Please note that the generated signatures come from the loopback -interface and may (are likely to) be different than those generated on -"normal" interfaces.""" - pid = os.fork() - port = random.randint(30000, 40000) - if pid > 0: - # parent: sniff - result = {} - - def addresult(res): - # TODO: wildcard window size in some cases? and maybe some - # other values? - if res[0] not in result: - result[res[0]] = [res[1]] - else: - if res[1] not in result[res[0]]: - result[res[0]].append(res[1]) - # XXX could we try with a "normal" interface using other hosts - iface = conf.route.route('127.0.0.1')[0] - # each packet is seen twice: S + RA, S + SA + A + FA + A - # XXX are the packets also seen twice on non Linux systems ? - count = 14 - pl = sniff(iface=iface, filter='tcp and port ' + str(port), count=count, timeout=3) # noqa: E501 - for pkt in pl: - for elt in packet2p0f(pkt): - addresult(elt) - os.waitpid(pid, 0) - elif pid < 0: - log_runtime.error("fork error") - else: - # child: send - # XXX erk - time.sleep(1) - s1 = socket.socket(socket.AF_INET, type=socket.SOCK_STREAM) - # S & RA - try: - s1.connect(('127.0.0.1', port)) - except socket.error: - pass - # S, SA, A, FA, A - s1.bind(('127.0.0.1', port)) - s1.connect(('127.0.0.1', port)) - # howto: get an RST w/o ACK packet - s1.close() - os._exit(0) - return result diff --git a/scripts/external_libs/scapy-2.4.3/scapy/modules/queso.py b/scripts/external_libs/scapy-2.4.3/scapy/modules/queso.py deleted file mode 100644 index fbc7d06b1d..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/modules/queso.py +++ /dev/null @@ -1,113 +0,0 @@ -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more informations -## Copyright (C) Philippe Biondi -## This program is published under a GPLv2 license - -""" -Clone of queso OS fingerprinting -""" - -from scapy.data import KnowledgeBase -from scapy.config import conf -from scapy.layers.inet import IP,TCP -#from - -conf.queso_base ="/etc/queso.conf" - - -################# -## Queso stuff ## -################# - - -def quesoTCPflags(flags): - if flags == "-": - return "-" - flv = "FSRPAUXY" - v = 0 - for i in flags: - v |= 2**flv.index(i) - return "%x" % v - -class QuesoKnowledgeBase(KnowledgeBase): - def lazy_init(self): - try: - f = open(self.filename) - except IOError: - return - self.base = {} - p = None - try: - for l in f: - l = l.strip() - if not l or l[0] == ';': - continue - if l[0] == '*': - if p is not None: - p[""] = name - name = l[1:].strip() - p = self.base - continue - if l[0] not in list("0123456"): - continue - res = l[2:].split() - res[-1] = quesoTCPflags(res[-1]) - res = " ".join(res) - if not res in p: - p[res] = {} - p = p[res] - if p is not None: - p[""] = name - except: - self.base = None - warning("Can't load queso base [%s]", self.filename) - f.close() - - -queso_kdb = QuesoKnowledgeBase(conf.queso_base) - - -def queso_sig(target, dport=80, timeout=3): - p = queso_kdb.get_base() - ret = [] - for flags in ["S", "SA", "F", "FA", "SF", "P", "SEC"]: - ans, unans = sr(IP(dst=target)/TCP(dport=dport,flags=flags,seq=RandInt()), - timeout=timeout, verbose=0) - if len(ans) == 0: - rs = "- - - -" - else: - s,r = ans[0] - rs = "%i" % (r.seq != 0) - if not r.ack: - r += " 0" - elif r.ack-s.seq > 666: - rs += " R" % 0 - else: - rs += " +%i" % (r.ack-s.seq) - rs += " %X" % r.window - rs += " %x" % r.payload.flags - ret.append(rs) - return ret - -def queso_search(sig): - p = queso_kdb.get_base() - sig.reverse() - ret = [] - try: - while sig: - s = sig.pop() - p = p[s] - if "" in p: - ret.append(p[""]) - except KeyError: - pass - return ret - - -@conf.commands.register -def queso(*args,**kargs): - """Queso OS fingerprinting -queso(target, dport=80, timeout=3)""" - return queso_search(queso_sig(*args, **kargs)) - - diff --git a/scripts/external_libs/scapy-2.4.3/scapy/modules/six.py b/scripts/external_libs/scapy-2.4.3/scapy/modules/six.py deleted file mode 100644 index bae38cde0e..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/modules/six.py +++ /dev/null @@ -1,891 +0,0 @@ -# Copyright (c) 2010-2017 Benjamin Peterson -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all # noqa: E501 -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -## This file is part of Scapy -## See http://www.secdev.org/projects/scapy for more information -## Copyright (C) Philippe Biondi -## This program is published under a GPLv2 license - -"""Utilities for writing code that runs on Python 2 and 3""" - -from __future__ import absolute_import - -import functools -import itertools -import operator -import sys -import types - -__author__ = "Benjamin Peterson " -__version__ = "1.10.0" - - -# Useful for very coarse version differentiation. -PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 -PY34 = sys.version_info[0:2] >= (3, 4) - -if PY3: - string_types = str, - integer_types = int, - class_types = type, - text_type = str - binary_type = bytes - - MAXSIZE = sys.maxsize -else: - string_types = basestring, - integer_types = (int, long) - class_types = (type, types.ClassType) - text_type = unicode - binary_type = str - - if sys.platform.startswith("java"): - # Jython always uses 32 bits. - MAXSIZE = int((1 << 31) - 1) - else: - # It's possible to have sizeof(long) != sizeof(Py_ssize_t). - class X(object): - - def __len__(self): - return 1 << 31 - try: - len(X()) - except OverflowError: - # 32-bit - MAXSIZE = int((1 << 31) - 1) - else: - # 64-bit - MAXSIZE = int((1 << 63) - 1) - del X - - -def _add_doc(func, doc): - """Add documentation to a function.""" - func.__doc__ = doc - - -def _import_module(name): - """Import module, returning the module after the last dot.""" - __import__(name) - return sys.modules[name] - - -class _LazyDescr(object): - - def __init__(self, name): - self.name = name - - def __get__(self, obj, tp): - result = self._resolve() - setattr(obj, self.name, result) # Invokes __set__. - try: - # This is a bit ugly, but it avoids running this again by - # removing this descriptor. - delattr(obj.__class__, self.name) - except AttributeError: - pass - return result - - -class MovedModule(_LazyDescr): - - def __init__(self, name, old, new=None): - super(MovedModule, self).__init__(name) - if PY3: - if new is None: - new = name - self.mod = new - else: - self.mod = old - - def _resolve(self): - return _import_module(self.mod) - - def __getattr__(self, attr): - _module = self._resolve() - value = getattr(_module, attr) - setattr(self, attr, value) - return value - - -class _LazyModule(types.ModuleType): - - def __init__(self, name): - super(_LazyModule, self).__init__(name) - self.__doc__ = self.__class__.__doc__ - - def __dir__(self): - attrs = ["__doc__", "__name__"] - attrs += [attr.name for attr in self._moved_attributes] - return attrs - - # Subclasses should override this - _moved_attributes = [] - - -class MovedAttribute(_LazyDescr): - - def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): - super(MovedAttribute, self).__init__(name) - if PY3: - if new_mod is None: - new_mod = name - self.mod = new_mod - if new_attr is None: - if old_attr is None: - new_attr = name - else: - new_attr = old_attr - self.attr = new_attr - else: - self.mod = old_mod - if old_attr is None: - old_attr = name - self.attr = old_attr - - def _resolve(self): - module = _import_module(self.mod) - return getattr(module, self.attr) - - -class _SixMetaPathImporter(object): - - """ - A meta path importer to import scapy.modules.six.moves and its submodules. - - This class implements a PEP302 finder and loader. It should be compatible - with Python 2.5 and all existing versions of Python3 - """ - - def __init__(self, six_module_name): - self.name = six_module_name - self.known_modules = {} - - def _add_module(self, mod, *fullnames): - for fullname in fullnames: - self.known_modules[self.name + "." + fullname] = mod - - def _get_module(self, fullname): - return self.known_modules[self.name + "." + fullname] - - def find_module(self, fullname, path=None): - if fullname in self.known_modules: - return self - return None - - def __get_module(self, fullname): - try: - return self.known_modules[fullname] - except KeyError: - raise ImportError("This loader does not know module " + fullname) - - def load_module(self, fullname): - try: - # in case of a reload - return sys.modules[fullname] - except KeyError: - pass - mod = self.__get_module(fullname) - if isinstance(mod, MovedModule): - mod = mod._resolve() - else: - mod.__loader__ = self - sys.modules[fullname] = mod - return mod - - def is_package(self, fullname): - """ - Return true, if the named module is a package. - - We need this method to get correct spec objects with - Python 3.4 (see PEP451) - """ - return hasattr(self.__get_module(fullname), "__path__") - - def get_code(self, fullname): - """Return None - - Required, if is_package is implemented""" - self.__get_module(fullname) # eventually raises ImportError - return None - get_source = get_code # same as get_code - -_importer = _SixMetaPathImporter(__name__) - - -class _MovedItems(_LazyModule): - - """Lazy loading of moved objects""" - __path__ = [] # mark as package - - -_moved_attributes = [ - MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), - MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), - MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), # noqa: E501 - MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), - MovedAttribute("intern", "__builtin__", "sys"), - MovedAttribute("map", "itertools", "builtins", "imap", "map"), - MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), - MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), - MovedAttribute("getstatusoutput", "commands", "subprocess"), - MovedAttribute("getoutput", "commands", "subprocess"), - MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), # noqa: E501 - MovedAttribute("reduce", "__builtin__", "functools"), - MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), - MovedAttribute("StringIO", "StringIO", "io"), - MovedAttribute("UserDict", "UserDict", "collections"), - MovedAttribute("UserList", "UserList", "collections"), - MovedAttribute("UserString", "UserString", "collections"), - MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), - MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), # noqa: E501 - MovedModule("builtins", "__builtin__"), - MovedModule("configparser", "ConfigParser"), - MovedModule("copyreg", "copy_reg"), - MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), - MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), - MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), - MovedModule("http_cookies", "Cookie", "http.cookies"), - MovedModule("html_entities", "htmlentitydefs", "html.entities"), - MovedModule("html_parser", "HTMLParser", "html.parser"), - MovedModule("http_client", "httplib", "http.client"), - MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), - MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"), - MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), # noqa: E501 - MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), # noqa: E501 - MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), - MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), - MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), - MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), - MovedModule("cPickle", "cPickle", "pickle"), - MovedModule("queue", "Queue"), - MovedModule("reprlib", "repr"), - MovedModule("socketserver", "SocketServer"), - MovedModule("_thread", "thread", "_thread"), - MovedModule("tkinter", "Tkinter"), - MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), - MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), - MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), # noqa: E501 - MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), # noqa: E501 - MovedModule("tkinter_tix", "Tix", "tkinter.tix"), - MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), - MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), - MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), - MovedModule("tkinter_colorchooser", "tkColorChooser", - "tkinter.colorchooser"), - MovedModule("tkinter_commondialog", "tkCommonDialog", - "tkinter.commondialog"), - MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), - MovedModule("tkinter_font", "tkFont", "tkinter.font"), - MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), - MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", - "tkinter.simpledialog"), - MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), # noqa: E501 - MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), # noqa: E501 - MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), # noqa: E501 - MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), - MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), - MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), -] -# Add windows specific modules. -if sys.platform == "win32": - _moved_attributes += [ - MovedModule("winreg", "_winreg"), - ] - -for attr in _moved_attributes: - setattr(_MovedItems, attr.name, attr) - if isinstance(attr, MovedModule): - _importer._add_module(attr, "moves." + attr.name) -del attr - -_MovedItems._moved_attributes = _moved_attributes - -moves = _MovedItems(__name__ + ".moves") -_importer._add_module(moves, "moves") - - -class Module_six_moves_urllib_parse(_LazyModule): - - """Lazy loading of moved objects in scapy.modules.six.urllib_parse""" - - -_urllib_parse_moved_attributes = [ - MovedAttribute("ParseResult", "urlparse", "urllib.parse"), - MovedAttribute("SplitResult", "urlparse", "urllib.parse"), - MovedAttribute("parse_qs", "urlparse", "urllib.parse"), - MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), - MovedAttribute("urldefrag", "urlparse", "urllib.parse"), - MovedAttribute("urljoin", "urlparse", "urllib.parse"), - MovedAttribute("urlparse", "urlparse", "urllib.parse"), - MovedAttribute("urlsplit", "urlparse", "urllib.parse"), - MovedAttribute("urlunparse", "urlparse", "urllib.parse"), - MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), - MovedAttribute("quote", "urllib", "urllib.parse"), - MovedAttribute("quote_plus", "urllib", "urllib.parse"), - MovedAttribute("unquote", "urllib", "urllib.parse"), - MovedAttribute("unquote_plus", "urllib", "urllib.parse"), - MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"), # noqa: E501 - MovedAttribute("urlencode", "urllib", "urllib.parse"), - MovedAttribute("splitquery", "urllib", "urllib.parse"), - MovedAttribute("splittag", "urllib", "urllib.parse"), - MovedAttribute("splituser", "urllib", "urllib.parse"), - MovedAttribute("splitvalue", "urllib", "urllib.parse"), - MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), - MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), - MovedAttribute("uses_params", "urlparse", "urllib.parse"), - MovedAttribute("uses_query", "urlparse", "urllib.parse"), - MovedAttribute("uses_relative", "urlparse", "urllib.parse"), -] -for attr in _urllib_parse_moved_attributes: - setattr(Module_six_moves_urllib_parse, attr.name, attr) -del attr - -Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes # noqa: E501 - -_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), # noqa: E501 - "moves.urllib_parse", "moves.urllib.parse") - - -class Module_six_moves_urllib_error(_LazyModule): - - """Lazy loading of moved objects in scapy.modules.six.urllib_error""" - - -_urllib_error_moved_attributes = [ - MovedAttribute("URLError", "urllib2", "urllib.error"), - MovedAttribute("HTTPError", "urllib2", "urllib.error"), - MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), -] -for attr in _urllib_error_moved_attributes: - setattr(Module_six_moves_urllib_error, attr.name, attr) -del attr - -Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes # noqa: E501 - -_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), # noqa: E501 - "moves.urllib_error", "moves.urllib.error") - - -class Module_six_moves_urllib_request(_LazyModule): - - """Lazy loading of moved objects in scapy.modules.six.urllib_request""" - - -_urllib_request_moved_attributes = [ - MovedAttribute("urlopen", "urllib2", "urllib.request"), - MovedAttribute("install_opener", "urllib2", "urllib.request"), - MovedAttribute("build_opener", "urllib2", "urllib.request"), - MovedAttribute("pathname2url", "urllib", "urllib.request"), - MovedAttribute("url2pathname", "urllib", "urllib.request"), - MovedAttribute("getproxies", "urllib", "urllib.request"), - MovedAttribute("Request", "urllib2", "urllib.request"), - MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), - MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), - MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), - MovedAttribute("BaseHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), # noqa: E501 - MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), - MovedAttribute("FileHandler", "urllib2", "urllib.request"), - MovedAttribute("FTPHandler", "urllib2", "urllib.request"), - MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), - MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), - MovedAttribute("urlretrieve", "urllib", "urllib.request"), - MovedAttribute("urlcleanup", "urllib", "urllib.request"), - MovedAttribute("URLopener", "urllib", "urllib.request"), - MovedAttribute("FancyURLopener", "urllib", "urllib.request"), - MovedAttribute("proxy_bypass", "urllib", "urllib.request"), -] -for attr in _urllib_request_moved_attributes: - setattr(Module_six_moves_urllib_request, attr.name, attr) -del attr - -Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes # noqa: E501 - -_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), # noqa: E501 - "moves.urllib_request", "moves.urllib.request") - - -class Module_six_moves_urllib_response(_LazyModule): - - """Lazy loading of moved objects in scapy.modules.six.urllib_response""" - - -_urllib_response_moved_attributes = [ - MovedAttribute("addbase", "urllib", "urllib.response"), - MovedAttribute("addclosehook", "urllib", "urllib.response"), - MovedAttribute("addinfo", "urllib", "urllib.response"), - MovedAttribute("addinfourl", "urllib", "urllib.response"), -] -for attr in _urllib_response_moved_attributes: - setattr(Module_six_moves_urllib_response, attr.name, attr) -del attr - -Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes # noqa: E501 - -_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), # noqa: E501 - "moves.urllib_response", "moves.urllib.response") - - -class Module_six_moves_urllib_robotparser(_LazyModule): - - """Lazy loading of moved objects in scapy.modules.six.urllib_robotparser""" - - -_urllib_robotparser_moved_attributes = [ - MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), -] -for attr in _urllib_robotparser_moved_attributes: - setattr(Module_six_moves_urllib_robotparser, attr.name, attr) -del attr - -Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes # noqa: E501 - -_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), # noqa: E501 - "moves.urllib_robotparser", "moves.urllib.robotparser") - - -class Module_six_moves_urllib(types.ModuleType): - - """Create a scapy.modules.six.urllib namespace that resembles the Python 3 namespace""" # noqa: E501 - __path__ = [] # mark as package - parse = _importer._get_module("moves.urllib_parse") - error = _importer._get_module("moves.urllib_error") - request = _importer._get_module("moves.urllib_request") - response = _importer._get_module("moves.urllib_response") - robotparser = _importer._get_module("moves.urllib_robotparser") - - def __dir__(self): - return ['parse', 'error', 'request', 'response', 'robotparser'] - -_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), - "moves.urllib") - - -def add_move(move): - """Add an item to scapy.modules.six.""" - setattr(_MovedItems, move.name, move) - - -def remove_move(name): - """Remove item from scapy.modules.six.""" - try: - delattr(_MovedItems, name) - except AttributeError: - try: - del moves.__dict__[name] - except KeyError: - raise AttributeError("no such move, %r" % (name,)) - - -if PY3: - _meth_func = "__func__" - _meth_self = "__self__" - - _func_closure = "__closure__" - _func_code = "__code__" - _func_defaults = "__defaults__" - _func_globals = "__globals__" -else: - _meth_func = "im_func" - _meth_self = "im_self" - - _func_closure = "func_closure" - _func_code = "func_code" - _func_defaults = "func_defaults" - _func_globals = "func_globals" - - -try: - advance_iterator = next -except NameError: - def advance_iterator(it): - return it.next() -next = advance_iterator - - -try: - callable = callable -except NameError: - def callable(obj): - return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) - - -if PY3: - def get_unbound_function(unbound): - return unbound - - create_bound_method = types.MethodType - - def create_unbound_method(func, cls): - return func - - Iterator = object -else: - def get_unbound_function(unbound): - return unbound.im_func - - def create_bound_method(func, obj): - return types.MethodType(func, obj, obj.__class__) - - def create_unbound_method(func, cls): - return types.MethodType(func, None, cls) - - class Iterator(object): - - def next(self): - return type(self).__next__(self) - - callable = callable -_add_doc(get_unbound_function, - """Get the function out of a possibly unbound function""") - - -get_method_function = operator.attrgetter(_meth_func) -get_method_self = operator.attrgetter(_meth_self) -get_function_closure = operator.attrgetter(_func_closure) -get_function_code = operator.attrgetter(_func_code) -get_function_defaults = operator.attrgetter(_func_defaults) -get_function_globals = operator.attrgetter(_func_globals) - - -if PY3: - def iterkeys(d, **kw): - return iter(d.keys(**kw)) - - def itervalues(d, **kw): - return iter(d.values(**kw)) - - def iteritems(d, **kw): - return iter(d.items(**kw)) - - def iterlists(d, **kw): - return iter(d.lists(**kw)) - - viewkeys = operator.methodcaller("keys") - - viewvalues = operator.methodcaller("values") - - viewitems = operator.methodcaller("items") -else: - def iterkeys(d, **kw): - return d.iterkeys(**kw) - - def itervalues(d, **kw): - return d.itervalues(**kw) - - def iteritems(d, **kw): - return d.iteritems(**kw) - - def iterlists(d, **kw): - return d.iterlists(**kw) - - viewkeys = operator.methodcaller("viewkeys") - - viewvalues = operator.methodcaller("viewvalues") - - viewitems = operator.methodcaller("viewitems") - -_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") -_add_doc(itervalues, "Return an iterator over the values of a dictionary.") -_add_doc(iteritems, - "Return an iterator over the (key, value) pairs of a dictionary.") -_add_doc(iterlists, - "Return an iterator over the (key, [values]) pairs of a dictionary.") - - -if PY3: - def b(s): - return s.encode("latin-1") - - def u(s): - return s - unichr = chr - import struct - int2byte = struct.Struct(">B").pack - del struct - byte2int = operator.itemgetter(0) - indexbytes = operator.getitem - iterbytes = iter - import io - StringIO = io.StringIO - BytesIO = io.BytesIO - _assertCountEqual = "assertCountEqual" - if sys.version_info[1] <= 1: - _assertRaisesRegex = "assertRaisesRegexp" - _assertRegex = "assertRegexpMatches" - else: - _assertRaisesRegex = "assertRaisesRegex" - _assertRegex = "assertRegex" -else: - def b(s): - return s - # Workaround for standalone backslash - - def u(s): - return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") - unichr = unichr - int2byte = chr - - def byte2int(bs): - return ord(bs[0]) - - def indexbytes(buf, i): - return ord(buf[i]) - iterbytes = functools.partial(itertools.imap, ord) - import StringIO - StringIO = BytesIO = StringIO.StringIO - _assertCountEqual = "assertItemsEqual" - _assertRaisesRegex = "assertRaisesRegexp" - _assertRegex = "assertRegexpMatches" -_add_doc(b, """Byte literal""") -_add_doc(u, """Text literal""") - - -def assertCountEqual(self, *args, **kwargs): - return getattr(self, _assertCountEqual)(*args, **kwargs) - - -def assertRaisesRegex(self, *args, **kwargs): - return getattr(self, _assertRaisesRegex)(*args, **kwargs) - - -def assertRegex(self, *args, **kwargs): - return getattr(self, _assertRegex)(*args, **kwargs) - - -if PY3: - exec_ = getattr(moves.builtins, "exec") - - def reraise(tp, value, tb=None): - try: - if value is None: - value = tp() - if value.__traceback__ is not tb: - raise value.with_traceback(tb) - raise value - finally: - value = None - tb = None - -else: - def exec_(_code_, _globs_=None, _locs_=None): - """Execute code in a namespace.""" - if _globs_ is None: - frame = sys._getframe(1) - _globs_ = frame.f_globals - if _locs_ is None: - _locs_ = frame.f_locals - del frame - elif _locs_ is None: - _locs_ = _globs_ - exec("""exec _code_ in _globs_, _locs_""") - - exec_("""def reraise(tp, value, tb=None): - try: - raise tp, value, tb - finally: - tb = None -""") - - -if sys.version_info[:2] == (3, 2): - exec_("""def raise_from(value, from_value): - try: - if from_value is None: - raise value - raise value from from_value - finally: - value = None -""") -elif sys.version_info[:2] > (3, 2): - exec_("""def raise_from(value, from_value): - try: - raise value from from_value - finally: - value = None -""") -else: - def raise_from(value, from_value): - raise value - - -print_ = getattr(moves.builtins, "print", None) -if print_ is None: - def print_(*args, **kwargs): - """The new-style print function for Python 2.4 and 2.5.""" - fp = kwargs.pop("file", sys.stdout) - if fp is None: - return - - def write(data): - if not isinstance(data, basestring): - data = str(data) - # If the file has an encoding, encode unicode with it. - if (isinstance(fp, file) and - isinstance(data, unicode) and - fp.encoding is not None): - errors = getattr(fp, "errors", None) - if errors is None: - errors = "strict" - data = data.encode(fp.encoding, errors) - fp.write(data) - want_unicode = False - sep = kwargs.pop("sep", None) - if sep is not None: - if isinstance(sep, unicode): - want_unicode = True - elif not isinstance(sep, str): - raise TypeError("sep must be None or a string") - end = kwargs.pop("end", None) - if end is not None: - if isinstance(end, unicode): - want_unicode = True - elif not isinstance(end, str): - raise TypeError("end must be None or a string") - if kwargs: - raise TypeError("invalid keyword arguments to print()") - if not want_unicode: - for arg in args: - if isinstance(arg, unicode): - want_unicode = True - break - if want_unicode: - newline = unicode("\n") - space = unicode(" ") - else: - newline = "\n" - space = " " - if sep is None: - sep = space - if end is None: - end = newline - for i, arg in enumerate(args): - if i: - write(sep) - write(arg) - write(end) -if sys.version_info[:2] < (3, 3): - _print = print_ - - def print_(*args, **kwargs): - fp = kwargs.get("file", sys.stdout) - flush = kwargs.pop("flush", False) - _print(*args, **kwargs) - if flush and fp is not None: - fp.flush() - -_add_doc(reraise, """Reraise an exception.""") - -if sys.version_info[0:2] < (3, 4): - def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, - updated=functools.WRAPPER_UPDATES): - def wrapper(f): - f = functools.wraps(wrapped, assigned, updated)(f) - f.__wrapped__ = wrapped - return f - return wrapper -else: - wraps = functools.wraps - - -def with_metaclass(meta, *bases): - """Create a base class with a metaclass.""" - # This requires a bit of explanation: the basic idea is to make a dummy - # metaclass for one level of class instantiation that replaces itself with - # the actual metaclass. - class metaclass(meta): - - def __new__(cls, name, this_bases, d): - return meta(name, bases, d) - return type.__new__(metaclass, 'temporary_class', (), {}) - - -def add_metaclass(metaclass): - """Class decorator for creating a class with a metaclass.""" - def wrapper(cls): - orig_vars = cls.__dict__.copy() - slots = orig_vars.get('__slots__') - if slots is not None: - if isinstance(slots, str): - slots = [slots] - for slots_var in slots: - orig_vars.pop(slots_var) - orig_vars.pop('__dict__', None) - orig_vars.pop('__weakref__', None) - return metaclass(cls.__name__, cls.__bases__, orig_vars) - return wrapper - - -def python_2_unicode_compatible(klass): - """ - A decorator that defines __unicode__ and __str__ methods under Python 2. - Under Python 3 it does nothing. - - To support Python 2 and 3 with a single code base, define a __str__ method - returning text and apply this decorator to the class. - """ - if PY2: - if '__str__' not in klass.__dict__: - raise ValueError("@python_2_unicode_compatible cannot be applied " - "to %s because it doesn't define __str__()." % - klass.__name__) - klass.__unicode__ = klass.__str__ - klass.__str__ = lambda self: self.__unicode__().encode('utf-8') - return klass - - -# Complete the moves implementation. -# This code is at the end of this module to speed up module loading. -# Turn this module into a package. -__path__ = [] # required for PEP 302 and PEP 451 -__package__ = __name__ # see PEP 366 @ReservedAssignment -if globals().get("__spec__") is not None: - __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable -# Remove other six meta path importers, since they cause problems. This can -# happen if six is removed from sys.modules and then reloaded. (Setuptools does -# this for some reason.) -if sys.meta_path: - for i, importer in enumerate(sys.meta_path): - # Here's some real nastiness: Another "instance" of the six module might # noqa: E501 - # be floating around. Therefore, we can't use isinstance() to check for - # the six meta path importer, since the other six instance will have - # inserted an importer with different class. - if (type(importer).__name__ == "_SixMetaPathImporter" and - importer.name == __name__): - del sys.meta_path[i] - break - del i, importer -# Finally, add the importer to the meta path import hook. -sys.meta_path.append(_importer) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/modules/voip.py b/scripts/external_libs/scapy-2.4.3/scapy/modules/voip.py deleted file mode 100644 index 420ed641b8..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/modules/voip.py +++ /dev/null @@ -1,176 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -VoIP (Voice over IP) related functions -""" - -from __future__ import absolute_import -import subprocess -################### -# Listen VoIP # -################### - -from scapy.sendrecv import sniff -from scapy.layers.inet import IP, UDP -from scapy.layers.rtp import RTP -from scapy.consts import WINDOWS -from scapy.config import conf -from scapy.modules.six.moves import range - - -sox_base = (["sox", "-t", ".ul"], ["-", "-t", "ossdsp", "/dev/dsp"]) - -if WINDOWS: - if conf.prog.sox is None: - raise OSError("Sox must be installed to play VoIP packets") - sox_base = ([conf.prog.sox, "-t", ".ul"], ["-", "-t", "waveaudio"]) - - -def _merge_sound_bytes(x, y, sample_size=2): - # TODO: find a better way to merge sound bytes - # This will only add them one next to each other: - # \xff + \xff ==> \xff\xff - m = "" - ss = sample_size - min_ = 0 - if len(x) >= len(y): - min_ = y - elif len(x) < len(y): - min_ = x - r_ = len(min_) - for i in range(r_ / ss): - m += x[ss * i:ss * (i + 1)] + y[ss * i:ss * (i + 1)] - return x[r_:], y[r_:], m - - -def voip_play(s1, lst=None, **kargs): - """Play VoIP packets with RAW data that - are either sniffed either from an IP, or - specified as a list. - - It will play only the incoming packets ! - - :param s1: The IP of the src of all VoIP packets. - :param lst: (optional) A list of packets to load - :type s1: string - :type lst: list - - :Example: - - >>> voip_play("64.2.142.189") - while calling '411@ideasip.com' - - >>> voip_play("64.2.142.189", lst) - with list a list of packets with VoIP data - in their RAW layer - - .. seealso:: voip_play2 - to play both the outcoming and incoming packets - at the same time. - - .. seealso:: voip_play3 - to read RTP VoIP packets - """ - - proc = subprocess.Popen(sox_base[0] + sox_base[1], stdin=subprocess.PIPE, - stdout=subprocess.PIPE) - dsp, rd = proc.stdin, proc.stdout - - def play(pkt): - if not pkt: - return - if not pkt.haslayer(UDP) or not pkt.haslayer(IP): - return - ip = pkt.getlayer(IP) - if s1 == ip.src: - dsp.write(pkt.getlayer(conf.raw_layer).load[12:]) - try: - if lst is None: - sniff(store=0, prn=play, **kargs) - else: - for p in lst: - play(p) - finally: - dsp.close() - rd.close() - - -def voip_play1(s1, lst=None, **kargs): - """Same than voip_play, backward compatibility - """ - return voip_play(s1, lst, **kargs) - - -def voip_play2(s1, **kargs): - """ - Same than voip_play, but will play - both incoming and outcoming packets. - The sound will surely suffer distortion. - - Only supports sniffing. - - .. seealso:: voip_play - to play only incoming packets. - """ - proc = subprocess.Popen(sox_base[0] + ["-c", "2"] + sox_base[1], - stdin=subprocess.PIPE, stdout=subprocess.PIPE) - dsp, rd = proc.stdin, proc.stdout - global x1, x2 - x1 = "" - x2 = "" - - def play(pkt): - global x1, x2 - if not pkt: - return - if not pkt.haslayer(UDP) or not pkt.haslayer(IP): - return - ip = pkt.getlayer(IP) - if s1 in [ip.src, ip.dst]: - if ip.dst == s1: - x1 += pkt.getlayer(conf.raw_layer).load[12:] - else: - x2 += pkt.getlayer(conf.raw_layer).load[12:] - x1, x2, r = _merge_sound_bytes(x1, x2) - dsp.write(r) - - try: - sniff(store=0, prn=play, **kargs) - finally: - try: - dsp.close() - rd.close() - except Exception: - pass - - -def voip_play3(lst=None, **kargs): - """Same than voip_play, but made to - read and play VoIP RTP packets, without - checking IP. - - .. seealso:: voip_play - for basic VoIP packets - """ - proc = subprocess.Popen(sox_base[0] + sox_base[1], stdin=subprocess.PIPE, - stdout=subprocess.PIPE) - dsp, rd = proc.stdin, proc.stdout - - def play(pkt, dsp=dsp): - if pkt and pkt.haslayer(UDP) and pkt.haslayer(RTP): - dsp.write(pkt.getlayer(RTP).load) - try: - if lst is None: - sniff(store=0, prn=play, **kargs) - else: - for p in lst: - play(p) - finally: - try: - dsp.close() - rd.close() - except Exception: - pass diff --git a/scripts/external_libs/scapy-2.4.3/scapy/modules/winpcapy.py b/scripts/external_libs/scapy-2.4.3/scapy/modules/winpcapy.py deleted file mode 100644 index 4a3513e2ac..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/modules/winpcapy.py +++ /dev/null @@ -1,789 +0,0 @@ -# Original license -#------------------------------------------------------------------------------- # noqa: E501 -# Name: winpcapy.py -# -# Author: Massimo Ciani -# -# Created: 01/09/2009 -# Copyright: (c) Massimo Ciani 2009 -# -#------------------------------------------------------------------------------- # noqa: E501 -# Modified for scapy's usage - Mainly to support Npcap/Monitor mode - -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# This program is published under a GPLv2 license - -from ctypes import * -from ctypes.util import find_library -import sys, os -from scapy.consts import WINDOWS - -HAVE_REMOTE = False - -if WINDOWS: - # Try to load Npcap, or Winpcap - HAVE_REMOTE=True - SOCKET = c_uint - npcap_folder = os.environ["WINDIR"] + "\\System32\\Npcap" - if os.path.exists(npcap_folder): - # Try to load npcap - os.environ['PATH'] = npcap_folder + ";" + os.environ['PATH'] - # Set DLL directory priority - windll.kernel32.SetDllDirectoryW(npcap_folder) - # Packet.dll is unused, but needs to overwrite the winpcap one if it exists # noqa: E501 - cdll.LoadLibrary(npcap_folder + "\\Packet.dll") - _lib = cdll.LoadLibrary(npcap_folder + "\\wpcap.dll") - else: - _lib=CDLL("wpcap.dll") - del npcap_folder -else: - # Try to load libpcap - SOCKET = c_int - _lib_name = find_library("pcap") - if not _lib_name: - raise OSError("Cannot fine libpcap.so library") - _lib=CDLL(_lib_name) - - -## -## misc -## -u_short = c_ushort -bpf_int32 = c_int -u_int = c_int -bpf_u_int32 = u_int -pcap = c_void_p -pcap_dumper = c_void_p -u_char = c_ubyte -FILE = c_void_p -STRING = c_char_p - -class bpf_insn(Structure): - _fields_=[("code",c_ushort), - ("jt",c_ubyte), - ("jf",c_ubyte), - ("k",bpf_u_int32)] - -class bpf_program(Structure): - pass -bpf_program._fields_ = [('bf_len', u_int), - ('bf_insns', POINTER(bpf_insn))] - -class bpf_version(Structure): - _fields_=[("bv_major",c_ushort), - ("bv_minor",c_ushort)] - - -class timeval(Structure): - pass -timeval._fields_ = [('tv_sec', c_long), - ('tv_usec', c_long)] - -## sockaddr is used by pcap_addr. -## For example if sa_family==socket.AF_INET then we need cast -## with sockaddr_in -if WINDOWS: - class sockaddr(Structure): - _fields_ = [("sa_family", c_ushort), - ("sa_data", c_ubyte * 14)] - - class sockaddr_in(Structure): - _fields_ = [("sin_family", c_ushort), - ("sin_port", c_uint16), - ("sin_addr", 4 * c_ubyte)] - - class sockaddr_in6(Structure): - _fields_ = [("sin6_family", c_ushort), - ("sin6_port", c_uint16), - ("sin6_flowinfo", c_uint32), - ("sin6_addr", 16 * c_ubyte), - ("sin6_scope", c_uint32)] -else: - class sockaddr(Structure): - _fields_ = [("sa_len", c_ubyte), - ("sa_family",c_ubyte), - ("sa_data",c_ubyte * 14)] - - class sockaddr_in(Structure): - _fields_ = [("sin_len", c_ubyte), - ("sin_family", c_ubyte), - ("sin_port", c_uint16), - ("sin_addr", 4 * c_ubyte), - ("sin_zero", 8 * c_char)] - - class sockaddr_in6(Structure): - _fields_ = [("sin6_len", c_ubyte), - ("sin6_family", c_ubyte), - ("sin6_port", c_uint16), - ("sin6_flowinfo", c_uint32), - ("sin6_addr", 16 * c_ubyte), - ("sin6_scope", c_uint32)] - - class sockaddr_dl(Structure): - _fields_ = [("sdl_len", c_ubyte), - ("sdl_family", c_ubyte), - ("sdl_index", c_ushort), - ("sdl_type", c_ubyte), - ("sdl_nlen", c_ubyte), - ("sdl_alen", c_ubyte), - ("sdl_slen", c_ubyte), - ("sdl_data", 46 * c_ubyte)] -## -## END misc -## - -## -## Data Structures -## - -## struct pcap_file_header -## Header of a libpcap dump file. -class pcap_file_header(Structure): - _fields_ = [('magic', bpf_u_int32), - ('version_major', u_short), - ('version_minor', u_short), - ('thiszone', bpf_int32), - ('sigfigs', bpf_u_int32), - ('snaplen', bpf_u_int32), - ('linktype', bpf_u_int32)] - -## struct pcap_pkthdr -## Header of a packet in the dump file. -class pcap_pkthdr(Structure): - _fields_ = [('ts', timeval), - ('caplen', bpf_u_int32), - ('len', bpf_u_int32)] - -## struct pcap_stat -## Structure that keeps statistical values on an interface. -class pcap_stat(Structure): - pass -### _fields_ list in Structure is final. -### We need a temp list -_tmpList = [("ps_recv", c_uint), ("ps_drop", c_uint), ("ps_ifdrop", c_uint)] -if HAVE_REMOTE: - _tmpList.append(("ps_capt",c_uint)) - _tmpList.append(("ps_sent",c_uint)) - _tmpList.append(("ps_netdrop",c_uint)) -pcap_stat._fields_=_tmpList - -## struct pcap_addr -## Representation of an interface address, used by pcap_findalldevs(). -class pcap_addr(Structure): - pass -pcap_addr._fields_ = [('next', POINTER(pcap_addr)), - ('addr', POINTER(sockaddr)), - ('netmask', POINTER(sockaddr)), - ('broadaddr', POINTER(sockaddr)), - ('dstaddr', POINTER(sockaddr))] - -## struct pcap_if -## Item in a list of interfaces, used by pcap_findalldevs(). -class pcap_if(Structure): - pass -pcap_if._fields_ = [('next', POINTER(pcap_if)), - ('name', STRING), - ('description', STRING), - ('addresses', POINTER(pcap_addr)), - ('flags', bpf_u_int32)] - -## -## END Data Structures -## - -## -## Defines -## - -##define PCAP_VERSION_MAJOR 2 -# Major libpcap dump file version. -PCAP_VERSION_MAJOR = 2 -##define PCAP_VERSION_MINOR 4 -# Minor libpcap dump file version. -PCAP_VERSION_MINOR = 4 -##define PCAP_ERRBUF_SIZE 256 -# Size to use when allocating the buffer that contains the libpcap errors. -PCAP_ERRBUF_SIZE = 256 -##define PCAP_IF_LOOPBACK 0x00000001 -# interface is loopback -PCAP_IF_LOOPBACK = 1 -##define MODE_CAPT 0 -# Capture mode, to be used when calling pcap_setmode(). -MODE_CAPT = 0 -##define MODE_STAT 1 -# Statistical mode, to be used when calling pcap_setmode(). -MODE_STAT = 1 - -## -## END Defines -## - -## -## Typedefs -## - -#typedef int bpf_int32 (already defined) -# 32-bit integer -#typedef u_int bpf_u_int32 (already defined) -# 32-bit unsigned integer -#typedef struct pcap pcap_t -# Descriptor of an open capture instance. This structure is opaque to the user, that handles its content through the functions provided by wpcap.dll. # noqa: E501 -pcap_t = pcap -#typedef struct pcap_dumper pcap_dumper_t -# libpcap savefile descriptor. -pcap_dumper_t = pcap_dumper -#typedef struct pcap_if pcap_if_t -# Item in a list of interfaces, see pcap_if. -pcap_if_t = pcap_if -#typedef struct pcap_addr pcap_addr_t -# Representation of an interface address, see pcap_addr. -pcap_addr_t = pcap_addr - -## -## END Typedefs -## - - - - - -# values for enumeration 'pcap_direction_t' -#pcap_direction_t = c_int # enum - -## -## Unix-compatible Functions -## These functions are part of the libpcap library, and therefore work both on Windows and on Linux. # noqa: E501 -## - -#typedef void(* pcap_handler )(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) # noqa: E501 -# Prototype of the callback function that receives the packets. -## This one is defined from programmer -pcap_handler=CFUNCTYPE(None,POINTER(c_ubyte),POINTER(pcap_pkthdr),POINTER(c_ubyte)) # noqa: E501 - -#pcap_t * pcap_open_live (const char *device, int snaplen, int promisc, int to_ms, char *ebuf) # noqa: E501 -# Open a live capture from the network. -pcap_open_live = _lib.pcap_open_live -pcap_open_live.restype = POINTER(pcap_t) -pcap_open_live.argtypes = [STRING, c_int, c_int, c_int, STRING] - -#pcap_t * pcap_open_dead (int linktype, int snaplen) -# Create a pcap_t structure without starting a capture. -pcap_open_dead = _lib.pcap_open_dead -pcap_open_dead.restype = POINTER(pcap_t) -pcap_open_dead.argtypes = [c_int, c_int] - -#pcap_t * pcap_open_offline (const char *fname, char *errbuf) -# Open a savefile in the tcpdump/libpcap format to read packets. -pcap_open_offline = _lib.pcap_open_offline -pcap_open_offline.restype = POINTER(pcap_t) -pcap_open_offline.argtypes = [STRING, STRING] - -try: # NPCAP ONLY function - #int pcap_set_rfmon (pcap_t *p) - # sets whether monitor mode should be set on a capture handle when the handle is activated. # noqa: E501 - pcap_set_rfmon = _lib.pcap_set_rfmon - pcap_set_rfmon.restype = c_int - pcap_set_rfmon.argtypes = [POINTER(pcap_t), c_int] - - #int pcap_create (pcap_t *p) - # create a packet capture handle to look at packets on the network. - pcap_create = _lib.pcap_create - pcap_create.restype = POINTER(pcap_t) - pcap_create.argtypes = [STRING, STRING] - - #int pcap_set_snaplen(pcap_t *p, int snaplen) - # set the snapshot length for a not-yet-activated capture handle - pcap_set_snaplen = _lib.pcap_set_snaplen - pcap_set_snaplen.restype = c_int - pcap_set_snaplen.argtypes = [POINTER(pcap_t), c_int] - - #int pcap_set_promisc(pcap_t *p, int promisc) - # set promiscuous mode for a not-yet-activated capture handle - pcap_set_promisc = _lib.pcap_set_promisc - pcap_set_promisc.restype = c_int - pcap_set_promisc.argtypes = [POINTER(pcap_t), c_int] - - #int pcap_set_timeout(pcap_t *p, int to_ms) - # set the packet buffer timeout for a not-yet-activated capture handle - pcap_set_timeout = _lib.pcap_set_timeout - pcap_set_timeout.restype = c_int - pcap_set_timeout.argtypes = [POINTER(pcap_t), c_int] - - #int pcap_activate(pcap_t *p) - # activate a capture handle - pcap_activate = _lib.pcap_activate - pcap_activate.restype = c_int - pcap_activate.argtypes = [POINTER(pcap_t)] -except AttributeError: - pass - -#pcap_dumper_t * pcap_dump_open (pcap_t *p, const char *fname) -# Open a file to write packets. -pcap_dump_open = _lib.pcap_dump_open -pcap_dump_open.restype = POINTER(pcap_dumper_t) -pcap_dump_open.argtypes = [POINTER(pcap_t), STRING] - -#int pcap_setnonblock (pcap_t *p, int nonblock, char *errbuf) -# Switch between blocking and nonblocking mode. -pcap_setnonblock = _lib.pcap_setnonblock -pcap_setnonblock.restype = c_int -pcap_setnonblock.argtypes = [POINTER(pcap_t), c_int, STRING] - -#int pcap_getnonblock (pcap_t *p, char *errbuf) -# Get the "non-blocking" state of an interface. -pcap_getnonblock = _lib.pcap_getnonblock -pcap_getnonblock.restype = c_int -pcap_getnonblock.argtypes = [POINTER(pcap_t), STRING] - -#int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf) -# Construct a list of network devices that can be opened with pcap_open_live(). # noqa: E501 -pcap_findalldevs = _lib.pcap_findalldevs -pcap_findalldevs.restype = c_int -pcap_findalldevs.argtypes = [POINTER(POINTER(pcap_if_t)), STRING] - -#void pcap_freealldevs (pcap_if_t *alldevsp) -# Free an interface list returned by pcap_findalldevs(). -pcap_freealldevs = _lib.pcap_freealldevs -pcap_freealldevs.restype = None -pcap_freealldevs.argtypes = [POINTER(pcap_if_t)] - -#char * pcap_lookupdev (char *errbuf) -# Return the first valid device in the system. -pcap_lookupdev = _lib.pcap_lookupdev -pcap_lookupdev.restype = STRING -pcap_lookupdev.argtypes = [STRING] - -#int pcap_lookupnet (const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp, char *errbuf) # noqa: E501 -# Return the subnet and netmask of an interface. -pcap_lookupnet = _lib.pcap_lookupnet -pcap_lookupnet.restype = c_int -pcap_lookupnet.argtypes = [STRING, POINTER(bpf_u_int32), POINTER(bpf_u_int32), STRING] # noqa: E501 - -#int pcap_dispatch (pcap_t *p, int cnt, pcap_handler callback, u_char *user) -# Collect a group of packets. -pcap_dispatch = _lib.pcap_dispatch -pcap_dispatch.restype = c_int -pcap_dispatch.argtypes = [POINTER(pcap_t), c_int, pcap_handler, POINTER(u_char)] # noqa: E501 - -#int pcap_loop (pcap_t *p, int cnt, pcap_handler callback, u_char *user) -# Collect a group of packets. -pcap_loop = _lib.pcap_loop -pcap_loop.restype = c_int -pcap_loop.argtypes = [POINTER(pcap_t), c_int, pcap_handler, POINTER(u_char)] - -#u_char * pcap_next (pcap_t *p, struct pcap_pkthdr *h) -# Return the next available packet. -pcap_next = _lib.pcap_next -pcap_next.restype = POINTER(u_char) -pcap_next.argtypes = [POINTER(pcap_t), POINTER(pcap_pkthdr)] - -#int pcap_next_ex (pcap_t *p, struct pcap_pkthdr **pkt_header, const u_char **pkt_data) # noqa: E501 -# Read a packet from an interface or from an offline capture. -pcap_next_ex = _lib.pcap_next_ex -pcap_next_ex.restype = c_int -pcap_next_ex.argtypes = [POINTER(pcap_t), POINTER(POINTER(pcap_pkthdr)), POINTER(POINTER(u_char))] # noqa: E501 - -#void pcap_breakloop (pcap_t *) -# set a flag that will force pcap_dispatch() or pcap_loop() to return rather than looping. # noqa: E501 -pcap_breakloop = _lib.pcap_breakloop -pcap_breakloop.restype = None -pcap_breakloop.argtypes = [POINTER(pcap_t)] - -#int pcap_sendpacket (pcap_t *p, u_char *buf, int size) -# Send a raw packet. -pcap_sendpacket = _lib.pcap_sendpacket -pcap_sendpacket.restype = c_int -#pcap_sendpacket.argtypes = [POINTER(pcap_t), POINTER(u_char), c_int] -pcap_sendpacket.argtypes = [POINTER(pcap_t), c_void_p, c_int] - -#void pcap_dump (u_char *user, const struct pcap_pkthdr *h, const u_char *sp) -# Save a packet to disk. -pcap_dump = _lib.pcap_dump -pcap_dump.restype = None -pcap_dump.argtypes = [POINTER(pcap_dumper_t), POINTER(pcap_pkthdr), POINTER(u_char)] # noqa: E501 - -#long pcap_dump_ftell (pcap_dumper_t *) -# Return the file position for a "savefile". -pcap_dump_ftell = _lib.pcap_dump_ftell -pcap_dump_ftell.restype = c_long -pcap_dump_ftell.argtypes = [POINTER(pcap_dumper_t)] - -#int pcap_compile (pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask) # noqa: E501 -# Compile a packet filter, converting an high level filtering expression (see Filtering expression syntax) in a program that can be interpreted by the kernel-level filtering engine. # noqa: E501 -pcap_compile = _lib.pcap_compile -pcap_compile.restype = c_int -pcap_compile.argtypes = [POINTER(pcap_t), POINTER(bpf_program), STRING, c_int, bpf_u_int32] # noqa: E501 - -#int pcap_compile_nopcap (int snaplen_arg, int linktype_arg, struct bpf_program *program, char *buf, int optimize, bpf_u_int32 mask) # noqa: E501 -# Compile a packet filter without the need of opening an adapter. This function converts an high level filtering expression (see Filtering expression syntax) in a program that can be interpreted by the kernel-level filtering engine. # noqa: E501 -pcap_compile_nopcap = _lib.pcap_compile_nopcap -pcap_compile_nopcap.restype = c_int -pcap_compile_nopcap.argtypes = [c_int, c_int, POINTER(bpf_program), STRING, c_int, bpf_u_int32] # noqa: E501 - -#int pcap_setfilter (pcap_t *p, struct bpf_program *fp) -# Associate a filter to a capture. -pcap_setfilter = _lib.pcap_setfilter -pcap_setfilter.restype = c_int -pcap_setfilter.argtypes = [POINTER(pcap_t), POINTER(bpf_program)] - -#void pcap_freecode (struct bpf_program *fp) -# Free a filter. -pcap_freecode = _lib.pcap_freecode -pcap_freecode.restype = None -pcap_freecode.argtypes = [POINTER(bpf_program)] - -#int pcap_datalink (pcap_t *p) -# Return the link layer of an adapter. -pcap_datalink = _lib.pcap_datalink -pcap_datalink.restype = c_int -pcap_datalink.argtypes = [POINTER(pcap_t)] - -#int pcap_list_datalinks (pcap_t *p, int **dlt_buf) -# list datalinks -pcap_list_datalinks = _lib.pcap_list_datalinks -pcap_list_datalinks.restype = c_int -#pcap_list_datalinks.argtypes = [POINTER(pcap_t), POINTER(POINTER(c_int))] - -#int pcap_set_datalink (pcap_t *p, int dlt) -# Set the current data link type of the pcap descriptor to the type specified by dlt. -1 is returned on failure. # noqa: E501 -pcap_set_datalink = _lib.pcap_set_datalink -pcap_set_datalink.restype = c_int -pcap_set_datalink.argtypes = [POINTER(pcap_t), c_int] - -#int pcap_datalink_name_to_val (const char *name) -# Translates a data link type name, which is a DLT_ name with the DLT_ removed, to the corresponding data link type value. The translation is case-insensitive. -1 is returned on failure. # noqa: E501 -pcap_datalink_name_to_val = _lib.pcap_datalink_name_to_val -pcap_datalink_name_to_val.restype = c_int -pcap_datalink_name_to_val.argtypes = [STRING] - -#const char * pcap_datalink_val_to_name (int dlt) -# Translates a data link type value to the corresponding data link type name. NULL is returned on failure. # noqa: E501 -pcap_datalink_val_to_name = _lib.pcap_datalink_val_to_name -pcap_datalink_val_to_name.restype = STRING -pcap_datalink_val_to_name.argtypes = [c_int] - -#const char * pcap_datalink_val_to_description (int dlt) -# Translates a data link type value to a short description of that data link type. NULL is returned on failure. # noqa: E501 -pcap_datalink_val_to_description = _lib.pcap_datalink_val_to_description -pcap_datalink_val_to_description.restype = STRING -pcap_datalink_val_to_description.argtypes = [c_int] - -#int pcap_snapshot (pcap_t *p) -# Return the dimension of the packet portion (in bytes) that is delivered to the application. # noqa: E501 -pcap_snapshot = _lib.pcap_snapshot -pcap_snapshot.restype = c_int -pcap_snapshot.argtypes = [POINTER(pcap_t)] - -#int pcap_is_swapped (pcap_t *p) -# returns true if the current savefile uses a different byte order than the current system. # noqa: E501 -pcap_is_swapped = _lib.pcap_is_swapped -pcap_is_swapped.restype = c_int -pcap_is_swapped.argtypes = [POINTER(pcap_t)] - -#int pcap_major_version (pcap_t *p) -# return the major version number of the pcap library used to write the savefile. # noqa: E501 -pcap_major_version = _lib.pcap_major_version -pcap_major_version.restype = c_int -pcap_major_version.argtypes = [POINTER(pcap_t)] - -#int pcap_minor_version (pcap_t *p) -# return the minor version number of the pcap library used to write the savefile. # noqa: E501 -pcap_minor_version = _lib.pcap_minor_version -pcap_minor_version.restype = c_int -pcap_minor_version.argtypes = [POINTER(pcap_t)] - -#FILE * pcap_file (pcap_t *p) -# Return the standard stream of an offline capture. -pcap_file=_lib.pcap_file -pcap_file.restype = FILE -pcap_file.argtypes = [POINTER(pcap_t)] - -#int pcap_stats (pcap_t *p, struct pcap_stat *ps) -# Return statistics on current capture. -pcap_stats = _lib.pcap_stats -pcap_stats.restype = c_int -pcap_stats.argtypes = [POINTER(pcap_t), POINTER(pcap_stat)] - -#void pcap_perror (pcap_t *p, char *prefix) -# print the text of the last pcap library error on stderr, prefixed by prefix. # noqa: E501 -pcap_perror = _lib.pcap_perror -pcap_perror.restype = None -pcap_perror.argtypes = [POINTER(pcap_t), STRING] - -#char * pcap_geterr (pcap_t *p) -# return the error text pertaining to the last pcap library error. -pcap_geterr = _lib.pcap_geterr -pcap_geterr.restype = STRING -pcap_geterr.argtypes = [POINTER(pcap_t)] - -#char * pcap_strerror (int error) -# Provided in case strerror() isn't available. -pcap_strerror = _lib.pcap_strerror -pcap_strerror.restype = STRING -pcap_strerror.argtypes = [c_int] - -#const char * pcap_lib_version (void) -# Returns a pointer to a string giving information about the version of the libpcap library being used; note that it contains more information than just a version number. # noqa: E501 -pcap_lib_version = _lib.pcap_lib_version -pcap_lib_version.restype = STRING -pcap_lib_version.argtypes = [] - -#void pcap_close (pcap_t *p) -# close the files associated with p and deallocates resources. -pcap_close = _lib.pcap_close -pcap_close.restype = None -pcap_close.argtypes = [POINTER(pcap_t)] - -#FILE * pcap_dump_file (pcap_dumper_t *p) -# return the standard I/O stream of the 'savefile' opened by pcap_dump_open(). # noqa: E501 -pcap_dump_file=_lib.pcap_dump_file -pcap_dump_file.restype=FILE -pcap_dump_file.argtypes= [POINTER(pcap_dumper_t)] - -#int pcap_dump_flush (pcap_dumper_t *p) -# Flushes the output buffer to the ``savefile,'' so that any packets written with pcap_dump() but not yet written to the ``savefile'' will be written. -1 is returned on error, 0 on success. # noqa: E501 -pcap_dump_flush = _lib.pcap_dump_flush -pcap_dump_flush.restype = c_int -pcap_dump_flush.argtypes = [POINTER(pcap_dumper_t)] - -#void pcap_dump_close (pcap_dumper_t *p) -# Closes a savefile. -pcap_dump_close = _lib.pcap_dump_close -pcap_dump_close.restype = None -pcap_dump_close.argtypes = [POINTER(pcap_dumper_t)] - -if not WINDOWS: - #int pcap_get_selectable_fd(pcap_t, *p) - # Returns, on UNIX, a file descriptor number for a file descriptor on which one can do a select(), poll(). -1 is returned if no such descriptor exists. # noqa: E501 - pcap_get_selectable_fd = _lib.pcap_get_selectable_fd - pcap_get_selectable_fd.restype = c_int - pcap_get_selectable_fd.argtypes = [POINTER(pcap_t)] - -########################################### -## Windows-specific Extensions -## The functions in this section extend libpcap to offer advanced functionalities # noqa: E501 -## (like remote packet capture, packet buffer size variation or high-precision packet injection). # noqa: E501 -## However, at the moment they can be used only in Windows. -########################################### -if WINDOWS: - HANDLE = c_void_p - - ############## - ## Identifiers related to the new source syntax - ############## - #define PCAP_SRC_FILE 2 - #define PCAP_SRC_IFLOCAL 3 - #define PCAP_SRC_IFREMOTE 4 - #Internal representation of the type of source in use (file, remote/local interface). # noqa: E501 - PCAP_SRC_FILE = 2 - PCAP_SRC_IFLOCAL = 3 - PCAP_SRC_IFREMOTE = 4 - - ############## - ## Strings related to the new source syntax - ############## - #define PCAP_SRC_FILE_STRING "file://" - #define PCAP_SRC_IF_STRING "rpcap://" - #String that will be used to determine the type of source in use (file, remote/local interface). # noqa: E501 - PCAP_SRC_FILE_STRING="file://" - PCAP_SRC_IF_STRING="rpcap://" - - ############## - ## Flags defined in the pcap_open() function - ############## - # define PCAP_OPENFLAG_PROMISCUOUS 1 - # Defines if the adapter has to go in promiscuous mode. - PCAP_OPENFLAG_PROMISCUOUS=1 - # define PCAP_OPENFLAG_DATATX_UDP 2 - # Defines if the data transfer (in case of a remote capture) has to be done with UDP protocol. # noqa: E501 - PCAP_OPENFLAG_DATATX_UDP=2 - # define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4 - PCAP_OPENFLAG_NOCAPTURE_RPCAP=4 - # Defines if the remote probe will capture its own generated traffic. - # define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8 - PCAP_OPENFLAG_NOCAPTURE_LOCAL = 8 - # define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16 - # This flag configures the adapter for maximum responsiveness. - PCAP_OPENFLAG_MAX_RESPONSIVENESS=16 - - ############## - ## Sampling methods defined in the pcap_setsampling() function - ############## - # define PCAP_SAMP_NOSAMP 0 - # No sampling has to be done on the current capture. - PCAP_SAMP_NOSAMP=0 - # define PCAP_SAMP_1_EVERY_N 1 - # It defines that only 1 out of N packets must be returned to the user. - PCAP_SAMP_1_EVERY_N=1 - #define PCAP_SAMP_FIRST_AFTER_N_MS 2 - # It defines that we have to return 1 packet every N milliseconds. - PCAP_SAMP_FIRST_AFTER_N_MS=2 - - ############## - ## Authentication methods supported by the RPCAP protocol - ############## - # define RPCAP_RMTAUTH_NULL 0 - # It defines the NULL authentication. - RPCAP_RMTAUTH_NULL=0 - # define RPCAP_RMTAUTH_PWD 1 - # It defines the username/password authentication. - RPCAP_RMTAUTH_PWD=1 - - - ############## - ## Remote struct and defines - ############## - # define PCAP_BUF_SIZE 1024 - # Defines the maximum buffer size in which address, port, interface names are kept. # noqa: E501 - PCAP_BUF_SIZE = 1024 - # define RPCAP_HOSTLIST_SIZE 1024 - # Maximum length of an host name (needed for the RPCAP active mode). - RPCAP_HOSTLIST_SIZE = 1024 - - class pcap_send_queue(Structure): - _fields_=[("maxlen",c_uint), - ("len",c_uint), - ("buffer",c_char_p)] - - ## struct pcap_rmtauth - ## This structure keeps the information needed to autheticate the user on a remote machine # noqa: E501 - class pcap_rmtauth(Structure): - _fields_=[("type",c_int), - ("username",c_char_p), - ("password",c_char_p)] - - ## struct pcap_samp - ## This structure defines the information related to sampling - class pcap_samp(Structure): - _fields_=[("method",c_int), - ("value",c_int)] - - #PAirpcapHandle pcap_get_airpcap_handle (pcap_t *p) - # Returns the AirPcap handler associated with an adapter. This handler can be used to change the wireless-related settings of the CACE Technologies AirPcap wireless capture adapters. # noqa: E501 - - #bool pcap_offline_filter (struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data) # noqa: E501 - # Returns if a given filter applies to an offline packet. - pcap_offline_filter = _lib.pcap_offline_filter - pcap_offline_filter.restype = c_bool - pcap_offline_filter.argtypes = [POINTER(bpf_program),POINTER(pcap_pkthdr),POINTER(u_char)] # noqa: E501 - - #int pcap_live_dump (pcap_t *p, char *filename, int maxsize, int maxpacks) - # Save a capture to file. - pcap_live_dump = _lib.pcap_live_dump - pcap_live_dump.restype = c_int - pcap_live_dump.argtypes = [POINTER(pcap_t), POINTER(c_char), c_int,c_int] - - #int pcap_live_dump_ended (pcap_t *p, int sync) - # Return the status of the kernel dump process, i.e. tells if one of the limits defined with pcap_live_dump() has been reached. # noqa: E501 - pcap_live_dump_ended = _lib.pcap_live_dump_ended - pcap_live_dump_ended.restype = c_int - pcap_live_dump_ended.argtypes = [POINTER(pcap_t), c_int] - - #struct pcap_stat * pcap_stats_ex (pcap_t *p, int *pcap_stat_size) - # Return statistics on current capture. - pcap_stats_ex = _lib.pcap_stats_ex - pcap_stats_ex.restype = POINTER(pcap_stat) - pcap_stats_ex.argtypes = [POINTER(pcap_t), POINTER(c_int)] - - #int pcap_setbuff (pcap_t *p, int dim) - # Set the size of the kernel buffer associated with an adapter. - pcap_setbuff = _lib.pcap_setbuff - pcap_setbuff.restype = c_int - pcap_setbuff.argtypes = [POINTER(pcap_t), c_int] - - #int pcap_setmode (pcap_t *p, int mode) - # Set the working mode of the interface p to mode. - pcap_setmode = _lib.pcap_setmode - pcap_setmode.restype = c_int - pcap_setmode.argtypes = [POINTER(pcap_t), c_int] - - #int pcap_setmintocopy (pcap_t *p, int size) - # Set the minimum amount of data received by the kernel in a single call. - pcap_setmintocopy = _lib.pcap_setmintocopy - pcap_setmintocopy.restype = c_int - pcap_setmintocopy.argtype = [POINTER(pcap_t), c_int] - - #HANDLE pcap_getevent (pcap_t *p) - # Return the handle of the event associated with the interface p. - pcap_getevent = _lib.pcap_getevent - pcap_getevent.restype = HANDLE - pcap_getevent.argtypes = [POINTER(pcap_t)] - - #pcap_send_queue * pcap_sendqueue_alloc (u_int memsize) - # Allocate a send queue. - pcap_sendqueue_alloc = _lib.pcap_sendqueue_alloc - pcap_sendqueue_alloc.restype = POINTER(pcap_send_queue) - pcap_sendqueue_alloc.argtypes = [c_uint] - - #void pcap_sendqueue_destroy (pcap_send_queue *queue) - # Destroy a send queue. - pcap_sendqueue_destroy = _lib.pcap_sendqueue_destroy - pcap_sendqueue_destroy.restype = None - pcap_sendqueue_destroy.argtypes = [POINTER(pcap_send_queue)] - - #int pcap_sendqueue_queue (pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) # noqa: E501 - # Add a packet to a send queue. - pcap_sendqueue_queue = _lib.pcap_sendqueue_queue - pcap_sendqueue_queue.restype = c_int - pcap_sendqueue_queue.argtypes = [POINTER(pcap_send_queue), POINTER(pcap_pkthdr), POINTER(u_char)] # noqa: E501 - - #u_int pcap_sendqueue_transmit (pcap_t *p, pcap_send_queue *queue, int sync) # noqa: E501 - # Send a queue of raw packets to the network. - pcap_sendqueue_transmit = _lib.pcap_sendqueue_transmit - pcap_sendqueue_transmit.retype = u_int - pcap_sendqueue_transmit.argtypes = [POINTER(pcap_t), POINTER(pcap_send_queue), c_int] # noqa: E501 - - #int pcap_findalldevs_ex (char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf) # noqa: E501 - # Create a list of network devices that can be opened with pcap_open(). - pcap_findalldevs_ex = _lib.pcap_findalldevs_ex - pcap_findalldevs_ex.retype = c_int - pcap_findalldevs_ex.argtypes = [STRING, POINTER(pcap_rmtauth), POINTER(POINTER(pcap_if_t)), STRING] # noqa: E501 - - #int pcap_createsrcstr (char *source, int type, const char *host, const char *port, const char *name, char *errbuf) # noqa: E501 - # Accept a set of strings (host name, port, ...), and it returns the complete source string according to the new format (e.g. 'rpcap://1.2.3.4/eth0'). # noqa: E501 - pcap_createsrcstr = _lib.pcap_createsrcstr - pcap_createsrcstr.restype = c_int - pcap_createsrcstr.argtypes = [STRING, c_int, STRING, STRING, STRING, STRING] # noqa: E501 - - #int pcap_parsesrcstr (const char *source, int *type, char *host, char *port, char *name, char *errbuf) # noqa: E501 - # Parse the source string and returns the pieces in which the source can be split. # noqa: E501 - pcap_parsesrcstr = _lib.pcap_parsesrcstr - pcap_parsesrcstr.retype = c_int - pcap_parsesrcstr.argtypes = [STRING, POINTER(c_int), STRING, STRING, STRING, STRING] # noqa: E501 - - #pcap_t * pcap_open (const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf) # noqa: E501 - # Open a generic source in order to capture / send (WinPcap only) traffic. # noqa: E501 - pcap_open = _lib.pcap_open - pcap_open.restype = POINTER(pcap_t) - pcap_open.argtypes = [STRING, c_int, c_int, c_int, POINTER(pcap_rmtauth), STRING] # noqa: E501 - - #struct pcap_samp * pcap_setsampling (pcap_t *p) - # Define a sampling method for packet capture. - pcap_setsampling = _lib.pcap_setsampling - pcap_setsampling.restype = POINTER(pcap_samp) - pcap_setsampling.argtypes = [POINTER(pcap_t)] - - #SOCKET pcap_remoteact_accept (const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf) # noqa: E501 - # Block until a network connection is accepted (active mode only). - pcap_remoteact_accept = _lib.pcap_remoteact_accept - pcap_remoteact_accept.restype = SOCKET - pcap_remoteact_accept.argtypes = [STRING, STRING, STRING, STRING, POINTER(pcap_rmtauth), STRING] # noqa: E501 - - #int pcap_remoteact_close (const char *host, char *errbuf) - # Drop an active connection (active mode only). - pcap_remoteact_close = _lib.pcap_remoteact_close - pcap_remoteact_close.restypes = c_int - pcap_remoteact_close.argtypes = [STRING, STRING] - - #void pcap_remoteact_cleanup () - # Clean the socket that is currently used in waiting active connections. - pcap_remoteact_cleanup = _lib.pcap_remoteact_cleanup - pcap_remoteact_cleanup.restypes = None - pcap_remoteact_cleanup.argtypes = [] - - #int pcap_remoteact_list (char *hostlist, char sep, int size, char *errbuf) - # Return the hostname of the host that have an active connection with us (active mode only). # noqa: E501 - pcap_remoteact_list = _lib.pcap_remoteact_list - pcap_remoteact_list.restype = c_int - pcap_remoteact_list.argtypes = [STRING, c_char, c_int, STRING] diff --git a/scripts/external_libs/scapy-2.4.3/scapy/packet.py b/scripts/external_libs/scapy-2.4.3/scapy/packet.py deleted file mode 100644 index 3f0f4b017b..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/packet.py +++ /dev/null @@ -1,2173 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Packet class. Binding mechanism. fuzz() method. -""" - -from __future__ import absolute_import -from __future__ import print_function -import re -import time -import itertools -import copy -import types -import warnings - -from scapy.fields import StrField, ConditionalField, Emph, PacketListField, \ - BitField, MultiEnumField, EnumField, FlagsField, MultipleTypeField -from scapy.config import conf, _version_checker -from scapy.compat import raw, orb, bytes_encode -from scapy.base_classes import BasePacket, Gen, SetGen, Packet_metaclass, \ - _CanvasDumpExtended -from scapy.volatile import RandField, VolatileValue -from scapy.utils import import_hexcap, tex_escape, colgen, issubtype, \ - pretty_list -from scapy.error import Scapy_Exception, log_runtime, warning -from scapy.extlib import PYX -import scapy.modules.six as six - - -class CGlobal: - ONCE = False -try: - import pyx -except ImportError: - pass - - -class RawVal: - def __init__(self, val=""): - self.val = val - - def __str__(self): - return str(self.val) - - def __bytes__(self): - return raw(self.val) - - def __repr__(self): - return "" % self.val - - -class CPacketRes: - pass - - -class Packet(six.with_metaclass(Packet_metaclass, BasePacket, - _CanvasDumpExtended)): - __slots__ = [ - "time", "sent_time", "name", - "default_fields", "fields", "fieldtype", - "overload_fields", "overloaded_fields", - "packetfields", - "original", "explicit", "raw_packet_cache", - "raw_packet_cache_fields", "_pkt", "post_transforms", - # then payload and underlayer - "payload", "underlayer", - "name", - # used for sr() - "_answered", - # used when sniffing - "direction", "sniffed_on", - # handle snaplen Vs real length - "wirelen", - # used while performing advanced dissection to handle padding - "_tmp_dissect_pos", - "_offset", - "_length", - "offset_fields" - ] - name = None - fields_desc = [] - deprecated_fields = {} - overload_fields = {} - payload_guess = [] - show_indent = 1 - show_summary = True - match_subclass = False - class_dont_cache = dict() - class_packetfields = dict() - class_default_fields = dict() - class_default_fields_ref = dict() - class_fieldtype = dict() - - @classmethod - def from_hexcap(cls): - return cls(import_hexcap()) - - @classmethod - def upper_bonds(self): - for fval, upper in self.payload_guess: - print("%-20s %s" % (upper.__name__, ", ".join("%-12s" % ("%s=%r" % i) for i in six.iteritems(fval)))) # noqa: E501 - - @classmethod - def lower_bonds(self): - for lower, fval in six.iteritems(self._overload_fields): - print("%-20s %s" % (lower.__name__, ", ".join("%-12s" % ("%s=%r" % i) for i in six.iteritems(fval)))) # noqa: E501 - - def _unpickle(self, dlist): - """Used to unpack pickling""" - self.__init__(b"".join(dlist)) - return self - - def __reduce__(self): - """Used by pickling methods""" - return (self.__class__, (), (self.build(),)) - - def __reduce_ex__(self, proto): - """Used by pickling methods""" - return self.__reduce__() - - def __getstate__(self): - """Mark object as pickable""" - return self.__reduce__()[2] - - def __setstate__(self, state): - """Rebuild state using pickable methods""" - return self._unpickle(state) - - def __deepcopy__(self, memo): - """Used by copy.deepcopy""" - return self.copy() - - def __init__(self, _pkt=b"", post_transform=None, _internal=0, _underlayer=None, **fields): # noqa: E501 - self.time = time.time() - self.sent_time = None - self.name = (self.__class__.__name__ - if self._name is None else - self._name) - self.default_fields = {} - self._offset = 0 # offset of the object - self._length = 0 - self.offset_fields = {} # offset of each field - self.overload_fields = self._overload_fields - self.overloaded_fields = {} - self.fields = {} - self.fieldtype = {} - self.packetfields = [] - self.payload = NoPayload() - self.init_fields() - self.underlayer = _underlayer - self.original = _pkt - self.explicit = 0 - self.raw_packet_cache = None - self.raw_packet_cache_fields = None - self.wirelen = None - if _pkt: - self.dissect(_pkt) - if not _internal: - self.dissection_done(self) - # We use this strange initialization so that the fields - # are initialized in their declaration order. - # It is required to always support MultipleTypeField - for field in self.fields_desc: - fname = field.name - try: - value = fields.pop(fname) - except KeyError: - continue - self.fields[fname] = self.get_field(fname).any2i(self, value) - # The remaining fields are unknown - for fname in fields: - if fname in self.deprecated_fields: - # Resolve deprecated fields - value = fields[fname] - fname = self._resolve_alias(fname) - self.fields[fname] = self.get_field(fname).any2i(self, value) - continue - raise AttributeError(fname) - if isinstance(post_transform, list): - self.post_transforms = post_transform - elif post_transform is None: - self.post_transforms = [] - else: - self.post_transforms = [post_transform] - - def init_fields(self): - """ - Initialize each fields of the fields_desc dict - """ - - if self.class_dont_cache.get(self.__class__, False): - self.do_init_fields(self.fields_desc) - else: - self.do_init_cached_fields() - - def do_init_fields(self, flist): - """ - Initialize each fields of the fields_desc dict - """ - default_fields = {} - for f in flist: - default_fields[f.name] = copy.deepcopy(f.default) - self.fieldtype[f.name] = f - if f.holds_packets: - self.packetfields.append(f) - # We set default_fields last to avoid race issues - self.default_fields = default_fields - - def do_init_cached_fields(self): - """ - Initialize each fields of the fields_desc dict, or use the cached - fields information - """ - - cls_name = self.__class__ - - # Build the fields information - if Packet.class_default_fields.get(cls_name, None) is None: - self.prepare_cached_fields(self.fields_desc) - - # Use fields information from cache - default_fields = Packet.class_default_fields.get(cls_name, None) - if default_fields: - self.default_fields = default_fields - self.fieldtype = Packet.class_fieldtype[cls_name] - self.packetfields = Packet.class_packetfields[cls_name] - - # Deepcopy default references - for fname in Packet.class_default_fields_ref[cls_name]: - value = self.default_fields[fname] - try: - self.fields[fname] = value.copy() - except AttributeError: - # Python 2.7 - list only - self.fields[fname] = value[:] - - def prepare_cached_fields(self, flist): - """ - Prepare the cached fields of the fields_desc dict - """ - - cls_name = self.__class__ - - # Fields cache initialization - if not flist: - return - - class_default_fields = dict() - class_default_fields_ref = list() - class_fieldtype = dict() - class_packetfields = list() - - # Fields initialization - for f in flist: - if isinstance(f, MultipleTypeField): - # Abort - self.class_dont_cache[cls_name] = True - self.do_init_fields(self.fields_desc) - return - - tmp_copy = copy.deepcopy(f.default) - class_default_fields[f.name] = tmp_copy - class_fieldtype[f.name] = f - if f.holds_packets: - class_packetfields.append(f) - - # Remember references - if isinstance(f.default, (list, dict, set, RandField, Packet)): - class_default_fields_ref.append(f.name) - - # Apply - Packet.class_default_fields_ref[cls_name] = class_default_fields_ref - Packet.class_fieldtype[cls_name] = class_fieldtype - Packet.class_packetfields[cls_name] = class_packetfields - # Last to avoid racing issues - Packet.class_default_fields[cls_name] = class_default_fields - - def dissection_done(self, pkt): - """DEV: will be called after a dissection is completed""" - self.post_dissection(pkt) - self.payload.dissection_done(pkt) - - def post_dissection(self, pkt): - """DEV: is called after the dissection of the whole packet""" - if self.payload: - self.payload._offset = self._offset + self._length - - def get_field(self, fld): - """DEV: returns the field instance from the name of the field""" - return self.fieldtype[fld] - - def add_payload(self, payload): - if payload is None: - return - elif not isinstance(self.payload, NoPayload): - self.payload.add_payload(payload) - else: - if isinstance(payload, Packet): - self.payload = payload - payload.add_underlayer(self) - for t in self.aliastypes: - if t in payload.overload_fields: - self.overloaded_fields = payload.overload_fields[t] - break - elif isinstance(payload, bytes): - self.payload = conf.raw_layer(load=payload) - else: - raise TypeError("payload must be either 'Packet' or 'bytes', not [%s]" % repr(payload)) # noqa: E501 - - def remove_payload(self): - self.payload.remove_underlayer(self) - self.payload = NoPayload() - self.overloaded_fields = {} - - def add_underlayer(self, underlayer): - self.underlayer = underlayer - - def remove_underlayer(self, other): - self.underlayer = None - - def copy(self): - """Returns a deep copy of the instance.""" - clone = self.__class__() - clone.fields = self.copy_fields_dict(self.fields) - clone.default_fields = self.copy_fields_dict(self.default_fields) - clone.overloaded_fields = self.overloaded_fields.copy() - clone._offset = self._offset - clone.underlayer = self.underlayer - clone.explicit = self.explicit - clone.raw_packet_cache = self.raw_packet_cache - clone.raw_packet_cache_fields = self.copy_fields_dict( - self.raw_packet_cache_fields - ) - clone.wirelen = self.wirelen - clone.post_transforms = self.post_transforms[:] - clone.payload = self.payload.copy() - clone.payload.add_underlayer(clone) - clone.time = self.time - return clone - - def dump_offsets (self): - print("obj-id {0} {1} {2}".format(id(self),self.name ,self._offset)) - if self.payload: - self.payload.dump_offsets() - - def dump_offsets_tree(self, indent = '', base_offset = 0): - ct = conf.color_theme - print("%s%s %s %s" % (indent, - ct.punct("###["), - ct.layer_name(self.name), - ct.punct("]###"))) - for f in self.fields_desc: - if isinstance(f, ConditionalField) and not f._evalcond(self): - continue - fvalue = self.getfieldval(f.name) - if isinstance(fvalue, Packet) or (f.islist and f.holds_packets and type(fvalue) is list): - print('\n%s %s: %s' % (indent, f.name, base_offset + f._offset)) - fvalue_gen = SetGen(fvalue, _iterpacket = 0) - fvalue_bu = None - for fvalue in fvalue_gen: - if fvalue_bu: - fvalue._offset = fvalue_bu._offset + len(fvalue_bu) - print('%s %s: %s' % (indent, fvalue.name, base_offset + f._offset + fvalue._offset)) - fvalue.dump_offsets_tree(' ' + indent, base_offset + f._offset + fvalue._offset) - fvalue_bu = fvalue - else: - print('%s %s: %s' % (indent, f.name, base_offset + f._offset)) - if self.payload: - print('---- payload ----') - self.payload.dump_offsets_tree(indent, base_offset + self._length) - - def _resolve_alias(self, attr): - new_attr, version = self.deprecated_fields[attr] - warnings.warn( - "%s has been deprecated in favor of %s since %s !" % ( - attr, new_attr, version - ), DeprecationWarning - ) - return new_attr - - def getfieldval(self, attr): - if self.deprecated_fields and attr in self.deprecated_fields: - attr = self._resolve_alias(attr) - if attr in self.fields: - return self.fields[attr] - if attr in self.overloaded_fields: - return self.overloaded_fields[attr] - if attr in self.default_fields: - return self.default_fields[attr] - return self.payload.getfieldval(attr) - - def getfield_and_val(self, attr): - if self.deprecated_fields and attr in self.deprecated_fields: - attr = self._resolve_alias(attr) - if attr in self.fields: - return self.get_field(attr), self.fields[attr] - if attr in self.overloaded_fields: - return self.get_field(attr), self.overloaded_fields[attr] - if attr in self.default_fields: - return self.get_field(attr), self.default_fields[attr] - - def __getattr__(self, attr): - try: - fld, v = self.getfield_and_val(attr) - except TypeError: - return self.payload.__getattr__(attr) - if fld is not None: - return fld.i2h(self, v) - return v - - def setfieldval(self, attr, val): - if self.deprecated_fields and attr in self.deprecated_fields: - attr = self._resolve_alias(attr) - if attr in self.default_fields: - fld = self.get_field(attr) - if fld is None: - any2i = lambda x, y: y - else: - any2i = fld.any2i - self.fields[attr] = any2i(self, val) - self.explicit = 0 - self.raw_packet_cache = None - self.raw_packet_cache_fields = None - self.wirelen = None - elif attr == "payload": - self.remove_payload() - self.add_payload(val) - else: - self.payload.setfieldval(attr, val) - - def __setattr__(self, attr, val): - if attr in self.__all_slots__: - if attr == "sent_time": - self.update_sent_time(val) - return object.__setattr__(self, attr, val) - try: - return self.setfieldval(attr, val) - except AttributeError: - pass - return object.__setattr__(self, attr, val) - - def delfieldval(self, attr): - if attr in self.fields: - del(self.fields[attr]) - self.explicit = 0 # in case a default value must be explicit - self.raw_packet_cache = None - self.raw_packet_cache_fields = None - self.wirelen = None - elif attr in self.default_fields: - pass - elif attr == "payload": - self.remove_payload() - else: - self.payload.delfieldval(attr) - - def __delattr__(self, attr): - if attr == "payload": - return self.remove_payload() - if attr in self.__all_slots__: - return object.__delattr__(self, attr) - try: - return self.delfieldval(attr) - except AttributeError: - pass - return object.__delattr__(self, attr) - - def _superdir(self): - """ - Return a list of slots and methods, including those from subclasses. - """ - attrs = set() - cls = self.__class__ - if hasattr(cls, '__all_slots__'): - attrs.update(cls.__all_slots__) - for bcls in cls.__mro__: - if hasattr(bcls, '__dict__'): - attrs.update(bcls.__dict__) - return attrs - - def __dir__(self): - """ - Add fields to tab completion list. - """ - return sorted(itertools.chain(self._superdir(), self.default_fields)) - - def __repr__(self): - s = "" - ct = conf.color_theme - for f in self.fields_desc: - if isinstance(f, ConditionalField) and not f._evalcond(self): - continue - if f.name in self.fields: - fval = self.fields[f.name] - if isinstance(fval, (list, dict, set)) and len(fval) == 0: - continue - val = f.i2repr(self, fval) - elif f.name in self.overloaded_fields: - fover = self.overloaded_fields[f.name] - if isinstance(fover, (list, dict, set)) and len(fover) == 0: - continue - val = f.i2repr(self, fover) - else: - continue - if isinstance(f, Emph) or f in conf.emph: - ncol = ct.emph_field_name - vcol = ct.emph_field_value - else: - ncol = ct.field_name - vcol = ct.field_value - - s += " %s%s%s" % (ncol(f.name), - ct.punct("="), - vcol(val)) - return "%s%s %s %s%s%s" % (ct.punct("<"), - ct.layer_name(self.__class__.__name__), - s, - ct.punct("|"), - repr(self.payload), - ct.punct(">")) - - if six.PY2: - def __str__(self): - return self.build() - else: - def __str__(self): - warning("Calling str(pkt) on Python 3 makes no sense!") - return str(self.build()) - - def __bytes__(self): - return self.build() - - def __div__(self, other): - if isinstance(other, Packet): - cloneA = self.copy() - cloneB = other.copy() - cloneA.add_payload(cloneB) - return cloneA - elif isinstance(other, (bytes, str)): - return self / conf.raw_layer(load=other) - else: - return other.__rdiv__(self) - __truediv__ = __div__ - - def __rdiv__(self, other): - if isinstance(other, (bytes, str)): - return conf.raw_layer(load=other) / self - else: - raise TypeError - __rtruediv__ = __rdiv__ - - def __mul__(self, other): - if isinstance(other, int): - return [self] * other - else: - raise TypeError - - def __rmul__(self, other): - return self.__mul__(other) - - def __nonzero__(self): - return True - __bool__ = __nonzero__ - - def __len__(self): - return len(self.__bytes__()) - - def dump_fields_offsets (self): - for f in self.fields_desc: - print ("field %-40s %02d %02d" % (f.name, f._offset,f.get_size_bytes ())) - - def copy_field_value(self, fieldname, value): - return self.get_field(fieldname).do_copy(value) - - def copy_fields_dict(self, fields): - if fields is None: - return None - return {fname: self.copy_field_value(fname, fval) - for fname, fval in six.iteritems(fields)} - - def clear_cache(self): - """Clear the raw packet cache for the field and all its subfields""" - self.raw_packet_cache = None - for fld, fval in six.iteritems(self.fields): - fld = self.get_field(fld) - if fld.holds_packets: - if isinstance(fval, Packet): - fval.clear_cache() - elif isinstance(fval, list): - for fsubval in fval: - fsubval.clear_cache() - self.payload.clear_cache() - - def self_build(self, field_pos_list=None): - """ - Create the default layer regarding fields_desc dict - - :param field_pos_list: - """ - if self.raw_packet_cache is not None: - for fname, fval in six.iteritems(self.raw_packet_cache_fields): - if self.getfieldval(fname) != fval: - self.raw_packet_cache = None - self.raw_packet_cache_fields = None - self.wirelen = None - break - if self.raw_packet_cache is not None: - return self.raw_packet_cache - p = b"" - for f in self.fields_desc: - if type(p) is tuple: - f._offset = len(p[0]) - else: - assert(type(p) is bytes) - f._offset = len(p) - val = self.getfieldval(f.name) - if isinstance(val, RawVal): - sval = raw(val) - p += sval - if field_pos_list is not None: - field_pos_list.append((f.name, sval.encode("string_escape"), len(p), len(sval))) # noqa: E501 - f._offset = val - else: - try: - p = f.addfield(self, p, val) - except Exception as e: - print('Error in %s adding %s, %s' % (self.name, f.name, e)) - raise - return p - - def do_build_payload(self): - """ - Create the default version of the payload layer - - :return: a string of payload layer - """ - return self.payload.do_build(None) - - def do_update_payload_offset(self, pkt): - self.payload._offset = self._offset + len(pkt) - - def dump_layers_offset(self): - p = self - while True: - print(p.name, "offset :", p._offset) - p = p.payload - if p is None or isinstance(p, NoPayload): - break - - def do_build(self, result): - """ - Create the default version of the layer - - :return: a string of the packet with the payload - """ - if not self.explicit: - self = next(iter(self)) - pkt = self.self_build() - for t in self.post_transforms: - pkt = t(pkt) - # TRex Change - self.do_update_payload_offset(pkt) - pay = self.do_build_payload() - # Trex Change - if result is not None: - result.pkt = self - if self.raw_packet_cache is None: - p = self.post_build(pkt, pay) - if result is not None: - result.pkt = self - return p - else: - return pkt + pay - - def build_padding(self): - return self.payload.build_padding() - - def update_build_info (self,other): - p = self - o = other - while True: - assert(p.aliastypes == o.aliastypes) - assert(type(p) == type(o)) - - #copy - p._offset = o._offset - - #next - p = p.payload - o = o.payload - if p is None or isinstance(p, NoPayload): - break - - def build(self): - """ - Create the current layer - - :return: string of the packet with the payload - """ - result = CPacketRes() - p = self.do_build(result) - p += self.build_padding() - p = self.build_done(p) - self.update_build_info(result.pkt) - return p - - - - def post_build(self, pkt, pay): - """ - DEV: called right after the current layer is build. - - :param str pkt: the current packet (build by self_buil function) - :param str pay: the packet payload (build by do_build_payload function) - :return: a string of the packet with the payload - """ - return pkt + pay - - def build_done(self, p): - return self.payload.build_done(p) - - def do_build_ps(self): - p = b"" - pl = [] - q = b"" - for f in self.fields_desc: - if isinstance(f, ConditionalField) and not f._evalcond(self): - continue - p = f.addfield(self, p, self.getfieldval(f.name)) - if isinstance(p, bytes): - r = p[len(q):] - q = p - else: - r = b"" - pl.append((f, f.i2repr(self, self.getfieldval(f.name)), r)) - - pkt, lst = self.payload.build_ps(internal=1) - p += pkt - lst.append((self, pl)) - - return p, lst - - def build_ps(self, internal=0): - p, lst = self.do_build_ps() -# if not internal: -# pkt = self -# while pkt.haslayer(conf.padding_layer): -# pkt = pkt.getlayer(conf.padding_layer) -# lst.append( (pkt, [ ("loakjkjd", pkt.load, pkt.load) ] ) ) -# p += pkt.load -# pkt = pkt.payload - return p, lst - - def canvas_dump(self, layer_shift=0, rebuild=1): - if PYX == 0: - raise ImportError("PyX and its dependencies must be installed") - canvas = pyx.canvas.canvas() - if rebuild: - _, t = self.__class__(raw(self)).build_ps() - else: - _, t = self.build_ps() - YTXT = len(t) - for _, l in t: - YTXT += len(l) - YTXT = float(YTXT) - YDUMP = YTXT - - XSTART = 1 - XDSTART = 10 - y = 0.0 - yd = 0.0 - XMUL = 0.55 - YMUL = 0.4 - - backcolor = colgen(0.6, 0.8, 1.0, trans=pyx.color.rgb) - forecolor = colgen(0.2, 0.5, 0.8, trans=pyx.color.rgb) -# backcolor=makecol(0.376, 0.729, 0.525, 1.0) - - def hexstr(x): - return " ".join("%02x" % orb(c) for c in x) - - def make_dump_txt(x, y, txt): - return pyx.text.text(XDSTART + x * XMUL, (YDUMP - y) * YMUL, r"\tt{%s}" % hexstr(txt), [pyx.text.size.Large]) # noqa: E501 - - def make_box(o): - return pyx.box.rect(o.left(), o.bottom(), o.width(), o.height(), relcenter=(0.5, 0.5)) # noqa: E501 - - def make_frame(lst): - if len(lst) == 1: - b = lst[0].bbox() - b.enlarge(pyx.unit.u_pt) - return b.path() - else: - fb = lst[0].bbox() - fb.enlarge(pyx.unit.u_pt) - lb = lst[-1].bbox() - lb.enlarge(pyx.unit.u_pt) - if len(lst) == 2 and fb.left() > lb.right(): - return pyx.path.path(pyx.path.moveto(fb.right(), fb.top()), - pyx.path.lineto(fb.left(), fb.top()), - pyx.path.lineto(fb.left(), fb.bottom()), # noqa: E501 - pyx.path.lineto(fb.right(), fb.bottom()), # noqa: E501 - pyx.path.moveto(lb.left(), lb.top()), - pyx.path.lineto(lb.right(), lb.top()), - pyx.path.lineto(lb.right(), lb.bottom()), # noqa: E501 - pyx.path.lineto(lb.left(), lb.bottom())) # noqa: E501 - else: - # XXX - gb = lst[1].bbox() - if gb != lb: - gb.enlarge(pyx.unit.u_pt) - kb = lst[-2].bbox() - if kb != gb and kb != lb: - kb.enlarge(pyx.unit.u_pt) - return pyx.path.path(pyx.path.moveto(fb.left(), fb.top()), - pyx.path.lineto(fb.right(), fb.top()), - pyx.path.lineto(fb.right(), kb.bottom()), # noqa: E501 - pyx.path.lineto(lb.right(), kb.bottom()), # noqa: E501 - pyx.path.lineto(lb.right(), lb.bottom()), # noqa: E501 - pyx.path.lineto(lb.left(), lb.bottom()), # noqa: E501 - pyx.path.lineto(lb.left(), gb.top()), - pyx.path.lineto(fb.left(), gb.top()), - pyx.path.closepath(),) - - def make_dump(s, shift=0, y=0, col=None, bkcol=None, large=16): - c = pyx.canvas.canvas() - tlist = [] - while s: - dmp, s = s[:large - shift], s[large - shift:] - txt = make_dump_txt(shift, y, dmp) - tlist.append(txt) - shift += len(dmp) - if shift >= 16: - shift = 0 - y += 1 - if col is None: - col = pyx.color.rgb.red - if bkcol is None: - bkcol = pyx.color.rgb.white - c.stroke(make_frame(tlist), [col, pyx.deco.filled([bkcol]), pyx.style.linewidth.Thick]) # noqa: E501 - for txt in tlist: - c.insert(txt) - return c, tlist[-1].bbox(), shift, y - - last_shift, last_y = 0, 0.0 - while t: - bkcol = next(backcolor) - proto, fields = t.pop() - y += 0.5 - pt = pyx.text.text(XSTART, (YTXT - y) * YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(proto.name), [pyx.text.size.Large]) # noqa: E501 - y += 1 - ptbb = pt.bbox() - ptbb.enlarge(pyx.unit.u_pt * 2) - canvas.stroke(ptbb.path(), [pyx.color.rgb.black, pyx.deco.filled([bkcol])]) # noqa: E501 - canvas.insert(pt) - for field, fval, fdump in fields: - col = next(forecolor) - ft = pyx.text.text(XSTART, (YTXT - y) * YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(field.name)) # noqa: E501 - if isinstance(field, BitField): - fsize = '%sb' % field.size - else: - fsize = '%sB' % len(fdump) - if (hasattr(field, 'field') and - 'LE' in field.field.__class__.__name__[:3] or - 'LE' in field.__class__.__name__[:3]): - fsize = r'$\scriptstyle\langle$' + fsize - st = pyx.text.text(XSTART + 3.4, (YTXT - y) * YMUL, r"\font\cmbxfont=cmssbx10 scaled 600\cmbxfont{%s}" % fsize, [pyx.text.halign.boxright]) # noqa: E501 - if isinstance(fval, str): - if len(fval) > 18: - fval = fval[:18] + "[...]" - else: - fval = "" - vt = pyx.text.text(XSTART + 3.5, (YTXT - y) * YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(fval)) # noqa: E501 - y += 1.0 - if fdump: - dt, target, last_shift, last_y = make_dump(fdump, last_shift, last_y, col, bkcol) # noqa: E501 - - dtb = dt.bbox() - dtb = target - vtb = vt.bbox() - bxvt = make_box(vtb) - bxdt = make_box(dtb) - dtb.enlarge(pyx.unit.u_pt) - try: - if yd < 0: - cnx = pyx.connector.curve(bxvt, bxdt, absangle1=0, absangle2=-90) # noqa: E501 - else: - cnx = pyx.connector.curve(bxvt, bxdt, absangle1=0, absangle2=90) # noqa: E501 - except Exception: - pass - else: - canvas.stroke(cnx, [pyx.style.linewidth.thin, pyx.deco.earrow.small, col]) # noqa: E501 - - canvas.insert(dt) - - canvas.insert(ft) - canvas.insert(st) - canvas.insert(vt) - last_y += layer_shift - - return canvas - - def extract_padding(self, s): - """ - DEV: to be overloaded to extract current layer's padding. - - :param str s: the current layer - :return: a couple of strings (actual layer, padding) - """ - return s, None - - def post_dissect(self, s): - """DEV: is called right after the current layer has been dissected""" - return s - - def pre_dissect(self, s): - """DEV: is called right before the current layer is dissected""" - return s - - def do_dissect(self, s): - if not isinstance(s, bytes): - s = bytes_encode(s) - _raw = s - offset = 0 - self.raw_packet_cache_fields = {} - # Temporary value, used by getfield() in some advanced cases (eg: dot11) # noqa: E501 - _lr = len(_raw) - self._tmp_dissect_pos = 0 # How many bytes have already been dissected - for f in self.fields_desc: - if not s: - break - f._offset = offset - s, fval = f.getfield(self, s) - offset = len(_raw) - (len(s[0]) if type(s) is tuple else len(s)) - if getattr(f, 'passon', False): # fix for DNS - offset += s[1] - self._tmp_dissect_pos = _lr - len(s) - # We need to track fields with mutable values to discard - # .raw_packet_cache when needed. - if f.islist or f.holds_packets or f.ismutable: - self.raw_packet_cache_fields[f.name] = f.do_copy(fval) - self.fields[f.name] = fval - del self._tmp_dissect_pos - self.raw_packet_cache = _raw[:-len(s)] if s else _raw - self.explicit = 1 - return s - - def do_dissect_payload(self, s): - """ - Perform the dissection of the layer's payload - - :param str s: the raw layer - """ - if s: - cls = self.guess_payload_class(s) - try: - p = cls(s, _internal=1, _underlayer=self) - except KeyboardInterrupt: - raise - except Exception: - if conf.debug_dissector: - if issubtype(cls, Packet): - log_runtime.error("%s dissector failed" % cls.__name__) - else: - log_runtime.error("%s.guess_payload_class() returned [%s]" % (self.__class__.__name__, repr(cls))) # noqa: E501 - if cls is not None: - raise - p = conf.raw_layer(s, _internal=1, _underlayer=self) - self.add_payload(p) - - def dissect(self, s): - start_len = len(s) - s = self.pre_dissect(s) - - s = self.do_dissect(s) - self._length = start_len - len(s) - - s = self.post_dissect(s) - - payl, pad = self.extract_padding(s) - self.do_dissect_payload(payl) - if pad and conf.padding: - self.add_payload(conf.padding_layer(pad)) - - def guess_payload_class(self, payload): - """ - DEV: Guesses the next payload class from layer bonds. - Can be overloaded to use a different mechanism. - - :param str payload: the layer's payload - :return: the payload class - """ - for t in self.aliastypes: - for fval, cls in t.payload_guess: - try: - if all(v == self.getfieldval(k) - for k, v in six.iteritems(fval)): - return cls - except AttributeError: - pass - return self.default_payload_class(payload) - - def default_payload_class(self, payload): - """ - DEV: Returns the default payload class if nothing has been found by the - guess_payload_class() method. - - :param str payload: the layer's payload - :return: the default payload class define inside the configuration file - """ - return conf.raw_layer - - def hide_defaults(self): - """Removes fields' values that are the same as default values.""" - # use list(): self.fields is modified in the loop - for k, v in list(six.iteritems(self.fields)): - v = self.fields[k] - if k in self.default_fields: - if self.default_fields[k] == v: - del self.fields[k] - self.payload.hide_defaults() - - def update_sent_time(self, time): - """Use by clone_with to share the sent_time value""" - pass - - def clone_with(self, payload=None, share_time=False, **kargs): - pkt = self.__class__() - pkt.explicit = 1 - pkt.fields = kargs - pkt._offset = self._offset - pkt.default_fields = self.copy_fields_dict(self.default_fields) - pkt.overloaded_fields = self.overloaded_fields.copy() - pkt.time = self.time - pkt.underlayer = self.underlayer - pkt.post_transforms = self.post_transforms - pkt.raw_packet_cache = self.raw_packet_cache - pkt.raw_packet_cache_fields = self.copy_fields_dict( - self.raw_packet_cache_fields - ) - pkt.wirelen = self.wirelen - if payload is not None: - pkt.add_payload(payload) - if share_time: - # This binds the subpacket .sent_time to this layer - def _up_time(x, parent=self): - parent.sent_time = x - pkt.update_sent_time = _up_time - return pkt - - def __iter__(self): - """Iterates through all sub-packets generated by this Packet.""" - # We use __iterlen__ as low as possible, to lower processing time - def loop(todo, done, self=self): - if todo: - eltname = todo.pop() - elt = self.getfieldval(eltname) - if not isinstance(elt, Gen): - if self.get_field(eltname).islist: - elt = SetGen([elt]) - else: - elt = SetGen(elt) - for e in elt: - done[eltname] = e - for x in loop(todo[:], done): - yield x - else: - if isinstance(self.payload, NoPayload): - payloads = SetGen([None]) - else: - payloads = self.payload - share_time = False - if self.fields == done and payloads.__iterlen__() == 1: - # In this case, the packets are identical. Let's bind - # their sent_time attribute for sending purpose - share_time = True - for payl in payloads: - # Let's make sure subpackets are consistent - done2 = done.copy() - for k in done2: - if isinstance(done2[k], VolatileValue): - done2[k] = done2[k]._fix() - pkt = self.clone_with(payload=payl, share_time=share_time, - **done2) - yield pkt - - if self.explicit or self.raw_packet_cache is not None: - todo = [] - done = self.fields - else: - todo = [k for (k, v) in itertools.chain(six.iteritems(self.default_fields), # noqa: E501 - six.iteritems(self.overloaded_fields)) # noqa: E501 - if isinstance(v, VolatileValue)] + list(self.fields) - done = {} - return loop(todo, done) - - def __iterlen__(self): - """Predict the total length of the iterator""" - fields = [key for (key, val) in itertools.chain(six.iteritems(self.default_fields), # noqa: E501 - six.iteritems(self.overloaded_fields)) - if isinstance(val, VolatileValue)] + list(self.fields) - length = 1 - - def is_valid_gen_tuple(x): - if not isinstance(x, tuple): - return False - return len(x) == 2 and all(isinstance(z, int) for z in x) - - for field in fields: - fld, val = self.getfield_and_val(field) - if hasattr(val, "__iterlen__"): - length *= val.__iterlen__() - elif is_valid_gen_tuple(val): - length *= (val[1] - val[0] + 1) - elif isinstance(val, list) and not fld.islist: - len2 = 0 - for x in val: - if hasattr(x, "__iterlen__"): - len2 += x.__iterlen__() - elif is_valid_gen_tuple(x): - len2 += (x[1] - x[0] + 1) - elif isinstance(x, list): - len2 += len(x) - else: - len2 += 1 - length *= len2 or 1 - if not isinstance(self.payload, NoPayload): - return length * self.payload.__iterlen__() - return length - - def iterpayloads(self): - """Used to iter through the paylods of a Packet. - Useful for DNS or 802.11 for instance. - """ - yield self - current = self - while current.payload: - current = current.payload - yield current - - def __gt__(self, other): - """True if other is an answer from self (self ==> other).""" - if isinstance(other, Packet): - return other < self - elif isinstance(other, bytes): - return 1 - else: - raise TypeError((self, other)) - - def __lt__(self, other): - """True if self is an answer from other (other ==> self).""" - if isinstance(other, Packet): - return self.answers(other) - elif isinstance(other, bytes): - return 1 - else: - raise TypeError((self, other)) - - def __eq__(self, other): - if not isinstance(other, self.__class__): - return False - for f in self.fields_desc: - if f not in other.fields_desc: - return False - if self.getfieldval(f.name) != other.getfieldval(f.name): - return False - return self.payload == other.payload - - def __ne__(self, other): - return not self.__eq__(other) - - def hashret(self): - """DEV: returns a string that has the same value for a request - and its answer.""" - return self.payload.hashret() - - def answers(self, other): - """DEV: true if self is an answer from other""" - if other.__class__ == self.__class__: - return self.payload.answers(other.payload) - return 0 - - def layers(self): - """returns a list of layer classes (including subclasses) in this packet""" # noqa: E501 - layers = [] - lyr = self - while lyr: - layers.append(lyr.__class__) - lyr = lyr.payload.getlayer(0, _subclass=True) - return layers - - def haslayer(self, cls): - """true if self has a layer that is an instance of cls. Superseded by "cls in self" syntax.""" # noqa: E501 - if self.__class__ == cls or cls in [self.__class__.__name__, - self._name]: - return True - for f in self.packetfields: - fvalue_gen = self.getfieldval(f.name) - if fvalue_gen is None: - continue - if not f.islist: - fvalue_gen = SetGen(fvalue_gen, _iterpacket=0) - for fvalue in fvalue_gen: - if isinstance(fvalue, Packet): - ret = fvalue.haslayer(cls) - if ret: - return ret - return self.payload.haslayer(cls) - - def getlayer(self, cls, nb=1, _track=None, _subclass=None, **flt): - """Return the nb^th layer that is an instance of cls, matching flt -values. - """ - if _subclass is None: - _subclass = self.match_subclass or None - if _subclass: - match = lambda cls1, cls2: issubclass(cls1, cls2) - else: - match = lambda cls1, cls2: cls1 == cls2 - if isinstance(cls, int): - nb = cls + 1 - cls = None - if isinstance(cls, str) and "." in cls: - ccls, fld = cls.split(".", 1) - else: - ccls, fld = cls, None - if cls is None or match(self.__class__, cls) \ - or ccls in [self.__class__.__name__, self._name]: - if all(self.getfieldval(fldname) == fldvalue - for fldname, fldvalue in six.iteritems(flt)): - if nb == 1: - if fld is None: - return self - else: - return self.getfieldval(fld) - else: - nb -= 1 - for f in self.packetfields: - fvalue_gen = self.getfieldval(f.name) - if fvalue_gen is None: - continue - if not f.islist: - fvalue_gen = SetGen(fvalue_gen, _iterpacket=0) - for fvalue in fvalue_gen: - if isinstance(fvalue, Packet): - track = [] - ret = fvalue.getlayer(cls, nb=nb, _track=track, - _subclass=_subclass, **flt) - if ret is not None: - return ret - nb = track[0] - return self.payload.getlayer(cls, nb=nb, _track=_track, - _subclass=_subclass, **flt) - - def firstlayer(self): - q = self - while q.underlayer is not None: - q = q.underlayer - return q - - def __getitem__(self, cls): - if isinstance(cls, slice): - lname = cls.start - if cls.stop: - ret = self.getlayer(cls.start, nb=cls.stop, **(cls.step or {})) - else: - ret = self.getlayer(cls.start, **(cls.step or {})) - else: - lname = cls - ret = self.getlayer(cls) - if ret is None: - if isinstance(lname, Packet_metaclass): - lname = lname.__name__ - elif not isinstance(lname, bytes): - lname = repr(lname) - raise IndexError("Layer [%s] not found" % lname) - return ret - - def __delitem__(self, cls): - del(self[cls].underlayer.payload) - - def __setitem__(self, cls, val): - self[cls].underlayer.payload = val - - def __contains__(self, cls): - """"cls in self" returns true if self has a layer which is an instance of cls.""" # noqa: E501 - return self.haslayer(cls) - - def route(self): - return self.payload.route() - - def fragment(self, *args, **kargs): - return self.payload.fragment(*args, **kargs) - - def display(self, *args, **kargs): # Deprecated. Use show() - """Deprecated. Use show() method.""" - self.show(*args, **kargs) - - def _show_or_dump(self, dump=False, indent=3, lvl="", label_lvl="", first_call=True): # noqa: E501 - """ - Internal method that shows or dumps a hierarchical view of a packet. - Called by show. - - :param dump: determine if it prints or returns the string value - :param int indent: the size of indentation for each layer - :param str lvl: additional information about the layer lvl - :param str label_lvl: additional information about the layer fields - :param first_call: determine if the current function is the first - :return: return a hierarchical view if dump, else print it - """ - - if dump: - from scapy.themes import AnsiColorTheme - ct = AnsiColorTheme() # No color for dump output - else: - ct = conf.color_theme - s = "%s%s %s %s \n" % (label_lvl, - ct.punct("###["), - ct.layer_name(self.name), - ct.punct("]###")) - for f in self.fields_desc: - if isinstance(f, ConditionalField) and not f._evalcond(self): - continue - if isinstance(f, Emph) or f in conf.emph: - ncol = ct.emph_field_name - vcol = ct.emph_field_value - else: - ncol = ct.field_name - vcol = ct.field_value - fvalue = self.getfieldval(f.name) - if isinstance(fvalue, Packet) or (f.islist and f.holds_packets and isinstance(fvalue, list)): # noqa: E501 - s += "%s \\%-10s\\\n" % (label_lvl + lvl, ncol(f.name)) - fvalue_gen = SetGen(fvalue, _iterpacket=0) - for fvalue in fvalue_gen: - s += fvalue._show_or_dump(dump=dump, indent=indent, label_lvl=label_lvl + lvl + " |", first_call=False) # noqa: E501 - else: - begn = "%s %-10s%s " % (label_lvl + lvl, - ncol(f.name), - ct.punct("="),) - reprval = f.i2repr(self, fvalue) - if isinstance(reprval, str): - reprval = reprval.replace("\n", "\n" + " " * (len(label_lvl) + # noqa: E501 - len(lvl) + - len(f.name) + - 4)) - s += "%s%s\n" % (begn, vcol(reprval)) - if self.payload: - s += self.payload._show_or_dump(dump=dump, indent=indent, lvl=lvl + (" " * indent * self.show_indent), label_lvl=label_lvl, first_call=False) # noqa: E501 - - if first_call and not dump: - print(s) - else: - return s - - def show(self, dump=False, indent=3, lvl="", label_lvl=""): - """ - Prints or returns (when "dump" is true) a hierarchical view of the - packet. - - :param dump: determine if it prints or returns the string value - :param int indent: the size of indentation for each layer - :param str lvl: additional information about the layer lvl - :param str label_lvl: additional information about the layer fields - :return: return a hierarchical view if dump, else print it - """ - return self._show_or_dump(dump, indent, lvl, label_lvl) - - def show2(self, dump=False, indent=3, lvl="", label_lvl=""): - """ - Prints or returns (when "dump" is true) a hierarchical view of an - assembled version of the packet, so that automatic fields are - calculated (checksums, etc.) - - :param dump: determine if it prints or returns the string value - :param int indent: the size of indentation for each layer - :param str lvl: additional information about the layer lvl - :param str label_lvl: additional information about the layer fields - :return: return a hierarchical view if dump, else print it - """ - return self.__class__(raw(self)).show(dump, indent, lvl, label_lvl) - - def sprintf(self, fmt, relax=1): - """sprintf(format, [relax=1]) -> str -where format is a string that can include directives. A directive begins and -ends by % and has the following format %[fmt[r],][cls[:nb].]field%. - -fmt is a classic printf directive, "r" can be appended for raw substitution -(ex: IP.flags=0x18 instead of SA), nb is the number of the layer we want -(ex: for IP/IP packets, IP:2.src is the src of the upper IP layer). -Special case : "%.time%" is the creation time. -Ex : p.sprintf("%.time% %-15s,IP.src% -> %-15s,IP.dst% %IP.chksum% " - "%03xr,IP.proto% %r,TCP.flags%") - -Moreover, the format string can include conditional statements. A conditional -statement looks like : {layer:string} where layer is a layer name, and string -is the string to insert in place of the condition if it is true, i.e. if layer -is present. If layer is preceded by a "!", the result is inverted. Conditions -can be imbricated. A valid statement can be : - p.sprintf("This is a{TCP: TCP}{UDP: UDP}{ICMP:n ICMP} packet") - p.sprintf("{IP:%IP.dst% {ICMP:%ICMP.type%}{TCP:%TCP.dport%}}") - -A side effect is that, to obtain "{" and "}" characters, you must use -"%(" and "%)". -""" - - escape = {"%": "%", - "(": "{", - ")": "}"} - - # Evaluate conditions - while "{" in fmt: - i = fmt.rindex("{") - j = fmt[i + 1:].index("}") - cond = fmt[i + 1:i + j + 1] - k = cond.find(":") - if k < 0: - raise Scapy_Exception("Bad condition in format string: [%s] (read sprintf doc!)" % cond) # noqa: E501 - cond, format_ = cond[:k], cond[k + 1:] - res = False - if cond[0] == "!": - res = True - cond = cond[1:] - if self.haslayer(cond): - res = not res - if not res: - format_ = "" - fmt = fmt[:i] + format_ + fmt[i + j + 2:] - - # Evaluate directives - s = "" - while "%" in fmt: - i = fmt.index("%") - s += fmt[:i] - fmt = fmt[i + 1:] - if fmt and fmt[0] in escape: - s += escape[fmt[0]] - fmt = fmt[1:] - continue - try: - i = fmt.index("%") - sfclsfld = fmt[:i] - fclsfld = sfclsfld.split(",") - if len(fclsfld) == 1: - f = "s" - clsfld = fclsfld[0] - elif len(fclsfld) == 2: - f, clsfld = fclsfld - else: - raise Scapy_Exception - if "." in clsfld: - cls, fld = clsfld.split(".") - else: - cls = self.__class__.__name__ - fld = clsfld - num = 1 - if ":" in cls: - cls, num = cls.split(":") - num = int(num) - fmt = fmt[i + 1:] - except Exception: - raise Scapy_Exception("Bad format string [%%%s%s]" % (fmt[:25], fmt[25:] and "...")) # noqa: E501 - else: - if fld == "time": - val = time.strftime("%H:%M:%S.%%06i", time.localtime(self.time)) % int((self.time - int(self.time)) * 1000000) # noqa: E501 - elif cls == self.__class__.__name__ and hasattr(self, fld): - if num > 1: - val = self.payload.sprintf("%%%s,%s:%s.%s%%" % (f, cls, num - 1, fld), relax) # noqa: E501 - f = "s" - elif f[-1] == "r": # Raw field value - val = getattr(self, fld) - f = f[:-1] - if not f: - f = "s" - else: - val = getattr(self, fld) - if fld in self.fieldtype: - val = self.fieldtype[fld].i2repr(self, val) - else: - val = self.payload.sprintf("%%%s%%" % sfclsfld, relax) - f = "s" - s += ("%" + f) % val - - s += fmt - return s - - def mysummary(self): - """DEV: can be overloaded to return a string that summarizes the layer. - Only one mysummary() is used in a whole packet summary: the one of the upper layer, # noqa: E501 - except if a mysummary() also returns (as a couple) a list of layers whose # noqa: E501 - mysummary() must be called if they are present.""" - return "" - - def _do_summary(self): - found, s, needed = self.payload._do_summary() - ret = "" - if not found or self.__class__ in needed: - ret = self.mysummary() - if isinstance(ret, tuple): - ret, n = ret - needed += n - if ret or needed: - found = 1 - if not ret: - ret = self.__class__.__name__ if self.show_summary else "" - if self.__class__ in conf.emph: - impf = [] - for f in self.fields_desc: - if f in conf.emph: - impf.append("%s=%s" % (f.name, f.i2repr(self, self.getfieldval(f.name)))) # noqa: E501 - ret = "%s [%s]" % (ret, " ".join(impf)) - if ret and s: - ret = "%s / %s" % (ret, s) - else: - ret = "%s%s" % (ret, s) - return found, ret, needed - - def summary(self, intern=0): - """Prints a one line summary of a packet.""" - return self._do_summary()[1] - - def lastlayer(self, layer=None): - """Returns the uppest layer of the packet""" - return self.payload.lastlayer(self) - - def decode_payload_as(self, cls): - """Reassembles the payload and decode it using another packet class""" - s = raw(self.payload) - self.payload = cls(s, _internal=1, _underlayer=self) - pp = self - while pp.underlayer is not None: - pp = pp.underlayer - self.payload.dissection_done(pp) - - def command(self): - """ - Returns a string representing the command you have to type to - obtain the same packet - """ - f = [] - for fn, fv in six.iteritems(self.fields): - fld = self.get_field(fn) - if isinstance(fv, (list, dict, set)) and len(fv) == 0: - continue - if isinstance(fv, Packet): - fv = fv.command() - elif fld.islist and fld.holds_packets and isinstance(fv, list): - fv = "[%s]" % ",".join(map(Packet.command, fv)) - elif isinstance(fld, FlagsField): - fv = int(fv) - else: - fv = repr(fv) - f.append("%s=%s" % (fn, fv)) - c = "%s(%s)" % (self.__class__.__name__, ",".join(f)) - pc = self.payload.command() - if pc: - c += "/" + pc - return c - - def __hash__(self): - """Needed for Python 2 only: Packet() subclasses should not be -hashable. - - """ - raise TypeError('unhashable type: %r' % self.__class__.__name__) - - def convert_to(self, other_cls, **kwargs): - """Converts this Packet to another type. - - This is not guaranteed to be a lossless process. - - By default, this only implements conversion to ``Raw``. - - :param other_cls: Reference to a Packet class to convert to. - :type other_cls: Type[Packet] - :returns: Converted form of the packet. - :rtype: other_cls - :raises TypeError: When conversion is not possible - """ - if not issubtype(other_cls, Packet): - raise TypeError("{} must implement Packet".format(other_cls)) - - if other_cls is Raw: - return Raw(raw(self)) - - if "_internal" not in kwargs: - return other_cls.convert_packet(self, _internal=True, **kwargs) - - raise TypeError("Cannot convert {} to {}".format( - type(self).__name__, other_cls.__name__)) - - @classmethod - def convert_packet(cls, pkt, **kwargs): - """Converts another packet to be this type. - - This is not guaranteed to be a lossless process. - - :param pkt: The packet to convert. - :type pkt: Packet - :returns: Converted form of the packet. - :rtype: cls - :raises TypeError: When conversion is not possible - """ - if not isinstance(pkt, Packet): - raise TypeError("Can only convert Packets") - - if "_internal" not in kwargs: - return pkt.convert_to(cls, _internal=True, **kwargs) - - raise TypeError("Cannot convert {} to {}".format( - type(pkt).__name__, cls.__name__)) - - @classmethod - def convert_packets(cls, pkts, **kwargs): - """Converts many packets to this type. - - This is implemented as a generator. - - See ``Packet.convert_packet``. - """ - for pkt in pkts: - yield cls.convert_packet(pkt, **kwargs) - - -class NoPayload(Packet): - def __new__(cls, *args, **kargs): - singl = cls.__dict__.get("__singl__") - if singl is None: - cls.__singl__ = singl = Packet.__new__(cls) - Packet.__init__(singl) - return singl - - def __init__(self, *args, **kargs): - pass - - def dissection_done(self, pkt): - return - - def add_payload(self, payload): - raise Scapy_Exception("Can't add payload to NoPayload instance") - - def remove_payload(self): - pass - - def add_underlayer(self, underlayer): - pass - - def remove_underlayer(self, other): - pass - - def copy(self): - return self - - def clear_cache(self): - pass - - def __repr__(self): - return "" - - def __str__(self): - return "" - - def __bytes__(self): - return b"" - - def __nonzero__(self): - return False - __bool__ = __nonzero__ - - def do_build(self, result): - return b"" - - def build(self): - return b"" - - def build_padding(self): - return b"" - - def build_done(self, p): - return p - - def build_ps(self, internal=0): - return b"", [] - - def getfieldval(self, attr): - raise AttributeError(attr) - - def getfield_and_val(self, attr): - raise AttributeError(attr) - - def setfieldval(self, attr, val): - raise AttributeError(attr) - - def delfieldval(self, attr): - raise AttributeError(attr) - - def hide_defaults(self): - pass - - def __iter__(self): - return iter([]) - - def __eq__(self, other): - if isinstance(other, NoPayload): - return True - return False - - def hashret(self): - return b"" - - def answers(self, other): - return isinstance(other, NoPayload) or isinstance(other, conf.padding_layer) # noqa: E501 - - def haslayer(self, cls): - return 0 - - def getlayer(self, cls, nb=1, _track=None, **flt): - if _track is not None: - _track.append(nb) - return None - - def fragment(self, *args, **kargs): - raise Scapy_Exception("cannot fragment this packet") - - def show(self, indent=3, lvl="", label_lvl=""): - pass - - def sprintf(self, fmt, relax): - if relax: - return "??" - else: - raise Scapy_Exception("Format not found [%s]" % fmt) - - def _do_summary(self): - return 0, "", [] - - def layers(self): - return [] - - def lastlayer(self, layer): - return layer - - def command(self): - return "" - - def route(self): - return (None, None, None) - - -#################### -# packet classes # -#################### - - -class Raw(Packet): - name = "Raw" - fields_desc = [StrField("load", "")] - - def answers(self, other): - return 1 -# s = raw(other) -# t = self.load -# l = min(len(s), len(t)) -# return s[:l] == t[:l] - - def mysummary(self): - cs = conf.raw_summary - if cs: - if callable(cs): - return "Raw %s" % cs(self.load) - else: - return "Raw %r" % self.load - return Packet.mysummary(self) - - @classmethod - def convert_packet(cls, pkt, **kwargs): - return Raw(raw(pkt)) - - -class Padding(Raw): - name = "Padding" - - def self_build(self): - return b"" - - def build_padding(self): - return (raw(self.load) if self.raw_packet_cache is None - else self.raw_packet_cache) + self.payload.build_padding() - - -conf.raw_layer = Raw -conf.padding_layer = Padding -if conf.default_l2 is None: - conf.default_l2 = Raw - -################# -# Bind layers # -################# - - -def bind_bottom_up(lower, upper, __fval=None, **fval): - """Bind 2 layers for dissection. - The upper layer will be chosen for dissection on top of the lower layer, if - ALL the passed arguments are validated. If multiple calls are made with the same # noqa: E501 - layers, the last one will be used as default. - - ex: - >>> bind_bottom_up(Ether, SNAP, type=0x1234) - >>> Ether(b'\xff\xff\xff\xff\xff\xff\xd0P\x99V\xdd\xf9\x124\x00\x00\x00\x00\x00') # noqa: E501 - > # noqa: E501 - """ - if __fval is not None: - fval.update(__fval) - lower.payload_guess = lower.payload_guess[:] - lower.payload_guess.append((fval, upper)) - - -def bind_top_down(lower, upper, __fval=None, **fval): - """Bind 2 layers for building. - When the upper layer is added as a payload of the lower layer, all the arguments # noqa: E501 - will be applied to them. - - ex: - >>> bind_top_down(Ether, SNAP, type=0x1234) - >>> Ether()/SNAP() - > - """ - if __fval is not None: - fval.update(__fval) - upper._overload_fields = upper._overload_fields.copy() - upper._overload_fields[lower] = fval - - -@conf.commands.register -def bind_layers(lower, upper, __fval=None, **fval): - """Bind 2 layers on some specific fields' values. - - It makes the packet being built and dissected when the arguments - are present. - - This function calls both bind_bottom_up and bind_top_down, with - all passed arguments. - - Please have a look at their docs: - - help(bind_bottom_up) - - help(bind_top_down) - """ - if __fval is not None: - fval.update(__fval) - bind_top_down(lower, upper, **fval) - bind_bottom_up(lower, upper, **fval) - - -def split_bottom_up(lower, upper, __fval=None, **fval): - """This call un-links an association that was made using bind_bottom_up. - Have a look at help(bind_bottom_up) - """ - if __fval is not None: - fval.update(__fval) - - def do_filter(params, cls): - params_is_invalid = any( - k not in params or params[k] != v for k, v in six.iteritems(fval) - ) - return cls != upper or params_is_invalid - lower.payload_guess = [x for x in lower.payload_guess if do_filter(*x)] - - -def split_top_down(lower, upper, __fval=None, **fval): - """This call un-links an association that was made using bind_top_down. - Have a look at help(bind_top_down) - """ - if __fval is not None: - fval.update(__fval) - if lower in upper._overload_fields: - ofval = upper._overload_fields[lower] - if any(k not in ofval or ofval[k] != v for k, v in six.iteritems(fval)): # noqa: E501 - return - upper._overload_fields = upper._overload_fields.copy() - del(upper._overload_fields[lower]) - - -@conf.commands.register -def split_layers(lower, upper, __fval=None, **fval): - """Split 2 layers previously bound. - This call un-links calls bind_top_down and bind_bottom_up. It is the opposite of # noqa: E501 - bind_layers. - - Please have a look at their docs: - - help(split_bottom_up) - - help(split_top_down) - """ - if __fval is not None: - fval.update(__fval) - split_bottom_up(lower, upper, **fval) - split_top_down(lower, upper, **fval) - - -@conf.commands.register -def explore(layer=None): - """Function used to discover the Scapy layers and protocols. - It helps to see which packets exists in contrib or layer files. - - params: - - layer: If specified, the function will explore the layer. If not, - the GUI mode will be activated, to browse the available layers - - examples: - >>> explore() # Launches the GUI - >>> explore("dns") # Explore scapy.layers.dns - >>> explore("http2") # Explore scapy.contrib.http2 - >>> explore(scapy.layers.bluetooth4LE) - - Note: to search a packet by name, use ls("name") rather than explore. - """ - if layer is None: # GUI MODE - if not conf.interactive: - raise Scapy_Exception("explore() GUI-mode cannot be run in " - "interactive mode. Please provide a " - "'layer' parameter !") - # 0 - Imports - try: - import prompt_toolkit - except ImportError: - raise ImportError("prompt_toolkit is not installed ! " - "You may install IPython, which contains it, via" - " `pip install ipython`") - if not _version_checker(prompt_toolkit, (2, 0)): - raise ImportError("prompt_toolkit >= 2.0.0 is required !") - # Only available with prompt_toolkit > 2.0, not released on PyPi yet - from prompt_toolkit.shortcuts.dialogs import radiolist_dialog, \ - button_dialog - from prompt_toolkit.formatted_text import HTML - # Check for prompt_toolkit >= 3.0.0 - if _version_checker(prompt_toolkit, (3, 0)): - call_ptk = lambda x: x.run() - else: - call_ptk = lambda x: x - # 1 - Ask for layer or contrib - btn_diag = button_dialog( - title="Scapy v%s" % conf.version, - text=HTML( - six.text_type( - '' - ) - ), - buttons=[ - (six.text_type("Layers"), "layers"), - (six.text_type("Contribs"), "contribs"), - (six.text_type("Cancel"), "cancel") - ]) - action = call_ptk(btn_diag) - # 2 - Retrieve list of Packets - if action == "layers": - # Get all loaded layers - _radio_values = conf.layers.layers() - # Restrict to layers-only (not contribs) + packet.py and asn1*.py - _radio_values = [x for x in _radio_values if ("layers" in x[0] or - "packet" in x[0] or - "asn1" in x[0])] - elif action == "contribs": - # Get all existing contribs - from scapy.main import list_contrib - _radio_values = list_contrib(ret=True) - _radio_values = [(x['name'], x['description']) - for x in _radio_values] - # Remove very specific modules - _radio_values = [x for x in _radio_values if not ("can" in x[0])] - else: - # Escape/Cancel was pressed - return - # Python 2 compat - if six.PY2: - _radio_values = [(six.text_type(x), six.text_type(y)) - for x, y in _radio_values] - # 3 - Ask for the layer/contrib module to explore - rd_diag = radiolist_dialog( - values=_radio_values, - title="Scapy v%s" % conf.version, - text=HTML( - six.text_type( - '' - ) - )) - result = call_ptk(rd_diag) - if result is None: - return # User pressed "Cancel" - # 4 - (Contrib only): load contrib - if action == "contribs": - from scapy.main import load_contrib - load_contrib(result) - result = "scapy.contrib." + result - else: # NON-GUI MODE - # We handle layer as a short layer name, full layer name - # or the module itself - if isinstance(layer, types.ModuleType): - layer = layer.__name__ - if isinstance(layer, str): - if layer.startswith("scapy.layers."): - result = layer - else: - if layer.startswith("scapy.contrib."): - layer = layer.replace("scapy.contrib.", "") - from scapy.main import load_contrib - load_contrib(layer) - result_layer, result_contrib = (("scapy.layers.%s" % layer), - ("scapy.contrib.%s" % layer)) - if result_layer in conf.layers.ldict: - result = result_layer - elif result_contrib in conf.layers.ldict: - result = result_contrib - else: - raise Scapy_Exception("Unknown scapy module '%s'" % layer) - else: - warning("Wrong usage ! Check out help(explore)") - return - - # COMMON PART - # Get the list of all Packets contained in that module - try: - all_layers = conf.layers.ldict[result] - except KeyError: - raise Scapy_Exception("Unknown scapy module '%s'" % layer) - # Print - print(conf.color_theme.layer_name("Packets contained in %s:" % result)) - rtlst = [(lay.__name__ or "", lay._name or "") for lay in all_layers] - print(pretty_list(rtlst, [("Class", "Name")], borders=True)) - - -@conf.commands.register -def ls(obj=None, case_sensitive=False, verbose=False): - """List available layers, or infos on a given layer class or name. - params: - - obj: Packet / packet name to use - - case_sensitive: if obj is a string, is it case sensitive? - - verbose - """ - is_string = isinstance(obj, six.string_types) - - if obj is None or is_string: - tip = False - if obj is None: - tip = True - all_layers = sorted(conf.layers, key=lambda x: x.__name__) - else: - pattern = re.compile(obj, 0 if case_sensitive else re.I) - # We first order by accuracy, then length - if case_sensitive: - sorter = lambda x: (x.__name__.index(obj), len(x.__name__)) - else: - obj = obj.lower() - sorter = lambda x: (x.__name__.lower().index(obj), - len(x.__name__)) - all_layers = sorted((layer for layer in conf.layers - if (isinstance(layer.__name__, str) and - pattern.search(layer.__name__)) or - (isinstance(layer.name, str) and - pattern.search(layer.name))), - key=sorter) - for layer in all_layers: - print("%-10s : %s" % (layer.__name__, layer._name)) - if tip and conf.interactive: - print("\nTIP: You may use explore() to navigate through all " - "layers using a clear GUI") - else: - is_pkt = isinstance(obj, Packet) - if issubtype(obj, Packet) or is_pkt: - for f in obj.fields_desc: - cur_fld = f - attrs = [] - long_attrs = [] - while isinstance(cur_fld, (Emph, ConditionalField)): - if isinstance(cur_fld, ConditionalField): - attrs.append(cur_fld.__class__.__name__[:4]) - cur_fld = cur_fld.fld - if verbose and isinstance(cur_fld, EnumField) \ - and hasattr(cur_fld, "i2s"): - if len(cur_fld.i2s) < 50: - long_attrs.extend( - "%s: %d" % (strval, numval) - for numval, strval in - sorted(six.iteritems(cur_fld.i2s)) - ) - elif isinstance(cur_fld, MultiEnumField): - fld_depend = cur_fld.depends_on(obj.__class__ - if is_pkt else obj) - attrs.append("Depends on %s" % fld_depend.name) - if verbose: - cur_i2s = cur_fld.i2s_multi.get( - cur_fld.depends_on(obj if is_pkt else obj()), {} - ) - if len(cur_i2s) < 50: - long_attrs.extend( - "%s: %d" % (strval, numval) - for numval, strval in - sorted(six.iteritems(cur_i2s)) - ) - elif verbose and isinstance(cur_fld, FlagsField): - names = cur_fld.names - long_attrs.append(", ".join(names)) - class_name = "%s (%s)" % ( - cur_fld.__class__.__name__, - ", ".join(attrs)) if attrs else cur_fld.__class__.__name__ - if isinstance(cur_fld, BitField): - class_name += " (%d bit%s)" % (cur_fld.size, - "s" if cur_fld.size > 1 - else "") - print("%-10s : %-35s =" % (f.name, class_name), end=' ') - if is_pkt: - print("%-15r" % (getattr(obj, f.name),), end=' ') - print("(%r)" % (f.default,)) - for attr in long_attrs: - print("%-15s%s" % ("", attr)) - if is_pkt and not isinstance(obj.payload, NoPayload): - print("--") - ls(obj.payload) - - else: - print("Not a packet class or name. Type 'ls()' to list packet classes.") # noqa: E501 - - -############# -# Fuzzing # -############# - -@conf.commands.register -def fuzz(p, _inplace=0): - """ - Transform a layer into a fuzzy layer by replacing some default values - by random objects. - - :param p: the Packet instance to fuzz - :returns: the fuzzed packet. - """ - if not _inplace: - p = p.copy() - q = p - while not isinstance(q, NoPayload): - new_default_fields = {} - multiple_type_fields = [] - for f in q.fields_desc: - if isinstance(f, PacketListField): - for r in getattr(q, f.name): - print("fuzzing", repr(r)) - fuzz(r, _inplace=1) - elif isinstance(f, MultipleTypeField): - # the type of the field will depend on others - multiple_type_fields.append(f.name) - elif f.default is not None: - if not isinstance(f, ConditionalField) or f._evalcond(q): - rnd = f.randval() - if rnd is not None: - new_default_fields[f.name] = rnd - # Process packets with MultipleTypeFields - if multiple_type_fields: - # freeze the other random values - new_default_fields = { - key: (val._fix() if isinstance(val, VolatileValue) else val) - for key, val in six.iteritems(new_default_fields) - } - q.default_fields.update(new_default_fields) - # add the random values of the MultipleTypeFields - for name in multiple_type_fields: - rnd = q.get_field(name)._find_fld_pkt(q).randval() - if rnd is not None: - new_default_fields[name] = rnd - q.default_fields.update(new_default_fields) - q = q.payload - return p diff --git a/scripts/external_libs/scapy-2.4.3/scapy/pipetool.py b/scripts/external_libs/scapy-2.4.3/scapy/pipetool.py deleted file mode 100644 index 38a9dfa8b7..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/pipetool.py +++ /dev/null @@ -1,714 +0,0 @@ -#! /usr/bin/env python - -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -from __future__ import print_function -import os -import subprocess -import collections -import time -import scapy.modules.six as six -from threading import Lock, Thread - -from scapy.automaton import Message, select_objects, SelectableObject -from scapy.consts import WINDOWS -from scapy.error import log_interactive, warning -from scapy.config import conf -from scapy.utils import get_temp_file, do_graph - - -class PipeEngine(SelectableObject): - pipes = {} - - @classmethod - def list_pipes(cls): - for pn, pc in sorted(cls.pipes.items()): - doc = pc.__doc__ or "" - if doc: - doc = doc.splitlines()[0] - print("%20s: %s" % (pn, doc)) - - @classmethod - def list_pipes_detailed(cls): - for pn, pc in sorted(cls.pipes.items()): - if pc.__doc__: - print("###### %s\n %s" % (pn, pc.__doc__)) - else: - print("###### %s" % pn) - - def __init__(self, *pipes): - self.active_pipes = set() - self.active_sources = set() - self.active_drains = set() - self.active_sinks = set() - self._add_pipes(*pipes) - self.thread_lock = Lock() - self.command_lock = Lock() - self.__fd_queue = collections.deque() - self.__fdr, self.__fdw = os.pipe() - self.thread = None - SelectableObject.__init__(self) - - def __getattr__(self, attr): - if attr.startswith("spawn_"): - dname = attr[6:] - if dname in self.pipes: - def f(*args, **kargs): - k = self.pipes[dname] - p = k(*args, **kargs) - self.add(p) - return p - return f - raise AttributeError(attr) - - def check_recv(self): - """As select.select is not available, we check if there - is some data to read by using a list that stores pointers.""" - return len(self.__fd_queue) > 0 - - def fileno(self): - return self.__fdr - - def _read_cmd(self): - os.read(self.__fdr, 1) - return self.__fd_queue.popleft() - - def _write_cmd(self, _cmd): - self.__fd_queue.append(_cmd) - os.write(self.__fdw, b"X") - self.call_release() - - def add_one_pipe(self, pipe): - self.active_pipes.add(pipe) - if isinstance(pipe, Source): - self.active_sources.add(pipe) - if isinstance(pipe, Drain): - self.active_drains.add(pipe) - if isinstance(pipe, Sink): - self.active_sinks.add(pipe) - - def get_pipe_list(self, pipe): - def flatten(p, l): - l.add(p) - for q in p.sources | p.sinks | p.high_sources | p.high_sinks: - if q not in l: - flatten(q, l) - pl = set() - flatten(pipe, pl) - return pl - - def _add_pipes(self, *pipes): - pl = set() - for p in pipes: - pl |= self.get_pipe_list(p) - pl -= self.active_pipes - for q in pl: - self.add_one_pipe(q) - return pl - - def run(self): - log_interactive.info("Pipe engine thread started.") - try: - for p in self.active_pipes: - p.start() - sources = self.active_sources - sources.add(self) - exhausted = set([]) - RUN = True - STOP_IF_EXHAUSTED = False - while RUN and (not STOP_IF_EXHAUSTED or len(sources) > 1): - fds = select_objects(sources, 2) - for fd in fds: - if fd is self: - cmd = self._read_cmd() - if cmd == "X": - RUN = False - break - elif cmd == "B": - STOP_IF_EXHAUSTED = True - elif cmd == "A": - sources = self.active_sources - exhausted - sources.add(self) - else: - warning("Unknown internal pipe engine command: %r. Ignoring." % cmd) # noqa: E501 - elif fd in sources: - try: - fd.deliver() - except Exception as e: - log_interactive.exception("piping from %s failed: %s" % (fd.name, e)) # noqa: E501 - else: - if fd.exhausted(): - exhausted.add(fd) - sources.remove(fd) - except KeyboardInterrupt: - pass - finally: - try: - for p in self.active_pipes: - p.stop() - finally: - self.thread_lock.release() - log_interactive.info("Pipe engine thread stopped.") - - def start(self): - if self.thread_lock.acquire(0): - _t = Thread(target=self.run) - _t.setDaemon(True) - _t.start() - self.thread = _t - else: - warning("Pipe engine already running") - - def wait_and_stop(self): - self.stop(_cmd="B") - - def stop(self, _cmd="X"): - try: - with self.command_lock: - if self.thread is not None: - self._write_cmd(_cmd) - self.thread.join() - try: - self.thread_lock.release() - except Exception: - pass - else: - warning("Pipe engine thread not running") - except KeyboardInterrupt: - print("Interrupted by user.") - - def add(self, *pipes): - pipes = self._add_pipes(*pipes) - with self.command_lock: - if self.thread is not None: - for p in pipes: - p.start() - self._write_cmd("A") - - def graph(self, **kargs): - g = ['digraph "pipe" {', "\tnode [shape=rectangle];", ] - for p in self.active_pipes: - g.append('\t"%i" [label="%s"];' % (id(p), p.name)) - g.append("") - g.append("\tedge [color=blue, arrowhead=vee];") - for p in self.active_pipes: - for q in p.sinks: - g.append('\t"%i" -> "%i";' % (id(p), id(q))) - g.append("") - g.append("\tedge [color=purple, arrowhead=veevee];") - for p in self.active_pipes: - for q in p.high_sinks: - g.append('\t"%i" -> "%i";' % (id(p), id(q))) - g.append("") - g.append("\tedge [color=red, arrowhead=diamond];") - for p in self.active_pipes: - for q in p.trigger_sinks: - g.append('\t"%i" -> "%i";' % (id(p), id(q))) - g.append('}') - graph = "\n".join(g) - do_graph(graph, **kargs) - - -class _ConnectorLogic(object): - def __init__(self): - self.sources = set() - self.sinks = set() - self.high_sources = set() - self.high_sinks = set() - self.trigger_sources = set() - self.trigger_sinks = set() - - def __lt__(self, other): - other.sinks.add(self) - self.sources.add(other) - return other - - def __gt__(self, other): - self.sinks.add(other) - other.sources.add(self) - return other - - def __eq__(self, other): - self > other - other > self - return other - - def __lshift__(self, other): - self.high_sources.add(other) - other.high_sinks.add(self) - return other - - def __rshift__(self, other): - self.high_sinks.add(other) - other.high_sources.add(self) - return other - - def __floordiv__(self, other): - self >> other - other >> self - return other - - def __xor__(self, other): - self.trigger_sinks.add(other) - other.trigger_sources.add(self) - return other - - def __hash__(self): - return object.__hash__(self) - - -class _PipeMeta(type): - def __new__(cls, name, bases, dct): - c = type.__new__(cls, name, bases, dct) - PipeEngine.pipes[name] = c - return c - - -class Pipe(six.with_metaclass(_PipeMeta, _ConnectorLogic)): - def __init__(self, name=None): - _ConnectorLogic.__init__(self) - if name is None: - name = "%s" % (self.__class__.__name__) - self.name = name - - def _send(self, msg): - for s in self.sinks: - s.push(msg) - - def _high_send(self, msg): - for s in self.high_sinks: - s.high_push(msg) - - def _trigger(self, msg=None): - for s in self.trigger_sinks: - s.on_trigger(msg) - - def __repr__(self): - ct = conf.color_theme - s = "%s%s" % (ct.punct("<"), ct.layer_name(self.name)) - if self.sources or self.sinks: - s += " %s" % ct.punct("[") - if self.sources: - s += "%s%s" % (ct.punct(",").join(ct.field_name(s.name) for s in self.sources), # noqa: E501 - ct.field_value(">")) - s += ct.layer_name("#") - if self.sinks: - s += "%s%s" % (ct.field_value(">"), - ct.punct(",").join(ct.field_name(s.name) for s in self.sinks)) # noqa: E501 - s += ct.punct("]") - - if self.high_sources or self.high_sinks: - s += " %s" % ct.punct("[") - if self.high_sources: - s += "%s%s" % (ct.punct(",").join(ct.field_name(s.name) for s in self.high_sources), # noqa: E501 - ct.field_value(">>")) - s += ct.layer_name("#") - if self.high_sinks: - s += "%s%s" % (ct.field_value(">>"), - ct.punct(",").join(ct.field_name(s.name) for s in self.high_sinks)) # noqa: E501 - s += ct.punct("]") - - if self.trigger_sources or self.trigger_sinks: - s += " %s" % ct.punct("[") - if self.trigger_sources: - s += "%s%s" % (ct.punct(",").join(ct.field_name(s.name) for s in self.trigger_sources), # noqa: E501 - ct.field_value("^")) - s += ct.layer_name("#") - if self.trigger_sinks: - s += "%s%s" % (ct.field_value("^"), - ct.punct(",").join(ct.field_name(s.name) for s in self.trigger_sinks)) # noqa: E501 - s += ct.punct("]") - - s += ct.punct(">") - return s - - -class Source(Pipe, SelectableObject): - def __init__(self, name=None): - Pipe.__init__(self, name=name) - SelectableObject.__init__(self) - self.is_exhausted = False - - def _read_message(self): - return Message() - - def deliver(self): - msg = self._read_message - self._send(msg) - - def fileno(self): - return None - - def check_recv(self): - return False - - def exhausted(self): - return self.is_exhausted - - def start(self): - pass - - def stop(self): - pass - - -class Drain(Pipe): - """Repeat messages from low/high entries to (resp.) low/high exits - +-------+ - >>-|-------|->> - | | - >-|-------|-> - +-------+ -""" - - def push(self, msg): - self._send(msg) - - def high_push(self, msg): - self._high_send(msg) - - def start(self): - pass - - def stop(self): - pass - - -class Sink(Pipe): - def push(self, msg): - pass - - def high_push(self, msg): - pass - - def start(self): - pass - - def stop(self): - pass - - -class AutoSource(Source, SelectableObject): - def __init__(self, name=None): - SelectableObject.__init__(self) - Source.__init__(self, name=name) - self.__fdr, self.__fdw = os.pipe() - self._queue = collections.deque() - - def fileno(self): - return self.__fdr - - def check_recv(self): - return len(self._queue) > 0 - - def _gen_data(self, msg): - self._queue.append((msg, False)) - self._wake_up() - - def _gen_high_data(self, msg): - self._queue.append((msg, True)) - self._wake_up() - - def _wake_up(self): - os.write(self.__fdw, b"X") - self.call_release() - - def deliver(self): - os.read(self.__fdr, 1) - try: - msg, high = self._queue.popleft() - except IndexError: # empty queue. Exhausted source - pass - else: - if high: - self._high_send(msg) - else: - self._send(msg) - - -class ThreadGenSource(AutoSource): - def __init__(self, name=None): - AutoSource.__init__(self, name=name) - self.RUN = False - - def generate(self): - pass - - def start(self): - self.RUN = True - Thread(target=self.generate).start() - - def stop(self): - self.RUN = False - - -class ConsoleSink(Sink): - """Print messages on low and high entries - +-------+ - >>-|--. |->> - | print | - >-|--' |-> - +-------+ -""" - - def push(self, msg): - print(">%r" % msg) - - def high_push(self, msg): - print(">>%r" % msg) - - -class RawConsoleSink(Sink): - """Print messages on low and high entries, using os.write - +-------+ - >>-|--. |->> - | write | - >-|--' |-> - +-------+ -""" - - def __init__(self, name=None, newlines=True): - Sink.__init__(self, name=name) - self.newlines = newlines - self._write_pipe = 1 - - def push(self, msg): - if self.newlines: - msg += "\n" - os.write(self._write_pipe, msg.encode("utf8")) - - def high_push(self, msg): - if self.newlines: - msg += "\n" - os.write(self._write_pipe, msg.encode("utf8")) - - -class CLIFeeder(AutoSource): - """Send messages from python command line - +--------+ - >>-| |->> - | send() | - >-| `----|-> - +--------+ -""" - - def send(self, msg): - self._gen_data(msg) - - def close(self): - self.is_exhausted = True - - -class CLIHighFeeder(CLIFeeder): - """Send messages from python command line to high output - +--------+ - >>-| .----|->> - | send() | - >-| |-> - +--------+ -""" - - def send(self, msg): - self._gen_high_data(msg) - - -class PeriodicSource(ThreadGenSource): - """Generage messages periodically on low exit - +-------+ - >>-| |->> - | msg,T | - >-| `----|-> - +-------+ -""" - - def __init__(self, msg, period, period2=0, name=None): - ThreadGenSource.__init__(self, name=name) - if not isinstance(msg, (list, set, tuple)): - msg = [msg] - self.msg = msg - self.period = period - self.period2 = period2 - - def generate(self): - while self.RUN: - empty_gen = True - for m in self.msg: - empty_gen = False - self._gen_data(m) - time.sleep(self.period) - if empty_gen: - self.is_exhausted = True - self._wake_up() - time.sleep(self.period2) - - -class TermSink(Sink): - """Print messages on low and high entries on a separate terminal - +-------+ - >>-|--. |->> - | print | - >-|--' |-> - +-------+ -""" - - def __init__(self, name=None, keepterm=True, newlines=True, openearly=True): # noqa: E501 - Sink.__init__(self, name=name) - self.keepterm = keepterm - self.newlines = newlines - self.openearly = openearly - self.opened = False - if self.openearly: - self.start() - - def _start_windows(self): - if not self.opened: - self.opened = True - self.__f = get_temp_file() - open(self.__f, "a").close() - self.name = "Scapy" if self.name is None else self.name - # Start a powershell in a new window and print the PID - cmd = "$app = Start-Process PowerShell -ArgumentList '-command &{$host.ui.RawUI.WindowTitle=\\\"%s\\\";Get-Content \\\"%s\\\" -wait}' -passthru; echo $app.Id" % (self.name, self.__f.replace("\\", "\\\\")) # noqa: E501 - proc = subprocess.Popen([conf.prog.powershell, cmd], stdout=subprocess.PIPE) # noqa: E501 - output, _ = proc.communicate() - # This is the process PID - self.pid = int(output) - print("PID: %d" % self.pid) - - def _start_unix(self): - if not self.opened: - self.opened = True - rdesc, self.wdesc = os.pipe() - cmd = ["xterm"] - if self.name is not None: - cmd.extend(["-title", self.name]) - if self.keepterm: - cmd.append("-hold") - cmd.extend(["-e", "cat <&%d" % rdesc]) - self.proc = subprocess.Popen(cmd, close_fds=False) - os.close(rdesc) - - def start(self): - if WINDOWS: - return self._start_windows() - else: - return self._start_unix() - - def _stop_windows(self): - if not self.keepterm: - self.opened = False - # Recipe to kill process with PID - # http://code.activestate.com/recipes/347462-terminating-a-subprocess-on-windows/ - import ctypes - PROCESS_TERMINATE = 1 - handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, self.pid) # noqa: E501 - ctypes.windll.kernel32.TerminateProcess(handle, -1) - ctypes.windll.kernel32.CloseHandle(handle) - - def _stop_unix(self): - if not self.keepterm: - self.opened = False - self.proc.kill() - self.proc.wait() - - def stop(self): - if WINDOWS: - return self._stop_windows() - else: - return self._stop_unix() - - def _print(self, s): - if self.newlines: - s += "\n" - if WINDOWS: - wdesc = open(self.__f, "a") - wdesc.write(s) - wdesc.close() - else: - os.write(self.wdesc, s.encode()) - - def push(self, msg): - self._print(str(msg)) - - def high_push(self, msg): - self._print(str(msg)) - - -class QueueSink(Sink): - """Collect messages from high and low entries and queue them. Messages are unqueued with the .recv() method. # noqa: E501 - +-------+ - >>-|--. |->> - | queue | - >-|--' |-> - +-------+ -""" - - def __init__(self, name=None): - Sink.__init__(self, name=name) - self.q = six.moves.queue.Queue() - - def push(self, msg): - self.q.put(msg) - - def high_push(self, msg): - self.q.put(msg) - - def recv(self, block=True, timeout=None): - try: - return self.q.get(block=block, timeout=timeout) - except six.moves.queue.Empty: - pass - - -class TransformDrain(Drain): - """Apply a function to messages on low and high entry - +-------+ - >>-|--[f]--|->> - | | - >-|--[f]--|-> - +-------+ -""" - - def __init__(self, f, name=None): - Drain.__init__(self, name=name) - self.f = f - - def push(self, msg): - self._send(self.f(msg)) - - def high_push(self, msg): - self._high_send(self.f(msg)) - - -class UpDrain(Drain): - """Repeat messages from low entry to high exit - +-------+ - >>-| ,--|->> - | / | - >-|--' |-> - +-------+ -""" - - def push(self, msg): - self._high_send(msg) - - def high_push(self, msg): - pass - - -class DownDrain(Drain): - r"""Repeat messages from high entry to low exit - +-------+ - >>-|--. |->> - | \ | - >-| `--|-> - +-------+ -""" - - def push(self, msg): - pass - - def high_push(self, msg): - self._send(msg) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/plist.py b/scripts/external_libs/scapy-2.4.3/scapy/plist.py deleted file mode 100644 index 74257f0dc0..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/plist.py +++ /dev/null @@ -1,648 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -PacketList: holds several packets and allows to do operations on them. -""" - - -from __future__ import absolute_import -from __future__ import print_function -import os -from collections import defaultdict - -from scapy.compat import lambda_tuple_converter -from scapy.config import conf -from scapy.base_classes import BasePacket, BasePacketList, _CanvasDumpExtended -from scapy.utils import do_graph, hexdump, make_table, make_lined_table, \ - make_tex_table, issubtype -from scapy.extlib import plt, MATPLOTLIB_INLINED, MATPLOTLIB_DEFAULT_PLOT_KARGS -from functools import reduce -import scapy.modules.six as six -from scapy.modules.six.moves import range, zip - -############# -# Results # -############# - - -class PacketList(BasePacketList, _CanvasDumpExtended): - __slots__ = ["stats", "res", "listname"] - - def __init__(self, res=None, name="PacketList", stats=None): - """create a packet list from a list of packets - res: the list of packets - stats: a list of classes that will appear in the stats (defaults to [TCP,UDP,ICMP])""" # noqa: E501 - if stats is None: - stats = conf.stats_classic_protocols - self.stats = stats - if res is None: - res = [] - elif isinstance(res, PacketList): - res = res.res - self.res = res - self.listname = name - - def __len__(self): - return len(self.res) - - def _elt2pkt(self, elt): - return elt - - def _elt2sum(self, elt): - return elt.summary() - - def _elt2show(self, elt): - return self._elt2sum(elt) - - def __repr__(self): - stats = {x: 0 for x in self.stats} - other = 0 - for r in self.res: - f = 0 - for p in stats: - if self._elt2pkt(r).haslayer(p): - stats[p] += 1 - f = 1 - break - if not f: - other += 1 - s = "" - ct = conf.color_theme - for p in self.stats: - s += " %s%s%s" % (ct.packetlist_proto(p._name), - ct.punct(":"), - ct.packetlist_value(stats[p])) - s += " %s%s%s" % (ct.packetlist_proto("Other"), - ct.punct(":"), - ct.packetlist_value(other)) - return "%s%s%s%s%s" % (ct.punct("<"), - ct.packetlist_name(self.listname), - ct.punct(":"), - s, - ct.punct(">")) - - def __getstate__(self): - """ - create a basic representation of the instance, used in conjunction with __setstate__() e.g. by pickle # noqa: E501 - :return: dict representing this instance - """ - state = { - 'res': self.res, - 'stats': self.stats, - 'listname': self.listname - } - return state - - def __setstate__(self, state): - """ - set instance attributes to values given by state, used in conjunction with __getstate__() e.g. by pickle # noqa: E501 - :param state: dict representing this instance - """ - self.res = state['res'] - self.stats = state['stats'] - self.listname = state['listname'] - - def __getattr__(self, attr): - return getattr(self.res, attr) - - def __getitem__(self, item): - if issubtype(item, BasePacket): - return self.__class__([x for x in self.res if item in self._elt2pkt(x)], # noqa: E501 - name="%s from %s" % (item.__name__, self.listname)) # noqa: E501 - if isinstance(item, slice): - return self.__class__(self.res.__getitem__(item), - name="mod %s" % self.listname) - return self.res.__getitem__(item) - - def __getslice__(self, *args, **kargs): - return self.__class__(self.res.__getslice__(*args, **kargs), - name="mod %s" % self.listname) - - def __add__(self, other): - return self.__class__(self.res + other.res, - name="%s+%s" % (self.listname, other.listname)) - - def summary(self, prn=None, lfilter=None): - """prints a summary of each packet -prn: function to apply to each packet instead of lambda x:x.summary() -lfilter: truth function to apply to each packet to decide whether it will be displayed""" # noqa: E501 - for r in self.res: - if lfilter is not None: - if not lfilter(r): - continue - if prn is None: - print(self._elt2sum(r)) - else: - print(prn(r)) - - def nsummary(self, prn=None, lfilter=None): - """prints a summary of each packet with the packet's number -prn: function to apply to each packet instead of lambda x:x.summary() -lfilter: truth function to apply to each packet to decide whether it will be displayed""" # noqa: E501 - for i, res in enumerate(self.res): - if lfilter is not None: - if not lfilter(res): - continue - print(conf.color_theme.id(i, fmt="%04i"), end=' ') - if prn is None: - print(self._elt2sum(res)) - else: - print(prn(res)) - - def display(self): # Deprecated. Use show() - """deprecated. is show()""" - self.show() - - def show(self, *args, **kargs): - """Best way to display the packet list. Defaults to nsummary() method""" # noqa: E501 - return self.nsummary(*args, **kargs) - - def filter(self, func): - """Returns a packet list filtered by a truth function. This truth - function has to take a packet as the only argument and return a boolean value.""" # noqa: E501 - return self.__class__([x for x in self.res if func(x)], - name="filtered %s" % self.listname) - - def make_table(self, *args, **kargs): - """Prints a table using a function that returns for each packet its head column value, head row value and displayed value # noqa: E501 - ex: p.make_table(lambda x:(x[IP].dst, x[TCP].dport, x[TCP].sprintf("%flags%")) """ # noqa: E501 - return make_table(self.res, *args, **kargs) - - def make_lined_table(self, *args, **kargs): - """Same as make_table, but print a table with lines""" - return make_lined_table(self.res, *args, **kargs) - - def make_tex_table(self, *args, **kargs): - """Same as make_table, but print a table with LaTeX syntax""" - return make_tex_table(self.res, *args, **kargs) - - def plot(self, f, lfilter=None, plot_xy=False, **kargs): - """Applies a function to each packet to get a value that will be plotted - with matplotlib. A list of matplotlib.lines.Line2D is returned. - - lfilter: a truth function that decides whether a packet must be plotted - """ - - # Python 2 backward compatibility - f = lambda_tuple_converter(f) - lfilter = lambda_tuple_converter(lfilter) - - # Get the list of packets - if lfilter is None: - lst_pkts = [f(*e) for e in self.res] - else: - lst_pkts = [f(*e) for e in self.res if lfilter(*e)] - - # Mimic the default gnuplot output - if kargs == {}: - kargs = MATPLOTLIB_DEFAULT_PLOT_KARGS - if plot_xy: - lines = plt.plot(*zip(*lst_pkts), **kargs) - else: - lines = plt.plot(lst_pkts, **kargs) - - # Call show() if matplotlib is not inlined - if not MATPLOTLIB_INLINED: - plt.show() - - return lines - - def diffplot(self, f, delay=1, lfilter=None, **kargs): - """diffplot(f, delay=1, lfilter=None) - Applies a function to couples (l[i],l[i+delay]) - - A list of matplotlib.lines.Line2D is returned. - """ - - # Get the list of packets - if lfilter is None: - lst_pkts = [f(self.res[i], self.res[i + 1]) - for i in range(len(self.res) - delay)] - else: - lst_pkts = [f(self.res[i], self.res[i + 1]) - for i in range(len(self.res) - delay) - if lfilter(self.res[i])] - - # Mimic the default gnuplot output - if kargs == {}: - kargs = MATPLOTLIB_DEFAULT_PLOT_KARGS - lines = plt.plot(lst_pkts, **kargs) - - # Call show() if matplotlib is not inlined - if not MATPLOTLIB_INLINED: - plt.show() - - return lines - - def multiplot(self, f, lfilter=None, plot_xy=False, **kargs): - """Uses a function that returns a label and a value for this label, then - plots all the values label by label. - - A list of matplotlib.lines.Line2D is returned. - """ - - # Python 2 backward compatibility - f = lambda_tuple_converter(f) - lfilter = lambda_tuple_converter(lfilter) - - # Get the list of packets - if lfilter is None: - lst_pkts = (f(*e) for e in self.res) - else: - lst_pkts = (f(*e) for e in self.res if lfilter(*e)) - - # Apply the function f to the packets - d = {} - for k, v in lst_pkts: - d.setdefault(k, []).append(v) - - # Mimic the default gnuplot output - if not kargs: - kargs = MATPLOTLIB_DEFAULT_PLOT_KARGS - - if plot_xy: - lines = [plt.plot(*zip(*pl), **dict(kargs, label=k)) - for k, pl in six.iteritems(d)] - else: - lines = [plt.plot(pl, **dict(kargs, label=k)) - for k, pl in six.iteritems(d)] - plt.legend(loc="center right", bbox_to_anchor=(1.5, 0.5)) - - # Call show() if matplotlib is not inlined - if not MATPLOTLIB_INLINED: - plt.show() - - return lines - - def rawhexdump(self): - """Prints an hexadecimal dump of each packet in the list""" - for p in self: - hexdump(self._elt2pkt(p)) - - def hexraw(self, lfilter=None): - """Same as nsummary(), except that if a packet has a Raw layer, it will be hexdumped # noqa: E501 - lfilter: a truth function that decides whether a packet must be displayed""" # noqa: E501 - for i, res in enumerate(self.res): - p = self._elt2pkt(res) - if lfilter is not None and not lfilter(p): - continue - print("%s %s %s" % (conf.color_theme.id(i, fmt="%04i"), - p.sprintf("%.time%"), - self._elt2sum(res))) - if p.haslayer(conf.raw_layer): - hexdump(p.getlayer(conf.raw_layer).load) - - def hexdump(self, lfilter=None): - """Same as nsummary(), except that packets are also hexdumped - lfilter: a truth function that decides whether a packet must be displayed""" # noqa: E501 - for i, res in enumerate(self.res): - p = self._elt2pkt(res) - if lfilter is not None and not lfilter(p): - continue - print("%s %s %s" % (conf.color_theme.id(i, fmt="%04i"), - p.sprintf("%.time%"), - self._elt2sum(res))) - hexdump(p) - - def padding(self, lfilter=None): - """Same as hexraw(), for Padding layer""" - for i, res in enumerate(self.res): - p = self._elt2pkt(res) - if p.haslayer(conf.padding_layer): - if lfilter is None or lfilter(p): - print("%s %s %s" % (conf.color_theme.id(i, fmt="%04i"), - p.sprintf("%.time%"), - self._elt2sum(res))) - hexdump(p.getlayer(conf.padding_layer).load) - - def nzpadding(self, lfilter=None): - """Same as padding() but only non null padding""" - for i, res in enumerate(self.res): - p = self._elt2pkt(res) - if p.haslayer(conf.padding_layer): - pad = p.getlayer(conf.padding_layer).load - if pad == pad[0] * len(pad): - continue - if lfilter is None or lfilter(p): - print("%s %s %s" % (conf.color_theme.id(i, fmt="%04i"), - p.sprintf("%.time%"), - self._elt2sum(res))) - hexdump(p.getlayer(conf.padding_layer).load) - - def conversations(self, getsrcdst=None, **kargs): - """Graphes a conversations between sources and destinations and display it - (using graphviz and imagemagick) - getsrcdst: a function that takes an element of the list and - returns the source, the destination and optionally - a label. By default, returns the IP source and - destination from IP and ARP layers - type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option # noqa: E501 - target: filename or redirect. Defaults pipe to Imagemagick's display program # noqa: E501 - prog: which graphviz program to use""" - if getsrcdst is None: - def getsrcdst(pkt): - """Extract src and dst addresses""" - if 'IP' in pkt: - return (pkt['IP'].src, pkt['IP'].dst) - if 'IPv6' in pkt: - return (pkt['IPv6'].src, pkt['IPv6'].dst) - if 'ARP' in pkt: - return (pkt['ARP'].psrc, pkt['ARP'].pdst) - raise TypeError() - conv = {} - for p in self.res: - p = self._elt2pkt(p) - try: - c = getsrcdst(p) - except Exception: - # No warning here: it's OK that getsrcdst() raises an - # exception, since it might be, for example, a - # function that expects a specific layer in each - # packet. The try/except approach is faster and - # considered more Pythonic than adding tests. - continue - if len(c) == 3: - conv.setdefault(c[:2], set()).add(c[2]) - else: - conv[c] = conv.get(c, 0) + 1 - gr = 'digraph "conv" {\n' - for (s, d), l in six.iteritems(conv): - gr += '\t "%s" -> "%s" [label="%s"]\n' % ( - s, d, ', '.join(str(x) for x in l) if isinstance(l, set) else l - ) - gr += "}\n" - return do_graph(gr, **kargs) - - def afterglow(self, src=None, event=None, dst=None, **kargs): - """Experimental clone attempt of http://sourceforge.net/projects/afterglow - each datum is reduced as src -> event -> dst and the data are graphed. - by default we have IP.src -> IP.dport -> IP.dst""" - if src is None: - src = lambda x: x['IP'].src - if event is None: - event = lambda x: x['IP'].dport - if dst is None: - dst = lambda x: x['IP'].dst - sl = {} - el = {} - dl = {} - for i in self.res: - try: - s, e, d = src(i), event(i), dst(i) - if s in sl: - n, lst = sl[s] - n += 1 - if e not in lst: - lst.append(e) - sl[s] = (n, lst) - else: - sl[s] = (1, [e]) - if e in el: - n, lst = el[e] - n += 1 - if d not in lst: - lst.append(d) - el[e] = (n, lst) - else: - el[e] = (1, [d]) - dl[d] = dl.get(d, 0) + 1 - except Exception: - continue - - def minmax(x): - m, M = reduce(lambda a, b: (min(a[0], b[0]), max(a[1], b[1])), - ((a, a) for a in x)) - if m == M: - m = 0 - if M == 0: - M = 1 - return m, M - - mins, maxs = minmax(x for x, _ in six.itervalues(sl)) - mine, maxe = minmax(x for x, _ in six.itervalues(el)) - mind, maxd = minmax(six.itervalues(dl)) - - gr = 'digraph "afterglow" {\n\tedge [len=2.5];\n' - - gr += "# src nodes\n" - for s in sl: - n, _ = sl[s] - n = 1 + float(n - mins) / (maxs - mins) - gr += '"src.%s" [label = "%s", shape=box, fillcolor="#FF0000", style=filled, fixedsize=1, height=%.2f,width=%.2f];\n' % (repr(s), repr(s), n, n) # noqa: E501 - gr += "# event nodes\n" - for e in el: - n, _ = el[e] - n = n = 1 + float(n - mine) / (maxe - mine) - gr += '"evt.%s" [label = "%s", shape=circle, fillcolor="#00FFFF", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (repr(e), repr(e), n, n) # noqa: E501 - for d in dl: - n = dl[d] - n = n = 1 + float(n - mind) / (maxd - mind) - gr += '"dst.%s" [label = "%s", shape=triangle, fillcolor="#0000ff", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (repr(d), repr(d), n, n) # noqa: E501 - - gr += "###\n" - for s in sl: - n, lst = sl[s] - for e in lst: - gr += ' "src.%s" -> "evt.%s";\n' % (repr(s), repr(e)) - for e in el: - n, lst = el[e] - for d in lst: - gr += ' "evt.%s" -> "dst.%s";\n' % (repr(e), repr(d)) - - gr += "}" - return do_graph(gr, **kargs) - - def canvas_dump(self, **kargs): - import pyx - d = pyx.document.document() - len_res = len(self.res) - for i, res in enumerate(self.res): - c = self._elt2pkt(res).canvas_dump(**kargs) - cbb = c.bbox() - c.text(cbb.left(), cbb.top() + 1, r"\font\cmssfont=cmss12\cmssfont{Frame %i/%i}" % (i, len_res), [pyx.text.size.LARGE]) # noqa: E501 - if conf.verb >= 2: - os.write(1, b".") - d.append(pyx.document.page(c, paperformat=pyx.document.paperformat.A4, # noqa: E501 - margin=1 * pyx.unit.t_cm, - fittosize=1)) - return d - - def sr(self, multi=0): - """sr([multi=1]) -> (SndRcvList, PacketList) - Matches packets in the list and return ( (matched couples), (unmatched packets) )""" # noqa: E501 - remain = self.res[:] - sr = [] - i = 0 - while i < len(remain): - s = remain[i] - j = i - while j < len(remain) - 1: - j += 1 - r = remain[j] - if r.answers(s): - sr.append((s, r)) - if multi: - remain[i]._answered = 1 - remain[j]._answered = 2 - continue - del(remain[j]) - del(remain[i]) - i -= 1 - break - i += 1 - if multi: - remain = [x for x in remain if not hasattr(x, "_answered")] - return SndRcvList(sr), PacketList(remain) - - def sessions(self, session_extractor=None): - if session_extractor is None: - def session_extractor(p): - """Extract sessions from packets""" - if 'Ether' in p: - if 'IP' in p or 'IPv6' in p: - ip_src_fmt = "{IP:%IP.src%}{IPv6:%IPv6.src%}" - ip_dst_fmt = "{IP:%IP.dst%}{IPv6:%IPv6.dst%}" - addr_fmt = (ip_src_fmt, ip_dst_fmt) - if 'TCP' in p: - fmt = "TCP {}:%r,TCP.sport% > {}:%r,TCP.dport%" - elif 'UDP' in p: - fmt = "UDP {}:%r,UDP.sport% > {}:%r,UDP.dport%" - elif 'ICMP' in p: - fmt = "ICMP {} > {} type=%r,ICMP.type% code=%r," \ - "ICMP.code% id=%ICMP.id%" - elif 'ICMPv6' in p: - fmt = "ICMPv6 {} > {} type=%r,ICMPv6.type% " \ - "code=%r,ICMPv6.code%" - elif 'IPv6' in p: - fmt = "IPv6 {} > {} nh=%IPv6.nh%" - else: - fmt = "IP {} > {} proto=%IP.proto%" - return p.sprintf(fmt.format(*addr_fmt)) - elif 'ARP' in p: - return p.sprintf("ARP %ARP.psrc% > %ARP.pdst%") - else: - return p.sprintf("Ethernet type=%04xr,Ether.type%") - return "Other" - sessions = defaultdict(self.__class__) - for p in self.res: - sess = session_extractor(self._elt2pkt(p)) - sessions[sess].append(p) - return dict(sessions) - - def replace(self, *args, **kargs): - """ - lst.replace(,[,]) - lst.replace( (fld,[ov],nv),(fld,[ov,]nv),...) - if ov is None, all values are replaced - ex: - lst.replace( IP.src, "192.168.1.1", "10.0.0.1" ) - lst.replace( IP.ttl, 64 ) - lst.replace( (IP.ttl, 64), (TCP.sport, 666, 777), ) - """ - delete_checksums = kargs.get("delete_checksums", False) - x = PacketList(name="Replaced %s" % self.listname) - if not isinstance(args[0], tuple): - args = (args,) - for p in self.res: - p = self._elt2pkt(p) - copied = False - for scheme in args: - fld = scheme[0] - old = scheme[1] # not used if len(scheme) == 2 - new = scheme[-1] - for o in fld.owners: - if o in p: - if len(scheme) == 2 or p[o].getfieldval(fld.name) == old: # noqa: E501 - if not copied: - p = p.copy() - if delete_checksums: - p.delete_checksums() - copied = True - setattr(p[o], fld.name, new) - x.append(p) - return x - - def getlayer(self, cls, nb=None, flt=None, name=None, stats=None): - """Returns the packet list from a given layer. - - See ``Packet.getlayer`` for more info. - - :param cls: search for a layer that is an instance of ``cls`` - :type cls: Type[Packet] - - :param nb: return the nb^th layer that is an instance of ``cls`` - :type nb: Optional[int] - - :param flt: filter parameters for ``Packet.getlayer`` - :type flt: Optional[Dict[str, Any]] - - :param name: optional name for the new PacketList - :type name: Optional[str] - - :param stats: optional list of protocols to give stats on; if not - specified, inherits from this PacketList. - :type stats: Optional[List[Type[Packet]]] - :rtype: PacketList - """ - if name is None: - name = "{} layer {}".format(self.listname, cls.__name__) - if stats is None: - stats = self.stats - - getlayer_arg = {} - if flt is not None: - getlayer_arg.update(flt) - getlayer_arg['cls'] = cls - if nb is not None: - getlayer_arg['nb'] = nb - - # Only return non-None getlayer results - return PacketList([ - pc for pc in (p.getlayer(**getlayer_arg) for p in self.res) - if pc is not None], - name, stats - ) - - def convert_to(self, other_cls, name=None, stats=None): - """Converts all packets to another type. - - See ``Packet.convert_to`` for more info. - - :param other_cls: reference to a Packet class to convert to - :type other_cls: Type[Packet] - - :param name: optional name for the new PacketList - :type name: Optional[str] - - :param stats: optional list of protocols to give stats on; - if not specified, inherits from this PacketList. - :type stats: Optional[List[Type[Packet]]] - - :rtype: PacketList - """ - if name is None: - name = "{} converted to {}".format( - self.listname, other_cls.__name__) - if stats is None: - stats = self.stats - - return PacketList( - [p.convert_to(other_cls) for p in self.res], - name, stats - ) - - -class SndRcvList(PacketList): - __slots__ = [] - - def __init__(self, res=None, name="Results", stats=None): - PacketList.__init__(self, res, name, stats) - - def _elt2pkt(self, elt): - return elt[1] - - def _elt2sum(self, elt): - return "%s ==> %s" % (elt[0].summary(), elt[1].summary()) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/pton_ntop.py b/scripts/external_libs/scapy-2.4.3/scapy/pton_ntop.py deleted file mode 100644 index e57da17dd2..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/pton_ntop.py +++ /dev/null @@ -1,137 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Convert IPv6 addresses between textual representation and binary. - -These functions are missing when python is compiled -without IPv6 support, on Windows for instance. -""" - -from __future__ import absolute_import -import socket -import re -import binascii -from scapy.modules.six.moves import range -from scapy.compat import plain_str, hex_bytes, bytes_encode, bytes_hex - -_IP6_ZEROS = re.compile('(?::|^)(0(?::0)+)(?::|$)') -_INET6_PTON_EXC = socket.error("illegal IP address string passed to inet_pton") - - -def _inet6_pton(addr): - """Convert an IPv6 address from text representation into binary form, -used when socket.inet_pton is not available. - - """ - joker_pos = None - result = b"" - addr = plain_str(addr) - if addr == '::': - return b'\x00' * 16 - if addr.startswith('::'): - addr = addr[1:] - if addr.endswith('::'): - addr = addr[:-1] - parts = addr.split(":") - nparts = len(parts) - for i, part in enumerate(parts): - if not part: - # "::" indicates one or more groups of 2 null bytes - if joker_pos is None: - joker_pos = len(result) - else: - # Wildcard is only allowed once - raise _INET6_PTON_EXC - elif i + 1 == nparts and '.' in part: - # The last part of an IPv6 address can be an IPv4 address - if part.count('.') != 3: - # we have to do this since socket.inet_aton('1.2') == - # b'\x01\x00\x00\x02' - raise _INET6_PTON_EXC - try: - result += socket.inet_aton(part) - except socket.error: - raise _INET6_PTON_EXC - else: - # Each part must be 16bit. Add missing zeroes before decoding. - try: - result += hex_bytes(part.rjust(4, "0")) - except (binascii.Error, TypeError): - raise _INET6_PTON_EXC - # If there's a wildcard, fill up with zeros to reach 128bit (16 bytes) - if joker_pos is not None: - if len(result) == 16: - raise _INET6_PTON_EXC - result = (result[:joker_pos] + b"\x00" * (16 - len(result)) + - result[joker_pos:]) - if len(result) != 16: - raise _INET6_PTON_EXC - return result - - -_INET_PTON = { - socket.AF_INET: socket.inet_aton, - socket.AF_INET6: _inet6_pton, -} - - -def inet_pton(af, addr): - """Convert an IP address from text representation into binary form.""" - # Will replace Net/Net6 objects - addr = plain_str(addr) - # Use inet_pton if available - try: - return socket.inet_pton(af, addr) - except AttributeError: - try: - return _INET_PTON[af](addr) - except KeyError: - raise socket.error("Address family not supported by protocol") - - -def _inet6_ntop(addr): - """Convert an IPv6 address from binary form into text representation, -used when socket.inet_pton is not available. - - """ - # IPv6 addresses have 128bits (16 bytes) - if len(addr) != 16: - raise ValueError("invalid length of packed IP address string") - - # Decode to hex representation - address = ":".join(plain_str(bytes_hex(addr[idx:idx + 2])).lstrip('0') or '0' # noqa: E501 - for idx in range(0, 16, 2)) - - try: - # Get the longest set of zero blocks. We need to take a look - # at group 1 regarding the length, as 0:0:1:0:0:2:3:4 would - # have two matches: 0:0: and :0:0: where the latter is longer, - # though the first one should be taken. Group 1 is in both - # cases 0:0. - match = max(_IP6_ZEROS.finditer(address), - key=lambda m: m.end(1) - m.start(1)) - return '{}::{}'.format(address[:match.start()], address[match.end():]) - except ValueError: - return address - - -_INET_NTOP = { - socket.AF_INET: socket.inet_ntoa, - socket.AF_INET6: _inet6_ntop, -} - - -def inet_ntop(af, addr): - """Convert an IP address from binary form into text representation.""" - # Use inet_ntop if available - addr = bytes_encode(addr) - try: - return socket.inet_ntop(af, addr) - except AttributeError: - try: - return _INET_NTOP[af](addr) - except KeyError: - raise ValueError("unknown address family %d" % af) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/route.py b/scripts/external_libs/scapy-2.4.3/scapy/route.py deleted file mode 100644 index daf61e6349..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/route.py +++ /dev/null @@ -1,211 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Routing and handling of network interfaces. -""" - - -from __future__ import absolute_import - - -import scapy.consts -from scapy.config import conf -from scapy.error import Scapy_Exception, warning -from scapy.modules import six -from scapy.utils import atol, ltoa, itom, plain_str, pretty_list - - -############################## -# Routing/Interfaces stuff # -############################## - -class Route: - def __init__(self): - self.resync() - - def invalidate_cache(self): - self.cache = {} - - def resync(self): - from scapy.arch import read_routes - self.invalidate_cache() - self.routes = read_routes() - - def __repr__(self): - rtlst = [] - for net, msk, gw, iface, addr, metric in self.routes: - rtlst.append((ltoa(net), - ltoa(msk), - gw, - (iface.description if not isinstance(iface, six.string_types) else iface), # noqa: E501 - addr, - str(metric))) - - return pretty_list(rtlst, - [("Network", "Netmask", "Gateway", "Iface", "Output IP", "Metric")]) # noqa: E501 - - def make_route(self, host=None, net=None, gw=None, dev=None, metric=1): - from scapy.arch import get_if_addr - if host is not None: - thenet, msk = host, 32 - elif net is not None: - thenet, msk = net.split("/") - msk = int(msk) - else: - raise Scapy_Exception("make_route: Incorrect parameters. You should specify a host or a net") # noqa: E501 - if gw is None: - gw = "0.0.0.0" - if dev is None: - if gw: - nhop = gw - else: - nhop = thenet - dev, ifaddr, _ = self.route(nhop) - else: - ifaddr = get_if_addr(dev) - return (atol(thenet), itom(msk), gw, dev, ifaddr, metric) - - def add(self, *args, **kargs): - """Ex: - add(net="192.168.1.0/24",gw="1.2.3.4") - """ - self.invalidate_cache() - self.routes.append(self.make_route(*args, **kargs)) - - def delt(self, *args, **kargs): - """delt(host|net, gw|dev)""" - self.invalidate_cache() - route = self.make_route(*args, **kargs) - try: - i = self.routes.index(route) - del(self.routes[i]) - except ValueError: - warning("no matching route found") - - def ifchange(self, iff, addr): - self.invalidate_cache() - the_addr, the_msk = (addr.split("/") + ["32"])[:2] - the_msk = itom(int(the_msk)) - the_rawaddr = atol(the_addr) - the_net = the_rawaddr & the_msk - - for i, route in enumerate(self.routes): - net, msk, gw, iface, addr, metric = route - if scapy.consts.WINDOWS: - if iff.guid != iface.guid: - continue - elif iff != iface: - continue - if gw == '0.0.0.0': - self.routes[i] = (the_net, the_msk, gw, iface, the_addr, metric) # noqa: E501 - else: - self.routes[i] = (net, msk, gw, iface, the_addr, metric) - conf.netcache.flush() - - def ifdel(self, iff): - self.invalidate_cache() - new_routes = [] - for rt in self.routes: - if scapy.consts.WINDOWS: - if iff.guid == rt[3].guid: - continue - elif iff == rt[3]: - continue - new_routes.append(rt) - self.routes = new_routes - - def ifadd(self, iff, addr): - self.invalidate_cache() - the_addr, the_msk = (addr.split("/") + ["32"])[:2] - the_msk = itom(int(the_msk)) - the_rawaddr = atol(the_addr) - the_net = the_rawaddr & the_msk - self.routes.append((the_net, the_msk, '0.0.0.0', iff, the_addr, 1)) - - def route(self, dst=None, verbose=conf.verb): - """Returns the IPv4 routes to a host. - parameters: - - dst: the IPv4 of the destination host - - returns: (iface, output_ip, gateway_ip) - - iface: the interface used to connect to the host - - output_ip: the outgoing IP that will be used - - gateway_ip: the gateway IP that will be used - """ - dst = dst or "0.0.0.0" # Enable route(None) to return default route - if isinstance(dst, bytes): - try: - dst = plain_str(dst) - except UnicodeDecodeError: - raise TypeError("Unknown IP address input (bytes)") - if dst in self.cache: - return self.cache[dst] - # Transform "192.168.*.1-5" to one IP of the set - _dst = dst.split("/")[0].replace("*", "0") - while True: - idx = _dst.find("-") - if idx < 0: - break - m = (_dst[idx:] + ".").find(".") - _dst = _dst[:idx] + _dst[idx + m:] - - atol_dst = atol(_dst) - paths = [] - for d, m, gw, i, a, me in self.routes: - if not a: # some interfaces may not currently be connected - continue - aa = atol(a) - if aa == atol_dst: - paths.append( - (0xffffffff, 1, (scapy.consts.LOOPBACK_INTERFACE, a, "0.0.0.0")) # noqa: E501 - ) - if (atol_dst & m) == (d & m): - paths.append((m, me, (i, a, gw))) - - if not paths: - if verbose: - warning("No route found (no default route?)") - return scapy.consts.LOOPBACK_INTERFACE, "0.0.0.0", "0.0.0.0" - # Choose the more specific route - # Sort by greatest netmask and use metrics as a tie-breaker - paths.sort(key=lambda x: (-x[0], x[1])) - # Return interface - ret = paths[0][2] - self.cache[dst] = ret - return ret - - def get_if_bcast(self, iff): - for net, msk, gw, iface, addr, metric in self.routes: - if net == 0: - continue - if scapy.consts.WINDOWS: - if iff.guid != iface.guid: - continue - elif iff != iface: - continue - bcast = atol(addr) | (~msk & 0xffffffff) # FIXME: check error in atol() # noqa: E501 - return ltoa(bcast) - warning("No broadcast address found for iface %s\n", iff) - - -# TRex Change - Set Route to None -# conf.route = Route() -conf.route = None - -# TRex Changes -# iface = conf.route.route(None, verbose=0)[0] -iface = None - -# Warning: scapy.consts.LOOPBACK_INTERFACE must always be used statically, because it # noqa: E501 -# may be changed by scapy/arch/windows during execution - -if getattr(iface, "name", iface) == scapy.consts.LOOPBACK_INTERFACE: - from scapy.arch import get_working_if - conf.iface = get_working_if() -else: - conf.iface = iface - -del iface diff --git a/scripts/external_libs/scapy-2.4.3/scapy/route6.py b/scripts/external_libs/scapy-2.4.3/scapy/route6.py deleted file mode 100644 index 9ef86f2b49..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/route6.py +++ /dev/null @@ -1,290 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -# Copyright (C) 2005 Guillaume Valadon -# Arnaud Ebalard - -""" -Routing and network interface handling for IPv6. -""" - -############################################################################# -# Routing/Interfaces stuff # -############################################################################# - -from __future__ import absolute_import -import socket -import scapy.consts -from scapy.config import conf -from scapy.utils6 import in6_ptop, in6_cidr2mask, in6_and, \ - in6_islladdr, in6_ismlladdr, in6_isincluded, in6_isgladdr, \ - in6_isaddr6to4, in6_ismaddr, construct_source_candidate_set, \ - get_source_addr_from_candidate_set -from scapy.arch import read_routes6, in6_getifaddr -from scapy.pton_ntop import inet_pton, inet_ntop -from scapy.error import warning, log_loading -import scapy.modules.six as six -from scapy.utils import pretty_list - - -class Route6: - - def __init__(self): - self.resync() - self.invalidate_cache() - - def invalidate_cache(self): - self.cache = {} - - def flush(self): - self.invalidate_cache() - self.routes = [] - - def resync(self): - # TODO : At the moment, resync will drop existing Teredo routes - # if any. Change that ... - self.invalidate_cache() - self.routes = read_routes6() - if self.routes == []: - log_loading.info("No IPv6 support in kernel") - - def __repr__(self): - rtlst = [] - - for net, msk, gw, iface, cset, metric in self.routes: - rtlst.append(('%s/%i' % (net, msk), - gw, - (iface if isinstance(iface, six.string_types) - else iface.description), - ", ".join(cset) if len(cset) > 0 else "", - str(metric))) - - return pretty_list(rtlst, - [('Destination', 'Next Hop', "Iface", "Src candidates", "Metric")], # noqa: E501 - sortBy=1) - - # Unlike Scapy's Route.make_route() function, we do not have 'host' and 'net' # noqa: E501 - # parameters. We only have a 'dst' parameter that accepts 'prefix' and - # 'prefix/prefixlen' values. - # WARNING: Providing a specific device will at the moment not work correctly. # noqa: E501 - def make_route(self, dst, gw=None, dev=None): - """Internal function : create a route for 'dst' via 'gw'. - """ - prefix, plen = (dst.split("/") + ["128"])[:2] - plen = int(plen) - - if gw is None: - gw = "::" - if dev is None: - dev, ifaddr, x = self.route(gw) - else: - # TODO: do better than that - # replace that unique address by the list of all addresses - lifaddr = in6_getifaddr() - devaddrs = [x for x in lifaddr if x[2] == dev] - ifaddr = construct_source_candidate_set(prefix, plen, devaddrs) - - return (prefix, plen, gw, dev, ifaddr, 1) - - def add(self, *args, **kargs): - """Ex: - add(dst="2001:db8:cafe:f000::/56") - add(dst="2001:db8:cafe:f000::/56", gw="2001:db8:cafe::1") - add(dst="2001:db8:cafe:f000::/64", gw="2001:db8:cafe::1", dev="eth0") - """ - self.invalidate_cache() - self.routes.append(self.make_route(*args, **kargs)) - - def delt(self, dst, gw=None): - """ Ex: - delt(dst="::/0") - delt(dst="2001:db8:cafe:f000::/56") - delt(dst="2001:db8:cafe:f000::/56", gw="2001:db8:deca::1") - """ - tmp = dst + "/128" - dst, plen = tmp.split('/')[:2] - dst = in6_ptop(dst) - plen = int(plen) - to_del = [x for x in self.routes - if in6_ptop(x[0]) == dst and x[1] == plen] - if gw: - gw = in6_ptop(gw) - to_del = [x for x in self.routes if in6_ptop(x[2]) == gw] - if len(to_del) == 0: - warning("No matching route found") - elif len(to_del) > 1: - warning("Found more than one match. Aborting.") - else: - i = self.routes.index(to_del[0]) - self.invalidate_cache() - del(self.routes[i]) - - def ifchange(self, iff, addr): - the_addr, the_plen = (addr.split("/") + ["128"])[:2] - the_plen = int(the_plen) - - naddr = inet_pton(socket.AF_INET6, the_addr) - nmask = in6_cidr2mask(the_plen) - the_net = inet_ntop(socket.AF_INET6, in6_and(nmask, naddr)) - - for i, route in enumerate(self.routes): - net, plen, gw, iface, addr, metric = route - if iface != iff: - continue - if gw == '::': - self.routes[i] = (the_net, the_plen, gw, iface, [the_addr], metric) # noqa: E501 - else: - self.routes[i] = (net, plen, gw, iface, [the_addr], metric) - self.invalidate_cache() - conf.netcache.in6_neighbor.flush() - - def ifdel(self, iff): - """ removes all route entries that uses 'iff' interface. """ - new_routes = [] - for rt in self.routes: - if rt[3] != iff: - new_routes.append(rt) - self.invalidate_cache() - self.routes = new_routes - - def ifadd(self, iff, addr): - """ - Add an interface 'iff' with provided address into routing table. - - Ex: ifadd('eth0', '2001:bd8:cafe:1::1/64') will add following entry into # noqa: E501 - Scapy6 internal routing table: - - Destination Next Hop iface Def src @ Metric - 2001:bd8:cafe:1::/64 :: eth0 2001:bd8:cafe:1::1 1 - - prefix length value can be omitted. In that case, a value of 128 - will be used. - """ - addr, plen = (addr.split("/") + ["128"])[:2] - addr = in6_ptop(addr) - plen = int(plen) - naddr = inet_pton(socket.AF_INET6, addr) - nmask = in6_cidr2mask(plen) - prefix = inet_ntop(socket.AF_INET6, in6_and(nmask, naddr)) - self.invalidate_cache() - self.routes.append((prefix, plen, '::', iff, [addr], 1)) - - def route(self, dst=None, dev=None, verbose=conf.verb): - """ - Provide best route to IPv6 destination address, based on Scapy - internal routing table content. - - When a set of address is passed (e.g. 2001:db8:cafe:*::1-5) an address - of the set is used. Be aware of that behavior when using wildcards in - upper parts of addresses ! - - If 'dst' parameter is a FQDN, name resolution is performed and result - is used. - - if optional 'dev' parameter is provided a specific interface, filtering - is performed to limit search to route associated to that interface. - """ - dst = dst or "::/0" # Enable route(None) to return default route - # Transform "2001:db8:cafe:*::1-5:0/120" to one IPv6 address of the set - dst = dst.split("/")[0] - savedst = dst # In case following inet_pton() fails - dst = dst.replace("*", "0") - idx = dst.find("-") - while idx >= 0: - m = (dst[idx:] + ":").find(":") - dst = dst[:idx] + dst[idx + m:] - idx = dst.find("-") - - try: - inet_pton(socket.AF_INET6, dst) - except socket.error: - dst = socket.getaddrinfo(savedst, None, socket.AF_INET6)[0][-1][0] - # TODO : Check if name resolution went well - - # Use the default interface while dealing with link-local addresses - if dev is None and (in6_islladdr(dst) or in6_ismlladdr(dst)): - dev = conf.iface - - # Deal with dev-specific request for cache search - k = dst - if dev is not None: - k = dst + "%%" + (dev if isinstance(dev, six.string_types) else dev.pcap_name) # noqa: E501 - if k in self.cache: - return self.cache[k] - - paths = [] - - # TODO : review all kinds of addresses (scope and *cast) to see - # if we are able to cope with everything possible. I'm convinced - # it's not the case. - # -- arnaud - for p, plen, gw, iface, cset, me in self.routes: - if dev is not None and iface != dev: - continue - if in6_isincluded(dst, p, plen): - paths.append((plen, me, (iface, cset, gw))) - elif (in6_ismlladdr(dst) and in6_islladdr(p) and in6_islladdr(cset[0])): # noqa: E501 - paths.append((plen, me, (iface, cset, gw))) - - if not paths: - if verbose: - warning("No route found for IPv6 destination %s " - "(no default route?)", dst) - return (scapy.consts.LOOPBACK_INTERFACE, "::", "::") - - # Sort with longest prefix first then use metrics as a tie-breaker - paths.sort(key=lambda x: (-x[0], x[1])) - - best_plen = (paths[0][0], paths[0][1]) - paths = [x for x in paths if (x[0], x[1]) == best_plen] - - res = [] - for p in paths: # Here we select best source address for every route - tmp = p[2] - srcaddr = get_source_addr_from_candidate_set(dst, tmp[1]) - if srcaddr is not None: - res.append((p[0], p[1], (tmp[0], srcaddr, tmp[2]))) - - if res == []: - warning("Found a route for IPv6 destination '%s', but no possible source address.", dst) # noqa: E501 - return (scapy.consts.LOOPBACK_INTERFACE, "::", "::") - - # Symptom : 2 routes with same weight (our weight is plen) - # Solution : - # - dst is unicast global. Check if it is 6to4 and we have a source - # 6to4 address in those available - # - dst is link local (unicast or multicast) and multiple output - # interfaces are available. Take main one (conf.iface6) - # - if none of the previous or ambiguity persists, be lazy and keep - # first one - - if len(res) > 1: - tmp = [] - if in6_isgladdr(dst) and in6_isaddr6to4(dst): - # TODO : see if taking the longest match between dst and - # every source addresses would provide better results - tmp = [x for x in res if in6_isaddr6to4(x[2][1])] - elif in6_ismaddr(dst) or in6_islladdr(dst): - # TODO : I'm sure we are not covering all addresses. Check that - tmp = [x for x in res if x[2][0] == conf.iface6] - - if tmp: - res = tmp - - # Fill the cache (including dev-specific request) - k = dst - if dev is not None: - k = dst + "%%" + (dev if isinstance(dev, six.string_types) else dev.pcap_name) # noqa: E501 - self.cache[k] = res[0][2] - - return res[0][2] - -# TRex Change - Set Route to None -# conf.route6 = Route6() -conf.route6 = None -try: - conf.iface6 = conf.route6.route(None)[0] -except Exception: - pass diff --git a/scripts/external_libs/scapy-2.4.3/scapy/scapypipes.py b/scripts/external_libs/scapy-2.4.3/scapy/scapypipes.py deleted file mode 100644 index 60d11ff0fd..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/scapypipes.py +++ /dev/null @@ -1,501 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -from __future__ import print_function -import socket -import subprocess - -from scapy.modules.six.moves.queue import Queue, Empty -from scapy.pipetool import Source, Drain, Sink -from scapy.config import conf -from scapy.compat import raw -from scapy.utils import ContextManagerSubprocess, PcapReader, PcapWriter -from scapy.automaton import recv_error -from scapy.consts import WINDOWS - - -class SniffSource(Source): - """Read packets from an interface and send them to low exit. - - +-----------+ - >>-| |->> - | | - >-| [iface]--|-> - +-----------+ - - If neither of the ``iface`` or ``socket`` parameters are specified, then - Scapy will capture from the first network interface. - - :param iface: A layer 2 interface to sniff packets from. Mutually - exclusive with the ``socket`` parameter. - :param filter: Packet filter to use while capturing. See ``L2listen``. - Not used with ``socket`` parameter. - :param socket: A ``SuperSocket`` to sniff packets from. - """ - - def __init__(self, iface=None, filter=None, socket=None, name=None): - Source.__init__(self, name=name) - - if (iface or filter) and socket: - raise ValueError("iface and filter options are mutually exclusive " - "with socket") - - self.s = socket - self.iface = iface - self.filter = filter - - def start(self): - if not self.s: - self.s = conf.L2listen(iface=self.iface, filter=self.filter) - - def stop(self): - if self.s: - self.s.close() - - def fileno(self): - return self.s.fileno() - - def check_recv(self): - return True - - def deliver(self): - try: - self._send(self.s.recv()) - except recv_error: - if not WINDOWS: - raise - - -class RdpcapSource(Source): - """Read packets from a PCAP file send them to low exit. - +----------+ - >>-| |->> - | | - >-| [pcap]--|-> - +----------+ -""" - - def __init__(self, fname, name=None): - Source.__init__(self, name=name) - self.fname = fname - self.f = PcapReader(self.fname) - - def start(self): - self.f = PcapReader(self.fname) - self.is_exhausted = False - - def stop(self): - self.f.close() - - def fileno(self): - return self.f.fileno() - - def check_recv(self): - return True - - def deliver(self): - try: - p = self.f.recv() - self._send(p) - except EOFError: - self.is_exhausted = True - - -class InjectSink(Sink): - """Packets received on low input are injected to an interface - +-----------+ - >>-| |->> - | | - >-|--[iface] |-> - +-----------+ -""" - - def __init__(self, iface=None, name=None): - Sink.__init__(self, name=name) - if iface is None: - iface = conf.iface - self.iface = iface - - def start(self): - self.s = conf.L2socket(iface=self.iface) - - def stop(self): - self.s.close() - - def push(self, msg): - self.s.send(msg) - - -class Inject3Sink(InjectSink): - def start(self): - self.s = conf.L3socket(iface=self.iface) - - -class WrpcapSink(Sink): - """Packets received on low input are written to PCAP file - +----------+ - >>-| |->> - | | - >-|--[pcap] |-> - +----------+ -""" - - def __init__(self, fname, name=None, linktype=None): - Sink.__init__(self, name=name) - self.fname = fname - self.f = None - self.linktype = linktype - - def start(self): - self.f = PcapWriter(self.fname, linktype=self.linktype) - - def stop(self): - if self.f: - self.f.flush() - self.f.close() - - def push(self, msg): - if msg: - self.f.write(msg) - - -class WiresharkSink(WrpcapSink): - """Packets received on low input are pushed to Wireshark. - - +----------+ - >>-| |->> - | | - >-|--[pcap] |-> - +----------+ - """ - - def __init__(self, name=None, linktype=None, args=None): - WrpcapSink.__init__(self, fname=None, name=name, linktype=linktype) - self.args = args - - def start(self): - # Wireshark must be running first, because PcapWriter will block until - # data has been read! - with ContextManagerSubprocess("WiresharkSink", conf.prog.wireshark): - args = [conf.prog.wireshark, "-ki", "-"] - if self.args: - args.extend(self.args) - - proc = subprocess.Popen( - args, - stdin=subprocess.PIPE, - stdout=None, - stderr=None, - ) - - self.fname = proc.stdin - WrpcapSink.start(self) - - -class UDPDrain(Drain): - """UDP payloads received on high entry are sent over UDP - +-------------+ - >>-|--[payload]--|->> - | X | - >-|----[UDP]----|-> - +-------------+ -""" - - def __init__(self, ip="127.0.0.1", port=1234): - Drain.__init__(self) - self.ip = ip - self.port = port - - def push(self, msg): - from scapy.layers.inet import IP, UDP - if IP in msg and msg[IP].proto == 17 and UDP in msg: - payload = msg[UDP].payload - self._high_send(raw(payload)) - - def high_push(self, msg): - from scapy.layers.inet import IP, UDP - p = IP(dst=self.ip) / UDP(sport=1234, dport=self.port) / msg - self._send(p) - - -class FDSourceSink(Source): - """Use a file descriptor as source and sink - +-------------+ - >>-| |->> - | | - >-|-[file desc]-|-> - +-------------+ -""" - - def __init__(self, fd, name=None): - Source.__init__(self, name=name) - self.fd = fd - - def push(self, msg): - self.fd.write(msg) - - def fileno(self): - return self.fd.fileno() - - def deliver(self): - self._send(self.fd.read()) - - -class TCPConnectPipe(Source): - """TCP connect to addr:port and use it as source and sink - +-------------+ - >>-| |->> - | | - >-|-[addr:port]-|-> - +-------------+ -""" - __selectable_force_select__ = True - - def __init__(self, addr="", port=0, name=None): - Source.__init__(self, name=name) - self.addr = addr - self.port = port - self.fd = None - - def start(self): - self.fd = socket.socket() - self.fd.connect((self.addr, self.port)) - - def stop(self): - if self.fd: - self.fd.close() - - def push(self, msg): - self.fd.send(msg) - - def fileno(self): - return self.fd.fileno() - - def deliver(self): - try: - msg = self.fd.recv(65536) - except socket.error: - self.stop() - raise - if msg: - self._send(msg) - - -class TCPListenPipe(TCPConnectPipe): - """TCP listen on [addr:]port and use first connection as source and sink ; send peer address to high output # noqa: E501 - +------^------+ - >>-| +-[peer]-|->> - | / | - >-|-[addr:port]-|-> - +-------------+ -""" - __selectable_force_select__ = True - - def __init__(self, addr="", port=0, name=None): - TCPConnectPipe.__init__(self, addr, port, name) - self.connected = False - self.q = Queue() - - def start(self): - self.connected = False - self.fd = socket.socket() - self.fd.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.fd.bind((self.addr, self.port)) - self.fd.listen(1) - - def push(self, msg): - if self.connected: - self.fd.send(msg) - else: - self.q.put(msg) - - def deliver(self): - if self.connected: - try: - msg = self.fd.recv(65536) - except socket.error: - self.stop() - raise - if msg: - self._send(msg) - else: - fd, frm = self.fd.accept() - self._high_send(frm) - self.fd.close() - self.fd = fd - self.connected = True - self._trigger(frm) - while True: - try: - self.fd.send(self.q.get(block=False)) - except Empty: - break - - -class TriggeredMessage(Drain): - """Send a preloaded message when triggered and trigger in chain - +------^------+ - >>-| | /----|->> - | |/ | - >-|-[ message ]-|-> - +------^------+ -""" - - def __init__(self, msg, name=None): - Drain.__init__(self, name=name) - self.msg = msg - - def on_trigger(self, trigmsg): - self._send(self.msg) - self._high_send(self.msg) - self._trigger(trigmsg) - - -class TriggerDrain(Drain): - """Pass messages and trigger when a condition is met - +------^------+ - >>-|-[condition]-|->> - | | | - >-|-[condition]-|-> - +-------------+ -""" - - def __init__(self, f, name=None): - Drain.__init__(self, name=name) - self.f = f - - def push(self, msg): - v = self.f(msg) - if v: - self._trigger(v) - self._send(msg) - - def high_push(self, msg): - v = self.f(msg) - if v: - self._trigger(v) - self._high_send(msg) - - -class TriggeredValve(Drain): - """Let messages alternatively pass or not, changing on trigger - +------^------+ - >>-|-[pass/stop]-|->> - | | | - >-|-[pass/stop]-|-> - +------^------+ -""" - - def __init__(self, start_state=True, name=None): - Drain.__init__(self, name=name) - self.opened = start_state - - def push(self, msg): - if self.opened: - self._send(msg) - - def high_push(self, msg): - if self.opened: - self._high_send(msg) - - def on_trigger(self, msg): - self.opened ^= True - self._trigger(msg) - - -class TriggeredQueueingValve(Drain): - """Let messages alternatively pass or queued, changing on trigger - +------^-------+ - >>-|-[pass/queue]-|->> - | | | - >-|-[pass/queue]-|-> - +------^-------+ -""" - - def __init__(self, start_state=True, name=None): - Drain.__init__(self, name=name) - self.opened = start_state - self.q = Queue() - - def start(self): - self.q = Queue() - - def push(self, msg): - if self.opened: - self._send(msg) - else: - self.q.put((True, msg)) - - def high_push(self, msg): - if self.opened: - self._send(msg) - else: - self.q.put((False, msg)) - - def on_trigger(self, msg): - self.opened ^= True - self._trigger(msg) - while True: - try: - low, msg = self.q.get(block=False) - except Empty: - break - else: - if low: - self._send(msg) - else: - self._high_send(msg) - - -class TriggeredSwitch(Drain): - r"""Let messages alternatively high or low, changing on trigger - +------^------+ - >>-|-\ | /-|->> - | [up/down] | - >-|-/ | \-|-> - +------^------+ -""" - - def __init__(self, start_state=True, name=None): - Drain.__init__(self, name=name) - self.low = start_state - - def push(self, msg): - if self.low: - self._send(msg) - else: - self._high_send(msg) - high_push = push - - def on_trigger(self, msg): - self.low ^= True - self._trigger(msg) - - -class ConvertPipe(Drain): - """Packets sent on entry are converted to another type of packet. - - +-------------+ - >>-|--[convert]--|->> - | | - >-|--[convert]--|-> - +-------------+ - - See ``Packet.convert_packet``. - """ - def __init__(self, low_type=None, high_type=None, name=None): - Drain.__init__(self, name=name) - self.low_type = low_type - self.high_type = high_type - - def push(self, msg): - if self.low_type: - msg = self.low_type.convert_packet(msg) - self._send(msg) - - def high_push(self, msg): - if self.high_type: - msg = self.high_type.convert_packet(msg) - self._high_send(msg) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/sendrecv.py b/scripts/external_libs/scapy-2.4.3/scapy/sendrecv.py deleted file mode 100644 index c1d814101c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/sendrecv.py +++ /dev/null @@ -1,1084 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Functions to send and receive packets. -""" - -from __future__ import absolute_import, print_function -import itertools -from threading import Thread, Event -import os -import re -import subprocess -import time -import types - -from scapy.compat import plain_str -from scapy.data import ETH_P_ALL -from scapy.config import conf -from scapy.error import warning -from scapy.packet import Gen, Packet -from scapy.utils import get_temp_file, tcpdump, wrpcap, \ - ContextManagerSubprocess, PcapReader -from scapy.plist import PacketList, SndRcvList -from scapy.error import log_runtime, log_interactive, Scapy_Exception -from scapy.base_classes import SetGen -from scapy.modules import six -from scapy.modules.six.moves import map -from scapy.sessions import DefaultSession -from scapy.supersocket import SuperSocket -if conf.route is None: - # unused import, only to initialize conf.route - import scapy.route # noqa: F401 - -################# -# Debug class # -################# - - -class debug: - recv = [] - sent = [] - match = [] - crashed_on = None - - -#################### -# Send / Receive # -#################### - -_DOC_SNDRCV_PARAMS = """ - pks: SuperSocket instance to send/receive packets - pkt: the packet to send - rcv_pks: if set, will be used instead of pks to receive packets. - packets will still be sent through pks - nofilter: put 1 to avoid use of BPF filters - retry: if positive, how many times to resend unanswered packets - if negative, how many times to retry when no more packets - are answered - timeout: how much time to wait after the last packet has been sent - verbose: set verbosity level - multi: whether to accept multiple answers for the same stimulus - store_unanswered: whether to store not-answered packets or not. - setting it to False will increase speed, and will return - None as the unans list. - process: if specified, only result from process(pkt) will be stored. - the function should follow the following format: - lambda sent, received: (func(sent), func2(received)) - if the packet is unanswered, `received` will be None. - if `store_unanswered` is False, the function won't be called on - un-answered packets. - prebuild: pre-build the packets before starting to send them. Automatically - enabled when a generator is passed as the packet - """ - - -class SndRcvHandler(object): - def __init__(self, pks, pkt, - timeout=None, inter=0, verbose=None, - chainCC=False, - retry=0, multi=False, rcv_pks=None, - prebuild=False, _flood=None, - session=None): - # Instantiate all arguments - if verbose is None: - verbose = conf.verb - if conf.debug_match: - debug.recv = PacketList([], "Received") - debug.sent = PacketList([], "Sent") - debug.match = SndRcvList([], "Matched") - self.nbrecv = 0 - self.ans = [] - self.pks = pks - self.rcv_pks = rcv_pks or pks - self.inter = inter - self.verbose = verbose - self.chainCC = chainCC - self.multi = multi - self.timeout = timeout - self.session = session - # Instantiate packet holders - if _flood: - self.tobesent = pkt - self.notans = _flood[0] - else: - if isinstance(pkt, types.GeneratorType) or prebuild: - self.tobesent = [p for p in pkt] - self.notans = len(self.tobesent) - else: - self.tobesent = ( - SetGen(pkt) if not isinstance(pkt, Gen) else pkt - ) - self.notans = self.tobesent.__iterlen__() - - if retry < 0: - autostop = retry = -retry - else: - autostop = 0 - - if timeout is not None and timeout < 0: - self.timeout = None - - while retry >= 0: - self.hsent = {} - - # Send packets in thread. - # https://github.com/secdev/scapy/issues/1791 - snd_thread = Thread( - target=self._sndrcv_snd - ) - snd_thread.setDaemon(True) - - # Start routine with callback - self._sndrcv_rcv(snd_thread.start) - - # Ended. Let's close gracefully - if _flood: - # Flood: stop send thread - _flood[1]() - snd_thread.join() - - if multi: - remain = [ - p for p in itertools.chain(*six.itervalues(self.hsent)) - if not hasattr(p, '_answered') - ] - else: - remain = list(itertools.chain(*six.itervalues(self.hsent))) - - if autostop and len(remain) > 0 and \ - len(remain) != len(self.tobesent): - retry = autostop - - self.tobesent = remain - if len(self.tobesent) == 0: - break - retry -= 1 - - if conf.debug_match: - debug.sent = PacketList(remain[:], "Sent") - debug.match = SndRcvList(self.ans[:]) - - # Clean the ans list to delete the field _answered - if multi: - for snd, _ in self.ans: - if hasattr(snd, '_answered'): - del snd._answered - - if verbose: - print( - "\nReceived %i packets, got %i answers, " - "remaining %i packets" % ( - self.nbrecv + len(self.ans), len(self.ans), self.notans - ) - ) - - self.ans_result = SndRcvList(self.ans) - self.unans_result = PacketList(remain, "Unanswered") - - def results(self): - return self.ans_result, self.unans_result - - def _sndrcv_snd(self): - """Function used in the sending thread of sndrcv()""" - try: - if self.verbose: - print("Begin emission:") - i = 0 - for p in self.tobesent: - # Populate the dictionary of _sndrcv_rcv - # _sndrcv_rcv won't miss the answer of a packet that - # has not been sent - self.hsent.setdefault(p.hashret(), []).append(p) - # Send packet - self.pks.send(p) - time.sleep(self.inter) - i += 1 - if self.verbose: - print("Finished sending %i packets." % i) - except SystemExit: - pass - except Exception: - log_runtime.exception("--- Error sending packets") - - def _process_packet(self, r): - """Internal function used to process each packet.""" - if r is None: - return - ok = False - h = r.hashret() - if h in self.hsent: - hlst = self.hsent[h] - for i, sentpkt in enumerate(hlst): - if r.answers(sentpkt): - self.ans.append((sentpkt, r)) - if self.verbose > 1: - os.write(1, b"*") - ok = True - if not self.multi: - del hlst[i] - self.notans -= 1 - else: - if not hasattr(sentpkt, '_answered'): - self.notans -= 1 - sentpkt._answered = 1 - break - if self.notans <= 0 and not self.multi: - self.sniffer.stop(join=False) - if not ok: - if self.verbose > 1: - os.write(1, b".") - self.nbrecv += 1 - if conf.debug_match: - debug.recv.append(r) - - def _sndrcv_rcv(self, callback): - """Function used to receive packets and check their hashret""" - self.sniffer = None - try: - self.sniffer = AsyncSniffer() - self.sniffer._run( - prn=self._process_packet, - timeout=self.timeout, - store=False, - opened_socket=self.pks, - session=self.session, - started_callback=callback - ) - except KeyboardInterrupt: - if self.chainCC: - raise - - -def sndrcv(*args, **kwargs): - """Scapy raw function to send a packet and receive its answer. - WARNING: This is an internal function. Using sr/srp/sr1/srp is - more appropriate in many cases. - """ - sndrcver = SndRcvHandler(*args, **kwargs) - return sndrcver.results() - - -def __gen_send(s, x, inter=0, loop=0, count=None, verbose=None, realtime=None, return_packets=False, *args, **kargs): # noqa: E501 - if isinstance(x, str): - x = conf.raw_layer(load=x) - if not isinstance(x, Gen): - x = SetGen(x) - if verbose is None: - verbose = conf.verb - n = 0 - if count is not None: - loop = -count - elif not loop: - loop = -1 - if return_packets: - sent_packets = PacketList() - try: - while loop: - dt0 = None - for p in x: - if realtime: - ct = time.time() - if dt0: - st = dt0 + p.time - ct - if st > 0: - time.sleep(st) - else: - dt0 = ct - p.time - s.send(p) - if return_packets: - sent_packets.append(p) - n += 1 - if verbose: - os.write(1, b".") - time.sleep(inter) - if loop < 0: - loop += 1 - except KeyboardInterrupt: - pass - if verbose: - print("\nSent %i packets." % n) - if return_packets: - return sent_packets - - -@conf.commands.register -def send(x, inter=0, loop=0, count=None, - verbose=None, realtime=None, - return_packets=False, socket=None, *args, **kargs): - """Send packets at layer 3 -send(packets, [inter=0], [loop=0], [count=None], [verbose=conf.verb], [realtime=None], [return_packets=False], # noqa: E501 - [socket=None]) -> None""" - need_closing = socket is None - socket = socket or conf.L3socket(*args, **kargs) - results = __gen_send(socket, x, inter=inter, loop=loop, - count=count, verbose=verbose, - realtime=realtime, return_packets=return_packets) - if need_closing: - socket.close() - return results - - -@conf.commands.register -def sendp(x, inter=0, loop=0, iface=None, iface_hint=None, count=None, - verbose=None, realtime=None, - return_packets=False, socket=None, *args, **kargs): - """Send packets at layer 2 -sendp(packets, [inter=0], [loop=0], [iface=None], [iface_hint=None], [count=None], [verbose=conf.verb], # noqa: E501 - [realtime=None], [return_packets=False], [socket=None]) -> None""" - if iface is None and iface_hint is not None and socket is None: - iface = conf.route.route(iface_hint)[0] - need_closing = socket is None - socket = socket or conf.L2socket(iface=iface, *args, **kargs) - results = __gen_send(socket, x, inter=inter, loop=loop, - count=count, verbose=verbose, - realtime=realtime, return_packets=return_packets) - if need_closing: - socket.close() - return results - - -@conf.commands.register -def sendpfast(x, pps=None, mbps=None, realtime=None, loop=0, file_cache=False, iface=None, replay_args=None, # noqa: E501 - parse_results=False): - """Send packets at layer 2 using tcpreplay for performance - pps: packets per second - mpbs: MBits per second - realtime: use packet's timestamp, bending time with real-time value - loop: number of times to process the packet list - file_cache: cache packets in RAM instead of reading from disk at each iteration # noqa: E501 - iface: output interface - replay_args: List of additional tcpreplay args (List[str]) - parse_results: Return a dictionary of information outputted by tcpreplay (default=False) # noqa: E501 - :returns stdout, stderr, command used""" - if iface is None: - iface = conf.iface - argv = [conf.prog.tcpreplay, "--intf1=%s" % iface] - if pps is not None: - argv.append("--pps=%i" % pps) - elif mbps is not None: - argv.append("--mbps=%f" % mbps) - elif realtime is not None: - argv.append("--multiplier=%f" % realtime) - else: - argv.append("--topspeed") - - if loop: - argv.append("--loop=%i" % loop) - if file_cache: - argv.append("--preload-pcap") - - # Check for any additional args we didn't cover. - if replay_args is not None: - argv.extend(replay_args) - - f = get_temp_file() - argv.append(f) - wrpcap(f, x) - results = None - with ContextManagerSubprocess("sendpfast()", conf.prog.tcpreplay): - try: - cmd = subprocess.Popen(argv, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - except KeyboardInterrupt: - log_interactive.info("Interrupted by user") - except Exception: - os.unlink(f) - raise - else: - stdout, stderr = cmd.communicate() - if stderr: - log_runtime.warning(stderr.decode()) - if parse_results: - results = _parse_tcpreplay_result(stdout, stderr, argv) - elif conf.verb > 2: - log_runtime.info(stdout.decode()) - os.unlink(f) - return results - - -def _parse_tcpreplay_result(stdout, stderr, argv): - """ - Parse the output of tcpreplay and modify the results_dict to populate output information. # noqa: E501 - Tested with tcpreplay v3.4.4 - Tested with tcpreplay v4.1.2 - :param stdout: stdout of tcpreplay subprocess call - :param stderr: stderr of tcpreplay subprocess call - :param argv: the command used in the subprocess call - :return: dictionary containing the results - """ - try: - results = {} - stdout = plain_str(stdout).lower() - stderr = plain_str(stderr).strip().split("\n") - elements = { - "actual": (int, int, float), - "rated": (float, float, float), - "flows": (int, float, int, int), - "attempted": (int,), - "successful": (int,), - "failed": (int,), - "truncated": (int,), - "retried packets (eno": (int,), - "retried packets (eag": (int,), - } - multi = { - "actual": ("packets", "bytes", "time"), - "rated": ("bps", "mbps", "pps"), - "flows": ("flows", "fps", "flow_packets", "non_flow"), - "retried packets (eno": ("retried_enobufs",), - "retried packets (eag": ("retried_eagain",), - } - float_reg = r"([0-9]*\.[0-9]+|[0-9]+)" - int_reg = r"([0-9]+)" - any_reg = r"[^0-9]*" - r_types = {int: int_reg, float: float_reg} - for line in stdout.split("\n"): - line = line.strip() - for elt, _types in elements.items(): - if line.startswith(elt): - regex = any_reg.join([r_types[x] for x in _types]) - matches = re.search(regex, line) - for i, typ in enumerate(_types): - name = multi.get(elt, [elt])[i] - results[name] = typ(matches.group(i + 1)) - results["command"] = " ".join(argv) - results["warnings"] = stderr[:-1] - return results - except Exception as parse_exception: - if not conf.interactive: - raise - log_runtime.error("Error parsing output: " + str(parse_exception)) - return {} - - -@conf.commands.register -def sr(x, promisc=None, filter=None, iface=None, nofilter=0, *args, **kargs): - """Send and receive packets at layer 3""" - s = conf.L3socket(promisc=promisc, filter=filter, - iface=iface, nofilter=nofilter) - result = sndrcv(s, x, *args, **kargs) - s.close() - return result - - -def _interface_selection(iface, packet): - """ - Select the network interface according to the layer 3 destination - """ - - if iface is None: - try: - iff = packet.route()[0] - except AttributeError: - iff = None - return iff or conf.iface - - return iface - - -@conf.commands.register -def sr1(x, promisc=None, filter=None, iface=None, nofilter=0, *args, **kargs): - """Send packets at layer 3 and return only the first answer""" - iface = _interface_selection(iface, x) - s = conf.L3socket(promisc=promisc, filter=filter, - nofilter=nofilter, iface=iface) - ans, _ = sndrcv(s, x, *args, **kargs) - s.close() - if len(ans) > 0: - return ans[0][1] - else: - return None - - -@conf.commands.register -def srp(x, promisc=None, iface=None, iface_hint=None, filter=None, - nofilter=0, type=ETH_P_ALL, *args, **kargs): - """Send and receive packets at layer 2""" - if iface is None and iface_hint is not None: - iface = conf.route.route(iface_hint)[0] - s = conf.L2socket(promisc=promisc, iface=iface, - filter=filter, nofilter=nofilter, type=type) - result = sndrcv(s, x, *args, **kargs) - s.close() - return result - - -@conf.commands.register -def srp1(*args, **kargs): - """Send and receive packets at layer 2 and return only the first answer""" - ans, _ = srp(*args, **kargs) - if len(ans) > 0: - return ans[0][1] - else: - return None - - -# Append doc -for sr_func in [srp, srp1, sr, sr1]: - sr_func.__doc__ += _DOC_SNDRCV_PARAMS - - -# SEND/RECV LOOP METHODS - - -def __sr_loop(srfunc, pkts, prn=lambda x: x[1].summary(), - prnfail=lambda x: x.summary(), - inter=1, timeout=None, count=None, verbose=None, store=1, - *args, **kargs): - n = 0 - r = 0 - ct = conf.color_theme - if verbose is None: - verbose = conf.verb - parity = 0 - ans = [] - unans = [] - if timeout is None: - timeout = min(2 * inter, 5) - try: - while True: - parity ^= 1 - col = [ct.even, ct.odd][parity] - if count is not None: - if count == 0: - break - count -= 1 - start = time.time() - if verbose > 1: - print("\rsend...\r", end=' ') - res = srfunc(pkts, timeout=timeout, verbose=0, chainCC=True, *args, **kargs) # noqa: E501 - n += len(res[0]) + len(res[1]) - r += len(res[0]) - if verbose > 1 and prn and len(res[0]) > 0: - msg = "RECV %i:" % len(res[0]) - print("\r" + ct.success(msg), end=' ') - for p in res[0]: - print(col(prn(p))) - print(" " * len(msg), end=' ') - if verbose > 1 and prnfail and len(res[1]) > 0: - msg = "fail %i:" % len(res[1]) - print("\r" + ct.fail(msg), end=' ') - for p in res[1]: - print(col(prnfail(p))) - print(" " * len(msg), end=' ') - if verbose > 1 and not (prn or prnfail): - print("recv:%i fail:%i" % tuple(map(len, res[:2]))) - if store: - ans += res[0] - unans += res[1] - end = time.time() - if end - start < inter: - time.sleep(inter + start - end) - except KeyboardInterrupt: - pass - - if verbose and n > 0: - print(ct.normal("\nSent %i packets, received %i packets. %3.1f%% hits." % (n, r, 100.0 * r / n))) # noqa: E501 - return SndRcvList(ans), PacketList(unans) - - -@conf.commands.register -def srloop(pkts, *args, **kargs): - """Send a packet at layer 3 in loop and print the answer each time -srloop(pkts, [prn], [inter], [count], ...) --> None""" - return __sr_loop(sr, pkts, *args, **kargs) - - -@conf.commands.register -def srploop(pkts, *args, **kargs): - """Send a packet at layer 2 in loop and print the answer each time -srloop(pkts, [prn], [inter], [count], ...) --> None""" - return __sr_loop(srp, pkts, *args, **kargs) - -# SEND/RECV FLOOD METHODS - - -def sndrcvflood(pks, pkt, inter=0, verbose=None, chainCC=False, timeout=None): - """sndrcv equivalent for flooding.""" - stopevent = Event() - - def send_in_loop(tobesent, stopevent): - """Infinite generator that produces the same - packet until stopevent is triggered.""" - while True: - for p in tobesent: - if stopevent.is_set(): - return - yield p - - infinite_gen = send_in_loop(pkt, stopevent) - _flood_len = pkt.__iterlen__() if isinstance(pkt, Gen) else len(pkt) - _flood = [_flood_len, stopevent.set] - return sndrcv( - pks, infinite_gen, - inter=inter, verbose=verbose, - chainCC=chainCC, timeout=None, - _flood=_flood - ) - - -@conf.commands.register -def srflood(x, promisc=None, filter=None, iface=None, nofilter=None, *args, **kargs): # noqa: E501 - """Flood and receive packets at layer 3 -prn: function applied to packets received -unique: only consider packets whose print -nofilter: put 1 to avoid use of BPF filters -filter: provide a BPF filter -iface: listen answers only on the given interface""" - s = conf.L3socket(promisc=promisc, filter=filter, iface=iface, nofilter=nofilter) # noqa: E501 - r = sndrcvflood(s, x, *args, **kargs) - s.close() - return r - - -@conf.commands.register -def sr1flood(x, promisc=None, filter=None, iface=None, nofilter=0, *args, **kargs): # noqa: E501 - """Flood and receive packets at layer 3 and return only the first answer -prn: function applied to packets received -verbose: set verbosity level -nofilter: put 1 to avoid use of BPF filters -filter: provide a BPF filter -iface: listen answers only on the given interface""" - s = conf.L3socket(promisc=promisc, filter=filter, nofilter=nofilter, iface=iface) # noqa: E501 - ans, _ = sndrcvflood(s, x, *args, **kargs) - s.close() - if len(ans) > 0: - return ans[0][1] - else: - return None - - -@conf.commands.register -def srpflood(x, promisc=None, filter=None, iface=None, iface_hint=None, nofilter=None, *args, **kargs): # noqa: E501 - """Flood and receive packets at layer 2 -prn: function applied to packets received -unique: only consider packets whose print -nofilter: put 1 to avoid use of BPF filters -filter: provide a BPF filter -iface: listen answers only on the given interface""" - if iface is None and iface_hint is not None: - iface = conf.route.route(iface_hint)[0] - s = conf.L2socket(promisc=promisc, filter=filter, iface=iface, nofilter=nofilter) # noqa: E501 - r = sndrcvflood(s, x, *args, **kargs) - s.close() - return r - - -@conf.commands.register -def srp1flood(x, promisc=None, filter=None, iface=None, nofilter=0, *args, **kargs): # noqa: E501 - """Flood and receive packets at layer 2 and return only the first answer -prn: function applied to packets received -verbose: set verbosity level -nofilter: put 1 to avoid use of BPF filters -filter: provide a BPF filter -iface: listen answers only on the given interface""" - s = conf.L2socket(promisc=promisc, filter=filter, nofilter=nofilter, iface=iface) # noqa: E501 - ans, _ = sndrcvflood(s, x, *args, **kargs) - s.close() - if len(ans) > 0: - return ans[0][1] - else: - return None - -# SNIFF METHODS - - -class AsyncSniffer(object): - """ - Sniff packets and return a list of packets. - - Args: - count: number of packets to capture. 0 means infinity. - store: whether to store sniffed packets or discard them - prn: function to apply to each packet. If something is returned, it - is displayed. - --Ex: prn = lambda x: x.summary() - session: a session = a flow decoder used to handle stream of packets. - e.g: IPSession (to defragment on-the-flow) or NetflowSession - filter: BPF filter to apply. - lfilter: Python function applied to each packet to determine if - further action may be done. - --Ex: lfilter = lambda x: x.haslayer(Padding) - offline: PCAP file (or list of PCAP files) to read packets from, - instead of sniffing them - timeout: stop sniffing after a given time (default: None). - L2socket: use the provided L2socket (default: use conf.L2listen). - opened_socket: provide an object (or a list of objects) ready to use - .recv() on. - stop_filter: Python function applied to each packet to determine if - we have to stop the capture after this packet. - --Ex: stop_filter = lambda x: x.haslayer(TCP) - iface: interface or list of interfaces (default: None for sniffing - on all interfaces). - monitor: use monitor mode. May not be available on all OS - started_callback: called as soon as the sniffer starts sniffing - (default: None). - - The iface, offline and opened_socket parameters can be either an - element, a list of elements, or a dict object mapping an element to a - label (see examples below). - - Examples: synchronous - >>> sniff(filter="arp") - >>> sniff(filter="tcp", - ... session=IPSession, # defragment on-the-flow - ... prn=lambda x: x.summary()) - >>> sniff(lfilter=lambda pkt: ARP in pkt) - >>> sniff(iface="eth0", prn=Packet.summary) - >>> sniff(iface=["eth0", "mon0"], - ... prn=lambda pkt: "%s: %s" % (pkt.sniffed_on, - ... pkt.summary())) - >>> sniff(iface={"eth0": "Ethernet", "mon0": "Wifi"}, - ... prn=lambda pkt: "%s: %s" % (pkt.sniffed_on, - ... pkt.summary())) - - Examples: asynchronous - >>> t = AsyncSniffer(iface="enp0s3") - >>> t.start() - >>> time.sleep(1) - >>> print("nice weather today") - >>> t.stop() - """ - def __init__(self, *args, **kwargs): - # Store keyword arguments - self.args = args - self.kwargs = kwargs - self.running = False - self.thread = None - self.results = None - - def _setup_thread(self): - # Prepare sniffing thread - self.thread = Thread( - target=self._run, - args=self.args, - kwargs=self.kwargs - ) - self.thread.setDaemon(True) - - def _run(self, - count=0, store=True, offline=None, - prn=None, lfilter=None, - L2socket=None, timeout=None, opened_socket=None, - stop_filter=None, iface=None, started_callback=None, - session=None, session_args=[], session_kwargs={}, - *arg, **karg): - self.running = True - # Start main thread - # instantiate session - session = session or DefaultSession - session = session(prn, store, *session_args, **session_kwargs) - # sniff_sockets follows: {socket: label} - sniff_sockets = {} - if opened_socket is not None: - if isinstance(opened_socket, list): - sniff_sockets.update( - (s, "socket%d" % i) - for i, s in enumerate(opened_socket) - ) - elif isinstance(opened_socket, dict): - sniff_sockets.update( - (s, label) - for s, label in six.iteritems(opened_socket) - ) - else: - sniff_sockets[opened_socket] = "socket0" - if offline is not None: - flt = karg.get('filter') - from scapy.arch.common import TCPDUMP - if not TCPDUMP and flt is not None: - message = "tcpdump is not available. Cannot use filter!" - raise Scapy_Exception(message) - - if isinstance(offline, list) and \ - all(isinstance(elt, str) for elt in offline): - sniff_sockets.update((PcapReader( - fname if flt is None else - tcpdump(fname, args=["-w", "-", flt], getfd=True) - ), fname) for fname in offline) - elif isinstance(offline, dict): - sniff_sockets.update((PcapReader( - fname if flt is None else - tcpdump(fname, args=["-w", "-", flt], getfd=True) - ), label) for fname, label in six.iteritems(offline)) - else: - # Write Scapy Packet objects to a pcap file - def _write_to_pcap(packets_list): - filename = get_temp_file(autoext=".pcap") - wrpcap(filename, offline) - return filename, filename - - if isinstance(offline, Packet): - tempfile_written, offline = _write_to_pcap([offline]) - elif isinstance(offline, list) and \ - all(isinstance(elt, Packet) for elt in offline): - tempfile_written, offline = _write_to_pcap(offline) - - sniff_sockets[PcapReader( - offline if flt is None else - tcpdump(offline, args=["-w", "-", flt], getfd=True) - )] = offline - if not sniff_sockets or iface is not None: - if L2socket is None: - L2socket = conf.L2listen - if isinstance(iface, list): - sniff_sockets.update( - (L2socket(type=ETH_P_ALL, iface=ifname, *arg, **karg), - ifname) - for ifname in iface - ) - elif isinstance(iface, dict): - sniff_sockets.update( - (L2socket(type=ETH_P_ALL, iface=ifname, *arg, **karg), - iflabel) - for ifname, iflabel in six.iteritems(iface) - ) - else: - sniff_sockets[L2socket(type=ETH_P_ALL, iface=iface, - *arg, **karg)] = iface - - # Get select information from the sockets - _main_socket = next(iter(sniff_sockets)) - read_allowed_exceptions = _main_socket.read_allowed_exceptions - select_func = _main_socket.select - _backup_read_func = _main_socket.__class__.recv - nonblocking_socket = _main_socket.nonblocking_socket - # We check that all sockets use the same select(), or raise a warning - if not all(select_func == sock.select for sock in sniff_sockets): - warning("Warning: inconsistent socket types ! " - "The used select function " - "will be the one of the first socket") - - # Fill if empty - if not read_allowed_exceptions: - read_allowed_exceptions = (IOError,) - - if nonblocking_socket: - # select is non blocking - def stop_cb(): - self.continue_sniff = False - self.stop_cb = stop_cb - close_pipe = None - else: - # select is blocking: Add special control socket - from scapy.automaton import ObjectPipe - close_pipe = ObjectPipe() - sniff_sockets[close_pipe] = "control_socket" - - def stop_cb(): - if self.running: - close_pipe.send(None) - self.continue_sniff = False - self.stop_cb = stop_cb - - try: - if started_callback: - started_callback() - self.continue_sniff = True - - # Start timeout - if timeout is not None: - stoptime = time.time() + timeout - remain = None - - while sniff_sockets and self.continue_sniff: - if timeout is not None: - remain = stoptime - time.time() - if remain <= 0: - break - sockets, read_func = select_func(sniff_sockets, remain) - read_func = read_func or _backup_read_func - dead_sockets = [] - for s in sockets: - if s is close_pipe: - break - try: - p = read_func(s) - except EOFError: - # End of stream - dead_sockets.append(s) - continue - except read_allowed_exceptions: - continue - except Exception as ex: - msg = " It was closed." - try: - # Make sure it's closed - s.close() - except Exception as ex: - msg = " close() failed with '%s'" % ex - warning( - "Socket %s failed with '%s'." % (s, ex) + msg - ) - dead_sockets.append(s) - continue - if p is None: - continue - if lfilter and not lfilter(p): - continue - p.sniffed_on = sniff_sockets[s] - # on_packet_received handles the prn/storage - session.on_packet_received(p) - # check - if (stop_filter and stop_filter(p)) or \ - (0 < count <= session.count): - self.continue_sniff = False - break - # Removed dead sockets - for s in dead_sockets: - del sniff_sockets[s] - except KeyboardInterrupt: - pass - self.running = False - if opened_socket is None: - for s in sniff_sockets: - s.close() - elif close_pipe: - close_pipe.close() - self.results = session.toPacketList() - - def start(self): - """Starts AsyncSniffer in async mode""" - self._setup_thread() - self.thread.start() - - def stop(self, join=True): - """Stops AsyncSniffer if not in async mode""" - if self.running: - try: - self.stop_cb() - except AttributeError: - raise Scapy_Exception( - "Unsupported (offline or unsupported socket)" - ) - if join: - self.join() - return self.results - else: - raise Scapy_Exception("Not started !") - - def join(self, *args, **kwargs): - if self.thread: - self.thread.join(*args, **kwargs) - - -@conf.commands.register -def sniff(*args, **kwargs): - sniffer = AsyncSniffer() - sniffer._run(*args, **kwargs) - return sniffer.results - - -sniff.__doc__ = AsyncSniffer.__doc__ - - -@conf.commands.register -def bridge_and_sniff(if1, if2, xfrm12=None, xfrm21=None, prn=None, L2socket=None, # noqa: E501 - *args, **kargs): - """Forward traffic between interfaces if1 and if2, sniff and return -the exchanged packets. - -Arguments: - - if1, if2: the interfaces to use (interface names or opened sockets). - - xfrm12: a function to call when forwarding a packet from if1 to - if2. If it returns True, the packet is forwarded as it. If it - returns False or None, the packet is discarded. If it returns a - packet, this packet is forwarded instead of the original packet - one. - - xfrm21: same as xfrm12 for packets forwarded from if2 to if1. - - The other arguments are the same than for the function sniff(), - except for offline, opened_socket and iface that are ignored. - See help(sniff) for more. - - """ - for arg in ['opened_socket', 'offline', 'iface']: - if arg in kargs: - log_runtime.warning("Argument %s cannot be used in " - "bridge_and_sniff() -- ignoring it.", arg) - del kargs[arg] - - def _init_socket(iface, count): - if isinstance(iface, SuperSocket): - return iface, "iface%d" % count - else: - return (L2socket or conf.L2socket)(iface=iface), iface - sckt1, if1 = _init_socket(if1, 1) - sckt2, if2 = _init_socket(if2, 2) - peers = {if1: sckt2, if2: sckt1} - xfrms = {} - if xfrm12 is not None: - xfrms[if1] = xfrm12 - if xfrm21 is not None: - xfrms[if2] = xfrm21 - - def prn_send(pkt): - try: - sendsock = peers[pkt.sniffed_on] - except KeyError: - return - if pkt.sniffed_on in xfrms: - try: - newpkt = xfrms[pkt.sniffed_on](pkt) - except Exception: - log_runtime.warning( - 'Exception in transformation function for packet [%s] ' - 'received on %s -- dropping', - pkt.summary(), pkt.sniffed_on, exc_info=True - ) - return - else: - if newpkt is True: - newpkt = pkt.original - elif not newpkt: - return - else: - newpkt = pkt.original - try: - sendsock.send(newpkt) - except Exception: - log_runtime.warning('Cannot forward packet [%s] received on %s', - pkt.summary(), pkt.sniffed_on, exc_info=True) - if prn is None: - prn = prn_send - else: - prn_orig = prn - - def prn(pkt): - prn_send(pkt) - return prn_orig(pkt) - - return sniff(opened_socket={sckt1: if1, sckt2: if2}, prn=prn, - *args, **kargs) - - -@conf.commands.register -def tshark(*args, **kargs): - """Sniff packets and print them calling pkt.summary(). - This tries to replicate what text-wireshark (tshark) would look like""" - - if 'iface' in kargs: - iface = kargs.get('iface') - elif 'opened_socket' in kargs: - iface = kargs.get('opened_socket').iface - else: - iface = conf.iface - print("Capturing on '%s'" % iface) - - # This should be a nonlocal variable, using a mutable object - # for Python 2 compatibility - i = [0] - - def _cb(pkt): - print("%5d\t%s" % (i[0], pkt.summary())) - i[0] += 1 - - sniff(prn=_cb, store=False, *args, **kargs) - print("\n%d packet%s captured" % (i[0], 's' if i[0] > 1 else '')) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/sessions.py b/scripts/external_libs/scapy-2.4.3/scapy/sessions.py deleted file mode 100644 index 90c07178b1..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/sessions.py +++ /dev/null @@ -1,234 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Sessions: decode flow of packets when sniffing -""" - -from collections import defaultdict -from scapy.compat import raw -from scapy.config import conf -from scapy.packet import NoPayload -from scapy.plist import PacketList - - -class DefaultSession(object): - """Default session: no stream decoding""" - - def __init__(self, prn, store, *args, **karg): - self.prn = prn - self.store = store - self.lst = [] - self.__count = 0 - - @property - def count(self): - return self.__count - - def toPacketList(self): - return PacketList(self.lst, "Sniffed") - - def on_packet_received(self, pkt): - """DEV: entry point. Will be called by sniff() for each - received packet (that passes the filters). - """ - if not pkt: - return - if isinstance(pkt, list): - for p in pkt: - DefaultSession.on_packet_received(self, p) - return - self.__count += 1 - if self.store: - self.lst.append(pkt) - if self.prn: - result = self.prn(pkt) - if result is not None: - print(result) - - -class IPSession(DefaultSession): - """Defragment IP packets 'on-the-flow'. - Usage: - >>> sniff(session=IPSession) - """ - - def __init__(self, *args): - DefaultSession.__init__(self, *args) - self.fragments = defaultdict(list) - - def _ip_process_packet(self, packet): - from scapy.layers.inet import _defrag_list, IP - if IP not in packet: - return packet - ip = packet[IP] - packet._defrag_pos = 0 - if ip.frag != 0 or ip.flags.MF: - uniq = (ip.id, ip.src, ip.dst, ip.proto) - self.fragments[uniq].append(packet) - if not ip.flags.MF: # end of frag - try: - if self.fragments[uniq][0].frag == 0: - # Has first fragment (otherwise ignore) - defrag, missfrag = [], [] - _defrag_list(self.fragments[uniq], defrag, missfrag) - defragmented_packet = defrag[0] - defragmented_packet = defragmented_packet.__class__( - raw(defragmented_packet) - ) - return defragmented_packet - finally: - del self.fragments[uniq] - else: - return packet - - def on_packet_received(self, pkt): - pkt = self._ip_process_packet(pkt) - DefaultSession.on_packet_received(self, pkt) - - -class StringBuffer(object): - """StringBuffer is an object used to re-order data received during - a TCP transmission. - - Each TCP fragment contains a sequence number, which marks - (relatively to the first sequence number) the index of the data contained - in the fragment. - - If a TCP fragment is missed, this class will fill the missing space with - zeros. - """ - def __init__(self): - self.content = bytearray(b"") - self.content_len = 0 - self.incomplete = [] - - def append(self, data, seq): - data_len = len(data) - seq = seq - 1 - if seq + data_len > self.content_len: - self.content += b"\x00" * (seq - self.content_len + data_len) - # If data was missing, mark it. - self.incomplete.append((self.content_len, seq)) - self.content_len = seq + data_len - assert len(self.content) == self.content_len - # XXX removes empty space marker. - # for ifrag in self.incomplete: - # if [???]: - # self.incomplete.remove([???]) - memoryview(self.content)[seq:seq + data_len] = data - - def full(self): - # Should only be true when all missing data was filled up, - # (or there never was missing data) - return True # XXX - - def clear(self): - self.__init__() - - def __bool__(self): - return bool(self.content_len) - __nonzero__ = __bool__ - - def __len__(self): - return self.content_len - - def __bytes__(self): - return bytes(self.content) - __str__ = __bytes__ - - -class TCPSession(IPSession): - """A Session that matches seq/ack packets together to dissect - special protocols, such as HTTP. - - DEV: implement a class-function `tcp_reassemble` in your Packet class: - @classmethod - def tcp_reassemble(cls, data, metadata): - # data = the reassembled data from the same request/flow - # metadata = empty dictionary, that can be used to store data - [...] - # If the packet is available, return it. Otherwise don't. - # Whenever you return a packet, the buffer will be discarded. - return pkt - # Otherwise, maybe store stuff in metadata, and return None, - # as you need additional data. - return None - - A (hard to understand) example can be found in scapy/layers/http.py - """ - - fmt = ('TCP {IP:%IP.src%}{IPv6:%IPv6.src%}:%r,TCP.sport% > ' + - '{IP:%IP.dst%}{IPv6:%IPv6.dst%}:%r,TCP.dport%') - - def __init__(self, *args): - super(TCPSession, self).__init__(*args) - # The StringBuffer() is used to build a global - # string from fragments and their seq nulber - self.tcp_frags = defaultdict( - lambda: (StringBuffer(), {}) - ) - - def _process_packet(self, pkt): - """Process each packet: matches the TCP seq/ack numbers - to follow the TCP streams, and orders the fragments. - """ - from scapy.layers.inet import IP, TCP - if TCP not in pkt: - return pkt - pay = pkt[TCP].payload - if isinstance(pay, (NoPayload, conf.padding_layer)): - return pkt - new_data = raw(pay) - # Match packets by a uniqute TCP identifier - seq = pkt[TCP].seq - ident = pkt.sprintf(self.fmt) - data, metadata = self.tcp_frags[ident] - # Let's guess which class is going to be used - if "pay_class" not in metadata: - pay_class = pay.__class__ - if not hasattr(pay_class, "tcp_reassemble"): - # Cannot tcp-reassemble - return pkt - metadata["pay_class"] = pay_class - else: - pay_class = metadata["pay_class"] - # Get a relative sequence number for a storage purpose - relative_seq = metadata.get("relative_seq", None) - if not relative_seq: - relative_seq = metadata["relative_seq"] = seq - 1 - seq = seq - relative_seq - # Add the data to the buffer - # Note that this take care of retransmission packets. - data.append(new_data, seq) - # Check TCP FIN or TCP RESET - if pkt[TCP].flags.F or pkt[TCP].flags.R or pkt[TCP].flags.P: - metadata["tcp_end"] = True - # XXX TODO: check that no empty space is missing in the buffer. - # XXX Currently, if a TCP fragment was missing, we won't notice it. - packet = None - if data.full(): - # Reassemble using all previous packets - packet = pay_class.tcp_reassemble(bytes(data), metadata) - # Stack the result on top of the previous frames - if packet: - data.clear() - del self.tcp_frags[ident] - pay.underlayer.remove_payload() - if IP in pkt: - pkt[IP].len = None - pkt[IP].chksum = None - return pkt / packet - - def on_packet_received(self, pkt): - """Hook to the Sessions API: entry point of the dissection. - This will defragment IP if necessary, then process to - TCP reassembly. - """ - # First, defragment IP if necessary - pkt = self._ip_process_packet(pkt) - # Now handle TCP reassembly - pkt = self._process_packet(pkt) - DefaultSession.on_packet_received(self, pkt) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/supersocket.py b/scripts/external_libs/scapy-2.4.3/scapy/supersocket.py deleted file mode 100644 index 61d7959878..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/supersocket.py +++ /dev/null @@ -1,369 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -SuperSocket. -""" - -from __future__ import absolute_import -from select import select, error as select_error -import errno -import os -import socket -import struct -import time - -from scapy.config import conf -from scapy.consts import LINUX, DARWIN, WINDOWS -from scapy.data import MTU, ETH_P_IP -from scapy.compat import raw, bytes_encode -from scapy.error import warning, log_runtime -import scapy.modules.six as six -import scapy.packet -from scapy.utils import PcapReader, tcpdump - - -class _SuperSocket_metaclass(type): - def __repr__(self): - if self.desc is not None: - return "<%s: %s>" % (self.__name__, self.desc) - else: - return "<%s>" % self.__name__ - - -class SuperSocket(six.with_metaclass(_SuperSocket_metaclass)): - desc = None - closed = 0 - nonblocking_socket = False - read_allowed_exceptions = () - - def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0): # noqa: E501 - self.ins = socket.socket(family, type, proto) - self.outs = self.ins - self.promisc = None - - def send(self, x): - sx = raw(x) - sent = self.outs.send(sx) - try: - x.sent_time = time.time() - except AttributeError: - pass - return sent - - def recv_raw(self, x=MTU): - """Returns a tuple containing (cls, pkt_data, time)""" - return conf.raw_layer, self.ins.recv(x), None - - def recv(self, x=MTU): - cls, val, ts = self.recv_raw(x) - if not val or not cls: - return - try: - pkt = cls(val) - except KeyboardInterrupt: - raise - except Exception: - if conf.debug_dissector: - from scapy.sendrecv import debug - debug.crashed_on = (cls, val) - raise - pkt = conf.raw_layer(val) - if ts: - pkt.time = ts - return pkt - - def fileno(self): - return self.ins.fileno() - - def close(self): - if self.closed: - return - self.closed = True - if getattr(self, "outs", None): - if getattr(self, "ins", None) != self.outs: - if WINDOWS or self.outs.fileno() != -1: - self.outs.close() - if getattr(self, "ins", None): - if WINDOWS or self.ins.fileno() != -1: - self.ins.close() - - def sr(self, *args, **kargs): - from scapy import sendrecv - return sendrecv.sndrcv(self, *args, **kargs) - - def sr1(self, *args, **kargs): - from scapy import sendrecv - a, b = sendrecv.sndrcv(self, *args, **kargs) - if len(a) > 0: - return a[0][1] - else: - return None - - def sniff(self, *args, **kargs): - from scapy import sendrecv - return sendrecv.sniff(opened_socket=self, *args, **kargs) - - def tshark(self, *args, **kargs): - from scapy import sendrecv - return sendrecv.tshark(opened_socket=self, *args, **kargs) - - @staticmethod - def select(sockets, remain=conf.recv_poll_rate): - """This function is called during sendrecv() routine to select - the available sockets. - - params: - - sockets: an array of sockets that need to be selected - returns: - - an array of sockets that were selected - - the function to be called next to get the packets (i.g. recv) - """ - try: - inp, _, _ = select(sockets, [], [], remain) - except (IOError, select_error) as exc: - # select.error has no .errno attribute - if exc.args[0] != errno.EINTR: - raise - return inp, None - - def __del__(self): - """Close the socket""" - self.close() - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, traceback): - """Close the socket""" - self.close() - - -class L3RawSocket(SuperSocket): - desc = "Layer 3 using Raw sockets (PF_INET/SOCK_RAW)" - - def __init__(self, type=ETH_P_IP, filter=None, iface=None, promisc=None, nofilter=0): # noqa: E501 - self.outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW) # noqa: E501 - self.outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1) - self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type)) # noqa: E501 - if iface is not None: - self.ins.bind((iface, type)) - - def recv(self, x=MTU): - pkt, sa_ll = self.ins.recvfrom(x) - if sa_ll[2] == socket.PACKET_OUTGOING: - return None - if sa_ll[3] in conf.l2types: - cls = conf.l2types[sa_ll[3]] - lvl = 2 - elif sa_ll[1] in conf.l3types: - cls = conf.l3types[sa_ll[1]] - lvl = 3 - else: - cls = conf.default_l2 - warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using %s", sa_ll[0], sa_ll[1], sa_ll[3], cls.name) # noqa: E501 - lvl = 3 - - try: - pkt = cls(pkt) - except KeyboardInterrupt: - raise - except Exception: - if conf.debug_dissector: - raise - pkt = conf.raw_layer(pkt) - if lvl == 2: - pkt = pkt.payload - - if pkt is not None: - from scapy.arch import get_last_packet_timestamp - pkt.time = get_last_packet_timestamp(self.ins) - return pkt - - def send(self, x): - try: - sx = raw(x) - x.sent_time = time.time() - self.outs.sendto(sx, (x.dst, 0)) - except socket.error as msg: - log_runtime.error(msg) - - -class SimpleSocket(SuperSocket): - desc = "wrapper around a classic socket" - - def __init__(self, sock): - self.ins = sock - self.outs = sock - - -class StreamSocket(SimpleSocket): - desc = "transforms a stream socket into a layer 2" - nonblocking_socket = True - - def __init__(self, sock, basecls=None): - if basecls is None: - basecls = conf.raw_layer - SimpleSocket.__init__(self, sock) - self.basecls = basecls - - def recv(self, x=MTU): - pkt = self.ins.recv(x, socket.MSG_PEEK) - x = len(pkt) - if x == 0: - return None - pkt = self.basecls(pkt) - pad = pkt.getlayer(conf.padding_layer) - if pad is not None and pad.underlayer is not None: - del(pad.underlayer.payload) - from scapy.packet import NoPayload - while pad is not None and not isinstance(pad, NoPayload): - x -= len(pad.load) - pad = pad.payload - self.ins.recv(x) - return pkt - - -class SSLStreamSocket(StreamSocket): - desc = "similar usage than StreamSocket but specialized for handling SSL-wrapped sockets" # noqa: E501 - - def __init__(self, sock, basecls=None): - self._buf = b"" - super(SSLStreamSocket, self).__init__(sock, basecls) - - # 65535, the default value of x is the maximum length of a TLS record - def recv(self, x=65535): - pkt = None - if self._buf != b"": - try: - pkt = self.basecls(self._buf) - except Exception: - # We assume that the exception is generated by a buffer underflow # noqa: E501 - pass - - if not pkt: - buf = self.ins.recv(x) - if len(buf) == 0: - raise socket.error((100, "Underlying stream socket tore down")) - self._buf += buf - - x = len(self._buf) - pkt = self.basecls(self._buf) - pad = pkt.getlayer(conf.padding_layer) - - if pad is not None and pad.underlayer is not None: - del(pad.underlayer.payload) - while pad is not None and not isinstance(pad, scapy.packet.NoPayload): - x -= len(pad.load) - pad = pad.payload - self._buf = self._buf[x:] - return pkt - - -class L2ListenTcpdump(SuperSocket): - desc = "read packets at layer 2 using tcpdump" - - def __init__(self, iface=None, promisc=None, filter=None, nofilter=False, - prog=None, *arg, **karg): - self.outs = None - args = ['-w', '-', '-s', '65535'] - if iface is not None: - if WINDOWS: - try: - args.extend(['-i', iface.pcap_name]) - except AttributeError: - args.extend(['-i', iface]) - else: - args.extend(['-i', iface]) - elif WINDOWS or DARWIN: - args.extend(['-i', conf.iface.pcap_name if WINDOWS else conf.iface]) # noqa: E501 - if not promisc: - args.append('-p') - if not nofilter: - if conf.except_filter: - if filter: - filter = "(%s) and not (%s)" % (filter, conf.except_filter) - else: - filter = "not (%s)" % conf.except_filter - if filter is not None: - args.append(filter) - self.tcpdump_proc = tcpdump(None, prog=prog, args=args, getproc=True) - self.ins = PcapReader(self.tcpdump_proc.stdout) - - def recv(self, x=MTU): - return self.ins.recv(x) - - def close(self): - SuperSocket.close(self) - self.tcpdump_proc.kill() - - -class TunTapInterface(SuperSocket): - """A socket to act as the host's peer of a tun / tap interface. - - """ - desc = "Act as the host's peer of a tun / tap interface" - - def __init__(self, iface=None, mode_tun=None, *arg, **karg): - self.iface = conf.iface if iface is None else iface - self.mode_tun = ("tun" in self.iface) if mode_tun is None else mode_tun - self.closed = True - self.open() - - def open(self): - """Open the TUN or TAP device.""" - if not self.closed: - return - self.outs = self.ins = open( - "/dev/net/tun" if LINUX else ("/dev/%s" % self.iface), "r+b", - buffering=0 - ) - if LINUX: - from fcntl import ioctl - # TUNSETIFF = 0x400454ca - # IFF_TUN = 0x0001 - # IFF_TAP = 0x0002 - # IFF_NO_PI = 0x1000 - ioctl(self.ins, 0x400454ca, struct.pack( - "16sH", bytes_encode(self.iface), - 0x0001 if self.mode_tun else 0x1002, - )) - self.closed = False - - def __call__(self, *arg, **karg): - """Needed when using an instantiated TunTapInterface object for -conf.L2listen, conf.L2socket or conf.L3socket. - - """ - return self - - def recv(self, x=MTU): - if self.mode_tun: - data = os.read(self.ins.fileno(), x + 4) - proto = struct.unpack('!H', data[2:4])[0] - return conf.l3types.get(proto, conf.raw_layer)(data[4:]) - return conf.l2types.get(1, conf.raw_layer)( - os.read(self.ins.fileno(), x) - ) - - def send(self, x): - sx = raw(x) - if hasattr(x, "sent_time"): - x.sent_time = time.time() - if self.mode_tun: - try: - proto = conf.l3types[type(x)] - except KeyError: - log_runtime.warning( - "Cannot find layer 3 protocol value to send %s in " - "conf.l3types, using 0", - x.name if hasattr(x, "name") else type(x).__name__ - ) - proto = 0 - sx = struct.pack('!HH', 0, proto) + sx - try: - os.write(self.outs.fileno(), sx) - except socket.error: - log_runtime.error("%s send", self.__class__.__name__, exc_info=True) # noqa: E501 diff --git a/scripts/external_libs/scapy-2.4.3/scapy/themes.py b/scripts/external_libs/scapy-2.4.3/scapy/themes.py deleted file mode 100644 index f9cbc30064..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/themes.py +++ /dev/null @@ -1,395 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Color themes for the interactive console. -""" - -################## -# Color themes # -################## - -import cgi -import sys - - -class ColorTable: - colors = { # Format: (ansi, pygments) - # foreground - "black": ("\033[30m", "#ansiblack"), - "red": ("\033[31m", "#ansired"), - "green": ("\033[32m", "#ansigreen"), - "yellow": ("\033[33m", "#ansiyellow"), - "blue": ("\033[34m", "#ansiblue"), - "purple": ("\033[35m", "#ansipurple"), - "cyan": ("\033[36m", "#ansicyan"), - "grey": ("\033[37m", "#ansiwhite"), - "reset": ("\033[39m", "noinherit"), - # background - "bg_black": ("\033[40m", "bg:#ansiblack"), - "bg_red": ("\033[41m", "bg:#ansired"), - "bg_green": ("\033[42m", "bg:#ansigreen"), - "bg_yellow": ("\033[43m", "bg:#ansiyellow"), - "bg_blue": ("\033[44m", "bg:#ansiblue"), - "bg_purple": ("\033[45m", "bg:#ansipurple"), - "bg_cyan": ("\033[46m", "bg:#ansicyan"), - "bg_grey": ("\033[47m", "bg:#ansiwhite"), - "bg_reset": ("\033[49m", "noinherit"), - # specials - "normal": ("\033[0m", "noinherit"), # color & brightness - "bold": ("\033[1m", "bold"), - "uline": ("\033[4m", "underline"), - "blink": ("\033[5m", ""), - "invert": ("\033[7m", ""), - } - - def __repr__(self): - return "" - - def __getattr__(self, attr): - return self.colors.get(attr, [""])[0] - - def ansi_to_pygments(self, x): # Transform ansi encoded text to Pygments text # noqa: E501 - inv_map = {v[0]: v[1] for k, v in self.colors.items()} - for k, v in inv_map.items(): - x = x.replace(k, " " + v) - return x.strip() - - -Color = ColorTable() - - -def create_styler(fmt=None, before="", after="", fmt2="%s"): - def do_style(val, fmt=fmt, before=before, after=after, fmt2=fmt2): - if fmt is None: - if not isinstance(val, str): - val = str(val) - else: - val = fmt % val - return fmt2 % (before + val + after) - return do_style - - -class ColorTheme: - def __repr__(self): - return "<%s>" % self.__class__.__name__ - - def __reduce__(self): - return (self.__class__, (), ()) - - def __getattr__(self, attr): - if attr in ["__getstate__", "__setstate__", "__getinitargs__", - "__reduce_ex__"]: - raise AttributeError() - return create_styler() - - def format(self, string, fmt): - for style in fmt.split("+"): - string = getattr(self, style)(string) - return string - - -class NoTheme(ColorTheme): - pass - - -class AnsiColorTheme(ColorTheme): - def __getattr__(self, attr): - if attr.startswith("__"): - raise AttributeError(attr) - s = "style_%s" % attr - if s in self.__class__.__dict__: - before = getattr(self, s) - after = self.style_normal - elif not isinstance(self, BlackAndWhite) and attr in Color.colors: - before = Color.colors[attr][0] - after = Color.colors["normal"][0] - else: - before = after = "" - - return create_styler(before=before, after=after) - - style_normal = "" - style_prompt = "" - style_punct = "" - style_id = "" - style_not_printable = "" - style_layer_name = "" - style_field_name = "" - style_field_value = "" - style_emph_field_name = "" - style_emph_field_value = "" - style_packetlist_name = "" - style_packetlist_proto = "" - style_packetlist_value = "" - style_fail = "" - style_success = "" - style_odd = "" - style_even = "" - style_opening = "" - style_active = "" - style_closed = "" - style_left = "" - style_right = "" - style_logo = "" - - -class BlackAndWhite(AnsiColorTheme, NoTheme): - pass - - -class DefaultTheme(AnsiColorTheme): - style_normal = Color.normal - style_prompt = Color.blue + Color.bold - style_punct = Color.normal - style_id = Color.blue + Color.bold - style_not_printable = Color.grey - style_layer_name = Color.red + Color.bold - style_field_name = Color.blue - style_field_value = Color.purple - style_emph_field_name = Color.blue + Color.uline + Color.bold - style_emph_field_value = Color.purple + Color.uline + Color.bold - style_packetlist_name = Color.red + Color.bold - style_packetlist_proto = Color.blue - style_packetlist_value = Color.purple - style_fail = Color.red + Color.bold - style_success = Color.blue + Color.bold - style_even = Color.black + Color.bold - style_odd = Color.black - style_opening = Color.yellow - style_active = Color.black - style_closed = Color.grey - style_left = Color.blue + Color.invert - style_right = Color.red + Color.invert - style_logo = Color.green + Color.bold - - -class BrightTheme(AnsiColorTheme): - style_normal = Color.normal - style_punct = Color.normal - style_id = Color.yellow + Color.bold - style_layer_name = Color.red + Color.bold - style_field_name = Color.yellow + Color.bold - style_field_value = Color.purple + Color.bold - style_emph_field_name = Color.yellow + Color.bold - style_emph_field_value = Color.green + Color.bold - style_packetlist_name = Color.red + Color.bold - style_packetlist_proto = Color.yellow + Color.bold - style_packetlist_value = Color.purple + Color.bold - style_fail = Color.red + Color.bold - style_success = Color.blue + Color.bold - style_even = Color.black + Color.bold - style_odd = Color.black - style_left = Color.cyan + Color.invert - style_right = Color.purple + Color.invert - style_logo = Color.green + Color.bold - - -class RastaTheme(AnsiColorTheme): - style_normal = Color.normal + Color.green + Color.bold - style_prompt = Color.yellow + Color.bold - style_punct = Color.red - style_id = Color.green + Color.bold - style_not_printable = Color.green - style_layer_name = Color.red + Color.bold - style_field_name = Color.yellow + Color.bold - style_field_value = Color.green + Color.bold - style_emph_field_name = Color.green - style_emph_field_value = Color.green - style_packetlist_name = Color.red + Color.bold - style_packetlist_proto = Color.yellow + Color.bold - style_packetlist_value = Color.green + Color.bold - style_fail = Color.red - style_success = Color.red + Color.bold - style_even = Color.yellow - style_odd = Color.green - style_left = Color.yellow + Color.invert - style_right = Color.red + Color.invert - style_logo = Color.green + Color.bold - - -class ColorOnBlackTheme(AnsiColorTheme): - """Color theme for black backgrounds""" - style_normal = Color.normal - style_prompt = Color.green + Color.bold - style_punct = Color.normal - style_id = Color.green - style_not_printable = Color.black + Color.bold - style_layer_name = Color.yellow + Color.bold - style_field_name = Color.cyan - style_field_value = Color.purple + Color.bold - style_emph_field_name = Color.cyan + Color.bold - style_emph_field_value = Color.red + Color.bold - style_packetlist_name = Color.black + Color.bold - style_packetlist_proto = Color.yellow + Color.bold - style_packetlist_value = Color.purple + Color.bold - style_fail = Color.red + Color.bold - style_success = Color.green - style_even = Color.black + Color.bold - style_odd = Color.grey - style_opening = Color.yellow - style_active = Color.grey + Color.bold - style_closed = Color.black + Color.bold - style_left = Color.cyan + Color.bold - style_right = Color.red + Color.bold - style_logo = Color.green + Color.bold - - -class FormatTheme(ColorTheme): - def __getattr__(self, attr): - if attr.startswith("__"): - raise AttributeError(attr) - colfmt = self.__class__.__dict__.get("style_%s" % attr, "%s") - return create_styler(fmt2=colfmt) - - -class LatexTheme(FormatTheme): - style_prompt = r"\textcolor{blue}{%s}" - style_not_printable = r"\textcolor{gray}{%s}" - style_layer_name = r"\textcolor{red}{\bf %s}" - style_field_name = r"\textcolor{blue}{%s}" - style_field_value = r"\textcolor{purple}{%s}" - style_emph_field_name = r"\textcolor{blue}{\underline{%s}}" # ul - style_emph_field_value = r"\textcolor{purple}{\underline{%s}}" # ul - style_packetlist_name = r"\textcolor{red}{\bf %s}" - style_packetlist_proto = r"\textcolor{blue}{%s}" - style_packetlist_value = r"\textcolor{purple}{%s}" - style_fail = r"\textcolor{red}{\bf %s}" - style_success = r"\textcolor{blue}{\bf %s}" - style_left = r"\textcolor{blue}{%s}" - style_right = r"\textcolor{red}{%s}" -# style_even = r"}{\bf " -# style_odd = "" - style_logo = r"\textcolor{green}{\bf %s}" - - -class LatexTheme2(FormatTheme): - style_prompt = r"@`@textcolor@[@blue@]@@[@%s@]@" - style_not_printable = r"@`@textcolor@[@gray@]@@[@%s@]@" - style_layer_name = r"@`@textcolor@[@red@]@@[@@`@bfseries@[@@]@%s@]@" - style_field_name = r"@`@textcolor@[@blue@]@@[@%s@]@" - style_field_value = r"@`@textcolor@[@purple@]@@[@%s@]@" - style_emph_field_name = r"@`@textcolor@[@blue@]@@[@@`@underline@[@%s@]@@]@" - style_emph_field_value = r"@`@textcolor@[@purple@]@@[@@`@underline@[@%s@]@@]@" # noqa: E501 - style_packetlist_name = r"@`@textcolor@[@red@]@@[@@`@bfseries@[@@]@%s@]@" - style_packetlist_proto = r"@`@textcolor@[@blue@]@@[@%s@]@" - style_packetlist_value = r"@`@textcolor@[@purple@]@@[@%s@]@" - style_fail = r"@`@textcolor@[@red@]@@[@@`@bfseries@[@@]@%s@]@" - style_success = r"@`@textcolor@[@blue@]@@[@@`@bfserices@[@@]@%s@]@" - style_even = r"@`@textcolor@[@gray@]@@[@@`@bfseries@[@@]@%s@]@" -# style_odd = r"@`@textcolor@[@black@]@@[@@`@bfseries@[@@]@%s@]@" - style_left = r"@`@textcolor@[@blue@]@@[@%s@]@" - style_right = r"@`@textcolor@[@red@]@@[@%s@]@" - style_logo = r"@`@textcolor@[@green@]@@[@@`@bfseries@[@@]@%s@]@" - - -class HTMLTheme(FormatTheme): - style_prompt = "%s" - style_not_printable = "%s" - style_layer_name = "%s" - style_field_name = "%s" - style_field_value = "%s" - style_emph_field_name = "%s" - style_emph_field_value = "%s" - style_packetlist_name = "%s" - style_packetlist_proto = "%s" - style_packetlist_value = "%s" - style_fail = "%s" - style_success = "%s" - style_even = "%s" - style_odd = "%s" - style_left = "%s" - style_right = "%s" - - -class HTMLTheme2(HTMLTheme): - style_prompt = "#[#span class=prompt#]#%s#[#/span#]#" - style_not_printable = "#[#span class=not_printable#]#%s#[#/span#]#" - style_layer_name = "#[#span class=layer_name#]#%s#[#/span#]#" - style_field_name = "#[#span class=field_name#]#%s#[#/span#]#" - style_field_value = "#[#span class=field_value#]#%s#[#/span#]#" - style_emph_field_name = "#[#span class=emph_field_name#]#%s#[#/span#]#" - style_emph_field_value = "#[#span class=emph_field_value#]#%s#[#/span#]#" - style_packetlist_name = "#[#span class=packetlist_name#]#%s#[#/span#]#" - style_packetlist_proto = "#[#span class=packetlist_proto#]#%s#[#/span#]#" - style_packetlist_value = "#[#span class=packetlist_value#]#%s#[#/span#]#" - style_fail = "#[#span class=fail#]#%s#[#/span#]#" - style_success = "#[#span class=success#]#%s#[#/span#]#" - style_even = "#[#span class=even#]#%s#[#/span#]#" - style_odd = "#[#span class=odd#]#%s#[#/span#]#" - style_left = "#[#span class=left#]#%s#[#/span#]#" - style_right = "#[#span class=right#]#%s#[#/span#]#" - - -def apply_ipython_style(shell): - """Updates the specified IPython console shell with - the conf.color_theme scapy theme.""" - try: - from IPython.terminal.prompts import Prompts, Token - except Exception: - from scapy.error import log_loading - log_loading.warning( - "IPython too old. Shell color won't be handled." - ) - return - from scapy.config import conf - scapy_style = {} - # Overwrite colors - if isinstance(conf.color_theme, NoTheme): - shell.colors = 'nocolor' - elif isinstance(conf.color_theme, BrightTheme): - # lightbg is optimized for light backgrounds - shell.colors = 'lightbg' - elif isinstance(conf.color_theme, ColorOnBlackTheme): - # linux is optimised for dark backgrounds - shell.colors = 'linux' - else: - # default - shell.colors = 'neutral' - try: - get_ipython() - # This function actually contains tons of hacks - color_magic = shell.magics_manager.magics["line"]["colors"] - color_magic(shell.colors) - except NameError: - pass - # Prompt Style - if isinstance(conf.prompt, Prompts): - # Set custom prompt style - shell.prompts_class = conf.prompt - else: - if isinstance(conf.color_theme, (FormatTheme, NoTheme)): - # Formatable - if isinstance(conf.color_theme, HTMLTheme): - prompt = cgi.escape(conf.prompt) - elif isinstance(conf.color_theme, LatexTheme): - from scapy.utils import tex_escape - prompt = tex_escape(conf.prompt) - else: - prompt = conf.prompt - prompt = conf.color_theme.prompt(prompt) - else: - # Needs to be manually set - prompt = str(conf.prompt) - scapy_style[Token.Prompt] = Color.ansi_to_pygments( - conf.color_theme.style_prompt - ) - - class ClassicPrompt(Prompts): - def in_prompt_tokens(self, cli=None): - return [(Token.Prompt, prompt), ] - - def out_prompt_tokens(self): - return [(Token.OutPrompt, ''), ] - # Apply classic prompt style - shell.prompts_class = ClassicPrompt - sys.ps1 = prompt - # Register scapy color style - shell.highlighting_style_overrides = scapy_style - # Apply if Live - try: - get_ipython().refresh_style() - except NameError: - pass diff --git a/scripts/external_libs/scapy-2.4.3/scapy/tools/UTscapy.py b/scripts/external_libs/scapy-2.4.3/scapy/tools/UTscapy.py deleted file mode 100644 index 31971c2410..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/tools/UTscapy.py +++ /dev/null @@ -1,1001 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -# flake8: noqa: E501 - -""" -Unit testing infrastructure for Scapy -""" - -from __future__ import absolute_import -from __future__ import print_function -import sys -import getopt -import glob -import importlib -import hashlib -import copy -import bz2 -import os.path -import time -import traceback -import warnings -import zlib - -from scapy.consts import WINDOWS -import scapy.modules.six as six -from scapy.modules.six.moves import range -from scapy.compat import base64_bytes, bytes_hex, plain_str - - -# Util class # - -class Bunch: - __init__ = lambda self, **kw: setattr(self, '__dict__', kw) - -def retry_test(func): - """Retries the passed function 3 times before failing""" - success = False - ex = Exception("Unknown") - for i in six.moves.range(3): - try: - result = func() - except Exception as e: - time.sleep(1) - ex = e - else: - success = True - break - if not success: - raise ex - assert success - return result - -# Import tool # - - -def import_module(name): - if name.endswith(".py"): - name = name[:-3] - try: - return importlib.import_module(name, package="scapy") - except Exception: - return importlib.import_module(name) - - -# INTERNAL/EXTERNAL FILE EMBEDDING # - -class File: - def __init__(self, name, URL, local): - self.name = name - self.local = local.encode("utf8") - self.URL = URL - - def get_local(self): - return bz2.decompress(base64_bytes(self.local)) - - def get_URL(self): - return self.URL - - def write(self, dir): - if dir: - dir += "/" - with open(dir + self.name, "wb") as fdesc: - fdesc.write(self.get_local()) - - -# Embed a base64 encoded bziped version of js and css files -# to work if you can't reach Internet. -class External_Files: - UTscapy_js = File("UTscapy.js", "https://scapy.net/files/UTscapy/UTscapy.js", # noqa: E501 - """QlpoOTFBWSZTWWVijKQAAXxfgERUYOvAChIhBAC -/79+qQAH8AFA0poANAMjQAAAGABo0NGEZNBo0\n0BhgAaNDRhGTQaNNAYFURJinp -lGaKbRkJiekzSenqmpA0Gm1LFMpRUklVQlK9WUTZYpNFI1IiEWE\nFT09Sfj5uO+ -qO6S5DQwKIxM92+Zku94wL6V/1KTKan2c66Ug6SmVKy1ZIrgauxMVLF5xLH0lJRQ -u\nKlqLF10iatlTzqvw7S9eS3+h4lu3GZyMgoOude3NJ1pQy8eo+X96IYZw+yneh -siPj73m0rnvQ3QX\nZ9BJQiZQYQ5/uNcl2WOlC5vyQqV/BWsnr2NZYLYXQLDs/Bf -fk4ZfR4/SH6GfA5Xlek4xHNHqbSsR\nbREOgueXo3kcYi94K6hSO3ldD2O/qJXOF -qJ8o3TE2aQahxtQpCVUKQMvODHwu2YkaORYZC6gihEa\nllcHDIAtRPScBACAJnU -ggYhLDX6DEko7nC9GvAw5OcEkiyDUbLdiGCzDaXWMC2DuQ2Y6sGf6NcRu\nON7QS -bhHsPc4KKmZ/xdyRThQkGVijKQ=\n""") - UTscapy_css = File("UTscapy.css", "https://scapy.net/files/UTscapy/UTscapy.css", # noqa: E501 - """QlpoOTFBWSZTWbpATIwAAFpfgHwQSB//+Cpj2Q -C//9/6UAS5t7qcLut3NNDp0gxKMmpqaep6n6iP\n1J+pPU0yAAaeoaDI0BJCTJqa -j1BoaGhoAAPSAAAJNSRqmmk8TQmj1DT1Hom1HkQABoNDmmJgATAB\nMAAJgACYJI -hDQUzCR5Q0niRoaAGgGmZS+faw7LNbkliDG1Q52WJCd85cxRVVKegld8qCRISoto -GD\nEGREFEYRW0CxAgTb13lodjuN7E1aCFgRFVhiEmZAZ/ek+XR0c8DWiAKpBgY2 -LNpQ1rOvlnoUI1Al\n0ySaP1w2MyFxoQqRicScCm6WnQOxDnufxk8s2deLLKlN+r -fvxyTTCGRAWZONkVGIxVQRZGZLeAwH\nbpQXZcYj467i85knEOYWmLcokaqEGYGS -xMCpD+cOIaL7GCxEU/aNSlWFNCvQBvzb915huAgdIdD2\nya9ZQGoqrmtommfAxu -7FGTDBNBfir9UkAMmT1KRzxasJ0n2OE+mlgTZzJnhydbJaMtAk8DJzUuvv\nZpc3 -CJLVyr8F3NmIQO5E3SJSY3SQnk1CQwlELqFutXjeWWzmiywo7xJk5rUcVOV9+Ro4 -96WmXsUr\nkKhNocbnFztqPhesccW5kja+KuNFmzdw4DVOBJ2JPhGOYSwCUiwUe2 -kOshYBdULUmwYwToAGdgA9\n5n3bSpG85LUFIE0Cw78EYVgY0ESnYW5UdfgBhj1w -PiiXDEG2vAtr38O9kdwg3tFU/0okilEjDYDa\nEfkomkLUSokmE8g1fMYBqQyyaP -RWmySO3EtAuMVhQqIuMldOzLqWubl7k1MnhuBaELOgtB2TChcS\n0k7jvgdBKIef -UkdAf3t2GO/LVSrDvkcb4l4TrwrI7JeCo8pBvXqZBqZJSqbsAziG7QDQVNqdtFGz -\nEvMKOvKvUQ6mJFigLxBnziGQGQDEMQPSGhlV2BwAN6rZEmLwgED0OrEiSxXDcB -MDskp36AV7IbKa\nCila/Wm1BKhBF+ZIqtiFyYpUhI1Q5+JK0zK7aVyLS9y7GaSr -NCRpr7uaa1UgapVKs6wKKQzYCWsV\n8iCGrAkgWZEnDMJWCGUZOIpcmMle1UXSAl -d5OoUYXNo0L7WSOcxEkSGjCcRhjvMRP1pAUuBPRCRA\n2lhC0ZgLYDAf5V2agMUa -ki1ZgOQDXQ7aIDTdjGRTgnzPML0V1X+tIoSSZmZhrxZbluMWGEkwwky6\n0ObWIM -cEbX4cawPPBVc6m5UUPbEmBANyjtNvTKE2ri7oOmBVKIMLqQKm+4rlmisu2uGSxW -zTov5w\nqQDp61FkHk40wzQUKk4YcBlbQT1l8VXeZJYAVFjSJIcC8JykBYZJ1yka -I4LDm5WP7s2NaRkhhV7A\nFVSD5zA8V/DJzfTk0QHmCT2wRgwPKjP60EqqlDUaST -/i7kinChIXSAmRgA==\n""") - - def get_local_dict(cls): - return {x: y.name for (x, y) in six.iteritems(cls.__dict__) - if isinstance(y, File)} - get_local_dict = classmethod(get_local_dict) - - def get_URL_dict(cls): - return {x: y.URL for (x, y) in six.iteritems(cls.__dict__) - if isinstance(y, File)} - get_URL_dict = classmethod(get_URL_dict) - - -# HELPER CLASSES FOR PARAMETRING OUTPUT FORMAT # - -class EnumClass: - def from_string(cls, x): - return cls.__dict__[x.upper()] - from_string = classmethod(from_string) - - -class Format(EnumClass): - TEXT = 1 - ANSI = 2 - HTML = 3 - LATEX = 4 - XUNIT = 5 - - -# TEST CLASSES # - -class TestClass: - def __getitem__(self, item): - return getattr(self, item) - - def add_keywords(self, kws): - if isinstance(kws, six.string_types): - kws = [kws.lower()] - for kwd in kws: - kwd = kwd.lower() - if kwd.startswith('-'): - try: - self.keywords.remove(kwd[1:]) - except KeyError: - pass - else: - self.keywords.add(kwd) - - -class TestCampaign(TestClass): - def __init__(self, title): - self.title = title - self.filename = None - self.headcomments = "" - self.campaign = [] - self.keywords = set() - self.crc = None - self.sha = None - self.preexec = None - self.preexec_output = None - self.end_pos = 0 - self.interrupted = False - def add_testset(self, testset): - self.campaign.append(testset) - testset.keywords.update(self.keywords) - def trunc(self, index): - self.campaign = self.campaign[:index] - def startNum(self, beginpos): - for ts in self: - for t in ts: - t.num = beginpos - beginpos += 1 - self.end_pos = beginpos - - def __iter__(self): - return self.campaign.__iter__() - - def all_tests(self): - for ts in self: - for t in ts: - yield t - - -class TestSet(TestClass): - def __init__(self, name): - self.name = name - self.tests = [] - self.comments = "" - self.keywords = set() - self.crc = None - self.expand = 1 - - def add_test(self, test): - self.tests.append(test) - test.keywords.update(self.keywords) - def trunc(self, index): - self.tests = self.tests[:index] - def __iter__(self): - return self.tests.__iter__() - - -class UnitTest(TestClass): - def __init__(self, name): - self.name = name - self.test = "" - self.comments = "" - self.result = "passed" # make instance True at init to have a different truth value than None - self.output = "" - self.num = -1 - self.keywords = set() - self.crc = None - self.expand = 1 - - def decode(self): - if six.PY2: - self.test = self.test.decode("utf8", "ignore") - self.output = self.output.decode("utf8", "ignore") - self.comments = self.comments.decode("utf8", "ignore") - self.result = self.result.decode("utf8", "ignore") - - def __nonzero__(self): - return self.result == "passed" - __bool__ = __nonzero__ - - -# Careful note: all data not included will be set by default. -# Use -c as first argument !! -def parse_config_file(config_path, verb=3): - """Parse provided json to get configuration - Empty default json: - { - "testfiles": [], - "breakfailed": true, - "onlyfailed": false, - "verb": 3, - "dump": 0, - "crc": true, - "scapy": "scapy", - "preexec": {}, - "global_preexec": "", - "outputfile": null, - "local": true, - "format": "ansi", - "num": null, - "modules": [], - "kw_ok": [], - "kw_ko": [] - } - - """ - import json - with open(config_path) as config_file: - data = json.load(config_file, encoding="utf8") - if verb > 2: - print("### Loaded config file", config_path, file=sys.stderr) - - def get_if_exist(key, default): - return data[key] if key in data else default - return Bunch(testfiles=get_if_exist("testfiles", []), - breakfailed=get_if_exist("breakfailed", True), - remove_testfiles=get_if_exist("remove_testfiles", []), - onlyfailed=get_if_exist("onlyfailed", False), - verb=get_if_exist("verb", 3), - dump=get_if_exist("dump", 0), crc=get_if_exist("crc", 1), - scapy=get_if_exist("scapy", "scapy"), - preexec=get_if_exist("preexec", {}), - global_preexec=get_if_exist("global_preexec", ""), - outfile=get_if_exist("outputfile", sys.stdout), - local=get_if_exist("local", False), - num=get_if_exist("num", None), - modules=get_if_exist("modules", []), - kw_ok=get_if_exist("kw_ok", []), - kw_ko=get_if_exist("kw_ko", []), - format=get_if_exist("format", "ansi")) - -# PARSE CAMPAIGN # - - -def parse_campaign_file(campaign_file): - test_campaign = TestCampaign("Test campaign") - test_campaign.filename = campaign_file.name - testset = None - test = None - testnb = 0 - - for l in campaign_file.readlines(): - if l[0] == '#': - continue - if l[0] == "~": - (test or testset or test_campaign).add_keywords(l[1:].split()) - elif l[0] == "%": - test_campaign.title = l[1:].strip() - elif l[0] == "+": - testset = TestSet(l[1:].strip()) - test_campaign.add_testset(testset) - test = None - elif l[0] == "=": - test = UnitTest(l[1:].strip()) - test.num = testnb - testnb += 1 - if testset is None: - error_m = "Please create a test set (i.e. '+' section)." - raise getopt.GetoptError(error_m) - testset.add_test(test) - elif l[0] == "*": - if test is not None: - test.comments += l[1:] - elif testset is not None: - testset.comments += l[1:] - else: - test_campaign.headcomments += l[1:] - else: - if test is None: - if l.strip(): - print("Unknown content [%s]" % l.strip(), file=sys.stderr) - else: - test.test += l - return test_campaign - - -def dump_campaign(test_campaign): - print("#" * (len(test_campaign.title) + 6)) - print("## %(title)s ##" % test_campaign) - print("#" * (len(test_campaign.title) + 6)) - if test_campaign.sha and test_campaign.crc: - print("CRC=[%(crc)s] SHA=[%(sha)s]" % test_campaign) - print("from file %(filename)s" % test_campaign) - print() - for ts in test_campaign: - if ts.crc: - print("+--[%s]%s(%s)--" % (ts.name, "-" * max(2, 80 - len(ts.name) - 18), ts.crc)) # noqa: E501 - else: - print("+--[%s]%s" % (ts.name, "-" * max(2, 80 - len(ts.name) - 6))) - if ts.keywords: - print(" kw=%s" % ",".join(ts.keywords)) - for t in ts: - print("%(num)03i %(name)s" % t) - c = k = "" - if t.keywords: - k = "kw=%s" % ",".join(t.keywords) - if t.crc: - c = "[%(crc)s] " % t - if c or k: - print(" %s%s" % (c, k)) - - -# COMPUTE CAMPAIGN DIGESTS # -if six.PY2: - def crc32(x): - return "%08X" % (0xffffffff & zlib.crc32(x)) - - def sha1(x): - return hashlib.sha1(x).hexdigest().upper() -else: - def crc32(x): - return "%08X" % (0xffffffff & zlib.crc32(bytearray(x, "utf8"))) - - def sha1(x): - return hashlib.sha1(x.encode("utf8")).hexdigest().upper() - - -def compute_campaign_digests(test_campaign): - dc = "" - for ts in test_campaign: - dts = "" - for t in ts: - dt = t.test.strip() - t.crc = crc32(dt) - dts += "\0" + dt - ts.crc = crc32(dts) - dc += "\0\x01" + dts - test_campaign.crc = crc32(dc) - with open(test_campaign.filename) as fdesc: - test_campaign.sha = sha1(fdesc.read()) - - -# FILTER CAMPAIGN # - -def filter_tests_on_numbers(test_campaign, num): - if num: - for ts in test_campaign: - ts.tests = [t for t in ts.tests if t.num in num] - test_campaign.campaign = [ts for ts in test_campaign.campaign - if ts.tests] - - -def _filter_tests_kw(test_campaign, kw, keep): - def kw_match(lst, kw): - return any(k for k in lst if kw == k) - - if kw: - kw = kw.lower() - if keep: - cond = lambda x: x - else: - cond = lambda x: not x - for ts in test_campaign: - ts.tests = [t for t in ts.tests if cond(kw_match(t.keywords, kw))] - - -def filter_tests_keep_on_keywords(test_campaign, kw): - return _filter_tests_kw(test_campaign, kw, True) - - -def filter_tests_remove_on_keywords(test_campaign, kw): - return _filter_tests_kw(test_campaign, kw, False) - - -def remove_empty_testsets(test_campaign): - test_campaign.campaign = [ts for ts in test_campaign.campaign if ts.tests] - - -#### RUN TEST ##### - -def run_test(test, get_interactive_session, verb=3, ignore_globals=None, my_globals=None): - """An internal UTScapy function to run a single test""" - test.output, res = get_interactive_session(test.test.strip(), ignore_globals=ignore_globals, verb=verb, my_globals=my_globals) - test.result = "failed" - try: - if res is None or res: - test.result = "passed" - if test.output.endswith('KeyboardInterrupt\n'): - test.result = "interrupted" - raise KeyboardInterrupt - except Exception: - test.output += "UTscapy: Error during result interpretation:\n" - test.output += "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2],)) - finally: - if test.result == "failed": - from scapy.sendrecv import debug - # Add optional debugging data to log - if debug.crashed_on: - cls, val = debug.crashed_on - test.output += "\n\nPACKET DISSECTION FAILED ON:\n %s(hex_bytes('%s'))" % (cls.__name__, plain_str(bytes_hex(val))) - debug.crashed_on = None - test.decode() - if verb > 1: - print("%(result)6s %(crc)s %(name)s" % test, file=sys.stderr) - - return bool(test) - -#### RUN CAMPAIGN ##### - -def import_UTscapy_tools(ses): - """Adds UTScapy tools directly to a session""" - ses["retry_test"] = retry_test - ses["Bunch"] = Bunch - -def run_campaign(test_campaign, get_interactive_session, verb=3, ignore_globals=None): # noqa: E501 - passed = failed = 0 - scapy_ses = importlib.import_module(".all", "scapy").__dict__ - import_UTscapy_tools(scapy_ses) - if test_campaign.preexec: - test_campaign.preexec_output = get_interactive_session(test_campaign.preexec.strip(), ignore_globals=ignore_globals, my_globals=scapy_ses)[0] - try: - for i, testset in enumerate(test_campaign): - for j, t in enumerate(testset): - if run_test(t, get_interactive_session, verb, my_globals=scapy_ses): - passed += 1 - else: - failed += 1 - except KeyboardInterrupt: - failed += 1 - testset.trunc(j+1) - test_campaign.trunc(i+1) - test_campaign.interrupted = True - if verb: - print("Campaign interrupted!", file=sys.stderr) - - test_campaign.passed = passed - test_campaign.failed = failed - if verb: - print("Campaign CRC=%(crc)s SHA=%(sha)s" % test_campaign, file=sys.stderr) # noqa: E501 - print("PASSED=%i FAILED=%i" % (passed, failed), file=sys.stderr) - return failed - - -# INFO LINES # - -def info_line(test_campaign): - filename = test_campaign.filename - if filename is None: - return "Run %s by UTscapy" % time.ctime() - else: - return "Run %s from [%s] by UTscapy" % (time.ctime(), filename) - - -def html_info_line(test_campaign): - filename = test_campaign.filename - if filename is None: - return """Run %s by UTscapy
""" % time.ctime() # noqa: E501 - else: - return """Run %s from [%s] by UTscapy
""" % (time.ctime(), filename) # noqa: E501 - - -# CAMPAIGN TO something # - -def campaign_to_TEXT(test_campaign): - output="%(title)s\n" % test_campaign - output += "-- "+info_line(test_campaign)+"\n\n" - output += "Passed=%(passed)i\nFailed=%(failed)i\n\n%(headcomments)s\n" % test_campaign - - for testset in test_campaign: - if any(t.expand for t in testset): - output += "######\n## %(name)s\n######\n%(comments)s\n\n" % testset - for t in testset: - if t.expand: - output += "###(%(num)03i)=[%(result)s] %(name)s\n%(comments)s\n%(output)s\n\n" % t # noqa: E501 - - return output - - -def campaign_to_ANSI(test_campaign): - return campaign_to_TEXT(test_campaign) - - -def campaign_to_xUNIT(test_campaign): - output = '\n\n' - for testset in test_campaign: - for t in testset: - output += ' %(title)s - -

-""" % test_campaign - - if test_campaign.crc is not None and test_campaign.sha is not None: - output += "CRC=%(crc)s SHA=%(sha)s
" % test_campaign - output += ""+html_info_line(test_campaign)+"" - output += "".join([ - test_campaign.headcomments, - "\n

", - "PASSED=%(passed)i FAILED=%(failed)i" % test_campaign, - " INTERRUPTED!" if test_campaign.interrupted else "", - "

\n\n", - ]) - - for testset in test_campaign: - output += "

" % testset - if testset.crc is not None: - output += "%(crc)s " % testset - output += "%(name)s

\n%(comments)s\n
    \n" % testset - for t in testset: - output += """
  • \n""" % t - if t.expand == 2: - output += """ - --%(num)03i- -""" % t - else: - output += """ -+%(num)03i+ - -""" % t - if t.crc is not None: - output += "%(crc)s\n" % t - output += """%(name)s\n -""" % t - output += "\n
\n\n" - return output - - -def pack_html_campaigns(runned_campaigns, data, local=False, title=None): - output = """ - - -%(title)s -

UTScapy tests

- -Shrink All -Expand All -Expand Passed -Expand Failed - -

-""" - for test_campaign in runned_campaigns: - for ts in test_campaign: - for t in ts: - output += """%(num)03i\n""" % t - - output += """

\n\n - - - - -%(data)s - -""" - out_dict = {'data': data, 'title': title if title else "UTScapy tests"} - if local: - dirname = os.path.dirname(test_campaign.output_file) - External_Files.UTscapy_js.write(dirname) - External_Files.UTscapy_css.write(dirname) - out_dict.update(External_Files.get_local_dict()) - else: - out_dict.update(External_Files.get_URL_dict()) - - output %= out_dict - return output - - -def campaign_to_LATEX(test_campaign): - output = r"""\documentclass{report} -\usepackage{alltt} -\usepackage{xcolor} -\usepackage{a4wide} -\usepackage{hyperref} - -\title{%(title)s} -\date{%%s} - -\begin{document} -\maketitle -\tableofcontents - -\begin{description} -\item[Passed:] %(passed)i -\item[Failed:] %(failed)i -\end{description} - -%(headcomments)s - -""" % test_campaign - output %= info_line(test_campaign) - - for testset in test_campaign: - output += "\\chapter{%(name)s}\n\n%(comments)s\n\n" % testset - for t in testset: - if t.expand: - output += r"""\section{%(name)s} - -[%(num)03i] [%(result)s] - -%(comments)s -\begin{alltt} -%(output)s -\end{alltt} - -""" % t - - output += "\\end{document}\n" - return output - - -#### USAGE #### - -def usage(): - print("""Usage: UTscapy [-m module] [-f {text|ansi|HTML|LaTeX}] [-o output_file] - [-t testfile] [-T testfile] [-k keywords [-k ...]] [-K keywords [-K ...]] - [-l] [-b] [-d|-D] [-F] [-q[q]] [-P preexecute_python_code] - [-s /path/to/scapy] [-c configfile] --t\t\t: provide test files (can be used many times) --T\t\t: if -t is used with *, remove a specific file (can be used many times) --l\t\t: generate local .js and .css files --F\t\t: expand only failed tests --b\t\t: stop at first failed campaign --d\t\t: dump campaign --D\t\t: dump campaign and stop --C\t\t: don't calculate CRC and SHA --s\t\t: path to scapy.py --c\t\t: load a .utsc config file --q\t\t: quiet mode --qq\t\t: [silent mode] --n \t: only tests whose numbers are given (eg. 1,3-7,12) --m \t: additional module to put in the namespace --k ,,...\t: include only tests with one of those keywords (can be used many times) --K ,,...\t: remove tests with one of those keywords (can be used many times) --P -""", file=sys.stderr) - raise SystemExit - - -# MAIN # - -def execute_campaign(TESTFILE, OUTPUTFILE, PREEXEC, NUM, KW_OK, KW_KO, DUMP, - FORMAT, VERB, ONLYFAILED, CRC, autorun_func, pos_begin=0, ignore_globals=None): # noqa: E501 - # Parse test file - test_campaign = parse_campaign_file(TESTFILE) - - # Report parameters - if PREEXEC: - test_campaign.preexec = PREEXEC - - # Compute campaign CRC and SHA - if CRC: - compute_campaign_digests(test_campaign) - - # Filter out unwanted tests - filter_tests_on_numbers(test_campaign, NUM) - for k in KW_OK: - filter_tests_keep_on_keywords(test_campaign, k) - for k in KW_KO: - filter_tests_remove_on_keywords(test_campaign, k) - - remove_empty_testsets(test_campaign) - - # Dump campaign - if DUMP: - dump_campaign(test_campaign) - if DUMP > 1: - sys.exit() - - # Run tests - test_campaign.output_file = OUTPUTFILE - result = run_campaign(test_campaign, autorun_func[FORMAT], verb=VERB, ignore_globals=None) # noqa: E501 - - # Shrink passed - if ONLYFAILED: - for t in test_campaign.all_tests(): - if t: - t.expand = 0 - else: - t.expand = 2 - - # Generate report - if FORMAT == Format.TEXT: - output = campaign_to_TEXT(test_campaign) - elif FORMAT == Format.ANSI: - output = campaign_to_ANSI(test_campaign) - elif FORMAT == Format.HTML: - test_campaign.startNum(pos_begin) - output = campaign_to_HTML(test_campaign) - elif FORMAT == Format.LATEX: - output = campaign_to_LATEX(test_campaign) - elif FORMAT == Format.XUNIT: - output = campaign_to_xUNIT(test_campaign) - - return output, (result == 0), test_campaign - - -def resolve_testfiles(TESTFILES): - for tfile in TESTFILES[:]: - if "*" in tfile: - TESTFILES.remove(tfile) - TESTFILES.extend(glob.glob(tfile)) - return TESTFILES - - -def main(): - argv = sys.argv[1:] - ignore_globals = list(six.moves.builtins.__dict__) - - # Parse arguments - - FORMAT = Format.ANSI - OUTPUTFILE = sys.stdout - LOCAL = 0 - NUM = None - KW_OK = [] - KW_KO = [] - DUMP = 0 - CRC = True - BREAKFAILED = True - ONLYFAILED = False - VERB = 3 - GLOB_PREEXEC = "" - PREEXEC_DICT = {} - SCAPY = "scapy" - MODULES = [] - TESTFILES = [] - try: - opts = getopt.getopt(argv, "o:t:T:c:f:hbln:m:k:K:DdCFqP:s:") - for opt, optarg in opts[0]: - if opt == "-h": - usage() - elif opt == "-b": - BREAKFAILED = True - elif opt == "-F": - ONLYFAILED = True - elif opt == "-q": - VERB -= 1 - elif opt == "-D": - DUMP = 2 - elif opt == "-d": - DUMP = 1 - elif opt == "-C": - CRC = False - elif opt == "-s": - SCAPY = optarg - elif opt == "-P": - GLOB_PREEXEC += "\n" + optarg - elif opt == "-f": - try: - FORMAT = Format.from_string(optarg) - except KeyError as msg: - raise getopt.GetoptError("Unknown output format %s" % msg) - elif opt == "-t": - TESTFILES.append(optarg) - TESTFILES = resolve_testfiles(TESTFILES) - elif opt == "-T": - TESTFILES.remove(optarg) - elif opt == "-c": - data = parse_config_file(optarg, VERB) - BREAKFAILED = data.breakfailed - ONLYFAILED = data.onlyfailed - VERB = data.verb - DUMP = data.dump - CRC = data.crc - SCAPY = data.scapy - PREEXEC_DICT = data.preexec - GLOB_PREEXEC = data.global_preexec - OUTPUTFILE = data.outfile - TESTFILES = data.testfiles - LOCAL = 1 if data.local else 0 - NUM = data.num - MODULES = data.modules - KW_OK.extend(data.kw_ok) - KW_KO.extend(data.kw_ko) - try: - FORMAT = Format.from_string(data.format) - except KeyError as msg: - raise getopt.GetoptError("Unknown output format %s" % msg) - TESTFILES = resolve_testfiles(TESTFILES) - for testfile in resolve_testfiles(data.remove_testfiles): - try: - TESTFILES.remove(testfile) - except ValueError: - error_m = "Cannot remove %s from test files" % testfile - raise getopt.GetoptError(error_m) - elif opt == "-o": - OUTPUTFILE = optarg - if not os.access(os.path.dirname(os.path.abspath(OUTPUTFILE)), os.W_OK): - raise getopt.GetoptError("Cannot write to file %s" % OUTPUTFILE) - elif opt == "-l": - LOCAL = 1 - elif opt == "-n": - NUM = [] - for v in (x.strip() for x in optarg.split(",")): - try: - NUM.append(int(v)) - except ValueError: - v1, v2 = [int(e) for e in v.split('-', 1)] - NUM.extend(range(v1, v2 + 1)) - elif opt == "-m": - MODULES.append(optarg) - elif opt == "-k": - KW_OK.extend(optarg.split(",")) - elif opt == "-K": - KW_KO.extend(optarg.split(",")) - - # Discard Python3 tests when using Python2 - if six.PY2: - KW_KO.append("python3_only") - - if VERB > 2: - print("### Booting scapy...", file=sys.stderr) - try: - from scapy import all as scapy - except Exception as e: - print("[CRITICAL]: Cannot import Scapy: %s" % e, file=sys.stderr) - traceback.print_exc() - sys.exit(1) # Abort the tests - - for m in MODULES: - try: - mod = import_module(m) - six.moves.builtins.__dict__.update(mod.__dict__) - except ImportError as e: - raise getopt.GetoptError("cannot import [%s]: %s" % (m, e)) - - if WINDOWS: - from scapy.arch.windows import route_add_loopback - route_add_loopback() - - # Add SCAPY_ROOT_DIR environment variable, used for tests - os.environ['SCAPY_ROOT_DIR'] = os.environ.get("PWD", os.getcwd()) - - except getopt.GetoptError as msg: - print("ERROR:", msg, file=sys.stderr) - raise SystemExit - - autorun_func = { - Format.TEXT: scapy.autorun_get_text_interactive_session, - Format.ANSI: scapy.autorun_get_ansi_interactive_session, - Format.HTML: scapy.autorun_get_html_interactive_session, - Format.LATEX: scapy.autorun_get_latex_interactive_session, - Format.XUNIT: scapy.autorun_get_text_interactive_session, - } - - if VERB > 2: - print("### Starting tests...", file=sys.stderr) - - glob_output = "" - glob_result = 0 - glob_title = None - - UNIQUE = len(TESTFILES) == 1 - - # Resolve tags and asterix - for prex in six.iterkeys(copy.copy(PREEXEC_DICT)): - if "*" in prex: - pycode = PREEXEC_DICT[prex] - del PREEXEC_DICT[prex] - for gl in glob.iglob(prex): - _pycode = pycode.replace("%name%", os.path.splitext(os.path.split(gl)[1])[0]) # noqa: E501 - PREEXEC_DICT[gl] = _pycode - - pos_begin = 0 - - runned_campaigns = [] - # Execute all files - for TESTFILE in TESTFILES: - if VERB > 2: - print("### Loading:", TESTFILE, file=sys.stderr) - PREEXEC = PREEXEC_DICT[TESTFILE] if TESTFILE in PREEXEC_DICT else GLOB_PREEXEC - with open(TESTFILE) as testfile: - output, result, campaign = execute_campaign(testfile, OUTPUTFILE, - PREEXEC, NUM, KW_OK, KW_KO, - DUMP, FORMAT, VERB, ONLYFAILED, - CRC, autorun_func, pos_begin, - ignore_globals) - runned_campaigns.append(campaign) - pos_begin = campaign.end_pos - if UNIQUE: - glob_title = campaign.title - glob_output += output - if not result: - glob_result = 1 - if BREAKFAILED: - break - - if VERB > 2: - print("### Writing output...", file=sys.stderr) - # Concenate outputs - if FORMAT == Format.HTML: - glob_output = pack_html_campaigns(runned_campaigns, glob_output, LOCAL, glob_title) - - # Write the final output - # Note: on Python 2, we force-encode to ignore ascii errors - # on Python 3, we need to detect the type of stream - if OUTPUTFILE == sys.stdout: - OUTPUTFILE.write(glob_output.encode("utf8", "ignore") - if 'b' in OUTPUTFILE.mode or six.PY2 else glob_output) - else: - with open(OUTPUTFILE, "wb") as f: - f.write(glob_output.encode("utf8", "ignore") - if 'b' in f.mode or six.PY2 else glob_output) - - # Delete scapy's test environment vars - del os.environ['SCAPY_ROOT_DIR'] - - # Return state - return glob_result - - -if __name__ == "__main__": - if sys.warnoptions: - with warnings.catch_warnings(record=True) as cw: - warnings.resetwarnings() - # Let's discover the garbage waste - warnings.simplefilter('error') - print("### Warning mode enabled ###") - res = main() - if cw: - res = 1 - sys.exit(res) - else: - sys.exit(main()) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/tools/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/tools/__init__.py deleted file mode 100644 index f625678a0f..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/tools/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -Additional tools to be run separately -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/tools/automotive/__init__.py b/scripts/external_libs/scapy-2.4.3/scapy/tools/automotive/__init__.py deleted file mode 100644 index bcf585e7e1..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/tools/automotive/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Nils Weiss -# This program is published under a GPLv2 license - -""" -Automotive related tools to be run separately -""" diff --git a/scripts/external_libs/scapy-2.4.3/scapy/tools/automotive/isotpscanner.py b/scripts/external_libs/scapy-2.4.3/scapy/tools/automotive/isotpscanner.py deleted file mode 100644 index e1dc33d8cc..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/tools/automotive/isotpscanner.py +++ /dev/null @@ -1,179 +0,0 @@ -#! /usr/bin/env python - -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Nils Weiss -# Copyright (C) Alexander Schroeder -# This program is published under a GPLv2 license - -from __future__ import print_function - -import getopt -import sys -import signal - -import scapy.modules.six as six -from scapy.config import conf -from scapy.consts import LINUX - -if six.PY2 or not LINUX: - conf.contribs['CANSocket'] = {'use-python-can': True} - -from scapy.contrib.cansocket import CANSocket, PYTHON_CAN # noqa: E402 -from scapy.contrib.isotp import ISOTPScan # noqa: E402 - - -def signal_handler(sig, frame): - print('Interrupting scan!') - sys.exit(0) - - -def usage(): - print('''usage:\tisotpscanner [-i interface] [-c channel] [-b bitrate] - [-n NOISE_LISTEN_TIME] [-t SNIFF_TIME] [-x|--extended] - [-C|--piso] [-v|--verbose] [-h|--help] [-s start] [-e end]\n - Scan for open ISOTP-Sockets.\n - required arguments: - -c, --channel python-can channel or Linux SocketCAN interface name - -s, --start Start scan at this identifier (hex) - -e, --end End scan at this identifier (hex)\n - additional required arguments for WINDOWS or Python 2: - -i, --interface python-can interface for the scan. - Depends on used interpreter and system, - see examples below. Any python-can interface can - be provided. Please see: - https://python-can.readthedocs.io for - further interface examples. - -b, --bitrate python-can bitrate.\n - optional arguments: - -h, --help show this help message and exit - -n NOISE_LISTEN_TIME, --noise_listen_time NOISE_LISTEN_TIME - Seconds listening for noise before scan. - -t SNIFF_TIME, --sniff_time SNIFF_TIME - Duration in milliseconds a sniff is waiting for a - flow-control response. - -x, --extended Scan with ISOTP extended addressing. - -C, --piso Print 'Copy&Paste'-ready ISOTPSockets. - -v, --verbose Display information during scan.\n - Example of use:\n - Python2 or Windows: - python2 -m scapy.tools.automotive.isotpscanner --interface=pcan --channel=PCAN_USBBUS1 --bitrate=250000 --start 0 --end 100 - python2 -m scapy.tools.automotive.isotpscanner --interface vector --channel 0 --bitrate 250000 --start 0 --end 100 - python2 -m scapy.tools.automotive.isotpscanner --interface socketcan --channel=can0 --bitrate=250000 --start 0 --end 100\n - Python3 on Linux: - python3 -m scapy.tools.automotive.isotpscanner --channel can0 --start 0 --end 100 \n''', # noqa: E501 - file=sys.stderr) - - -def main(): - extended = False - piso = False - verbose = False - sniff_time = 100 - noise_listen_time = 2 - start = None - end = None - channel = None - interface = None - bitrate = None - - options = getopt.getopt( - sys.argv[1:], - 'vxCt:n:i:c:b:s:e:h', - ['verbose', 'noise_listen_time=', 'sniff_time=', 'interface=', 'piso', - 'channel=', 'bitrate=', 'start=', 'end=', 'help', 'extended']) - - try: - for opt, arg in options[0]: - if opt in ('-v', '--verbose'): - verbose = True - elif opt in ('-x', '--extended'): - extended = True - elif opt in ('-C', '--piso'): - piso = True - elif opt in ('-h', '--help'): - usage() - sys.exit(-1) - elif opt in ('-t', '--sniff_time'): - sniff_time = int(arg) - elif opt in ('-n', '--noise_listen_time'): - noise_listen_time = int(arg) - elif opt in ('-i', '--interface'): - interface = arg - elif opt in ('-c', '--channel'): - channel = arg - elif opt in ('-b', '--bitrate'): - bitrate = int(arg) - elif opt in ('-s', '--start'): - start = int(arg, 16) - elif opt in ('-e', '--end'): - end = int(arg, 16) - except getopt.GetoptError as msg: - usage() - print("ERROR:", msg, file=sys.stderr) - raise SystemExit - - if start is None or \ - end is None or \ - channel is None or \ - (PYTHON_CAN and (bitrate is None or interface is None)): - usage() - print("\nPlease provide all required arguments.\n", file=sys.stderr) - sys.exit(-1) - - if end >= 0x800: - print("end must be < 0x800.", file=sys.stderr) - sys.exit(-1) - - if end < start: - print("start must be equal or smaller than end.", file=sys.stderr) - sys.exit(-1) - - if PYTHON_CAN: - import can - try: - can.rc['interface'] = interface - can.rc['channel'] = channel - can.rc['bitrate'] = bitrate - scan_interface = can.interface.Bus() - interface_string = "CANSocket(iface=can.interface.Bus(bustype=" \ - "'%s', channel='%s', bitrate=%d))" % \ - (interface, channel, bitrate) - except Exception as e: - usage() - print("\nCheck python-can interface assignment.\n", - file=sys.stderr) - print(e, file=sys.stderr) - sys.exit(-1) - else: - scan_interface = channel - interface_string = "\"%s\"" % channel - - try: - sock = CANSocket(iface=scan_interface) - except Exception as e: - usage() - print("\nSocket couldn't be created. Check your arguments.\n", - file=sys.stderr) - print(e, file=sys.stderr) - sys.exit(-1) - - if verbose: - print("Start scan (%s - %s)" % (hex(start), hex(end))) - - signal.signal(signal.SIGINT, signal_handler) - - result = ISOTPScan(sock, - range(start, end + 1), - extended_addressing=extended, - noise_listen_time=noise_listen_time, - sniff_time=float(sniff_time) / 1000, - output_format="code" if piso else "text", - can_interface=interface_string, - verbose=verbose) - - print("Scan: \n%s" % result) - - -if __name__ == '__main__': - main() diff --git a/scripts/external_libs/scapy-2.4.3/scapy/tools/check_asdis.py b/scripts/external_libs/scapy-2.4.3/scapy/tools/check_asdis.py deleted file mode 100644 index 24419c535c..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/tools/check_asdis.py +++ /dev/null @@ -1,101 +0,0 @@ -#! /usr/bin/env python - -from __future__ import print_function -import getopt - - -def usage(): - print("""Usage: check_asdis -i [-o ] - -v increase verbosity - -d hexdiff packets that differ - -z compress output pcap - -a open pcap file in append mode""", file=sys.stderr) - - -def main(argv): - PCAP_IN = None - PCAP_OUT = None - COMPRESS = False - APPEND = False - DIFF = False - VERBOSE = 0 - try: - opts = getopt.getopt(argv, "hi:o:azdv") - for opt, parm in opts[0]: - if opt == "-h": - usage() - raise SystemExit - elif opt == "-i": - PCAP_IN = parm - elif opt == "-o": - PCAP_OUT = parm - elif opt == "-v": - VERBOSE += 1 - elif opt == "-d": - DIFF = True - elif opt == "-a": - APPEND = True - elif opt == "-z": - COMPRESS = True - - if PCAP_IN is None: - raise getopt.GetoptError("Missing pcap file (-i)") - - except getopt.GetoptError as e: - print("ERROR: %s" % e, file=sys.stderr) - raise SystemExit - - from scapy.config import conf - from scapy.utils import RawPcapReader, RawPcapWriter, hexdiff - from scapy.layers import all # noqa: F401 - - pcap = RawPcapReader(PCAP_IN) - pcap_out = None - if PCAP_OUT: - pcap_out = RawPcapWriter(PCAP_OUT, append=APPEND, gz=COMPRESS, linktype=pcap.linktype) # noqa: E501 - pcap_out._write_header(None) - - LLcls = conf.l2types.get(pcap.linktype) - if LLcls is None: - print(" Unknown link type [%i]. Can't test anything!" % pcap.linktype, file=sys.stderr) # noqa: E501 - raise SystemExit - - i = -1 - differ = 0 - failed = 0 - for p1, meta in pcap: - i += 1 - try: - p2d = LLcls(p1) - p2 = str(p2d) - except KeyboardInterrupt: - raise - except Exception as e: - print("Dissection error on packet %i: %s" % (i, e)) - failed += 1 - else: - if p1 == p2: - if VERBOSE >= 2: - print("Packet %i ok" % i) - continue - else: - print("Packet %i differs" % i) - differ += 1 - if VERBOSE >= 1: - print(repr(p2d)) - if DIFF: - hexdiff(p1, p2) - if pcap_out is not None: - pcap_out.write(p1) - i += 1 - correct = i - differ - failed - print("%i total packets. %i ok, %i differed, %i failed. %.2f%% correct." % (i, correct, differ, # noqa: E501 - failed, i and 100.0 * (correct) / i)) # noqa: E501 - - -if __name__ == "__main__": - import sys - try: - main(sys.argv[1:]) - except KeyboardInterrupt: - print("Interrupted by user.", file=sys.stderr) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/tools/generate_ethertypes.py b/scripts/external_libs/scapy-2.4.3/scapy/tools/generate_ethertypes.py deleted file mode 100644 index 5bc5cdf982..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/tools/generate_ethertypes.py +++ /dev/null @@ -1,48 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Copyright (C) Gabriel Potter -# This program is published under a GPLv2 license - -"""Generate the ethertypes file (/etc/ethertypes) -based on the OpenBSD source. - -It allows to have a file with the format of -http://git.netfilter.org/ebtables/plain/ethertypes -but up-to-date. -""" - -import re -import urllib.request - -URL = "https://raw.githubusercontent.com/openbsd/src/master/sys/net/ethertypes.h" # noqa: E501 - -with urllib.request.urlopen(URL) as stream: - DATA = stream.read() - -reg = rb".*ETHERTYPE_([^\s]+)\s.0x([0-9A-Fa-f]+).*\/\*(.*)\*\/" -COMPILED = b"""# -# Ethernet frame types -# This file describes some of the various Ethernet -# protocol types that are used on Ethernet networks. -# -# This list could be found on: -# http://www.iana.org/assignments/ethernet-numbers -# http://www.iana.org/assignments/ieee-802-numbers -# -# ... #Comment -# -""" -for line in DATA.split(b"\n"): - match = re.match(reg, line) - if match: - name = match.group(1).ljust(16) - number = match.group(2).upper() - comment = match.group(3).strip() - compiled_line = (b"%b%b" + b" " * 25 + b"# %b\n") % ( - name, number, comment - ) - COMPILED += compiled_line - -with open("ethertypes", "wb") as output: - print("Written: %s" % output.write(COMPILED)) diff --git a/scripts/external_libs/scapy-2.4.3/scapy/utils.py b/scripts/external_libs/scapy-2.4.3/scapy/utils.py deleted file mode 100644 index ef97a1fd48..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/utils.py +++ /dev/null @@ -1,1998 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -""" -General utility functions. -""" - -from __future__ import absolute_import -from __future__ import print_function -from decimal import Decimal - -import os -import sys -import socket -import collections -import random -import time -import gzip -import re -import struct -import array -import subprocess -import tempfile -import threading - -import scapy.modules.six as six -from scapy.modules.six.moves import range - -from scapy.config import conf -from scapy.consts import DARWIN, WINDOWS, WINDOWS_XP, OPENBSD -from scapy.data import MTU, DLT_EN10MB -from scapy.compat import orb, raw, plain_str, chb, bytes_base64,\ - base64_bytes, hex_bytes, lambda_tuple_converter, bytes_encode -from scapy.error import log_runtime, Scapy_Exception, warning -from scapy.pton_ntop import inet_pton - -########### -# Tools # -########### - - -def issubtype(x, t): - """issubtype(C, B) -> bool - - Return whether C is a class and if it is a subclass of class B. - When using a tuple as the second argument issubtype(X, (A, B, ...)), - is a shortcut for issubtype(X, A) or issubtype(X, B) or ... (etc.). - """ - return isinstance(x, type) and issubclass(x, t) - - -def get_temp_file(keep=False, autoext="", fd=False): - """Creates a temporary file. - - :param keep: If False, automatically delete the file when Scapy exits. - :param autoext: Suffix to add to the generated file name. - :param fd: If True, this returns a file-like object with the temporary - file opened. If False (default), this returns a file path. - """ - f = tempfile.NamedTemporaryFile(prefix="scapy", suffix=autoext, - delete=False) - if not keep: - conf.temp_files.append(f.name) - - if fd: - return f - else: - # Close the file so something else can take it. - f.close() - return f.name - - -def get_temp_dir(keep=False): - """Creates a temporary file, and returns its name. - - :param keep: If False (default), the directory will be recursively - deleted when Scapy exits. - :return: A full path to a temporary directory. - """ - - dname = tempfile.mkdtemp(prefix="scapy") - - if not keep: - conf.temp_files.append(dname) - - return dname - - -def str2bytes(x): - """Convert input argument to bytes""" - if type(x) is bytes: - return x - elif type(x) is str: - return bytes([ ord(i) for i in x ]) - else: - return str2bytes(str(x)) - - -def sane_color(x): - r = "" - for i in x: - j = orb(i) - if (j < 32) or (j >= 127): - r += conf.color_theme.not_printable(".") - else: - r += chr(j) - return r - - -def sane(x): - r = "" - for i in x: - j = orb(i) - if (j < 32) or (j >= 127): - r += "." - else: - r += chr(j) - return r - - -@conf.commands.register -def restart(): - """Restarts scapy""" - if not conf.interactive or not os.path.isfile(sys.argv[0]): - raise OSError("Scapy was not started from console") - if WINDOWS: - try: - res_code = subprocess.call([sys.executable] + sys.argv) - except KeyboardInterrupt: - res_code = 1 - finally: - os._exit(res_code) - os.execv(sys.executable, [sys.executable] + sys.argv) - - -def lhex(x): - if type(x) in six.integer_types: - return hex(x) - elif isinstance(x, tuple): - return "(%s)" % ", ".join(map(lhex, x)) - elif isinstance(x, list): - return "[%s]" % ", ".join(map(lhex, x)) - else: - return x - - -@conf.commands.register -def hexdump(x, dump=False): - """Build a tcpdump like hexadecimal view - - :param x: a Packet - :param dump: define if the result must be printed or returned in a variable - :returns: a String only when dump=True - """ - s = "" - x = bytes_encode(x) - x_len = len(x) - i = 0 - while i < x_len: - s += "%04x " % i - for j in range(16): - if i + j < x_len: - s += "%02X " % orb(x[i + j]) - else: - s += " " - s += " %s\n" % sane_color(x[i:i + 16]) - i += 16 - # remove trailing \n - s = s[:-1] if s.endswith("\n") else s - if dump: - return s - else: - print(s) - - -@conf.commands.register -def linehexdump(x, onlyasc=0, onlyhex=0, dump=False): - """Build an equivalent view of hexdump() on a single line - - Note that setting both onlyasc and onlyhex to 1 results in a empty output - - :param x: a Packet - :param onlyasc: 1 to display only the ascii view - :param onlyhex: 1 to display only the hexadecimal view - :param dump: print the view if False - :returns: a String only when dump=True - """ - s = "" - s = hexstr(x, onlyasc=onlyasc, onlyhex=onlyhex, color=not dump) - if dump: - return s - else: - print(s) - - -@conf.commands.register -def chexdump(x, dump=False): - """Build a per byte hexadecimal representation - - Example: - >>> chexdump(IP()) - 0x45, 0x00, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x7c, 0xe7, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00, 0x00, 0x01 # noqa: E501 - - :param x: a Packet - :param dump: print the view if False - :returns: a String only if dump=True - """ - x = bytes_encode(x) - s = ", ".join("%#04x" % orb(x) for x in x) - if dump: - return s - else: - print(s) - - -@conf.commands.register -def hexstr(x, onlyasc=0, onlyhex=0, color=False): - """Build a fancy tcpdump like hex from bytes.""" - x = bytes_encode(x) - _sane_func = sane_color if color else sane - s = [] - if not onlyasc: - s.append(" ".join("%02X" % orb(b) for b in x)) - if not onlyhex: - s.append(_sane_func(x)) - return " ".join(s) - - -def repr_hex(s): - """ Convert provided bitstring to a simple string of hex digits """ - return "".join("%02x" % orb(x) for x in s) - - -@conf.commands.register -def hexdiff(x, y): - """Show differences between 2 binary strings""" - x = bytes_encode(x)[::-1] - y = bytes_encode(y)[::-1] - SUBST = 1 - INSERT = 1 - d = {(-1, -1): (0, (-1, -1))} - for j in range(len(y)): - d[-1, j] = d[-1, j - 1][0] + INSERT, (-1, j - 1) - for i in range(len(x)): - d[i, -1] = d[i - 1, -1][0] + INSERT, (i - 1, -1) - - for j in range(len(y)): - for i in range(len(x)): - d[i, j] = min((d[i - 1, j - 1][0] + SUBST * (x[i] != y[j]), (i - 1, j - 1)), # noqa: E501 - (d[i - 1, j][0] + INSERT, (i - 1, j)), - (d[i, j - 1][0] + INSERT, (i, j - 1))) - - backtrackx = [] - backtracky = [] - i = len(x) - 1 - j = len(y) - 1 - while not (i == j == -1): - i2, j2 = d[i, j][1] - backtrackx.append(x[i2 + 1:i + 1]) - backtracky.append(y[j2 + 1:j + 1]) - i, j = i2, j2 - - x = y = i = 0 - colorize = {0: lambda x: x, - -1: conf.color_theme.left, - 1: conf.color_theme.right} - - dox = 1 - doy = 0 - btx_len = len(backtrackx) - while i < btx_len: - linex = backtrackx[i:i + 16] - liney = backtracky[i:i + 16] - xx = sum(len(k) for k in linex) - yy = sum(len(k) for k in liney) - if dox and not xx: - dox = 0 - doy = 1 - if dox and linex == liney: - doy = 1 - - if dox: - xd = y - j = 0 - while not linex[j]: - j += 1 - xd -= 1 - print(colorize[doy - dox]("%04x" % xd), end=' ') - x += xx - line = linex - else: - print(" ", end=' ') - if doy: - yd = y - j = 0 - while not liney[j]: - j += 1 - yd -= 1 - print(colorize[doy - dox]("%04x" % yd), end=' ') - y += yy - line = liney - else: - print(" ", end=' ') - - print(" ", end=' ') - - cl = "" - for j in range(16): - if i + j < btx_len: - if line[j]: - col = colorize[(linex[j] != liney[j]) * (doy - dox)] - print(col("%02X" % orb(line[j])), end=' ') - if linex[j] == liney[j]: - cl += sane_color(line[j]) - else: - cl += col(sane(line[j])) - else: - print(" ", end=' ') - cl += " " - else: - print(" ", end=' ') - if j == 7: - print("", end=' ') - - print(" ", cl) - - if doy or not yy: - doy = 0 - dox = 1 - i += 16 - else: - if yy: - dox = 0 - doy = 1 - else: - i += 16 - - -if struct.pack("H", 1) == b"\x00\x01": # big endian - checksum_endian_transform = lambda chk: chk -else: - checksum_endian_transform = lambda chk: ((chk >> 8) & 0xff) | chk << 8 - - -def checksum(pkt): - if len(pkt) % 2 == 1: - pkt += b"\0" - s = sum(array.array("H", pkt)) - s = (s >> 16) + (s & 0xffff) - s += s >> 16 - s = ~s - return checksum_endian_transform(s) & 0xffff - - -def _fletcher16(charbuf): - # This is based on the GPLed C implementation in Zebra # noqa: E501 - c0 = c1 = 0 - for char in charbuf: - c0 += orb(char) - c1 += c0 - - c0 %= 255 - c1 %= 255 - return (c0, c1) - - -@conf.commands.register -def fletcher16_checksum(binbuf): - """Calculates Fletcher-16 checksum of the given buffer. - - Note: - If the buffer contains the two checkbytes derived from the Fletcher-16 checksum # noqa: E501 - the result of this function has to be 0. Otherwise the buffer has been corrupted. # noqa: E501 - """ - (c0, c1) = _fletcher16(binbuf) - return (c1 << 8) | c0 - - -@conf.commands.register -def fletcher16_checkbytes(binbuf, offset): - """Calculates the Fletcher-16 checkbytes returned as 2 byte binary-string. - - Including the bytes into the buffer (at the position marked by offset) the # noqa: E501 - global Fletcher-16 checksum of the buffer will be 0. Thus it is easy to verify # noqa: E501 - the integrity of the buffer on the receiver side. - - For details on the algorithm, see RFC 2328 chapter 12.1.7 and RFC 905 Annex B. # noqa: E501 - """ - - # This is based on the GPLed C implementation in Zebra # noqa: E501 - if len(binbuf) < offset: - raise Exception("Packet too short for checkbytes %d" % len(binbuf)) - - binbuf = binbuf[:offset] + b"\x00\x00" + binbuf[offset + 2:] - (c0, c1) = _fletcher16(binbuf) - - x = ((len(binbuf) - offset - 1) * c0 - c1) % 255 - - if (x <= 0): - x += 255 - - y = 510 - c0 - x - - if (y > 255): - y -= 255 - return chb(x) + chb(y) - - -def mac2str(mac): - return b"".join(chb(int(x, 16)) for x in plain_str(mac).split(':')) - - -def valid_mac(mac): - try: - return len(mac2str(mac)) == 6 - except ValueError: - pass - return False - - -def str2mac(s): - if isinstance(s, str): - return ("%02x:" * 6)[:-1] % tuple(map(ord, s)) - return ("%02x:" * 6)[:-1] % tuple(s) - -# TRex Change - Added the function -def str2ip(s): - return ("%s."*4)[:-1] % tuple(map(ord, s)) if six.PY2 else ("%s."*4)[:-1] % tuple(s) - - -def randstring(l): - """ - Returns a random string of length l (l >= 0) - """ - return b"".join(struct.pack('B', random.randint(0, 255)) for _ in range(l)) - - -def zerofree_randstring(l): - """ - Returns a random string of length l (l >= 0) without zero in it. - """ - return b"".join(struct.pack('B', random.randint(1, 255)) for _ in range(l)) - - -def strxor(s1, s2): - """ - Returns the binary XOR of the 2 provided strings s1 and s2. s1 and s2 - must be of same length. - """ - return b"".join(map(lambda x, y: chb(orb(x) ^ orb(y)), s1, s2)) - - -def strand(s1, s2): - """ - Returns the binary AND of the 2 provided strings s1 and s2. s1 and s2 - must be of same length. - """ - return b"".join(map(lambda x, y: chb(orb(x) & orb(y)), s1, s2)) - - -# Workaround bug 643005 : https://sourceforge.net/tracker/?func=detail&atid=105470&aid=643005&group_id=5470 # noqa: E501 -try: - socket.inet_aton("255.255.255.255") -except socket.error: - def inet_aton(x): - if x == "255.255.255.255": - return b"\xff" * 4 - else: - return socket.inet_aton(x) -else: - inet_aton = socket.inet_aton - -inet_ntoa = socket.inet_ntoa - - -def atol(x): - try: - ip = inet_aton(x) - except socket.error: - ip = inet_aton(socket.gethostbyname(x)) - return struct.unpack("!I", ip)[0] - - -def valid_ip(addr): - try: - addr = plain_str(addr) - except UnicodeDecodeError: - return False - try: - atol(addr) - except (OSError, ValueError, socket.error): - return False - return True - - -def valid_net(addr): - try: - addr = plain_str(addr) - except UnicodeDecodeError: - return False - if '/' in addr: - ip, mask = addr.split('/', 1) - return valid_ip(ip) and mask.isdigit() and 0 <= int(mask) <= 32 - return valid_ip(addr) - - -def valid_ip6(addr): - try: - addr = plain_str(addr) - except UnicodeDecodeError: - return False - try: - inet_pton(socket.AF_INET6, addr) - except socket.error: - try: - socket.getaddrinfo(addr, None, socket.AF_INET6)[0][4][0] - except socket.error: - return False - return True - - -def valid_net6(addr): - try: - addr = plain_str(addr) - except UnicodeDecodeError: - return False - if '/' in addr: - ip, mask = addr.split('/', 1) - return valid_ip6(ip) and mask.isdigit() and 0 <= int(mask) <= 128 - return valid_ip6(addr) - - -if WINDOWS_XP: - # That is a hell of compatibility :( - def ltoa(x): - return inet_ntoa(struct.pack("> x) & 0xffffffff - - -class ContextManagerSubprocess(object): - """ - Context manager that eases checking for unknown command. - - Example: - >>> with ContextManagerSubprocess("my custom message", "unknown_command"): - >>> subprocess.Popen(["unknown_command"]) - - """ - - def __init__(self, name, prog): - self.name = name - self.prog = prog - - def __enter__(self): - pass - - def __exit__(self, exc_type, exc_value, traceback): - if isinstance(exc_value, (OSError, TypeError)): - msg = "%s: executing %r failed" % (self.name, self.prog) if self.prog else "Could not execute %s, is it installed ?" % self.name # noqa: E501 - if not conf.interactive: - raise OSError(msg) - else: - log_runtime.error(msg, exc_info=True) - return True # Suppress the exception - - -class ContextManagerCaptureOutput(object): - """ - Context manager that intercept the console's output. - - Example: - >>> with ContextManagerCaptureOutput() as cmco: - ... print("hey") - ... assert cmco.get_output() == "hey" - """ - - def __init__(self): - self.result_export_object = "" - try: - import mock # noqa: F401 - except Exception: - raise ImportError("The mock module needs to be installed !") - - def __enter__(self): - import mock - - def write(s, decorator=self): - decorator.result_export_object += s - mock_stdout = mock.Mock() - mock_stdout.write = write - self.bck_stdout = sys.stdout - sys.stdout = mock_stdout - return self - - def __exit__(self, *exc): - sys.stdout = self.bck_stdout - return False - - def get_output(self, eval_bytes=False): - if self.result_export_object.startswith("b'") and eval_bytes: - return plain_str(eval(self.result_export_object)) - return self.result_export_object - - -def do_graph(graph, prog=None, format=None, target=None, type=None, string=None, options=None): # noqa: E501 - """do_graph(graph, prog=conf.prog.dot, format="svg", - target="| conf.prog.display", options=None, [string=1]): - string: if not None, simply return the graph string - graph: GraphViz graph description - format: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option - target: filename or redirect. Defaults pipe to Imagemagick's display program # noqa: E501 - prog: which graphviz program to use - options: options to be passed to prog""" - - if format is None: - if WINDOWS: - format = "png" # use common format to make sure a viewer is installed # noqa: E501 - else: - format = "svg" - if string: - return graph - if type is not None: - format = type - if prog is None: - prog = conf.prog.dot - start_viewer = False - if target is None: - if WINDOWS: - target = get_temp_file(autoext="." + format) - start_viewer = True - else: - with ContextManagerSubprocess("do_graph()", conf.prog.display): - target = subprocess.Popen([conf.prog.display], - stdin=subprocess.PIPE).stdin - if format is not None: - format = "-T%s" % format - if isinstance(target, str): - if target.startswith('|'): - target = subprocess.Popen(target[1:].lstrip(), shell=True, - stdin=subprocess.PIPE).stdin - elif target.startswith('>'): - target = open(target[1:].lstrip(), "wb") - else: - target = open(os.path.abspath(target), "wb") - proc = subprocess.Popen("\"%s\" %s %s" % (prog, options or "", format or ""), # noqa: E501 - shell=True, stdin=subprocess.PIPE, stdout=target) - proc.stdin.write(bytes_encode(graph)) - proc.stdin.close() - proc.wait() - try: - target.close() - except Exception: - pass - if start_viewer: - # Workaround for file not found error: We wait until tempfile is written. # noqa: E501 - waiting_start = time.time() - while not os.path.exists(target.name): - time.sleep(0.1) - if time.time() - waiting_start > 3: - warning("Temporary file '%s' could not be written. Graphic will not be displayed.", tempfile) # noqa: E501 - break - else: - if conf.prog.display == conf.prog._default: - os.startfile(target.name) - else: - with ContextManagerSubprocess("do_graph()", conf.prog.display): - subprocess.Popen([conf.prog.display, target.name]) - - -_TEX_TR = { - "{": "{\\tt\\char123}", - "}": "{\\tt\\char125}", - "\\": "{\\tt\\char92}", - "^": "\\^{}", - "$": "\\$", - "#": "\\#", - "_": "\\_", - "&": "\\&", - "%": "\\%", - "|": "{\\tt\\char124}", - "~": "{\\tt\\char126}", - "<": "{\\tt\\char60}", - ">": "{\\tt\\char62}", -} - - -def tex_escape(x): - s = "" - for c in x: - s += _TEX_TR.get(c, c) - return s - - -def colgen(*lstcol, **kargs): - """Returns a generator that mixes provided quantities forever - trans: a function to convert the three arguments into a color. lambda x,y,z:(x,y,z) by default""" # noqa: E501 - if len(lstcol) < 2: - lstcol *= 2 - trans = kargs.get("trans", lambda x, y, z: (x, y, z)) - while True: - for i in range(len(lstcol)): - for j in range(len(lstcol)): - for k in range(len(lstcol)): - if i != j or j != k or k != i: - yield trans(lstcol[(i + j) % len(lstcol)], lstcol[(j + k) % len(lstcol)], lstcol[(k + i) % len(lstcol)]) # noqa: E501 - - -def incremental_label(label="tag%05i", start=0): - while True: - yield label % start - start += 1 - - -def binrepr(val): - return bin(val)[2:] - - -def long_converter(s): - return int(s.replace('\n', '').replace(' ', ''), 16) - -######################### -# Enum management # -######################### - - -class EnumElement: - _value = None - - def __init__(self, key, value): - self._key = key - self._value = value - - def __repr__(self): - return "<%s %s[%r]>" % (self.__dict__.get("_name", self.__class__.__name__), self._key, self._value) # noqa: E501 - - def __getattr__(self, attr): - return getattr(self._value, attr) - - def __str__(self): - return self._key - - def __bytes__(self): - return bytes_encode(self.__str__()) - - def __hash__(self): - return self._value - - def __int__(self): - return int(self._value) - - def __eq__(self, other): - return self._value == int(other) - - def __neq__(self, other): - return not self.__eq__(other) - - -class Enum_metaclass(type): - element_class = EnumElement - - def __new__(cls, name, bases, dct): - rdict = {} - for k, v in six.iteritems(dct): - if isinstance(v, int): - v = cls.element_class(k, v) - dct[k] = v - rdict[v] = k - dct["__rdict__"] = rdict - return super(Enum_metaclass, cls).__new__(cls, name, bases, dct) - - def __getitem__(self, attr): - return self.__rdict__[attr] - - def __contains__(self, val): - return val in self.__rdict__ - - def get(self, attr, val=None): - return self.__rdict__.get(attr, val) - - def __repr__(self): - return "<%s>" % self.__dict__.get("name", self.__name__) - - -################### -# Object saving # -################### - - -def export_object(obj): - print(bytes_base64(gzip.zlib.compress(six.moves.cPickle.dumps(obj, 2), 9))) - - -def import_object(obj=None): - if obj is None: - obj = sys.stdin.read() - return six.moves.cPickle.loads(gzip.zlib.decompress(base64_bytes(obj.strip()))) # noqa: E501 - - -def save_object(fname, obj): - """Pickle a Python object""" - - fd = gzip.open(fname, "wb") - six.moves.cPickle.dump(obj, fd) - fd.close() - - -def load_object(fname): - """unpickle a Python object""" - return six.moves.cPickle.load(gzip.open(fname, "rb")) - - -@conf.commands.register -def corrupt_bytes(s, p=0.01, n=None): - """Corrupt a given percentage or number of bytes from a string""" - s = array.array("B", bytes_encode(s)) - s_len = len(s) - if n is None: - n = max(1, int(s_len * p)) - for i in random.sample(range(s_len), n): - s[i] = (s[i] + random.randint(1, 255)) % 256 - return s.tostring() if six.PY2 else s.tobytes() - - -@conf.commands.register -def corrupt_bits(s, p=0.01, n=None): - """Flip a given percentage or number of bits from a string""" - s = array.array("B", bytes_encode(s)) - s_len = len(s) * 8 - if n is None: - n = max(1, int(s_len * p)) - for i in random.sample(range(s_len), n): - s[i // 8] ^= 1 << (i % 8) - return s.tostring() if six.PY2 else s.tobytes() - - -############################# -# pcap capture file stuff # -############################# - -@conf.commands.register -def wrpcap(filename, pkt, *args, **kargs): - """Write a list of packets to a pcap file - -filename: the name of the file to write packets to, or an open, - writable file-like object. The file descriptor will be - closed at the end of the call, so do not use an object you - do not want to close (e.g., running wrpcap(sys.stdout, []) - in interactive mode will crash Scapy). -gz: set to 1 to save a gzipped capture -linktype: force linktype value -endianness: "<" or ">", force endianness -sync: do not bufferize writes to the capture file - - """ - with PcapWriter(filename, *args, **kargs) as fdesc: - fdesc.write(pkt) - - -@conf.commands.register -def rdpcap(filename, count=-1): - """Read a pcap or pcapng file and return a packet list - -count: read only packets - - """ - with PcapReader(filename) as fdesc: - return fdesc.read_all(count=count) - - -class PcapReader_metaclass(type): - """Metaclass for (Raw)Pcap(Ng)Readers""" - - def __new__(cls, name, bases, dct): - """The `alternative` class attribute is declared in the PcapNg - variant, and set here to the Pcap variant. - - """ - newcls = super(PcapReader_metaclass, cls).__new__(cls, name, bases, dct) # noqa: E501 - if 'alternative' in dct: - dct['alternative'].alternative = newcls - return newcls - - def __call__(cls, filename): - """Creates a cls instance, use the `alternative` if that - fails. - - """ - i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__) - filename, fdesc, magic = cls.open(filename) - try: - i.__init__(filename, fdesc, magic) - except Scapy_Exception: - if "alternative" in cls.__dict__: - cls = cls.__dict__["alternative"] - i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__) - try: - i.__init__(filename, fdesc, magic) - except Scapy_Exception: - try: - i.f.seek(-4, 1) - except Exception: - pass - raise Scapy_Exception("Not a supported capture file") - - return i - - @staticmethod - def open(filename): - """Open (if necessary) filename, and read the magic.""" - if isinstance(filename, six.string_types): - try: - fdesc = gzip.open(filename, "rb") - magic = fdesc.read(4) - except IOError: - fdesc = open(filename, "rb") - magic = fdesc.read(4) - else: - fdesc = filename - filename = getattr(fdesc, "name", "No name") - magic = fdesc.read(4) - return filename, fdesc, magic - - -class RawPcapReader(six.with_metaclass(PcapReader_metaclass)): - """A stateful pcap reader. Each packet is returned as a string""" - - read_allowed_exceptions = () # emulate SuperSocket - nonblocking_socket = True - PacketMetadata = collections.namedtuple("PacketMetadata", - ["sec", "usec", "wirelen", "caplen"]) # noqa: E501 - - def __init__(self, filename, fdesc, magic): - self.filename = filename - self.f = fdesc - if magic == b"\xa1\xb2\xc3\xd4": # big endian - self.endian = ">" - self.nano = False - elif magic == b"\xd4\xc3\xb2\xa1": # little endian - self.endian = "<" - self.nano = False - elif magic == b"\xa1\xb2\x3c\x4d": # big endian, nanosecond-precision - self.endian = ">" - self.nano = True - elif magic == b"\x4d\x3c\xb2\xa1": # little endian, nanosecond-precision # noqa: E501 - self.endian = "<" - self.nano = True - else: - raise Scapy_Exception( - "Not a pcap capture file (bad magic: %r)" % magic - ) - hdr = self.f.read(20) - if len(hdr) < 20: - raise Scapy_Exception("Invalid pcap file (too short)") - vermaj, vermin, tz, sig, snaplen, linktype = struct.unpack( - self.endian + "HHIIII", hdr - ) - self.linktype = linktype - - def __iter__(self): - return self - - def next(self): - """implement the iterator protocol on a set of packets in a pcap file - pkt is a tuple (pkt_data, pkt_metadata) as defined in - RawPcapReader.read_packet() - - """ - try: - return self.read_packet() - except EOFError: - raise StopIteration - __next__ = next - - def read_packet(self, size=MTU): - """return a single packet read from the file as a tuple containing - (pkt_data, pkt_metadata) - - raise EOFError when no more packets are available - """ - hdr = self.f.read(16) - if len(hdr) < 16: - raise EOFError - sec, usec, caplen, wirelen = struct.unpack(self.endian + "IIII", hdr) - return (self.f.read(caplen)[:size], - RawPcapReader.PacketMetadata(sec=sec, usec=usec, - wirelen=wirelen, caplen=caplen)) - - def dispatch(self, callback): - """call the specified callback routine for each packet read - - This is just a convenience function for the main loop - that allows for easy launching of packet processing in a - thread. - """ - for p in self: - callback(p) - - def read_all(self, count=-1): - """return a list of all packets in the pcap file - """ - res = [] - while count != 0: - count -= 1 - try: - p = self.read_packet() - except EOFError: - break - res.append(p) - return res - - def recv(self, size=MTU): - """ Emulate a socket - """ - return self.read_packet(size=size)[0] - - def fileno(self): - return self.f.fileno() - - def close(self): - return self.f.close() - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, tracback): - self.close() - - # emulate SuperSocket - @staticmethod - def select(sockets, remain=None): - return sockets, None - - -class PcapReader(RawPcapReader): - def __init__(self, filename, fdesc, magic): - RawPcapReader.__init__(self, filename, fdesc, magic) - try: - self.LLcls = conf.l2types[self.linktype] - except KeyError: - warning("PcapReader: unknown LL type [%i]/[%#x]. Using Raw packets" % (self.linktype, self.linktype)) # noqa: E501 - self.LLcls = conf.raw_layer - - def read_packet(self, size=MTU): - rp = super(PcapReader, self).read_packet(size=size) - if rp is None: - raise EOFError - s, pkt_info = rp - - try: - p = self.LLcls(s) - except KeyboardInterrupt: - raise - except Exception: - if conf.debug_dissector: - from scapy.sendrecv import debug - debug.crashed_on = (self.LLcls, s) - raise - p = conf.raw_layer(s) - power = Decimal(10) ** Decimal(-9 if self.nano else -6) - p.time = Decimal(pkt_info.sec + power * pkt_info.usec) - p.wirelen = pkt_info.wirelen - return p - - def read_all(self, count=-1): - res = RawPcapReader.read_all(self, count) - from scapy import plist - return plist.PacketList(res, name=os.path.basename(self.filename)) - - def recv(self, size=MTU): - return self.read_packet(size=size) - - -class RawPcapNgReader(RawPcapReader): - """A stateful pcapng reader. Each packet is returned as a - string. - - """ - - alternative = RawPcapReader - - PacketMetadata = collections.namedtuple("PacketMetadata", - ["linktype", "tsresol", - "tshigh", "tslow", "wirelen"]) - - def __init__(self, filename, fdesc, magic): - self.filename = filename - self.f = fdesc - # A list of (linktype, snaplen, tsresol); will be populated by IDBs. - self.interfaces = [] - self.blocktypes = { - 1: self.read_block_idb, - 2: self.read_block_pkt, - 3: self.read_block_spb, - 6: self.read_block_epb, - } - if magic != b"\x0a\x0d\x0d\x0a": # PcapNg: - raise Scapy_Exception( - "Not a pcapng capture file (bad magic: %r)" % magic - ) - # see https://github.com/pcapng/pcapng - blocklen, magic = self.f.read(4), self.f.read(4) # noqa: F841 - if magic == b"\x1a\x2b\x3c\x4d": - self.endian = ">" - elif magic == b"\x4d\x3c\x2b\x1a": - self.endian = "<" - else: - raise Scapy_Exception("Not a pcapng capture file (bad magic)") - try: - self.f.seek(0) - except Exception: - pass - - def read_packet(self, size=MTU): - """Read blocks until it reaches either EOF or a packet, and - returns None or (packet, (linktype, sec, usec, wirelen)), - where packet is a string. - - """ - while True: - try: - blocktype, blocklen = struct.unpack(self.endian + "2I", - self.f.read(8)) - except struct.error: - raise EOFError - block = self.f.read(blocklen - 12) - if blocklen % 4: - pad = self.f.read(4 - (blocklen % 4)) - warning("PcapNg: bad blocklen %d (MUST be a multiple of 4. " - "Ignored padding %r" % (blocklen, pad)) - try: - if (blocklen,) != struct.unpack(self.endian + 'I', - self.f.read(4)): - warning("PcapNg: Invalid pcapng block (bad blocklen)") - except struct.error: - raise EOFError - res = self.blocktypes.get(blocktype, - lambda block, size: None)(block, size) - if res is not None: - return res - - def read_block_idb(self, block, _): - """Interface Description Block""" - options = block[16:] - tsresol = 1000000 - while len(options) >= 4: - code, length = struct.unpack(self.endian + "HH", options[:4]) - # PCAP Next Generation (pcapng) Capture File Format - # 4.2. - Interface Description Block - # http://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://raw.githubusercontent.com/pcapng/pcapng/master/draft-tuexen-opsawg-pcapng.xml&modeAsFormat=html/ascii&type=ascii#rfc.section.4.2 - if code == 9 and length == 1 and len(options) >= 5: - tsresol = orb(options[4]) - tsresol = (2 if tsresol & 128 else 10) ** (tsresol & 127) - if code == 0: - if length != 0: - warning("PcapNg: invalid option length %d for end-of-option" % length) # noqa: E501 - break - if length % 4: - length += (4 - (length % 4)) - options = options[4 + length:] - self.interfaces.append(struct.unpack(self.endian + "HxxI", block[:8]) + - (tsresol,)) - - def read_block_epb(self, block, size): - """Enhanced Packet Block""" - intid, tshigh, tslow, caplen, wirelen = struct.unpack( - self.endian + "5I", - block[:20], - ) - return (block[20:20 + caplen][:size], - RawPcapNgReader.PacketMetadata(linktype=self.interfaces[intid][0], # noqa: E501 - tsresol=self.interfaces[intid][2], # noqa: E501 - tshigh=tshigh, - tslow=tslow, - wirelen=wirelen)) - - def read_block_spb(self, block, size): - """Simple Packet Block""" - # "it MUST be assumed that all the Simple Packet Blocks have - # been captured on the interface previously specified in the - # first Interface Description Block." - intid = 0 - wirelen, = struct.unpack(self.endian + "I", block[:4]) - caplen = min(wirelen, self.interfaces[intid][1]) - return (block[4:4 + caplen][:size], - RawPcapNgReader.PacketMetadata(linktype=self.interfaces[intid][0], # noqa: E501 - tsresol=self.interfaces[intid][2], # noqa: E501 - tshigh=None, - tslow=None, - wirelen=wirelen)) - - def read_block_pkt(self, block, size): - """(Obsolete) Packet Block""" - intid, drops, tshigh, tslow, caplen, wirelen = struct.unpack( - self.endian + "HH4I", - block[:20], - ) - return (block[20:20 + caplen][:size], - RawPcapNgReader.PacketMetadata(linktype=self.interfaces[intid][0], # noqa: E501 - tsresol=self.interfaces[intid][2], # noqa: E501 - tshigh=tshigh, - tslow=tslow, - wirelen=wirelen)) - - -class PcapNgReader(RawPcapNgReader): - - alternative = PcapReader - - def __init__(self, filename, fdesc, magic): - RawPcapNgReader.__init__(self, filename, fdesc, magic) - - def read_packet(self, size=MTU): - rp = super(PcapNgReader, self).read_packet(size=size) - if rp is None: - raise EOFError - s, (linktype, tsresol, tshigh, tslow, wirelen) = rp - try: - p = conf.l2types[linktype](s) - except KeyboardInterrupt: - raise - except Exception: - if conf.debug_dissector: - raise - p = conf.raw_layer(s) - if tshigh is not None: - p.time = float((tshigh << 32) + tslow) / tsresol - p.wirelen = wirelen - return p - - def read_all(self, count=-1): - res = RawPcapNgReader.read_all(self, count) - from scapy import plist - return plist.PacketList(res, name=os.path.basename(self.filename)) - - def recv(self, size=MTU): - return self.read_packet() - - -class RawPcapWriter: - """A stream PCAP writer with more control than wrpcap()""" - - def __init__(self, filename, linktype=None, gz=False, endianness="", - append=False, sync=False, nano=False): - """ -filename: the name of the file to write packets to, or an open, - writable file-like object. -linktype: force linktype to a given value. If None, linktype is taken - from the first writer packet -gz: compress the capture on the fly -endianness: force an endianness (little:"<", big:">"). Default is native -append: append packets to the capture file instead of truncating it -sync: do not bufferize writes to the capture file -nano: use nanosecond-precision (requires libpcap >= 1.5.0) - - """ - - self.linktype = linktype - self.header_present = 0 - self.append = append - self.gz = gz - self.endian = endianness - self.sync = sync - self.nano = nano - bufsz = 4096 - if sync: - bufsz = 0 - - if isinstance(filename, six.string_types): - self.filename = filename - self.f = [open, gzip.open][gz](filename, append and "ab" or "wb", gz and 9 or bufsz) # noqa: E501 - else: - self.f = filename - self.filename = getattr(filename, "name", "No name") - - def fileno(self): - return self.f.fileno() - - def _write_header(self, pkt): - self.header_present = 1 - - if self.append: - # Even if prone to race conditions, this seems to be - # safest way to tell whether the header is already present - # because we have to handle compressed streams that - # are not as flexible as basic files - g = [open, gzip.open][self.gz](self.filename, "rb") - if g.read(16): - return - - self.f.write(struct.pack(self.endian + "IHHIIII", 0xa1b23c4d if self.nano else 0xa1b2c3d4, # noqa: E501 - 2, 4, 0, 0, MTU, self.linktype)) - self.f.flush() - - def write(self, pkt): - """ - Writes a Packet, a SndRcvList object, or bytes to a pcap file. - - :param pkt: Packet(s) to write (one record for each Packet), or raw - bytes to write (as one record). - :type pkt: iterable[Packet], Packet or bytes - """ - if isinstance(pkt, bytes): - if not self.header_present: - self._write_header(pkt) - self._write_packet(pkt) - else: - # Import here to avoid a circular dependency - from scapy.plist import SndRcvList - if isinstance(pkt, SndRcvList): - pkt = (p for t in pkt for p in t) - else: - pkt = pkt.__iter__() - for p in pkt: - if not self.header_present: - self._write_header(p) - self._write_packet(p) - - def _write_packet(self, packet, sec=None, usec=None, caplen=None, - wirelen=None): - """ - Writes a single packet to the pcap file. - - :param packet: bytes for a single packet - :type packet: bytes - :param sec: time the packet was captured, in seconds since epoch. If - not supplied, defaults to now. - :type sec: int or long - :param usec: If ``nano=True``, then number of nanoseconds after the - second that the packet was captured. If ``nano=False``, - then the number of microseconds after the second the - packet was captured - :type usec: int or long - :param caplen: The length of the packet in the capture file. If not - specified, uses ``len(packet)``. - :type caplen: int - :param wirelen: The length of the packet on the wire. If not - specified, uses ``caplen``. - :type wirelen: int - :returns: None - :rtype: None - """ - if caplen is None: - caplen = len(packet) - if wirelen is None: - wirelen = caplen - if sec is None or usec is None: - t = time.time() - it = int(t) - if sec is None: - sec = it - usec = int(round((t - it) * - (1000000000 if self.nano else 1000000))) - elif usec is None: - usec = 0 - - self.f.write(struct.pack(self.endian + "IIII", - sec, usec, caplen, wirelen)) - self.f.write(packet) - if self.sync: - self.f.flush() - - def flush(self): - return self.f.flush() - - def close(self): - if not self.header_present: - self._write_header(None) - return self.f.close() - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, tracback): - self.flush() - self.close() - - -class PcapWriter(RawPcapWriter): - """A stream PCAP writer with more control than wrpcap()""" - - def _write_header(self, pkt): - if self.linktype is None: - try: - self.linktype = conf.l2types[pkt.__class__] - # Import here to prevent import loops - from scapy.layers.inet import IP - from scapy.layers.inet6 import IPv6 - if OPENBSD and isinstance(pkt, (IP, IPv6)): - self.linktype = 14 # DLT_RAW - except KeyError: - warning("PcapWriter: unknown LL type for %s. Using type 1 (Ethernet)", pkt.__class__.__name__) # noqa: E501 - self.linktype = DLT_EN10MB - RawPcapWriter._write_header(self, pkt) - - def _write_packet(self, packet, sec=None, usec=None, caplen=None, - wirelen=None): - """ - Writes a single packet to the pcap file. - - :param packet: Packet, or bytes for a single packet - :type packet: Packet or bytes - :param sec: time the packet was captured, in seconds since epoch. If - not supplied, defaults to now. - :type sec: int or long - :param usec: If ``nano=True``, then number of nanoseconds after the - second that the packet was captured. If ``nano=False``, - then the number of microseconds after the second the - packet was captured. If ``sec`` is not specified, - this value is ignored. - :type usec: int or long - :param caplen: The length of the packet in the capture file. If not - specified, uses ``len(raw(packet))``. - :type caplen: int - :param wirelen: The length of the packet on the wire. If not - specified, tries ``packet.wirelen``, otherwise uses - ``caplen``. - :type wirelen: int - :returns: None - :rtype: None - """ - if hasattr(packet, "time"): - if sec is None: - sec = int(packet.time) - usec = int(round((packet.time - sec) * - (1000000000 if self.nano else 1000000))) - if usec is None: - usec = 0 - - rawpkt = raw(packet) - caplen = len(rawpkt) if caplen is None else caplen - - if wirelen is None: - if hasattr(packet, "wirelen"): - wirelen = packet.wirelen - if wirelen is None: - wirelen = caplen - - RawPcapWriter._write_packet( - self, rawpkt, sec=sec, usec=usec, caplen=caplen, wirelen=wirelen) - - -@conf.commands.register -def import_hexcap(): - """Imports a tcpdump like hexadecimal view - - e.g: exported via hexdump() or tcpdump or wireshark's "export as hex" - """ - re_extract_hexcap = re.compile(r"^((0x)?[0-9a-fA-F]{2,}[ :\t]{,3}|) *(([0-9a-fA-F]{2} {,2}){,16})") # noqa: E501 - p = "" - try: - while True: - line = input().strip() - if not line: - break - try: - p += re_extract_hexcap.match(line).groups()[2] - except Exception: - warning("Parsing error during hexcap") - continue - except EOFError: - pass - - p = p.replace(" ", "") - return hex_bytes(p) - - -@conf.commands.register -def wireshark(pktlist, wait=False, **kwargs): - """ - Runs Wireshark on a list of packets. - - See :func:`tcpdump` for more parameter description. - - Note: this defaults to wait=False, to run Wireshark in the background. - """ - return tcpdump(pktlist, prog=conf.prog.wireshark, wait=wait, **kwargs) - - -@conf.commands.register -def tdecode(pktlist, args=None, **kwargs): - """ - Run tshark on a list of packets. - - :param args: If not specified, defaults to ``tshark -V``. - - See :func:`tcpdump` for more parameters. - """ - if args is None: - args = ["-V"] - return tcpdump(pktlist, prog=conf.prog.tshark, args=args, **kwargs) - - -def _guess_linktype_name(value): - """Guess the DLT name from its value.""" - import scapy.data - return next( - k[4:] for k, v in six.iteritems(scapy.data.__dict__) - if k.startswith("DLT") and v == value - ) - - -def _guess_linktype_value(name): - """Guess the value of a DLT name.""" - import scapy.data - if not name.startswith("DLT_"): - name = "DLT_" + name - return scapy.data.__dict__[name] - - -@conf.commands.register -def tcpdump(pktlist, dump=False, getfd=False, args=None, - prog=None, getproc=False, quiet=False, use_tempfile=None, - read_stdin_opts=None, linktype=None, wait=True): - """Run tcpdump or tshark on a list of packets. - - When using ``tcpdump`` on OSX (``prog == conf.prog.tcpdump``), this uses a - temporary file to store the packets. This works around a bug in Apple's - version of ``tcpdump``: http://apple.stackexchange.com/questions/152682/ - - Otherwise, the packets are passed in stdin. - - This function can be explicitly enabled or disabled with the - ``use_tempfile`` parameter. - - When using ``wireshark``, it will be called with ``-ki -`` to start - immediately capturing packets from stdin. - - Otherwise, the command will be run with ``-r -`` (which is correct for - ``tcpdump`` and ``tshark``). - - This can be overridden with ``read_stdin_opts``. This has no effect when - ``use_tempfile=True``, or otherwise reading packets from a regular file. - -pktlist: a Packet instance, a PacketList instance or a list of Packet - instances. Can also be a filename (as a string), an open - file-like object that must be a file format readable by - tshark (Pcap, PcapNg, etc.) or None (to sniff) - -dump: when set to True, returns a string instead of displaying it. -getfd: when set to True, returns a file-like object to read data - from tcpdump or tshark from. -getproc: when set to True, the subprocess.Popen object is returned -args: arguments (as a list) to pass to tshark (example for tshark: - args=["-T", "json"]). -prog: program to use (defaults to tcpdump, will work with tshark) -quiet: when set to True, the process stderr is discarded -use_tempfile: When set to True, always use a temporary file to store packets. - When set to False, pipe packets through stdin. - When set to None (default), only use a temporary file with - ``tcpdump`` on OSX. -read_stdin_opts: When set, a list of arguments needed to capture from stdin. - Otherwise, attempts to guess. -linktype: A custom DLT value or name, to overwrite the default values. -wait: If True (default), waits for the process to terminate before returning - to Scapy. If False, the process will be detached to the background. If - dump, getproc or getfd is True, these have the same effect as - ``wait=False``. - -Examples: - ->>> tcpdump([IP()/TCP(), IP()/UDP()]) -reading from file -, link-type RAW (Raw IP) -16:46:00.474515 IP 127.0.0.1.20 > 127.0.0.1.80: Flags [S], seq 0, win 8192, length 0 # noqa: E501 -16:46:00.475019 IP 127.0.0.1.53 > 127.0.0.1.53: [|domain] - ->>> tcpdump([IP()/TCP(), IP()/UDP()], prog=conf.prog.tshark) - 1 0.000000 127.0.0.1 -> 127.0.0.1 TCP 40 20->80 [SYN] Seq=0 Win=8192 Len=0 # noqa: E501 - 2 0.000459 127.0.0.1 -> 127.0.0.1 UDP 28 53->53 Len=0 - -To get a JSON representation of a tshark-parsed PacketList(), one can: ->>> import json, pprint ->>> json_data = json.load(tcpdump(IP(src="217.25.178.5", dst="45.33.32.156"), -... prog=conf.prog.tshark, args=["-T", "json"], -... getfd=True)) ->>> pprint.pprint(json_data) -[{u'_index': u'packets-2016-12-23', - u'_score': None, - u'_source': {u'layers': {u'frame': {u'frame.cap_len': u'20', - u'frame.encap_type': u'7', -[...] - u'frame.time_relative': u'0.000000000'}, - u'ip': {u'ip.addr': u'45.33.32.156', - u'ip.checksum': u'0x0000a20d', -[...] - u'ip.ttl': u'64', - u'ip.version': u'4'}, - u'raw': u'Raw packet data'}}, - u'_type': u'pcap_file'}] ->>> json_data[0]['_source']['layers']['ip']['ip.ttl'] -u'64' - """ - getfd = getfd or getproc - if prog is None: - prog = [conf.prog.tcpdump] - _prog_name = "windump()" if WINDOWS else "tcpdump()" - elif isinstance(prog, six.string_types): - _prog_name = "{}()".format(prog) - prog = [prog] - else: - raise ValueError("prog must be a string") - from scapy.arch.common import TCPDUMP - if prog[0] == conf.prog.tcpdump and not TCPDUMP: - message = "tcpdump is not available. Cannot use tcpdump() !" - raise Scapy_Exception(message) - - if linktype is not None: - # Tcpdump does not support integers in -y (yet) - # https://github.com/the-tcpdump-group/tcpdump/issues/758 - if isinstance(linktype, int): - # Guess name from value - try: - linktype_name = _guess_linktype_name(linktype) - except StopIteration: - linktype = -1 - else: - # Guess value from name - if linktype.startswith("DLT_"): - linktype = linktype[4:] - linktype_name = linktype - try: - linktype = _guess_linktype_value(linktype) - except KeyError: - linktype = -1 - if linktype == -1: - raise ValueError( - "Unknown linktype. Try passing its datalink name instead" - ) - prog += ["-y", linktype_name] - - # Build Popen arguments - if args is None: - args = [] - else: - # Make a copy of args - args = list(args) - - stdout = subprocess.PIPE if dump or getfd else None - stderr = open(os.devnull) if quiet else None - - if use_tempfile is None: - # Apple's tcpdump cannot read from stdin, see: - # http://apple.stackexchange.com/questions/152682/ - use_tempfile = DARWIN and prog[0] == conf.prog.tcpdump - - if read_stdin_opts is None: - if prog[0] == conf.prog.wireshark: - # Start capturing immediately (-k) from stdin (-i -) - read_stdin_opts = ["-ki", "-"] - else: - read_stdin_opts = ["-r", "-"] - else: - # Make a copy of read_stdin_opts - read_stdin_opts = list(read_stdin_opts) - - if pktlist is None: - # sniff - with ContextManagerSubprocess(_prog_name, prog[0]): - proc = subprocess.Popen( - prog + args, - stdout=stdout, - stderr=stderr, - ) - elif isinstance(pktlist, six.string_types): - # file - with ContextManagerSubprocess(_prog_name, prog[0]): - proc = subprocess.Popen( - prog + ["-r", pktlist] + args, - stdout=stdout, - stderr=stderr, - ) - elif use_tempfile: - tmpfile = get_temp_file(autoext=".pcap", fd=True) - try: - tmpfile.writelines(iter(lambda: pktlist.read(1048576), b"")) - except AttributeError: - wrpcap(tmpfile, pktlist, linktype=linktype) - else: - tmpfile.close() - with ContextManagerSubprocess(_prog_name, prog[0]): - proc = subprocess.Popen( - prog + ["-r", tmpfile.name] + args, - stdout=stdout, - stderr=stderr, - ) - else: - # pass the packet stream - with ContextManagerSubprocess(_prog_name, prog[0]): - proc = subprocess.Popen( - prog + read_stdin_opts + args, - stdin=subprocess.PIPE, - stdout=stdout, - stderr=stderr, - ) - try: - proc.stdin.writelines(iter(lambda: pktlist.read(1048576), b"")) - except AttributeError: - wrpcap(proc.stdin, pktlist, linktype=linktype) - except UnboundLocalError: - raise IOError("%s died unexpectedly !" % prog) - else: - proc.stdin.close() - if dump: - return b"".join(iter(lambda: proc.stdout.read(1048576), b"")) - if getproc: - return proc - if getfd: - return proc.stdout - if wait: - proc.wait() - - -@conf.commands.register -def hexedit(pktlist): - """Run hexedit on a list of packets, then return the edited packets.""" - f = get_temp_file() - wrpcap(f, pktlist) - with ContextManagerSubprocess("hexedit()", conf.prog.hexedit): - subprocess.call([conf.prog.hexedit, f]) - pktlist = rdpcap(f) - os.unlink(f) - return pktlist - - -def get_terminal_width(): - """Get terminal width (number of characters) if in a window. - - Notice: this will try several methods in order to - support as many terminals and OS as possible. - """ - # Let's first try using the official API - # (Python 3.3+) - if not six.PY2: - import shutil - sizex = shutil.get_terminal_size(fallback=(0, 0))[0] - if sizex != 0: - return sizex - # Backups / Python 2.7 - if WINDOWS: - from ctypes import windll, create_string_buffer - # http://code.activestate.com/recipes/440694-determine-size-of-console-window-on-windows/ - h = windll.kernel32.GetStdHandle(-12) - csbi = create_string_buffer(22) - res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi) - if res: - (bufx, bufy, curx, cury, wattr, - left, top, right, bottom, maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw) # noqa: E501 - sizex = right - left + 1 - # sizey = bottom - top + 1 - return sizex - return None - else: - # We have various methods - sizex = None - # COLUMNS is set on some terminals - try: - sizex = int(os.environ['COLUMNS']) - except Exception: - pass - if sizex: - return sizex - # We can query TIOCGWINSZ - try: - import fcntl - import termios - s = struct.pack('HHHH', 0, 0, 0, 0) - x = fcntl.ioctl(1, termios.TIOCGWINSZ, s) - sizex = struct.unpack('HHHH', x)[1] - except IOError: - pass - return sizex - - -def pretty_list(rtlst, header, sortBy=0, borders=False): - """Pretty list to fit the terminal, and add header""" - if borders: - _space = "|" - else: - _space = " " - # Windows has a fat terminal border - _spacelen = len(_space) * (len(header) - 1) + (10 if WINDOWS else 0) - _croped = False - # Sort correctly - rtlst.sort(key=lambda x: x[sortBy]) - # Append tag - rtlst = header + rtlst - # Detect column's width - colwidth = [max([len(y) for y in x]) for x in zip(*rtlst)] - # Make text fit in box (if required) - width = get_terminal_width() - if conf.auto_crop_tables and width: - width = width - _spacelen - while sum(colwidth) > width: - _croped = True - # Needs to be cropped - # Get the longest row - i = colwidth.index(max(colwidth)) - # Get all elements of this row - row = [len(x[i]) for x in rtlst] - # Get biggest element of this row: biggest of the array - j = row.index(max(row)) - # Re-build column tuple with the edited element - t = list(rtlst[j]) - t[i] = t[i][:-2] + "_" - rtlst[j] = tuple(t) - # Update max size - row[j] = len(t[i]) - colwidth[i] = max(row) - if _croped: - log_runtime.info("Table cropped to fit the terminal (conf.auto_crop_tables==True)") # noqa: E501 - # Generate padding scheme - fmt = _space.join(["%%-%ds" % x for x in colwidth]) - # Append separation line if needed - if borders: - rtlst.insert(1, tuple("-" * x for x in colwidth)) - # Compile - rt = "\n".join(((fmt % x).strip() for x in rtlst)) - return rt - - -def __make_table(yfmtfunc, fmtfunc, endline, data, fxyz, sortx=None, sorty=None, seplinefunc=None): # noqa: E501 - """Core function of the make_table suite, which generates the table""" - vx = {} - vy = {} - vz = {} - vxf = {} - - # Python 2 backward compatibility - fxyz = lambda_tuple_converter(fxyz) - - tmp_len = 0 - for e in data: - xx, yy, zz = [str(s) for s in fxyz(*e)] - tmp_len = max(len(yy), tmp_len) - vx[xx] = max(vx.get(xx, 0), len(xx), len(zz)) - vy[yy] = None - vz[(xx, yy)] = zz - - vxk = list(vx) - vyk = list(vy) - if sortx: - vxk.sort(key=sortx) - else: - try: - vxk.sort(key=int) - except Exception: - try: - vxk.sort(key=atol) - except Exception: - vxk.sort() - if sorty: - vyk.sort(key=sorty) - else: - try: - vyk.sort(key=int) - except Exception: - try: - vyk.sort(key=atol) - except Exception: - vyk.sort() - - if seplinefunc: - sepline = seplinefunc(tmp_len, [vx[x] for x in vxk]) - print(sepline) - - fmt = yfmtfunc(tmp_len) - print(fmt % "", end=' ') - for x in vxk: - vxf[x] = fmtfunc(vx[x]) - print(vxf[x] % x, end=' ') - print(endline) - if seplinefunc: - print(sepline) - for y in vyk: - print(fmt % y, end=' ') - for x in vxk: - print(vxf[x] % vz.get((x, y), "-"), end=' ') - print(endline) - if seplinefunc: - print(sepline) - - -def make_table(*args, **kargs): - __make_table(lambda l: "%%-%is" % l, lambda l: "%%-%is" % l, "", *args, **kargs) # noqa: E501 - - -def make_lined_table(*args, **kargs): - __make_table(lambda l: "%%-%is |" % l, lambda l: "%%-%is |" % l, "", - seplinefunc=lambda a, x: "+".join('-' * (y + 2) for y in [a - 1] + x + [-2]), # noqa: E501 - *args, **kargs) - - -def make_tex_table(*args, **kargs): - __make_table(lambda l: "%s", lambda l: "& %s", "\\\\", seplinefunc=lambda a, x: "\\hline", *args, **kargs) # noqa: E501 - -# TRex Change - Added function -def str2int(s): - if type(s) not in (str, bytes): - # Not a string, returning the data. - return s - if type(s) is str: - s = str2bytes(s) - i = 0 - for c in s: - c = ord(c) if type(c) is not int else c - i = i << 8 - i += c - return i - -# TRex Change - Added function -def int2str(num, length = None): - c_arr = [] - i = num - while i: - c_arr.insert(0, chr(i & 0xff)) - i = i >> 8 - if six.PY2: - s = b''.join(c_arr) - if length is None: - return s - if length < len(s): - raise Exception("Given integer: '%s' can't fit string of length '%s'!" % (num, length)) - return s.rjust(length, b'\0') - elif six.PY3: - s = ''.join(c_arr) - if length is None: - return str2bytes(s) - if length < len(s): - raise Exception("Given integer: '%s' can't fit string of length '%s'!" % (num, length)) - return str2bytes(s.rjust(length, '\0')) - -#################### -# WHOIS CLIENT # -#################### - - -def whois(ip_address): - """Whois client for Python""" - whois_ip = str(ip_address) - try: - query = socket.gethostbyname(whois_ip) - except Exception: - query = whois_ip - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect(("whois.ripe.net", 43)) - s.send(query.encode("utf8") + b"\r\n") - answer = b"" - while True: - d = s.recv(4096) - answer += d - if not d: - break - s.close() - ignore_tag = b"remarks:" - # ignore all lines starting with the ignore_tag - lines = [line for line in answer.split(b"\n") if not line or (line and not line.startswith(ignore_tag))] # noqa: E501 - # remove empty lines at the bottom - for i in range(1, len(lines)): - if not lines[-i].strip(): - del lines[-i] - else: - break - return b"\n".join(lines[3:]) - -####################### -# PERIODIC SENDER # -####################### - - -class PeriodicSenderThread(threading.Thread): - def __init__(self, sock, pkt, interval=0.5): - """ Thread to send packets periodically - - Args: - sock: socket where packet is sent periodically - pkt: packet to send - interval: interval between two packets - """ - self._pkt = pkt - self._socket = sock - self._stopped = threading.Event() - self._interval = interval - threading.Thread.__init__(self) - - def run(self): - while not self._stopped.is_set(): - self._socket.send(self._pkt) - time.sleep(self._interval) - - def stop(self): - self._stopped.set() diff --git a/scripts/external_libs/scapy-2.4.3/scapy/utils6.py b/scripts/external_libs/scapy-2.4.3/scapy/utils6.py deleted file mode 100644 index 187382f3da..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/utils6.py +++ /dev/null @@ -1,904 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# This program is published under a GPLv2 license - -# Copyright (C) 2005 Guillaume Valadon -# Arnaud Ebalard - -""" -Utility functions for IPv6. -""" -from __future__ import absolute_import -import operator -import random -import socket -import struct -import time -import re - -from scapy.config import conf -import scapy.consts -from scapy.base_classes import Gen -from scapy.data import IPV6_ADDR_GLOBAL, IPV6_ADDR_LINKLOCAL, \ - IPV6_ADDR_SITELOCAL, IPV6_ADDR_LOOPBACK, IPV6_ADDR_UNICAST,\ - IPV6_ADDR_MULTICAST, IPV6_ADDR_6TO4, IPV6_ADDR_UNSPECIFIED -from scapy.utils import strxor -from scapy.compat import orb, chb -from scapy.pton_ntop import inet_pton, inet_ntop -from scapy.volatile import RandMAC -from scapy.error import warning, Scapy_Exception -from functools import reduce, cmp_to_key -from scapy.modules.six.moves import range, zip - - -def construct_source_candidate_set(addr, plen, laddr): - """ - Given all addresses assigned to a specific interface ('laddr' parameter), - this function returns the "candidate set" associated with 'addr/plen'. - - Basically, the function filters all interface addresses to keep only those - that have the same scope as provided prefix. - - This is on this list of addresses that the source selection mechanism - will then be performed to select the best source address associated - with some specific destination that uses this prefix. - """ - def cset_sort(x, y): - x_global = 0 - if in6_isgladdr(x): - x_global = 1 - y_global = 0 - if in6_isgladdr(y): - y_global = 1 - res = y_global - x_global - if res != 0 or y_global != 1: - return res - # two global addresses: if one is native, it wins. - if not in6_isaddr6to4(x): - return -1 - return -res - - cset = [] - if in6_isgladdr(addr) or in6_isuladdr(addr): - cset = (x for x in laddr if x[1] == IPV6_ADDR_GLOBAL) - elif in6_islladdr(addr): - cset = (x for x in laddr if x[1] == IPV6_ADDR_LINKLOCAL) - elif in6_issladdr(addr): - cset = (x for x in laddr if x[1] == IPV6_ADDR_SITELOCAL) - elif in6_ismaddr(addr): - if in6_ismnladdr(addr): - cset = [('::1', 16, scapy.consts.LOOPBACK_INTERFACE)] - elif in6_ismgladdr(addr): - cset = (x for x in laddr if x[1] == IPV6_ADDR_GLOBAL) - elif in6_ismlladdr(addr): - cset = (x for x in laddr if x[1] == IPV6_ADDR_LINKLOCAL) - elif in6_ismsladdr(addr): - cset = (x for x in laddr if x[1] == IPV6_ADDR_SITELOCAL) - elif addr == '::' and plen == 0: - cset = (x for x in laddr if x[1] == IPV6_ADDR_GLOBAL) - cset = [x[0] for x in cset] - # TODO convert the cmd use into a key - cset.sort(key=cmp_to_key(cset_sort)) # Sort with global addresses first - return cset - - -def get_source_addr_from_candidate_set(dst, candidate_set): - """ - This function implement a limited version of source address selection - algorithm defined in section 5 of RFC 3484. The format is very different - from that described in the document because it operates on a set - of candidate source address for some specific route. - """ - - def scope_cmp(a, b): - """ - Given two addresses, returns -1, 0 or 1 based on comparison of - their scope - """ - scope_mapper = {IPV6_ADDR_GLOBAL: 4, - IPV6_ADDR_SITELOCAL: 3, - IPV6_ADDR_LINKLOCAL: 2, - IPV6_ADDR_LOOPBACK: 1} - sa = in6_getscope(a) - if sa == -1: - sa = IPV6_ADDR_LOOPBACK - sb = in6_getscope(b) - if sb == -1: - sb = IPV6_ADDR_LOOPBACK - - sa = scope_mapper[sa] - sb = scope_mapper[sb] - - if sa == sb: - return 0 - if sa > sb: - return 1 - return -1 - - def rfc3484_cmp(source_a, source_b): - """ - The function implements a limited version of the rules from Source - Address selection algorithm defined section of RFC 3484. - """ - - # Rule 1: Prefer same address - if source_a == dst: - return 1 - if source_b == dst: - return 1 - - # Rule 2: Prefer appropriate scope - tmp = scope_cmp(source_a, source_b) - if tmp == -1: - if scope_cmp(source_a, dst) == -1: - return 1 - else: - return -1 - elif tmp == 1: - if scope_cmp(source_b, dst) == -1: - return 1 - else: - return -1 - - # Rule 3: cannot be easily implemented - # Rule 4: cannot be easily implemented - # Rule 5: does not make sense here - # Rule 6: cannot be implemented - # Rule 7: cannot be implemented - - # Rule 8: Longest prefix match - tmp1 = in6_get_common_plen(source_a, dst) - tmp2 = in6_get_common_plen(source_b, dst) - if tmp1 > tmp2: - return 1 - elif tmp2 > tmp1: - return -1 - return 0 - - if not candidate_set: - # Should not happen - return None - - candidate_set.sort(key=cmp_to_key(rfc3484_cmp), reverse=True) - - return candidate_set[0] - - -# Think before modify it : for instance, FE::1 does exist and is unicast -# there are many others like that. -# TODO : integrate Unique Local Addresses -def in6_getAddrType(addr): - naddr = inet_pton(socket.AF_INET6, addr) - paddr = inet_ntop(socket.AF_INET6, naddr) # normalize - addrType = 0 - # _Assignable_ Global Unicast Address space - # is defined in RFC 3513 as those in 2000::/3 - if ((orb(naddr[0]) & 0xE0) == 0x20): - addrType = (IPV6_ADDR_UNICAST | IPV6_ADDR_GLOBAL) - if naddr[:2] == b' \x02': # Mark 6to4 @ - addrType |= IPV6_ADDR_6TO4 - elif orb(naddr[0]) == 0xff: # multicast - addrScope = paddr[3] - if addrScope == '2': - addrType = (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_MULTICAST) - elif addrScope == 'e': - addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_MULTICAST) - else: - addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_MULTICAST) - elif ((orb(naddr[0]) == 0xfe) and ((int(paddr[2], 16) & 0xC) == 0x8)): - addrType = (IPV6_ADDR_UNICAST | IPV6_ADDR_LINKLOCAL) - elif paddr == "::1": - addrType = IPV6_ADDR_LOOPBACK - elif paddr == "::": - addrType = IPV6_ADDR_UNSPECIFIED - else: - # Everything else is global unicast (RFC 3513) - # Even old deprecated (RFC3879) Site-Local addresses - addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST) - - return addrType - - -def in6_mactoifaceid(mac, ulbit=None): - """ - Compute the interface ID in modified EUI-64 format associated - to the Ethernet address provided as input. - value taken by U/L bit in the interface identifier is basically - the reversed value of that in given MAC address it can be forced - to a specific value by using optional 'ulbit' parameter. - """ - if len(mac) != 17: - return None - m = "".join(mac.split(':')) - if len(m) != 12: - return None - first = int(m[0:2], 16) - if ulbit is None or not (ulbit == 0 or ulbit == 1): - ulbit = [1, '-', 0][first & 0x02] - ulbit *= 2 - first = "%.02x" % ((first & 0xFD) | ulbit) - eui64 = first + m[2:4] + ":" + m[4:6] + "FF:FE" + m[6:8] + ":" + m[8:12] - return eui64.upper() - - -def in6_ifaceidtomac(ifaceid): - """ - Extract the mac address from provided iface ID. Iface ID is provided - in printable format ("XXXX:XXFF:FEXX:XXXX", eventually compressed). None - is returned on error. - """ - try: - # Set ifaceid to a binary form - ifaceid = inet_pton(socket.AF_INET6, "::" + ifaceid)[8:16] - except Exception: - return None - if ifaceid[3:5] != b'\xff\xfe': # Check for burned-in MAC address - return None - - # Unpacking and converting first byte of faceid to MAC address equivalent - first = struct.unpack("B", ifaceid[:1])[0] - ulbit = 2 * [1, '-', 0][first & 0x02] - first = struct.pack("B", ((first & 0xFD) | ulbit)) - # Split into two vars to remove the \xff\xfe bytes - oui = first + ifaceid[1:3] - end = ifaceid[5:] - # Convert and reconstruct into a MAC Address - mac_bytes = ["%.02x" % orb(x) for x in list(oui + end)] - return ":".join(mac_bytes) - - -def in6_addrtomac(addr): - """ - Extract the mac address from provided address. None is returned - on error. - """ - mask = inet_pton(socket.AF_INET6, "::ffff:ffff:ffff:ffff") - x = in6_and(mask, inet_pton(socket.AF_INET6, addr)) - ifaceid = inet_ntop(socket.AF_INET6, x)[2:] - return in6_ifaceidtomac(ifaceid) - - -def in6_addrtovendor(addr): - """ - Extract the MAC address from a modified EUI-64 constructed IPv6 - address provided and use the IANA oui.txt file to get the vendor. - The database used for the conversion is the one loaded by Scapy - from a Wireshark installation if discovered in a well-known - location. None is returned on error, "UNKNOWN" if the vendor is - unknown. - """ - mac = in6_addrtomac(addr) - if mac is None or not conf.manufdb: - return None - - res = conf.manufdb._get_manuf(mac) - if len(res) == 17 and res.count(':') != 5: # Mac address, i.e. unknown - res = "UNKNOWN" - - return res - - -def in6_getLinkScopedMcastAddr(addr, grpid=None, scope=2): - """ - Generate a Link-Scoped Multicast Address as described in RFC 4489. - Returned value is in printable notation. - - 'addr' parameter specifies the link-local address to use for generating - Link-scoped multicast address IID. - - By default, the function returns a ::/96 prefix (aka last 32 bits of - returned address are null). If a group id is provided through 'grpid' - parameter, last 32 bits of the address are set to that value (accepted - formats : b'\x12\x34\x56\x78' or '12345678' or 0x12345678 or 305419896). - - By default, generated address scope is Link-Local (2). That value can - be modified by passing a specific 'scope' value as an argument of the - function. RFC 4489 only authorizes scope values <= 2. Enforcement - is performed by the function (None will be returned). - - If no link-local address can be used to generate the Link-Scoped IPv6 - Multicast address, or if another error occurs, None is returned. - """ - if scope not in [0, 1, 2]: - return None - try: - if not in6_islladdr(addr): - return None - addr = inet_pton(socket.AF_INET6, addr) - except Exception: - warning("in6_getLinkScopedMcastPrefix(): Invalid address provided") - return None - - iid = addr[8:] - - if grpid is None: - grpid = b'\x00\x00\x00\x00' - else: - if isinstance(grpid, (bytes, str)): - if len(grpid) == 8: - try: - grpid = int(grpid, 16) & 0xffffffff - except Exception: - warning("in6_getLinkScopedMcastPrefix(): Invalid group id provided") # noqa: E501 - return None - elif len(grpid) == 4: - try: - grpid = struct.unpack("!I", grpid)[0] - except Exception: - warning("in6_getLinkScopedMcastPrefix(): Invalid group id provided") # noqa: E501 - return None - grpid = struct.pack("!I", grpid) - - flgscope = struct.pack("B", 0xff & ((0x3 << 4) | scope)) - plen = b'\xff' - res = b'\x00' - a = b'\xff' + flgscope + res + plen + iid + grpid - - return inet_ntop(socket.AF_INET6, a) - - -def in6_get6to4Prefix(addr): - """ - Returns the /48 6to4 prefix associated with provided IPv4 address - On error, None is returned. No check is performed on public/private - status of the address - """ - try: - addr = inet_pton(socket.AF_INET, addr) - addr = inet_ntop(socket.AF_INET6, b'\x20\x02' + addr + b'\x00' * 10) - except Exception: - return None - return addr - - -def in6_6to4ExtractAddr(addr): - """ - Extract IPv4 address embedded in 6to4 address. Passed address must be - a 6to4 address. None is returned on error. - """ - try: - addr = inet_pton(socket.AF_INET6, addr) - except Exception: - return None - if addr[:2] != b" \x02": - return None - return inet_ntop(socket.AF_INET, addr[2:6]) - - -def in6_getLocalUniquePrefix(): - """ - Returns a pseudo-randomly generated Local Unique prefix. Function - follows recommendation of Section 3.2.2 of RFC 4193 for prefix - generation. - """ - # 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. - - # epoch = (1900, 1, 1, 0, 0, 0, 5, 1, 0) - # x = time.time() - # from time import gmtime, strftime, gmtime, mktime - # delta = mktime(gmtime(0)) - mktime(self.epoch) - # x = x-delta - - tod = time.time() # time of day. Will bother with epoch later - i = int(tod) - j = int((tod - i) * (2**32)) - tod = struct.pack("!II", i, j) - mac = RandMAC() - # construct modified EUI-64 ID - eui64 = inet_pton(socket.AF_INET6, '::' + in6_mactoifaceid(mac))[8:] - import hashlib - globalid = hashlib.sha1(tod + eui64).digest()[:5] - return inet_ntop(socket.AF_INET6, b'\xfd' + globalid + b'\x00' * 10) - - -def in6_getRandomizedIfaceId(ifaceid, previous=None): - """ - Implements the interface ID generation algorithm described in RFC 3041. - The function takes the Modified EUI-64 interface identifier generated - as described in RFC 4291 and an optional previous history value (the - first element of the output of this function). If no previous interface - identifier is provided, a random one is generated. The function returns - a tuple containing the randomized interface identifier and the history - value (for possible future use). Input and output values are provided in - a "printable" format as depicted below. - - ex: - >>> in6_getRandomizedIfaceId('20b:93ff:feeb:2d3') - ('4c61:76ff:f46a:a5f3', 'd006:d540:db11:b092') - >>> in6_getRandomizedIfaceId('20b:93ff:feeb:2d3', - previous='d006:d540:db11:b092') - ('fe97:46fe:9871:bd38', 'eeed:d79c:2e3f:62e') - """ - - s = b"" - if previous is None: - d = b"".join(chb(x) for x in range(256)) - for _ in range(8): - s += chb(random.choice(d)) - previous = s - s = inet_pton(socket.AF_INET6, "::" + ifaceid)[8:] + previous - import hashlib - s = hashlib.md5(s).digest() - s1, s2 = s[:8], s[8:] - s1 = chb(orb(s1[0]) | 0x04) + s1[1:] - s1 = inet_ntop(socket.AF_INET6, b"\xff" * 8 + s1)[20:] - s2 = inet_ntop(socket.AF_INET6, b"\xff" * 8 + s2)[20:] - return (s1, s2) - - -_rfc1924map = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', # noqa: E501 - 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', # noqa: E501 - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', # noqa: E501 - 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', # noqa: E501 - 'y', 'z', '!', '#', '$', '%', '&', '(', ')', '*', '+', '-', ';', '<', '=', # noqa: E501 - '>', '?', '@', '^', '_', '`', '{', '|', '}', '~'] - - -def in6_ctop(addr): - """ - Convert an IPv6 address in Compact Representation Notation - (RFC 1924) to printable representation ;-) - Returns None on error. - """ - if len(addr) != 20 or not reduce(lambda x, y: x and y, - [x in _rfc1924map for x in addr]): - return None - i = 0 - for c in addr: - j = _rfc1924map.index(c) - i = 85 * i + j - res = [] - for j in range(4): - res.append(struct.pack("!I", i % 2**32)) - i = i // (2**32) - res.reverse() - return inet_ntop(socket.AF_INET6, b"".join(res)) - - -def in6_ptoc(addr): - """ - Converts an IPv6 address in printable representation to RFC - 1924 Compact Representation ;-) - Returns None on error. - """ - try: - d = struct.unpack("!IIII", inet_pton(socket.AF_INET6, addr)) - except Exception: - return None - res = 0 - m = [2**96, 2**64, 2**32, 1] - for i in range(4): - res += d[i] * m[i] - rem = res - res = [] - while rem: - res.append(_rfc1924map[rem % 85]) - rem = rem // 85 - res.reverse() - return "".join(res) - - -def in6_isaddr6to4(x): - """ - Return True if provided address (in printable format) is a 6to4 - address (being in 2002::/16). - """ - x = inet_pton(socket.AF_INET6, x) - return x[:2] == b' \x02' - - -conf.teredoPrefix = "2001::" # old one was 3ffe:831f (it is a /32) -conf.teredoServerPort = 3544 - - -def in6_isaddrTeredo(x): - """ - Return True if provided address is a Teredo, meaning it is under - the /32 conf.teredoPrefix prefix value (by default, 2001::). - Otherwise, False is returned. Address must be passed in printable - format. - """ - our = inet_pton(socket.AF_INET6, x)[0:4] - teredoPrefix = inet_pton(socket.AF_INET6, conf.teredoPrefix)[0:4] - return teredoPrefix == our - - -def teredoAddrExtractInfo(x): - """ - Extract information from a Teredo address. Return value is - a 4-tuple made of IPv4 address of Teredo server, flag value (int), - mapped address (non obfuscated) and mapped port (non obfuscated). - No specific checks are performed on passed address. - """ - addr = inet_pton(socket.AF_INET6, x) - server = inet_ntop(socket.AF_INET, addr[4:8]) - flag = struct.unpack("!H", addr[8:10])[0] - mappedport = struct.unpack("!H", strxor(addr[10:12], b'\xff' * 2))[0] - mappedaddr = inet_ntop(socket.AF_INET, strxor(addr[12:16], b'\xff' * 4)) - return server, flag, mappedaddr, mappedport - - -def in6_iseui64(x): - """ - Return True if provided address has an interface identifier part - created in modified EUI-64 format (meaning it matches *::*:*ff:fe*:*). - Otherwise, False is returned. Address must be passed in printable - format. - """ - eui64 = inet_pton(socket.AF_INET6, '::ff:fe00:0') - x = in6_and(inet_pton(socket.AF_INET6, x), eui64) - return x == eui64 - - -def in6_isanycast(x): # RFC 2526 - if in6_iseui64(x): - s = '::fdff:ffff:ffff:ff80' - packed_x = inet_pton(socket.AF_INET6, x) - packed_s = inet_pton(socket.AF_INET6, s) - x_and_s = in6_and(packed_x, packed_s) - return x_and_s == packed_s - else: - # not EUI-64 - # | n bits | 121-n bits | 7 bits | - # +---------------------------------+------------------+------------+ - # | subnet prefix | 1111111...111111 | anycast ID | - # +---------------------------------+------------------+------------+ - # | interface identifier field | - warning('in6_isanycast(): TODO not EUI-64') - return 0 - - -def _in6_bitops(a1, a2, operator=0): - a1 = struct.unpack('4I', a1) - a2 = struct.unpack('4I', a2) - fop = [lambda x, y: x | y, - lambda x, y: x & y, - lambda x, y: x ^ y - ] - ret = map(fop[operator % len(fop)], a1, a2) - return b"".join(struct.pack('I', x) for x in ret) - - -def in6_or(a1, a2): - """ - Provides a bit to bit OR of provided addresses. They must be - passed in network format. Return value is also an IPv6 address - in network format. - """ - return _in6_bitops(a1, a2, 0) - - -def in6_and(a1, a2): - """ - Provides a bit to bit AND of provided addresses. They must be - passed in network format. Return value is also an IPv6 address - in network format. - """ - return _in6_bitops(a1, a2, 1) - - -def in6_xor(a1, a2): - """ - Provides a bit to bit XOR of provided addresses. They must be - passed in network format. Return value is also an IPv6 address - in network format. - """ - return _in6_bitops(a1, a2, 2) - - -def in6_cidr2mask(m): - """ - Return the mask (bitstring) associated with provided length - value. For instance if function is called on 48, return value is - b'\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'. - - """ - if m > 128 or m < 0: - raise Scapy_Exception("value provided to in6_cidr2mask outside [0, 128] domain (%d)" % m) # noqa: E501 - - t = [] - for i in range(0, 4): - t.append(max(0, 2**32 - 2**(32 - min(32, m)))) - m -= 32 - - return b"".join(struct.pack('!I', x) for x in t) - - -def in6_getnsma(a): - """ - Return link-local solicited-node multicast address for given - address. Passed address must be provided in network format. - Returned value is also in network format. - """ - - r = in6_and(a, inet_pton(socket.AF_INET6, '::ff:ffff')) - r = in6_or(inet_pton(socket.AF_INET6, 'ff02::1:ff00:0'), r) - return r - - -def in6_getnsmac(a): # return multicast Ethernet address associated with multicast v6 destination # noqa: E501 - """ - Return the multicast mac address associated with provided - IPv6 address. Passed address must be in network format. - """ - - a = struct.unpack('16B', a)[-4:] - mac = '33:33:' - mac += ':'.join("%.2x" % x for x in a) - return mac - - -def in6_getha(prefix): - """ - Return the anycast address associated with all home agents on a given - subnet. - """ - r = in6_and(inet_pton(socket.AF_INET6, prefix), in6_cidr2mask(64)) - r = in6_or(r, inet_pton(socket.AF_INET6, '::fdff:ffff:ffff:fffe')) - return inet_ntop(socket.AF_INET6, r) - - -def in6_ptop(str): - """ - Normalizes IPv6 addresses provided in printable format, returning the - same address in printable format. (2001:0db8:0:0::1 -> 2001:db8::1) - """ - return inet_ntop(socket.AF_INET6, inet_pton(socket.AF_INET6, str)) - - -def in6_isincluded(addr, prefix, plen): - """ - Returns True when 'addr' belongs to prefix/plen. False otherwise. - """ - temp = inet_pton(socket.AF_INET6, addr) - pref = in6_cidr2mask(plen) - zero = inet_pton(socket.AF_INET6, prefix) - return zero == in6_and(temp, pref) - - -def in6_isllsnmaddr(str): - """ - Return True if provided address is a link-local solicited node - multicast address, i.e. belongs to ff02::1:ff00:0/104. False is - returned otherwise. - """ - temp = in6_and(b"\xff" * 13 + b"\x00" * 3, inet_pton(socket.AF_INET6, str)) - temp2 = b'\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00\x00' - return temp == temp2 - - -def in6_isdocaddr(str): - """ - Returns True if provided address in printable format belongs to - 2001:db8::/32 address space reserved for documentation (as defined - in RFC 3849). - """ - return in6_isincluded(str, '2001:db8::', 32) - - -def in6_islladdr(str): - """ - Returns True if provided address in printable format belongs to - _allocated_ link-local unicast address space (fe80::/10) - """ - return in6_isincluded(str, 'fe80::', 10) - - -def in6_issladdr(str): - """ - Returns True if provided address in printable format belongs to - _allocated_ site-local address space (fec0::/10). This prefix has - been deprecated, address being now reserved by IANA. Function - will remain for historic reasons. - """ - return in6_isincluded(str, 'fec0::', 10) - - -def in6_isuladdr(str): - """ - Returns True if provided address in printable format belongs to - Unique local address space (fc00::/7). - """ - return in6_isincluded(str, 'fc00::', 7) - -# TODO : we should see the status of Unique Local addresses against -# global address space. -# Up-to-date information is available through RFC 3587. -# We should review function behavior based on its content. - - -def in6_isgladdr(str): - """ - Returns True if provided address in printable format belongs to - _allocated_ global address space (2000::/3). Please note that, - Unique Local addresses (FC00::/7) are not part of global address - space, and won't match. - """ - return in6_isincluded(str, '2000::', 3) - - -def in6_ismaddr(str): - """ - Returns True if provided address in printable format belongs to - allocated Multicast address space (ff00::/8). - """ - return in6_isincluded(str, 'ff00::', 8) - - -def in6_ismnladdr(str): - """ - Returns True if address belongs to node-local multicast address - space (ff01::/16) as defined in RFC - """ - return in6_isincluded(str, 'ff01::', 16) - - -def in6_ismgladdr(str): - """ - Returns True if address belongs to global multicast address - space (ff0e::/16). - """ - return in6_isincluded(str, 'ff0e::', 16) - - -def in6_ismlladdr(str): - """ - Returns True if address belongs to link-local multicast address - space (ff02::/16) - """ - return in6_isincluded(str, 'ff02::', 16) - - -def in6_ismsladdr(str): - """ - Returns True if address belongs to site-local multicast address - space (ff05::/16). Site local address space has been deprecated. - Function remains for historic reasons. - """ - return in6_isincluded(str, 'ff05::', 16) - - -def in6_isaddrllallnodes(str): - """ - Returns True if address is the link-local all-nodes multicast - address (ff02::1). - """ - return (inet_pton(socket.AF_INET6, "ff02::1") == - inet_pton(socket.AF_INET6, str)) - - -def in6_isaddrllallservers(str): - """ - Returns True if address is the link-local all-servers multicast - address (ff02::2). - """ - return (inet_pton(socket.AF_INET6, "ff02::2") == - inet_pton(socket.AF_INET6, str)) - - -def in6_getscope(addr): - """ - Returns the scope of the address. - """ - if in6_isgladdr(addr) or in6_isuladdr(addr): - scope = IPV6_ADDR_GLOBAL - elif in6_islladdr(addr): - scope = IPV6_ADDR_LINKLOCAL - elif in6_issladdr(addr): - scope = IPV6_ADDR_SITELOCAL - elif in6_ismaddr(addr): - if in6_ismgladdr(addr): - scope = IPV6_ADDR_GLOBAL - elif in6_ismlladdr(addr): - scope = IPV6_ADDR_LINKLOCAL - elif in6_ismsladdr(addr): - scope = IPV6_ADDR_SITELOCAL - elif in6_ismnladdr(addr): - scope = IPV6_ADDR_LOOPBACK - else: - scope = -1 - elif addr == '::1': - scope = IPV6_ADDR_LOOPBACK - else: - scope = -1 - return scope - - -def in6_get_common_plen(a, b): - """ - Return common prefix length of IPv6 addresses a and b. - """ - def matching_bits(byte1, byte2): - for i in range(8): - cur_mask = 0x80 >> i - if (byte1 & cur_mask) != (byte2 & cur_mask): - return i - return 8 - - tmpA = inet_pton(socket.AF_INET6, a) - tmpB = inet_pton(socket.AF_INET6, b) - for i in range(16): - mbits = matching_bits(orb(tmpA[i]), orb(tmpB[i])) - if mbits != 8: - return 8 * i + mbits - return 128 - - -def in6_isvalid(address): - """Return True if 'address' is a valid IPv6 address string, False - otherwise.""" - - try: - socket.inet_pton(socket.AF_INET6, address) - return True - except Exception: - return False - - -class Net6(Gen): # syntax ex. fec0::/126 - """Generate a list of IPv6s from a network address or a name""" - name = "ipv6" - ip_regex = 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.ip_regex.match(net): - tmp[0] = socket.getaddrinfo(tmp[0], None, socket.AF_INET6)[0][-1][0] # noqa: E501 - - netmask = int(tmp[1]) - self.net = inet_pton(socket.AF_INET6, tmp[0]) - self.mask = in6_cidr2mask(netmask) - self.plen = netmask - - def _parse(self): - def parse_digit(value, netmask): - netmask = min(8, max(netmask, 0)) - value = int(value) - return (value & (0xff << netmask), - (value | (0xff >> (8 - netmask))) + 1) - - self.parsed = [ - parse_digit(x, y) for x, y in zip( - struct.unpack("16B", in6_and(self.net, self.mask)), - (x - self.plen for x in range(8, 129, 8)), - ) - ] - - def __iter__(self): - self._parse() - - def rec(n, l): - sep = ':' if n and n % 2 == 0 else '' - if n == 16: - return l - return rec(n + 1, [y + sep + '%.2x' % i - # faster than '%s%s%.2x' % (y, sep, i) - for i in range(*self.parsed[n]) - for y in l]) - - return (in6_ptop(addr) for addr in iter(rec(0, ['']))) - - def __iterlen__(self): - self._parse() - return reduce(operator.mul, ((y - x) for (x, y) in self.parsed), 1) - - def __str__(self): - try: - return next(self.__iter__()) - except (StopIteration, RuntimeError): - return None - - def __eq__(self, other): - return str(other) == str(self) - - def __ne__(self, other): - return str(other) != str(self) - - def __repr__(self): - return "Net6(%r)" % self.repr diff --git a/scripts/external_libs/scapy-2.4.3/scapy/volatile.py b/scripts/external_libs/scapy-2.4.3/scapy/volatile.py deleted file mode 100644 index d7fe5e362f..0000000000 --- a/scripts/external_libs/scapy-2.4.3/scapy/volatile.py +++ /dev/null @@ -1,1007 +0,0 @@ -# This file is part of Scapy -# See http://www.secdev.org/projects/scapy for more information -# Copyright (C) Philippe Biondi -# Copyright (C) Michael Farrell -# Copyright (C) Gauthier Sebaux -# This program is published under a GPLv2 license - -""" -Fields that hold random numbers. -""" - -from __future__ import absolute_import -import copy -import random -import time -import math -import re -import uuid -import struct - -from scapy.base_classes import Net -from scapy.compat import bytes_encode, chb, plain_str -from scapy.utils import corrupt_bits, corrupt_bytes -from scapy.modules.six.moves import range - -#################### -# Random numbers # -#################### - - -class RandomEnumeration: - """iterate through a sequence in random order. - When all the values have been drawn, if forever=1, the drawing is done again. # noqa: E501 - If renewkeys=0, the draw will be in the same order, guaranteeing that the same # noqa: E501 - number will be drawn in not less than the number of integers of the sequence""" # noqa: E501 - - def __init__(self, inf, sup, seed=None, forever=1, renewkeys=0): - self.forever = forever - self.renewkeys = renewkeys - self.inf = inf - self.rnd = random.Random(seed) - self.sbox_size = 256 - - self.top = sup - inf + 1 - - n = 0 - while (1 << n) < self.top: - n += 1 - self.n = n - - self.fs = min(3, (n + 1) // 2) - self.fsmask = 2**self.fs - 1 - self.rounds = max(self.n, 3) - self.turns = 0 - self.i = 0 - - def __iter__(self): - return self - - def next(self): - while True: - if self.turns == 0 or (self.i == 0 and self.renewkeys): - self.cnt_key = self.rnd.randint(0, 2**self.n - 1) - self.sbox = [self.rnd.randint(0, self.fsmask) - for _ in range(self.sbox_size)] - self.turns += 1 - while self.i < 2**self.n: - ct = self.i ^ self.cnt_key - self.i += 1 - for _ in range(self.rounds): # Unbalanced Feistel Network - lsb = ct & self.fsmask - ct >>= self.fs - lsb ^= self.sbox[ct % self.sbox_size] - ct |= lsb << (self.n - self.fs) - - if ct < self.top: - return self.inf + ct - self.i = 0 - if not self.forever: - raise StopIteration - __next__ = next - - -class VolatileValue(object): - def __repr__(self): - return "<%s>" % self.__class__.__name__ - - def __eq__(self, other): - x = self._fix() - y = other._fix() if isinstance(other, VolatileValue) else other - if not isinstance(x, type(y)): - return False - return x == y - - def __getattr__(self, attr): - if attr in ["__setstate__", "__getstate__"]: - raise AttributeError(attr) - return getattr(self._fix(), attr) - - def __str__(self): - return str(self._fix()) - - def __bytes__(self): - return bytes_encode(self._fix()) - - def __int__(self): - return int(self._fix()) - - def __len__(self): - return len(self._fix()) - - def copy(self): - return copy.copy(self) - - def _fix(self): - return None - - -class RandField(VolatileValue): - pass - - -class RandNum(RandField): - """Instances evaluate to random integers in selected range""" - min = 0 - max = 0 - - def __init__(self, min, max): - self.min = min - self.max = max - - def _fix(self): - return random.randrange(self.min, self.max + 1) - - def __int__(self): - return int(self._fix()) - - def __index__(self): - return int(self) - - def __nonzero__(self): - return bool(self._fix()) - __bool__ = __nonzero__ - - def __add__(self, other): - return self._fix() + other - - def __radd__(self, other): - return other + self._fix() - - def __sub__(self, other): - return self._fix() - other - - def __rsub__(self, other): - return other - self._fix() - - def __mul__(self, other): - return self._fix() * other - - def __rmul__(self, other): - return other * self._fix() - - def __floordiv__(self, other): - return self._fix() / other - __div__ = __floordiv__ - - def __lt__(self, other): - return self._fix() < other - - def __le__(self, other): - return self._fix() <= other - - def __eq__(self, other): - return self._fix() == other - - def __ne__(self, other): - return self._fix() != other - - def __ge__(self, other): - return self._fix() >= other - - def __gt__(self, other): - return self._fix() > other - - def __lshift__(self, other): - return self._fix() << other - - def __rshift__(self, other): - return self._fix() >> other - - def __and__(self, other): - return self._fix() & other - - def __rand__(self, other): - return other & self._fix() - - def __or__(self, other): - return self._fix() | other - - def __ror__(self, other): - return other | self._fix() - - -class RandFloat(RandNum): - def _fix(self): - return random.uniform(self.min, self.max) - - -class RandBinFloat(RandNum): - def _fix(self): - return struct.unpack("!f", bytes(RandBin(4)))[0] - - -class RandNumGamma(RandNum): - def __init__(self, alpha, beta): - self.alpha = alpha - self.beta = beta - - def _fix(self): - return int(round(random.gammavariate(self.alpha, self.beta))) - - -class RandNumGauss(RandNum): - def __init__(self, mu, sigma): - self.mu = mu - self.sigma = sigma - - def _fix(self): - return int(round(random.gauss(self.mu, self.sigma))) - - -class RandNumExpo(RandNum): - def __init__(self, lambd, base=0): - self.lambd = lambd - self.base = base - - def _fix(self): - return self.base + int(round(random.expovariate(self.lambd))) - - -class RandEnum(RandNum): - """Instances evaluate to integer sampling without replacement from the given interval""" # noqa: E501 - - def __init__(self, min, max, seed=None): - self.seq = RandomEnumeration(min, max, seed) - - def _fix(self): - return next(self.seq) - - -class RandByte(RandNum): - def __init__(self): - RandNum.__init__(self, 0, 2**8 - 1) - - -class RandSByte(RandNum): - def __init__(self): - RandNum.__init__(self, -2**7, 2**7 - 1) - - -class RandShort(RandNum): - def __init__(self): - RandNum.__init__(self, 0, 2**16 - 1) - - -class RandSShort(RandNum): - def __init__(self): - RandNum.__init__(self, -2**15, 2**15 - 1) - - -class RandInt(RandNum): - def __init__(self): - RandNum.__init__(self, 0, 2**32 - 1) - - -class RandSInt(RandNum): - def __init__(self): - RandNum.__init__(self, -2**31, 2**31 - 1) - - -class RandLong(RandNum): - def __init__(self): - RandNum.__init__(self, 0, 2**64 - 1) - - -class RandSLong(RandNum): - def __init__(self): - RandNum.__init__(self, -2**63, 2**63 - 1) - - -class RandEnumByte(RandEnum): - def __init__(self): - RandEnum.__init__(self, 0, 2**8 - 1) - - -class RandEnumSByte(RandEnum): - def __init__(self): - RandEnum.__init__(self, -2**7, 2**7 - 1) - - -class RandEnumShort(RandEnum): - def __init__(self): - RandEnum.__init__(self, 0, 2**16 - 1) - - -class RandEnumSShort(RandEnum): - def __init__(self): - RandEnum.__init__(self, -2**15, 2**15 - 1) - - -class RandEnumInt(RandEnum): - def __init__(self): - RandEnum.__init__(self, 0, 2**32 - 1) - - -class RandEnumSInt(RandEnum): - def __init__(self): - RandEnum.__init__(self, -2**31, 2**31 - 1) - - -class RandEnumLong(RandEnum): - def __init__(self): - RandEnum.__init__(self, 0, 2**64 - 1) - - -class RandEnumSLong(RandEnum): - def __init__(self): - RandEnum.__init__(self, -2**63, 2**63 - 1) - - -class RandEnumKeys(RandEnum): - """Picks a random value from dict keys list. """ - - def __init__(self, enum, seed=None): - self.enum = list(enum) - self.seq = RandomEnumeration(0, len(self.enum) - 1, seed) - - def _fix(self): - return self.enum[next(self.seq)] - - -class RandChoice(RandField): - def __init__(self, *args): - if not args: - raise TypeError("RandChoice needs at least one choice") - self._choice = args - - def _fix(self): - return random.choice(self._choice) - - -class RandString(RandField): - def __init__(self, size=None, chars=b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"): # noqa: E501 - if size is None: - size = RandNumExpo(0.01) - self.size = size - self.chars = chars - - def _fix(self): - s = b"" - for _ in range(self.size): - rdm_chr = random.choice(self.chars) - s += rdm_chr if isinstance(rdm_chr, str) else chb(rdm_chr) - return s - - def __str__(self): - return plain_str(self._fix()) - - def __bytes__(self): - return bytes_encode(self._fix()) - - def __mul__(self, n): - return self._fix() * n - - -class RandBin(RandString): - def __init__(self, size=None): - super(RandBin, self).__init__(size=size, chars=b"".join(chb(c) for c in range(256))) # noqa: E501 - - -class RandTermString(RandBin): - def __init__(self, size, term): - self.term = bytes_encode(term) - super(RandTermString, self).__init__(size=size) - - def _fix(self): - return RandBin._fix(self) + self.term - - -class RandIP(RandString): - def __init__(self, iptemplate="0.0.0.0/0"): - self.ip = Net(iptemplate) - - def _fix(self): - return self.ip.choice() - - -class RandMAC(RandString): - def __init__(self, template="*"): - template += ":*:*:*:*:*" - template = template.split(":") - self.mac = () - for i in range(6): - if template[i] == "*": - v = RandByte() - elif "-" in template[i]: - x, y = template[i].split("-") - v = RandNum(int(x, 16), int(y, 16)) - else: - v = int(template[i], 16) - self.mac += (v,) - - def _fix(self): - return "%02x:%02x:%02x:%02x:%02x:%02x" % self.mac - - -class RandIP6(RandString): - def __init__(self, ip6template="**"): - self.tmpl = ip6template - self.sp = self.tmpl.split(":") - for i, v in enumerate(self.sp): - if not v or v == "**": - continue - if "-" in v: - a, b = v.split("-") - elif v == "*": - a = b = "" - else: - a = b = v - - if not a: - a = "0" - if not b: - b = "ffff" - if a == b: - self.sp[i] = int(a, 16) - else: - self.sp[i] = RandNum(int(a, 16), int(b, 16)) - self.variable = "" in self.sp - self.multi = self.sp.count("**") - - def _fix(self): - nbm = self.multi - ip = [] - for i, n in enumerate(self.sp): - if n == "**": - nbm -= 1 - remain = 8 - (len(self.sp) - i - 1) - len(ip) + nbm - if "" in self.sp: - remain += 1 - if nbm or self.variable: - remain = random.randint(0, remain) - for j in range(remain): - ip.append("%04x" % random.randint(0, 65535)) - elif isinstance(n, RandNum): - ip.append("%04x" % n) - elif n == 0: - ip.append("0") - elif not n: - ip.append("") - else: - ip.append("%04x" % n) - if len(ip) == 9: - ip.remove("") - if ip[-1] == "": - ip[-1] = "0" - return ":".join(ip) - - -class RandOID(RandString): - def __init__(self, fmt=None, depth=RandNumExpo(0.1), idnum=RandNumExpo(0.01)): # noqa: E501 - self.ori_fmt = fmt - if fmt is not None: - fmt = fmt.split(".") - for i in range(len(fmt)): - if "-" in fmt[i]: - fmt[i] = tuple(map(int, fmt[i].split("-"))) - self.fmt = fmt - self.depth = depth - self.idnum = idnum - - def __repr__(self): - if self.ori_fmt is None: - return "<%s>" % self.__class__.__name__ - else: - return "<%s [%s]>" % (self.__class__.__name__, self.ori_fmt) - - def _fix(self): - if self.fmt is None: - return ".".join(str(self.idnum) for _ in range(1 + self.depth)) - else: - oid = [] - for i in self.fmt: - if i == "*": - oid.append(str(self.idnum)) - elif i == "**": - oid += [str(self.idnum) for i in range(1 + self.depth)] - elif isinstance(i, tuple): - oid.append(str(random.randrange(*i))) - else: - oid.append(i) - return ".".join(oid) - - -class RandRegExp(RandField): - def __init__(self, regexp, lambda_=0.3,): - self._regexp = regexp - self._lambda = lambda_ - - @staticmethod - def choice_expand(s): # XXX does not support special sets like (ex ':alnum:') # noqa: E501 - m = "" - invert = s and s[0] == "^" - while True: - p = s.find("-") - if p < 0: - break - if p == 0 or p == len(s) - 1: - m = "-" - if p: - s = s[:-1] - else: - s = s[1:] - else: - c1 = s[p - 1] - c2 = s[p + 1] - rng = "".join(map(chr, range(ord(c1), ord(c2) + 1))) - s = s[:p - 1] + rng + s[p + 1:] - res = m + s - if invert: - res = "".join(chr(x) for x in range(256) if chr(x) not in res) - return res - - @staticmethod - def stack_fix(lst, index): - r = "" - mul = 1 - for e in lst: - if isinstance(e, list): - if mul != 1: - mul = mul - 1 - r += RandRegExp.stack_fix(e[1:] * mul, index) - # only the last iteration should be kept for back reference - f = RandRegExp.stack_fix(e[1:], index) - for i, idx in enumerate(index): - if e is idx: - index[i] = f - r += f - mul = 1 - elif isinstance(e, tuple): - kind, val = e - if kind == "cite": - r += index[val - 1] - elif kind == "repeat": - mul = val - - elif kind == "choice": - if mul == 1: - c = random.choice(val) - r += RandRegExp.stack_fix(c[1:], index) - else: - r += RandRegExp.stack_fix([e] * mul, index) - mul = 1 - else: - if mul != 1: - r += RandRegExp.stack_fix([e] * mul, index) - mul = 1 - else: - r += str(e) - return r - - def _fix(self): - stack = [None] - index = [] - current = stack - i = 0 - ln = len(self._regexp) - interp = True - while i < ln: - c = self._regexp[i] - i += 1 - - if c == '(': - current = [current] - current[0].append(current) - elif c == '|': - p = current[0] - ch = p[-1] - if not isinstance(ch, tuple): - ch = ("choice", [current]) - p[-1] = ch - else: - ch[1].append(current) - current = [p] - elif c == ')': - ch = current[0][-1] - if isinstance(ch, tuple): - ch[1].append(current) - index.append(current) - current = current[0] - elif c == '[' or c == '{': - current = [current] - current[0].append(current) - interp = False - elif c == ']': - current = current[0] - choice = RandRegExp.choice_expand("".join(current.pop()[1:])) - current.append(RandChoice(*list(choice))) - interp = True - elif c == '}': - current = current[0] - num = "".join(current.pop()[1:]) - e = current.pop() - if "," not in num: - n = int(num) - current.append([current] + [e] * n) - else: - num_min, num_max = num.split(",") - if not num_min: - num_min = "0" - if num_max: - n = RandNum(int(num_min), int(num_max)) - else: - n = RandNumExpo(self._lambda, base=int(num_min)) - current.append(("repeat", n)) - current.append(e) - interp = True - elif c == '\\': - c = self._regexp[i] - if c == "s": - c = RandChoice(" ", "\t") - elif c in "0123456789": - c = ("cite", ord(c) - 0x30) - current.append(c) - i += 1 - elif not interp: - current.append(c) - elif c == '+': - e = current.pop() - current.append([current] + [e] * (int(random.expovariate(self._lambda)) + 1)) # noqa: E501 - elif c == '*': - e = current.pop() - current.append([current] + [e] * int(random.expovariate(self._lambda))) # noqa: E501 - elif c == '?': - if random.randint(0, 1): - current.pop() - elif c == '.': - current.append(RandChoice(*[chr(x) for x in range(256)])) - elif c == '$' or c == '^': - pass - else: - current.append(c) - - return RandRegExp.stack_fix(stack[1:], index) - - def __repr__(self): - return "<%s [%r]>" % (self.__class__.__name__, self._regexp) - - -class RandSingularity(RandChoice): - pass - - -class RandSingNum(RandSingularity): - @staticmethod - def make_power_of_two(end): - sign = 1 - if end == 0: - end = 1 - if end < 0: - end = -end - sign = -1 - end_n = int(math.log(end) / math.log(2)) + 1 - return {sign * 2**i for i in range(end_n)} - - def __init__(self, mn, mx): - sing = {0, mn, mx, int((mn + mx) / 2)} - sing |= self.make_power_of_two(mn) - sing |= self.make_power_of_two(mx) - for i in sing.copy(): - sing.add(i + 1) - sing.add(i - 1) - for i in sing.copy(): - if not mn <= i <= mx: - sing.remove(i) - self._choice = list(sing) - self._choice.sort() - - -class RandSingByte(RandSingNum): - def __init__(self): - RandSingNum.__init__(self, 0, 2**8 - 1) - - -class RandSingSByte(RandSingNum): - def __init__(self): - RandSingNum.__init__(self, -2**7, 2**7 - 1) - - -class RandSingShort(RandSingNum): - def __init__(self): - RandSingNum.__init__(self, 0, 2**16 - 1) - - -class RandSingSShort(RandSingNum): - def __init__(self): - RandSingNum.__init__(self, -2**15, 2**15 - 1) - - -class RandSingInt(RandSingNum): - def __init__(self): - RandSingNum.__init__(self, 0, 2**32 - 1) - - -class RandSingSInt(RandSingNum): - def __init__(self): - RandSingNum.__init__(self, -2**31, 2**31 - 1) - - -class RandSingLong(RandSingNum): - def __init__(self): - RandSingNum.__init__(self, 0, 2**64 - 1) - - -class RandSingSLong(RandSingNum): - def __init__(self): - RandSingNum.__init__(self, -2**63, 2**63 - 1) - - -class RandSingString(RandSingularity): - def __init__(self): - self._choice = ["", - "%x", - "%%", - "%s", - "%i", - "%n", - "%x%x%x%x%x%x%x%x%x", - "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", - "%", - "%%%", - "A" * 4096, - b"\x00" * 4096, - b"\xff" * 4096, - b"\x7f" * 4096, - b"\x80" * 4096, - " " * 4096, - "\\" * 4096, - "(" * 4096, - "../" * 1024, - "/" * 1024, - "${HOME}" * 512, - " or 1=1 --", - "' or 1=1 --", - '" or 1=1 --', - " or 1=1; #", - "' or 1=1; #", - '" or 1=1; #', - ";reboot;", - "$(reboot)", - "`reboot`", - "index.php%00", - b"\x00", - "%00", - "\\", - "../../../../../../../../../../../../../../../../../etc/passwd", # noqa: E501 - "%2e%2e%2f" * 20 + "etc/passwd", - "%252e%252e%252f" * 20 + "boot.ini", - "..%c0%af" * 20 + "etc/passwd", - "..%c0%af" * 20 + "boot.ini", - "//etc/passwd", - r"..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\boot.ini", # noqa: E501 - "AUX:", - "CLOCK$", - "COM:", - "CON:", - "LPT:", - "LST:", - "NUL:", - "CON:", - r"C:\CON\CON", - r"C:\boot.ini", - r"\\myserver\share", - "foo.exe:", - "foo.exe\\", ] - - def __str__(self): - return str(self._fix()) - - def __bytes__(self): - return bytes_encode(self._fix()) - - -class RandPool(RandField): - def __init__(self, *args): - """Each parameter is a volatile object or a couple (volatile object, weight)""" # noqa: E501 - pool = [] - for p in args: - w = 1 - if isinstance(p, tuple): - p, w = p - pool += [p] * w - self._pool = pool - - def _fix(self): - r = random.choice(self._pool) - return r._fix() - - -class RandUUID(RandField): - """Generates a random UUID. - - By default, this generates a RFC 4122 version 4 UUID (totally random). - - See Python's ``uuid`` module documentation for more information. - - Args: - template (optional): A template to build the UUID from. Not valid with - any other option. - node (optional): A 48-bit Host ID. Only valid for version 1 (where it - is optional). - clock_seq (optional): An integer of up to 14-bits for the sequence - number. Only valid for version 1 (where it is - optional). - namespace: A namespace identifier, which is also a UUID. Required for - versions 3 and 5, must be omitted otherwise. - name: string, required for versions 3 and 5, must be omitted otherwise. - version: Version of UUID to use (1, 3, 4 or 5). If omitted, attempts to - guess which version to generate, defaulting to version 4 - (totally random). - - Raises: - ValueError: on invalid constructor arguments - """ - # This was originally scapy.contrib.dce_rpc.RandUUID. - - _BASE = "([0-9a-f]{{{0}}}|\\*|[0-9a-f]{{{0}}}:[0-9a-f]{{{0}}})" - _REG = re.compile( - r"^{0}-?{1}-?{1}-?{2}{2}-?{2}{2}{2}{2}{2}{2}$".format( - _BASE.format(8), _BASE.format(4), _BASE.format(2) - ), - re.I - ) - VERSIONS = [1, 3, 4, 5] - - def __init__(self, template=None, node=None, clock_seq=None, - namespace=None, name=None, version=None): - self.uuid_template = None - self.node = None - self.clock_seq = None - self.namespace = None - self.node = None - self.version = None - - if template: - if node or clock_seq or namespace or name or version: - raise ValueError("UUID template must be the only parameter, " - "if specified") - tmp = RandUUID._REG.match(template) - if tmp: - template = tmp.groups() - else: - # Invalid template - raise ValueError("UUID template is invalid") - - rnd_f = [RandInt] + [RandShort] * 2 + [RandByte] * 8 - uuid_template = [] - for i, t in enumerate(template): - if t == "*": - val = rnd_f[i]() - elif ":" in t: - mini, maxi = t.split(":") - val = RandNum(int(mini, 16), int(maxi, 16)) - else: - val = int(t, 16) - uuid_template.append(val) - - self.uuid_template = tuple(uuid_template) - else: - if version: - if version not in RandUUID.VERSIONS: - raise ValueError("version is not supported") - else: - self.version = version - else: - # No version specified, try to guess... - # This could be wrong, and cause an error later! - if node or clock_seq: - self.version = 1 - elif namespace and name: - self.version = 5 - else: - # Don't know, random! - self.version = 4 - - # We have a version, now do things... - if self.version == 1: - if namespace or name: - raise ValueError("namespace and name may not be used with " - "version 1") - self.node = node - self.clock_seq = clock_seq - elif self.version in (3, 5): - if node or clock_seq: - raise ValueError("node and clock_seq may not be used with " - "version {}".format(self.version)) - - self.namespace = namespace - self.name = name - elif self.version == 4: - if namespace or name or node or clock_seq: - raise ValueError("node, clock_seq, node and clock_seq may " - "not be used with version 4. If you " - "did not specify version, you need to " - "specify it explicitly.") - - def _fix(self): - if self.uuid_template: - return uuid.UUID(("%08x%04x%04x" + ("%02x" * 8)) - % self.uuid_template) - elif self.version == 1: - return uuid.uuid1(self.node, self.clock_seq) - elif self.version == 3: - return uuid.uuid3(self.namespace, self.name) - elif self.version == 4: - return uuid.uuid4() - elif self.version == 5: - return uuid.uuid5(self.namespace, self.name) - else: - raise ValueError("Unhandled version") - - -# Automatic timestamp - - -class AutoTime(VolatileValue): - def __init__(self, base=None): - if base is None: - self.diff = 0 - else: - self.diff = time.time() - base - - def _fix(self): - return time.time() - self.diff - - -class IntAutoTime(AutoTime): - def _fix(self): - return int(time.time() - self.diff) - - -class ZuluTime(AutoTime): - def __init__(self, diff=0): - self.diff = diff - - def _fix(self): - return time.strftime("%y%m%d%H%M%SZ", - time.gmtime(time.time() + self.diff)) - - -class GeneralizedTime(AutoTime): - def __init__(self, diff=0): - self.diff = diff - - def _fix(self): - return time.strftime("%Y%m%d%H%M%SZ", - time.gmtime(time.time() + self.diff)) - - -class DelayedEval(VolatileValue): - """ Example of usage: DelayedEval("time.time()") """ - - def __init__(self, expr): - self.expr = expr - - def _fix(self): - return eval(self.expr) - - -class IncrementalValue(VolatileValue): - def __init__(self, start=0, step=1, restart=-1): - self.start = self.val = start - self.step = step - self.restart = restart - - def _fix(self): - v = self.val - if self.val == self.restart: - self.val = self.start - else: - self.val += self.step - return v - - -class CorruptedBytes(VolatileValue): - def __init__(self, s, p=0.01, n=None): - self.s = s - self.p = p - self.n = n - - def _fix(self): - return corrupt_bytes(self.s, self.p, self.n) - - -class CorruptedBits(CorruptedBytes): - def _fix(self): - return corrupt_bits(self.s, self.p, self.n)