diff options
93 files changed, 10738 insertions, 12 deletions
diff --git a/scripts/automation/__init__.py b/scripts/automation/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/scripts/automation/__init__.py diff --git a/scripts/automation/trex_control_plane/client/trex_client.py b/scripts/automation/trex_control_plane/client/trex_client.py index 0fbb4719..56775766 100755 --- a/scripts/automation/trex_control_plane/client/trex_client.py +++ b/scripts/automation/trex_control_plane/client/trex_client.py @@ -1062,5 +1062,3 @@ class CTRexResult(object): if __name__ == "__main__": pass - - diff --git a/scripts/automation/trex_control_plane/client/trex_hltapi.py b/scripts/automation/trex_control_plane/client/trex_hltapi.py new file mode 100644 index 00000000..46c283f8 --- /dev/null +++ b/scripts/automation/trex_control_plane/client/trex_hltapi.py @@ -0,0 +1,18 @@ +#!/router/bin/python + +import trex_root_path +from client_utils.packet_builder import CTRexPktBuilder + +print "done!" + +class CTRexHltApi(object): + + def __init__(self): + pass + + def config_traffic(self): + pass + +if __name__ == "__main__": + pass + diff --git a/scripts/automation/trex_control_plane/client/trex_root_path.py b/scripts/automation/trex_control_plane/client/trex_root_path.py new file mode 100644 index 00000000..de4ec03b --- /dev/null +++ b/scripts/automation/trex_control_plane/client/trex_root_path.py @@ -0,0 +1,15 @@ +#!/router/bin/python + +import os +import sys + +def add_root_to_path (): + """adds trex_control_plane root dir to script path, up to `depth` parent dirs""" + root_dirname = 'trex_control_plane' + file_path = os.path.dirname(os.path.realpath(__file__)) + + components = file_path.split(os.sep) + sys.path.append( str.join(os.sep, components[:components.index(root_dirname)+1]) ) + return + +add_root_to_path() diff --git a/scripts/automation/trex_control_plane/client/trex_stateless_client.py b/scripts/automation/trex_control_plane/client/trex_stateless_client.py new file mode 100644 index 00000000..5513f420 --- /dev/null +++ b/scripts/automation/trex_control_plane/client/trex_stateless_client.py @@ -0,0 +1,51 @@ +#!/router/bin/python + +try: + # support import for Python 2 + import outer_packages +except ImportError: + # support import for Python 3 + import client.outer_packages +from client_utils.jsonrpc_client import JsonRpcClient + + + +class CTRexStatelessClient(object): + """docstring for CTRexStatelessClient""" + def __init__(self, server="localhost", port=5050, virtual=False): + super(CTRexStatelessClient, self).__init__() + self.tx_link = CTRexStatelessClient.CTxLink(server, port, virtual) + + + def transmit(self, method_name, params = {}): + return self.tx_link.transmit(method_name, params) + + + + class CTxLink(object): + """describes the connectivity of the stateless client method""" + def __init__(self, server="localhost", port=5050, virtual=False): + super(CTRexStatelessClient.CTxLink, self).__init__() + self.virtual = virtual + self.server = server + self.port = port + self.rpc_link = JsonRpcClient(self.server, self.port) + if not self.virtual: + self.rpc_link.connect() + + def transmit(self, method_name, params = {}): + if self.virtual: + print "Transmitting virtually over tcp://{server}:{port}".format( + server=self.server, + port=self.port) + id, msg = self.rpc_link.create_jsonrpc_v2(method_name, params) + print msg + return + else: + return self.rpc_link.invoke_rpc_method(method_name, params) + + + + +if __name__ == "__main__": + pass diff --git a/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py b/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py index aff6b36e..c6b22218 100644 --- a/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py +++ b/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py @@ -63,16 +63,16 @@ class JsonRpcClient(object): print "[verbose] " + msg - def create_jsonrpc_v2 (self, method_name, params = {}, id = None): + def create_jsonrpc_v2 (self, method_name, params = {}): msg = {} msg["jsonrpc"] = "2.0" msg["method"] = method_name msg["params"] = params - msg["id"] = id + msg["id"] = self.id_gen.next() - return json.dumps(msg) + return id, json.dumps(msg) def invoke_rpc_method (self, method_name, params = {}, block = False): rc, msg = self._invoke_rpc_method(method_name, params, block) @@ -85,8 +85,7 @@ class JsonRpcClient(object): if not self.connected: return False, "Not connected to server" - id = self.id_gen.next() - msg = self.create_jsonrpc_v2(method_name, params, id = id) + id, msg = self.create_jsonrpc_v2(method_name, params) self.verbose_msg("Sending Request To Server:\n\n" + self.pretty_json(msg) + "\n") @@ -209,7 +208,8 @@ class JsonRpcClient(object): def __del__(self): print "Shutting down RPC client\n" - self.context.destroy(linger=0) + if hasattr(self, "context"): + self.context.destroy(linger=0) if __name__ == "__main__": pass diff --git a/scripts/automation/trex_control_plane/client_utils/outer_packages.py b/scripts/automation/trex_control_plane/client_utils/outer_packages.py index c489fd3d..a6c9a2eb 100644 --- a/scripts/automation/trex_control_plane/client_utils/outer_packages.py +++ b/scripts/automation/trex_control_plane/client_utils/outer_packages.py @@ -8,7 +8,9 @@ CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) ROOT_PATH = os.path.abspath(os.path.join(CURRENT_PATH, os.pardir)) # path to trex_control_plane directory PATH_TO_PYTHON_LIB = os.path.abspath(os.path.join(ROOT_PATH, os.pardir, os.pardir, 'external_libs')) -CLIENT_UTILS_MODULES = ['zmq'] +CLIENT_UTILS_MODULES = ['zmq', + 'dpkt-1.8.6' + ] def import_client_utils_modules(): diff --git a/scripts/automation/trex_control_plane/client_utils/packet_builder.py b/scripts/automation/trex_control_plane/client_utils/packet_builder.py new file mode 100644 index 00000000..fc34d931 --- /dev/null +++ b/scripts/automation/trex_control_plane/client_utils/packet_builder.py @@ -0,0 +1,720 @@ +#!/router/bin/python + + +import outer_packages +import dpkt +import socket +import binascii +import copy +import random +import string +import struct +import re + + +class CTRexPktBuilder(object): + """ + This class defines the TRex API of building a packet using dpkt package. + Using this class the user can also define how TRex will handle the packet by specifying the VM setting. + """ + def __init__(self, max_pkt_size=dpkt.ethernet.ETH_LEN_MAX): + """ + Instantiate a CTRexPktBuilder object + + :parameters: + None + + """ + super(CTRexPktBuilder, self).__init__() + self._packet = None + self._pkt_by_hdr = {} + self._pkt_top_layer = None + self._max_pkt_size = max_pkt_size + self.payload_generator = CTRexPktBuilder.CTRexPayloadGen(self._packet, self._max_pkt_size) + self.vm = CTRexPktBuilder.CTRexVM() + + def add_pkt_layer(self, layer_name, pkt_layer): + """ + This method adds additional header to the already existing packet + + :parameters: + layer_name: str + a string representing the name of the layer. + Example: "l2", "l4_tcp", etc. + + pkt_layer : dpkt.Packet obj + a dpkt object, generally from higher layer, that will be added on top of existing layer. + + :raises: + + :exc:`ValueError`, in case the desired layer_name already exists. + + """ + assert isinstance(pkt_layer, dpkt.Packet) + if layer_name in self._pkt_by_hdr: + raise ValueError("Given layer name '{0}' already exists.".format(layer_name)) + else: + dup_pkt = copy.copy(pkt_layer) # using copy of layer to avoid cyclic packets that may lead to infinite loop + if not self._pkt_top_layer: # this is the first header added + self._packet = dup_pkt + else: + self._pkt_top_layer.data = dup_pkt + self._pkt_top_layer = dup_pkt + self._pkt_by_hdr[layer_name] = dup_pkt + return + + def set_ip_layer_addr(self, layer_name, attr, ip_addr, ip_type="ipv4"): + try: + layer = self._pkt_by_hdr[layer_name.lower()] + if not (isinstance(layer, dpkt.ip.IP) or isinstance(layer, dpkt.ip6.IP6)): + raise ValueError("The specified layer '{0}' is not of IPv4/IPv6 type.".format(layer_name)) + else: + decoded_ip = CTRexPktBuilder._decode_ip_addr(ip_addr, ip_type) + setattr(layer, attr, decoded_ip) + except KeyError: + raise KeyError("Specified layer '{0}' doesn't exist on packet.".format(layer_name)) + + def set_ipv6_layer_addr(self, layer_name, attr, ip_addr): + self.set_ip_layer_addr(layer_name, attr, ip_addr, ip_type="ipv6") + + def set_eth_layer_addr(self, layer_name, attr, mac_addr): + try: + layer = self._pkt_by_hdr[layer_name.lower()] + if not isinstance(layer, dpkt.ethernet.Ethernet): + raise ValueError("The specified layer '{0}' is not of Ethernet type.".format(layer_name)) + else: + decoded_mac = CTRexPktBuilder._decode_mac_addr(mac_addr) + setattr(layer, attr, decoded_mac) + except KeyError: + raise KeyError("Specified layer '{0}' doesn't exist on packet.".format(layer_name)) + + def set_layer_attr(self, layer_name, attr, val, toggle_bit=False): + """ + This method enables the user to change a value of a previously defined packet layer. + This method isn't to be used to set the data attribute of a packet with payload. + Use :func:`packet_builder.CTRexPktBuilder.set_payload` instead. + + :parameters: + layer_name: str + a string representing the name of the layer. + Example: "l2", "l4_tcp", etc. + + attr : str + a string representing the attribute to be changed on desired layer + + val : + value of attribute. + + toggle_bit : bool + Indicating if trying to set a specific bit of a field, such as "do not fragment" bit of IP layer. + + Default: **False** + + :raises: + + :exc:`KeyError`, in case of missing layer (the desired layer isn't part of packet) + + :exc:`ValueError`, in case invalid attribute to the specified layer. + + """ + try: + layer = self._pkt_by_hdr[layer_name.lower()] + if attr == 'data' and not isinstance(val, dpkt.Packet): + # Don't allow setting 'data' attribute + raise ValueError("Set a data attribute with object that is not dpkt.Packet is not allowed using " + "set_layer_attr method.\nUse set_payload method instead.") + if hasattr(layer, attr): + if toggle_bit: + setattr(layer, attr, val | getattr(layer, attr, 0)) + else: + setattr(layer, attr, val) + if attr == 'data': + # re-evaluate packet from the start, possible broken link between layers + self._reevaluate_packet(layer_name.lower()) + else: + raise ValueError("Given attr name '{0}' doesn't exists on specified layer ({1}).".format(layer_name, + attr)) + except KeyError: + raise KeyError("Specified layer '{0}' doesn't exist on packet.".format(layer_name)) + + def set_layer_bit_attr(self, layer_name, attr, val): + return self.set_layer_attr(layer_name, attr, val, True) + + def set_pkt_payload(self, payload): + """ + This method sets a payload to the topmost layer of the generated packet. + This method isn't to be used to set another networking layer to the packet. + Use :func:`packet_builder.CTRexPktBuilder.set_layer_attr` instead. + + + :parameters: + payload: + a payload to be added to the packet at the topmost layer. + this object cannot be of type dpkt.Packet. + + :raises: + + :exc:`AttributeError`, in case no underlying header to host the payload. + + """ + assert isinstance(payload, str) + try: + self._pkt_top_layer.data = payload + except AttributeError: + raise AttributeError("The so far built packet doesn't contain an option for payload attachment.\n" + "Make sure to set appropriate underlying header before adding payload") + + def load_packet(self, packet): + """ + This method enables the user to change a value of a previously defined packet layer. + + :parameters: + packet: dpkt.Packet obj + a dpkt object that represents a packet. + + + :raises: + + :exc:`CTRexPktBuilder.IPAddressError`, in case invalid ip type option specified. + + """ + assert isinstance(packet, dpkt.Packet) + self._packet = copy.copy(packet) + + self._pkt_by_hdr.clear() + self._pkt_top_layer = self._packet + # analyze packet to layers + tmp_layer = self._packet + while True: + if isinstance(tmp_layer, dpkt.Packet): + layer_name = self._gen_layer_name(type(tmp_layer).__name__) + self._pkt_by_hdr[layer_name] = tmp_layer + self._pkt_top_layer = tmp_layer + try: + # check existence of upper layer + tmp_layer = tmp_layer.data + except AttributeError: + # this is the most upper header + self._pkt_by_hdr['pkt_final_payload'] = tmp_layer.data + break + else: + self._pkt_by_hdr['pkt_final_payload'] = tmp_layer + break + return + + def get_packet(self, get_ptr=False): + """ + This method provides access to the built packet, as an instance or as a pointer to packet itself. + + :parameters: + get_ptr : bool + indicate whether to get a reference to packet or a copy. + Use only in advanced modes + if set to true, metadata for packet is cleared, and any further modification is not guaranteed. + + default value : False + + :return: + + the current packet built by CTRexPktBuilder object. + + None if packet is empty + + """ + if get_ptr: + self._pkt_by_hdr = {} + self._pkt_top_layer = None + return self._packet + else: + return copy.copy(self._packet) + + def get_layer(self, layer_name): + """ + This method provides access to a specific layer of the packet, as a **copy of the layer instance**. + + :parameters: + layer_name : str + the name given to desired layer + + :return: + + a copy of the desired layer of the current packet if exists. + + None if no such layer + + """ + layer = self._pkt_by_hdr.get(layer_name) + return copy.copy(layer) if layer else None + + # VM access methods + def set_vm_ip_range(self, ip_start, ip_end, ip_type="ipv4"): + pass + + def set_vm_range_type(self, ip_type): + pass + + def set_vm_core_mask(self, ip_type): + pass + + def get_vm_data(self): + pass + + def dump_pkt(self): + """ + Dumps the packet as a decimal array of bytes (each item x gets value between 0-255) + + :parameters: + None + + :return: + + packet representation as array of bytes + + :raises: + + :exc:`CTRexPktBuilder.EmptyPacketError`, in case packet is empty. + + """ + if self._packet is None: + raise CTRexPktBuilder.EmptyPacketError() + pkt_in_hex = binascii.hexlify(str(self._packet)) + return [int(pkt_in_hex[i:i+2], 16) + for i in range(0, len(pkt_in_hex), 2)] + # return [pkt_in_hex[i:i+2] for i in range(0, len(pkt_in_hex), 2)] + + def dump_pkt_to_pcap(self, file_path, ts=None): + """ + Dumps the packet as a decimal array of bytes (each item x gets value between 0-255) + + :parameters: + file_path : str + a path (including filename) to which to write to pcap file to. + + ts : int + a timestamp to attach to the packet when dumped to pcap file. + if ts in None, then time.time() is used to set the timestamp. + + Default: **None** + + :return: + None + + :raises: + + :exc:`CTRexPktBuilder.EmptyPacketError`, in case packet is empty. + + """ + if self._packet is None: + raise CTRexPktBuilder.EmptyPacketError() + try: + with open(file_path, 'wb') as f: + pcap_wr = dpkt.pcap.Writer(f) + pcap_wr.writepkt(self._packet, ts) + return + except IOError: + raise IOError(2, "The provided path could not be accessed") + + + # ----- useful shortcut methods ----- # + def gen_dns_packet(self): + pass + + # ----- internal methods ----- # + def _reevaluate_packet(self, layer_name): + cur_layer = self._packet + known_layers = set(self._pkt_by_hdr.keys()) + found_layers = set() + while True: + pointing_layer_name = self._find_pointing_layer(known_layers, cur_layer) + found_layers.add(pointing_layer_name) + if self._pkt_by_hdr[layer_name] is cur_layer: + self._pkt_top_layer = cur_layer + disconnected_layers = known_layers.difference(found_layers) + # remove disconnected layers + for layer in disconnected_layers: + self._pkt_by_hdr.pop(layer) + break + else: + cur_layer = cur_layer.data + + def _gen_layer_name(self, layer_class_name): + assert isinstance(layer_class_name, str) + layer_name = layer_class_name.lower() + idx = 1 + while True: + tmp_name = "{name}_{id}".format(name=layer_name, id=idx) + if tmp_name not in self._pkt_by_hdr: + return tmp_name + else: + idx += 1 + + def _find_pointing_layer(self, known_layers, layer_obj): + assert isinstance(known_layers, set) + for layer in known_layers: + if self._pkt_by_hdr[layer] is layer_obj: + return layer + + @staticmethod + def _decode_mac_addr(mac_addr): + """ + Static method to test for MAC address validity. + + :parameters: + mac_addr : str + a string representing an MAC address, separated by ':' or '-'. + + examples: '00:de:34:ef:2e:f4', '00-de-34-ef-2e-f4 + + :return: + + an hex-string representation of the MAC address. + for example, ip 00:de:34:ef:2e:f4 will return '\x00\xdeU\xef.\xf4' + + :raises: + + :exc:`CTRexPktBuilder.MACAddressError`, in case invalid ip type option specified. + + """ + tmp_mac = mac_addr.lower().replace('-', ':') + if re.match("[0-9a-f]{2}([-:])[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", tmp_mac): + return binascii.unhexlify(tmp_mac.replace(':', '')) + # another option for both Python 2 and 3: + # codecs.decode(tmp_mac.replace(':', ''), 'hex') + else: + raise CTRexPktBuilder.MACAddressError() + + @staticmethod + def _decode_ip_addr(ip_addr, ip_type): + """ + Static method to test for IPv4/IPv6 address validity. + + :parameters: + ip_addr : str + a string representing an IP address (IPv4/IPv6) + + ip_type : str + The type of IP to be checked. + Valid types: "ipv4", "ipv6". + + :return: + + an hex-string representation of the ip address. + for example, ip 1.2.3.4 will return '\x01\x02\x03\x04' + + :raises: + + :exc:`CTRexPktBuilder.IPAddressError`, in case invalid ip type option specified. + + """ + if ip_type == "ipv4": + try: + return socket.inet_pton(socket.AF_INET, ip_addr) + except AttributeError: # no inet_pton here, sorry + # try: + return socket.inet_aton(ip_addr) + # except socket.error: + # return False + # return ip_addr.count('.') == 3 + except socket.error: # not a valid address + raise CTRexPktBuilder.IPAddressError() + elif ip_type == "ipv6": + try: + return socket.inet_pton(socket.AF_INET6, ip_addr) + except socket.error: # not a valid address + raise CTRexPktBuilder.IPAddressError() + else: + raise CTRexPktBuilder.IPAddressError() + + # ------ private classes ------ # + class CTRexPayloadGen(object): + + def __init__(self, packet_ref, max_pkt_size): + self._pkt_ref = packet_ref + self._max_pkt_size = max_pkt_size + + def gen_random_str(self): + gen_length = self._calc_gen_length() + # return a string of size gen_length bytes, to pad the packet to its max_size + return ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) + for _ in range(gen_length)) + + def gen_repeat_ptrn(self, ptrn_to_repeat): + gen_length = self._calc_gen_length() + if isinstance(ptrn_to_repeat, str): + # generate repeated string + return (ptrn_to_repeat * (gen_length/len(ptrn_to_repeat) + 1))[:gen_length] + elif isinstance(ptrn_to_repeat, int): + ptrn = binascii.unhexlify(hex(ptrn_to_repeat)[2:]) + return (ptrn * (gen_length/len(ptrn) + 1))[:gen_length] + elif isinstance(ptrn_to_repeat, tuple): + if not all((isinstance(x, int) and (x < 255) and (x >= 0)) + for x in ptrn_to_repeat): + raise ValueError("All numbers in tuple must be in range 0 <= number <= 255 ") + # generate repeated sequence + to_pack = (ptrn_to_repeat * (gen_length/len(ptrn_to_repeat) + 1))[:gen_length] + return struct.pack('B'*gen_length, *to_pack) + else: + raise ValueError("Given ptrn_to_repeat argument type ({0}) is illegal.". + format(type(ptrn_to_repeat))) + + def _calc_gen_length(self): + return self._max_pkt_size - len(self._pkt_ref) + + class CTRexVM(object): + """ + This class defines the TRex VM which represents how TRex will regenerate packets. + The packets will be regenerated based on the built packet containing this class. + """ + def __init__(self): + """ + Instantiate a CTRexVM object + + :parameters: + None + """ + super(CTRexPktBuilder.CTRexVM, self).__init__() + self.vm_variables = {} + + def set_vm_var_field(self, var_name, field_name, val): + """ + Set VM variable field. Only existing variables are allowed to be changed. + + :parameters: + var_name : str + a string representing the name of the VM variable to be changed. + field_name : str + a string representing the field name of the VM variable to be changed. + val : + a value to be applied to field_name field of the var_name VM variable. + + :raises: + + :exc:`KeyError`, in case invalid var_name has been specified. + + :exc:`CTRexPktBuilder.VMVarFieldTypeError`, in case mismatch between `val` and allowed type. + + :exc:`CTRexPktBuilder.VMVarValueError`, in case val isn't one of allowed options of field_name. + + """ + return self.vm_variables[var_name].set_field(field_name, val) + + def add_flow_man_simple(self, name, **kwargs): + """ + Adds a new flow manipulation object to the VM instance. + + :parameters: + name : str + name of the manipulation, must be distinct. + Example: 'source_ip_change' + + **kwargs : dict + optional, set flow_man fields on initialization (key = field_name, val = field_val). + Must be used with legit fields, see :func:`CTRexPktBuilder.CTRexVM.CTRexVMVariable.set_field`. + + :return: + None + + :raises: + + :exc:`CTRexPktBuilder.VMVarNameExistsError`, in case of desired flow_man name already taken. + + Exceptions from :func:`CTRexPktBuilder.CTRexVM.CTRexVMVariable.set_field` method. + Will rise when VM variables were misconfiguration. + """ + if name not in self.vm_variables.keys(): + self.vm_variables[name] = self.CTRexVMVariable(name) + # try configuring VM var attributes + for (field, value) in kwargs.items(): + self.vm_variables[name].set_field(field, value) + else: + raise CTRexPktBuilder.VMVarNameExistsError(name) + + def load_flow_man(self, flow_obj): + """ + Loads an outer VM variable (instruction) into current VM. + The outer VM variable must contain different name than existing VM variables currently registered on VM. + + :parameters: + flow_obj : CTRexVMVariable + a CTRexVMVariable to be loaded into VM variable sets. + + :return: + list holds variables data of VM + + """ + assert isinstance(flow_obj, CTRexPktBuilder.CTRexVM.CTRexVMVariable) + if flow_obj.name not in self.vm_variables.keys(): + self.vm_variables[flow_obj.name] = flow_obj + else: + raise CTRexPktBuilder.VMVarNameExistsError(flow_obj.name) + + def dump(self): + """ + dumps a VM variables (instructions) into an list data structure. + + :parameters: + None + + :return: + list holds variables data of VM + + """ + return [var.dump() + for key, var in self.vm_variables.items()] + + class CTRexVMVariable(object): + """ + This class defines a single VM variable to be used as part of CTRexVar object. + """ + VALID_SIZE = [1, 2, 4, 8] + VALID_OPERATION = ["inc", "dec", "random"] + + def __init__(self, name): + """ + Instantiate a CTRexVMVariable object + + :parameters: + name : str + a string representing the name of the VM variable. + """ + super(CTRexPktBuilder.CTRexVM.CTRexVMVariable, self).__init__() + self.name = name + self.size = 4 + self.big_endian = True + self.operation = "inc" + self.split_by_core = False + self.init_value = 1 + self.min_value = self.init_value + self.max_value = self.init_value + + def set_field(self, field_name, val): + """ + Set VM variable field. Only existing variables are allowed to be changed. + + :parameters: + field_name : str + a string representing the field name of the VM variable to be changed. + val : + a value to be applied to field_name field of the var_name VM variable. + + :return: + None + + :raises: + + :exc:`CTRexPktBuilder.VMVarNameError`, in case of illegal field name. + + :exc:`CTRexPktBuilder.VMVarFieldTypeError`, in case mismatch between `val` and allowed type. + + :exc:`CTRexPktBuilder.VMVarValueError`, in case val isn't one of allowed options of field_name. + + """ + if not hasattr(self, field_name): + raise CTRexPktBuilder.VMVarNameError(field_name) + elif field_name == "size": + if type(val) != int: + raise CTRexPktBuilder.VMVarFieldTypeError("size", int) + elif val not in self.VALID_SIZE: + raise CTRexPktBuilder.VMVarValueError("size", self.VALID_SIZE) + elif field_name == "init_value": + if type(val) != int: + raise CTRexPktBuilder.VMVarFieldTypeError("init_value", int) + elif field_name == "operation": + if type(val) != str: + raise CTRexPktBuilder.VMVarFieldTypeError("operation", str) + elif val not in self.VALID_OPERATION: + raise CTRexPktBuilder.VMVarValueError("operation", self.VALID_OPERATION) + elif field_name == "split_by_core": + val = bool(val) + # update field value on success + setattr(self, field_name, val) + + def is_valid(self): + if self.size not in self.VALID_SIZE: + return False + if self.type not in self.VALID_OPERATION: + return False + return True + + def dump(self): + """ + dumps a variable fields in a dictionary data structure. + + :parameters: + None + + :return: + dictionary holds variable data of VM variable + + """ + return {"ins_name": "flow_man_simple", # VM variable dump always refers to manipulate instruction. + "flow_variable_name": self.name, + "object_size": self.size, + # "big_endian": self.big_endian, + "Operation": self.operation, + "split_by_core": self.split_by_core, + "init_value": self.init_value, + "min_value": self.min_value, + "max_value": self.max_value} + + class CPacketBuildException(Exception): + """ + This is the general Packet Building error exception class. + """ + def __init__(self, code, message): + self.code = code + self.message = message + + def __str__(self): + return self.__repr__() + + def __repr__(self): + return u"[errcode:%r] %r" % (self.code, self.message) + + class EmptyPacketError(CPacketBuildException): + """ + This exception is used to indicate an error caused by operation performed on an empty packet. + """ + def __init__(self, message=''): + self._default_message = 'Illegal operation on empty packet.' + self.message = message or self._default_message + super(CTRexPktBuilder.EmptyPacketError, self).__init__(-10, self.message) + + class IPAddressError(CPacketBuildException): + """ + This exception is used to indicate an error on the IP addressing part of the packet. + """ + def __init__(self, message=''): + self._default_message = 'Illegal type or value of IP address has been provided.' + self.message = message or self._default_message + super(CTRexPktBuilder.IPAddressError, self).__init__(-11, self.message) + + class MACAddressError(CPacketBuildException): + """ + This exception is used to indicate an error on the MAC addressing part of the packet. + """ + def __init__(self, message=''): + self._default_message = 'Illegal MAC address has been provided.' + self.message = message or self._default_message + super(CTRexPktBuilder.MACAddressError, self).__init__(-11, self.message) + + class VMVarNameExistsError(CPacketBuildException): + """ + This exception is used to indicate a duplicate usage of VM variable. + """ + def __init__(self, name, message=''): + self._default_message = 'The given VM name ({0}) already exists as part of the stream.'.format(name) + self.message = message or self._default_message + super(CTRexPktBuilder.VMVarNameExistsError, self).__init__(-21, self.message) + + class VMVarNameError(CPacketBuildException): + """ + This exception is used to indicate that an undefined VM var field name has been accessed. + """ + def __init__(self, name, message=''): + self._default_message = "The given VM field name ({0}) is not defined and isn't legal.".format(name) + self.message = message or self._default_message + super(CTRexPktBuilder.VMVarNameError, self).__init__(-22, self.message) + + class VMVarFieldTypeError(CPacketBuildException): + """ + This exception is used to indicate an illegal value has type has been given to VM variable field. + """ + def __init__(self, name, ok_type, message=''): + self._default_message = 'The desired value of field {field_name} is of type {field_type}, \ + and not of the allowed {allowed_type}.'.format(field_name=name, + field_type=type(name).__name__, + allowed_type=ok_type.__name__) + self.message = message or self._default_message + super(CTRexPktBuilder.VMVarFieldTypeError, self).__init__(-31, self.message) + + class VMVarValueError(CPacketBuildException): + """ + This exception is used to indicate an error an illegal value has been assigned to VM variable field. + """ + def __init__(self, name, ok_opts, message=''): + self._default_message = 'The desired value of field {field_name} is illegal.\n \ + The only allowed options are: {allowed_opts}.'.format(field_name=name, + allowed_opts=ok_opts) + self.message = message or self._default_message + super(CTRexPktBuilder.VMVarValueError, self).__init__(-32, self.message) + + +if __name__ == "__main__": + pass diff --git a/scripts/automation/trex_control_plane/examples/client_interactive_example.py b/scripts/automation/trex_control_plane/examples/client_interactive_example.py index 10735221..05028463 100755 --- a/scripts/automation/trex_control_plane/examples/client_interactive_example.py +++ b/scripts/automation/trex_control_plane/examples/client_interactive_example.py @@ -13,7 +13,6 @@ import time import socket import errno - class InteractiveTRexClient(cmd.Cmd): intro = termstyle.green("\nInteractive shell to play with Cisco's T-Rex API.\nType help to view available pre-defined scenarios\n(c) All rights reserved.\n") diff --git a/scripts/automation/trex_control_plane/server/extended_daemon_runner.py b/scripts/automation/trex_control_plane/server/extended_daemon_runner.py index 2ce1eb06..1813ed48 100755 --- a/scripts/automation/trex_control_plane/server/extended_daemon_runner.py +++ b/scripts/automation/trex_control_plane/server/extended_daemon_runner.py @@ -35,7 +35,7 @@ class ExtendedDaemonRunner(runner.DaemonRunner): help_menu = """Specify action command to be applied on server.
(*) start : start the application in as a daemon process.
- (*) show : prompt a updated status of daemon process (running/ not running).
+ (*) show : prompt an updated status of daemon process (running/ not running).
(*) stop : exit the daemon process.
(*) restart : stop, then start again the application as daemon process
(*) start-live : start the application in live mode (no daemon process).
diff --git a/scripts/automation/trex_control_plane/server/trex_server.py b/scripts/automation/trex_control_plane/server/trex_server.py index 992a1d5f..35b2669a 100755 --- a/scripts/automation/trex_control_plane/server/trex_server.py +++ b/scripts/automation/trex_control_plane/server/trex_server.py @@ -53,7 +53,7 @@ class CTRexServer(object): the port number on which trex's zmq module will interact with daemon server default value: 4500 - Instatiate a T-Rex client object, and connecting it to listening daemon-server + Instantiate a T-Rex client object, and connecting it to listening daemon-server """ self.TREX_PATH = os.path.abspath(os.path.dirname(trex_path+'/')) self.trex_files_path = os.path.abspath(os.path.dirname(trex_files_path+'/')) diff --git a/scripts/external_libs/dpkt-1.8.6/AUTHORS b/scripts/external_libs/dpkt-1.8.6/AUTHORS new file mode 100644 index 00000000..dcefbef9 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/AUTHORS @@ -0,0 +1,60 @@ + +Original author +--------------- + +Dug Song <dugsong@monkey.org> + + +Contributors +------------ + +Timur Alperovich <timuralp@umich.edu> + radiotap module + +Nic Bellamy <nic.bellamy@vadacom.co.nz> + HTTP header parsing fix + +the grugq <thegrugq@gmail.com> + better RTP module + +David Helder <dhelder@gizmolabs.org> + bug fixes + +Przemyslaw Karwasiecki <karwas@gmail.com> + TABLE_DUMP in MRT module + +Reza Lotun <rlotun@cs.ubc.ca> + MetaPacket cleanup + +Jeff Nathan <jeff@snort.org> + bug fixes + +Tim Newsham <newsham@lava.net> + IPv6 bugfixing and improvements + +keisuke.nishimoto@gmail.com + Snoop file parser + +Jon Oberheide <jon@oberheide.org> + STUN, H.225, TPKT, NTP, RIP, Diameter, SCTP, BGP, MRT, RX modules + +plotnikoff@gmail.com + handle dynamic imports from py2exe/freeze.py/zipped egg packages + +simdream@gmail.com + handle multiple cookie values in HTTP + +Owen Stephens <owen@owenstephens.co.uk> + IP6 extension header support + +Robert Stone <otaku@monkey.org> + Netflow and QQ modules + +Thomas Taranowski <thomastaranowski@yahoo.com> + dnet IP checksum bug on i386 + +Jirka Vejrazka + bug fixes + +Tim Yardley <yardley@gmail.com> + DHCP definitions diff --git a/scripts/external_libs/dpkt-1.8.6/CHANGES b/scripts/external_libs/dpkt-1.8.6/CHANGES new file mode 100644 index 00000000..a5f05121 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/CHANGES @@ -0,0 +1,71 @@ +dpkg-1.8: + - fix a typo in vrrp.py + - fix IPv4 and IPv6 packet to correctly handle zero payload length + - store cipher_suite as int in TLSServerHello to allow app-specific messages + - improve SSL parsing + +dpkt-1.7: + - handle dynamic imports from py2exe/freeze.py/zipped egg + packages, from plotnikoff + - decode Ethernet MPLS labels, Cisco ISL VLAN tags, 802.2 LLC fields + - handle multiply-defined HTTP headers from simdream + - add IPv6 extension header support (minus ESP) from Owen Stephens + - add radiotap module from Timur Alperovich + - add IEEE80211 module from Jon Oberheide + - add RFB module from Jon Oberheide + - fix IP6 checksum to include options + - rename 'as' to 'asn' field in BGP header + - fix transport-layer checksum in IP6 + - handle improper TCP header offset + - fix SSL typo + - handle malformed ICMP headers + - added RX module from Jon Oberheide + - fixed loopback module IP/IP6 decoding + - set transport-layer (TCP, UDP) checksum in IP + - MRT module fixes + - fix pcap.Writer timestamp calculation + +dpkt-1.6: + - DNS RR packing fixed + - added STUN, H.225, TPKT, NTP, RIP, Diameter, SCTP, + BGP, and MRT modules from Jon Oberheide + - new dpkt.NeedData exception + +dpkt-1.5: + - IP6 checksum fix + - __getitem__() interface to Packet (e.g. ip['src'] == ip.src) + - faster Ethernet, IP, PPP module loading + - support any endianness capture file in pcap module, + and export a pypcap-compatible Reader + - additional CDP definitions + - replaced rtp module with the grugq's version + - added QQ module from Robert Stone + - added gzip module + - added PPPoE module + - added RADIUS module + +dpkt-1.4: + - fix IP checksum bug on i386, caught by Thomas Taranowski + +dpkt-1.3: + - autoload IP, Ethernet dispatch tables + - IP6 bugfixes from Tim Newsham + - additional DHCP definitions from Tim Yardley + - HTTP bugfixes and abstraction (see SIP) + - RPC bugfixes + - added pypcap-compatible PcapReader + - added Linux libpcap "cooked" capture module + - added preliminary SSL module + - added SIP module + - added SCCP module + - added RTP module + - added Portmap module + +dpkt-1.2: + - changed license from GPL to BSD + - added DTP module + - added HTTP module + - added DNS RR decodes + - added enough PPP to decode PPTP GRE encapsulation + +# $Id: CHANGES 379 2006-07-27 05:23:19Z dugsong $ diff --git a/scripts/external_libs/dpkt-1.8.6/LICENSE b/scripts/external_libs/dpkt-1.8.6/LICENSE new file mode 100644 index 00000000..99d14371 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/LICENSE @@ -0,0 +1,28 @@ + + Copyright (c) 2004 Dug Song <dugsong@monkey.org> + All rights reserved, all wrongs reversed. + + 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. The names of the authors and copyright holders may not be used to + endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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. + diff --git a/scripts/external_libs/dpkt-1.8.6/MANIFEST.in b/scripts/external_libs/dpkt-1.8.6/MANIFEST.in new file mode 100644 index 00000000..e96d54c1 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/MANIFEST.in @@ -0,0 +1,2 @@ + +include AUTHORS CHANGES README.rst LICENSE diff --git a/scripts/external_libs/dpkt-1.8.6/PKG-INFO b/scripts/external_libs/dpkt-1.8.6/PKG-INFO new file mode 100644 index 00000000..e82397e7 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/PKG-INFO @@ -0,0 +1,122 @@ +Metadata-Version: 1.1 +Name: dpkt +Version: 1.8.6 +Summary: fast, simple packet creation / parsing, with definitions for the basic TCP/IP protocols +Home-page: http://dpkt.googlecode.com/ +Author: Dug Song <dugsong@monkey.org> +Author-email: UNKNOWN +License: BSD +Description: + ==== + dpkt + ==== + + | |docs| |travis| |coveralls| |landscape| |version| + | |downloads| |wheel| |supported-versions| |supported-implementations| + + .. |docs| image:: https://readthedocs.org/projects/dpkt/badge/?style=flat + :target: https://readthedocs.org/projects/dpkt + :alt: Documentation Status + + .. |travis| image:: http://img.shields.io/travis/kbandla/dpkt/master.png?style=flat + :alt: Travis-CI Build Status + :target: https://travis-ci.org/kbandla/dpkt + + .. |coveralls| image:: http://img.shields.io/coveralls/kbandla/dpkt/master.png?style=flat + :alt: Coverage Status + :target: https://coveralls.io/r/kbandla/dpkt + + .. |landscape| image:: https://landscape.io/github/kbandla/dpkt/master/landscape.svg?style=flat + :target: https://landscape.io/github/kbandla/dpkt/master + :alt: Code Quality Status + + .. |version| image:: http://img.shields.io/pypi/v/dpkt.png?style=flat + :alt: PyPI Package latest release + :target: https://pypi.python.org/pypi/dpkt + + .. |downloads| image:: http://img.shields.io/pypi/dm/dpkt.png?style=flat + :alt: PyPI Package monthly downloads + :target: https://pypi.python.org/pypi/dpkt + + .. |wheel| image:: https://pypip.in/wheel/dpkt/badge.png?style=flat + :alt: PyPI Wheel + :target: https://pypi.python.org/pypi/dpkt + + .. |supported-versions| image:: https://pypip.in/py_versions/dpkt/badge.png?style=flat + :alt: Supported versions + :target: https://pypi.python.org/pypi/dpkt + + .. |supported-implementations| image:: https://pypip.in/implementation/dpkt/badge.png?style=flat + :alt: Supported implementations + :target: https://pypi.python.org/pypi/dpkt + + Installation + ============ + + :: + + pip install dpkt + + Documentation + ============= + + https://dpkt.readthedocs.org/ + + Development + =========== + + To run the all tests run:: + + tox + + + Deviations from upstream + ~~~~~~~~~~~~~~~~~~~~~~~~ + + This code is based on `dpkt code <https://code.google.com/p/dpkt/>`__ lead by Dug Song. + + At this point, this is not the exact `upstream + version <https://code.google.com/p/dpkt/>`__. If you are looking for the + latest stock dpkt, please get it from the above link. + + Almost all of the upstream changes are pulled. However, some modules are + not. Here is a list of the changes: + + - `dpkt/dpkt.py <https://github.com/kbandla/dpkt/commit/336fe02b0e2f00b382d91cd42558a69eec16d6c7>`__: + decouple dnet from dpkt + - `dpkt/dns.py <https://github.com/kbandla/dpkt/commit/2bf3cde213144391fd90488d12f9ccce51b5fbca>`__ + : parse some more DNS flags + + Examples + -------- + + [@jonoberheide's](https://twitter.com/jonoberheide) old examples still + apply: + + - `dpkt Tutorial #1: ICMP + Echo <https://jon.oberheide.org/blog/2008/08/25/dpkt-tutorial-1-icmp-echo/>`__ + - `dpkt Tutorial #2: Parsing a PCAP + File <https://jon.oberheide.org/blog/2008/10/15/dpkt-tutorial-2-parsing-a-pcap-file/>`__ + - `dpkt Tutorial #3: dns + spoofing <https://jon.oberheide.org/blog/2008/12/20/dpkt-tutorial-3-dns-spoofing/>`__ + - `dpkt Tutorial #4: AS Paths from + MRT/BGP <https://jon.oberheide.org/blog/2009/03/25/dpkt-tutorial-4-as-paths-from-mrt-bgp/>`__ + + `Jeff Silverman <https://github.com/jeffsilverm>`__ has some + `code <https://github.com/jeffsilverm/dpkt_doc>`__ and + `documentation <http://www.commercialventvac.com/dpkt.html>`__. + + LICENSE + ------- + + BSD 3-Clause License, as the upstream project + +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Natural Language :: English +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy diff --git a/scripts/external_libs/dpkt-1.8.6/README.rst b/scripts/external_libs/dpkt-1.8.6/README.rst new file mode 100644 index 00000000..9339c574 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/README.rst @@ -0,0 +1,104 @@ + +==== +dpkt +==== + +| |docs| |travis| |coveralls| |landscape| |version| +| |downloads| |wheel| |supported-versions| |supported-implementations| + +.. |docs| image:: https://readthedocs.org/projects/dpkt/badge/?style=flat + :target: https://readthedocs.org/projects/dpkt + :alt: Documentation Status + +.. |travis| image:: http://img.shields.io/travis/kbandla/dpkt/master.png?style=flat + :alt: Travis-CI Build Status + :target: https://travis-ci.org/kbandla/dpkt + +.. |coveralls| image:: http://img.shields.io/coveralls/kbandla/dpkt/master.png?style=flat + :alt: Coverage Status + :target: https://coveralls.io/r/kbandla/dpkt + +.. |landscape| image:: https://landscape.io/github/kbandla/dpkt/master/landscape.svg?style=flat + :target: https://landscape.io/github/kbandla/dpkt/master + :alt: Code Quality Status + +.. |version| image:: http://img.shields.io/pypi/v/dpkt.png?style=flat + :alt: PyPI Package latest release + :target: https://pypi.python.org/pypi/dpkt + +.. |downloads| image:: http://img.shields.io/pypi/dm/dpkt.png?style=flat + :alt: PyPI Package monthly downloads + :target: https://pypi.python.org/pypi/dpkt + +.. |wheel| image:: https://pypip.in/wheel/dpkt/badge.png?style=flat + :alt: PyPI Wheel + :target: https://pypi.python.org/pypi/dpkt + +.. |supported-versions| image:: https://pypip.in/py_versions/dpkt/badge.png?style=flat + :alt: Supported versions + :target: https://pypi.python.org/pypi/dpkt + +.. |supported-implementations| image:: https://pypip.in/implementation/dpkt/badge.png?style=flat + :alt: Supported implementations + :target: https://pypi.python.org/pypi/dpkt + +Installation +============ + +:: + + pip install dpkt + +Documentation +============= + +https://dpkt.readthedocs.org/ + +Development +=========== + +To run the all tests run:: + + tox + + +Deviations from upstream +~~~~~~~~~~~~~~~~~~~~~~~~ + +This code is based on `dpkt code <https://code.google.com/p/dpkt/>`__ lead by Dug Song. + +At this point, this is not the exact `upstream +version <https://code.google.com/p/dpkt/>`__. If you are looking for the +latest stock dpkt, please get it from the above link. + +Almost all of the upstream changes are pulled. However, some modules are +not. Here is a list of the changes: + +- `dpkt/dpkt.py <https://github.com/kbandla/dpkt/commit/336fe02b0e2f00b382d91cd42558a69eec16d6c7>`__: + decouple dnet from dpkt +- `dpkt/dns.py <https://github.com/kbandla/dpkt/commit/2bf3cde213144391fd90488d12f9ccce51b5fbca>`__ + : parse some more DNS flags + +Examples +-------- + +[@jonoberheide's](https://twitter.com/jonoberheide) old examples still +apply: + +- `dpkt Tutorial #1: ICMP + Echo <https://jon.oberheide.org/blog/2008/08/25/dpkt-tutorial-1-icmp-echo/>`__ +- `dpkt Tutorial #2: Parsing a PCAP + File <https://jon.oberheide.org/blog/2008/10/15/dpkt-tutorial-2-parsing-a-pcap-file/>`__ +- `dpkt Tutorial #3: dns + spoofing <https://jon.oberheide.org/blog/2008/12/20/dpkt-tutorial-3-dns-spoofing/>`__ +- `dpkt Tutorial #4: AS Paths from + MRT/BGP <https://jon.oberheide.org/blog/2009/03/25/dpkt-tutorial-4-as-paths-from-mrt-bgp/>`__ + +`Jeff Silverman <https://github.com/jeffsilverm>`__ has some +`code <https://github.com/jeffsilverm/dpkt_doc>`__ and +`documentation <http://www.commercialventvac.com/dpkt.html>`__. + +LICENSE +------- + +BSD 3-Clause License, as the upstream project diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/PKG-INFO b/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/PKG-INFO new file mode 100644 index 00000000..e82397e7 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/PKG-INFO @@ -0,0 +1,122 @@ +Metadata-Version: 1.1 +Name: dpkt +Version: 1.8.6 +Summary: fast, simple packet creation / parsing, with definitions for the basic TCP/IP protocols +Home-page: http://dpkt.googlecode.com/ +Author: Dug Song <dugsong@monkey.org> +Author-email: UNKNOWN +License: BSD +Description: + ==== + dpkt + ==== + + | |docs| |travis| |coveralls| |landscape| |version| + | |downloads| |wheel| |supported-versions| |supported-implementations| + + .. |docs| image:: https://readthedocs.org/projects/dpkt/badge/?style=flat + :target: https://readthedocs.org/projects/dpkt + :alt: Documentation Status + + .. |travis| image:: http://img.shields.io/travis/kbandla/dpkt/master.png?style=flat + :alt: Travis-CI Build Status + :target: https://travis-ci.org/kbandla/dpkt + + .. |coveralls| image:: http://img.shields.io/coveralls/kbandla/dpkt/master.png?style=flat + :alt: Coverage Status + :target: https://coveralls.io/r/kbandla/dpkt + + .. |landscape| image:: https://landscape.io/github/kbandla/dpkt/master/landscape.svg?style=flat + :target: https://landscape.io/github/kbandla/dpkt/master + :alt: Code Quality Status + + .. |version| image:: http://img.shields.io/pypi/v/dpkt.png?style=flat + :alt: PyPI Package latest release + :target: https://pypi.python.org/pypi/dpkt + + .. |downloads| image:: http://img.shields.io/pypi/dm/dpkt.png?style=flat + :alt: PyPI Package monthly downloads + :target: https://pypi.python.org/pypi/dpkt + + .. |wheel| image:: https://pypip.in/wheel/dpkt/badge.png?style=flat + :alt: PyPI Wheel + :target: https://pypi.python.org/pypi/dpkt + + .. |supported-versions| image:: https://pypip.in/py_versions/dpkt/badge.png?style=flat + :alt: Supported versions + :target: https://pypi.python.org/pypi/dpkt + + .. |supported-implementations| image:: https://pypip.in/implementation/dpkt/badge.png?style=flat + :alt: Supported implementations + :target: https://pypi.python.org/pypi/dpkt + + Installation + ============ + + :: + + pip install dpkt + + Documentation + ============= + + https://dpkt.readthedocs.org/ + + Development + =========== + + To run the all tests run:: + + tox + + + Deviations from upstream + ~~~~~~~~~~~~~~~~~~~~~~~~ + + This code is based on `dpkt code <https://code.google.com/p/dpkt/>`__ lead by Dug Song. + + At this point, this is not the exact `upstream + version <https://code.google.com/p/dpkt/>`__. If you are looking for the + latest stock dpkt, please get it from the above link. + + Almost all of the upstream changes are pulled. However, some modules are + not. Here is a list of the changes: + + - `dpkt/dpkt.py <https://github.com/kbandla/dpkt/commit/336fe02b0e2f00b382d91cd42558a69eec16d6c7>`__: + decouple dnet from dpkt + - `dpkt/dns.py <https://github.com/kbandla/dpkt/commit/2bf3cde213144391fd90488d12f9ccce51b5fbca>`__ + : parse some more DNS flags + + Examples + -------- + + [@jonoberheide's](https://twitter.com/jonoberheide) old examples still + apply: + + - `dpkt Tutorial #1: ICMP + Echo <https://jon.oberheide.org/blog/2008/08/25/dpkt-tutorial-1-icmp-echo/>`__ + - `dpkt Tutorial #2: Parsing a PCAP + File <https://jon.oberheide.org/blog/2008/10/15/dpkt-tutorial-2-parsing-a-pcap-file/>`__ + - `dpkt Tutorial #3: dns + spoofing <https://jon.oberheide.org/blog/2008/12/20/dpkt-tutorial-3-dns-spoofing/>`__ + - `dpkt Tutorial #4: AS Paths from + MRT/BGP <https://jon.oberheide.org/blog/2009/03/25/dpkt-tutorial-4-as-paths-from-mrt-bgp/>`__ + + `Jeff Silverman <https://github.com/jeffsilverm>`__ has some + `code <https://github.com/jeffsilverm/dpkt_doc>`__ and + `documentation <http://www.commercialventvac.com/dpkt.html>`__. + + LICENSE + ------- + + BSD 3-Clause License, as the upstream project + +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Natural Language :: English +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/SOURCES.txt b/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/SOURCES.txt new file mode 100644 index 00000000..c2521e2a --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/SOURCES.txt @@ -0,0 +1,80 @@ +AUTHORS +CHANGES +LICENSE +MANIFEST.in +README.rst +setup.cfg +setup.py +dpkt/__init__.py +dpkt/ah.py +dpkt/aim.py +dpkt/aoe.py +dpkt/aoeata.py +dpkt/aoecfg.py +dpkt/arp.py +dpkt/asn1.py +dpkt/bgp.py +dpkt/cdp.py +dpkt/crc32c.py +dpkt/dhcp.py +dpkt/diameter.py +dpkt/dns.py +dpkt/dpkt.py +dpkt/dtp.py +dpkt/esp.py +dpkt/ethernet.py +dpkt/gre.py +dpkt/gzip.py +dpkt/h225.py +dpkt/hsrp.py +dpkt/http.py +dpkt/icmp.py +dpkt/icmp6.py +dpkt/ieee80211.py +dpkt/igmp.py +dpkt/ip.py +dpkt/ip6.py +dpkt/ipx.py +dpkt/llc.py +dpkt/loopback.py +dpkt/mrt.py +dpkt/netbios.py +dpkt/netflow.py +dpkt/ntp.py +dpkt/ospf.py +dpkt/pcap.py +dpkt/pim.py +dpkt/pmap.py +dpkt/ppp.py +dpkt/pppoe.py +dpkt/qq.py +dpkt/radiotap.py +dpkt/radius.py +dpkt/rfb.py +dpkt/rip.py +dpkt/rpc.py +dpkt/rtp.py +dpkt/rx.py +dpkt/sccp.py +dpkt/sctp.py +dpkt/sip.py +dpkt/sll.py +dpkt/smb.py +dpkt/snoop.py +dpkt/ssl.py +dpkt/ssl_ciphersuites.py +dpkt/stp.py +dpkt/stun.py +dpkt/tcp.py +dpkt/telnet.py +dpkt/tftp.py +dpkt/tns.py +dpkt/tpkt.py +dpkt/udp.py +dpkt/vrrp.py +dpkt/yahoo.py +dpkt.egg-info/PKG-INFO +dpkt.egg-info/SOURCES.txt +dpkt.egg-info/dependency_links.txt +dpkt.egg-info/not-zip-safe +dpkt.egg-info/top_level.txt
\ No newline at end of file diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/dependency_links.txt b/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/dependency_links.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/not-zip-safe b/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/not-zip-safe new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/not-zip-safe @@ -0,0 +1 @@ + diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/top_level.txt b/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/top_level.txt new file mode 100644 index 00000000..4daab81a --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/top_level.txt @@ -0,0 +1 @@ +dpkt diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/__init__.py b/scripts/external_libs/dpkt-1.8.6/dpkt/__init__.py new file mode 100644 index 00000000..31d6281d --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/__init__.py @@ -0,0 +1,70 @@ +"""fast, simple packet creation and parsing.""" + +__author__ = 'Dug Song <dugsong@monkey.org>' +__copyright__ = 'Copyright (c) 2004 Dug Song' +__license__ = 'BSD' +__url__ = 'http://dpkt.googlecode.com/' +__version__ = '1.8.6' + +from dpkt import * + +import ah +import aim +import arp +import asn1 +import bgp +import cdp +import dhcp +import diameter +import dns +import dtp +import esp +import ethernet +import gre +import gzip +import h225 +import hsrp +import http +import icmp +import icmp6 +import ieee80211 +import igmp +import ip +import ip6 +import ipx +import llc +import loopback +import mrt +import netbios +import netflow +import ntp +import ospf +import pcap +import pim +import pmap +import ppp +import pppoe +import qq +import radiotap +import radius +import rfb +import rip +import rpc +import rtp +import rx +import sccp +import sctp +import sip +import sll +import smb +import ssl +import stp +import stun +import tcp +import telnet +import tftp +import tns +import tpkt +import udp +import vrrp +import yahoo diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/ah.py b/scripts/external_libs/dpkt-1.8.6/dpkt/ah.py new file mode 100644 index 00000000..87def27e --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/ah.py @@ -0,0 +1,31 @@ +# $Id: ah.py 34 2007-01-28 07:54:20Z dugsong $ + +"""Authentication Header.""" + +import dpkt + +class AH(dpkt.Packet): + __hdr__ = ( + ('nxt', 'B', 0), + ('len', 'B', 0), # payload length + ('rsvd', 'H', 0), + ('spi', 'I', 0), + ('seq', 'I', 0) + ) + auth = '' + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.auth = self.data[:self.len] + buf = self.data[self.len:] + import ip + try: + self.data = ip.IP.get_proto(self.nxt)(buf) + setattr(self, self.data.__class__.__name__.lower(), self.data) + except (KeyError, dpkt.UnpackError): + self.data = buf + + def __len__(self): + return self.__hdr_len__ + len(self.auth) + len(self.data) + + def __str__(self): + return self.pack_hdr() + str(self.auth) + str(self.data) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/aim.py b/scripts/external_libs/dpkt-1.8.6/dpkt/aim.py new file mode 100644 index 00000000..0fb58063 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/aim.py @@ -0,0 +1,47 @@ +# $Id: aim.py 23 2006-11-08 15:45:33Z dugsong $ + +"""AOL Instant Messenger.""" + +import dpkt +import struct + +# OSCAR: http://iserverd1.khstu.ru/oscar/ + +class FLAP(dpkt.Packet): + __hdr__ = ( + ('ast', 'B', 0x2a), # '*' + ('type', 'B', 0), + ('seq', 'H', 0), + ('len', 'H', 0) + ) + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + if self.ast != 0x2a: + raise dpkt.UnpackError('invalid FLAP header') + if len(self.data) < self.len: + raise dpkt.NeedData, '%d left, %d needed' % (len(self.data), self.len) + +class SNAC(dpkt.Packet): + __hdr__ = ( + ('family', 'H', 0), + ('subtype', 'H', 0), + ('flags', 'H', 0), + ('reqid', 'I', 0) + ) + +def tlv(buf): + n = 4 + try: + t, l = struct.unpack('>HH', buf[:n]) + except struct.error: + raise dpkt.UnpackError + v = buf[n:n+l] + if len(v) < l: + raise dpkt.NeedData + buf = buf[n+l:] + return (t,l,v, buf) + +# TOC 1.0: http://jamwt.com/Py-TOC/PROTOCOL + +# TOC 2.0: http://www.firestuff.org/projects/firetalk/doc/toc2.txt + diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/aoe.py b/scripts/external_libs/dpkt-1.8.6/dpkt/aoe.py new file mode 100644 index 00000000..45a1eaf2 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/aoe.py @@ -0,0 +1,70 @@ +"""ATA over Ethernet Protocol.""" + +import struct + + +import dpkt + + +class AOE(dpkt.Packet): + __hdr__ = ( + ('ver_fl', 'B', 0x10), + ('err', 'B', 0), + ('maj', 'H', 0), + ('min', 'B', 0), + ('cmd', 'B', 0), + ('tag', 'I', 0), + ) + _cmdsw = {} + + def _get_ver(self): return self.ver_fl >> 4 + def _set_ver(self, ver): self.ver_fl = (ver << 4) | (self.ver_fl & 0xf) + ver = property(_get_ver, _set_ver) + + def _get_fl(self): return self.ver_fl & 0xf + def _set_fl(self, fl): self.ver_fl = (self.ver_fl & 0xf0) | fl + fl = property(_get_fl, _set_fl) + + def set_cmd(cls, cmd, pktclass): + cls._cmdsw[cmd] = pktclass + set_cmd = classmethod(set_cmd) + + def get_cmd(cls, cmd): + return cls._cmdsw[cmd] + get_cmd = classmethod(get_cmd) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + try: + self.data = self._cmdsw[self.cmd](self.data) + setattr(self, self.data.__class__.__name__.lower(), self.data) + except (KeyError, struct.error, dpkt.UnpackError): + pass + + def pack_hdr(self): + try: + return dpkt.Packet.pack_hdr(self) + except struct.error, e: + raise dpkt.PackError(str(e)) + + +AOE_CMD_ATA = 0 +AOE_CMD_CFG = 1 +AOE_FLAG_RSP = 1 << 3 + + +def __load_cmds(): + prefix = 'AOE_CMD_' + g = globals() + for k, v in g.iteritems(): + if k.startswith(prefix): + name = 'aoe' + k[len(prefix):].lower() + try: + mod = __import__(name, g) + except ImportError: + continue + AOE.set_cmd(v, getattr(mod, name.upper())) + + +if not AOE._cmdsw: + __load_cmds() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/aoeata.py b/scripts/external_libs/dpkt-1.8.6/dpkt/aoeata.py new file mode 100644 index 00000000..67e2ca11 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/aoeata.py @@ -0,0 +1,34 @@ +'''ATA over Ethernet ATA command''' + +import dpkt, aoe + +ATA_DEVICE_IDENTIFY = 0xec + +class AOEATA(dpkt.Packet): + __hdr__ = ( + ('aflags', 'B', 0), + ('errfeat', 'B', 0), + ('scnt', 'B', 0), + ('cmdstat', 'B', ATA_DEVICE_IDENTIFY), + ('lba0', 'B', 0), + ('lba1', 'B', 0), + ('lba2', 'B', 0), + ('lba3', 'B', 0), + ('lba4', 'B', 0), + ('lba5', 'B', 0), + ('res', 'H', 0), + ) + + # XXX: in unpack, switch on ATA command like icmp does on type + + +if __name__ == '__main__': + import unittest + + class AOEATATestCase(unittest.TestCase): + def test_AOEATA(self): + s = '\x03\x0a\x6b\x19\x00\x00\x00\x00\x45\x00\x00\x28\x94\x1f\x00\x00\xe3\x06\x99\xb4\x23\x2b\x24\x00\xde\x8e\x84\x42\xab\xd1\x00\x50\x00\x35\xe1\x29\x20\xd9\x00\x00\x00\x22\x9b\xf0\xe2\x04\x65\x6b' + aoeata = AOEATA(s) + self.failUnless(str(aoeata) == s) + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/aoecfg.py b/scripts/external_libs/dpkt-1.8.6/dpkt/aoecfg.py new file mode 100644 index 00000000..00831504 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/aoecfg.py @@ -0,0 +1,24 @@ +'''ATA over Ethernet ATA command''' + +import dpkt + +class AOECFG(dpkt.Packet): + __hdr__ = ( + ('bufcnt', 'H', 0), + ('fwver', 'H', 0), + ('scnt', 'B', 0), + ('aoeccmd', 'B', 0), + ('cslen', 'H', 0), + ) + + +if __name__ == '__main__': + import unittest + + class AOECFGTestCase(unittest.TestCase): + def test_AOECFG(self): + s = '\x01\x02\x03\x04\x05\x06\x11\x12\x13\x14\x15\x16\x88\xa2\x10\x00\x00\x01\x02\x01\x80\x00\x00\x00\x12\x34\x00\x00\x00\x00\x04\x00' + '\0xed' * 1024 + aoecfg = AOECFG(s[14+10:]) + self.failUnless(aoecfg.bufcnt == 0x1234) + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/arp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/arp.py new file mode 100644 index 00000000..6e742ee1 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/arp.py @@ -0,0 +1,31 @@ +# $Id: arp.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Address Resolution Protocol.""" + +import dpkt + +# Hardware address format +ARP_HRD_ETH = 0x0001 # ethernet hardware +ARP_HRD_IEEE802 = 0x0006 # IEEE 802 hardware + +# Protocol address format +ARP_PRO_IP = 0x0800 # IP protocol + +# ARP operation +ARP_OP_REQUEST = 1 # request to resolve ha given pa +ARP_OP_REPLY = 2 # response giving hardware address +ARP_OP_REVREQUEST = 3 # request to resolve pa given ha +ARP_OP_REVREPLY = 4 # response giving protocol address + +class ARP(dpkt.Packet): + __hdr__ = ( + ('hrd', 'H', ARP_HRD_ETH), + ('pro', 'H', ARP_PRO_IP), + ('hln', 'B', 6), # hardware address length + ('pln', 'B', 4), # protocol address length + ('op', 'H', ARP_OP_REQUEST), + ('sha', '6s', ''), + ('spa', '4s', ''), + ('tha', '6s', ''), + ('tpa', '4s', '') + ) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/asn1.py b/scripts/external_libs/dpkt-1.8.6/dpkt/asn1.py new file mode 100644 index 00000000..9a088107 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/asn1.py @@ -0,0 +1,119 @@ +# $Id: asn1.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Abstract Syntax Notation #1.""" + +import struct, time +import dpkt + +# Type class +CLASSMASK = 0xc0 +UNIVERSAL = 0x00 +APPLICATION = 0x40 +CONTEXT = 0x80 +PRIVATE = 0xc0 + +# Constructed (vs. primitive) +CONSTRUCTED = 0x20 + +# Universal-class tags +TAGMASK = 0x1f +INTEGER = 2 +BIT_STRING = 3 # arbitrary bit string +OCTET_STRING = 4 # arbitrary octet string +NULL = 5 +OID = 6 # object identifier +SEQUENCE = 16 # ordered collection of types +SET = 17 # unordered collection of types +PRINT_STRING = 19 # printable string +T61_STRING = 20 # T.61 (8-bit) character string +IA5_STRING = 22 # ASCII +UTC_TIME = 23 + +def utctime(buf): + """Convert ASN.1 UTCTime string to UTC float.""" + yy = int(buf[:2]) + mm = int(buf[2:4]) + dd = int(buf[4:6]) + hh = int(buf[6:8]) + mm = int(buf[8:10]) + try: + ss = int(buf[10:12]) + buf = buf[12:] + except TypeError: + ss = 0 + buf = buf[10:] + if buf[0] == '+': + hh -= int(buf[1:3]) + mm -= int(buf[3:5]) + elif buf[0] == '-': + hh += int(buf[1:3]) + mm += int(buf[3:5]) + return time.mktime((2000 + yy, mm, dd, hh, mm, ss, 0, 0, 0)) + +def decode(buf): + """Sleazy ASN.1 decoder. + Return list of (id, value) tuples from ASN.1 BER/DER encoded buffer. + """ + msg = [] + while buf: + t = ord(buf[0]) + constructed = t & CONSTRUCTED + tag = t & TAGMASK + l = ord(buf[1]) + c = 0 + if constructed and l == 128: + # XXX - constructed, indefinite length + msg.append(t, decode(buf[2:])) + elif l >= 128: + c = l & 127 + if c == 1: + l = ord(buf[2]) + elif c == 2: + l = struct.unpack('>H', buf[2:4])[0] + elif c == 3: + l = struct.unpack('>I', buf[1:5])[0] & 0xfff + c = 2 + elif c == 4: + l = struct.unpack('>I', buf[2:6])[0] + else: + # XXX - can be up to 127 bytes, but... + raise dpkt.UnpackError('excessive long-form ASN.1 length %d' % l) + + # Skip type, length + buf = buf[2+c:] + + # Parse content + if constructed: + msg.append((t, decode(buf))) + elif tag == INTEGER: + if l == 0: + n = 0 + elif l == 1: + n = ord(buf[0]) + elif l == 2: + n = struct.unpack('>H', buf[:2])[0] + elif l == 3: + n = struct.unpack('>I', buf[:4])[0] >> 8 + elif l == 4: + n = struct.unpack('>I', buf[:4])[0] + else: + raise dpkt.UnpackError('excessive integer length > %d bytes' % l) + msg.append((t, n)) + elif tag == UTC_TIME: + msg.append((t, utctime(buf[:l]))) + else: + msg.append((t, buf[:l])) + + # Skip content + buf = buf[l:] + return msg + +if __name__ == '__main__': + import unittest + + class ASN1TestCase(unittest.TestCase): + def test_asn1(self): + s = '0\x82\x02Q\x02\x01\x0bc\x82\x02J\x04xcn=Douglas J Song 1, ou=Information Technology Division, ou=Faculty and Staff, ou=People, o=University of Michigan, c=US\n\x01\x00\n\x01\x03\x02\x01\x00\x02\x01\x00\x01\x01\x00\x87\x0bobjectclass0\x82\x01\xb0\x04\rmemberOfGroup\x04\x03acl\x04\x02cn\x04\x05title\x04\rpostalAddress\x04\x0ftelephoneNumber\x04\x04mail\x04\x06member\x04\thomePhone\x04\x11homePostalAddress\x04\x0bobjectClass\x04\x0bdescription\x04\x18facsimileTelephoneNumber\x04\x05pager\x04\x03uid\x04\x0cuserPassword\x04\x08joinable\x04\x10associatedDomain\x04\x05owner\x04\x0erfc822ErrorsTo\x04\x08ErrorsTo\x04\x10rfc822RequestsTo\x04\nRequestsTo\x04\tmoderator\x04\nlabeledURL\x04\nonVacation\x04\x0fvacationMessage\x04\x05drink\x04\x0elastModifiedBy\x04\x10lastModifiedTime\x04\rmodifiersname\x04\x0fmodifytimestamp\x04\x0ccreatorsname\x04\x0fcreatetimestamp' + self.failUnless(decode(s) == [(48, [(2, 11), (99, [(4, 'cn=Douglas J Song 1, ou=Information Technology Division, ou=Faculty and Staff, ou=People, o=University of Michigan, c=US'), (10, '\x00'), (10, '\x03'), (2, 0), (2, 0), (1, '\x00'), (135, 'objectclass'), (48, [(4, 'memberOfGroup'), (4, 'acl'), (4, 'cn'), (4, 'title'), (4, 'postalAddress'), (4, 'telephoneNumber'), (4, 'mail'), (4, 'member'), (4, 'homePhone'), (4, 'homePostalAddress'), (4, 'objectClass'), (4, 'description'), (4, 'facsimileTelephoneNumber'), (4, 'pager'), (4, 'uid'), (4, 'userPassword'), (4, 'joinable'), (4, 'associatedDomain'), (4, 'owner'), (4, 'rfc822ErrorsTo'), (4, 'ErrorsTo'), (4, 'rfc822RequestsTo'), (4, 'RequestsTo'), (4, 'moderator'), (4, 'labeledURL'), (4, 'onVacation'), (4, 'vacationMessage'), (4, 'drink'), (4, 'lastModifiedBy'), (4, 'lastModifiedTime'), (4, 'modifiersname'), (4, 'modifytimestamp'), (4, 'creatorsname'), (4, 'createtimestamp')])])])]) + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/bgp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/bgp.py new file mode 100644 index 00000000..b9fb26a0 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/bgp.py @@ -0,0 +1,760 @@ +# $Id: bgp.py 76 2011-01-06 15:51:30Z dugsong $ + +"""Border Gateway Protocol.""" + +import dpkt +import struct, socket + +# Border Gateway Protocol 4 - RFC 4271 +# Communities Attribute - RFC 1997 +# Capabilities - RFC 3392 +# Route Refresh - RFC 2918 +# Route Reflection - RFC 4456 +# Confederations - RFC 3065 +# Cease Subcodes - RFC 4486 +# NOPEER Community - RFC 3765 +# Multiprotocol Extensions - 2858 + +# Message Types +OPEN = 1 +UPDATE = 2 +NOTIFICATION = 3 +KEEPALIVE = 4 +ROUTE_REFRESH = 5 + +# Attribute Types +ORIGIN = 1 +AS_PATH = 2 +NEXT_HOP = 3 +MULTI_EXIT_DISC = 4 +LOCAL_PREF = 5 +ATOMIC_AGGREGATE = 6 +AGGREGATOR = 7 +COMMUNITIES = 8 +ORIGINATOR_ID = 9 +CLUSTER_LIST = 10 +MP_REACH_NLRI = 14 +MP_UNREACH_NLRI = 15 + +# Origin Types +ORIGIN_IGP = 0 +ORIGIN_EGP = 1 +INCOMPLETE = 2 + +# AS Path Types +AS_SET = 1 +AS_SEQUENCE = 2 +AS_CONFED_SEQUENCE = 3 +AS_CONFED_SET = 4 + +# Reserved Communities Types +NO_EXPORT = 0xffffff01L +NO_ADVERTISE = 0xffffff02L +NO_EXPORT_SUBCONFED = 0xffffff03L +NO_PEER = 0xffffff04L + +# Common AFI types +AFI_IPV4 = 1 +AFI_IPV6 = 2 + +# Multiprotocol SAFI types +SAFI_UNICAST = 1 +SAFI_MULTICAST = 2 +SAFI_UNICAST_MULTICAST = 3 + +# OPEN Message Optional Parameters +AUTHENTICATION = 1 +CAPABILITY = 2 + +# Capability Types +CAP_MULTIPROTOCOL = 1 +CAP_ROUTE_REFRESH = 2 + +# NOTIFICATION Error Codes +MESSAGE_HEADER_ERROR = 1 +OPEN_MESSAGE_ERROR = 2 +UPDATE_MESSAGE_ERROR = 3 +HOLD_TIMER_EXPIRED = 4 +FSM_ERROR = 5 +CEASE = 6 + +# Message Header Error Subcodes +CONNECTION_NOT_SYNCHRONIZED = 1 +BAD_MESSAGE_LENGTH = 2 +BAD_MESSAGE_TYPE = 3 + +# OPEN Message Error Subcodes +UNSUPPORTED_VERSION_NUMBER = 1 +BAD_PEER_AS = 2 +BAD_BGP_IDENTIFIER = 3 +UNSUPPORTED_OPTIONAL_PARAMETER = 4 +AUTHENTICATION_FAILURE = 5 +UNACCEPTABLE_HOLD_TIME = 6 +UNSUPPORTED_CAPABILITY = 7 + +# UPDATE Message Error Subcodes +MALFORMED_ATTRIBUTE_LIST = 1 +UNRECOGNIZED_ATTRIBUTE = 2 +MISSING_ATTRIBUTE = 3 +ATTRIBUTE_FLAGS_ERROR = 4 +ATTRIBUTE_LENGTH_ERROR = 5 +INVALID_ORIGIN_ATTRIBUTE = 6 +AS_ROUTING_LOOP = 7 +INVALID_NEXT_HOP_ATTRIBUTE = 8 +OPTIONAL_ATTRIBUTE_ERROR = 9 +INVALID_NETWORK_FIELD = 10 +MALFORMED_AS_PATH = 11 + +# Cease Error Subcodes +MAX_NUMBER_OF_PREFIXES_REACHED = 1 +ADMINISTRATIVE_SHUTDOWN = 2 +PEER_DECONFIGURED = 3 +ADMINISTRATIVE_RESET = 4 +CONNECTION_REJECTED = 5 +OTHER_CONFIGURATION_CHANGE = 6 +CONNECTION_COLLISION_RESOLUTION = 7 +OUT_OF_RESOURCES = 8 + + +class BGP(dpkt.Packet): + __hdr__ = ( + ('marker', '16s', '\xff' * 16), + ('len', 'H', 0), + ('type', 'B', OPEN) + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.data[:self.len - self.__hdr_len__] + if self.type == OPEN: + self.data = self.open = self.Open(self.data) + elif self.type == UPDATE: + self.data = self.update = self.Update(self.data) + elif self.type == NOTIFICATION: + self.data = self.notifiation = self.Notification(self.data) + elif self.type == KEEPALIVE: + self.data = self.keepalive = self.Keepalive(self.data) + elif self.type == ROUTE_REFRESH: + self.data = self.route_refresh = self.RouteRefresh(self.data) + + class Open(dpkt.Packet): + __hdr__ = ( + ('v', 'B', 4), + ('asn', 'H', 0), + ('holdtime', 'H', 0), + ('identifier', 'I', 0), + ('param_len', 'B', 0) + ) + __hdr_defaults__ = { + 'parameters': [] + } + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + l = [] + plen = self.param_len + while plen > 0: + param = self.Parameter(self.data) + self.data = self.data[len(param):] + plen -= len(param) + l.append(param) + self.data = self.parameters = l + + def __len__(self): + return self.__hdr_len__ + \ + sum(map(len, self.parameters)) + + def __str__(self): + params = ''.join(map(str, self.parameters)) + self.param_len = len(params) + return self.pack_hdr() + params + + class Parameter(dpkt.Packet): + __hdr__ = ( + ('type', 'B', 0), + ('len', 'B', 0) + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.data[:self.len] + + if self.type == AUTHENTICATION: + self.data = self.authentication = self.Authentication(self.data) + elif self.type == CAPABILITY: + self.data = self.capability = self.Capability(self.data) + + class Authentication(dpkt.Packet): + __hdr__ = ( + ('code', 'B', 0), + ) + + class Capability(dpkt.Packet): + __hdr__ = ( + ('code', 'B', 0), + ('len', 'B', 0) + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.data[:self.len] + + + class Update(dpkt.Packet): + __hdr_defaults__ = { + 'withdrawn': [], + 'attributes': [], + 'announced': [] + } + + def unpack(self, buf): + self.data = buf + + # Withdrawn Routes + wlen = struct.unpack('>H', self.data[:2])[0] + self.data = self.data[2:] + l = [] + while wlen > 0: + route = RouteIPV4(self.data) + self.data = self.data[len(route):] + wlen -= len(route) + l.append(route) + self.withdrawn = l + + # Path Attributes + plen = struct.unpack('>H', self.data[:2])[0] + self.data = self.data[2:] + l = [] + while plen > 0: + attr = self.Attribute(self.data) + self.data = self.data[len(attr):] + plen -= len(attr) + l.append(attr) + self.attributes = l + + # Announced Routes + l = [] + while self.data: + route = RouteIPV4(self.data) + self.data = self.data[len(route):] + l.append(route) + self.announced = l + + def __len__(self): + return 2 + sum(map(len, self.withdrawn)) + \ + 2 + sum(map(len, self.attributes)) + \ + sum(map(len, self.announced)) + + def __str__(self): + return struct.pack('>H', sum(map(len, self.withdrawn))) + \ + ''.join(map(str, self.withdrawn)) + \ + struct.pack('>H', sum(map(len, self.attributes))) + \ + ''.join(map(str, self.attributes)) + \ + ''.join(map(str, self.announced)) + + class Attribute(dpkt.Packet): + __hdr__ = ( + ('flags', 'B', 0), + ('type', 'B', 0) + ) + + def _get_o(self): + return (self.flags >> 7) & 0x1 + def _set_o(self, o): + self.flags = (self.flags & ~0x80) | ((o & 0x1) << 7) + optional = property(_get_o, _set_o) + + def _get_t(self): + return (self.flags >> 6) & 0x1 + def _set_t(self, t): + self.flags = (self.flags & ~0x40) | ((t & 0x1) << 6) + transitive = property(_get_t, _set_t) + + def _get_p(self): + return (self.flags >> 5) & 0x1 + def _set_p(self, p): + self.flags = (self.flags & ~0x20) | ((p & 0x1) << 5) + partial = property(_get_p, _set_p) + + def _get_e(self): + return (self.flags >> 4) & 0x1 + def _set_e(self, e): + self.flags = (self.flags & ~0x10) | ((e & 0x1) << 4) + extended_length = property(_get_e, _set_e) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + + if self.extended_length: + self.len = struct.unpack('>H', self.data[:2])[0] + self.data = self.data[2:] + else: + self.len = struct.unpack('B', self.data[:1])[0] + self.data = self.data[1:] + + self.data = self.data[:self.len] + + if self.type == ORIGIN: + self.data = self.origin = self.Origin(self.data) + elif self.type == AS_PATH: + self.data = self.as_path = self.ASPath(self.data) + elif self.type == NEXT_HOP: + self.data = self.next_hop = self.NextHop(self.data) + elif self.type == MULTI_EXIT_DISC: + self.data = self.multi_exit_disc = self.MultiExitDisc(self.data) + elif self.type == LOCAL_PREF: + self.data = self.local_pref = self.LocalPref(self.data) + elif self.type == ATOMIC_AGGREGATE: + self.data = self.atomic_aggregate = self.AtomicAggregate(self.data) + elif self.type == AGGREGATOR: + self.data = self.aggregator = self.Aggregator(self.data) + elif self.type == COMMUNITIES: + self.data = self.communities = self.Communities(self.data) + elif self.type == ORIGINATOR_ID: + self.data = self.originator_id = self.OriginatorID(self.data) + elif self.type == CLUSTER_LIST: + self.data = self.cluster_list = self.ClusterList(self.data) + elif self.type == MP_REACH_NLRI: + self.data = self.mp_reach_nlri = self.MPReachNLRI(self.data) + elif self.type == MP_UNREACH_NLRI: + self.data = self.mp_unreach_nlri = self.MPUnreachNLRI(self.data) + + def __len__(self): + if self.extended_length: + attr_len = 2 + else: + attr_len = 1 + return self.__hdr_len__ + \ + attr_len + \ + len(self.data) + + def __str__(self): + if self.extended_length: + attr_len_str = struct.pack('>H', self.len) + else: + attr_len_str = struct.pack('B', self.len) + return self.pack_hdr() + \ + attr_len_str + \ + str(self.data) + + class Origin(dpkt.Packet): + __hdr__ = ( + ('type', 'B', ORIGIN_IGP), + ) + + class ASPath(dpkt.Packet): + __hdr_defaults__ = { + 'segments': [] + } + + def unpack(self, buf): + self.data = buf + l = [] + while self.data: + seg = self.ASPathSegment(self.data) + self.data = self.data[len(seg):] + l.append(seg) + self.data = self.segments = l + + def __len__(self): + return sum(map(len, self.data)) + + def __str__(self): + return ''.join(map(str, self.data)) + + class ASPathSegment(dpkt.Packet): + __hdr__ = ( + ('type', 'B', 0), + ('len', 'B', 0) + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + l = [] + for i in range(self.len): + AS = struct.unpack('>H', self.data[:2])[0] + self.data = self.data[2:] + l.append(AS) + self.data = self.path = l + + def __len__(self): + return self.__hdr_len__ + \ + 2 * len(self.path) + + def __str__(self): + as_str = '' + for AS in self.path: + as_str += struct.pack('>H', AS) + return self.pack_hdr() + \ + as_str + + class NextHop(dpkt.Packet): + __hdr__ = ( + ('ip', 'I', 0), + ) + + class MultiExitDisc(dpkt.Packet): + __hdr__ = ( + ('value', 'I', 0), + ) + + class LocalPref(dpkt.Packet): + __hdr__ = ( + ('value', 'I', 0), + ) + + class AtomicAggregate(dpkt.Packet): + def unpack(self, buf): + pass + + def __len__(self): + return 0 + + def __str__(self): + return '' + + class Aggregator(dpkt.Packet): + __hdr__ = ( + ('asn', 'H', 0), + ('ip', 'I', 0) + ) + + class Communities(dpkt.Packet): + __hdr_defaults__ = { + 'list': [] + } + + def unpack(self, buf): + self.data = buf + l = [] + while self.data: + val = struct.unpack('>I', self.data[:4])[0] + if (val >= 0x00000000L and val <= 0x0000ffffL) or \ + (val >= 0xffff0000L and val <= 0xffffffffL): + comm = self.ReservedCommunity(self.data[:4]) + else: + comm = self.Community(self.data[:4]) + self.data = self.data[len(comm):] + l.append(comm) + self.data = self.list = l + + def __len__(self): + return sum(map(len, self.data)) + + def __str__(self): + return ''.join(map(str, self.data)) + + class Community(dpkt.Packet): + __hdr__ = ( + ('asn', 'H', 0), + ('value', 'H', 0) + ) + + class ReservedCommunity(dpkt.Packet): + __hdr__ = ( + ('value', 'I', 0), + ) + + class OriginatorID(dpkt.Packet): + __hdr__ = ( + ('value', 'I', 0), + ) + + class ClusterList(dpkt.Packet): + __hdr_defaults__ = { + 'list': [] + } + + def unpack(self, buf): + self.data = buf + l = [] + while self.data: + id = struct.unpack('>I', self.data[:4])[0] + self.data = self.data[4:] + l.append(id) + self.data = self.list = l + + def __len__(self): + return 4 * len(self.list) + + def __str__(self): + cluster_str = '' + for val in self.list: + cluster_str += struct.pack('>I', val) + return cluster_str + + class MPReachNLRI(dpkt.Packet): + __hdr__ = ( + ('afi', 'H', AFI_IPV4), + ('safi', 'B', SAFI_UNICAST), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + + # Next Hop + nlen = struct.unpack('B', self.data[:1])[0] + self.data = self.data[1:] + self.next_hop = self.data[:nlen] + self.data = self.data[nlen:] + + # SNPAs + l = [] + num_snpas = struct.unpack('B', self.data[:1])[0] + self.data = self.data[1:] + for i in range(num_snpas): + snpa = self.SNPA(self.data) + self.data = self.data[len(snpa):] + l.append(snpa) + self.snpas = l + + if self.afi == AFI_IPV4: + Route = RouteIPV4 + elif self.afi == AFI_IPV6: + Route = RouteIPV6 + else: + Route = RouteGeneric + + # Announced Routes + l = [] + while self.data: + route = Route(self.data) + self.data = self.data[len(route):] + l.append(route) + self.data = self.announced = l + + def __len__(self): + return self.__hdr_len__ + \ + 1 + len(self.next_hop) + \ + 1 + sum(map(len, self.snpas)) + \ + sum(map(len, self.announced)) + + def __str__(self): + return self.pack_hdr() + \ + struct.pack('B', len(self.next_hop)) + \ + str(self.next_hop) + \ + struct.pack('B', len(self.snpas)) + \ + ''.join(map(str, self.snpas)) + \ + ''.join(map(str, self.announced)) + + class SNPA: + __hdr__ = ( + ('len', 'B', 0), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.data[:(self.len + 1) / 2] + + class MPUnreachNLRI(dpkt.Packet): + __hdr__ = ( + ('afi', 'H', AFI_IPV4), + ('safi', 'B', SAFI_UNICAST), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + + if self.afi == AFI_IPV4: + Route = RouteIPV4 + elif self.afi == AFI_IPV6: + Route = RouteIPV6 + else: + Route = RouteGeneric + + # Withdrawn Routes + l = [] + while self.data: + route = Route(self.data) + self.data = self.data[len(route):] + l.append(route) + self.data = self.withdrawn = l + + def __len__(self): + return self.__hdr_len__ + \ + sum(map(len, self.data)) + + def __str__(self): + return self.pack_hdr() + \ + ''.join(map(str, self.data)) + + + class Notification(dpkt.Packet): + __hdr__ = ( + ('code', 'B', 0), + ('subcode', 'B', 0), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.error = self.data + + + class Keepalive(dpkt.Packet): + def unpack(self, buf): + pass + + def __len__(self): + return 0 + + def __str__(self): + return '' + + + class RouteRefresh(dpkt.Packet): + __hdr__ = ( + ('afi', 'H', AFI_IPV4), + ('rsvd', 'B', 0), + ('safi', 'B', SAFI_UNICAST) + ) + + +class RouteGeneric(dpkt.Packet): + __hdr__ = ( + ('len', 'B', 0), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.prefix = self.data[:(self.len + 7) / 8] + +class RouteIPV4(dpkt.Packet): + __hdr__ = ( + ('len', 'B', 0), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + tmp = self.data[:(self.len + 7) / 8] + tmp += (4 - len(tmp)) * '\x00' + self.data = self.prefix = tmp + + def __repr__(self): + cidr = '%s/%d' % (socket.inet_ntoa(self.prefix), self.len) + return '%s(%s)' % (self.__class__.__name__, cidr) + + def __len__(self): + return self.__hdr_len__ + \ + (self.len + 7) / 8 + + def __str__(self): + return self.pack_hdr() + \ + self.prefix[:(self.len + 7) / 8] + +class RouteIPV6(dpkt.Packet): + __hdr__ = ( + ('len', 'B', 0), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + tmp = self.data[:(self.len + 7) / 8] + tmp += (16 - len(tmp)) * '\x00' + self.data = self.prefix = tmp + + def __len__(self): + return self.__hdr_len__ + \ + (self.len + 7) / 8 + + def __str__(self): + return self.pack_hdr() + \ + self.prefix[:(self.len + 7) / 8] + + +if __name__ == '__main__': + import unittest + + class BGPTestCase(unittest.TestCase): + def testPack(self): + b1 = BGP(self.bgp1) + self.failUnless(self.bgp1 == str(b1)) + b2 = BGP(self.bgp2) + self.failUnless(self.bgp2 == str(b2)) + b3 = BGP(self.bgp3) + self.failUnless(self.bgp3 == str(b3)) + b4 = BGP(self.bgp4) + self.failUnless(self.bgp4 == str(b4)) + + def testUnpack(self): + b1 = BGP(self.bgp1) + self.failUnless(b1.len == 19) + self.failUnless(b1.type == KEEPALIVE) + self.failUnless(b1.keepalive is not None) + + b2 = BGP(self.bgp2) + self.failUnless(b2.type == UPDATE) + self.failUnless(len(b2.update.withdrawn) == 0) + self.failUnless(len(b2.update.announced) == 1) + self.failUnless(len(b2.update.attributes) == 9) + a = b2.update.attributes[1] + self.failUnless(a.type == AS_PATH) + self.failUnless(a.len == 10) + self.failUnless(len(a.as_path.segments) == 2) + s = a.as_path.segments[0] + self.failUnless(s.type == AS_SET) + self.failUnless(s.len == 2) + self.failUnless(len(s.path) == 2) + self.failUnless(s.path[0] == 500) + + a = b2.update.attributes[6] + self.failUnless(a.type == COMMUNITIES) + self.failUnless(a.len == 12) + self.failUnless(len(a.communities.list) == 3) + c = a.communities.list[0] + self.failUnless(c.asn == 65215) + self.failUnless(c.value == 1) + r = b2.update.announced[0] + self.failUnless(r.len == 22) + self.failUnless(r.prefix == '\xc0\xa8\x04\x00') + + b3 = BGP(self.bgp3) + self.failUnless(b3.type == UPDATE) + self.failUnless(len(b3.update.withdrawn) == 0) + self.failUnless(len(b3.update.announced) == 0) + self.failUnless(len(b3.update.attributes) == 6) + a = b3.update.attributes[0] + self.failUnless(a.optional == False) + self.failUnless(a.transitive == True) + self.failUnless(a.partial == False) + self.failUnless(a.extended_length == False) + self.failUnless(a.type == ORIGIN) + self.failUnless(a.len == 1) + o = a.origin + self.failUnless(o.type == ORIGIN_IGP) + a = b3.update.attributes[5] + self.failUnless(a.optional == True) + self.failUnless(a.transitive == False) + self.failUnless(a.partial == False) + self.failUnless(a.extended_length == True) + self.failUnless(a.type == MP_REACH_NLRI) + self.failUnless(a.len == 30) + m = a.mp_reach_nlri + self.failUnless(m.afi == AFI_IPV4) + self.failUnless(len(m.snpas) == 0) + self.failUnless(len(m.announced) == 1) + p = m.announced[0] + self.failUnless(p.len == 96) + + b4 = BGP(self.bgp4) + self.failUnless(b4.len == 45) + self.failUnless(b4.type == OPEN) + self.failUnless(b4.open.asn == 237) + self.failUnless(b4.open.param_len == 16) + self.failUnless(len(b4.open.parameters) == 3) + p = b4.open.parameters[0] + self.failUnless(p.type == CAPABILITY) + self.failUnless(p.len == 6) + c = p.capability + self.failUnless(c.code == CAP_MULTIPROTOCOL) + self.failUnless(c.len == 4) + self.failUnless(c.data == '\x00\x01\x00\x01') + c = b4.open.parameters[2].capability + self.failUnless(c.code == CAP_ROUTE_REFRESH) + self.failUnless(c.len == 0) + + bgp1 = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x13\x04' + bgp2 = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x63\x02\x00\x00\x00\x48\x40\x01\x01\x00\x40\x02\x0a\x01\x02\x01\xf4\x01\xf4\x02\x01\xfe\xbb\x40\x03\x04\xc0\xa8\x00\x0f\x40\x05\x04\x00\x00\x00\x64\x40\x06\x00\xc0\x07\x06\xfe\xba\xc0\xa8\x00\x0a\xc0\x08\x0c\xfe\xbf\x00\x01\x03\x16\x00\x04\x01\x54\x00\xfa\x80\x09\x04\xc0\xa8\x00\x0f\x80\x0a\x04\xc0\xa8\x00\xfa\x16\xc0\xa8\x04' + bgp3 = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x79\x02\x00\x00\x00\x62\x40\x01\x01\x00\x40\x02\x00\x40\x05\x04\x00\x00\x00\x64\xc0\x10\x08\x00\x02\x01\x2c\x00\x00\x01\x2c\xc0\x80\x24\x00\x00\xfd\xe9\x40\x01\x01\x00\x40\x02\x04\x02\x01\x15\xb3\x40\x05\x04\x00\x00\x00\x2c\x80\x09\x04\x16\x05\x05\x05\x80\x0a\x04\x16\x05\x05\x05\x90\x0e\x00\x1e\x00\x01\x80\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x04\x04\x04\x00\x60\x18\x77\x01\x00\x00\x01\xf4\x00\x00\x01\xf4\x85' + bgp4 = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x2d\x01\x04\x00\xed\x00\x5a\xc6\x6e\x83\x7d\x10\x02\x06\x01\x04\x00\x01\x00\x01\x02\x02\x80\x00\x02\x02\x02\x00' + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/cdp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/cdp.py new file mode 100644 index 00000000..71c2c6ba --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/cdp.py @@ -0,0 +1,95 @@ +# $Id: cdp.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Cisco Discovery Protocol.""" + +import struct +import dpkt + +CDP_DEVID = 1 # string +CDP_ADDRESS = 2 +CDP_PORTID = 3 # string +CDP_CAPABILITIES = 4 # 32-bit bitmask +CDP_VERSION = 5 # string +CDP_PLATFORM = 6 # string +CDP_IPPREFIX = 7 + +CDP_VTP_MGMT_DOMAIN = 9 # string +CDP_NATIVE_VLAN = 10 # 16-bit integer +CDP_DUPLEX = 11 # 8-bit boolean +CDP_TRUST_BITMAP = 18 # 8-bit bitmask0x13 +CDP_UNTRUST_COS = 19 # 8-bit port +CDP_SYSTEM_NAME = 20 # string +CDP_SYSTEM_OID = 21 # 10-byte binary string +CDP_MGMT_ADDRESS = 22 # 32-bit number of addrs, Addresses +CDP_LOCATION = 23 # string + +class CDP(dpkt.Packet): + __hdr__ = ( + ('version', 'B', 2), + ('ttl', 'B', 180), + ('sum', 'H', 0) + ) + class Address(dpkt.Packet): + # XXX - only handle NLPID/IP for now + __hdr__ = ( + ('ptype', 'B', 1), # protocol type (NLPID) + ('plen', 'B', 1), # protocol length + ('p', 'B', 0xcc), # IP + ('alen', 'H', 4) # address length + ) + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.data[:self.alen] + + class TLV(dpkt.Packet): + __hdr__ = ( + ('type', 'H', 0), + ('len', 'H', 4) + ) + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.data[:self.len - 4] + if self.type == CDP_ADDRESS: + n = struct.unpack('>I', self.data[:4])[0] + buf = self.data[4:] + l = [] + for i in range(n): + a = CDP.Address(buf) + l.append(a) + buf = buf[len(a):] + self.data = l + + def __len__(self): + if self.type == CDP_ADDRESS: + n = 4 + sum(map(len, self.data)) + else: + n = len(self.data) + return self.__hdr_len__ + n + + def __str__(self): + self.len = len(self) + if self.type == CDP_ADDRESS: + s = struct.pack('>I', len(self.data)) + \ + ''.join(map(str, self.data)) + else: + s = self.data + return self.pack_hdr() + s + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + buf = self.data + l = [] + while buf: + tlv = self.TLV(buf) + l.append(tlv) + buf = buf[len(tlv):] + self.data = l + + def __len__(self): + return self.__hdr_len__ + sum(map(len, self.data)) + + def __str__(self): + data = ''.join(map(str, self.data)) + if not self.sum: + self.sum = dpkt.in_cksum(self.pack_hdr() + data) + return self.pack_hdr() + data diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/crc32c.py b/scripts/external_libs/dpkt-1.8.6/dpkt/crc32c.py new file mode 100644 index 00000000..45593882 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/crc32c.py @@ -0,0 +1,80 @@ +# $Id: crc32c.py 23 2006-11-08 15:45:33Z dugsong $ + +import array + +# CRC-32C Checksum +# http://tools.ietf.org/html/rfc3309 + +crc32c_table = ( + 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL, + 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL, 0x78B2DBCCL, + 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, + 0x5E133C24L, 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, + 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L, + 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL, + 0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, + 0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, + 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL, + 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L, + 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, + 0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, + 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 0x417B1DBCL, + 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L, + 0x67DAFA54L, 0x95B17957L, 0xCBA24573L, 0x39C9C670L, 0x2A993584L, + 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, + 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL, + 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL, + 0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, + 0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, + 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL, + 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L, + 0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, + 0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, + 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL, + 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL, + 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, + 0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, + 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 0x92A8FC17L, + 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL, + 0xB4091BFFL, 0x466298FCL, 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, + 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, + 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L, + 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL, + 0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, + 0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, + 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L, + 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL, + 0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, + 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, + 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L, + 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L, + 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L, + 0x07198540L, 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, + 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL, + 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L, + 0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, + 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, + 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL, + 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L, + 0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, + 0xAD7D5351L + ) + +def add(crc, buf): + buf = array.array('B', buf) + for b in buf: + crc = (crc >> 8) ^ crc32c_table[(crc ^ b) & 0xff] + return crc + +def done(crc): + tmp = ~crc & 0xffffffffL + b0 = tmp & 0xff + b1 = (tmp >> 8) & 0xff + b2 = (tmp >> 16) & 0xff + b3 = (tmp >> 24) & 0xff + crc = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3 + return crc + +def cksum(buf): + """Return computed CRC-32c checksum.""" + return done(add(0xffffffffL, buf)) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/dhcp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/dhcp.py new file mode 100644 index 00000000..9916884a --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/dhcp.py @@ -0,0 +1,168 @@ +# $Id: dhcp.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Dynamic Host Configuration Protocol.""" + +import arp, dpkt + +DHCP_OP_REQUEST = 1 +DHCP_OP_REPLY = 2 + +DHCP_MAGIC = 0x63825363 + +# DHCP option codes +DHCP_OPT_NETMASK = 1 # I: subnet mask +DHCP_OPT_TIMEOFFSET = 2 +DHCP_OPT_ROUTER = 3 # s: list of router ips +DHCP_OPT_TIMESERVER = 4 +DHCP_OPT_NAMESERVER = 5 +DHCP_OPT_DNS_SVRS = 6 # s: list of DNS servers +DHCP_OPT_LOGSERV = 7 +DHCP_OPT_COOKIESERV = 8 +DHCP_OPT_LPRSERV = 9 +DHCP_OPT_IMPSERV = 10 +DHCP_OPT_RESSERV = 11 +DHCP_OPT_HOSTNAME = 12 # s: client hostname +DHCP_OPT_BOOTFILESIZE = 13 +DHCP_OPT_DUMPFILE = 14 +DHCP_OPT_DOMAIN = 15 # s: domain name +DHCP_OPT_SWAPSERV = 16 +DHCP_OPT_ROOTPATH = 17 +DHCP_OPT_EXTENPATH = 18 +DHCP_OPT_IPFORWARD = 19 +DHCP_OPT_SRCROUTE = 20 +DHCP_OPT_POLICYFILTER = 21 +DHCP_OPT_MAXASMSIZE = 22 +DHCP_OPT_IPTTL = 23 +DHCP_OPT_MTUTIMEOUT = 24 +DHCP_OPT_MTUTABLE = 25 +DHCP_OPT_MTUSIZE = 26 +DHCP_OPT_LOCALSUBNETS = 27 +DHCP_OPT_BROADCASTADDR = 28 +DHCP_OPT_DOMASKDISCOV = 29 +DHCP_OPT_MASKSUPPLY = 30 +DHCP_OPT_DOROUTEDISC = 31 +DHCP_OPT_ROUTERSOLICIT = 32 +DHCP_OPT_STATICROUTE = 33 +DHCP_OPT_TRAILERENCAP = 34 +DHCP_OPT_ARPTIMEOUT = 35 +DHCP_OPT_ETHERENCAP = 36 +DHCP_OPT_TCPTTL = 37 +DHCP_OPT_TCPKEEPALIVE = 38 +DHCP_OPT_TCPALIVEGARBAGE = 39 +DHCP_OPT_NISDOMAIN = 40 +DHCP_OPT_NISSERVERS = 41 +DHCP_OPT_NISTIMESERV = 42 +DHCP_OPT_VENDSPECIFIC = 43 +DHCP_OPT_NBNS = 44 +DHCP_OPT_NBDD = 45 +DHCP_OPT_NBTCPIP = 46 +DHCP_OPT_NBTCPSCOPE = 47 +DHCP_OPT_XFONT = 48 +DHCP_OPT_XDISPLAYMGR = 49 +DHCP_OPT_REQ_IP = 50 # I: IP address +DHCP_OPT_LEASE_SEC = 51 # I: lease seconds +DHCP_OPT_OPTIONOVERLOAD = 52 +DHCP_OPT_MSGTYPE = 53 # B: message type +DHCP_OPT_SERVER_ID = 54 # I: server IP address +DHCP_OPT_PARAM_REQ = 55 # s: list of option codes +DHCP_OPT_MESSAGE = 56 +DHCP_OPT_MAXMSGSIZE = 57 +DHCP_OPT_RENEWTIME = 58 +DHCP_OPT_REBINDTIME = 59 +DHCP_OPT_VENDOR_ID = 60 # s: vendor class id +DHCP_OPT_CLIENT_ID = 61 # Bs: idtype, id (idtype 0: FQDN, idtype 1: MAC) +DHCP_OPT_NISPLUSDOMAIN = 64 +DHCP_OPT_NISPLUSSERVERS = 65 +DHCP_OPT_MOBILEIPAGENT = 68 +DHCP_OPT_SMTPSERVER = 69 +DHCP_OPT_POP3SERVER = 70 +DHCP_OPT_NNTPSERVER = 71 +DHCP_OPT_WWWSERVER = 72 +DHCP_OPT_FINGERSERVER = 73 +DHCP_OPT_IRCSERVER = 74 +DHCP_OPT_STSERVER = 75 +DHCP_OPT_STDASERVER = 76 + +# DHCP message type values +DHCPDISCOVER = 1 +DHCPOFFER = 2 +DHCPREQUEST = 3 +DHCPDECLINE = 4 +DHCPACK = 5 +DHCPNAK = 6 +DHCPRELEASE = 7 +DHCPINFORM = 8 + +class DHCP(dpkt.Packet): + __hdr__ = ( + ('op', 'B', DHCP_OP_REQUEST), + ('hrd', 'B', arp.ARP_HRD_ETH), # just like ARP.hrd + ('hln', 'B', 6), # and ARP.hln + ('hops', 'B', 0), + ('xid', 'I', 0xdeadbeefL), + ('secs', 'H', 0), + ('flags', 'H', 0), + ('ciaddr', 'I', 0), + ('yiaddr', 'I', 0), + ('siaddr', 'I', 0), + ('giaddr', 'I', 0), + ('chaddr', '16s', 16 * '\x00'), + ('sname', '64s', 64 * '\x00'), + ('file', '128s', 128 * '\x00'), + ('magic', 'I', DHCP_MAGIC), + ) + opts = ( + (DHCP_OPT_MSGTYPE, chr(DHCPDISCOVER)), + (DHCP_OPT_PARAM_REQ, ''.join(map(chr, (DHCP_OPT_REQ_IP, + DHCP_OPT_ROUTER, + DHCP_OPT_NETMASK, + DHCP_OPT_DNS_SVRS)))) + ) # list of (type, data) tuples + + def __len__(self): + return self.__hdr_len__ + \ + sum([ 2 + len(o[1]) for o in self.opts ]) + 1 + len(self.data) + + def __str__(self): + return self.pack_hdr() + self.pack_opts() + str(self.data) + + def pack_opts(self): + """Return packed options string.""" + if not self.opts: + return '' + l = [] + for t, data in self.opts: + l.append('%s%s%s' % (chr(t), chr(len(data)), data)) + l.append('\xff') + return ''.join(l) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.chaddr = self.chaddr[:self.hln] + buf = self.data + l = [] + while buf: + t = ord(buf[0]) + if t == 0xff: + buf = buf[1:] + break + elif t == 0: + buf = buf[1:] + else: + n = ord(buf[1]) + l.append((t, buf[2:2+n])) + buf = buf[2+n:] + self.opts = l + self.data = buf + +if __name__ == '__main__': + import unittest + + class DHCPTestCast(unittest.TestCase): + def test_DHCP(self): + s = '\x01\x01\x06\x00\xadS\xc8c\xb8\x87\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02U\x82\xf3\xa6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00c\x82Sc5\x01\x01\xfb\x01\x01=\x07\x01\x00\x02U\x82\xf3\xa62\x04\n\x00\x01e\x0c\tGuinevere<\x08MSFT 5.07\n\x01\x0f\x03\x06,./\x1f!+\xff\x00\x00\x00\x00\x00' + dhcp = DHCP(s) + self.failUnless(s == str(dhcp)) + + unittest.main() + diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/diameter.py b/scripts/external_libs/dpkt-1.8.6/dpkt/diameter.py new file mode 100644 index 00000000..505eccd0 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/diameter.py @@ -0,0 +1,181 @@ +# $Id: diameter.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Diameter.""" + +import struct +import dpkt + +# Diameter Base Protocol - RFC 3588 +# http://tools.ietf.org/html/rfc3588 + +# Request/Answer Command Codes +ABORT_SESSION = 274 +ACCOUTING = 271 +CAPABILITIES_EXCHANGE = 257 +DEVICE_WATCHDOG = 280 +DISCONNECT_PEER = 282 +RE_AUTH = 258 +SESSION_TERMINATION = 275 + +class Diameter(dpkt.Packet): + __hdr__ = ( + ('v', 'B', 1), + ('len', '3s', 0), + ('flags', 'B', 0), + ('cmd', '3s', 0), + ('app_id', 'I', 0), + ('hop_id', 'I', 0), + ('end_id', 'I', 0) + ) + + def _get_r(self): + return (self.flags >> 7) & 0x1 + def _set_r(self, r): + self.flags = (self.flags & ~0x80) | ((r & 0x1) << 7) + request_flag = property(_get_r, _set_r) + + def _get_p(self): + return (self.flags >> 6) & 0x1 + def _set_p(self, p): + self.flags = (self.flags & ~0x40) | ((p & 0x1) << 6) + proxiable_flag = property(_get_p, _set_p) + + def _get_e(self): + return (self.flags >> 5) & 0x1 + def _set_e(self, e): + self.flags = (self.flags & ~0x20) | ((e & 0x1) << 5) + error_flag = property(_get_e, _set_e) + + def _get_t(self): + return (self.flags >> 4) & 0x1 + def _set_t(self, t): + self.flags = (self.flags & ~0x10) | ((t & 0x1) << 4) + retransmit_flag = property(_get_t, _set_t) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.cmd = (ord(self.cmd[0]) << 16) | \ + (ord(self.cmd[1]) << 8) | \ + ord(self.cmd[2]) + self.len = (ord(self.len[0]) << 16) | \ + (ord(self.len[1]) << 8) | \ + ord(self.len[2]) + self.data = self.data[:self.len - self.__hdr_len__] + + l = [] + while self.data: + avp = AVP(self.data) + l.append(avp) + self.data = self.data[len(avp):] + self.data = self.avps = l + + def pack_hdr(self): + self.len = chr((self.len >> 16) & 0xff) + \ + chr((self.len >> 8) & 0xff) + \ + chr(self.len & 0xff) + self.cmd = chr((self.cmd >> 16) & 0xff) + \ + chr((self.cmd >> 8) & 0xff) + \ + chr(self.cmd & 0xff) + return dpkt.Packet.pack_hdr(self) + + def __len__(self): + return self.__hdr_len__ + \ + sum(map(len, self.data)) + + def __str__(self): + return self.pack_hdr() + \ + ''.join(map(str, self.data)) + +class AVP(dpkt.Packet): + __hdr__ = ( + ('code', 'I', 0), + ('flags', 'B', 0), + ('len', '3s', 0), + ) + + def _get_v(self): + return (self.flags >> 7) & 0x1 + def _set_v(self, v): + self.flags = (self.flags & ~0x80) | ((v & 0x1) << 7) + vendor_flag = property(_get_v, _set_v) + + def _get_m(self): + return (self.flags >> 6) & 0x1 + def _set_m(self, m): + self.flags = (self.flags & ~0x40) | ((m & 0x1) << 6) + mandatory_flag = property(_get_m, _set_m) + + def _get_p(self): + return (self.flags >> 5) & 0x1 + def _set_p(self, p): + self.flags = (self.flags & ~0x20) | ((p & 0x1) << 5) + protected_flag = property(_get_p, _set_p) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.len = (ord(self.len[0]) << 16) | \ + (ord(self.len[1]) << 8) | \ + ord(self.len[2]) + + if self.vendor_flag: + self.vendor = struct.unpack('>I', self.data[:4])[0] + self.data = self.data[4:self.len - self.__hdr_len__] + else: + self.data = self.data[:self.len - self.__hdr_len__] + + def pack_hdr(self): + self.len = chr((self.len >> 16) & 0xff) + \ + chr((self.len >> 8) & 0xff) + \ + chr(self.len & 0xff) + data = dpkt.Packet.pack_hdr(self) + if self.vendor_flag: + data += struct.pack('>I', self.vendor) + return data + + def __len__(self): + length = self.__hdr_len__ + \ + sum(map(len, self.data)) + if self.vendor_flag: + length += 4 + return length + + +if __name__ == '__main__': + import unittest + + class DiameterTestCase(unittest.TestCase): + def testPack(self): + d = Diameter(self.s) + self.failUnless(self.s == str(d)) + d = Diameter(self.t) + self.failUnless(self.t == str(d)) + + def testUnpack(self): + d = Diameter(self.s) + self.failUnless(d.len == 40) + #self.failUnless(d.cmd == DEVICE_WATCHDOG_REQUEST) + self.failUnless(d.request_flag == 1) + self.failUnless(d.error_flag == 0) + self.failUnless(len(d.avps) == 2) + + avp = d.avps[0] + #self.failUnless(avp.code == ORIGIN_HOST) + self.failUnless(avp.mandatory_flag == 1) + self.failUnless(avp.vendor_flag == 0) + self.failUnless(avp.len == 12) + self.failUnless(len(avp) == 12) + self.failUnless(avp.data == '\x68\x30\x30\x32') + + # also test the optional vendor id support + d = Diameter(self.t) + self.failUnless(d.len == 44) + avp = d.avps[0] + self.failUnless(avp.vendor_flag == 1) + self.failUnless(avp.len == 16) + self.failUnless(len(avp) == 16) + self.failUnless(avp.vendor == 3735928559) + self.failUnless(avp.data == '\x68\x30\x30\x32') + + s = '\x01\x00\x00\x28\x80\x00\x01\x18\x00\x00\x00\x00\x00\x00\x41\xc8\x00\x00\x00\x0c\x00\x00\x01\x08\x40\x00\x00\x0c\x68\x30\x30\x32\x00\x00\x01\x28\x40\x00\x00\x08' + t = '\x01\x00\x00\x2c\x80\x00\x01\x18\x00\x00\x00\x00\x00\x00\x41\xc8\x00\x00\x00\x0c\x00\x00\x01\x08\xc0\x00\x00\x10\xde\xad\xbe\xef\x68\x30\x30\x32\x00\x00\x01\x28\x40\x00\x00\x08' + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/dns.py b/scripts/external_libs/dpkt-1.8.6/dpkt/dns.py new file mode 100644 index 00000000..24ca1bd6 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/dns.py @@ -0,0 +1,342 @@ +# $Id: dns.py 27 2006-11-21 01:22:52Z dahelder $ + +"""Domain Name System.""" + +import struct +import dpkt + +DNS_Q = 0 +DNS_R = 1 + +# Opcodes +DNS_QUERY = 0 +DNS_IQUERY = 1 +DNS_STATUS = 2 +DNS_NOTIFY = 4 +DNS_UPDATE = 5 + +# Flags +DNS_CD = 0x0010 # checking disabled +DNS_AD = 0x0020 # authenticated data +DNS_Z = 0x0040 # unused +DNS_RA = 0x0080 # recursion available +DNS_RD = 0x0100 # recursion desired +DNS_TC = 0x0200 # truncated +DNS_AA = 0x0400 # authoritative answer +DNS_QR = 0x8000 # response ( query / response ) + +# Response codes +DNS_RCODE_NOERR = 0 +DNS_RCODE_FORMERR = 1 +DNS_RCODE_SERVFAIL = 2 +DNS_RCODE_NXDOMAIN = 3 +DNS_RCODE_NOTIMP = 4 +DNS_RCODE_REFUSED = 5 +DNS_RCODE_YXDOMAIN = 6 +DNS_RCODE_YXRRSET = 7 +DNS_RCODE_NXRRSET = 8 +DNS_RCODE_NOTAUTH = 9 +DNS_RCODE_NOTZONE = 10 + +# RR types +DNS_A = 1 +DNS_NS = 2 +DNS_CNAME = 5 +DNS_SOA = 6 +DNS_PTR = 12 +DNS_HINFO = 13 +DNS_MX = 15 +DNS_TXT = 16 +DNS_AAAA = 28 +DNS_SRV = 33 + +# RR classes +DNS_IN = 1 +DNS_CHAOS = 3 +DNS_HESIOD = 4 +DNS_ANY = 255 + +def pack_name(name, off, label_ptrs): + if name: + labels = name.split('.') + else: + labels = [] + labels.append('') + buf = '' + for i, label in enumerate(labels): + key = '.'.join(labels[i:]).upper() + ptr = label_ptrs.get(key) + if not ptr: + if len(key) > 1: + ptr = off + len(buf) + if ptr < 0xc000: + label_ptrs[key] = ptr + i = len(label) + buf += chr(i) + label + else: + buf += struct.pack('>H', (0xc000 | ptr)) + break + return buf + +def unpack_name(buf, off): + name = '' + saved_off = 0 + for i in range(100): # XXX + n = ord(buf[off]) + if n == 0: + off += 1 + break + elif (n & 0xc0) == 0xc0: + ptr = struct.unpack('>H', buf[off:off+2])[0] & 0x3fff + off += 2 + if not saved_off: + saved_off = off + # XXX - don't use recursion!@#$ + name = name + unpack_name(buf, ptr)[0] + '.' + break + else: + off += 1 + name = name + buf[off:off+n] + '.' + if len(name) > 255: + raise dpkt.UnpackError('name longer than 255 bytes') + off += n + return name.strip('.'), off + +class DNS(dpkt.Packet): + __hdr__ = ( + ('id', 'H', 0), + ('op', 'H', DNS_RD), # recursive query + # XXX - lists of query, RR objects + ('qd', 'H', []), + ('an', 'H', []), + ('ns', 'H', []), + ('ar', 'H', []) + ) + def get_qr(self): + return int((self.op & DNS_QR) == DNS_QR) + def set_qr(self, v): + if v: self.op |= DNS_QR + else: self.op &= ~DNS_QR + qr = property(get_qr, set_qr) + + def get_opcode(self): + return (self.op >> 11) & 0xf + def set_opcode(self, v): + self.op = (self.op & ~0x7800) | ((v & 0xf) << 11) + opcode = property(get_opcode, set_opcode) + + def get_aa(self): + return int((self.op & DNS_AA) == DNS_AA) + def set_aa(self, v): + if v: self.op |= DNS_AA + else: self.op &= ~DNS_AA + aa = property(get_aa, set_aa) + + def get_rd(self): + return int((self.op & DNS_RD) == DNS_RD) + def set_rd(self,v): + if v: self.op |= DNS_RD + else: self.op &= ~DNS_RD + rd = property(get_rd, set_rd) + + def get_ra(self): + return int((self.op & DNS_RA) == DNS_RA) + def set_ra(self,v): + if v: self.op |= DNS_RA + else: self.op &= ~DNS_RA + ra = property(get_ra, set_ra) + + def get_zero(self): + return int((self.op & DNS_Z) == DNS_Z) + def set_zero(self, v): + if v: self.op |= DNS_Z + else: self.op &= ~DNS_Z + zero = property(get_zero, set_zero) + + def get_rcode(self): + return self.op & 0xf + def set_rcode(self, v): + self.op = (self.op & ~0xf) | (v & 0xf) + rcode = property(get_rcode, set_rcode) + + class Q(dpkt.Packet): + """DNS question.""" + __hdr__ = ( + ('name', '1025s', ''), + ('type', 'H', DNS_A), + ('cls', 'H', DNS_IN) + ) + # XXX - suk + def __len__(self): + raise NotImplementedError + __str__ = __len__ + def unpack(self, buf): + raise NotImplementedError + + class RR(Q): + """DNS resource record.""" + __hdr__ = ( + ('name', '1025s', ''), + ('type', 'H', DNS_A), + ('cls', 'H', DNS_IN), + ('ttl', 'I', 0), + ('rlen', 'H', 4), + ('rdata', 's', '') + ) + def pack_rdata(self, off, label_ptrs): + # XXX - yeah, this sux + if self.rdata: + return self.rdata + if self.type == DNS_A: + return self.ip + elif self.type == DNS_NS: + return pack_name(self.nsname, off, label_ptrs) + elif self.type == DNS_CNAME: + return pack_name(self.cname, off, label_ptrs) + elif self.type == DNS_PTR: + return pack_name(self.ptrname, off, label_ptrs) + elif self.type == DNS_SOA: + l = [] + l.append(pack_name(self.mname, off, label_ptrs)) + l.append(pack_name(self.rname, off + len(l[0]), label_ptrs)) + l.append(struct.pack('>IIIII', self.serial, self.refresh, + self.retry, self.expire, self.minimum)) + return ''.join(l) + elif self.type == DNS_MX: + return struct.pack('>H', self.preference) + \ + pack_name(self.mxname, off + 2, label_ptrs) + elif self.type == DNS_TXT or self.type == DNS_HINFO: + return ''.join([ '%s%s' % (chr(len(x)), x) + for x in self.text ]) + elif self.type == DNS_AAAA: + return self.ip6 + elif self.type == DNS_SRV: + return struct.pack('>HHH', self.priority, self.weight, self.port) + \ + pack_name(self.srvname, off + 6, label_ptrs) + + def unpack_rdata(self, buf, off): + if self.type == DNS_A: + self.ip = self.rdata + elif self.type == DNS_NS: + self.nsname, off = unpack_name(buf, off) + elif self.type == DNS_CNAME: + self.cname, off = unpack_name(buf, off) + elif self.type == DNS_PTR: + self.ptrname, off = unpack_name(buf, off) + elif self.type == DNS_SOA: + self.mname, off = unpack_name(buf, off) + self.rname, off = unpack_name(buf, off) + self.serial, self.refresh, self.retry, self.expire, \ + self.minimum = struct.unpack('>IIIII', buf[off:off+20]) + elif self.type == DNS_MX: + self.preference = struct.unpack('>H', self.rdata[:2]) + self.mxname, off = unpack_name(buf, off+2) + elif self.type == DNS_TXT or self.type == DNS_HINFO: + self.text = [] + buf = self.rdata + while buf: + n = ord(buf[0]) + self.text.append(buf[1:1+n]) + buf = buf[1+n:] + elif self.type == DNS_AAAA: + self.ip6 = self.rdata + elif self.type == DNS_SRV: + self.priority, self.weight, self.port = \ + struct.unpack('>HHH', self.rdata[:6]) + self.srvname, off = unpack_name(buf, off+6) + + def pack_q(self, buf, q): + """Append packed DNS question and return buf.""" + return buf + pack_name(q.name, len(buf), self.label_ptrs) + \ + struct.pack('>HH', q.type, q.cls) + + def unpack_q(self, buf, off): + """Return DNS question and new offset.""" + q = self.Q() + q.name, off = unpack_name(buf, off) + q.type, q.cls = struct.unpack('>HH', buf[off:off+4]) + off += 4 + return q, off + + def pack_rr(self, buf, rr): + """Append packed DNS RR and return buf.""" + name = pack_name(rr.name, len(buf), self.label_ptrs) + rdata = rr.pack_rdata(len(buf) + len(name) + 10, self.label_ptrs) + return buf + name + struct.pack('>HHIH', rr.type, rr.cls, rr.ttl, + len(rdata)) + rdata + + def unpack_rr(self, buf, off): + """Return DNS RR and new offset.""" + rr = self.RR() + rr.name, off = unpack_name(buf, off) + rr.type, rr.cls, rr.ttl, rdlen = struct.unpack('>HHIH', buf[off:off+10]) + off += 10 + rr.rdata = buf[off:off+rdlen] + rr.unpack_rdata(buf, off) + off += rdlen + return rr, off + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + off = self.__hdr_len__ + cnt = self.qd + self.qd = [] + for i in range(cnt): + q, off = self.unpack_q(buf, off) + self.qd.append(q) + for x in ('an', 'ns', 'ar'): + cnt = getattr(self, x, 0) + setattr(self, x, []) + for i in range(cnt): + rr, off = self.unpack_rr(buf, off) + getattr(self, x).append(rr) + self.data = '' + + def __len__(self): + # XXX - cop out + return len(str(self)) + + def __str__(self): + # XXX - compress names on the fly + self.label_ptrs = {} + buf = struct.pack(self.__hdr_fmt__, self.id, self.op, len(self.qd), + len(self.an), len(self.ns), len(self.ar)) + for q in self.qd: + buf = self.pack_q(buf, q) + for x in ('an', 'ns', 'ar'): + for rr in getattr(self, x): + buf = self.pack_rr(buf, rr) + del self.label_ptrs + return buf + +if __name__ == '__main__': + import unittest + from ip import IP + + class DNSTestCase(unittest.TestCase): + def test_basic(self): + s = 'E\x00\x02\x08\xc15\x00\x00\x80\x11\x92aBk0\x01Bk0w\x005\xc07\x01\xf4\xda\xc2d\xd2\x81\x80\x00\x01\x00\x03\x00\x0b\x00\x0b\x03www\x06google\x03com\x00\x00\x01\x00\x01\xc0\x0c\x00\x05\x00\x01\x00\x00\x03V\x00\x17\x03www\x06google\x06akadns\x03net\x00\xc0,\x00\x01\x00\x01\x00\x00\x01\xa3\x00\x04@\xe9\xabh\xc0,\x00\x01\x00\x01\x00\x00\x01\xa3\x00\x04@\xe9\xabc\xc07\x00\x02\x00\x01\x00\x00KG\x00\x0c\x04usw5\x04akam\xc0>\xc07\x00\x02\x00\x01\x00\x00KG\x00\x07\x04usw6\xc0t\xc07\x00\x02\x00\x01\x00\x00KG\x00\x07\x04usw7\xc0t\xc07\x00\x02\x00\x01\x00\x00KG\x00\x08\x05asia3\xc0t\xc07\x00\x02\x00\x01\x00\x00KG\x00\x05\x02za\xc07\xc07\x00\x02\x00\x01\x00\x00KG\x00\x0f\x02zc\x06akadns\x03org\x00\xc07\x00\x02\x00\x01\x00\x00KG\x00\x05\x02zf\xc07\xc07\x00\x02\x00\x01\x00\x00KG\x00\x05\x02zh\xc0\xd5\xc07\x00\x02\x00\x01\x00\x00KG\x00\x07\x04eur3\xc0t\xc07\x00\x02\x00\x01\x00\x00KG\x00\x07\x04use2\xc0t\xc07\x00\x02\x00\x01\x00\x00KG\x00\x07\x04use4\xc0t\xc0\xc1\x00\x01\x00\x01\x00\x00\xfb4\x00\x04\xd0\xb9\x84\xb0\xc0\xd2\x00\x01\x00\x01\x00\x001\x0c\x00\x04?\xf1\xc76\xc0\xed\x00\x01\x00\x01\x00\x00\xfb4\x00\x04?\xd7\xc6S\xc0\xfe\x00\x01\x00\x01\x00\x001\x0c\x00\x04?\xd00.\xc1\x0f\x00\x01\x00\x01\x00\x00\n\xdf\x00\x04\xc1-\x01g\xc1"\x00\x01\x00\x01\x00\x00\x101\x00\x04?\xd1\xaa\x88\xc15\x00\x01\x00\x01\x00\x00\r\x1a\x00\x04PCC\xb6\xc0o\x00\x01\x00\x01\x00\x00\x10\x7f\x00\x04?\xf1I\xd6\xc0\x87\x00\x01\x00\x01\x00\x00\n\xdf\x00\x04\xce\x84dl\xc0\x9a\x00\x01\x00\x01\x00\x00\n\xdf\x00\x04A\xcb\xea\x1b\xc0\xad\x00\x01\x00\x01\x00\x00\x0b)\x00\x04\xc1l\x9a\t' + ip = IP(s) + dns = DNS(ip.udp.data) + self.failUnless(dns.qd[0].name == 'www.google.com' and + dns.an[1].name == 'www.google.akadns.net') + s = '\x05\xf5\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03www\x03cnn\x03com\x00\x00\x01\x00\x01' + dns = DNS(s) + self.failUnless(s == str(dns)) + + def test_PTR(self): + s = 'g\x02\x81\x80\x00\x01\x00\x01\x00\x03\x00\x00\x011\x011\x03211\x03141\x07in-addr\x04arpa\x00\x00\x0c\x00\x01\xc0\x0c\x00\x0c\x00\x01\x00\x00\r6\x00$\x07default\nv-umce-ifs\x05umnet\x05umich\x03edu\x00\xc0\x0e\x00\x02\x00\x01\x00\x00\r6\x00\r\x06shabby\x03ifs\xc0O\xc0\x0e\x00\x02\x00\x01\x00\x00\r6\x00\x0f\x0cfish-license\xc0m\xc0\x0e\x00\x02\x00\x01\x00\x00\r6\x00\x0b\x04dns2\x03itd\xc0O' + dns = DNS(s) + self.failUnless(dns.qd[0].name == '1.1.211.141.in-addr.arpa' and + dns.an[0].ptrname == 'default.v-umce-ifs.umnet.umich.edu' and + dns.ns[0].nsname == 'shabby.ifs.umich.edu' and + dns.ns[1].ttl == 3382L and + dns.ns[2].nsname == 'dns2.itd.umich.edu') + self.failUnless(s == str(dns)) + + def test_pack_name(self): + # Empty name is \0 + x = pack_name('', 0, {}) + self.assertEqual(x, '\0') + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/dot1q.py b/scripts/external_libs/dpkt-1.8.6/dpkt/dot1q.py new file mode 100644 index 00000000..ac6eb185 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/dot1q.py @@ -0,0 +1,1110 @@ + + + +<!DOCTYPE html> +<html lang="en" class=" is-copy-enabled"> + <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# object: http://ogp.me/ns/object# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#"> + <meta charset='utf-8'> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta http-equiv="Content-Language" content="en"> + <meta name="viewport" content="width=1020"> + + + <title>hexcap/dot1q.py at master · hexcap/hexcap</title> + <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub"> + <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub"> + <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-114.png"> + <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114.png"> + <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-144.png"> + <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144.png"> + <meta property="fb:app_id" content="1401488693436528"> + + <meta content="@github" name="twitter:site" /><meta content="summary" name="twitter:card" /><meta content="hexcap/hexcap" name="twitter:title" /><meta content="hexcap - ncurses based hex editor for pcap files" name="twitter:description" /><meta content="https://avatars3.githubusercontent.com/u/5732830?v=3&s=400" name="twitter:image:src" /> + <meta content="GitHub" property="og:site_name" /><meta content="object" property="og:type" /><meta content="https://avatars3.githubusercontent.com/u/5732830?v=3&s=400" property="og:image" /><meta content="hexcap/hexcap" property="og:title" /><meta content="https://github.com/hexcap/hexcap" property="og:url" /><meta content="hexcap - ncurses based hex editor for pcap files" property="og:description" /> + <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats"> + <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors"> + <link rel="assets" href="https://assets-cdn.github.com/"> + <link rel="web-socket" href="wss://live.github.com/_sockets/NjE1MjA5Mjo4ZmY1YzBmYTBhNTQ0YzIzMTlkOWNlMDA3ZWQzNDM2Mzo1ZjcyZGY3ZTViMDQ2ODJlNjhjMDQzMDM5MjE3ZTIxNmI3ZTAwM2IyYmFhMDYyNjZlMTI0YmM1MDZlMzY2YTMw--521096dfee0071c38c7c0cbb37a19125d136bade"> + <meta name="pjax-timeout" content="1000"> + <link rel="sudo-modal" href="/sessions/sudo_modal"> + + <meta name="msapplication-TileImage" content="/windows-tile.png"> + <meta name="msapplication-TileColor" content="#ffffff"> + <meta name="selected-link" value="repo_source" data-pjax-transient> + + <meta name="google-site-verification" content="KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU"> + <meta name="google-analytics" content="UA-3769691-2"> + + <meta content="collector.githubapp.com" name="octolytics-host" /><meta content="collector-cdn.github.com" name="octolytics-script-host" /><meta content="github" name="octolytics-app-id" /><meta content="C0764E39:0F18:5EE73AA:55ED75B0" name="octolytics-dimension-request_id" /><meta content="6152092" name="octolytics-actor-id" /><meta content="danklein10" name="octolytics-actor-login" /><meta content="a094d7c15626ff3dfc327b66cc85ebc7fb8bf99dd6502952c19c58263e0a4131" name="octolytics-actor-hash" /> + + <meta content="Rails, view, blob#show" data-pjax-transient="true" name="analytics-event" /> + <meta class="js-ga-set" name="dimension1" content="Logged In"> + <meta class="js-ga-set" name="dimension4" content="Current repo nav"> + <meta name="is-dotcom" content="true"> + <meta name="hostname" content="github.com"> + <meta name="user-login" content="danklein10"> + + <link rel="mask-icon" href="https://assets-cdn.github.com/pinned-octocat.svg" color="#4078c0"> + <link rel="icon" type="image/x-icon" href="https://assets-cdn.github.com/favicon.ico"> + + <!-- </textarea> --><!-- '"` --><meta content="authenticity_token" name="csrf-param" /> +<meta content="38AGn6qyEzkQYOxGwzHrOFJlA8PVe1dGcw8fNEwl4eRgd01lt1QnIGHZA2qAEVIlvKBjuwlN1tMuWBkCq8W7Gg==" name="csrf-token" /> + <meta content="ac3d26b394d1e74b2cb512f7e309125427b6279a" name="form-nonce" /> + + <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/github-20ef81825cb67c29f98949804b58cf91dbf3de37cb09ccaa59c93970272e0b35.css" media="all" rel="stylesheet" /> + <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/github2-726d0810d308c486e226fbd3d4392b84987fddf613a311c76e816dbaf2461c38.css" media="all" rel="stylesheet" /> + + + + + <meta http-equiv="x-pjax-version" content="e21519a1f589ffb51c1a9b6cfaa2bbfc"> + + + <meta name="description" content="hexcap - ncurses based hex editor for pcap files"> + <meta name="go-import" content="github.com/hexcap/hexcap git https://github.com/hexcap/hexcap.git"> + + <meta content="5732830" name="octolytics-dimension-user_id" /><meta content="hexcap" name="octolytics-dimension-user_login" /><meta content="9747136" name="octolytics-dimension-repository_id" /><meta content="hexcap/hexcap" name="octolytics-dimension-repository_nwo" /><meta content="true" name="octolytics-dimension-repository_public" /><meta content="false" name="octolytics-dimension-repository_is_fork" /><meta content="9747136" name="octolytics-dimension-repository_network_root_id" /><meta content="hexcap/hexcap" name="octolytics-dimension-repository_network_root_nwo" /> + <link href="https://github.com/hexcap/hexcap/commits/master.atom" rel="alternate" title="Recent Commits to hexcap:master" type="application/atom+xml"> + + </head> + + + <body class="logged_in env-production windows vis-public page-blob"> + <a href="#start-of-content" tabindex="1" class="accessibility-aid js-skip-to-content">Skip to content</a> + + + + + + + + <div class="header header-logged-in true" role="banner"> + <div class="container clearfix"> + + <a class="header-logo-invertocat" href="https://github.com/orgs/cisco-system-traffic-generator/dashboard" data-hotkey="g d" aria-label="Homepage" data-ga-click="Header, go to dashboard, icon:logo"> + <span class="mega-octicon octicon-mark-github"></span> +</a> + + + <div class="site-search repo-scope js-site-search" role="search"> + <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/hexcap/hexcap/search" class="js-site-search-form" data-global-search-url="/search" data-repo-search-url="/hexcap/hexcap/search" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /></div> + <label class="js-chromeless-input-container form-control"> + <div class="scope-badge">This repository</div> + <input type="text" + class="js-site-search-focus js-site-search-field is-clearable chromeless-input" + data-hotkey="s" + name="q" + placeholder="Search" + aria-label="Search this repository" + data-global-scope-placeholder="Search GitHub" + data-repo-scope-placeholder="Search" + tabindex="1" + autocapitalize="off"> + </label> +</form> + </div> + + <ul class="header-nav left" role="navigation"> + <li class="header-nav-item"> + <a href="/pulls" class="js-selected-navigation-item header-nav-link" data-ga-click="Header, click, Nav menu - item:pulls context:user" data-hotkey="g p" data-selected-links="/pulls /pulls/assigned /pulls/mentioned /pulls"> + Pull requests +</a> </li> + <li class="header-nav-item"> + <a href="/issues" class="js-selected-navigation-item header-nav-link" data-ga-click="Header, click, Nav menu - item:issues context:user" data-hotkey="g i" data-selected-links="/issues /issues/assigned /issues/mentioned /issues"> + Issues +</a> </li> + <li class="header-nav-item"> + <a class="header-nav-link" href="https://gist.github.com/" data-ga-click="Header, go to gist, text:gist">Gist</a> + </li> + </ul> + + +<ul class="header-nav user-nav right" id="user-links"> + <li class="header-nav-item"> + <span class="js-socket-channel js-updatable-content" + data-channel="notification-changed:danklein10" + data-url="/notifications/header"> + <a href="/notifications" aria-label="You have no unread notifications" class="header-nav-link notification-indicator tooltipped tooltipped-s" data-ga-click="Header, go to notifications, icon:read" data-hotkey="g n"> + <span class="mail-status all-read"></span> + <span class="octicon octicon-bell"></span> +</a> </span> + + </li> + + <li class="header-nav-item dropdown js-menu-container"> + <a class="header-nav-link tooltipped tooltipped-s js-menu-target" href="/new" + aria-label="Create new…" + data-ga-click="Header, create new, icon:add"> + <span class="octicon octicon-plus left"></span> + <span class="dropdown-caret"></span> + </a> + + <div class="dropdown-menu-content js-menu-content"> + <ul class="dropdown-menu dropdown-menu-sw"> + +<a class="dropdown-item" href="/new" data-ga-click="Header, create new repository"> + New repository +</a> + + + <a class="dropdown-item" href="/organizations/new" data-ga-click="Header, create new organization"> + New organization + </a> + + + + <div class="dropdown-divider"></div> + <div class="dropdown-header"> + <span title="hexcap/hexcap">This repository</span> + </div> + <a class="dropdown-item" href="/hexcap/hexcap/issues/new" data-ga-click="Header, create new issue"> + New issue + </a> + + </ul> + </div> + </li> + + <li class="header-nav-item dropdown js-menu-container"> + <a class="header-nav-link name tooltipped tooltipped-s js-menu-target" href="/danklein10" + aria-label="View profile and more" + data-ga-click="Header, show menu, icon:avatar"> + <img alt="@danklein10" class="avatar" height="20" src="https://avatars1.githubusercontent.com/u/6152092?v=3&s=40" width="20" /> + <span class="dropdown-caret"></span> + </a> + + <div class="dropdown-menu-content js-menu-content"> + <div class="dropdown-menu dropdown-menu-sw"> + <div class="dropdown-header header-nav-current-user css-truncate"> + Signed in as <strong class="css-truncate-target">danklein10</strong> + </div> + <div class="dropdown-divider"></div> + + <a class="dropdown-item" href="/danklein10" data-ga-click="Header, go to profile, text:your profile"> + Your profile + </a> + <a class="dropdown-item" href="/stars" data-ga-click="Header, go to starred repos, text:your stars"> + Your stars + </a> + <a class="dropdown-item" href="/explore" data-ga-click="Header, go to explore, text:explore"> + Explore + </a> + <a class="dropdown-item" href="https://help.github.com" data-ga-click="Header, go to help, text:help"> + Help + </a> + <div class="dropdown-divider"></div> + + <a class="dropdown-item" href="/settings/profile" data-ga-click="Header, go to settings, icon:settings"> + Settings + </a> + + <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/logout" class="logout-form" data-form-nonce="ac3d26b394d1e74b2cb512f7e309125427b6279a" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="N8m5Se0EOXw1Ui0v3MX+KEHzjZjgzzddbmLRz+Tv22u2OVzVM6Ztj/KT5sYvuJ3Krimi+7iKMVFWvkrAdu18aQ==" /></div> + <button class="dropdown-item dropdown-signout" data-ga-click="Header, sign out, icon:logout"> + Sign out + </button> +</form> </div> + </div> + </li> +</ul> + + + + </div> +</div> + + + + + + + <div id="start-of-content" class="accessibility-aid"></div> + + <div id="js-flash-container"> +</div> + + + <div itemscope itemtype="http://schema.org/WebPage"> + <div class="pagehead repohead instapaper_ignore readability-menu"> + <div class="container"> + + <div class="clearfix"> + +<ul class="pagehead-actions"> + + <li> + <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/notifications/subscribe" class="js-social-container" data-autosubmit="true" data-form-nonce="ac3d26b394d1e74b2cb512f7e309125427b6279a" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="oH+kDkXDGZ0VSv7TIzO+kQpjN+0KO7kmbf3Ltx0zg8M7XTbRwpsfJQpVrG2t3+0JACcc2FDlXzzNGCHk8MBhIA==" /></div> <input id="repository_id" name="repository_id" type="hidden" value="9747136" /> + + <div class="select-menu js-menu-container js-select-menu"> + <a href="/hexcap/hexcap/subscription" + class="btn btn-sm btn-with-count select-menu-button js-menu-target" role="button" tabindex="0" aria-haspopup="true" + data-ga-click="Repository, click Watch settings, action:blob#show"> + <span class="js-select-button"> + <span class="octicon octicon-eye"></span> + Watch + </span> + </a> + <a class="social-count js-social-count" href="/hexcap/hexcap/watchers"> + 1 + </a> + + <div class="select-menu-modal-holder"> + <div class="select-menu-modal subscription-menu-modal js-menu-content" aria-hidden="true"> + <div class="select-menu-header"> + <span class="select-menu-title">Notifications</span> + <span class="octicon octicon-x js-menu-close" role="button" aria-label="Close"></span> + </div> + + <div class="select-menu-list js-navigation-container" role="menu"> + + <div class="select-menu-item js-navigation-item selected" role="menuitem" tabindex="0"> + <span class="select-menu-item-icon octicon octicon-check"></span> + <div class="select-menu-item-text"> + <input checked="checked" id="do_included" name="do" type="radio" value="included" /> + <span class="select-menu-item-heading">Not watching</span> + <span class="description">Be notified when participating or @mentioned.</span> + <span class="js-select-button-text hidden-select-button-text"> + <span class="octicon octicon-eye"></span> + Watch + </span> + </div> + </div> + + <div class="select-menu-item js-navigation-item " role="menuitem" tabindex="0"> + <span class="select-menu-item-icon octicon octicon octicon-check"></span> + <div class="select-menu-item-text"> + <input id="do_subscribed" name="do" type="radio" value="subscribed" /> + <span class="select-menu-item-heading">Watching</span> + <span class="description">Be notified of all conversations.</span> + <span class="js-select-button-text hidden-select-button-text"> + <span class="octicon octicon-eye"></span> + Unwatch + </span> + </div> + </div> + + <div class="select-menu-item js-navigation-item " role="menuitem" tabindex="0"> + <span class="select-menu-item-icon octicon octicon-check"></span> + <div class="select-menu-item-text"> + <input id="do_ignore" name="do" type="radio" value="ignore" /> + <span class="select-menu-item-heading">Ignoring</span> + <span class="description">Never be notified.</span> + <span class="js-select-button-text hidden-select-button-text"> + <span class="octicon octicon-mute"></span> + Stop ignoring + </span> + </div> + </div> + + </div> + + </div> + </div> + </div> +</form> + </li> + + <li> + + <div class="js-toggler-container js-social-container starring-container "> + + <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/hexcap/hexcap/unstar" class="js-toggler-form starred js-unstar-button" data-form-nonce="ac3d26b394d1e74b2cb512f7e309125427b6279a" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="JgpGes1Y6iXFjyvt8la+hHwYGri9NzgLW6Fm/4Irc/gcJTASeXTPJc4DMFLoiG1jiPAke7zt61iMUnXyibSo/g==" /></div> + <button + class="btn btn-sm btn-with-count js-toggler-target" + aria-label="Unstar this repository" title="Unstar hexcap/hexcap" + data-ga-click="Repository, click unstar button, action:blob#show; text:Unstar"> + <span class="octicon octicon-star"></span> + Unstar + </button> + <a class="social-count js-social-count" href="/hexcap/hexcap/stargazers"> + 9 + </a> +</form> + <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/hexcap/hexcap/star" class="js-toggler-form unstarred js-star-button" data-form-nonce="ac3d26b394d1e74b2cb512f7e309125427b6279a" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="dWxeklRDfQhNmhahVOQuj1ONldm0pP66i9Wgz7xH3GeyuP9g6mXjnP/tSyp4qMR263/J9ch0SGGk5ownYVPsWg==" /></div> + <button + class="btn btn-sm btn-with-count js-toggler-target" + aria-label="Star this repository" title="Star hexcap/hexcap" + data-ga-click="Repository, click star button, action:blob#show; text:Star"> + <span class="octicon octicon-star"></span> + Star + </button> + <a class="social-count js-social-count" href="/hexcap/hexcap/stargazers"> + 9 + </a> +</form> </div> + + </li> + + <li> + <a href="#fork-destination-box" class="btn btn-sm btn-with-count" + title="Fork your own copy of hexcap/hexcap to your account" + aria-label="Fork your own copy of hexcap/hexcap to your account" + rel="facebox" + data-ga-click="Repository, show fork modal, action:blob#show; text:Fork"> + <span class="octicon octicon-repo-forked"></span> + Fork + </a> + <a href="/hexcap/hexcap/network" class="social-count">0</a> + + <div id="fork-destination-box" style="display: none;"> + <h2 class="facebox-header" data-facebox-id="facebox-header">Where should we fork this repository?</h2> + <include-fragment src="" + class="js-fork-select-fragment fork-select-fragment" + data-url="/hexcap/hexcap/fork?fragment=1"> + <img alt="Loading" height="64" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-128.gif" width="64" /> + </include-fragment> + </div> + </li> + +</ul> + + <h1 itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="entry-title public "> + <span class="mega-octicon octicon-repo"></span> + <span class="author"><a href="/hexcap" class="url fn" itemprop="url" rel="author"><span itemprop="title">hexcap</span></a></span><!-- +--><span class="path-divider">/</span><!-- +--><strong><a href="/hexcap/hexcap" data-pjax="#js-repo-pjax-container">hexcap</a></strong> + + <span class="page-context-loader"> + <img alt="" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16" /> + </span> + +</h1> + + </div> + </div> + </div> + + <div class="container"> + <div class="repository-with-sidebar repo-container new-discussion-timeline "> + <div class="repository-sidebar clearfix"> + +<nav class="sunken-menu repo-nav js-repo-nav js-sidenav-container-pjax js-octicon-loaders" + role="navigation" + data-pjax="#js-repo-pjax-container" + data-issue-count-url="/hexcap/hexcap/issues/counts"> + <ul class="sunken-menu-group"> + <li class="tooltipped tooltipped-w" aria-label="Code"> + <a href="/hexcap/hexcap" aria-label="Code" aria-selected="true" class="js-selected-navigation-item selected sunken-menu-item" data-hotkey="g c" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches /hexcap/hexcap"> + <span class="octicon octicon-code"></span> <span class="full-word">Code</span> + <img alt="" class="mini-loader" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16" /> +</a> </li> + + <li class="tooltipped tooltipped-w" aria-label="Issues"> + <a href="/hexcap/hexcap/issues" aria-label="Issues" class="js-selected-navigation-item sunken-menu-item" data-hotkey="g i" data-selected-links="repo_issues repo_labels repo_milestones /hexcap/hexcap/issues"> + <span class="octicon octicon-issue-opened"></span> <span class="full-word">Issues</span> + <span class="js-issue-replace-counter"></span> + <img alt="" class="mini-loader" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16" /> +</a> </li> + + <li class="tooltipped tooltipped-w" aria-label="Pull requests"> + <a href="/hexcap/hexcap/pulls" aria-label="Pull requests" class="js-selected-navigation-item sunken-menu-item" data-hotkey="g p" data-selected-links="repo_pulls /hexcap/hexcap/pulls"> + <span class="octicon octicon-git-pull-request"></span> <span class="full-word">Pull requests</span> + <span class="js-pull-replace-counter"></span> + <img alt="" class="mini-loader" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16" /> +</a> </li> + + <li class="tooltipped tooltipped-w" aria-label="Wiki"> + <a href="/hexcap/hexcap/wiki" aria-label="Wiki" class="js-selected-navigation-item sunken-menu-item" data-hotkey="g w" data-selected-links="repo_wiki /hexcap/hexcap/wiki"> + <span class="octicon octicon-book"></span> <span class="full-word">Wiki</span> + <img alt="" class="mini-loader" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16" /> +</a> </li> + </ul> + <div class="sunken-menu-separator"></div> + <ul class="sunken-menu-group"> + + <li class="tooltipped tooltipped-w" aria-label="Pulse"> + <a href="/hexcap/hexcap/pulse" aria-label="Pulse" class="js-selected-navigation-item sunken-menu-item" data-selected-links="pulse /hexcap/hexcap/pulse"> + <span class="octicon octicon-pulse"></span> <span class="full-word">Pulse</span> + <img alt="" class="mini-loader" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16" /> +</a> </li> + + <li class="tooltipped tooltipped-w" aria-label="Graphs"> + <a href="/hexcap/hexcap/graphs" aria-label="Graphs" class="js-selected-navigation-item sunken-menu-item" data-selected-links="repo_graphs repo_contributors /hexcap/hexcap/graphs"> + <span class="octicon octicon-graph"></span> <span class="full-word">Graphs</span> + <img alt="" class="mini-loader" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16" /> +</a> </li> + </ul> + + +</nav> + + <div class="only-with-full-nav"> + +<div class="js-clone-url clone-url open" + data-protocol-type="http"> + <h3><span class="text-emphasized">HTTPS</span> clone URL</h3> + <div class="input-group js-zeroclipboard-container"> + <input type="text" class="input-mini input-monospace js-url-field js-zeroclipboard-target" + value="https://github.com/hexcap/hexcap.git" readonly="readonly" aria-label="HTTPS clone URL"> + <span class="input-group-button"> + <button aria-label="Copy to clipboard" class="js-zeroclipboard btn btn-sm zeroclipboard-button tooltipped tooltipped-s" data-copied-hint="Copied!" type="button"><span class="octicon octicon-clippy"></span></button> + </span> + </div> +</div> + + +<div class="js-clone-url clone-url " + data-protocol-type="ssh"> + <h3><span class="text-emphasized">SSH</span> clone URL</h3> + <div class="input-group js-zeroclipboard-container"> + <input type="text" class="input-mini input-monospace js-url-field js-zeroclipboard-target" + value="git@github.com:hexcap/hexcap.git" readonly="readonly" aria-label="SSH clone URL"> + <span class="input-group-button"> + <button aria-label="Copy to clipboard" class="js-zeroclipboard btn btn-sm zeroclipboard-button tooltipped tooltipped-s" data-copied-hint="Copied!" type="button"><span class="octicon octicon-clippy"></span></button> + </span> + </div> +</div> + + +<div class="js-clone-url clone-url " + data-protocol-type="subversion"> + <h3><span class="text-emphasized">Subversion</span> checkout URL</h3> + <div class="input-group js-zeroclipboard-container"> + <input type="text" class="input-mini input-monospace js-url-field js-zeroclipboard-target" + value="https://github.com/hexcap/hexcap" readonly="readonly" aria-label="Subversion checkout URL"> + <span class="input-group-button"> + <button aria-label="Copy to clipboard" class="js-zeroclipboard btn btn-sm zeroclipboard-button tooltipped tooltipped-s" data-copied-hint="Copied!" type="button"><span class="octicon octicon-clippy"></span></button> + </span> + </div> +</div> + + + + <div class="clone-options">You can clone with + <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/users/set_protocol?protocol_selector=http&protocol_type=clone" class="inline-form js-clone-selector-form is-enabled" data-form-nonce="ac3d26b394d1e74b2cb512f7e309125427b6279a" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="T3BePf/8xkb6d6hQ1WxSRPwxd0cVHJD04Qcvw7XDgDf2KRpWMc1KDQXjof8YNA9SMwlC0J+/rLdH0uf+d3FtGw==" /></div><button class="btn-link js-clone-selector" data-protocol="http" type="submit">HTTPS</button></form>, <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/users/set_protocol?protocol_selector=ssh&protocol_type=clone" class="inline-form js-clone-selector-form is-enabled" data-form-nonce="ac3d26b394d1e74b2cb512f7e309125427b6279a" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="3ZZHZ1uyO2YyXJllsAEy6Uyl5IzKd9pnlMqcxOr6siiIUSr9yHihssjv9CD7IZ6VhlEbKvHuVODR80DN4nF2MQ==" /></div><button class="btn-link js-clone-selector" data-protocol="ssh" type="submit">SSH</button></form>, or <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/users/set_protocol?protocol_selector=subversion&protocol_type=clone" class="inline-form js-clone-selector-form is-enabled" data-form-nonce="ac3d26b394d1e74b2cb512f7e309125427b6279a" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="kwiF8pqkQsMfxWxA65L8G9PRBro/xPHPAN3GTPg9dbRP/w7eUuTJu4tyT6Kxk2iP8bRpg53eQ+KYY8UiaGq19A==" /></div><button class="btn-link js-clone-selector" data-protocol="subversion" type="submit">Subversion</button></form>. + <a href="https://help.github.com/articles/which-remote-url-should-i-use" class="help tooltipped tooltipped-n" aria-label="Get help on which URL is right for you."> + <span class="octicon octicon-question"></span> + </a> + </div> + <a href="https://windows.github.com" class="btn btn-sm sidebar-button" title="Save hexcap/hexcap to your computer and use it in GitHub Desktop." aria-label="Save hexcap/hexcap to your computer and use it in GitHub Desktop."> + <span class="octicon octicon-desktop-download"></span> + Clone in Desktop + </a> + + <a href="/hexcap/hexcap/archive/master.zip" + class="btn btn-sm sidebar-button" + aria-label="Download the contents of hexcap/hexcap as a zip file" + title="Download the contents of hexcap/hexcap as a zip file" + rel="nofollow"> + <span class="octicon octicon-cloud-download"></span> + Download ZIP + </a> + </div> + </div> + <div id="js-repo-pjax-container" class="repository-content context-loader-container" data-pjax-container> + + + +<a href="/hexcap/hexcap/blob/ee8686e7c7a4cc4a1d836895fda01012fb930251/dpkt/dpkt/dot1q.py" class="hidden js-permalink-shortcut" data-hotkey="y">Permalink</a> + +<!-- blob contrib key: blob_contributors:v21:46bde8b0229c416e6f538e044b428839 --> + + <div class="file-navigation js-zeroclipboard-container"> + +<div class="select-menu js-menu-container js-select-menu left"> + <span class="btn btn-sm select-menu-button js-menu-target css-truncate" data-hotkey="w" + data-ref="master" + title="master" + role="button" aria-label="Switch branches or tags" tabindex="0" aria-haspopup="true"> + <i>Branch:</i> + <span class="js-select-button css-truncate-target">master</span> + </span> + + <div class="select-menu-modal-holder js-menu-content js-navigation-container" data-pjax aria-hidden="true"> + + <div class="select-menu-modal"> + <div class="select-menu-header"> + <span class="select-menu-title">Switch branches/tags</span> + <span class="octicon octicon-x js-menu-close" role="button" aria-label="Close"></span> + </div> + + <div class="select-menu-filters"> + <div class="select-menu-text-filter"> + <input type="text" aria-label="Filter branches/tags" id="context-commitish-filter-field" class="js-filterable-field js-navigation-enable" placeholder="Filter branches/tags"> + </div> + <div class="select-menu-tabs"> + <ul> + <li class="select-menu-tab"> + <a href="#" data-tab-filter="branches" data-filter-placeholder="Filter branches/tags" class="js-select-menu-tab" role="tab">Branches</a> + </li> + <li class="select-menu-tab"> + <a href="#" data-tab-filter="tags" data-filter-placeholder="Find a tag…" class="js-select-menu-tab" role="tab">Tags</a> + </li> + </ul> + </div> + </div> + + <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="branches" role="menu"> + + <div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring"> + + + <a class="select-menu-item js-navigation-item js-navigation-open selected" + href="/hexcap/hexcap/blob/master/dpkt/dpkt/dot1q.py" + data-name="master" + data-skip-pjax="true" + rel="nofollow"> + <span class="select-menu-item-icon octicon octicon-check"></span> + <span class="select-menu-item-text css-truncate-target" title="master"> + master + </span> + </a> + </div> + + <div class="select-menu-no-results">Nothing to show</div> + </div> + + <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="tags"> + <div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring"> + + + </div> + + <div class="select-menu-no-results">Nothing to show</div> + </div> + + </div> + </div> +</div> + + <div class="btn-group right"> + <a href="/hexcap/hexcap/find/master" + class="js-show-file-finder btn btn-sm empty-icon tooltipped tooltipped-nw" + data-pjax + data-hotkey="t" + aria-label="Quickly jump between files"> + <span class="octicon octicon-list-unordered"></span> + </a> + <button aria-label="Copy file path to clipboard" class="js-zeroclipboard btn btn-sm zeroclipboard-button tooltipped tooltipped-s" data-copied-hint="Copied!" type="button"><span class="octicon octicon-clippy"></span></button> + </div> + + <div class="breadcrumb js-zeroclipboard-target"> + <span class="repo-root js-repo-root"><span itemscope="" itemtype="http://data-vocabulary.org/Breadcrumb"><a href="/hexcap/hexcap" class="" data-branch="master" data-pjax="true" itemscope="url"><span itemprop="title">hexcap</span></a></span></span><span class="separator">/</span><span itemscope="" itemtype="http://data-vocabulary.org/Breadcrumb"><a href="/hexcap/hexcap/tree/master/dpkt" class="" data-branch="master" data-pjax="true" itemscope="url"><span itemprop="title">dpkt</span></a></span><span class="separator">/</span><span itemscope="" itemtype="http://data-vocabulary.org/Breadcrumb"><a href="/hexcap/hexcap/tree/master/dpkt/dpkt" class="" data-branch="master" data-pjax="true" itemscope="url"><span itemprop="title">dpkt</span></a></span><span class="separator">/</span><strong class="final-path">dot1q.py</strong> + </div> + </div> + + + <div class="commit file-history-tease"> + <div class="file-history-tease-header"> + <img alt="@smutt" class="avatar" height="24" src="https://avatars3.githubusercontent.com/u/1223204?v=3&s=48" width="24" /> + <span class="author"><a href="/smutt" rel="contributor">smutt</a></span> + <time datetime="2014-06-11T23:12:09Z" is="relative-time">Jun 11, 2014</time> + <div class="commit-title"> + <a href="/hexcap/hexcap/commit/1e35c451e857e98e9a572700f88b89e3847e53aa" class="message" data-pjax="true" title="Renamed dpkt-read-only/ to dpkt/">Renamed dpkt-read-only/ to dpkt/</a> + </div> + </div> + + <div class="participation"> + <p class="quickstat"> + <a href="#blob_contributors_box" rel="facebox"> + <strong>1</strong> + contributor + </a> + </p> + + </div> + <div id="blob_contributors_box" style="display:none"> + <h2 class="facebox-header" data-facebox-id="facebox-header">Users who have contributed to this file</h2> + <ul class="facebox-user-list" data-facebox-id="facebox-description"> + <li class="facebox-user-list-item"> + <img alt="@smutt" height="24" src="https://avatars3.githubusercontent.com/u/1223204?v=3&s=48" width="24" /> + <a href="/smutt">smutt</a> + </li> + </ul> + </div> + </div> + +<div class="file"> + <div class="file-header"> + <div class="file-actions"> + + <div class="btn-group"> + <a href="/hexcap/hexcap/raw/master/dpkt/dpkt/dot1q.py" class="btn btn-sm " id="raw-url">Raw</a> + <a href="/hexcap/hexcap/blame/master/dpkt/dpkt/dot1q.py" class="btn btn-sm js-update-url-with-hash">Blame</a> + <a href="/hexcap/hexcap/commits/master/dpkt/dpkt/dot1q.py" class="btn btn-sm " rel="nofollow">History</a> + </div> + + <a class="octicon-btn tooltipped tooltipped-nw" + href="https://windows.github.com" + aria-label="Open this file in GitHub Desktop" + data-ga-click="Repository, open with desktop, type:windows"> + <span class="octicon octicon-device-desktop"></span> + </a> + + <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/hexcap/hexcap/edit/master/dpkt/dpkt/dot1q.py" class="inline-form" data-form-nonce="ac3d26b394d1e74b2cb512f7e309125427b6279a" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="SU0n03ayv7838ksqISz81DL+rsSEUTJ8VWf2X1NBBMo9p5gPaM9YXCNa6Sezt7xjvJJLjZP1eBMl7fduX9rrpw==" /></div> + <button class="octicon-btn tooltipped tooltipped-n" type="submit" aria-label="Fork this project and edit the file" data-hotkey="e" data-disable-with> + <span class="octicon octicon-pencil"></span> + </button> +</form> + <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/hexcap/hexcap/delete/master/dpkt/dpkt/dot1q.py" class="inline-form" data-form-nonce="ac3d26b394d1e74b2cb512f7e309125427b6279a" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="e3j1i6vBsJAzzNVXfe8zggdfxap3rh2bJPDs6A9KfsXTcxVc8/fqgnyjGgf61qd9qj5NUp6K+wZ7/IU756EzQA==" /></div> + <button class="octicon-btn octicon-btn-danger tooltipped tooltipped-n" type="submit" aria-label="Fork this project and delete this file" data-disable-with> + <span class="octicon octicon-trashcan"></span> + </button> +</form> </div> + + <div class="file-info"> + <span class="file-mode" title="File mode">executable file</span> + <span class="file-info-divider"></span> + 93 lines (79 sloc) + <span class="file-info-divider"></span> + 3.071 kB + </div> + </div> + + + <div class="blob-wrapper data type-python"> + <table class="highlight tab-size js-file-line-container" data-tab-size="8"> + <tr> + <td id="L1" class="blob-num js-line-number" data-line-number="1"></td> + <td id="LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-s"><span class="pl-pds">"""</span>IEEE 802.1q<span class="pl-pds">"""</span></span></td> + </tr> + <tr> + <td id="L2" class="blob-num js-line-number" data-line-number="2"></td> + <td id="LC2" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L3" class="blob-num js-line-number" data-line-number="3"></td> + <td id="LC3" class="blob-code blob-code-inner js-file-line"><span class="pl-k">import</span> struct</td> + </tr> + <tr> + <td id="L4" class="blob-num js-line-number" data-line-number="4"></td> + <td id="LC4" class="blob-code blob-code-inner js-file-line"><span class="pl-k">import</span> dpkt</td> + </tr> + <tr> + <td id="L5" class="blob-num js-line-number" data-line-number="5"></td> + <td id="LC5" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L6" class="blob-num js-line-number" data-line-number="6"></td> + <td id="LC6" class="blob-code blob-code-inner js-file-line"><span class="pl-c"># Ethernet payload types - http://standards.ieee.org/regauth/ethertype</span></td> + </tr> + <tr> + <td id="L7" class="blob-num js-line-number" data-line-number="7"></td> + <td id="LC7" class="blob-code blob-code-inner js-file-line">ETH_TYPE_PUP <span class="pl-k">=</span> <span class="pl-c1">0x</span>0200 <span class="pl-c"># PUP protocol</span></td> + </tr> + <tr> + <td id="L8" class="blob-num js-line-number" data-line-number="8"></td> + <td id="LC8" class="blob-code blob-code-inner js-file-line">ETH_TYPE_IP <span class="pl-k">=</span> <span class="pl-c1">0x</span>0800 <span class="pl-c"># IP protocol</span></td> + </tr> + <tr> + <td id="L9" class="blob-num js-line-number" data-line-number="9"></td> + <td id="LC9" class="blob-code blob-code-inner js-file-line">ETH_TYPE_ARP <span class="pl-k">=</span> <span class="pl-c1">0x</span>0806 <span class="pl-c"># address resolution protocol</span></td> + </tr> + <tr> + <td id="L10" class="blob-num js-line-number" data-line-number="10"></td> + <td id="LC10" class="blob-code blob-code-inner js-file-line">ETH_TYPE_CDP <span class="pl-k">=</span> <span class="pl-c1">0x</span>2000 <span class="pl-c"># Cisco Discovery Protocol</span></td> + </tr> + <tr> + <td id="L11" class="blob-num js-line-number" data-line-number="11"></td> + <td id="LC11" class="blob-code blob-code-inner js-file-line">ETH_TYPE_DTP <span class="pl-k">=</span> <span class="pl-c1">0x</span>2004 <span class="pl-c"># Cisco Dynamic Trunking Protocol</span></td> + </tr> + <tr> + <td id="L12" class="blob-num js-line-number" data-line-number="12"></td> + <td id="LC12" class="blob-code blob-code-inner js-file-line">ETH_TYPE_REVARP <span class="pl-k">=</span> <span class="pl-c1">0x</span>8035 <span class="pl-c"># reverse addr resolution protocol</span></td> + </tr> + <tr> + <td id="L13" class="blob-num js-line-number" data-line-number="13"></td> + <td id="LC13" class="blob-code blob-code-inner js-file-line">ETH_TYPE_DOT1Q <span class="pl-k">=</span> <span class="pl-c1">0x</span>8100 <span class="pl-c"># IEEE 802.1Q VLAN tagging</span></td> + </tr> + <tr> + <td id="L14" class="blob-num js-line-number" data-line-number="14"></td> + <td id="LC14" class="blob-code blob-code-inner js-file-line">ETH_TYPE_IPX <span class="pl-k">=</span> <span class="pl-c1">0x</span>8137 <span class="pl-c"># Internetwork Packet Exchange</span></td> + </tr> + <tr> + <td id="L15" class="blob-num js-line-number" data-line-number="15"></td> + <td id="LC15" class="blob-code blob-code-inner js-file-line">ETH_TYPE_IP6 <span class="pl-k">=</span> <span class="pl-c1">0x</span>86DD <span class="pl-c"># IPv6 protocol</span></td> + </tr> + <tr> + <td id="L16" class="blob-num js-line-number" data-line-number="16"></td> + <td id="LC16" class="blob-code blob-code-inner js-file-line">ETH_TYPE_PPP <span class="pl-k">=</span> <span class="pl-c1">0x</span>880B <span class="pl-c"># PPP</span></td> + </tr> + <tr> + <td id="L17" class="blob-num js-line-number" data-line-number="17"></td> + <td id="LC17" class="blob-code blob-code-inner js-file-line">ETH_TYPE_MPLS <span class="pl-k">=</span> <span class="pl-c1">0x</span>8847 <span class="pl-c"># MPLS</span></td> + </tr> + <tr> + <td id="L18" class="blob-num js-line-number" data-line-number="18"></td> + <td id="LC18" class="blob-code blob-code-inner js-file-line">ETH_TYPE_MPLS_MCAST <span class="pl-k">=</span> <span class="pl-c1">0x</span>8848 <span class="pl-c"># MPLS Multicast</span></td> + </tr> + <tr> + <td id="L19" class="blob-num js-line-number" data-line-number="19"></td> + <td id="LC19" class="blob-code blob-code-inner js-file-line">ETH_TYPE_PPPoE_DISC <span class="pl-k">=</span> <span class="pl-c1">0x</span>8863 <span class="pl-c"># PPP Over Ethernet Discovery Stage</span></td> + </tr> + <tr> + <td id="L20" class="blob-num js-line-number" data-line-number="20"></td> + <td id="LC20" class="blob-code blob-code-inner js-file-line">ETH_TYPE_PPPoE <span class="pl-k">=</span> <span class="pl-c1">0x</span>8864 <span class="pl-c"># PPP Over Ethernet Session Stage</span></td> + </tr> + <tr> + <td id="L21" class="blob-num js-line-number" data-line-number="21"></td> + <td id="LC21" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L22" class="blob-num js-line-number" data-line-number="22"></td> + <td id="LC22" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-en">DOT1Q</span>(<span class="pl-e">dpkt.Packet</span>):</td> + </tr> + <tr> + <td id="L23" class="blob-num js-line-number" data-line-number="23"></td> + <td id="LC23" class="blob-code blob-code-inner js-file-line"> __hdr__ <span class="pl-k">=</span> (</td> + </tr> + <tr> + <td id="L24" class="blob-num js-line-number" data-line-number="24"></td> + <td id="LC24" class="blob-code blob-code-inner js-file-line"> (<span class="pl-s"><span class="pl-pds">'</span>x2<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>H<span class="pl-pds">'</span></span>, <span class="pl-c1">0</span>),</td> + </tr> + <tr> + <td id="L25" class="blob-num js-line-number" data-line-number="25"></td> + <td id="LC25" class="blob-code blob-code-inner js-file-line"> (<span class="pl-s"><span class="pl-pds">'</span>type<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>H<span class="pl-pds">'</span></span>, <span class="pl-c1">0</span>)</td> + </tr> + <tr> + <td id="L26" class="blob-num js-line-number" data-line-number="26"></td> + <td id="LC26" class="blob-code blob-code-inner js-file-line"> )</td> + </tr> + <tr> + <td id="L27" class="blob-num js-line-number" data-line-number="27"></td> + <td id="LC27" class="blob-code blob-code-inner js-file-line"> _typesw <span class="pl-k">=</span> {}</td> + </tr> + <tr> + <td id="L28" class="blob-num js-line-number" data-line-number="28"></td> + <td id="LC28" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L29" class="blob-num js-line-number" data-line-number="29"></td> + <td id="LC29" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"># pcp == Priority Code Point(802.1p)</span></td> + </tr> + <tr> + <td id="L30" class="blob-num js-line-number" data-line-number="30"></td> + <td id="LC30" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">def</span> <span class="pl-en">_get_pcp</span>(<span class="pl-smi">self</span>): <span class="pl-k">return</span> <span class="pl-v">self</span>.x2 <span class="pl-k">>></span> <span class="pl-c1">13</span></td> + </tr> + <tr> + <td id="L31" class="blob-num js-line-number" data-line-number="31"></td> + <td id="LC31" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">def</span> <span class="pl-en">_set_pcp</span>(<span class="pl-smi">self</span>, <span class="pl-smi">pcp</span>): <span class="pl-v">self</span>.x2 <span class="pl-k">=</span> (<span class="pl-v">self</span>.x2 <span class="pl-k">&</span> <span class="pl-c1">0x</span>1fff) <span class="pl-k">|</span> (pcp <span class="pl-k"><<</span> <span class="pl-c1">13</span>)</td> + </tr> + <tr> + <td id="L32" class="blob-num js-line-number" data-line-number="32"></td> + <td id="LC32" class="blob-code blob-code-inner js-file-line"> pcp <span class="pl-k">=</span> <span class="pl-c1">property</span>(_get_pcp, _set_pcp)</td> + </tr> + <tr> + <td id="L33" class="blob-num js-line-number" data-line-number="33"></td> + <td id="LC33" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L34" class="blob-num js-line-number" data-line-number="34"></td> + <td id="LC34" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"># dei == Drop Eligible Indicator(almost never actually used)</span></td> + </tr> + <tr> + <td id="L35" class="blob-num js-line-number" data-line-number="35"></td> + <td id="LC35" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">def</span> <span class="pl-en">_get_dei</span>(<span class="pl-smi">self</span>): <span class="pl-k">return</span> (<span class="pl-v">self</span>.x2 <span class="pl-k">>></span> <span class="pl-c1">12</span>) <span class="pl-k">&</span> <span class="pl-c1">1</span> </td> + </tr> + <tr> + <td id="L36" class="blob-num js-line-number" data-line-number="36"></td> + <td id="LC36" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">def</span> <span class="pl-en">_set_dei</span>(<span class="pl-smi">self</span>, <span class="pl-smi">dei</span>): <span class="pl-v">self</span>.x2 <span class="pl-k">=</span> (<span class="pl-v">self</span>.x2 <span class="pl-k">&</span> <span class="pl-c1">61439</span>) <span class="pl-k">|</span> (dei <span class="pl-k"><<</span> <span class="pl-c1">12</span>)</td> + </tr> + <tr> + <td id="L37" class="blob-num js-line-number" data-line-number="37"></td> + <td id="LC37" class="blob-code blob-code-inner js-file-line"> dei <span class="pl-k">=</span> <span class="pl-c1">property</span>(_get_dei, _set_dei)</td> + </tr> + <tr> + <td id="L38" class="blob-num js-line-number" data-line-number="38"></td> + <td id="LC38" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L39" class="blob-num js-line-number" data-line-number="39"></td> + <td id="LC39" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"># tag == vlan tag</span></td> + </tr> + <tr> + <td id="L40" class="blob-num js-line-number" data-line-number="40"></td> + <td id="LC40" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">def</span> <span class="pl-en">_get_tag</span>(<span class="pl-smi">self</span>): <span class="pl-k">return</span> <span class="pl-v">self</span>.x2 <span class="pl-k">&</span> (<span class="pl-c1">65535</span> <span class="pl-k">>></span> <span class="pl-c1">4</span>)</td> + </tr> + <tr> + <td id="L41" class="blob-num js-line-number" data-line-number="41"></td> + <td id="LC41" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">def</span> <span class="pl-en">_set_tag</span>(<span class="pl-smi">self</span>, <span class="pl-smi">tag</span>): <span class="pl-v">self</span>.x2 <span class="pl-k">=</span> (<span class="pl-v">self</span>.x2 <span class="pl-k">&</span> <span class="pl-c1">0x</span>fff) <span class="pl-k">|</span> tag</td> + </tr> + <tr> + <td id="L42" class="blob-num js-line-number" data-line-number="42"></td> + <td id="LC42" class="blob-code blob-code-inner js-file-line"> tag <span class="pl-k">=</span> <span class="pl-c1">property</span>(_get_tag, _set_tag)</td> + </tr> + <tr> + <td id="L43" class="blob-num js-line-number" data-line-number="43"></td> + <td id="LC43" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L44" class="blob-num js-line-number" data-line-number="44"></td> + <td id="LC44" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">def</span> <span class="pl-en">set_type</span>(<span class="pl-smi">cls</span>, <span class="pl-smi">t</span>, <span class="pl-smi">pktclass</span>):</td> + </tr> + <tr> + <td id="L45" class="blob-num js-line-number" data-line-number="45"></td> + <td id="LC45" class="blob-code blob-code-inner js-file-line"> <span class="pl-v">cls</span>._typesw[t] <span class="pl-k">=</span> pktclass</td> + </tr> + <tr> + <td id="L46" class="blob-num js-line-number" data-line-number="46"></td> + <td id="LC46" class="blob-code blob-code-inner js-file-line"> set_type <span class="pl-k">=</span> <span class="pl-c1">classmethod</span>(set_type)</td> + </tr> + <tr> + <td id="L47" class="blob-num js-line-number" data-line-number="47"></td> + <td id="LC47" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L48" class="blob-num js-line-number" data-line-number="48"></td> + <td id="LC48" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">def</span> <span class="pl-en">get_type</span>(<span class="pl-smi">cls</span>, <span class="pl-smi">t</span>):</td> + </tr> + <tr> + <td id="L49" class="blob-num js-line-number" data-line-number="49"></td> + <td id="LC49" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">return</span> <span class="pl-v">cls</span>._typesw[t]</td> + </tr> + <tr> + <td id="L50" class="blob-num js-line-number" data-line-number="50"></td> + <td id="LC50" class="blob-code blob-code-inner js-file-line"> get_type <span class="pl-k">=</span> <span class="pl-c1">classmethod</span>(get_type)</td> + </tr> + <tr> + <td id="L51" class="blob-num js-line-number" data-line-number="51"></td> + <td id="LC51" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L52" class="blob-num js-line-number" data-line-number="52"></td> + <td id="LC52" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">def</span> <span class="pl-en">_unpack_data</span>(<span class="pl-smi">self</span>, <span class="pl-smi">buf</span>):</td> + </tr> + <tr> + <td id="L53" class="blob-num js-line-number" data-line-number="53"></td> + <td id="LC53" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> <span class="pl-v">self</span>.type <span class="pl-k">==</span> ETH_TYPE_MPLS <span class="pl-k">or</span> \</td> + </tr> + <tr> + <td id="L54" class="blob-num js-line-number" data-line-number="54"></td> + <td id="LC54" class="blob-code blob-code-inner js-file-line"> <span class="pl-v">self</span>.type <span class="pl-k">==</span> ETH_TYPE_MPLS_MCAST:</td> + </tr> + <tr> + <td id="L55" class="blob-num js-line-number" data-line-number="55"></td> + <td id="LC55" class="blob-code blob-code-inner js-file-line"> <span class="pl-c"># XXX - skip labels (max # of labels is undefined, just use 24)</span></td> + </tr> + <tr> + <td id="L56" class="blob-num js-line-number" data-line-number="56"></td> + <td id="LC56" class="blob-code blob-code-inner js-file-line"> <span class="pl-v">self</span>.labels <span class="pl-k">=</span> []</td> + </tr> + <tr> + <td id="L57" class="blob-num js-line-number" data-line-number="57"></td> + <td id="LC57" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">for</span> i <span class="pl-k">in</span> <span class="pl-c1">range</span>(<span class="pl-c1">24</span>):</td> + </tr> + <tr> + <td id="L58" class="blob-num js-line-number" data-line-number="58"></td> + <td id="LC58" class="blob-code blob-code-inner js-file-line"> entry <span class="pl-k">=</span> struct.unpack(<span class="pl-s"><span class="pl-pds">'</span>>I<span class="pl-pds">'</span></span>, buf[i<span class="pl-k">*</span><span class="pl-c1">4</span>:i<span class="pl-k">*</span><span class="pl-c1">4</span><span class="pl-k">+</span><span class="pl-c1">4</span>])[<span class="pl-c1">0</span>]</td> + </tr> + <tr> + <td id="L59" class="blob-num js-line-number" data-line-number="59"></td> + <td id="LC59" class="blob-code blob-code-inner js-file-line"> label <span class="pl-k">=</span> ((entry <span class="pl-k">&</span> MPLS_LABEL_MASK) <span class="pl-k">>></span> MPLS_LABEL_SHIFT, \</td> + </tr> + <tr> + <td id="L60" class="blob-num js-line-number" data-line-number="60"></td> + <td id="LC60" class="blob-code blob-code-inner js-file-line"> (entry <span class="pl-k">&</span> MPLS_QOS_MASK) <span class="pl-k">>></span> MPLS_QOS_SHIFT, \</td> + </tr> + <tr> + <td id="L61" class="blob-num js-line-number" data-line-number="61"></td> + <td id="LC61" class="blob-code blob-code-inner js-file-line"> (entry <span class="pl-k">&</span> MPLS_TTL_MASK) <span class="pl-k">>></span> MPLS_TTL_SHIFT)</td> + </tr> + <tr> + <td id="L62" class="blob-num js-line-number" data-line-number="62"></td> + <td id="LC62" class="blob-code blob-code-inner js-file-line"> <span class="pl-v">self</span>.labels.append(label)</td> + </tr> + <tr> + <td id="L63" class="blob-num js-line-number" data-line-number="63"></td> + <td id="LC63" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> entry <span class="pl-k">&</span> MPLS_STACK_BOTTOM:</td> + </tr> + <tr> + <td id="L64" class="blob-num js-line-number" data-line-number="64"></td> + <td id="LC64" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">break</span></td> + </tr> + <tr> + <td id="L65" class="blob-num js-line-number" data-line-number="65"></td> + <td id="LC65" class="blob-code blob-code-inner js-file-line"> <span class="pl-v">self</span>.type <span class="pl-k">=</span> ETH_TYPE_IP</td> + </tr> + <tr> + <td id="L66" class="blob-num js-line-number" data-line-number="66"></td> + <td id="LC66" class="blob-code blob-code-inner js-file-line"> buf <span class="pl-k">=</span> buf[(i <span class="pl-k">+</span> <span class="pl-c1">1</span>) <span class="pl-k">*</span> <span class="pl-c1">4</span>:]</td> + </tr> + <tr> + <td id="L67" class="blob-num js-line-number" data-line-number="67"></td> + <td id="LC67" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">try</span>:</td> + </tr> + <tr> + <td id="L68" class="blob-num js-line-number" data-line-number="68"></td> + <td id="LC68" class="blob-code blob-code-inner js-file-line"> <span class="pl-v">self</span>.data <span class="pl-k">=</span> <span class="pl-v">self</span>._typesw[<span class="pl-v">self</span>.type](buf)</td> + </tr> + <tr> + <td id="L69" class="blob-num js-line-number" data-line-number="69"></td> + <td id="LC69" class="blob-code blob-code-inner js-file-line"> <span class="pl-c1">setattr</span>(<span class="pl-v">self</span>, <span class="pl-v">self</span>.data.<span class="pl-c1">__class__</span>.<span class="pl-c1">__name__</span>.lower(), <span class="pl-v">self</span>.data)</td> + </tr> + <tr> + <td id="L70" class="blob-num js-line-number" data-line-number="70"></td> + <td id="LC70" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">except</span> (<span class="pl-c1">KeyError</span>, dpkt.UnpackError):</td> + </tr> + <tr> + <td id="L71" class="blob-num js-line-number" data-line-number="71"></td> + <td id="LC71" class="blob-code blob-code-inner js-file-line"> <span class="pl-v">self</span>.data <span class="pl-k">=</span> buf</td> + </tr> + <tr> + <td id="L72" class="blob-num js-line-number" data-line-number="72"></td> + <td id="LC72" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L73" class="blob-num js-line-number" data-line-number="73"></td> + <td id="LC73" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">def</span> <span class="pl-en">unpack</span>(<span class="pl-smi">self</span>, <span class="pl-smi">buf</span>):</td> + </tr> + <tr> + <td id="L74" class="blob-num js-line-number" data-line-number="74"></td> + <td id="LC74" class="blob-code blob-code-inner js-file-line"> dpkt.Packet.unpack(<span class="pl-v">self</span>, buf)</td> + </tr> + <tr> + <td id="L75" class="blob-num js-line-number" data-line-number="75"></td> + <td id="LC75" class="blob-code blob-code-inner js-file-line"> <span class="pl-v">self</span>._unpack_data(<span class="pl-v">self</span>.data)</td> + </tr> + <tr> + <td id="L76" class="blob-num js-line-number" data-line-number="76"></td> + <td id="LC76" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L77" class="blob-num js-line-number" data-line-number="77"></td> + <td id="LC77" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L78" class="blob-num js-line-number" data-line-number="78"></td> + <td id="LC78" class="blob-code blob-code-inner js-file-line"><span class="pl-c"># XXX - auto-load Ethernet dispatch table from ETH_TYPE_* definitions</span></td> + </tr> + <tr> + <td id="L79" class="blob-num js-line-number" data-line-number="79"></td> + <td id="LC79" class="blob-code blob-code-inner js-file-line"><span class="pl-k">def</span> <span class="pl-en">__load_types</span>():</td> + </tr> + <tr> + <td id="L80" class="blob-num js-line-number" data-line-number="80"></td> + <td id="LC80" class="blob-code blob-code-inner js-file-line"> g <span class="pl-k">=</span> <span class="pl-c1">globals</span>()</td> + </tr> + <tr> + <td id="L81" class="blob-num js-line-number" data-line-number="81"></td> + <td id="LC81" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">for</span> k, v <span class="pl-k">in</span> g.iteritems():</td> + </tr> + <tr> + <td id="L82" class="blob-num js-line-number" data-line-number="82"></td> + <td id="LC82" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">if</span> k.startswith(<span class="pl-s"><span class="pl-pds">'</span>ETH_TYPE_<span class="pl-pds">'</span></span>):</td> + </tr> + <tr> + <td id="L83" class="blob-num js-line-number" data-line-number="83"></td> + <td id="LC83" class="blob-code blob-code-inner js-file-line"> name <span class="pl-k">=</span> k[<span class="pl-c1">9</span>:]</td> + </tr> + <tr> + <td id="L84" class="blob-num js-line-number" data-line-number="84"></td> + <td id="LC84" class="blob-code blob-code-inner js-file-line"> modname <span class="pl-k">=</span> name.lower()</td> + </tr> + <tr> + <td id="L85" class="blob-num js-line-number" data-line-number="85"></td> + <td id="LC85" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">try</span>:</td> + </tr> + <tr> + <td id="L86" class="blob-num js-line-number" data-line-number="86"></td> + <td id="LC86" class="blob-code blob-code-inner js-file-line"> mod <span class="pl-k">=</span> <span class="pl-c1">__import__</span>(modname, g)</td> + </tr> + <tr> + <td id="L87" class="blob-num js-line-number" data-line-number="87"></td> + <td id="LC87" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">except</span> <span class="pl-c1">ImportError</span>:</td> + </tr> + <tr> + <td id="L88" class="blob-num js-line-number" data-line-number="88"></td> + <td id="LC88" class="blob-code blob-code-inner js-file-line"> <span class="pl-k">continue</span></td> + </tr> + <tr> + <td id="L89" class="blob-num js-line-number" data-line-number="89"></td> + <td id="LC89" class="blob-code blob-code-inner js-file-line"> DOT1Q.set_type(v, <span class="pl-c1">getattr</span>(mod, name))</td> + </tr> + <tr> + <td id="L90" class="blob-num js-line-number" data-line-number="90"></td> + <td id="LC90" class="blob-code blob-code-inner js-file-line"> +</td> + </tr> + <tr> + <td id="L91" class="blob-num js-line-number" data-line-number="91"></td> + <td id="LC91" class="blob-code blob-code-inner js-file-line"><span class="pl-k">if</span> <span class="pl-k">not</span> DOT1Q._typesw:</td> + </tr> + <tr> + <td id="L92" class="blob-num js-line-number" data-line-number="92"></td> + <td id="LC92" class="blob-code blob-code-inner js-file-line"> __load_types()</td> + </tr> +</table> + + </div> + +</div> + +<a href="#jump-to-line" rel="facebox[.linejump]" data-hotkey="l" style="display:none">Jump to Line</a> +<div id="jump-to-line" style="display:none"> + <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="" class="js-jump-to-line-form" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /></div> + <input class="linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line…" aria-label="Jump to line" autofocus> + <button type="submit" class="btn">Go</button> +</form></div> + + </div> + </div> + <div class="modal-backdrop"></div> + </div> + </div> + + + + <div class="container"> + <div class="site-footer" role="contentinfo"> + <ul class="site-footer-links right"> + <li><a href="https://status.github.com/" data-ga-click="Footer, go to status, text:status">Status</a></li> + <li><a href="https://developer.github.com" data-ga-click="Footer, go to api, text:api">API</a></li> + <li><a href="https://training.github.com" data-ga-click="Footer, go to training, text:training">Training</a></li> + <li><a href="https://shop.github.com" data-ga-click="Footer, go to shop, text:shop">Shop</a></li> + <li><a href="https://github.com/blog" data-ga-click="Footer, go to blog, text:blog">Blog</a></li> + <li><a href="https://github.com/about" data-ga-click="Footer, go to about, text:about">About</a></li> + <li><a href="https://github.com/pricing" data-ga-click="Footer, go to pricing, text:pricing">Pricing</a></li> + + </ul> + + <a href="https://github.com" aria-label="Homepage"> + <span class="mega-octicon octicon-mark-github" title="GitHub"></span> +</a> + <ul class="site-footer-links"> + <li>© 2015 <span title="0.09612s from github-fe127-cp1-prd.iad.github.net">GitHub</span>, Inc.</li> + <li><a href="https://github.com/site/terms" data-ga-click="Footer, go to terms, text:terms">Terms</a></li> + <li><a href="https://github.com/site/privacy" data-ga-click="Footer, go to privacy, text:privacy">Privacy</a></li> + <li><a href="https://github.com/security" data-ga-click="Footer, go to security, text:security">Security</a></li> + <li><a href="https://github.com/contact" data-ga-click="Footer, go to contact, text:contact">Contact</a></li> + <li><a href="https://help.github.com" data-ga-click="Footer, go to help, text:help">Help</a></li> + </ul> + </div> +</div> + + + + + + + <div id="ajax-error-message" class="flash flash-error"> + <span class="octicon octicon-alert"></span> + <button type="button" class="flash-close js-flash-close js-ajax-error-dismiss" aria-label="Dismiss error"> + <span class="octicon octicon-x"></span> + </button> + Something went wrong with that request. Please try again. + </div> + + + <script crossorigin="anonymous" src="https://assets-cdn.github.com/assets/frameworks-06e65f5639cc52d1aaada53115a54614b60fa90ab446a673e3e1818df167663b.js"></script> + <script async="async" crossorigin="anonymous" src="https://assets-cdn.github.com/assets/github-435b0c380a8b91b3f42654ca3dbe8b623eebe6dfa2314a80f961d364de7e3f42.js"></script> + + + <div class="js-stale-session-flash stale-session-flash flash flash-warn flash-banner hidden"> + <span class="octicon octicon-alert"></span> + <span class="signed-in-tab-flash">You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span> + <span class="signed-out-tab-flash">You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span> + </div> + </body> +</html> + diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/dpkt.py b/scripts/external_libs/dpkt-1.8.6/dpkt/dpkt.py new file mode 100644 index 00000000..e14d46bd --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/dpkt.py @@ -0,0 +1,168 @@ + +# $Id: dpkt.py 43 2007-08-02 22:42:59Z jon.oberheide $ + +"""Simple packet creation and parsing.""" + +import copy, itertools, socket, struct + +class Error(Exception): pass +class UnpackError(Error): pass +class NeedData(UnpackError): pass +class PackError(Error): pass + +class _MetaPacket(type): + def __new__(cls, clsname, clsbases, clsdict): + t = type.__new__(cls, clsname, clsbases, clsdict) + st = getattr(t, '__hdr__', None) + if st is not None: + # XXX - __slots__ only created in __new__() + clsdict['__slots__'] = [ x[0] for x in st ] + [ 'data' ] + t = type.__new__(cls, clsname, clsbases, clsdict) + t.__hdr_fields__ = [ x[0] for x in st ] + t.__hdr_fmt__ = getattr(t, '__byte_order__', '>') + \ + ''.join([ x[1] for x in st ]) + t.__hdr_len__ = struct.calcsize(t.__hdr_fmt__) + t.__hdr_defaults__ = dict(zip( + t.__hdr_fields__, [ x[2] for x in st ])) + return t + +class Packet(object): + """Base packet class, with metaclass magic to generate members from + self.__hdr__. + + __hdr__ should be defined as a list of (name, structfmt, default) tuples + __byte_order__ can be set to override the default ('>') + + Example:: + + >>> class Foo(Packet): + ... __hdr__ = (('foo', 'I', 1), ('bar', 'H', 2), ('baz', '4s', 'quux')) + ... + >>> foo = Foo(bar=3) + >>> foo + Foo(bar=3) + >>> str(foo) + '\x00\x00\x00\x01\x00\x03quux' + >>> foo.bar + 3 + >>> foo.baz + 'quux' + >>> foo.foo = 7 + >>> foo.baz = 'whee' + >>> foo + Foo(baz='whee', foo=7, bar=3) + >>> Foo('hello, world!') + Foo(baz=' wor', foo=1751477356L, bar=28460, data='ld!') + """ + __metaclass__ = _MetaPacket + + def __init__(self, *args, **kwargs): + """Packet constructor with ([buf], [field=val,...]) prototype. + + Arguments: + + buf -- optional packet buffer to unpack + + Optional keyword arguments correspond to members to set + (matching fields in self.__hdr__, or 'data'). + """ + self.data = '' + if args: + try: + self.unpack(args[0]) + except struct.error: + if len(args[0]) < self.__hdr_len__: + raise NeedData + raise UnpackError('invalid %s: %r' % + (self.__class__.__name__, args[0])) + else: + for k in self.__hdr_fields__: + setattr(self, k, copy.copy(self.__hdr_defaults__[k])) + for k, v in kwargs.iteritems(): + setattr(self, k, v) + + def __len__(self): + return self.__hdr_len__ + len(self.data) + + def __getitem__(self, k): + try: return getattr(self, k) + except AttributeError: raise KeyError + + def __repr__(self): + l = [ '%s=%r' % (k, getattr(self, k)) + for k in self.__hdr_defaults__ + if getattr(self, k) != self.__hdr_defaults__[k] ] + if self.data: + l.append('data=%r' % self.data) + return '%s(%s)' % (self.__class__.__name__, ', '.join(l)) + + def __str__(self): + return self.pack_hdr() + str(self.data) + + def pack_hdr(self): + """Return packed header string.""" + try: + return struct.pack(self.__hdr_fmt__, + *[ getattr(self, k) for k in self.__hdr_fields__ ]) + except struct.error: + vals = [] + for k in self.__hdr_fields__: + v = getattr(self, k) + if isinstance(v, tuple): + vals.extend(v) + else: + vals.append(v) + try: + return struct.pack(self.__hdr_fmt__, *vals) + except struct.error, e: + raise PackError(str(e)) + + def pack(self): + """Return packed header + self.data string.""" + return str(self) + + def unpack(self, buf): + """Unpack packet header fields from buf, and set self.data.""" + for k, v in itertools.izip(self.__hdr_fields__, + struct.unpack(self.__hdr_fmt__, buf[:self.__hdr_len__])): + setattr(self, k, v) + self.data = buf[self.__hdr_len__:] + +# XXX - ''.join([(len(`chr(x)`)==3) and chr(x) or '.' for x in range(256)]) +__vis_filter = """................................ !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[.]^_`abcdefghijklmnopqrstuvwxyz{|}~.................................................................................................................................""" + +def hexdump(buf, length=16): + """Return a hexdump output string of the given buffer.""" + n = 0 + res = [] + while buf: + line, buf = buf[:length], buf[length:] + hexa = ' '.join(['%02x' % ord(x) for x in line]) + line = line.translate(__vis_filter) + res.append(' %04d: %-*s %s' % (n, length * 3, hexa, line)) + n += length + return '\n'.join(res) + +try: + import dnet2 + def in_cksum_add(s, buf): + return dnet.ip_cksum_add(buf, s) + def in_cksum_done(s): + return socket.ntohs(dnet.ip_cksum_carry(s)) +except ImportError: + import array + def in_cksum_add(s, buf): + n = len(buf) + cnt = (n / 2) * 2 + a = array.array('H', buf[:cnt]) + if cnt != n: + a.append(struct.unpack('H', buf[-1] + '\x00')[0]) + return s + sum(a) + def in_cksum_done(s): + s = (s >> 16) + (s & 0xffff) + s += (s >> 16) + return socket.ntohs(~s & 0xffff) + +def in_cksum(buf): + """Return computed Internet checksum.""" + return in_cksum_done(in_cksum_add(0, buf)) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/dtp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/dtp.py new file mode 100644 index 00000000..9ceec387 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/dtp.py @@ -0,0 +1,23 @@ +# $Id: dtp.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Dynamic Trunking Protocol.""" + +import struct +import dpkt + +class DTP(dpkt.Packet): + __hdr__ = ( + ('v', 'B', 0), + ) # rest is TLVs + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + buf = self.data + tvs = [] + while buf: + t, l = struct.unpack('>HH', buf[:4]) + v, buf = buf[4:4+l], buf[4+l:] + tvs.append((t, v)) + self.data = tvs + +TRUNK_NAME = 0x01 +MAC_ADDR = 0x04 diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/esp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/esp.py new file mode 100644 index 00000000..890482ea --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/esp.py @@ -0,0 +1,11 @@ +# $Id: esp.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Encapsulated Security Protocol.""" + +import dpkt + +class ESP(dpkt.Packet): + __hdr__ = ( + ('spi', 'I', 0), + ('seq', 'I', 0) + ) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/ethernet.py b/scripts/external_libs/dpkt-1.8.6/dpkt/ethernet.py new file mode 100644 index 00000000..eca04868 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/ethernet.py @@ -0,0 +1,140 @@ +# $Id: ethernet.py 65 2010-03-26 02:53:51Z dugsong $ + +"""Ethernet II, LLC (802.3+802.2), LLC/SNAP, and Novell raw 802.3, +with automatic 802.1q, MPLS, PPPoE, and Cisco ISL decapsulation.""" + +import struct +import dpkt, stp + +ETH_CRC_LEN = 4 +ETH_HDR_LEN = 14 + +ETH_LEN_MIN = 64 # minimum frame length with CRC +ETH_LEN_MAX = 1518 # maximum frame length with CRC + +ETH_MTU = (ETH_LEN_MAX - ETH_HDR_LEN - ETH_CRC_LEN) +ETH_MIN = (ETH_LEN_MIN - ETH_HDR_LEN - ETH_CRC_LEN) + +# Ethernet payload types - http://standards.ieee.org/regauth/ethertype +ETH_TYPE_PUP = 0x0200 # PUP protocol +ETH_TYPE_IP = 0x0800 # IP protocol +ETH_TYPE_ARP = 0x0806 # address resolution protocol +ETH_TYPE_AOE = 0x88a2 # AoE protocol +ETH_TYPE_CDP = 0x2000 # Cisco Discovery Protocol +ETH_TYPE_DTP = 0x2004 # Cisco Dynamic Trunking Protocol +ETH_TYPE_REVARP = 0x8035 # reverse addr resolution protocol +ETH_TYPE_8021Q = 0x8100 # IEEE 802.1Q VLAN tagging +ETH_TYPE_IPX = 0x8137 # Internetwork Packet Exchange +ETH_TYPE_IP6 = 0x86DD # IPv6 protocol +ETH_TYPE_PPP = 0x880B # PPP +ETH_TYPE_MPLS = 0x8847 # MPLS +ETH_TYPE_MPLS_MCAST = 0x8848 # MPLS Multicast +ETH_TYPE_PPPoE_DISC = 0x8863 # PPP Over Ethernet Discovery Stage +ETH_TYPE_PPPoE = 0x8864 # PPP Over Ethernet Session Stage +ETH_TYPE_LLDP = 0x88CC #Link Layer Discovery Protocol + +# MPLS label stack fields +MPLS_LABEL_MASK = 0xfffff000 +MPLS_QOS_MASK = 0x00000e00 +MPLS_TTL_MASK = 0x000000ff +MPLS_LABEL_SHIFT= 12 +MPLS_QOS_SHIFT = 9 +MPLS_TTL_SHIFT = 0 +MPLS_STACK_BOTTOM=0x0100 + +class Ethernet(dpkt.Packet): + __hdr__ = ( + ('dst', '6s', ''), + ('src', '6s', ''), + ('type', 'H', ETH_TYPE_IP) + ) + _typesw = {} + + def _unpack_data(self, buf): + if self.type == ETH_TYPE_8021Q: + self.tag, self.type = struct.unpack('>HH', buf[:4]) + buf = buf[4:] + elif self.type == ETH_TYPE_MPLS or \ + self.type == ETH_TYPE_MPLS_MCAST: + # XXX - skip labels (max # of labels is undefined, just use 24) + self.labels = [] + for i in range(24): + entry = struct.unpack('>I', buf[i*4:i*4+4])[0] + label = ((entry & MPLS_LABEL_MASK) >> MPLS_LABEL_SHIFT, \ + (entry & MPLS_QOS_MASK) >> MPLS_QOS_SHIFT, \ + (entry & MPLS_TTL_MASK) >> MPLS_TTL_SHIFT) + self.labels.append(label) + if entry & MPLS_STACK_BOTTOM: + break + self.type = ETH_TYPE_IP + buf = buf[(i + 1) * 4:] + try: + self.data = self._typesw[self.type](buf) + setattr(self, self.data.__class__.__name__.lower(), self.data) + except (KeyError, dpkt.UnpackError): + self.data = buf + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + if self.type > 1500: + # Ethernet II + self._unpack_data(self.data) + elif self.dst.startswith('\x01\x00\x0c\x00\x00') or \ + self.dst.startswith('\x03\x00\x0c\x00\x00'): + # Cisco ISL + self.vlan = struct.unpack('>H', self.data[6:8])[0] + self.unpack(self.data[12:]) + elif self.data.startswith('\xff\xff'): + # Novell "raw" 802.3 + self.type = ETH_TYPE_IPX + self.data = self.ipx = self._typesw[ETH_TYPE_IPX](self.data[2:]) + else: + # 802.2 LLC + self.dsap, self.ssap, self.ctl = struct.unpack('BBB', self.data[:3]) + if self.data.startswith('\xaa\xaa'): + # SNAP + self.type = struct.unpack('>H', self.data[6:8])[0] + self._unpack_data(self.data[8:]) + else: + # non-SNAP + dsap = ord(self.data[0]) + if dsap == 0x06: # SAP_IP + self.data = self.ip = self._typesw[ETH_TYPE_IP](self.data[3:]) + elif dsap == 0x10 or dsap == 0xe0: # SAP_NETWARE{1,2} + self.data = self.ipx = self._typesw[ETH_TYPE_IPX](self.data[3:]) + elif dsap == 0x42: # SAP_STP + self.data = self.stp = stp.STP(self.data[3:]) + + def set_type(cls, t, pktclass): + cls._typesw[t] = pktclass + set_type = classmethod(set_type) + + def get_type(cls, t): + return cls._typesw[t] + get_type = classmethod(get_type) + +# XXX - auto-load Ethernet dispatch table from ETH_TYPE_* definitions +def __load_types(): + g = globals() + for k, v in g.iteritems(): + if k.startswith('ETH_TYPE_'): + name = k[9:] + modname = name.lower() + try: + mod = __import__(modname, g) + except ImportError: + continue + Ethernet.set_type(v, getattr(mod, name)) + +if not Ethernet._typesw: + __load_types() + +if __name__ == '__main__': + import unittest + + class EthTestCase(unittest.TestCase): + def test_eth(self): + s = '\x00\xb0\xd0\xe1\x80r\x00\x11$\x8c\x11\xde\x86\xdd`\x00\x00\x00\x00(\x06@\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x11$\xff\xfe\x8c\x11\xde\xfe\x80\x00\x00\x00\x00\x00\x00\x02\xb0\xd0\xff\xfe\xe1\x80r\xcd\xd3\x00\x16\xffP\xd7\x13\x00\x00\x00\x00\xa0\x02\xff\xffg\xd3\x00\x00\x02\x04\x05\xa0\x01\x03\x03\x00\x01\x01\x08\n}\x18:a\x00\x00\x00\x00' + eth = Ethernet(s) + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/gre.py b/scripts/external_libs/dpkt-1.8.6/dpkt/gre.py new file mode 100644 index 00000000..4d462edc --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/gre.py @@ -0,0 +1,103 @@ +# $Id: gre.py 75 2010-08-03 14:42:19Z jon.oberheide $ + +"""Generic Routing Encapsulation.""" + +import struct +import dpkt + +GRE_CP = 0x8000 # Checksum Present +GRE_RP = 0x4000 # Routing Present +GRE_KP = 0x2000 # Key Present +GRE_SP = 0x1000 # Sequence Present +GRE_SS = 0x0800 # Strict Source Route +GRE_AP = 0x0080 # Acknowledgment Present + +GRE_opt_fields = ( + (GRE_CP|GRE_RP, 'sum', 'H'), (GRE_CP|GRE_RP, 'off', 'H'), + (GRE_KP, 'key', 'I'), (GRE_SP, 'seq', 'I'), (GRE_AP, 'ack', 'I') + ) +class GRE(dpkt.Packet): + __hdr__ = ( + ('flags', 'H', 0), + ('p', 'H', 0x0800), # ETH_TYPE_IP + ) + _protosw = {} + sre = () + def get_v(self): + return self.flags & 0x7 + def set_v(self, v): + self.flags = (self.flags & ~0x7) | (v & 0x7) + v = property(get_v, set_v) + + def get_recur(self): + return (self.flags >> 5) & 0x7 + def set_recur(self, v): + self.flags = (self.flags & ~0xe0) | ((v & 0x7) << 5) + recur = property(get_recur, set_recur) + + class SRE(dpkt.Packet): + __hdr__ = [ + ('family', 'H', 0), + ('off', 'B', 0), + ('len', 'B', 0) + ] + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.data[:self.len] + + def opt_fields_fmts(self): + if self.v == 0: + fields, fmts = [], [] + opt_fields = GRE_opt_fields + else: + fields, fmts = [ 'len', 'callid' ], [ 'H', 'H' ] + opt_fields = GRE_opt_fields[-2:] + for flags, field, fmt in opt_fields: + if self.flags & flags: + fields.append(field) + fmts.append(fmt) + return fields, fmts + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + fields, fmts = self.opt_fields_fmts() + if fields: + fmt = ''.join(fmts) + fmtlen = struct.calcsize(fmt) + vals = struct.unpack(fmt, self.data[:fmtlen]) + self.data = self.data[fmtlen:] + self.__dict__.update(dict(zip(fields, vals))) + if self.flags & GRE_RP: + l = [] + while True: + sre = self.SRE(self.data) + self.data = self.data[len(sre):] + l.append(sre) + if not sre.len: + break + self.sre = l + self.data = ethernet.Ethernet._typesw[self.p](self.data) + setattr(self, self.data.__class__.__name__.lower(), self.data) + + def __len__(self): + opt_fmtlen = struct.calcsize(''.join(self.opt_fields_fmts()[1])) + return self.__hdr_len__ + opt_fmtlen + \ + sum(map(len, self.sre)) + len(self.data) + + # XXX - need to fix up repr to display optional fields... + + def __str__(self): + fields, fmts = self.opt_fields_fmts() + if fields: + vals = [] + for f in fields: + vals.append(getattr(self, f)) + opt_s = struct.pack(''.join(fmts), *vals) + else: + opt_s = '' + return self.pack_hdr() + opt_s + ''.join(map(str, self.sre)) + \ + str(self.data) + +# XXX - auto-load GRE dispatch table from Ethernet dispatch table +import ethernet +GRE._protosw.update(ethernet.Ethernet._typesw) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/gzip.py b/scripts/external_libs/dpkt-1.8.6/dpkt/gzip.py new file mode 100644 index 00000000..e0bc619f --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/gzip.py @@ -0,0 +1,117 @@ +# $Id: gzip.py 23 2006-11-08 15:45:33Z dugsong $ + +"""GNU zip.""" + +import struct, zlib +import dpkt + +# RFC 1952 +GZIP_MAGIC = '\x1f\x8b' + +# Compression methods +GZIP_MSTORED = 0 +GZIP_MCOMPRESS = 1 +GZIP_MPACKED = 2 +GZIP_MLZHED = 3 +GZIP_MDEFLATE = 8 + +# Flags +GZIP_FTEXT = 0x01 +GZIP_FHCRC = 0x02 +GZIP_FEXTRA = 0x04 +GZIP_FNAME = 0x08 +GZIP_FCOMMENT = 0x10 +GZIP_FENCRYPT = 0x20 +GZIP_FRESERVED = 0xC0 + +# OS +GZIP_OS_MSDOS = 0 +GZIP_OS_AMIGA = 1 +GZIP_OS_VMS = 2 +GZIP_OS_UNIX = 3 +GZIP_OS_VMCMS = 4 +GZIP_OS_ATARI = 5 +GZIP_OS_OS2 = 6 +GZIP_OS_MACOS = 7 +GZIP_OS_ZSYSTEM = 8 +GZIP_OS_CPM = 9 +GZIP_OS_TOPS20 = 10 +GZIP_OS_WIN32 = 11 +GZIP_OS_QDOS = 12 +GZIP_OS_RISCOS = 13 +GZIP_OS_UNKNOWN = 255 + +GZIP_FENCRYPT_LEN = 12 + +class GzipExtra(dpkt.Packet): + __hdr__ = ( + ('id', '2s', ''), + ('len', 'H', 0) + ) + +class Gzip(dpkt.Packet): + __hdr__ = ( + ('magic', '2s', GZIP_MAGIC), + ('method', 'B', GZIP_MDEFLATE), + ('flags', 'B', 0), + ('mtime', 'I', 0), + ('xflags', 'B', 0), + ('os', 'B', GZIP_OS_UNIX), + + ('extra', '0s', ''), # XXX - GZIP_FEXTRA + ('filename', '0s', ''), # XXX - GZIP_FNAME + ('comment', '0s', '') # XXX - GZIP_FCOMMENT + ) + + def unpack(self, buf): + super(Gzip, self).unpack(buf) + if self.flags & GZIP_FEXTRA: + n = struct.unpack(self.data[:2], '>H')[0] + self.extra = GzipExtra(self.data[2:2+n]) + self.data = self.data[2+n:] + if self.flags & GZIP_FNAME: + n = self.data.find('\x00') + self.filename = self.data[:n] + self.data = self.data[n + 1:] + if self.flags & GZIP_FCOMMENT: + n = self.data.find('\x00') + self.comment = self.data[:n] + self.data = self.data[n + 1:] + if self.flags & GZIP_FENCRYPT: + self.data = self.data[GZIP_FENCRYPT_LEN:] # XXX - skip + if self.flags & GZIP_FHCRC: + self.data = self.data[2:] # XXX - skip + + def pack_hdr(self): + l = [] + if self.extra: + self.flags |= GZIP_FEXTRA + s = str(self.extra) + l.append(struct.pack('>H', len(s))) + l.append(s) + if self.filename: + self.flags |= GZIP_FNAME + l.append(self.filename) + l.append('\x00') + if self.comment: + self.flags |= GZIP_FCOMMENT + l.append(self.comment) + l.append('\x00') + l.insert(0, super(Gzip, self).pack_hdr()) + return ''.join(l) + + def compress(self): + """Compress self.data.""" + c = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS, + zlib.DEF_MEM_LEVEL, 0) + self.data = c.compress(self.data) + + def decompress(self): + """Return decompressed payload.""" + d = zlib.decompressobj(-zlib.MAX_WBITS) + return d.decompress(self.data) + +if __name__ == '__main__': + import sys + gz = Gzip(open(sys.argv[1]).read()) + print `gz`, `gz.decompress()` diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/h225.py b/scripts/external_libs/dpkt-1.8.6/dpkt/h225.py new file mode 100644 index 00000000..a8fe2cbe --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/h225.py @@ -0,0 +1,217 @@ +# $Id: h225.py 23 2006-11-08 15:45:33Z dugsong $ + +"""ITU-T H.225.0 Call Signaling.""" + +import dpkt, tpkt +import struct + +# H225 Call Signaling +# +# Call messages and information elements (IEs) are defined by Q.931: +# http://cvsup.de.openbsd.org/historic/comp/doc/standards/itu/Q/Q.931.ps.gz +# +# The User-to-User IEs of H225 are encoded by PER of ASN.1. + +# Call Establishment Messages +ALERTING = 1 +CALL_PROCEEDING = 2 +CONNECT = 7 +CONNECT_ACKNOWLEDGE = 15 +PROGRESS = 3 +SETUP = 5 +SETUP_ACKNOWLEDGE = 13 + +# Call Information Phase Messages +RESUME = 38 +RESUME_ACKNOWLEDGE = 46 +RESUME_REJECT = 34 +SUSPEND = 37 +SUSPEND_ACKNOWLEDGE = 45 +SUSPEND_REJECT = 33 +USER_INFORMATION = 32 + +# Call Clearing Messages +DISCONNECT = 69 +RELEASE = 77 +RELEASE_COMPLETE = 90 +RESTART = 70 +RESTART_ACKNOWLEDGE = 78 + +# Miscellaneous Messages +SEGMENT = 96 +CONGESTION_CONTROL = 121 +INFORMATION = 123 +NOTIFY = 110 +STATUS = 125 +STATUS_ENQUIRY = 117 + +# Type 1 Single Octet Information Element IDs +RESERVED = 128 +SHIFT = 144 +CONGESTION_LEVEL = 176 +REPEAT_INDICATOR = 208 + +# Type 2 Single Octet Information Element IDs +MORE_DATA = 160 +SENDING_COMPLETE = 161 + +# Variable Length Information Element IDs +SEGMENTED_MESSAGE = 0 +BEARER_CAPABILITY = 4 +CAUSE = 8 +CALL_IDENTITY = 16 +CALL_STATE = 20 +CHANNEL_IDENTIFICATION = 24 +PROGRESS_INDICATOR = 30 +NETWORK_SPECIFIC_FACILITIES = 32 +NOTIFICATION_INDICATOR = 39 +DISPLAY = 40 +DATE_TIME = 41 +KEYPAD_FACILITY = 44 +SIGNAL = 52 +INFORMATION_RATE = 64 +END_TO_END_TRANSIT_DELAY = 66 +TRANSIT_DELAY_SELECTION_AND_INDICATION = 67 +PACKET_LAYER_BINARY_PARAMETERS = 68 +PACKET_LAYER_WINDOW_SIZE = 69 +PACKET_SIZE = 70 +CLOSED_USER_GROUP = 71 +REVERSE_CHARGE_INDICATION = 74 +CALLING_PARTY_NUMBER = 108 +CALLING_PARTY_SUBADDRESS = 109 +CALLED_PARTY_NUMBER = 112 +CALLED_PARTY_SUBADDRESS = 113 +REDIRECTING_NUMBER = 116 +TRANSIT_NETWORK_SELECTION = 120 +RESTART_INDICATOR = 121 +LOW_LAYER_COMPATIBILITY = 124 +HIGH_LAYER_COMPATIBILITY = 125 +USER_TO_USER = 126 +ESCAPE_FOR_EXTENSION = 127 + +class H225(dpkt.Packet): + __hdr__ = ( + ('proto', 'B', 8), + ('ref_len', 'B', 2) + ) + + def unpack(self, buf): + # TPKT header + self.tpkt = tpkt.TPKT(buf) + if self.tpkt.v != 3: + raise dpkt.UnpackError('invalid TPKT version') + if self.tpkt.rsvd != 0: + raise dpkt.UnpackError('invalid TPKT reserved value') + n = self.tpkt.len - self.tpkt.__hdr_len__ + if n > len(self.tpkt.data): + raise dpkt.UnpackError('invalid TPKT length') + buf = self.tpkt.data + + # Q.931 payload + dpkt.Packet.unpack(self, buf) + buf = buf[self.__hdr_len__:] + self.ref_val = buf[:self.ref_len] + buf = buf[self.ref_len:] + self.type = struct.unpack('B', buf[:1])[0] + buf = buf[1:] + + # Information Elements + l = [] + while buf: + ie = self.IE(buf) + l.append(ie) + buf = buf[len(ie):] + self.data = l + + def __len__(self): + return self.tpkt.__hdr_len__ + \ + self.__hdr_len__ + \ + sum(map(len, self.data)) + + def __str__(self): + return self.tpkt.pack_hdr() + \ + self.pack_hdr() + \ + self.ref_val + \ + struct.pack('B', self.type) + \ + ''.join(map(str, self.data)) + + class IE(dpkt.Packet): + __hdr__ = ( + ('type', 'B', 0), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + buf = buf[self.__hdr_len__:] + + # single-byte IE + if self.type & 0x80: + self.len = 0 + self.data = None + # multi-byte IE + else: + # special PER-encoded UUIE + if self.type == USER_TO_USER: + self.len = struct.unpack('>H', buf[:2])[0] + buf = buf[2:] + # normal TLV-like IE + else: + self.len = struct.unpack('B', buf[:1])[0] + buf = buf[1:] + self.data = buf[:self.len] + + def __len__(self): + if self.type & 0x80: + n = 0 + else: + if self.type == USER_TO_USER: + n = 2 + else: + n = 1 + return self.__hdr_len__ + \ + self.len \ + + n + + def __str__(self): + if self.type & 0x80: + length_str = None + else: + if self.type == USER_TO_USER: + length_str = struct.pack('>H', self.len) + else: + length_str = struct.pack('B', self.len) + return struct.pack('B', self.type) + \ + length_str + \ + self.data + + +if __name__ == '__main__': + import unittest + + class H225TestCase(unittest.TestCase): + def testPack(self): + h = H225(self.s) + self.failUnless(self.s == str(h)) + + def testUnpack(self): + h = H225(self.s) + self.failUnless(h.tpkt.v == 3) + self.failUnless(h.tpkt.rsvd == 0) + self.failUnless(h.tpkt.len == 1041) + self.failUnless(h.proto == 8) + self.failUnless(h.type == SETUP) + self.failUnless(len(h.data) == 3) + + ie = h.data[0] + self.failUnless(ie.type == BEARER_CAPABILITY) + self.failUnless(ie.len == 3) + ie = h.data[1] + self.failUnless(ie.type == DISPLAY) + self.failUnless(ie.len == 14) + ie = h.data[2] + self.failUnless(ie.type == USER_TO_USER) + self.failUnless(ie.len == 1008) + + s = '\x03\x00\x04\x11\x08\x02\x54\x2b\x05\x04\x03\x88\x93\xa5\x28\x0e\x4a\x6f\x6e\x20\x4f\x62\x65\x72\x68\x65\x69\x64\x65\x00\x7e\x03\xf0\x05\x20\xb8\x06\x00\x08\x91\x4a\x00\x04\x01\x40\x0c\x00\x4a\x00\x6f\x00\x6e\x00\x20\x00\x4f\x00\x62\x00\x65\x00\x72\x00\x68\x00\x65\x00\x69\x00\x64\x00\x65\x22\xc0\x09\x00\x00\x3d\x06\x65\x6b\x69\x67\x61\x00\x00\x14\x32\x2e\x30\x2e\x32\x20\x28\x4f\x50\x41\x4c\x20\x76\x32\x2e\x32\x2e\x32\x29\x00\x00\x00\x01\x40\x15\x00\x74\x00\x63\x00\x70\x00\x24\x00\x68\x00\x33\x00\x32\x00\x33\x00\x2e\x00\x76\x00\x6f\x00\x78\x00\x67\x00\x72\x00\x61\x00\x74\x00\x69\x00\x61\x00\x2e\x00\x6f\x00\x72\x00\x67\x00\x42\x87\x23\x2c\x06\xb8\x00\x6a\x8b\x1d\x0c\xb7\x06\xdb\x11\x9e\xca\x00\x10\xa4\x89\x6d\x6a\x00\xc5\x1d\x80\x04\x07\x00\x0a\x00\x01\x7a\x75\x30\x11\x00\x5e\x88\x1d\x0c\xb7\x06\xdb\x11\x9e\xca\x00\x10\xa4\x89\x6d\x6a\x82\x2b\x0e\x30\x40\x00\x00\x06\x04\x01\x00\x4c\x10\x09\x00\x00\x3d\x0f\x53\x70\x65\x65\x78\x20\x62\x73\x34\x20\x57\x69\x64\x65\x36\x80\x11\x1c\x00\x01\x00\x98\xa0\x26\x41\x13\x8a\x00\x98\xa0\x26\x41\x13\x8b\x26\x00\x00\x64\x0c\x10\x09\x00\x00\x3d\x0f\x53\x70\x65\x65\x78\x20\x62\x73\x34\x20\x57\x69\x64\x65\x36\x80\x0b\x0d\x00\x01\x00\x98\xa0\x26\x41\x13\x8b\x00\x2a\x40\x00\x00\x06\x04\x01\x00\x4c\x10\x09\x00\x00\x3d\x09\x69\x4c\x42\x43\x2d\x31\x33\x6b\x33\x80\x11\x1c\x00\x01\x00\x98\xa0\x26\x41\x13\x8a\x00\x98\xa0\x26\x41\x13\x8b\x20\x00\x00\x65\x0c\x10\x09\x00\x00\x3d\x09\x69\x4c\x42\x43\x2d\x31\x33\x6b\x33\x80\x0b\x0d\x00\x01\x00\x98\xa0\x26\x41\x13\x8b\x00\x20\x40\x00\x00\x06\x04\x01\x00\x4e\x0c\x03\x00\x83\x00\x80\x11\x1c\x00\x01\x00\x98\xa0\x26\x41\x13\x8a\x00\x98\xa0\x26\x41\x13\x8b\x16\x00\x00\x66\x0e\x0c\x03\x00\x83\x00\x80\x0b\x0d\x00\x01\x00\x98\xa0\x26\x41\x13\x8b\x00\x4b\x40\x00\x00\x06\x04\x01\x00\x4c\x10\xb5\x00\x53\x4c\x2a\x02\x00\x00\x00\x00\x00\x40\x01\x00\x00\x40\x01\x02\x00\x08\x00\x00\x00\x00\x00\x31\x00\x01\x00\x40\x1f\x00\x00\x59\x06\x00\x00\x41\x00\x00\x00\x02\x00\x40\x01\x00\x00\x80\x11\x1c\x00\x01\x00\x98\xa0\x26\x41\x13\x8a\x00\x98\xa0\x26\x41\x13\x8b\x41\x00\x00\x67\x0c\x10\xb5\x00\x53\x4c\x2a\x02\x00\x00\x00\x00\x00\x40\x01\x00\x00\x40\x01\x02\x00\x08\x00\x00\x00\x00\x00\x31\x00\x01\x00\x40\x1f\x00\x00\x59\x06\x00\x00\x41\x00\x00\x00\x02\x00\x40\x01\x00\x00\x80\x0b\x0d\x00\x01\x00\x98\xa0\x26\x41\x13\x8b\x00\x32\x40\x00\x00\x06\x04\x01\x00\x4c\x10\x09\x00\x00\x3d\x11\x53\x70\x65\x65\x78\x20\x62\x73\x34\x20\x4e\x61\x72\x72\x6f\x77\x33\x80\x11\x1c\x00\x01\x00\x98\xa0\x26\x41\x13\x8a\x00\x98\xa0\x26\x41\x13\x8b\x28\x00\x00\x68\x0c\x10\x09\x00\x00\x3d\x11\x53\x70\x65\x65\x78\x20\x62\x73\x34\x20\x4e\x61\x72\x72\x6f\x77\x33\x80\x0b\x0d\x00\x01\x00\x98\xa0\x26\x41\x13\x8b\x00\x1d\x40\x00\x00\x06\x04\x01\x00\x4c\x60\x1d\x80\x11\x1c\x00\x01\x00\x98\xa0\x26\x41\x13\x8a\x00\x98\xa0\x26\x41\x13\x8b\x13\x00\x00\x69\x0c\x60\x1d\x80\x0b\x0d\x00\x01\x00\x98\xa0\x26\x41\x13\x8b\x00\x1d\x40\x00\x00\x06\x04\x01\x00\x4c\x20\x1d\x80\x11\x1c\x00\x01\x00\x98\xa0\x26\x41\x13\x8a\x00\x98\xa0\x26\x41\x13\x8b\x13\x00\x00\x6a\x0c\x20\x1d\x80\x0b\x0d\x00\x01\x00\x98\xa0\x26\x41\x13\x8b\x00\x01\x00\x01\x00\x01\x00\x01\x00\x81\x03\x02\x80\xf8\x02\x70\x01\x06\x00\x08\x81\x75\x00\x0b\x80\x13\x80\x01\xf4\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x0c\xc0\x01\x00\x01\x80\x0b\x80\x00\x00\x20\x20\x09\x00\x00\x3d\x0f\x53\x70\x65\x65\x78\x20\x62\x73\x34\x20\x57\x69\x64\x65\x36\x80\x00\x01\x20\x20\x09\x00\x00\x3d\x09\x69\x4c\x42\x43\x2d\x31\x33\x6b\x33\x80\x00\x02\x24\x18\x03\x00\xe6\x00\x80\x00\x03\x20\x20\xb5\x00\x53\x4c\x2a\x02\x00\x00\x00\x00\x00\x40\x01\x00\x00\x40\x01\x02\x00\x08\x00\x00\x00\x00\x00\x31\x00\x01\x00\x40\x1f\x00\x00\x59\x06\x00\x00\x41\x00\x00\x00\x02\x00\x40\x01\x00\x00\x80\x00\x04\x20\x20\x09\x00\x00\x3d\x11\x53\x70\x65\x65\x78\x20\x62\x73\x34\x20\x4e\x61\x72\x72\x6f\x77\x33\x80\x00\x05\x20\xc0\xef\x80\x00\x06\x20\x40\xef\x80\x00\x07\x08\xe0\x03\x51\x00\x80\x01\x00\x80\x00\x08\x08\xd0\x03\x51\x00\x80\x01\x00\x80\x00\x09\x83\x01\x50\x80\x00\x0a\x83\x01\x10\x80\x00\x0b\x83\x01\x40\x00\x80\x01\x03\x06\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x01\x00\x07\x00\x08\x00\x00\x09\x01\x00\x0a\x00\x0b\x07\x01\x00\x32\x80\xa6\xff\x4c\x02\x80\x01\x80' + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/hsrp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/hsrp.py new file mode 100644 index 00000000..9a082a3d --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/hsrp.py @@ -0,0 +1,32 @@ +# $Id: hsrp.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Cisco Hot Standby Router Protocol.""" + +import dpkt + +# Opcodes +HELLO = 0 +COUP = 1 +RESIGN = 2 + +# States +INITIAL = 0x00 +LEARN = 0x01 +LISTEN = 0x02 +SPEAK = 0x04 +STANDBY = 0x08 +ACTIVE = 0x10 + +class HSRP(dpkt.Packet): + __hdr__ = ( + ('version', 'B', 0), + ('opcode', 'B', 0), + ('state', 'B', 0), + ('hello', 'B', 0), + ('hold', 'B', 0), + ('priority', 'B', 0), + ('group', 'B', 0), + ('rsvd', 'B', 0), + ('auth', '8s', 'cisco'), + ('vip', '4s', '') + ) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/http.py b/scripts/external_libs/dpkt-1.8.6/dpkt/http.py new file mode 100644 index 00000000..ce0ddc64 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/http.py @@ -0,0 +1,237 @@ +# $Id: http.py 86 2013-03-05 19:25:19Z andrewflnr@gmail.com $ + +"""Hypertext Transfer Protocol.""" + +import cStringIO +import dpkt + +def parse_headers(f): + """Return dict of HTTP headers parsed from a file object.""" + d = {} + while 1: + line = f.readline() + if not line: + raise dpkt.NeedData('premature end of headers') + line = line.strip() + if not line: + break + l = line.split(':', 1) + if len(l[0].split()) != 1: + raise dpkt.UnpackError('invalid header: %r' % line) + k = l[0].lower() + v = len(l) != 1 and l[1].lstrip() or '' + if k in d: + if not type(d[k]) is list: + d[k] = [d[k]] + d[k].append(v) + else: + d[k] = v + return d + +def parse_body(f, headers): + """Return HTTP body parsed from a file object, given HTTP header dict.""" + if headers.get('transfer-encoding', '').lower() == 'chunked': + l = [] + found_end = False + while 1: + try: + sz = f.readline().split(None, 1)[0] + except IndexError: + raise dpkt.UnpackError('missing chunk size') + n = int(sz, 16) + if n == 0: + found_end = True + buf = f.read(n) + if f.readline().strip(): + break + if n and len(buf) == n: + l.append(buf) + else: + break + if not found_end: + raise dpkt.NeedData('premature end of chunked body') + body = ''.join(l) + elif 'content-length' in headers: + n = int(headers['content-length']) + body = f.read(n) + if len(body) != n: + raise dpkt.NeedData('short body (missing %d bytes)' % (n - len(body))) + elif 'content-type' in headers: + body = f.read() + else: + # XXX - need to handle HTTP/0.9 + body = '' + return body + +class Message(dpkt.Packet): + """Hypertext Transfer Protocol headers + body.""" + __metaclass__ = type + __hdr_defaults__ = {} + headers = None + body = None + + def __init__(self, *args, **kwargs): + if args: + self.unpack(args[0]) + else: + self.headers = {} + self.body = '' + for k, v in self.__hdr_defaults__.iteritems(): + setattr(self, k, v) + for k, v in kwargs.iteritems(): + setattr(self, k, v) + + def unpack(self, buf): + f = cStringIO.StringIO(buf) + # Parse headers + self.headers = parse_headers(f) + # Parse body + self.body = parse_body(f, self.headers) + # Save the rest + self.data = f.read() + + def pack_hdr(self): + return ''.join([ '%s: %s\r\n' % t for t in self.headers.iteritems() ]) + + def __len__(self): + return len(str(self)) + + def __str__(self): + return '%s\r\n%s' % (self.pack_hdr(), self.body) + +class Request(Message): + """Hypertext Transfer Protocol Request.""" + __hdr_defaults__ = { + 'method':'GET', + 'uri':'/', + 'version':'1.0', + } + __methods = dict.fromkeys(( + 'GET', 'PUT', 'ICY', + 'COPY', 'HEAD', 'LOCK', 'MOVE', 'POLL', 'POST', + 'BCOPY', 'BMOVE', 'MKCOL', 'TRACE', 'LABEL', 'MERGE', + 'DELETE', 'SEARCH', 'UNLOCK', 'REPORT', 'UPDATE', 'NOTIFY', + 'BDELETE', 'CONNECT', 'OPTIONS', 'CHECKIN', + 'PROPFIND', 'CHECKOUT', 'CCM_POST', + 'SUBSCRIBE', 'PROPPATCH', 'BPROPFIND', + 'BPROPPATCH', 'UNCHECKOUT', 'MKACTIVITY', + 'MKWORKSPACE', 'UNSUBSCRIBE', 'RPC_CONNECT', + 'VERSION-CONTROL', + 'BASELINE-CONTROL' + )) + __proto = 'HTTP' + + def unpack(self, buf): + f = cStringIO.StringIO(buf) + line = f.readline() + l = line.strip().split() + if len(l) < 2: + raise dpkt.UnpackError('invalid request: %r' % line) + if l[0] not in self.__methods: + raise dpkt.UnpackError('invalid http method: %r' % l[0]) + if len(l) == 2: + # HTTP/0.9 does not specify a version in the request line + self.version = '0.9' + else: + if not l[2].startswith(self.__proto): + raise dpkt.UnpackError('invalid http version: %r' % l[2]) + self.version = l[2][len(self.__proto)+1:] + self.method = l[0] + self.uri = l[1] + Message.unpack(self, f.read()) + + def __str__(self): + return '%s %s %s/%s\r\n' % (self.method, self.uri, self.__proto, + self.version) + Message.__str__(self) + +class Response(Message): + """Hypertext Transfer Protocol Response.""" + __hdr_defaults__ = { + 'version':'1.0', + 'status':'200', + 'reason':'OK' + } + __proto = 'HTTP' + + def unpack(self, buf): + f = cStringIO.StringIO(buf) + line = f.readline() + l = line.strip().split(None, 2) + if len(l) < 2 or not l[0].startswith(self.__proto) or not l[1].isdigit(): + raise dpkt.UnpackError('invalid response: %r' % line) + self.version = l[0][len(self.__proto)+1:] + self.status = l[1] + self.reason = l[2] + Message.unpack(self, f.read()) + + def __str__(self): + return '%s/%s %s %s\r\n' % (self.__proto, self.version, self.status, + self.reason) + Message.__str__(self) + +if __name__ == '__main__': + import unittest + + class HTTPTest(unittest.TestCase): + def test_parse_request(self): + s = """POST /main/redirect/ab/1,295,,00.html HTTP/1.0\r\nReferer: http://www.email.com/login/snap/login.jhtml\r\nConnection: Keep-Alive\r\nUser-Agent: Mozilla/4.75 [en] (X11; U; OpenBSD 2.8 i386; Nav)\r\nHost: ltd.snap.com\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\r\nAccept-Encoding: gzip\r\nAccept-Language: en\r\nAccept-Charset: iso-8859-1,*,utf-8\r\nContent-type: application/x-www-form-urlencoded\r\nContent-length: 61\r\n\r\nsn=em&mn=dtest4&pw=this+is+atest&fr=true&login=Sign+in&od=www""" + r = Request(s) + assert r.method == 'POST' + assert r.uri == '/main/redirect/ab/1,295,,00.html' + assert r.body == 'sn=em&mn=dtest4&pw=this+is+atest&fr=true&login=Sign+in&od=www' + assert r.headers['content-type'] == 'application/x-www-form-urlencoded' + try: + r = Request(s[:60]) + assert 'invalid headers parsed!' + except dpkt.UnpackError: + pass + + def test_format_request(self): + r = Request() + assert str(r) == 'GET / HTTP/1.0\r\n\r\n' + r.method = 'POST' + r.uri = '/foo/bar/baz.html' + r.headers['content-type'] = 'text/plain' + r.headers['content-length'] = '5' + r.body = 'hello' + s = str(r) + assert s.startswith('POST /foo/bar/baz.html HTTP/1.0\r\n') + assert s.endswith('\r\n\r\nhello') + assert '\r\ncontent-length: 5\r\n' in s + assert '\r\ncontent-type: text/plain\r\n' in s + r = Request(str(r)) + assert str(r) == s + + def test_chunked_response(self): + s = """HTTP/1.1 200 OK\r\nCache-control: no-cache\r\nPragma: no-cache\r\nContent-Type: text/javascript; charset=utf-8\r\nContent-Encoding: gzip\r\nTransfer-Encoding: chunked\r\nSet-Cookie: S=gmail=agg:gmail_yj=v2s:gmproxy=JkU; Domain=.google.com; Path=/\r\nServer: GFE/1.3\r\nDate: Mon, 12 Dec 2005 22:33:23 GMT\r\n\r\na\r\n\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00\r\n152\r\nm\x91MO\xc4 \x10\x86\xef\xfe\n\x82\xc9\x9eXJK\xe9\xb6\xee\xc1\xe8\x1e6\x9e4\xf1\xe0a5\x86R\xda\x12Yh\x80\xba\xfa\xef\x85\xee\x1a/\xf21\x99\x0c\xef0<\xc3\x81\xa0\xc3\x01\xe6\x10\xc1<\xa7eYT5\xa1\xa4\xac\xe1\xdb\x15:\xa4\x9d\x0c\xfa5K\x00\xf6.\xaa\xeb\x86\xd5y\xcdHY\x954\x8e\xbc*h\x8c\x8e!L7Y\xe6\'\xeb\x82WZ\xcf>8\x1ed\x87\x851X\xd8c\xe6\xbc\x17Z\x89\x8f\xac \x84e\xde\n!]\x96\x17i\xb5\x02{{\xc2z0\x1e\x0f#7\x9cw3v\x992\x9d\xfc\xc2c8\xea[/EP\xd6\xbc\xce\x84\xd0\xce\xab\xf7`\'\x1f\xacS\xd2\xc7\xd2\xfb\x94\x02N\xdc\x04\x0f\xee\xba\x19X\x03TtW\xd7\xb4\xd9\x92\n\xbcX\xa7;\xb0\x9b\'\x10$?F\xfd\xf3CzPt\x8aU\xef\xb8\xc8\x8b-\x18\xed\xec<\xe0\x83\x85\x08!\xf8"[\xb0\xd3j\x82h\x93\xb8\xcf\xd8\x9b\xba\xda\xd0\x92\x14\xa4a\rc\reM\xfd\x87=X;h\xd9j;\xe0db\x17\xc2\x02\xbd\xb0F\xc2in#\xfb:\xb6\xc4x\x15\xd6\x9f\x8a\xaf\xcf)\x0b^\xbc\xe7i\x11\x80\x8b\x00D\x01\xd8/\x82x\xf6\xd8\xf7J(\xae/\x11p\x1f+\xc4p\t:\xfe\xfd\xdf\xa3Y\xfa\xae4\x7f\x00\xc5\xa5\x95\xa1\xe2\x01\x00\x00\r\n0\r\n\r\n""" + r = Response(s) + assert r.version == '1.1' + assert r.status == '200' + assert r.reason == 'OK' + + def test_multicookie_response(self): + s = """HTTP/1.x 200 OK\r\nSet-Cookie: first_cookie=cookie1; path=/; domain=.example.com\r\nSet-Cookie: second_cookie=cookie2; path=/; domain=.example.com\r\nContent-Length: 0\r\n\r\n""" + r = Response(s) + assert type(r.headers['set-cookie']) is list + assert len(r.headers['set-cookie']) == 2 + + def test_request_version(self): + s = """GET / HTTP/1.0\r\n\r\n""" + r = Request(s) + assert r.method == 'GET' + assert r.uri == '/' + assert r.version == '1.0' + + s = """GET /\r\n\r\n""" + r = Request(s) + assert r.method == 'GET' + assert r.uri == '/' + assert r.version == '0.9' + + s = """GET / CHEESE/1.0\r\n\r\n""" + try: + r = Request(s) + assert "invalid protocol version parsed!" + except: + pass + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/icmp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/icmp.py new file mode 100644 index 00000000..37cdec05 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/icmp.py @@ -0,0 +1,122 @@ +# $Id: icmp.py 45 2007-08-03 00:05:22Z jon.oberheide $ + +"""Internet Control Message Protocol.""" + +import dpkt, ip + +# Types (icmp_type) and codes (icmp_code) - +# http://www.iana.org/assignments/icmp-parameters + +ICMP_CODE_NONE = 0 # for types without codes +ICMP_ECHOREPLY = 0 # echo reply +ICMP_UNREACH = 3 # dest unreachable, codes: +ICMP_UNREACH_NET = 0 # bad net +ICMP_UNREACH_HOST = 1 # bad host +ICMP_UNREACH_PROTO = 2 # bad protocol +ICMP_UNREACH_PORT = 3 # bad port +ICMP_UNREACH_NEEDFRAG = 4 # IP_DF caused drop +ICMP_UNREACH_SRCFAIL = 5 # src route failed +ICMP_UNREACH_NET_UNKNOWN = 6 # unknown net +ICMP_UNREACH_HOST_UNKNOWN = 7 # unknown host +ICMP_UNREACH_ISOLATED = 8 # src host isolated +ICMP_UNREACH_NET_PROHIB = 9 # for crypto devs +ICMP_UNREACH_HOST_PROHIB = 10 # ditto +ICMP_UNREACH_TOSNET = 11 # bad tos for net +ICMP_UNREACH_TOSHOST = 12 # bad tos for host +ICMP_UNREACH_FILTER_PROHIB = 13 # prohibited access +ICMP_UNREACH_HOST_PRECEDENCE = 14 # precedence error +ICMP_UNREACH_PRECEDENCE_CUTOFF = 15 # precedence cutoff +ICMP_SRCQUENCH = 4 # packet lost, slow down +ICMP_REDIRECT = 5 # shorter route, codes: +ICMP_REDIRECT_NET = 0 # for network +ICMP_REDIRECT_HOST = 1 # for host +ICMP_REDIRECT_TOSNET = 2 # for tos and net +ICMP_REDIRECT_TOSHOST = 3 # for tos and host +ICMP_ALTHOSTADDR = 6 # alternate host address +ICMP_ECHO = 8 # echo service +ICMP_RTRADVERT = 9 # router advertise, codes: +ICMP_RTRADVERT_NORMAL = 0 # normal +ICMP_RTRADVERT_NOROUTE_COMMON = 16 # selective routing +ICMP_RTRSOLICIT = 10 # router solicitation +ICMP_TIMEXCEED = 11 # time exceeded, code: +ICMP_TIMEXCEED_INTRANS = 0 # ttl==0 in transit +ICMP_TIMEXCEED_REASS = 1 # ttl==0 in reass +ICMP_PARAMPROB = 12 # ip header bad +ICMP_PARAMPROB_ERRATPTR = 0 # req. opt. absent +ICMP_PARAMPROB_OPTABSENT = 1 # req. opt. absent +ICMP_PARAMPROB_LENGTH = 2 # bad length +ICMP_TSTAMP = 13 # timestamp request +ICMP_TSTAMPREPLY = 14 # timestamp reply +ICMP_INFO = 15 # information request +ICMP_INFOREPLY = 16 # information reply +ICMP_MASK = 17 # address mask request +ICMP_MASKREPLY = 18 # address mask reply +ICMP_TRACEROUTE = 30 # traceroute +ICMP_DATACONVERR = 31 # data conversion error +ICMP_MOBILE_REDIRECT = 32 # mobile host redirect +ICMP_IP6_WHEREAREYOU = 33 # IPv6 where-are-you +ICMP_IP6_IAMHERE = 34 # IPv6 i-am-here +ICMP_MOBILE_REG = 35 # mobile registration req +ICMP_MOBILE_REGREPLY = 36 # mobile registration reply +ICMP_DNS = 37 # domain name request +ICMP_DNSREPLY = 38 # domain name reply +ICMP_SKIP = 39 # SKIP +ICMP_PHOTURIS = 40 # Photuris +ICMP_PHOTURIS_UNKNOWN_INDEX = 0 # unknown sec index +ICMP_PHOTURIS_AUTH_FAILED = 1 # auth failed +ICMP_PHOTURIS_DECOMPRESS_FAILED = 2 # decompress failed +ICMP_PHOTURIS_DECRYPT_FAILED = 3 # decrypt failed +ICMP_PHOTURIS_NEED_AUTHN = 4 # no authentication +ICMP_PHOTURIS_NEED_AUTHZ = 5 # no authorization +ICMP_TYPE_MAX = 40 + +class ICMP(dpkt.Packet): + __hdr__ = ( + ('type', 'B', 8), + ('code', 'B', 0), + ('sum', 'H', 0) + ) + class Echo(dpkt.Packet): + __hdr__ = (('id', 'H', 0), ('seq', 'H', 0)) + class Quote(dpkt.Packet): + __hdr__ = (('pad', 'I', 0),) + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.ip = ip.IP(self.data) + class Unreach(Quote): + __hdr__ = (('pad', 'H', 0), ('mtu', 'H', 0)) + class Quench(Quote): + pass + class Redirect(Quote): + __hdr__ = (('gw', 'I', 0),) + class ParamProbe(Quote): + __hdr__ = (('ptr', 'B', 0), ('pad1', 'B', 0), ('pad2', 'H', 0)) + class TimeExceed(Quote): + pass + + _typesw = { 0:Echo, 3:Unreach, 4:Quench, 5:Redirect, 8:Echo, + 11:TimeExceed } + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + try: + self.data = self._typesw[self.type](self.data) + setattr(self, self.data.__class__.__name__.lower(), self.data) + except (KeyError, dpkt.UnpackError): + pass + + def __str__(self): + if not self.sum: + self.sum = dpkt.in_cksum(dpkt.Packet.__str__(self)) + return dpkt.Packet.__str__(self) + +if __name__ == '__main__': + import unittest + + class ICMPTestCase(unittest.TestCase): + def test_ICMP(self): + s = '\x03\x0a\x6b\x19\x00\x00\x00\x00\x45\x00\x00\x28\x94\x1f\x00\x00\xe3\x06\x99\xb4\x23\x2b\x24\x00\xde\x8e\x84\x42\xab\xd1\x00\x50\x00\x35\xe1\x29\x20\xd9\x00\x00\x00\x22\x9b\xf0\xe2\x04\x65\x6b' + icmp = ICMP(s) + self.failUnless(str(icmp) == s) + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/icmp6.py b/scripts/external_libs/dpkt-1.8.6/dpkt/icmp6.py new file mode 100644 index 00000000..5f1d4dae --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/icmp6.py @@ -0,0 +1,72 @@ +# $Id: icmp6.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Internet Control Message Protocol for IPv6.""" + +import dpkt, ip6 + +ICMP6_DST_UNREACH = 1 # dest unreachable, codes: +ICMP6_PACKET_TOO_BIG = 2 # packet too big +ICMP6_TIME_EXCEEDED = 3 # time exceeded, code: +ICMP6_PARAM_PROB = 4 # ip6 header bad + +ICMP6_ECHO_REQUEST = 128 # echo service +ICMP6_ECHO_REPLY = 129 # echo reply +MLD_LISTENER_QUERY = 130 # multicast listener query +MLD_LISTENER_REPORT = 131 # multicast listener report +MLD_LISTENER_DONE = 132 # multicast listener done + +# RFC2292 decls +ICMP6_MEMBERSHIP_QUERY = 130 # group membership query +ICMP6_MEMBERSHIP_REPORT = 131 # group membership report +ICMP6_MEMBERSHIP_REDUCTION = 132 # group membership termination + +ND_ROUTER_SOLICIT = 133 # router solicitation +ND_ROUTER_ADVERT = 134 # router advertisment +ND_NEIGHBOR_SOLICIT = 135 # neighbor solicitation +ND_NEIGHBOR_ADVERT = 136 # neighbor advertisment +ND_REDIRECT = 137 # redirect + +ICMP6_ROUTER_RENUMBERING = 138 # router renumbering + +ICMP6_WRUREQUEST = 139 # who are you request +ICMP6_WRUREPLY = 140 # who are you reply +ICMP6_FQDN_QUERY = 139 # FQDN query +ICMP6_FQDN_REPLY = 140 # FQDN reply +ICMP6_NI_QUERY = 139 # node information request +ICMP6_NI_REPLY = 140 # node information reply + +ICMP6_MAXTYPE = 201 + +class ICMP6(dpkt.Packet): + __hdr__ = ( + ('type', 'B', 0), + ('code', 'B', 0), + ('sum', 'H', 0) + ) + class Error(dpkt.Packet): + __hdr__ = (('pad', 'I', 0), ) + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.ip6 = ip6.IP6(self.data) + class Unreach(Error): + pass + class TooBig(Error): + __hdr__ = (('mtu', 'I', 1232), ) + class TimeExceed(Error): + pass + class ParamProb(Error): + __hdr__ = (('ptr', 'I', 0), ) + + class Echo(dpkt.Packet): + __hdr__ = (('id', 'H', 0), ('seq', 'H', 0)) + + _typesw = { 1:Unreach, 2:TooBig, 3:TimeExceed, 4:ParamProb, + 128:Echo, 129:Echo } + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + try: + self.data = self._typesw[self.type](self.data) + setattr(self, self.data.__class__.__name__.lower(), self.data) + except (KeyError, dpkt.UnpackError): + self.data = buf diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/ieee80211.py b/scripts/external_libs/dpkt-1.8.6/dpkt/ieee80211.py new file mode 100644 index 00000000..8f41e0ac --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/ieee80211.py @@ -0,0 +1,706 @@ +# $Id: 80211.py 53 2008-12-18 01:22:57Z jon.oberheide $ + +"""IEEE 802.11.""" + +import dpkt, socket, struct + +# Frame Types +MGMT_TYPE = 0 +CTL_TYPE = 1 +DATA_TYPE = 2 + +# Frame Sub-Types +M_ASSOC_REQ = 0 +M_ASSOC_RESP = 1 +M_REASSOC_REQ = 2 +M_REASSOC_RESP = 3 +M_PROBE_REQ = 4 +M_PROBE_RESP = 5 +M_BEACON = 8 +M_ATIM = 9 +M_DISASSOC = 10 +M_AUTH = 11 +M_DEAUTH = 12 +M_ACTION = 13 +C_BLOCK_ACK_REQ = 8 +C_BLOCK_ACK = 9 +C_PS_POLL = 10 +C_RTS = 11 +C_CTS = 12 +C_ACK = 13 +C_CF_END = 14 +C_CF_END_ACK = 15 +D_DATA = 0 +D_DATA_CF_ACK = 1 +D_DATA_CF_POLL = 2 +D_DATA_CF_ACK_POLL = 3 +D_NULL = 4 +D_CF_ACK = 5 +D_CF_POLL = 6 +D_CF_ACK_POLL = 7 +D_QOS_DATA = 8 +D_QOS_CF_ACK = 9 +D_QOS_CF_POLL = 10 +D_QOS_CF_ACK_POLL = 11 +D_QOS_NULL = 12 +D_QOS_CF_POLL_EMPTY = 14 + +TO_DS_FLAG = 10 +FROM_DS_FLAG = 1 +INTER_DS_FLAG = 11 + +# Bitshifts for Frame Control +_VERSION_MASK = 0x0300 +_TYPE_MASK = 0x0c00 +_SUBTYPE_MASK = 0xf000 +_TO_DS_MASK = 0x0001 +_FROM_DS_MASK = 0x0002 +_MORE_FRAG_MASK = 0x0004 +_RETRY_MASK = 0x0008 +_PWR_MGT_MASK = 0x0010 +_MORE_DATA_MASK = 0x0020 +_WEP_MASK = 0x0040 +_ORDER_MASK = 0x0080 +_VERSION_SHIFT = 8 +_TYPE_SHIFT = 10 +_SUBTYPE_SHIFT = 12 +_TO_DS_SHIFT = 0 +_FROM_DS_SHIFT = 1 +_MORE_FRAG_SHIFT = 2 +_RETRY_SHIFT = 3 +_PWR_MGT_SHIFT = 4 +_MORE_DATA_SHIFT = 5 +_WEP_SHIFT = 6 +_ORDER_SHIFT = 7 + +# IEs +IE_SSID = 0 +IE_RATES = 1 +IE_FH = 2 +IE_DS = 3 +IE_CF = 4 +IE_TIM = 5 +IE_IBSS = 6 +IE_HT_CAPA = 45 +IE_ESR = 50 +IE_HT_INFO = 61 + +FCS_LENGTH = 4 + +FRAMES_WITH_CAPABILITY = [ M_BEACON, + M_ASSOC_RESP, + M_ASSOC_REQ, + M_REASSOC_REQ, + ] + +# Block Ack control constants +_ACK_POLICY_SHIFT = 0 +_MULTI_TID_SHIFT = 1 +_COMPRESSED_SHIFT = 2 +_TID_SHIFT = 12 + +_ACK_POLICY_MASK = 0x0001 +_MULTI_TID_MASK = 0x0002 +_COMPRESSED_MASK = 0x0004 +_TID_MASK = 0xf000 + +_COMPRESSED_BMP_LENGTH = 8 +_BMP_LENGTH = 128 + +# Action frame categories +BLOCK_ACK = 3 + +# Block ack category action codes +BLOCK_ACK_CODE_REQUEST = 0 +BLOCK_ACK_CODE_RESPONSE = 1 + +class IEEE80211(dpkt.Packet): + __hdr__ = ( + ('framectl', 'H', 0), + ('duration', 'H', 0) + ) + + def _get_version(self): return (self.framectl & _VERSION_MASK) >> _VERSION_SHIFT + def _set_version(self, val): self.framectl = (val << _VERSION_SHIFT) | (self.framectl & ~_VERSION_MASK) + def _get_type(self): return (self.framectl & _TYPE_MASK) >> _TYPE_SHIFT + def _set_type(self, val): self.framectl = (val << _TYPE_SHIFT) | (self.framectl & ~_TYPE_MASK) + def _get_subtype(self): return (self.framectl & _SUBTYPE_MASK) >> _SUBTYPE_SHIFT + def _set_subtype(self, val): self.framectl = (val << _SUBTYPE_SHIFT) | (self.framectl & ~_SUBTYPE_MASK) + def _get_to_ds(self): return (self.framectl & _TO_DS_MASK) >> _TO_DS_SHIFT + def _set_to_ds(self, val): self.framectl = (val << _TO_DS_SHIFT) | (self.framectl & ~_TO_DS_MASK) + def _get_from_ds(self): return (self.framectl & _FROM_DS_MASK) >> _FROM_DS_SHIFT + def _set_from_ds(self, val): self.framectl = (val << _FROM_DS_SHIFT) | (self.framectl & ~_FROM_DS_MASK) + def _get_more_frag(self): return (self.framectl & _MORE_FRAG_MASK) >> _MORE_FRAG_SHIFT + def _set_more_frag(self, val): self.framectl = (val << _MORE_FRAG_SHIFT) | (self.framectl & ~_MORE_FRAG_MASK) + def _get_retry(self): return (self.framectl & _RETRY_MASK) >> _RETRY_SHIFT + def _set_retry(self, val): self.framectl = (val << _RETRY_SHIFT) | (self.framectl & ~_RETRY_MASK) + def _get_pwr_mgt(self): return (self.framectl & _PWR_MGT_MASK) >> _PWR_MGT_SHIFT + def _set_pwr_mgt(self, val): self.framectl = (val << _PWR_MGT_SHIFT) | (self.framectl & ~_PWR_MGT_MASK) + def _get_more_data(self): return (self.framectl & _MORE_DATA_MASK) >> _MORE_DATA_SHIFT + def _set_more_data(self, val): self.framectl = (val << _MORE_DATA_SHIFT) | (self.framectl & ~_MORE_DATA_MASK) + def _get_wep(self): return (self.framectl & _WEP_MASK) >> _WEP_SHIFT + def _set_wep(self, val): self.framectl = (val << _WEP_SHIFT) | (self.framectl & ~_WEP_MASK) + def _get_order(self): return (self.framectl & _ORDER_MASK) >> _ORDER_SHIFT + def _set_order(self, val): self.framectl = (val << _ORDER_SHIFT) | (self.framectl & ~_ORDER_MASK) + + version = property(_get_version, _set_version) + type = property(_get_type, _set_type) + subtype = property(_get_subtype, _set_subtype) + to_ds = property(_get_to_ds, _set_to_ds) + from_ds = property(_get_from_ds, _set_from_ds) + more_frag = property(_get_more_frag, _set_more_frag) + retry = property(_get_retry, _set_retry) + pwr_mgt = property(_get_pwr_mgt, _set_pwr_mgt) + more_data = property(_get_more_data, _set_more_data) + wep = property(_get_wep, _set_wep) + order = property(_get_order, _set_order) + + def unpack_ies(self, buf): + self.ies = [] + + ie_decoder = { + IE_SSID: ('ssid', self.IE), + IE_RATES: ('rate', self.IE), + IE_FH: ('fh', self.FH), + IE_DS: ('ds', self.DS), + IE_CF: ('cf', self.CF), + IE_TIM: ('tim', self.TIM), + IE_IBSS: ('ibss', self.IBSS), + IE_HT_CAPA: ('ht_capa', self.IE), + IE_ESR: ('esr', self.IE), + IE_HT_INFO: ('ht_info', self.IE) + } + + # each IE starts with an ID and a length + while len(buf) > FCS_LENGTH: + ie_id = struct.unpack('B',(buf[0]))[0] + try: + parser = ie_decoder[ie_id][1] + name = ie_decoder[ie_id][0] + except KeyError: + parser = self.IE + name = 'ie_' + str(ie_id) + ie = parser(buf) + + ie.data = buf[2:2+ie.len] + setattr(self, name, ie) + self.ies.append(ie) + buf = buf[2+ie.len:] + + class Capability: + def __init__(self, field): + self.ess = field & 1 + self.ibss = (field >> 1) & 1 + self.cf_poll = (field >> 2) & 1 + self.cf_poll_req = (field >> 3) & 1 + self.privacy = (field >> 4) & 1 + self.short_preamble = (field >> 5) & 1 + self.pbcc = (field >> 6) & 1 + self.hopping = (field >> 7) & 1 + self.spec_mgmt = (field >> 8) & 1 + self.qos = (field >> 9) & 1 + self.short_slot = (field >> 10) & 1 + self.apsd = (field >> 11) & 1 + self.dsss = (field >> 13) & 1 + self.delayed_blk_ack = (field >> 14) & 1 + self.imm_blk_ack = (field >> 15) & 1 + + def __init__(self, *args, **kwargs): + if kwargs and 'fcs' in kwargs: + self.fcs_present = kwargs.pop('fcs') + else: + self.fcs_present = False + + super(IEEE80211, self).__init__(*args, **kwargs) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = buf[self.__hdr_len__:] + + m_decoder = { + M_BEACON: ('beacon', self.Beacon), + M_ASSOC_REQ: ('assoc_req', self.Assoc_Req), + M_ASSOC_RESP: ('assoc_resp', self.Assoc_Resp), + M_DISASSOC: ('diassoc', self.Disassoc), + M_REASSOC_REQ: ('reassoc_req', self.Reassoc_Req), + M_REASSOC_RESP: ('reassoc_resp',self.Assoc_Resp), + M_AUTH: ('auth', self.Auth), + M_PROBE_RESP: ('probe_resp', self.Beacon), + M_DEAUTH: ('deauth', self.Deauth), + M_ACTION: ('action', self.Action) + } + + c_decoder = { + C_RTS: ('rts', self.RTS), + C_CTS: ('cts', self.CTS), + C_ACK: ('ack', self.ACK), + C_BLOCK_ACK_REQ:('bar', self.BlockAckReq), + C_BLOCK_ACK: ('back', self.BlockAck), + C_CF_END: ('cf_end', self.CFEnd), + } + + d_dsData = { + 0 : self.Data, + FROM_DS_FLAG : self.DataFromDS, + TO_DS_FLAG : self.DataToDS, + INTER_DS_FLAG : self.DataInterDS + } + + + # For now decode everything with DATA. Haven't checked about other QoS + # additions + d_decoder = { + # modified the decoder to consider the ToDS and FromDS flags + # Omitting the 11 case for now + D_DATA: ('data_frame', d_dsData), + D_NULL: ('data_frame', d_dsData), + D_QOS_DATA: ('data_frame', d_dsData), + D_QOS_NULL: ('data_frame', d_dsData) + } + + decoder = { + MGMT_TYPE:m_decoder, + CTL_TYPE:c_decoder, + DATA_TYPE:d_decoder + } + + # Strip off the FCS field + if self.fcs_present: + self.fcs = struct.unpack('I', self.data[-1 * FCS_LENGTH:])[0] + self.data = self.data[0: -1 * FCS_LENGTH] + + if self.type == MGMT_TYPE: + self.mgmt = self.MGMT_Frame(self.data) + self.data = self.mgmt.data + if self.subtype == M_PROBE_REQ: + self.unpack_ies(self.data) + return + if self.subtype == M_ATIM: + return + + try: + parser = decoder[self.type][self.subtype][1] + name = decoder[self.type][self.subtype][0] + except KeyError: + print "Key error:", self.type, self.subtype + return + + if self.type == DATA_TYPE: + # need to grab the ToDS/FromDS info + parser = parser[self.to_ds*10+self.from_ds] + + if self.type == MGMT_TYPE: + field = parser(self.mgmt.data) + else: + field = parser(self.data) + self.data = field + + setattr(self, name, field) + + if self.type == MGMT_TYPE: + self.ies = self.unpack_ies(field.data) + if self.subtype in FRAMES_WITH_CAPABILITY: + self.capability = self.Capability(socket.ntohs(field.capability)) + + if self.type == DATA_TYPE and self.subtype == D_QOS_DATA: + self.qos_data = self.QoS_Data(field.data) + field.data = self.qos_data.data + + self.data = field.data + + class BlockAckReq(dpkt.Packet): + __hdr__ = ( + ('dst', '6s', '\x00' * 6), + ('src', '6s', '\x00' *6), + ('ctl', 'H', 0), + ('seq', 'H', 0), + ) + + class BlockAck(dpkt.Packet): + __hdr__ = ( + ('dst', '6s', '\x00' * 6), + ('src', '6s', '\x00' * 6), + ('ctl', 'H', 0), + ('seq', 'H', 0), + ) + + def _get_compressed(self): return (self.ctl & _COMPRESSED_MASK) >> _COMPRESSED_SHIFT + def _set_compressed(self, val): self.ctl = (val << _COMPRESSED_SHIFT) | (self.ctl & ~_COMPRESSED_MASK) + + def _get_ack_policy(self): return (self.ctl & _ACK_POLICY_MASK) >> _ACK_POLICY_SHIFT + def _set_ack_policy(self, val): self.ctl = (val << _ACK_POLICY_SHIFT) | (self.ctl & ~_ACK_POLICY_MASK) + + def _get_multi_tid(self): return (self.ctl & _MULTI_TID_MASK) >> _MULTI_TID_SHIFT + def _set_multi_tid(self, val): self.ctl = (val << _MULTI_TID_SHIFT) | (self.ctl & ~_MULTI_TID_MASK) + + def _get_tid(self): return (self.ctl & _TID_MASK) >> _TID_SHIFT + def _set_tid(self, val): self.ctl = (val << _TID_SHIFT) | (self.ctl & ~_TID_MASK) + + compressed = property(_get_compressed, _set_compressed) + ack_policy = property(_get_ack_policy, _set_ack_policy) + multi_tid = property(_get_multi_tid, _set_multi_tid) + tid = property(_get_tid, _set_tid) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = buf[self.__hdr_len__:] + self.ctl = socket.ntohs(self.ctl) + + if self.compressed: + self.bmp = struct.unpack('8s', self.data[0:_COMPRESSED_BMP_LENGTH])[0] + else: + self.bmp = struct.unpack('128s', self.data[0:_BMP_LENGTH])[0] + self.data = self.data[len(self.__hdr__) + len(self.bmp):] + + class RTS(dpkt.Packet): + __hdr__ = ( + ('dst', '6s', '\x00' * 6), + ('src', '6s', '\x00' * 6) + ) + + class CTS(dpkt.Packet): + __hdr__ = ( + ('dst', '6s', '\x00' * 6), + ) + + class ACK(dpkt.Packet): + __hdr__ = ( + ('dst', '6s', '\x00' * 6), + ) + + class CFEnd(dpkt.Packet): + __hdr__ = ( + ('dst', '6s', '\x00' *6), + ('src', '6s', '\x00' *6), + ) + + class MGMT_Frame(dpkt.Packet): + __hdr__ = ( + ('dst', '6s', '\x00' *6), + ('src', '6s', '\x00' *6), + ('bssid', '6s', '\x00' *6), + ('frag_seq', 'H', 0) + ) + + class Beacon(dpkt.Packet): + __hdr__ = ( + ('timestamp', 'Q', 0), + ('interval', 'H', 0), + ('capability', 'H', 0) + ) + + class Disassoc(dpkt.Packet): + __hdr__ = ( + ('reason', 'H', 0), + ) + + class Assoc_Req(dpkt.Packet): + __hdr__ = ( + ('capability', 'H', 0), + ('interval', 'H', 0) + ) + + class Assoc_Resp(dpkt.Packet): + __hdr__ = ( + ('capability', 'H', 0), + ('status', 'H', 0), + ('aid', 'H', 0) + ) + + class Reassoc_Req(dpkt.Packet): + __hdr__ = ( + ('capability', 'H', 0), + ('interval', 'H', 0), + ('current_ap', '6s', '\x00'*6) + ) + + # This obviously doesn't support any of AUTH frames that use encryption + class Auth(dpkt.Packet): + __hdr__ = ( + ('algorithm', 'H', 0), + ('auth_seq', 'H', 0), + ) + + class Deauth(dpkt.Packet): + __hdr__ = ( + ('reason', 'H', 0), + ) + + class Action(dpkt.Packet): + __hdr__ = ( + ('category', 'B', 0), + ('code', 'B', 0), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + + action_parser = { + BLOCK_ACK: { BLOCK_ACK_CODE_REQUEST: ('block_ack_request', IEEE80211.BlockAckActionRequest), + BLOCK_ACK_CODE_RESPONSE: ('block_ack_response', IEEE80211.BlockAckActionResponse), + }, + } + + decoder = action_parser[self.category][self.code][1] + field_name = action_parser[self.category][self.code][0] + field = decoder(self.data) + setattr(self, field_name, field) + self.data = field.data + + class BlockAckActionRequest(dpkt.Packet): + __hdr__ = ( + ('dialog', 'B', 0), + ('parameters', 'H', 0), + ('timeout', 'H', 0), + ('starting_seq', 'H', 0), + ) + + class BlockAckActionResponse(dpkt.Packet): + __hdr__ = ( + ('dialog', 'B', 0), + ('status_code', 'H', 0), + ('parameters', 'H', 0), + ('timeout', 'H', 0), + ) + + class Data(dpkt.Packet): + __hdr__ = ( + ('dst', '6s', '\x00'*6), + ('src', '6s', '\x00'*6), + ('bssid', '6s', '\x00'*6), + ('frag_seq', 'H', 0) + ) + + + class DataFromDS(dpkt.Packet): + __hdr__ = ( + ('dst', '6s', '\x00'*6), + ('bssid', '6s', '\x00'*6), + ('src', '6s', '\x00'*6), + ('frag_seq', 'H', 0) + ) + + + class DataToDS(dpkt.Packet): + __hdr__ = ( + ('bssid', '6s', '\x00'*6), + ('src', '6s', '\x00'*6), + ('dst', '6s', '\x00'*6), + ('frag_seq', 'H', 0) + ) + + class DataInterDS(dpkt.Packet): + __hdr__ = ( + ('dst', '6s', '\x00'*6), + ('src', '6s', '\x00'*6), + ('da', '6s', '\x00'*6), + ('frag_seq', 'H', 0), + ('sa', '6s', '\x00'*6) + ) + + class QoS_Data(dpkt.Packet): + __hdr__ = ( + ('control', 'H', 0), + ) + + class IE(dpkt.Packet): + __hdr__ = ( + ('id', 'B', 0), + ('len', 'B', 0) + ) + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.info = buf[2:self.len+ 2] + + class FH(dpkt.Packet): + __hdr__ = ( + ('id', 'B', 0), + ('len', 'B', 0), + ('tu', 'H', 0), + ('hopset', 'B', 0), + ('hoppattern', 'B', 0), + ('hopindex', 'B', 0) + ) + + class DS(dpkt.Packet): + __hdr__ = ( + ('id', 'B', 0), + ('len', 'B', 0), + ('ch', 'B', 0) + ) + + class CF(dpkt.Packet): + __hdr__ = ( + ('id', 'B', 0), + ('len', 'B', 0), + ('count', 'B', 0), + ('period', 'B', 0), + ('max', 'H', 0), + ('dur', 'H', 0) + ) + + class TIM(dpkt.Packet): + __hdr__ = ( + ('id', 'B', 0), + ('len', 'B', 0), + ('count', 'B', 0), + ('period', 'B', 0), + ('ctrl', 'H', 0) + ) + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.bitmap = buf[5:self.len+ 2] + + class IBSS(dpkt.Packet): + __hdr__ = ( + ('id', 'B', 0), + ('len', 'B', 0), + ('atim', 'H', 0) + ) + + + +if __name__ == '__main__': + import unittest + + class IEEE80211TestCase(unittest.TestCase): + def test_802211_ack(self): + s = '\xd4\x00\x00\x00\x00\x12\xf0\xb6\x1c\xa4\xff\xff\xff\xff' + ieee = IEEE80211(s, fcs = True) + self.failUnless(ieee.version == 0) + self.failUnless(ieee.type == CTL_TYPE) + self.failUnless(ieee.subtype == C_ACK) + self.failUnless(ieee.to_ds == 0) + self.failUnless(ieee.from_ds == 0) + self.failUnless(ieee.pwr_mgt == 0) + self.failUnless(ieee.more_data == 0) + self.failUnless(ieee.wep == 0) + self.failUnless(ieee.order == 0) + self.failUnless(ieee.ack.dst == '\x00\x12\xf0\xb6\x1c\xa4') + fcs = struct.unpack('I', s[-4:])[0] + self.failUnless(ieee.fcs == fcs) + + def test_80211_beacon(self): + s = '\x80\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x26\xcb\x18\x6a\x30\x00\x26\xcb\x18\x6a\x30\xa0\xd0\x77\x09\x32\x03\x8f\x00\x00\x00\x66\x00\x31\x04\x00\x04\x43\x41\x45\x4e\x01\x08\x82\x84\x8b\x0c\x12\x96\x18\x24\x03\x01\x01\x05\x04\x00\x01\x00\x00\x07\x06\x55\x53\x20\x01\x0b\x1a\x0b\x05\x00\x00\x6e\x00\x00\x2a\x01\x02\x2d\x1a\x6e\x18\x1b\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x14\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x28\x00\x32\x04\x30\x48\x60\x6c\x36\x03\x51\x63\x03\x3d\x16\x01\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x1e\x05\x00\x8f\x00\x0f\x00\xff\x03\x59\x00\x63\x73\x65\x2d\x33\x39\x31\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x36\x96\x06\x00\x40\x96\x00\x14\x00\xdd\x18\x00\x50\xf2\x02\x01\x01\x80\x00\x03\xa4\x00\x00\x27\xa4\x00\x00\x42\x43\x5e\x00\x62\x32\x2f\x00\xdd\x06\x00\x40\x96\x01\x01\x04\xdd\x05\x00\x40\x96\x03\x05\xdd\x05\x00\x40\x96\x0b\x09\xdd\x08\x00\x40\x96\x13\x01\x00\x34\x01\xdd\x05\x00\x40\x96\x14\x05' + ieee = IEEE80211(s, fcs = True) + self.failUnless(ieee.version == 0) + self.failUnless(ieee.type == MGMT_TYPE) + self.failUnless(ieee.subtype == M_BEACON) + self.failUnless(ieee.to_ds == 0) + self.failUnless(ieee.from_ds == 0) + self.failUnless(ieee.pwr_mgt == 0) + self.failUnless(ieee.more_data == 0) + self.failUnless(ieee.wep == 0) + self.failUnless(ieee.order == 0) + self.failUnless(ieee.mgmt.dst == '\xff\xff\xff\xff\xff\xff') + self.failUnless(ieee.mgmt.src == '\x00\x26\xcb\x18\x6a\x30') + self.failUnless(ieee.beacon.capability == 0x3104) + self.failUnless(ieee.capability.privacy == 1) + self.failUnless(ieee.ssid.data == 'CAEN') + self.failUnless(ieee.rate.data == '\x82\x84\x8b\x0c\x12\x96\x18\x24') + self.failUnless(ieee.ds.data == '\x01') + self.failUnless(ieee.tim.data == '\x00\x01\x00\x00') + fcs = struct.unpack('I', s[-4:])[0] + self.failUnless(ieee.fcs == fcs) + + def test_80211_data(self): + s = '\x08\x09\x20\x00\x00\x26\xcb\x17\x3d\x91\x00\x16\x44\xb0\xae\xc6\x00\x02\xb3\xd6\x26\x3c\x80\x7e\xaa\xaa\x03\x00\x00\x00\x08\x00\x45\x00\x00\x28\x07\x27\x40\x00\x80\x06\x1d\x39\x8d\xd4\x37\x3d\x3f\xf5\xd1\x69\xc0\x5f\x01\xbb\xb2\xd6\xef\x23\x38\x2b\x4f\x08\x50\x10\x42\x04\xac\x17\x00\x00' + ieee = IEEE80211(s, fcs = True) + self.failUnless(ieee.type == DATA_TYPE) + self.failUnless(ieee.subtype == D_DATA) + self.failUnless(ieee.data_frame.dst == '\x00\x02\xb3\xd6\x26\x3c') + self.failUnless(ieee.data_frame.src == '\x00\x16\x44\xb0\xae\xc6') + self.failUnless(ieee.data_frame.frag_seq == 0x807e) + self.failUnless(ieee.data == '\xaa\xaa\x03\x00\x00\x00\x08\x00\x45\x00\x00\x28\x07\x27\x40\x00\x80\x06\x1d\x39\x8d\xd4\x37\x3d\x3f\xf5\xd1\x69\xc0\x5f\x01\xbb\xb2\xd6\xef\x23\x38\x2b\x4f\x08\x50\x10\x42\x04') + self.failUnless(ieee.fcs == struct.unpack('I', '\xac\x17\x00\x00')[0]) + + import llc, ip + llc_pkt = llc.LLC(ieee.data_frame.data) + ip_pkt = ip.IP(llc_pkt.data) + self.failUnless(ip_pkt.dst == '\x3f\xf5\xd1\x69') + + def test_80211_data_qos(self): + s = '\x88\x01\x3a\x01\x00\x26\xcb\x17\x44\xf0\x00\x23\xdf\xc9\xc0\x93\x00\x26\xcb\x17\x44\xf0\x20\x7b\x00\x00\xaa\xaa\x03\x00\x00\x00\x88\x8e\x01\x00\x00\x74\x02\x02\x00\x74\x19\x80\x00\x00\x00\x6a\x16\x03\x01\x00\x65\x01\x00\x00\x61\x03\x01\x4b\x4c\xa7\x7e\x27\x61\x6f\x02\x7b\x3c\x72\x39\xe3\x7b\xd7\x43\x59\x91\x7f\xaa\x22\x47\x51\xb6\x88\x9f\x85\x90\x87\x5a\xd1\x13\x20\xe0\x07\x00\x00\x68\xbd\xa4\x13\xb0\xd5\x82\x7e\xc7\xfb\xe7\xcc\xab\x6e\x5d\x5a\x51\x50\xd4\x45\xc5\xa1\x65\x53\xad\xb5\x88\x5b\x00\x1a\x00\x2f\x00\x05\x00\x04\x00\x35\x00\x0a\x00\x09\x00\x03\x00\x08\x00\x33\x00\x39\x00\x16\x00\x15\x00\x14\x01\x00\xff\xff\xff\xff' + ieee = IEEE80211(s, fcs = True) + self.failUnless(ieee.type == DATA_TYPE) + self.failUnless(ieee.subtype == D_QOS_DATA) + self.failUnless(ieee.data_frame.dst == '\x00\x26\xcb\x17\x44\xf0') + self.failUnless(ieee.data_frame.src == '\x00\x23\xdf\xc9\xc0\x93') + self.failUnless(ieee.data_frame.frag_seq == 0x207b) + self.failUnless(ieee.data == '\xaa\xaa\x03\x00\x00\x00\x88\x8e\x01\x00\x00\x74\x02\x02\x00\x74\x19\x80\x00\x00\x00\x6a\x16\x03\x01\x00\x65\x01\x00\x00\x61\x03\x01\x4b\x4c\xa7\x7e\x27\x61\x6f\x02\x7b\x3c\x72\x39\xe3\x7b\xd7\x43\x59\x91\x7f\xaa\x22\x47\x51\xb6\x88\x9f\x85\x90\x87\x5a\xd1\x13\x20\xe0\x07\x00\x00\x68\xbd\xa4\x13\xb0\xd5\x82\x7e\xc7\xfb\xe7\xcc\xab\x6e\x5d\x5a\x51\x50\xd4\x45\xc5\xa1\x65\x53\xad\xb5\x88\x5b\x00\x1a\x00\x2f\x00\x05\x00\x04\x00\x35\x00\x0a\x00\x09\x00\x03\x00\x08\x00\x33\x00\x39\x00\x16\x00\x15\x00\x14\x01\x00') + self.failUnless(ieee.qos_data.control == 0x0) + self.failUnless(ieee.fcs == struct.unpack('I', '\xff\xff\xff\xff')[0]) + + def test_bug(self): + s = '\x88\x41\x2c\x00\x00\x26\xcb\x17\x44\xf0\x00\x1e\x52\x97\x14\x11\x00\x1f\x6d\xe8\x18\x00\xd0\x07\x00\x00\x6f\x00\x00\x20\x00\x00\x00\x00' + ieee = IEEE80211(s) + self.failUnless(ieee.wep == 1) + + def test_data_ds(self): + # verifying the ToDS and FromDS fields and that we're getting the + # correct values + + s = '\x08\x03\x00\x00\x01\x0b\x85\x00\x00\x00\x00\x26\xcb\x18\x73\x50\x01\x0b\x85\x00\x00\x00\x00\x89\x00\x26\xcb\x18\x73\x50' + ieee = IEEE80211(s) + self.failUnless(ieee.type == DATA_TYPE) + self.failUnless(ieee.to_ds == 1) + self.failUnless(ieee.from_ds == 1) + self.failUnless(ieee.data_frame.sa == '\x00\x26\xcb\x18\x73\x50') + self.failUnless(ieee.data_frame.src == '\x00\x26\xcb\x18\x73\x50') + self.failUnless(ieee.data_frame.dst == '\x01\x0b\x85\x00\x00\x00') + self.failUnless(ieee.data_frame.da == '\x01\x0b\x85\x00\x00\x00') + + s = '\x88\x41\x50\x01\x00\x26\xcb\x17\x48\xc1\x00\x24\x2c\xe7\xfe\x8a\xff\xff\xff\xff\xff\xff\x80\xa0\x00\x00\x09\x1a\x00\x20\x00\x00\x00\x00' + ieee = IEEE80211(s) + self.failUnless(ieee.type == DATA_TYPE) + self.failUnless(ieee.to_ds == 1) + self.failUnless(ieee.from_ds == 0) + self.failUnless(ieee.data_frame.bssid == '\x00\x26\xcb\x17\x48\xc1') + self.failUnless(ieee.data_frame.src == '\x00\x24\x2c\xe7\xfe\x8a') + self.failUnless(ieee.data_frame.dst == '\xff\xff\xff\xff\xff\xff') + + s = '\x08\x02\x02\x01\x00\x02\x44\xac\x27\x70\x00\x1f\x33\x39\x75\x44\x00\x1f\x33\x39\x75\x44\x90\xa4' + ieee = IEEE80211(s) + self.failUnless(ieee.type == DATA_TYPE) + self.failUnless(ieee.to_ds == 0) + self.failUnless(ieee.from_ds == 1) + self.failUnless(ieee.data_frame.bssid == '\x00\x1f\x33\x39\x75\x44') + self.failUnless(ieee.data_frame.src == '\x00\x1f\x33\x39\x75\x44') + self.failUnless(ieee.data_frame.dst == '\x00\x02\x44\xac\x27\x70') + + def test_compressed_block_ack(self): + s = '\x94\x00\x00\x00\x34\xc0\x59\xd6\x3f\x62\xb4\x75\x0e\x46\x83\xc1\x05\x50\x80\xee\x03\x00\x00\x00\x00\x00\x00\x00\xa2\xe4\x98\x45' + ieee = IEEE80211(s, fcs = True) + self.failUnless(ieee.type == CTL_TYPE) + self.failUnless(ieee.subtype == C_BLOCK_ACK) + self.failUnless(ieee.back.dst == '\x34\xc0\x59\xd6\x3f\x62') + self.failUnless(ieee.back.src == '\xb4\x75\x0e\x46\x83\xc1') + self.failUnless(ieee.back.compressed == 1) + self.failUnless(len(ieee.back.bmp) == 8) + self.failUnless(ieee.back.ack_policy == 1) + self.failUnless(ieee.back.tid == 5) + + def test_action_block_ack_request(self): + s = '\xd0\x00\x3a\x01\x00\x23\x14\x36\x52\x30\xb4\x75\x0e\x46\x83\xc1\xb4\x75\x0e\x46\x83\xc1\x70\x14\x03\x00\x0d\x02\x10\x00\x00\x40\x29\x06\x50\x33\x9e' + ieee = IEEE80211(s, fcs = True) + self.failUnless(ieee.type == MGMT_TYPE) + self.failUnless(ieee.subtype == M_ACTION) + self.failUnless(ieee.action.category == BLOCK_ACK) + self.failUnless(ieee.action.code == BLOCK_ACK_CODE_REQUEST) + self.failUnless(ieee.action.block_ack_request.timeout == 0) + parameters = struct.unpack('H', '\x10\x02')[0] + self.failUnless(ieee.action.block_ack_request.parameters == parameters) + + def test_action_block_ack_response(self): + s = '\xd0\x00\x3c\x00\xb4\x75\x0e\x46\x83\xc1\x00\x23\x14\x36\x52\x30\xb4\x75\x0e\x46\x83\xc1\xd0\x68\x03\x01\x0d\x00\x00\x02\x10\x88\x13\x9f\xc0\x0b\x75' + ieee = IEEE80211(s, fcs = True) + self.failUnless(ieee.type == MGMT_TYPE) + self.failUnless(ieee.subtype == M_ACTION) + self.failUnless(ieee.action.category == BLOCK_ACK) + self.failUnless(ieee.action.code == BLOCK_ACK_CODE_RESPONSE) + timeout = struct.unpack('H', '\x13\x88')[0] + self.failUnless(ieee.action.block_ack_response.timeout == timeout) + parameters = struct.unpack('H', '\x10\x02')[0] + self.failUnless(ieee.action.block_ack_response.parameters == parameters) + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/igmp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/igmp.py new file mode 100644 index 00000000..8031fa72 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/igmp.py @@ -0,0 +1,17 @@ +# $Id: igmp.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Internet Group Management Protocol.""" + +import dpkt + +class IGMP(dpkt.Packet): + __hdr__ = ( + ('type', 'B', 0), + ('maxresp', 'B', 0), + ('sum', 'H', 0), + ('group', 'I', 0) + ) + def __str__(self): + if not self.sum: + self.sum = dpkt.in_cksum(dpkt.Packet.__str__(self)) + return dpkt.Packet.__str__(self) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/ip.py b/scripts/external_libs/dpkt-1.8.6/dpkt/ip.py new file mode 100644 index 00000000..a8f9bd96 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/ip.py @@ -0,0 +1,301 @@ +# $Id: ip.py 87 2013-03-05 19:41:04Z andrewflnr@gmail.com $ + +"""Internet Protocol.""" + +import dpkt + +class IP(dpkt.Packet): + __hdr__ = ( + ('v_hl', 'B', (4 << 4) | (20 >> 2)), + ('tos', 'B', 0), + ('len', 'H', 20), + ('id', 'H', 0), + ('off', 'H', 0), + ('ttl', 'B', 64), + ('p', 'B', 0), + ('sum', 'H', 0), + ('src', '4s', '\x00' * 4), + ('dst', '4s', '\x00' * 4) + ) + _protosw = {} + opts = '' + + def _get_v(self): return self.v_hl >> 4 + def _set_v(self, v): self.v_hl = (v << 4) | (self.v_hl & 0xf) + v = property(_get_v, _set_v) + + def _get_hl(self): return self.v_hl & 0xf + def _set_hl(self, hl): self.v_hl = (self.v_hl & 0xf0) | hl + hl = property(_get_hl, _set_hl) + + def __len__(self): + return self.__hdr_len__ + len(self.opts) + len(self.data) + + def __str__(self): + if self.sum == 0: + self.sum = dpkt.in_cksum(self.pack_hdr() + self.opts) + if (self.p == 6 or self.p == 17) and \ + (self.off & (IP_MF|IP_OFFMASK)) == 0 and \ + isinstance(self.data, dpkt.Packet) and self.data.sum == 0: + # Set zeroed TCP and UDP checksums for non-fragments. + p = str(self.data) + s = dpkt.struct.pack('>4s4sxBH', self.src, self.dst, + self.p, len(p)) + s = dpkt.in_cksum_add(0, s) + s = dpkt.in_cksum_add(s, p) + self.data.sum = dpkt.in_cksum_done(s) + if self.p == 17 and self.data.sum == 0: + self.data.sum = 0xffff # RFC 768 + # XXX - skip transports which don't need the pseudoheader + return self.pack_hdr() + self.opts + str(self.data) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + ol = ((self.v_hl & 0xf) << 2) - self.__hdr_len__ + if ol < 0: + raise dpkt.UnpackError, 'invalid header length' + self.opts = buf[self.__hdr_len__:self.__hdr_len__ + ol] + if self.len: + buf = buf[self.__hdr_len__ + ol:self.len] + else: # very likely due to TCP segmentation offload + buf = buf[self.__hdr_len__ + ol:] + try: + self.data = self._protosw[self.p](buf) + setattr(self, self.data.__class__.__name__.lower(), self.data) + except (KeyError, dpkt.UnpackError): + self.data = buf + + def set_proto(cls, p, pktclass): + cls._protosw[p] = pktclass + set_proto = classmethod(set_proto) + + def get_proto(cls, p): + return cls._protosw[p] + get_proto = classmethod(get_proto) + +# Type of service (ip_tos), RFC 1349 ("obsoleted by RFC 2474") +IP_TOS_DEFAULT = 0x00 # default +IP_TOS_LOWDELAY = 0x10 # low delay +IP_TOS_THROUGHPUT = 0x08 # high throughput +IP_TOS_RELIABILITY = 0x04 # high reliability +IP_TOS_LOWCOST = 0x02 # low monetary cost - XXX +IP_TOS_ECT = 0x02 # ECN-capable transport +IP_TOS_CE = 0x01 # congestion experienced + +# IP precedence (high 3 bits of ip_tos), hopefully unused +IP_TOS_PREC_ROUTINE = 0x00 +IP_TOS_PREC_PRIORITY = 0x20 +IP_TOS_PREC_IMMEDIATE = 0x40 +IP_TOS_PREC_FLASH = 0x60 +IP_TOS_PREC_FLASHOVERRIDE = 0x80 +IP_TOS_PREC_CRITIC_ECP = 0xa0 +IP_TOS_PREC_INTERNETCONTROL = 0xc0 +IP_TOS_PREC_NETCONTROL = 0xe0 + +# Fragmentation flags (ip_off) +IP_RF = 0x8000 # reserved +IP_DF = 0x4000 # don't fragment +IP_MF = 0x2000 # more fragments (not last frag) +IP_OFFMASK = 0x1fff # mask for fragment offset + +# Time-to-live (ip_ttl), seconds +IP_TTL_DEFAULT = 64 # default ttl, RFC 1122, RFC 1340 +IP_TTL_MAX = 255 # maximum ttl + +# Protocol (ip_p) - http://www.iana.org/assignments/protocol-numbers +IP_PROTO_IP = 0 # dummy for IP +IP_PROTO_HOPOPTS = IP_PROTO_IP # IPv6 hop-by-hop options +IP_PROTO_ICMP = 1 # ICMP +IP_PROTO_IGMP = 2 # IGMP +IP_PROTO_GGP = 3 # gateway-gateway protocol +IP_PROTO_IPIP = 4 # IP in IP +IP_PROTO_ST = 5 # ST datagram mode +IP_PROTO_TCP = 6 # TCP +IP_PROTO_CBT = 7 # CBT +IP_PROTO_EGP = 8 # exterior gateway protocol +IP_PROTO_IGP = 9 # interior gateway protocol +IP_PROTO_BBNRCC = 10 # BBN RCC monitoring +IP_PROTO_NVP = 11 # Network Voice Protocol +IP_PROTO_PUP = 12 # PARC universal packet +IP_PROTO_ARGUS = 13 # ARGUS +IP_PROTO_EMCON = 14 # EMCON +IP_PROTO_XNET = 15 # Cross Net Debugger +IP_PROTO_CHAOS = 16 # Chaos +IP_PROTO_UDP = 17 # UDP +IP_PROTO_MUX = 18 # multiplexing +IP_PROTO_DCNMEAS = 19 # DCN measurement +IP_PROTO_HMP = 20 # Host Monitoring Protocol +IP_PROTO_PRM = 21 # Packet Radio Measurement +IP_PROTO_IDP = 22 # Xerox NS IDP +IP_PROTO_TRUNK1 = 23 # Trunk-1 +IP_PROTO_TRUNK2 = 24 # Trunk-2 +IP_PROTO_LEAF1 = 25 # Leaf-1 +IP_PROTO_LEAF2 = 26 # Leaf-2 +IP_PROTO_RDP = 27 # "Reliable Datagram" proto +IP_PROTO_IRTP = 28 # Inet Reliable Transaction +IP_PROTO_TP = 29 # ISO TP class 4 +IP_PROTO_NETBLT = 30 # Bulk Data Transfer +IP_PROTO_MFPNSP = 31 # MFE Network Services +IP_PROTO_MERITINP = 32 # Merit Internodal Protocol +IP_PROTO_SEP = 33 # Sequential Exchange proto +IP_PROTO_3PC = 34 # Third Party Connect proto +IP_PROTO_IDPR = 35 # Interdomain Policy Route +IP_PROTO_XTP = 36 # Xpress Transfer Protocol +IP_PROTO_DDP = 37 # Datagram Delivery Proto +IP_PROTO_CMTP = 38 # IDPR Ctrl Message Trans +IP_PROTO_TPPP = 39 # TP++ Transport Protocol +IP_PROTO_IL = 40 # IL Transport Protocol +IP_PROTO_IP6 = 41 # IPv6 +IP_PROTO_SDRP = 42 # Source Demand Routing +IP_PROTO_ROUTING = 43 # IPv6 routing header +IP_PROTO_FRAGMENT = 44 # IPv6 fragmentation header +IP_PROTO_RSVP = 46 # Reservation protocol +IP_PROTO_GRE = 47 # General Routing Encap +IP_PROTO_MHRP = 48 # Mobile Host Routing +IP_PROTO_ENA = 49 # ENA +IP_PROTO_ESP = 50 # Encap Security Payload +IP_PROTO_AH = 51 # Authentication Header +IP_PROTO_INLSP = 52 # Integated Net Layer Sec +IP_PROTO_SWIPE = 53 # SWIPE +IP_PROTO_NARP = 54 # NBMA Address Resolution +IP_PROTO_MOBILE = 55 # Mobile IP, RFC 2004 +IP_PROTO_TLSP = 56 # Transport Layer Security +IP_PROTO_SKIP = 57 # SKIP +IP_PROTO_ICMP6 = 58 # ICMP for IPv6 +IP_PROTO_NONE = 59 # IPv6 no next header +IP_PROTO_DSTOPTS = 60 # IPv6 destination options +IP_PROTO_ANYHOST = 61 # any host internal proto +IP_PROTO_CFTP = 62 # CFTP +IP_PROTO_ANYNET = 63 # any local network +IP_PROTO_EXPAK = 64 # SATNET and Backroom EXPAK +IP_PROTO_KRYPTOLAN = 65 # Kryptolan +IP_PROTO_RVD = 66 # MIT Remote Virtual Disk +IP_PROTO_IPPC = 67 # Inet Pluribus Packet Core +IP_PROTO_DISTFS = 68 # any distributed fs +IP_PROTO_SATMON = 69 # SATNET Monitoring +IP_PROTO_VISA = 70 # VISA Protocol +IP_PROTO_IPCV = 71 # Inet Packet Core Utility +IP_PROTO_CPNX = 72 # Comp Proto Net Executive +IP_PROTO_CPHB = 73 # Comp Protocol Heart Beat +IP_PROTO_WSN = 74 # Wang Span Network +IP_PROTO_PVP = 75 # Packet Video Protocol +IP_PROTO_BRSATMON = 76 # Backroom SATNET Monitor +IP_PROTO_SUNND = 77 # SUN ND Protocol +IP_PROTO_WBMON = 78 # WIDEBAND Monitoring +IP_PROTO_WBEXPAK = 79 # WIDEBAND EXPAK +IP_PROTO_EON = 80 # ISO CNLP +IP_PROTO_VMTP = 81 # Versatile Msg Transport +IP_PROTO_SVMTP = 82 # Secure VMTP +IP_PROTO_VINES = 83 # VINES +IP_PROTO_TTP = 84 # TTP +IP_PROTO_NSFIGP = 85 # NSFNET-IGP +IP_PROTO_DGP = 86 # Dissimilar Gateway Proto +IP_PROTO_TCF = 87 # TCF +IP_PROTO_EIGRP = 88 # EIGRP +IP_PROTO_OSPF = 89 # Open Shortest Path First +IP_PROTO_SPRITERPC = 90 # Sprite RPC Protocol +IP_PROTO_LARP = 91 # Locus Address Resolution +IP_PROTO_MTP = 92 # Multicast Transport Proto +IP_PROTO_AX25 = 93 # AX.25 Frames +IP_PROTO_IPIPENCAP = 94 # yet-another IP encap +IP_PROTO_MICP = 95 # Mobile Internet Ctrl +IP_PROTO_SCCSP = 96 # Semaphore Comm Sec Proto +IP_PROTO_ETHERIP = 97 # Ethernet in IPv4 +IP_PROTO_ENCAP = 98 # encapsulation header +IP_PROTO_ANYENC = 99 # private encryption scheme +IP_PROTO_GMTP = 100 # GMTP +IP_PROTO_IFMP = 101 # Ipsilon Flow Mgmt Proto +IP_PROTO_PNNI = 102 # PNNI over IP +IP_PROTO_PIM = 103 # Protocol Indep Multicast +IP_PROTO_ARIS = 104 # ARIS +IP_PROTO_SCPS = 105 # SCPS +IP_PROTO_QNX = 106 # QNX +IP_PROTO_AN = 107 # Active Networks +IP_PROTO_IPCOMP = 108 # IP Payload Compression +IP_PROTO_SNP = 109 # Sitara Networks Protocol +IP_PROTO_COMPAQPEER = 110 # Compaq Peer Protocol +IP_PROTO_IPXIP = 111 # IPX in IP +IP_PROTO_VRRP = 112 # Virtual Router Redundancy +IP_PROTO_PGM = 113 # PGM Reliable Transport +IP_PROTO_ANY0HOP = 114 # 0-hop protocol +IP_PROTO_L2TP = 115 # Layer 2 Tunneling Proto +IP_PROTO_DDX = 116 # D-II Data Exchange (DDX) +IP_PROTO_IATP = 117 # Interactive Agent Xfer +IP_PROTO_STP = 118 # Schedule Transfer Proto +IP_PROTO_SRP = 119 # SpectraLink Radio Proto +IP_PROTO_UTI = 120 # UTI +IP_PROTO_SMP = 121 # Simple Message Protocol +IP_PROTO_SM = 122 # SM +IP_PROTO_PTP = 123 # Performance Transparency +IP_PROTO_ISIS = 124 # ISIS over IPv4 +IP_PROTO_FIRE = 125 # FIRE +IP_PROTO_CRTP = 126 # Combat Radio Transport +IP_PROTO_CRUDP = 127 # Combat Radio UDP +IP_PROTO_SSCOPMCE = 128 # SSCOPMCE +IP_PROTO_IPLT = 129 # IPLT +IP_PROTO_SPS = 130 # Secure Packet Shield +IP_PROTO_PIPE = 131 # Private IP Encap in IP +IP_PROTO_SCTP = 132 # Stream Ctrl Transmission +IP_PROTO_FC = 133 # Fibre Channel +IP_PROTO_RSVPIGN = 134 # RSVP-E2E-IGNORE +IP_PROTO_RAW = 255 # Raw IP packets +IP_PROTO_RESERVED = IP_PROTO_RAW # Reserved +IP_PROTO_MAX = 255 + +# XXX - auto-load IP dispatch table from IP_PROTO_* definitions +def __load_protos(): + g = globals() + for k, v in g.iteritems(): + if k.startswith('IP_PROTO_'): + name = k[9:].lower() + try: + mod = __import__(name, g) + except ImportError: + continue + IP.set_proto(v, getattr(mod, name.upper())) + +if not IP._protosw: + __load_protos() + +if __name__ == '__main__': + import unittest + + class IPTestCase(unittest.TestCase): + def test_IP(self): + import udp + s = 'E\x00\x00"\x00\x00\x00\x00@\x11r\xc0\x01\x02\x03\x04\x01\x02\x03\x04\x00o\x00\xde\x00\x0e\xbf5foobar' + ip = IP(id=0, src='\x01\x02\x03\x04', dst='\x01\x02\x03\x04', p=17) + u = udp.UDP(sport=111, dport=222) + u.data = 'foobar' + u.ulen += len(u.data) + ip.data = u + ip.len += len(u) + self.failUnless(str(ip) == s) + + ip = IP(s) + self.failUnless(str(ip) == s) + self.failUnless(ip.udp.sport == 111) + self.failUnless(ip.udp.data == 'foobar') + + def test_hl(self): + s = 'BB\x03\x00\x00\x00\x00\x00\x00\x00\xd0\x00\xec\xbc\xa5\x00\x00\x00\x03\x80\x00\x00\xd0\x01\xf2\xac\xa5"0\x01\x00\x14\x00\x02\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00' + try: + ip = IP(s) + except dpkt.UnpackError: + pass + + def test_opt(self): + s = '\x4f\x00\x00\x50\xae\x08\x00\x00\x40\x06\x17\xfc\xc0\xa8\x0a\x26\xc0\xa8\x0a\x01\x07\x27\x08\x01\x02\x03\x04\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + ip = IP(s) + ip.sum = 0 + self.failUnless(str(ip) == s) + + def test_zerolen(self): + import tcp + d = 'X' * 2048 + s = 'E\x00\x00\x004\xce@\x00\x80\x06\x00\x00\x7f\x00\x00\x01\x7f\x00\x00\x01\xccN\x0c8`\xff\xc6N_\x8a\x12\x98P\x18@):\xa3\x00\x00' + d + ip = IP(s) + self.failUnless(isinstance(ip.data, tcp.TCP)) + self.failUnless(ip.tcp.data == d) + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/ip6.py b/scripts/external_libs/dpkt-1.8.6/dpkt/ip6.py new file mode 100644 index 00000000..38002fa6 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/ip6.py @@ -0,0 +1,307 @@ +# $Id: ip6.py 87 2013-03-05 19:41:04Z andrewflnr@gmail.com $ + +"""Internet Protocol, version 6.""" + +import dpkt + +class IP6(dpkt.Packet): + __hdr__ = ( + ('v_fc_flow', 'I', 0x60000000L), + ('plen', 'H', 0), # payload length (not including header) + ('nxt', 'B', 0), # next header protocol + ('hlim', 'B', 0), # hop limit + ('src', '16s', ''), + ('dst', '16s', '') + ) + + # XXX - to be shared with IP. We cannot refer to the ip module + # right now because ip.__load_protos() expects the IP6 class to be + # defined. + _protosw = None + + def _get_v(self): + return self.v_fc_flow >> 28 + def _set_v(self, v): + self.v_fc_flow = (self.v_fc_flow & ~0xf0000000L) | (v << 28) + v = property(_get_v, _set_v) + + def _get_fc(self): + return (self.v_fc_flow >> 20) & 0xff + def _set_fc(self, v): + self.v_fc_flow = (self.v_fc_flow & ~0xff00000L) | (v << 20) + fc = property(_get_fc, _set_fc) + + def _get_flow(self): + return self.v_fc_flow & 0xfffff + def _set_flow(self, v): + self.v_fc_flow = (self.v_fc_flow & ~0xfffff) | (v & 0xfffff) + flow = property(_get_flow, _set_flow) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.extension_hdrs = dict(((i, None) for i in ext_hdrs)) + + if self.plen: + buf = self.data[:self.plen] + else: # due to jumbo payload or TSO + buf = self.data + + next = self.nxt + + while (next in ext_hdrs): + ext = ext_hdrs_cls[next](buf) + self.extension_hdrs[next] = ext + buf = buf[ext.length:] + next = ext.nxt + + # set the payload protocol id + setattr(self, 'p', next) + + try: + self.data = self._protosw[next](buf) + setattr(self, self.data.__class__.__name__.lower(), self.data) + except (KeyError, dpkt.UnpackError): + self.data = buf + + def headers_str(self): + """ + Output extension headers in order defined in RFC1883 (except dest opts) + """ + + header_str = "" + + for hdr in ext_hdrs: + if not self.extension_hdrs[hdr] is None: + header_str += str(self.extension_hdrs[hdr]) + return header_str + + + def __str__(self): + if (self.nxt == 6 or self.nxt == 17 or self.nxt == 58) and \ + not self.data.sum: + # XXX - set TCP, UDP, and ICMPv6 checksums + p = str(self.data) + s = dpkt.struct.pack('>16s16sxBH', self.src, self.dst, self.nxt, len(p)) + s = dpkt.in_cksum_add(0, s) + s = dpkt.in_cksum_add(s, p) + try: + self.data.sum = dpkt.in_cksum_done(s) + except AttributeError: + pass + return self.pack_hdr() + self.headers_str() + str(self.data) + + def set_proto(cls, p, pktclass): + cls._protosw[p] = pktclass + set_proto = classmethod(set_proto) + + def get_proto(cls, p): + return cls._protosw[p] + get_proto = classmethod(get_proto) + +import ip +# We are most likely still in the middle of ip.__load_protos() which +# implicitly loads this module through __import__(), so the content of +# ip.IP._protosw is still incomplete at the moment. By sharing the +# same dictionary by reference as opposed to making a copy, when +# ip.__load_protos() finishes, we will also automatically get the most +# up-to-date dictionary. +IP6._protosw = ip.IP._protosw + +class IP6ExtensionHeader(dpkt.Packet): + """ + An extension header is very similar to a 'sub-packet'. + We just want to re-use all the hdr unpacking etc. + """ + pass + +class IP6OptsHeader(IP6ExtensionHeader): + __hdr__ = ( + ('nxt', 'B', 0), # next extension header protocol + ('len', 'B', 0) # option data length in 8 octect units (ignoring first 8 octets) so, len 0 == 64bit header + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + setattr(self, 'length', (self.len + 1) * 8) + options = [] + + index = 0 + + while (index < self.length - 2): + opt_type = ord(self.data[index]) + + # PAD1 option + if opt_type == 0: + index += 1 + continue; + + opt_length = ord(self.data[index + 1]) + + if opt_type == 1: # PADN option + # PADN uses opt_length bytes in total + index += opt_length + 2 + continue + + options.append({'type': opt_type, 'opt_length': opt_length, 'data': self.data[index + 2:index + 2 + opt_length]}) + + # add the two chars and the option_length, to move to the next option + index += opt_length + 2 + + setattr(self, 'options', options) + +class IP6HopOptsHeader(IP6OptsHeader): pass + +class IP6DstOptsHeader(IP6OptsHeader): pass + +class IP6RoutingHeader(IP6ExtensionHeader): + __hdr__ = ( + ('nxt', 'B', 0), # next extension header protocol + ('len', 'B', 0), # extension data length in 8 octect units (ignoring first 8 octets) (<= 46 for type 0) + ('type', 'B', 0), # routing type (currently, only 0 is used) + ('segs_left', 'B', 0), # remaining segments in route, until destination (<= 23) + ('rsvd_sl_bits', 'I', 0), # reserved (1 byte), strict/loose bitmap for addresses + ) + + def _get_sl_bits(self): + return self.rsvd_sl_bits & 0xffffff + def _set_sl_bits(self, v): + self.rsvd_sl_bits = (self.rsvd_sl_bits & ~0xfffff) | (v & 0xfffff) + sl_bits = property(_get_sl_bits, _set_sl_bits) + + def unpack(self, buf): + hdr_size = 8 + addr_size = 16 + + dpkt.Packet.unpack(self, buf) + + addresses = [] + num_addresses = self.len / 2 + buf = buf[hdr_size:hdr_size + num_addresses * addr_size] + + for i in range(num_addresses): + addresses.append(buf[i * addr_size: i * addr_size + addr_size]) + + self.data = buf + setattr(self, 'addresses', addresses) + setattr(self, 'length', self.len * 8 + 8) + +class IP6FragmentHeader(IP6ExtensionHeader): + __hdr__ = ( + ('nxt', 'B', 0), # next extension header protocol + ('resv', 'B', 0), # reserved, set to 0 + ('frag_off_resv_m', 'H', 0), # frag offset (13 bits), reserved zero (2 bits), More frags flag + ('id', 'I', 0) # fragments id + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + setattr(self, 'length', self.__hdr_len__) + + def _get_frag_off(self): + return self.frag_off_resv_m >> 3 + def _set_frag_off(self, v): + self.frag_off_resv_m = (self.frag_off_resv_m & ~0xfff8) | (v << 3) + frag_off = property(_get_frag_off, _set_frag_off) + + def _get_m_flag(self): + return self.frag_off_resv_m & 1 + def _set_m_flag(self, v): + self.frag_off_resv_m = (self.frag_off_resv_m & ~0xfffe) | v + m_flag = property(_get_m_flag, _set_m_flag) + +class IP6AHHeader(IP6ExtensionHeader): + __hdr__ = ( + ('nxt', 'B', 0), # next extension header protocol + ('len', 'B', 0), # length of header in 4 octet units (ignoring first 2 units) + ('resv', 'H', 0), # reserved, 2 bytes of 0 + ('spi', 'I', 0), # SPI security parameter index + ('seq', 'I', 0) # sequence no. + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + setattr(self, 'length', (self.len + 2) * 4) + setattr(self, 'auth_data', self.data[:(self.len - 1) * 4]) + + +class IP6ESPHeader(IP6ExtensionHeader): + def unpack(self, buf): + raise NotImplementedError("ESP extension headers are not supported.") + + +ext_hdrs = [ip.IP_PROTO_HOPOPTS, ip.IP_PROTO_ROUTING, ip.IP_PROTO_FRAGMENT, ip.IP_PROTO_AH, ip.IP_PROTO_ESP, ip.IP_PROTO_DSTOPTS] +ext_hdrs_cls = {ip.IP_PROTO_HOPOPTS: IP6HopOptsHeader, + ip.IP_PROTO_ROUTING: IP6RoutingHeader, + ip.IP_PROTO_FRAGMENT: IP6FragmentHeader, + ip.IP_PROTO_ESP: IP6ESPHeader, + ip.IP_PROTO_AH: IP6AHHeader, + ip.IP_PROTO_DSTOPTS: IP6DstOptsHeader} + +if __name__ == '__main__': + import unittest + + class IP6TestCase(unittest.TestCase): + + def test_IP6(self): + s = '`\x00\x00\x00\x00(\x06@\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x11$\xff\xfe\x8c\x11\xde\xfe\x80\x00\x00\x00\x00\x00\x00\x02\xb0\xd0\xff\xfe\xe1\x80r\xcd\xca\x00\x16\x04\x84F\xd5\x00\x00\x00\x00\xa0\x02\xff\xff\xf8\t\x00\x00\x02\x04\x05\xa0\x01\x03\x03\x00\x01\x01\x08\n}\x185?\x00\x00\x00\x00' + ip = IP6(s) + #print `ip` + ip.data.sum = 0 + s2 = str(ip) + ip2 = IP6(s) + #print `ip2` + assert(s == s2) + + def test_IP6RoutingHeader(self): + s = '`\x00\x00\x00\x00<+@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x06\x04\x00\x02\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x91\x7f\x00\x00' + ip = IP6(s) + s2 = str(ip) + # 43 is Routing header id + assert(len(ip.extension_hdrs[43].addresses) == 2) + assert(ip.tcp) + assert(s == s2) + + + def test_IP6FragmentHeader(self): + s = '\x06\xee\xff\xfb\x00\x00\xff\xff' + fh = IP6FragmentHeader(s) + s2 = str(fh) + assert(fh.nxt == 6) + assert(fh.id == 65535) + assert(fh.frag_off == 8191) + assert(fh.m_flag == 1) + + def test_IP6OptionsHeader(self): + s = ';\x04\x01\x02\x00\x00\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xc2\x04\x00\x00\x00\x00\x05\x02\x00\x00\x01\x02\x00\x00' + options = IP6OptsHeader(s).options + assert(len(options) == 3) + + def test_IP6AHHeader(self): + s = ';\x04\x00\x00\x02\x02\x02\x02\x01\x01\x01\x01\x78\x78\x78\x78\x78\x78\x78\x78' + ah = IP6AHHeader(s) + assert(ah.length == 24) + assert(ah.auth_data == 'xxxxxxxx') + assert(ah.spi == 0x2020202) + assert(ah.seq == 0x1010101) + + def test_IP6ExtensionHeaders(self): + p = '`\x00\x00\x00\x00<+@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x06\x04\x00\x02\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x91\x7f\x00\x00' + ip = IP6(p) + + o = ';\x04\x01\x02\x00\x00\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xc2\x04\x00\x00\x00\x00\x05\x02\x00\x00\x01\x02\x00\x00' + options = IP6HopOptsHeader(o) + + ip.extension_hdrs[0] = options + + fh = '\x06\xee\xff\xfb\x00\x00\xff\xff' + ip.extension_hdrs[44] = IP6FragmentHeader(fh) + + ah = ';\x04\x00\x00\x02\x02\x02\x02\x01\x01\x01\x01\x78\x78\x78\x78\x78\x78\x78\x78' + ip.extension_hdrs[51] = IP6AHHeader(ah) + + do = ';\x02\x01\x02\x00\x00\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + ip.extension_hdrs[60] = IP6DstOptsHeader(do) + + assert(len([k for k in ip.extension_hdrs if (not ip.extension_hdrs[k] is None)]) == 5) + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/ipx.py b/scripts/external_libs/dpkt-1.8.6/dpkt/ipx.py new file mode 100644 index 00000000..74e7982a --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/ipx.py @@ -0,0 +1,17 @@ +# $Id: ipx.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Internetwork Packet Exchange.""" + +import dpkt + +IPX_HDR_LEN = 30 + +class IPX(dpkt.Packet): + __hdr__ = ( + ('sum', 'H', 0xffff), + ('len', 'H', IPX_HDR_LEN), + ('tc', 'B', 0), + ('pt', 'B', 0), + ('dst', '12s', ''), + ('src', '12s', '') + ) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/llc.py b/scripts/external_libs/dpkt-1.8.6/dpkt/llc.py new file mode 100644 index 00000000..28246131 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/llc.py @@ -0,0 +1,55 @@ +import struct +import dpkt, stp, ethernet + +class LLC(dpkt.Packet): + _typesw = {} + + def _unpack_data(self, buf): + if self.type == ethernet.ETH_TYPE_8021Q: + self.tag, self.type = struct.unpack('>HH', buf[:4]) + buf = buf[4:] + elif self.type == ethernet.ETH_TYPE_MPLS or \ + self.type == ethernet.ETH_TYPE_MPLS_MCAST: + # XXX - skip labels + for i in range(24): + if struct.unpack('>I', buf[i:i+4])[0] & 0x0100: # MPLS_STACK_BOTTOM + break + self.type = ethernet.ETH_TYPE_IP + buf = buf[(i + 1) * 4:] + try: + self.data = self._typesw[self.type](buf) + setattr(self, self.data.__class__.__name__.lower(), self.data) + except (KeyError, dpkt.UnpackError): + self.data = buf + + def unpack(self, buf): + self.data = buf + if self.data.startswith('\xaa\xaa'): + # SNAP + self.type = struct.unpack('>H', self.data[6:8])[0] + self._unpack_data(self.data[8:]) + else: + # non-SNAP + dsap = ord(self.data[0]) + if dsap == 0x06: # SAP_IP + self.data = self.ip = self._typesw[ethernet.ETH_TYPE_IP](self.data[3:]) + elif dsap == 0x10 or dsap == 0xe0: # SAP_NETWARE{1,2} + self.data = self.ipx = self._typesw[ethernet.ETH_TYPE_IPX](self.data[3:]) + elif dsap == 0x42: # SAP_STP + self.data = self.stp = stp.STP(self.data[3:]) + +if __name__ == '__main__': + import unittest + + class LLCTestCase(unittest.TestCase): + + def test_llc(self): + s = '\xaa\xaa\x03\x00\x00\x00\x08\x00\x45\x00\x00\x28\x07\x27\x40\x00\x80\x06\x1d\x39\x8d\xd4\x37\x3d\x3f\xf5\xd1\x69\xc0\x5f\x01\xbb\xb2\xd6\xef\x23\x38\x2b\x4f\x08\x50\x10\x42\x04\xac\x17\x00\x00' + + import ip + llc_pkt = LLC(s) + ip_pkt = ip.IP(llc_pkt.data) + self.failUnless(llc_pkt.type == ethernet.ETH_TYPE_IP) + self.failUnless(ip_pkt.dst == '\x3f\xf5\xd1\x69') + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/loopback.py b/scripts/external_libs/dpkt-1.8.6/dpkt/loopback.py new file mode 100644 index 00000000..25992b31 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/loopback.py @@ -0,0 +1,20 @@ +# $Id: loopback.py 38 2007-03-17 03:33:16Z dugsong $ + +"""Platform-dependent loopback header.""" + +import dpkt, ethernet, ip, ip6 + +class Loopback(dpkt.Packet): + __hdr__ = (('family', 'I', 0), ) + __byte_order__ = '@' + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + if self.family == 2: + self.data = ip.IP(self.data) + elif self.family == 0x02000000: + self.family = 2 + self.data = ip.IP(self.data) + elif self.family in (24, 28, 30): + self.data = ip6.IP6(self.data) + elif self.family > 1500: + self.data = ethernet.Ethernet(self.data) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/mrt.py b/scripts/external_libs/dpkt-1.8.6/dpkt/mrt.py new file mode 100644 index 00000000..9f3c719c --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/mrt.py @@ -0,0 +1,92 @@ +# $Id: mrt.py 29 2007-01-26 02:29:07Z jon.oberheide $ + +"""Multi-threaded Routing Toolkit.""" + +import dpkt +import bgp + +# Multi-threaded Routing Toolkit +# http://www.ietf.org/internet-drafts/draft-ietf-grow-mrt-03.txt + +# MRT Types +NULL = 0 +START = 1 +DIE = 2 +I_AM_DEAD = 3 +PEER_DOWN = 4 +BGP = 5 # Deprecated by BGP4MP +RIP = 6 +IDRP = 7 +RIPNG = 8 +BGP4PLUS = 9 # Deprecated by BGP4MP +BGP4PLUS_01 = 10 # Deprecated by BGP4MP +OSPF = 11 +TABLE_DUMP = 12 +BGP4MP = 16 +BGP4MP_ET = 17 +ISIS = 32 +ISIS_ET = 33 +OSPF_ET = 64 + +# BGP4MP Subtypes +BGP4MP_STATE_CHANGE = 0 +BGP4MP_MESSAGE = 1 +BGP4MP_ENTRY = 2 +BGP4MP_SNAPSHOT = 3 +BGP4MP_MESSAGE_32BIT_AS = 4 + +# Address Family Types +AFI_IPv4 = 1 +AFI_IPv6 = 2 + +class MRTHeader(dpkt.Packet): + __hdr__ = ( + ('ts', 'I', 0), + ('type', 'H', 0), + ('subtype', 'H', 0), + ('len', 'I', 0) + ) + +class TableDump(dpkt.Packet): + __hdr__ = ( + ('view', 'H', 0), + ('seq', 'H', 0), + ('prefix', 'I', 0), + ('prefix_len', 'B', 0), + ('status', 'B', 1), + ('originated_ts', 'I', 0), + ('peer_ip', 'I', 0), + ('peer_as', 'H', 0), + ('attr_len', 'H', 0) + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + plen = self.attr_len + l = [] + while plen > 0: + attr = bgp.BGP.Update.Attribute(self.data) + self.data = self.data[len(attr):] + plen -= len(attr) + l.append(attr) + self.attributes = l + +class BGP4MPMessage(dpkt.Packet): + __hdr__ = ( + ('src_as', 'H', 0), + ('dst_as', 'H', 0), + ('intf', 'H', 0), + ('family', 'H', AFI_IPv4), + ('src_ip', 'I', 0), + ('dst_ip', 'I', 0) + ) + +class BGP4MPMessage_32(dpkt.Packet): + __hdr__ = ( + ('src_as', 'I', 0), + ('dst_as', 'I', 0), + ('intf', 'H', 0), + ('family', 'H', AFI_IPv4), + ('src_ip', 'I', 0), + ('dst_ip', 'I', 0) + ) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/netbios.py b/scripts/external_libs/dpkt-1.8.6/dpkt/netbios.py new file mode 100644 index 00000000..e535ad04 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/netbios.py @@ -0,0 +1,154 @@ +# $Id: netbios.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Network Basic Input/Output System.""" + +import struct +import dpkt, dns + +def encode_name(name): + """Return the NetBIOS first-level encoded name.""" + l = [] + for c in struct.pack('16s', name): + c = ord(c) + l.append(chr((c >> 4) + 0x41)) + l.append(chr((c & 0xf) + 0x41)) + return ''.join(l) + +def decode_name(nbname): + """Return the NetBIOS first-level decoded nbname.""" + if len(nbname) != 32: + return nbname + l = [] + for i in range(0, 32, 2): + l.append(chr(((ord(nbname[i]) - 0x41) << 4) | + ((ord(nbname[i+1]) - 0x41) & 0xf))) + return ''.join(l).split('\x00', 1)[0] + +# RR types +NS_A = 0x01 # IP address +NS_NS = 0x02 # Name Server +NS_NULL = 0x0A # NULL +NS_NB = 0x20 # NetBIOS general Name Service +NS_NBSTAT = 0x21 # NetBIOS NODE STATUS + +# RR classes +NS_IN = 1 + +# NBSTAT name flags +NS_NAME_G = 0x8000 # group name (as opposed to unique) +NS_NAME_DRG = 0x1000 # deregister +NS_NAME_CNF = 0x0800 # conflict +NS_NAME_ACT = 0x0400 # active +NS_NAME_PRM = 0x0200 # permanent + +# NBSTAT service names +nbstat_svcs = { + # (service, unique): list of ordered (name prefix, service name) tuples + (0x00, 0):[ ('', 'Domain Name') ], + (0x00, 1):[ ('IS~', 'IIS'), ('', 'Workstation Service') ], + (0x01, 0):[ ('__MSBROWSE__', 'Master Browser') ], + (0x01, 1):[ ('', 'Messenger Service') ], + (0x03, 1):[ ('', 'Messenger Service') ], + (0x06, 1):[ ('', 'RAS Server Service') ], + (0x1B, 1):[ ('', 'Domain Master Browser') ], + (0x1C, 0):[ ('INet~Services', 'IIS'), ('', 'Domain Controllers') ], + (0x1D, 1):[ ('', 'Master Browser') ], + (0x1E, 0):[ ('', 'Browser Service Elections') ], + (0x1F, 1):[ ('', 'NetDDE Service') ], + (0x20, 1):[ ('Forte_$ND800ZA', 'DCA IrmaLan Gateway Server Service'), + ('', 'File Server Service') ], + (0x21, 1):[ ('', 'RAS Client Service') ], + (0x22, 1):[ ('', 'Microsoft Exchange Interchange(MSMail Connector)') ], + (0x23, 1):[ ('', 'Microsoft Exchange Store') ], + (0x24, 1):[ ('', 'Microsoft Exchange Directory') ], + (0x2B, 1):[ ('', 'Lotus Notes Server Service') ], + (0x2F, 0):[ ('IRISMULTICAST', 'Lotus Notes') ], + (0x30, 1):[ ('', 'Modem Sharing Server Service') ], + (0x31, 1):[ ('', 'Modem Sharing Client Service') ], + (0x33, 0):[ ('IRISNAMESERVER', 'Lotus Notes') ], + (0x43, 1):[ ('', 'SMS Clients Remote Control') ], + (0x44, 1):[ ('', 'SMS Administrators Remote Control Tool') ], + (0x45, 1):[ ('', 'SMS Clients Remote Chat') ], + (0x46, 1):[ ('', 'SMS Clients Remote Transfer') ], + (0x4C, 1):[ ('', 'DEC Pathworks TCPIP service on Windows NT') ], + (0x52, 1):[ ('', 'DEC Pathworks TCPIP service on Windows NT') ], + (0x87, 1):[ ('', 'Microsoft Exchange MTA') ], + (0x6A, 1):[ ('', 'Microsoft Exchange IMC') ], + (0xBE, 1):[ ('', 'Network Monitor Agent') ], + (0xBF, 1):[ ('', 'Network Monitor Application') ] + } +def node_to_service_name((name, service, flags)): + try: + unique = int(flags & NS_NAME_G == 0) + for namepfx, svcname in nbstat_svcs[(service, unique)]: + if name.startswith(namepfx): + return svcname + except KeyError: + pass + return '' + +class NS(dns.DNS): + """NetBIOS Name Service.""" + class Q(dns.DNS.Q): + pass + + class RR(dns.DNS.RR): + """NetBIOS resource record.""" + def unpack_rdata(self, buf, off): + if self.type == NS_A: + self.ip = self.rdata + elif self.type == NS_NBSTAT: + num = ord(self.rdata[0]) + off = 1 + l = [] + for i in range(num): + name = self.rdata[off:off+15].split(None, 1)[0].split('\x00', 1)[0] + service = ord(self.rdata[off+15]) + off += 16 + flags = struct.unpack('>H', self.rdata[off:off+2])[0] + off += 2 + l.append((name, service, flags)) + self.nodenames = l + # XXX - skip stats + + def pack_name(self, buf, name): + return dns.DNS.pack_name(self, buf, encode_name(name)) + + def unpack_name(self, buf, off): + name, off = dns.DNS.unpack_name(self, buf, off) + return decode_name(name), off + +class Session(dpkt.Packet): + """NetBIOS Session Service.""" + __hdr__ = ( + ('type', 'B', 0), + ('flags', 'B', 0), + ('len', 'H', 0) + ) + +SSN_MESSAGE = 0 +SSN_REQUEST = 1 +SSN_POSITIVE = 2 +SSN_NEGATIVE = 3 +SSN_RETARGET = 4 +SSN_KEEPALIVE = 5 + +class Datagram(dpkt.Packet): + """NetBIOS Datagram Service.""" + __hdr__ = ( + ('type', 'B', 0), + ('flags', 'B', 0), + ('id', 'H', 0), + ('src', 'I', 0), + ('sport', 'H', 0), + ('len', 'H', 0), + ('off', 'H', 0) + ) + +DGRAM_UNIQUE = 0x10 +DGRAM_GROUP = 0x11 +DGRAM_BROADCAST = 0x12 +DGRAM_ERROR = 0x13 +DGRAM_QUERY = 0x14 +DGRAM_POSITIVE = 0x15 +DGRAM_NEGATIVE = 0x16 diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/netflow.py b/scripts/external_libs/dpkt-1.8.6/dpkt/netflow.py new file mode 100644 index 00000000..103b04f1 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/netflow.py @@ -0,0 +1,214 @@ +# $Id: netflow.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Cisco Netflow.""" + +import itertools, struct +import dpkt + +class NetflowBase(dpkt.Packet): + """Base class for Cisco Netflow packets.""" + + __hdr__ = ( + ('version', 'H', 1), + ('count', 'H', 0), + ('sys_uptime', 'I', 0), + ('unix_sec', 'I', 0), + ('unix_nsec', 'I', 0) + ) + + def __len__(self): + return self.__hdr_len__ + (len(self.data[0]) * self.count) + + def __str__(self): + # for now, don't try to enforce any size limits + self.count = len(self.data) + return self.pack_hdr() + ''.join(map(str, self.data)) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + buf = self.data + l = [] + while buf: + flow = self.NetflowRecord(buf) + l.append(flow) + buf = buf[len(flow):] + self.data = l + + class NetflowRecordBase(dpkt.Packet): + """Base class for netflow v1-v7 netflow records.""" + + # performance optimizations + def __len__(self): + # don't bother with data + return self.__hdr_len__ + + def __str__(self): + # don't bother with data + return self.pack_hdr() + + def unpack(self, buf): + # don't bother with data + for k, v in itertools.izip(self.__hdr_fields__, + struct.unpack(self.__hdr_fmt__, buf[:self.__hdr_len__])): + setattr(self, k, v) + self.data = "" + + +class Netflow1(NetflowBase): + """Netflow Version 1.""" + + class NetflowRecord(NetflowBase.NetflowRecordBase): + """Netflow v1 flow record.""" + __hdr__ = ( + ('src_addr', 'I', 0), + ('dst_addr', 'I', 0), + ('next_hop', 'I', 0), + ('input_iface', 'H', 0), + ('output_iface', 'H', 0), + ('pkts_sent', 'I', 0), + ('bytes_sent', 'I', 0), + ('start_time', 'I', 0), + ('end_time', 'I', 0), + ('src_port', 'H', 0), + ('dst_port', 'H', 0), + ('pad1', 'H', 0), + ('ip_proto', 'B', 0), + ('tos', 'B', 0), + ('tcp_flags', 'B', 0), + ('pad2', 'B', 0), + ('pad3', 'H', 0), + ('reserved', 'I', 0) + ) + +# FYI, versions 2-4 don't appear to have ever seen the light of day. + +class Netflow5(NetflowBase): + """Netflow Version 5.""" + __hdr__ = NetflowBase.__hdr__ + ( + ('flow_sequence', 'I', 0), + ('engine_type', 'B', 0), + ('engine_id', 'B', 0), + ('reserved', 'H', 0), + ) + + class NetflowRecord(NetflowBase.NetflowRecordBase): + """Netflow v5 flow record.""" + __hdr__ = ( + ('src_addr', 'I', 0), + ('dst_addr', 'I', 0), + ('next_hop', 'I', 0), + ('input_iface', 'H', 0), + ('output_iface', 'H', 0), + ('pkts_sent', 'I', 0), + ('bytes_sent', 'I', 0), + ('start_time', 'I', 0), + ('end_time', 'I', 0), + ('src_port', 'H', 0), + ('dst_port', 'H', 0), + ('pad1', 'B', 0), + ('tcp_flags', 'B', 0), + ('ip_proto', 'B', 0), + ('tos', 'B', 0), + ('src_as', 'H', 0), + ('dst_as', 'H', 0), + ('src_mask', 'B', 0), + ('dst_mask', 'B', 0), + ('pad2', 'H', 0), + ) + +class Netflow6(NetflowBase): + """Netflow Version 6. + XXX - unsupported by Cisco, but may be found in the field. + """ + __hdr__ = Netflow5.__hdr__ + + class NetflowRecord(NetflowBase.NetflowRecordBase): + """Netflow v6 flow record.""" + __hdr__ = ( + ('src_addr', 'I', 0), + ('dst_addr', 'I', 0), + ('next_hop', 'I', 0), + ('input_iface', 'H', 0), + ('output_iface', 'H', 0), + ('pkts_sent', 'I', 0), + ('bytes_sent', 'I', 0), + ('start_time', 'I', 0), + ('end_time', 'I', 0), + ('src_port', 'H', 0), + ('dst_port', 'H', 0), + ('pad1', 'B', 0), + ('tcp_flags', 'B', 0), + ('ip_proto', 'B', 0), + ('tos', 'B', 0), + ('src_as', 'H', 0), + ('dst_as', 'H', 0), + ('src_mask', 'B', 0), + ('dst_mask', 'B', 0), + ('in_encaps', 'B', 0), + ('out_encaps', 'B', 0), + ('peer_nexthop', 'I', 0), + ) + +class Netflow7(NetflowBase): + """Netflow Version 7.""" + __hdr__ = NetflowBase.__hdr__ + ( + ('flow_sequence', 'I', 0), + ('reserved', 'I', 0), + ) + + class NetflowRecord(NetflowBase.NetflowRecordBase): + """Netflow v7 flow record.""" + __hdr__ = ( + ('src_addr', 'I', 0), + ('dst_addr', 'I', 0), + ('next_hop', 'I', 0), + ('input_iface', 'H', 0), + ('output_iface', 'H', 0), + ('pkts_sent', 'I', 0), + ('bytes_sent', 'I', 0), + ('start_time', 'I', 0), + ('end_time', 'I', 0), + ('src_port', 'H', 0), + ('dst_port', 'H', 0), + ('flags', 'B', 0), + ('tcp_flags', 'B', 0), + ('ip_proto', 'B', 0), + ('tos', 'B', 0), + ('src_as', 'H', 0), + ('dst_as', 'H', 0), + ('src_mask', 'B', 0), + ('dst_mask', 'B', 0), + ('pad2', 'H', 0), + ('router_sc', 'I', 0), + ) + +# No support for v8 or v9 yet. + +if __name__ == '__main__': + import unittest + + class NetflowV1TestCase(unittest.TestCase): + sample_v1 = "\x00\x01\x00\x18gza<B\x00\xfc\x1c$\x93\x08p\xac\x01 W\xc0\xa8c\xf7\n\x00\x02\x01\x00\x03\x00\n\x00\x00\x00\x01\x00\x00\x02(gz7,gz7,\\\x1b\x00P\xac\x01\x11,\x10\x00\x00\x00\x00\x04\x00\x1b\xac\x01\x18S\xac\x18\xd9\xaa\xc0\xa82\x02\x00\x03\x00\x19\x00\x00\x00\x01\x00\x00\x05\xdcgz7|gz7|\xd8\xe3\x00P\xac\x01\x06,\x10\x00\x00\x00\x00\x04\x00\x1b\xac\x01\x14\x18\xac\x18\x8d\xcd\xc0\xa82f\x00\x03\x00\x07\x00\x00\x00\x01\x00\x00\x05\xdcgz7\x90gz7\x90\x8a\x81\x17o\xac\x01\x066\x10\x00\x00\x00\x00\x04\x00\x03\xac\x0f'$\xac\x01\xe5\x1d\xc0\xa82\x06\x00\x04\x00\x1b\x00\x00\x00\x01\x00\x00\x02(gz:8gz:8\xa3Q\x126\xac)\x06\xfd\x18\x00\x00\x00\x00\x04\x00\x1b\xac\x01\x16E\xac#\x17\x8e\xc0\xa82\x06\x00\x03\x00\x1b\x00\x00\x00\x01\x00\x00\x02(gz:Lgz:L\xc9\xff\x00P\xac\x1f\x06\x86\x02\x00\x00\x00\x00\x03\x00\x1b\xac\r\t\xff\xac\x01\x99\x95\xc0\xa82\x06\x00\x04\x00\x1b\x00\x00\x00\x01\x00\x00\x05\xdcgz:Xgz:X\xee9\x00\x17\xac\x01\x06\xde\x10\x00\x00\x00\x00\x04\x00\x03\xac\x0eJ\xd8\xac\x01\xae/\xc0\xa82\x06\x00\x04\x00\x1b\x00\x00\x00\x01\x00\x00\x05\xdcgz:hgz:h\xb3n\x00\x15\xac\x01\x06\x81\x10\x00\x00\x00\x00\x04\x00\x1b\xac\x01#8\xac\x01\xd9*\xc0\xa82\x06\x00\x03\x00\x1b\x00\x00\x00\x01\x00\x00\x05\xdcgz:tgz:t\x00\x00\x83P\xac!\x01\xab\x10\x00\x00\x00\x00\x03\x00\x1b\xac\n`7\xac*\x93J\xc0\xa82\x06\x00\x04\x00\x1b\x00\x00\x00\x01\x00\x00\x05\xdcgz:tgz:t\x00\x00\x00\x00\xac\x012\xa9\x10\x00\x00\x00\x00\x04\x00\x07\xac\nG\x1f\xac\x01\xfdJ\xc0\xa82\x06\x00\x04\x00\x1b\x00\x00\x00\x01\x00\x00\x00(gz:\x88gz:\x88!\x99i\x87\xac\x1e\x06~\x02\x00\x00\x00\x00\x03\x00\x1b\xac\x01(\xc9\xac\x01B\xc4\xc0\xa82\x02\x00\x03\x00\x19\x00\x00\x00\x01\x00\x00\x00(gz:\x88gz:\x88}6\x00P\xac\x01\x06\xfe\x10\x00\x00\x00\x00\x04\x00\x1b\xac\x0b\x08\xe8\xac\x01F\xe2\xc0\xa82\x02\x00\x04\x00\x19\x00\x00\x00\x01\x00\x00\x05\xdcgz:\x9cgz:\x9c`ii\x87\xac\x01\x06;\x10\x00\x00\x00\x00\x04\x00\x1b\xac\x01\x1d$\xac<\xf0\xc3\xc0\xa82\x06\x00\x03\x00\x1b\x00\x00\x00\x01\x00\x00\x05\xdcgz:\x9cgz:\x9cF2\x00\x14\xac\x01\x06s\x18\x00\x00\x00\x00\x04\x00\x03\xac\x0b\x11Q\xac\x01\xde\x06\xc0\xa82\x06\x00\x04\x00\x1b\x00\x00\x00\x01\x00\x00\x05\xdcgz:\xb0gz:\xb0\xef#\x1a+\xac)\x06\xe9\x10\x00\x00\x00\x00\x04\x00\x1b\xac\x0cR\xd9\xac\x01o\xe8\xc0\xa82\x02\x00\x04\x00\x19\x00\x00\x00\x01\x00\x00\x05\xdcgz:\xc4gz:\xc4\x13n\x00n\xac\x19\x06\xa8\x10\x00\x00\x00\x00\x03\x00\x19\xac\x01=\xdd\xac\x01}\xee\xc0\xa82f\x00\x03\x00\x07\x00\x00\x00\x01\x00\x00\x00(gz:\xc4gz:\xc4\x00\x00\xdc\xbb\xac\x01\x01\xd3\x10\x00\x00\x00\x00\x04\x00\x1b\xac\x0f(\xd1\xac\x01\xcc\xa5\xc0\xa82\x06\x00\x04\x00\x1b\x00\x00\x00\x01\x00\x00\x05\xdcgz:\xd8gz:\xd8\xc5s\x17o\xac\x19\x06#\x18\x00\x00\x00\x00\x03\x00\x07\xac\n\x85[\xc0\xa8cn\n\x00\x02\x01\x00\x04\x00\n\x00\x00\x00\x01\x00\x00\x05\xdcgz:\xe4gz:\xe4\xbfl\x00P\xac\x01\x06\xcf\x10\x00\x00\x00\x00\x04\x00\x07\xac\x010\x1f\xac\x18!E\xc0\xa82f\x00\x03\x00\x07\x00\x00\x00\x01\x00\x00\x05\xdcgz;\x00gz;\x00\x11\x95\x04\xbe\xc0\xa8\x06\xea\x10\x00\x00\x00\x00\x03\x00\n\xac\x010\xb6\xac\x1e\xf4\xaa\xc0\xa82\x06\x00\x03\x00\x1b\x00\x00\x00\x01\x00\x00\x05\xdcgz;4gz;4\x88d\x00\x17\xac\x01\x06\x1f\x10\x00\x00\x00\x00\x04\x00\x1b\xac\x01#_\xac\x1e\xb0\t\xc0\xa82\x06\x00\x03\x00\x1b\x00\x00\x00\x01\x00\x00\x05\xdcgz;Hgz;H\x81S\x00P\xac \x06N\x10\x00\x00\x00\x00\x03\x00\x1b\xac\x01\x04\xd9\xac\x01\x94c\xc0\xa82\x06\x00\x03\x00\x1b\x00\x00\x00\x01\x00\x00\x02(gz;\\gz;\\U\x10\x00P\xac\x01\x06P\x18\x00\x00\x00\x00\x04\x00\x1b\xac\x01<\xae\xac*\xac!\xc0\xa82\x06\x00\x03\x00\x1b\x00\x00\x00\x01\x00\x00\x00\xfagz;\x84gz;\x84\x0c\xe7\x00P\xac\x01\x11\xfd\x10\x00\x00\x00\x00\x04\x00\x1b\xac\x01\x1f\x1f\xac\x17\xedi\xc0\xa82\x02\x00\x03\x00\x19\x00\x00\x00\x01\x00\x00\x05\xdcgz;\x98gz;\x98\xba\x17\x00\x16\xac\x01\x06|\x10\x00\x00\x00\x00\x03\x00\x07" + + def testPack(self): + pass + + def testUnpack(self): + nf = Netflow1(self.sample_v1) + assert len(nf.data) == 24 + #print repr(nfv1) + + class NetflowV5TestCase(unittest.TestCase): + sample_v5 = '\x00\x05\x00\x1d\xb5\xfa\xc9\xd0:\x0bAB&Vw\xde\x9bsv1\x00\x01\x00\x00\xac\n\x86\xa6\xac\x01\xaa\xf7\xc0\xa822\x02q\x00i\x00\x00\x00\x01\x00\x00\x02(\xb5\xfa\x81\x14\xb5\xfa\x81\x1452\x00P\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x01\x91D\xac\x14C\xe4\xc0\xa82\x16\x00i\x02q\x00\x00\x00\x01\x00\x00\x00(\xb5\xfa\x9b\xbd\xb5\xfa\x9b\xbd\x00P\x85\xd7\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x17\xe2\xd7\xac\x01\x8cV\xc0\xa822\x02q\x00i\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfao\xb8\xb5\xfao\xb8v\xe8\x17o\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x0e\xf2\xe5\xac\x01\x91\xb2\xc0\xa822\x02q\x00i\x00\x00\x00\x01\x00\x00\x00\xfa\xb5\xfa\x81\xee\xb5\xfa\x81\xee\xd0\xeb\x00\x15\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\nCj\xac)\xa7\t\n\x00\x02\x01\x02q\x00\xdb\x00\x00\x00\x01\x00\x00\x02(\xb5\xfa\x85\x92\xb5\xfa\x85\x92\x8c\xb0\x005\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x01\x96=\xac\x15\x1a\xa8\xc0\xa82\x16\x00i\x02q\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfa\x86\xe0\xb5\xfa\x86\xe0\xb4\xe7\x00\xc2\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x01V\xd1\xac\x01\x86\x15\xc0\xa822\x02q\x00i\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfa}:\xb5\xfa}:[Q\x00P\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac2\xf1\xb1\xac)\x19\xca\n\x00\x02\x01\x02q\x00\xdb\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfa\x83\xc3\xb5\xfa\x83\xc3\x16,\x00\x15\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x0cA4\xac\x01\x9az\xc0\xa822\x02q\x00i\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfa\x8d\xa7\xb5\xfa\x8d\xa7\x173\x00\x15\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x1e\xd2\x84\xac)\xd8\xd2\n\x00\x02\x01\x02q\x00\xdb\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfa\x8e\x97\xb5\xfa\x8e\x977*\x17o\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x01\x85J\xac \x11\xfc\xc0\xa82\x16\x00i\x02q\x00\x00\x00\x01\x00\x00\x02(\xb5\xfa\x884\xb5\xfa\x884\xf5\xdd\x00\x8f\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x01\x04\x80\xac<[n\n\x00\x02\x01\x02q\x00\xdb\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfa\x9dr\xb5\xfa\x9drs$\x00\x16\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x01\xb9J\xac"\xc9\xd7\xc0\xa82\x16\x00i\x02q\x00\x00\x00\x01\x00\x00\x00(\xb5\xfa\x90r\xb5\xfa\x90r\x0f\x8d\x00\xc2\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac*\xa3\x10\xac\x01\xb4\x19\xc0\xa822\x02q\x00i\x00\x00\x00\x01\x00\x00\x00(\xb5\xfa\x92\x03\xb5\xfa\x92\x03pf\x00\x15\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x01\xabo\xac\x1e\x7fi\xc0\xa82\x16\x00i\x02q\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfa\x93\x7f\xb5\xfa\x93\x7f\x00P\x0b\x98\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x0c\n\xea\xac\x01\xa1\x15\xc0\xa822\x02q\x00i\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfay\xcf\xb5\xfay\xcf[3\x17\xe0\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x01\xbb\xb3\xac)u\x8c\n\x00\x02\x01\x00i\x00\xdb\x00\x00\x00\x01\x00\x00\x00\xfa\xb5\xfa\x943\xb5\xfa\x943\x00P\x1e\xca\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x0fJ`\xac\x01\xab\x94\xc0\xa822\x02q\x00i\x00\x00\x00\x01\x00\x00\x02(\xb5\xfa\x87[\xb5\xfa\x87[\x9a\xd6/\xab\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac*\x0f\x93\xac\x01\xb8\xa3\xc0\xa822\x02q\x00i\x00\x00\x00\x01\x00\x00\x00(\xb5\xfa\x89\xbb\xb5\xfa\x89\xbbn\xe1\x00P\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x01\x93\xa1\xac\x16\x80\x0c\xc0\xa82\x16\x00i\x02q\x00\x00\x00\x01\x00\x00\x00(\xb5\xfa\x87&\xb5\xfa\x87&\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x01\x83Z\xac\x1fR\xcd\xc0\xa82\x16\x00i\x02q\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfa\x90\r\xb5\xfa\x90\r\xf7*\x00\x8a\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x0c\xe0\xad\xac\x01\xa8V\xc0\xa822\x02q\x00i\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfa\x9c\xf6\xb5\xfa\x9c\xf6\xe5|\x1a+\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x1e\xccT\xac<x&\n\x00\x02\x01\x02q\x00\xdb\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfa\x80\xea\xb5\xfa\x80\xea\x00\x00\x00\x00\x00\x00/\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x01\xbb\x18\xac\x01|z\xc0\xa82\x16\x00i\x02q\x00\x00\x00\x01\x00\x00\x00\xfa\xb5\xfa\x88p\xb5\xfa\x88p\x00P\x0b}\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x17\x0er\xac\x01\x8f\xdd\xc0\xa822\x02q\x00i\x00\x00\x00\x01\x00\x00\x02(\xb5\xfa\x89\xf7\xb5\xfa\x89\xf7\r\xf7\x00\x8a\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\n\xbb\x04\xac<\xb0\x15\n\x00\x02\x01\x02q\x00\xdb\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfa\x90\xa9\xb5\xfa\x90\xa9\x9c\xd0\x00\x8f\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\nz?\xac)\x03\xc8\n\x00\x02\x01\x02q\x00\xdb\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfaue\xb5\xfaue\xee\xa6\x00P\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x01\xb5\x05\xc0\xa8c\x9f\n\x00\x02\x01\x00i\x00\xdb\x00\x00\x00\x01\x00\x00\x05\xdc\xb5\xfa{\xc7\xb5\xfa{\xc7\x00P\x86\xa9\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac2\xa5\x1b\xac)0\xbf\n\x00\x02\x01\x02q\x00\xdb\x00\x00\x00\x01\x00\x00\x00\xfa\xb5\xfa\x9bZ\xb5\xfa\x9bZC\xf9\x17\xe0\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00' + + def testPack(self): + pass + + def testUnpack(self): + nf = Netflow5(self.sample_v5) + assert len(nf.data) == 29 + #print repr(nfv5) + + unittest.main() + + diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/ntp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/ntp.py new file mode 100644 index 00000000..7012af2a --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/ntp.py @@ -0,0 +1,83 @@ +# $Id: ntp.py 48 2008-05-27 17:31:15Z yardley $ + +"""Network Time Protocol.""" + +import dpkt + +# NTP v4 + +# Leap Indicator (LI) Codes +NO_WARNING = 0 +LAST_MINUTE_61_SECONDS = 1 +LAST_MINUTE_59_SECONDS = 2 +ALARM_CONDITION = 3 + +# Mode Codes +RESERVED = 0 +SYMMETRIC_ACTIVE = 1 +SYMMETRIC_PASSIVE = 2 +CLIENT = 3 +SERVER = 4 +BROADCAST = 5 +CONTROL_MESSAGE = 6 +PRIVATE = 7 + +class NTP(dpkt.Packet): + __hdr__ = ( + ('flags', 'B', 0), + ('stratum', 'B', 0), + ('interval', 'B', 0), + ('precision', 'B', 0), + ('delay', 'I', 0), + ('dispersion', 'I', 0), + ('id', '4s', 0), + ('update_time', '8s', 0), + ('originate_time', '8s', 0), + ('receive_time', '8s', 0), + ('transmit_time', '8s', 0) + ) + + def _get_v(self): + return (self.flags >> 3) & 0x7 + def _set_v(self, v): + self.flags = (self.flags & ~0x38) | ((v & 0x7) << 3) + v = property(_get_v, _set_v) + + def _get_li(self): + return (self.flags >> 6) & 0x3 + def _set_li(self, li): + self.flags = (self.flags & ~0xc0) | ((li & 0x3) << 6) + li = property(_get_li, _set_li) + + def _get_mode(self): + return (self.flags & 0x7) + def _set_mode(self, mode): + self.flags = (self.flags & ~0x7) | (mode & 0x7) + mode = property(_get_mode, _set_mode) + +if __name__ == '__main__': + import unittest + + class NTPTestCase(unittest.TestCase): + def testPack(self): + n = NTP(self.s) + self.failUnless(self.s == str(n)) + + def testUnpack(self): + n = NTP(self.s) + self.failUnless(n.li == NO_WARNING) + self.failUnless(n.v == 4) + self.failUnless(n.mode == SERVER) + self.failUnless(n.stratum == 2) + self.failUnless(n.id == '\xc1\x02\x04\x02') + + # test get/set functions + n.li = ALARM_CONDITION + n.v = 3 + n.mode = CLIENT + self.failUnless(n.li == ALARM_CONDITION) + self.failUnless(n.v == 3) + self.failUnless(n.mode == CLIENT) + + s = '\x24\x02\x04\xef\x00\x00\x00\x84\x00\x00\x33\x27\xc1\x02\x04\x02\xc8\x90\xec\x11\x22\xae\x07\xe5\xc8\x90\xf9\xd9\xc0\x7e\x8c\xcd\xc8\x90\xf9\xd9\xda\xc5\xb0\x78\xc8\x90\xf9\xd9\xda\xc6\x8a\x93' + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/ospf.py b/scripts/external_libs/dpkt-1.8.6/dpkt/ospf.py new file mode 100644 index 00000000..0ea0b3ca --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/ospf.py @@ -0,0 +1,25 @@ +# $Id: ospf.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Open Shortest Path First.""" + +import dpkt + +AUTH_NONE = 0 +AUTH_PASSWORD = 1 +AUTH_CRYPTO = 2 + +class OSPF(dpkt.Packet): + __hdr__ = ( + ('v', 'B', 0), + ('type', 'B', 0), + ('len', 'H', 0), + ('router', 'I', 0), + ('area', 'I', 0), + ('sum', 'H', 0), + ('atype', 'H', 0), + ('auth', '8s', '') + ) + def __str__(self): + if not self.sum: + self.sum = dpkt.in_cksum(dpkt.Packet.__str__(self)) + return dpkt.Packet.__str__(self) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/pcap.py b/scripts/external_libs/dpkt-1.8.6/dpkt/pcap.py new file mode 100644 index 00000000..45aca3b1 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/pcap.py @@ -0,0 +1,164 @@ +# $Id: pcap.py 77 2011-01-06 15:59:38Z dugsong $ + +"""Libpcap file format.""" + +import sys, time +import dpkt + +TCPDUMP_MAGIC = 0xa1b2c3d4L +PMUDPCT_MAGIC = 0xd4c3b2a1L + +PCAP_VERSION_MAJOR = 2 +PCAP_VERSION_MINOR = 4 + +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 +DLT_PFSYNC = 18 +DLT_IEEE802_11 = 105 +DLT_LINUX_SLL = 113 +DLT_PFLOG = 117 +DLT_IEEE802_11_RADIO = 127 + +if sys.platform.find('openbsd') != -1: + DLT_LOOP = 12 + DLT_RAW = 14 +else: + DLT_LOOP = 108 + DLT_RAW = 12 + +dltoff = { DLT_NULL:4, DLT_EN10MB:14, DLT_IEEE802:22, DLT_ARCNET:6, + DLT_SLIP:16, DLT_PPP:4, DLT_FDDI:21, DLT_PFLOG:48, DLT_PFSYNC:4, + DLT_LOOP:4, DLT_LINUX_SLL:16 } + +class PktHdr(dpkt.Packet): + """pcap packet header.""" + __hdr__ = ( + ('tv_sec', 'I', 0), + ('tv_usec', 'I', 0), + ('caplen', 'I', 0), + ('len', 'I', 0), + ) + +class LEPktHdr(PktHdr): + __byte_order__ = '<' + +class FileHdr(dpkt.Packet): + """pcap file header.""" + __hdr__ = ( + ('magic', 'I', TCPDUMP_MAGIC), + ('v_major', 'H', PCAP_VERSION_MAJOR), + ('v_minor', 'H', PCAP_VERSION_MINOR), + ('thiszone', 'I', 0), + ('sigfigs', 'I', 0), + ('snaplen', 'I', 1500), + ('linktype', 'I', 1), + ) + +class LEFileHdr(FileHdr): + __byte_order__ = '<' + +class Writer(object): + """Simple pcap dumpfile writer.""" + def __init__(self, fileobj, snaplen=1500, linktype=DLT_EN10MB): + self.__f = fileobj + if sys.byteorder == 'little': + fh = LEFileHdr(snaplen=snaplen, linktype=linktype) + else: + fh = FileHdr(snaplen=snaplen, linktype=linktype) + self.__f.write(str(fh)) + + def writepkt(self, pkt, ts=None): + if ts is None: + ts = time.time() + s = str(pkt) + n = len(s) + if sys.byteorder == 'little': + ph = LEPktHdr(tv_sec=int(ts), + tv_usec=int((float(ts) - int(ts)) * 1000000.0), + caplen=n, len=n) + else: + ph = PktHdr(tv_sec=int(ts), + tv_usec=int((float(ts) - int(ts)) * 1000000.0), + caplen=n, len=n) + self.__f.write(str(ph)) + self.__f.write(s) + + def close(self): + self.__f.close() + +class Reader(object): + """Simple pypcap-compatible pcap file reader.""" + + def __init__(self, fileobj): + self.name = fileobj.name + self.fd = fileobj.fileno() + self.__f = fileobj + buf = self.__f.read(FileHdr.__hdr_len__) + self.__fh = FileHdr(buf) + self.__ph = PktHdr + if self.__fh.magic == PMUDPCT_MAGIC: + self.__fh = LEFileHdr(buf) + self.__ph = LEPktHdr + elif self.__fh.magic != TCPDUMP_MAGIC: + raise ValueError, 'invalid tcpdump header' + if self.__fh.linktype in dltoff: + self.dloff = dltoff[self.__fh.linktype] + else: + self.dloff = 0 + self.snaplen = self.__fh.snaplen + self.filter = '' + + def fileno(self): + return self.fd + + def datalink(self): + return self.__fh.linktype + + def setfilter(self, value, optimize=1): + return NotImplementedError + + def readpkts(self): + return list(self) + + def dispatch(self, cnt, callback, *args): + if cnt > 0: + for i in range(cnt): + ts, pkt = self.next() + callback(ts, pkt, *args) + else: + for ts, pkt in self: + callback(ts, pkt, *args) + + def loop(self, callback, *args): + self.dispatch(0, callback, *args) + + def __iter__(self): + self.__f.seek(FileHdr.__hdr_len__) + while 1: + buf = self.__f.read(PktHdr.__hdr_len__) + if not buf: break + hdr = self.__ph(buf) + buf = self.__f.read(hdr.caplen) + yield (hdr.tv_sec + (hdr.tv_usec / 1000000.0), buf) + +if __name__ == '__main__': + import unittest + + class PcapTestCase(unittest.TestCase): + def test_endian(self): + be = '\xa1\xb2\xc3\xd4\x00\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x01' + le = '\xd4\xc3\xb2\xa1\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x01\x00\x00\x00' + befh = FileHdr(be) + lefh = LEFileHdr(le) + self.failUnless(befh.linktype == lefh.linktype) + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/pim.py b/scripts/external_libs/dpkt-1.8.6/dpkt/pim.py new file mode 100644 index 00000000..fa340dd0 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/pim.py @@ -0,0 +1,24 @@ +# $Id: pim.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Protocol Independent Multicast.""" + +import dpkt + +class PIM(dpkt.Packet): + __hdr__ = ( + ('v_type', 'B', 0x20), + ('rsvd', 'B', 0), + ('sum', 'H', 0) + ) + def _get_v(self): return self.v_type >> 4 + def _set_v(self, v): self.v_type = (v << 4) | (self.v_type & 0xf) + v = property(_get_v, _set_v) + + def _get_type(self): return self.v_type & 0xf + def _set_type(self, type): self.v_type = (self.v_type & 0xf0) | type + type = property(_get_type, _set_type) + + def __str__(self): + if not self.sum: + self.sum = dpkt.in_cksum(dpkt.Packet.__str__(self)) + return dpkt.Packet.__str__(self) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/pmap.py b/scripts/external_libs/dpkt-1.8.6/dpkt/pmap.py new file mode 100644 index 00000000..53185b22 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/pmap.py @@ -0,0 +1,17 @@ +# $Id: pmap.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Portmap / rpcbind.""" + +import dpkt + +PMAP_PROG = 100000L +PMAP_PROCDUMP = 4 +PMAP_VERS = 2 + +class Pmap(dpkt.Packet): + __hdr__ = ( + ('prog', 'I', 0), + ('vers', 'I', 0), + ('prot', 'I', 0), + ('port', 'I', 0), + ) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/ppp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/ppp.py new file mode 100644 index 00000000..f4898b95 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/ppp.py @@ -0,0 +1,63 @@ +# $Id: ppp.py 65 2010-03-26 02:53:51Z dugsong $ + +"""Point-to-Point Protocol.""" + +import struct +import dpkt + +# XXX - finish later + +# http://www.iana.org/assignments/ppp-numbers +PPP_IP = 0x21 # Internet Protocol +PPP_IP6 = 0x57 # Internet Protocol v6 + +# Protocol field compression +PFC_BIT = 0x01 + +class PPP(dpkt.Packet): + __hdr__ = ( + ('p', 'B', PPP_IP), + ) + _protosw = {} + + def set_p(cls, p, pktclass): + cls._protosw[p] = pktclass + set_p = classmethod(set_p) + + def get_p(cls, p): + return cls._protosw[p] + get_p = classmethod(get_p) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + if self.p & PFC_BIT == 0: + self.p = struct.unpack('>H', buf[:2])[0] + self.data = self.data[1:] + try: + self.data = self._protosw[self.p](self.data) + setattr(self, self.data.__class__.__name__.lower(), self.data) + except (KeyError, struct.error, dpkt.UnpackError): + pass + + def pack_hdr(self): + try: + if self.p > 0xff: + return struct.pack('>H', self.p) + return dpkt.Packet.pack_hdr(self) + except struct.error, e: + raise dpkt.PackError(str(e)) + +def __load_protos(): + g = globals() + for k, v in g.iteritems(): + if k.startswith('PPP_'): + name = k[4:] + modname = name.lower() + try: + mod = __import__(modname, g) + except ImportError: + continue + PPP.set_p(v, getattr(mod, name)) + +if not PPP._protosw: + __load_protos() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/pppoe.py b/scripts/external_libs/dpkt-1.8.6/dpkt/pppoe.py new file mode 100644 index 00000000..8b4c9e71 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/pppoe.py @@ -0,0 +1,38 @@ +# $Id: pppoe.py 23 2006-11-08 15:45:33Z dugsong $ + +"""PPP-over-Ethernet.""" + +import dpkt, ppp + +# RFC 2516 codes +PPPoE_PADI = 0x09 +PPPoE_PADO = 0x07 +PPPoE_PADR = 0x19 +PPPoE_PADS = 0x65 +PPPoE_PADT = 0xA7 +PPPoE_SESSION = 0x00 + +class PPPoE(dpkt.Packet): + __hdr__ = ( + ('v_type', 'B', 0x11), + ('code', 'B', 0), + ('session', 'H', 0), + ('len', 'H', 0) # payload length + ) + def _get_v(self): return self.v_type >> 4 + def _set_v(self, v): self.v_type = (v << 4) | (self.v_type & 0xf) + v = property(_get_v, _set_v) + + def _get_type(self): return self.v_type & 0xf + def _set_type(self, t): self.v_type = (self.v_type & 0xf0) | t + type = property(_get_type, _set_type) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + try: + if self.code == 0: + self.data = self.ppp = ppp.PPP(self.data) + except dpkt.UnpackError: + pass + +# XXX - TODO TLVs, etc. diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/qq.py b/scripts/external_libs/dpkt-1.8.6/dpkt/qq.py new file mode 100644 index 00000000..4720c69b --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/qq.py @@ -0,0 +1,224 @@ +# $Id: qq.py 48 2008-05-27 17:31:15Z yardley $ + +from dpkt import Packet + +# header_type +QQ_HEADER_BASIC_FAMILY = 0x02 +QQ_HEADER_P2P_FAMILY = 0x00 +QQ_HEADER_03_FAMILY = 0x03 +QQ_HEADER_04_FAMILY = 0x04 +QQ_HEADER_05_FAMILY = 0x05 + +header_type_str = [ + "QQ_HEADER_P2P_FAMILY", + "Unknown Type", + "QQ_HEADER_03_FAMILY", + "QQ_HEADER_04_FAMILY", + "QQ_HEADER_05_FAMILY", +] + +# command +QQ_CMD_LOGOUT = 0x0001 +QQ_CMD_KEEP_ALIVE = 0x0002 +QQ_CMD_MODIFY_INFO = 0x0004 +QQ_CMD_SEARCH_USER = 0x0005 +QQ_CMD_GET_USER_INFO = 0x0006 +QQ_CMD_ADD_FRIEND = 0x0009 +QQ_CMD_DELETE_FRIEND = 0x000A +QQ_CMD_ADD_FRIEND_AUTH = 0x000B +QQ_CMD_CHANGE_STATUS = 0x000D +QQ_CMD_ACK_SYS_MSG = 0x0012 +QQ_CMD_SEND_IM = 0x0016 +QQ_CMD_RECV_IM = 0x0017 +QQ_CMD_REMOVE_SELF = 0x001C +QQ_CMD_REQUEST_KEY = 0x001D +QQ_CMD_LOGIN = 0x0022 +QQ_CMD_GET_FRIEND_LIST = 0x0026 +QQ_CMD_GET_ONLINE_OP = 0x0027 +QQ_CMD_SEND_SMS = 0x002D +QQ_CMD_CLUSTER_CMD = 0x0030 +QQ_CMD_TEST = 0x0031 +QQ_CMD_GROUP_DATA_OP = 0x003C +QQ_CMD_UPLOAD_GROUP_FRIEND = 0x003D +QQ_CMD_FRIEND_DATA_OP = 0x003E +QQ_CMD_DOWNLOAD_GROUP_FRIEND = 0x0058 +QQ_CMD_FRIEND_LEVEL_OP = 0x005C +QQ_CMD_PRIVACY_DATA_OP = 0x005E +QQ_CMD_CLUSTER_DATA_OP = 0x005F +QQ_CMD_ADVANCED_SEARCH = 0x0061 +QQ_CMD_REQUEST_LOGIN_TOKEN = 0x0062 +QQ_CMD_USER_PROPERTY_OP = 0x0065 +QQ_CMD_TEMP_SESSION_OP = 0x0066 +QQ_CMD_SIGNATURE_OP = 0x0067 +QQ_CMD_RECV_MSG_SYS = 0x0080 +QQ_CMD_RECV_MSG_FRIEND_CHANGE_STATUS = 0x0081 +QQ_CMD_WEATHER_OP = 0x00A6 +QQ_CMD_ADD_FRIEND_EX = 0x00A7 +QQ_CMD_AUTHORIZE = 0X00A8 +QQ_CMD_UNKNOWN = 0xFFFF +QQ_SUB_CMD_SEARCH_ME_BY_QQ_ONLY = 0x03 +QQ_SUB_CMD_SHARE_GEOGRAPHY = 0x04 +QQ_SUB_CMD_GET_FRIEND_LEVEL = 0x02 +QQ_SUB_CMD_GET_CLUSTER_ONLINE_MEMBER = 0x01 +QQ_05_CMD_REQUEST_AGENT = 0x0021 +QQ_05_CMD_REQUEST_FACE = 0x0022 +QQ_05_CMD_TRANSFER = 0x0023 +QQ_05_CMD_REQUEST_BEGIN = 0x0026 +QQ_CLUSTER_CMD_CREATE_CLUSTER= 0x01 +QQ_CLUSTER_CMD_MODIFY_MEMBER= 0x02 +QQ_CLUSTER_CMD_MODIFY_CLUSTER_INFO= 0x03 +QQ_CLUSTER_CMD_GET_CLUSTER_INFO= 0x04 +QQ_CLUSTER_CMD_ACTIVATE_CLUSTER= 0x05 +QQ_CLUSTER_CMD_SEARCH_CLUSTER= 0x06 +QQ_CLUSTER_CMD_JOIN_CLUSTER= 0x07 +QQ_CLUSTER_CMD_JOIN_CLUSTER_AUTH= 0x08 +QQ_CLUSTER_CMD_EXIT_CLUSTER= 0x09 +QQ_CLUSTER_CMD_SEND_IM= 0x0A +QQ_CLUSTER_CMD_GET_ONLINE_MEMBER= 0x0B +QQ_CLUSTER_CMD_GET_MEMBER_INFO= 0x0C +QQ_CLUSTER_CMD_MODIFY_CARD = 0x0E +QQ_CLUSTER_CMD_GET_CARD_BATCH= 0x0F +QQ_CLUSTER_CMD_GET_CARD = 0x10 +QQ_CLUSTER_CMD_COMMIT_ORGANIZATION = 0x11 +QQ_CLUSTER_CMD_UPDATE_ORGANIZATION= 0x12 +QQ_CLUSTER_CMD_COMMIT_MEMBER_ORGANIZATION = 0x13 +QQ_CLUSTER_CMD_GET_VERSION_ID= 0x19 +QQ_CLUSTER_CMD_SEND_IM_EX = 0x1A +QQ_CLUSTER_CMD_SET_ROLE = 0x1B +QQ_CLUSTER_CMD_TRANSFER_ROLE = 0x1C +QQ_CLUSTER_CMD_CREATE_TEMP = 0x30 +QQ_CLUSTER_CMD_MODIFY_TEMP_MEMBER = 0x31 +QQ_CLUSTER_CMD_EXIT_TEMP = 0x32 +QQ_CLUSTER_CMD_GET_TEMP_INFO = 0x33 +QQ_CLUSTER_CMD_MODIFY_TEMP_INFO = 0x34 +QQ_CLUSTER_CMD_SEND_TEMP_IM = 0x35 +QQ_CLUSTER_CMD_SUB_CLUSTER_OP = 0x36 +QQ_CLUSTER_CMD_ACTIVATE_TEMP = 0x37 + +QQ_CLUSTER_SUB_CMD_ADD_MEMBER = 0x01 +QQ_CLUSTER_SUB_CMD_REMOVE_MEMBER = 0x02 +QQ_CLUSTER_SUB_CMD_GET_SUBJECT_LIST = 0x02 +QQ_CLUSTER_SUB_CMD_GET_DIALOG_LIST = 0x01 + +QQ_SUB_CMD_GET_ONLINE_FRIEND = 0x2 +QQ_SUB_CMD_GET_ONLINE_SERVICE = 0x3 +QQ_SUB_CMD_UPLOAD_GROUP_NAME = 0x2 +QQ_SUB_CMD_DOWNLOAD_GROUP_NAME = 0x1 +QQ_SUB_CMD_SEND_TEMP_SESSION_IM = 0x01 +QQ_SUB_CMD_BATCH_DOWNLOAD_FRIEND_REMARK = 0x0 +QQ_SUB_CMD_UPLOAD_FRIEND_REMARK = 0x1 +QQ_SUB_CMD_REMOVE_FRIEND_FROM_LIST = 0x2 +QQ_SUB_CMD_DOWNLOAD_FRIEND_REMARK = 0x3 +QQ_SUB_CMD_MODIFY_SIGNATURE = 0x01 +QQ_SUB_CMD_DELETE_SIGNATURE = 0x02 +QQ_SUB_CMD_GET_SIGNATURE = 0x03 +QQ_SUB_CMD_GET_USER_PROPERTY = 0x01 +QQ_SUB_CMD_GET_WEATHER = 0x01 + +QQ_FILE_CMD_HEART_BEAT = 0x0001 +QQ_FILE_CMD_HEART_BEAT_ACK = 0x0002 +QQ_FILE_CMD_TRANSFER_FINISHED = 0x0003 +QQ_FILE_CMD_FILE_OP = 0x0007 +QQ_FILE_CMD_FILE_OP_ACK = 0x0008 +QQ_FILE_CMD_SENDER_SAY_HELLO = 0x0031 +QQ_FILE_CMD_SENDER_SAY_HELLO_ACK = 0x0032 +QQ_FILE_CMD_RECEIVER_SAY_HELLO = 0x0033 +QQ_FILE_CMD_RECEIVER_SAY_HELLO_ACK = 0x0034 +QQ_FILE_CMD_NOTIFY_IP_ACK = 0x003C +QQ_FILE_CMD_PING = 0x003D +QQ_FILE_CMD_PONG = 0x003E +QQ_FILE_CMD_YES_I_AM_BEHIND_FIREWALL = 0x0040 +QQ_FILE_CMD_REQUEST_AGENT = 0x0001 +QQ_FILE_CMD_CHECK_IN = 0x0002 +QQ_FILE_CMD_FORWARD = 0x0003 +QQ_FILE_CMD_FORWARD_FINISHED = 0x0004 +QQ_FILE_CMD_IT_IS_TIME = 0x0005 +QQ_FILE_CMD_I_AM_READY = 0x0006 + +command_str = { + 0x0001: "QQ_CMD_LOGOUT", + 0x0002: "QQ_CMD_KEEP_ALIVE", + 0x0004: "QQ_CMD_MODIFY_INFO", + 0x0005: "QQ_CMD_SEARCH_USER", + 0x0006: "QQ_CMD_GET_USER_INFO", + 0x0009: "QQ_CMD_ADD_FRIEND", + 0x000A: "QQ_CMD_DELETE_FRIEND", + 0x000B: "QQ_CMD_ADD_FRIEND_AUTH", + 0x000D: "QQ_CMD_CHANGE_STATUS", + 0x0012: "QQ_CMD_ACK_SYS_MSG", + 0x0016: "QQ_CMD_SEND_IM", + 0x0017: "QQ_CMD_RECV_IM", + 0x001C: "QQ_CMD_REMOVE_SELF", + 0x001D: "QQ_CMD_REQUEST_KEY", + 0x0022: "QQ_CMD_LOGIN", + 0x0026: "QQ_CMD_GET_FRIEND_LIST", + 0x0027: "QQ_CMD_GET_ONLINE_OP", + 0x002D: "QQ_CMD_SEND_SMS", + 0x0030: "QQ_CMD_CLUSTER_CMD", + 0x0031: "QQ_CMD_TEST", + 0x003C: "QQ_CMD_GROUP_DATA_OP", + 0x003D: "QQ_CMD_UPLOAD_GROUP_FRIEND", + 0x003E: "QQ_CMD_FRIEND_DATA_OP", + 0x0058: "QQ_CMD_DOWNLOAD_GROUP_FRIEND", + 0x005C: "QQ_CMD_FRIEND_LEVEL_OP", + 0x005E: "QQ_CMD_PRIVACY_DATA_OP", + 0x005F: "QQ_CMD_CLUSTER_DATA_OP", + 0x0061: "QQ_CMD_ADVANCED_SEARCH", + 0x0062: "QQ_CMD_REQUEST_LOGIN_TOKEN", + 0x0065: "QQ_CMD_USER_PROPERTY_OP", + 0x0066: "QQ_CMD_TEMP_SESSION_OP", + 0x0067: "QQ_CMD_SIGNATURE_OP", + 0x0080: "QQ_CMD_RECV_MSG_SYS", + 0x0081: "QQ_CMD_RECV_MSG_FRIEND_CHANGE_STATUS", + 0x00A6: "QQ_CMD_WEATHER_OP", + 0x00A7: "QQ_CMD_ADD_FRIEND_EX", + 0x00A8: "QQ_CMD_AUTHORIZE", + 0xFFFF: "QQ_CMD_UNKNOWN", + 0x0021: "_CMD_REQUEST_AGENT", + 0x0022: "_CMD_REQUEST_FACE", + 0x0023: "_CMD_TRANSFER", + 0x0026: "_CMD_REQUEST_BEGIN", +} + + +class QQBasicPacket(Packet): + __hdr__ = ( + ('header_type', 'B', 2), + ('source', 'H', 0), + ('command', 'H', 0), + ('sequence', 'H', 0), + ('qqNum', 'L', 0), + ) + + +class QQ3Packet(Packet): + __hdr__ = ( + ('header_type', 'B', 3), + ('command', 'B', 0), + ('sequence', 'H', 0), + ('unknown1', 'L', 0), + ('unknown2', 'L', 0), + ('unknown3', 'L', 0), + ('unknown4', 'L', 0), + ('unknown5', 'L', 0), + ('unknown6', 'L', 0), + ('unknown7', 'L', 0), + ('unknown8', 'L', 0), + ('unknown9', 'L', 0), + ('unknown10', 'B', 1), + ('unknown11', 'B', 0), + ('unknown12', 'B', 0), + ('source', 'H', 0), + ('unknown13', 'B', 0), + ) + + +class QQ5Packet(Packet): + __hdr__ = ( + ('header_type', 'B', 5), + ('source', 'H', 0), + ('unknown', 'H', 0), + ('command', 'H', 0), + ('sequence', 'H', 0), + ('qqNum', 'L', 0), + ) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/radiotap.py b/scripts/external_libs/dpkt-1.8.6/dpkt/radiotap.py new file mode 100644 index 00000000..318be6cc --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/radiotap.py @@ -0,0 +1,292 @@ +'''Radiotap''' + +import dpkt +import ieee80211 +import socket + +# Ref: http://www.radiotap.org +# Fields Ref: http://www.radiotap.org/defined-fields/all + +# Present flags +_TSFT_MASK = 0x1000000 +_FLAGS_MASK = 0x2000000 +_RATE_MASK = 0x4000000 +_CHANNEL_MASK = 0x8000000 +_FHSS_MASK = 0x10000000 +_ANT_SIG_MASK = 0x20000000 +_ANT_NOISE_MASK = 0x40000000 +_LOCK_QUAL_MASK = 0x80000000 +_TX_ATTN_MASK = 0x10000 +_DB_TX_ATTN_MASK = 0x20000 +_DBM_TX_POWER_MASK = 0x40000 +_ANTENNA_MASK = 0x80000 +_DB_ANT_SIG_MASK = 0x100000 +_DB_ANT_NOISE_MASK = 0x200000 +_RX_FLAGS_MASK = 0x400000 +_CHANNELPLUS_MASK = 0x200 +_EXT_MASK = 0x1 + +_TSFT_SHIFT = 24 +_FLAGS_SHIFT = 25 +_RATE_SHIFT = 26 +_CHANNEL_SHIFT = 27 +_FHSS_SHIFT = 28 +_ANT_SIG_SHIFT = 29 +_ANT_NOISE_SHIFT = 30 +_LOCK_QUAL_SHIFT = 31 +_TX_ATTN_SHIFT = 16 +_DB_TX_ATTN_SHIFT = 17 +_DBM_TX_POWER_SHIFT = 18 +_ANTENNA_SHIFT = 19 +_DB_ANT_SIG_SHIFT = 20 +_DB_ANT_NOISE_SHIFT = 21 +_RX_FLAGS_SHIFT = 22 +_CHANNELPLUS_SHIFT = 10 +_EXT_SHIFT = 0 + +# Flags elements +_FLAGS_SIZE = 2 +_CFP_FLAG_SHIFT = 0 +_PREAMBLE_SHIFT = 1 +_WEP_SHIFT = 2 +_FRAG_SHIFT = 3 +_FCS_SHIFT = 4 +_DATA_PAD_SHIFT = 5 +_BAD_FCS_SHIFT = 6 +_SHORT_GI_SHIFT = 7 + +# Channel type +_CHAN_TYPE_SIZE = 4 +_CHANNEL_TYPE_SHIFT = 4 +_CCK_SHIFT = 5 +_OFDM_SHIFT = 6 +_TWO_GHZ_SHIFT = 7 +_FIVE_GHZ_SHIFT = 8 +_PASSIVE_SHIFT = 9 +_DYN_CCK_OFDM_SHIFT = 10 +_GFSK_SHIFT = 11 +_GSM_SHIFT = 12 +_STATIC_TURBO_SHIFT = 13 +_HALF_RATE_SHIFT = 14 +_QUARTER_RATE_SHIFT = 15 + +# Flags offsets and masks +_FCS_SHIFT = 4 +_FCS_MASK = 0x10 + +class Radiotap(dpkt.Packet): + __hdr__ = ( + ('version', 'B', 0), + ('pad', 'B', 0), + ('length', 'H', 0), + ('present_flags', 'I', 0) + ) + + def _get_tsft_present(self): return (self.present_flags & _TSFT_MASK) >> _TSFT_SHIFT + def _set_tsft_present(self, val): self.present_flags = self.present_flags | (val << _TSFT_SHIFT) + def _get_flags_present(self): return (self.present_flags & _FLAGS_MASK) >> _FLAGS_SHIFT + def _set_flags_present(self, val): self.present_flags = self.present_flags | (val << _FLAGS_SHIFT) + def _get_rate_present(self): return (self.present_flags & _RATE_MASK) >> _RATE_SHIFT + def _set_rate_present(self, val): self.present_flags = self.present_flags | (val << _RATE_SHIFT) + def _get_channel_present(self): return (self.present_flags & _CHANNEL_MASK) >> _CHANNEL_SHIFT + def _set_channel_present(self, val): self.present_flags = self.present_flags | (val << _CHANNEL_SHIFT) + def _get_fhss_present(self): return (self.present_flags & _FHSS_MASK) >> _FHSS_SHIFT + def _set_fhss_present(self, val): self.present_flags = self.present_flags | (val << _FHSS_SHIFT) + def _get_ant_sig_present(self): return (self.present_flags & _ANT_SIG_MASK) >> _ANT_SIG_SHIFT + def _set_ant_sig_present(self, val): self.present_flags = self.present_flags | (val << _ANT_SIG_SHIFT) + def _get_ant_noise_present(self): return (self.present_flags & _ANT_NOISE_MASK) >> _ANT_NOISE_SHIFT + def _set_ant_noise_present(self, val): self.present_flags = self.present_flags | (val << _ANT_NOISE_SHIFT) + def _get_lock_qual_present(self): return (self.present_flags & _LOCK_QUAL_MASK) >> _LOCK_QUAL_SHIFT + def _set_lock_qual_present(self, val): self.present_flags = self.present_flags | (val << _LOCK_QUAL_SHIFT) + def _get_tx_attn_present(self): return (self.present_flags & _TX_ATTN_MASK) >> _TX_ATTN_SHIFT + def _set_tx_attn_present(self, val): self.present_flags = self.present_flags | (val << _TX_ATTN_SHIFT) + def _get_db_tx_attn_present(self): return (self.present_flags & _DB_TX_ATTN_MASK) >> _DB_TX_ATTN_SHIFT + def _set_db_tx_attn_present(self, val): self.present_flags = self.present_flags | (val << _DB_TX_ATTN_SHIFT) + def _get_dbm_power_present(self): return (self.present_flags & _DBM_TX_POWER_MASK) >> _DBM_TX_POWER_SHIFT + def _set_dbm_power_present(self, val): self.present_flags = self.present_flags | (val << _DBM_TX_POWER_SHIFT) + def _get_ant_present(self): return (self.present_flags & _ANTENNA_MASK) >> _ANTENNA_SHIFT + def _set_ant_present(self, val): self.present_flags = self.present_flags | (val << _ANTENNA_SHIFT) + def _get_db_ant_sig_present(self): return (self.present_flags & _DB_ANT_SIG_MASK) >> _DB_ANT_SIG_SHIFT + def _set_db_ant_sig_present(self, val): self.present_flags = self.present_flags | (val << _DB_ANT_SIG_SHIFT) + def _get_db_ant_noise_present(self): return (self.present_flags & _DB_ANT_NOISE_MASK) >> _DB_ANT_NOISE_SHIFT + def _set_db_ant_noise_present(self, val): self.present_flags = self.present_flags | (val << _DB_ANT_NOISE_SHIFT) + def _get_rx_flags_present(self): return (self.present_flags & _RX_FLAGS_MASK) >> _RX_FLAGS_SHIFT + def _set_rx_flags_present(self, val): self.present_flags = self.present_flags | (val << _RX_FLAGS_SHIFT) + def _get_chanplus_present(self): return (self.present_flags & _CHANNELPLUS_MASK) >> _CHANNELPLUS_SHIFT + def _set_chanplus_present(self, val): self.present_flags = self.present_flags | (val << _CHANNELPLUS_SHIFT) + def _get_ext_present(self): return (self.present_flags & _EXT_MASK) >> _EXT_SHIFT + def _set_ext_present(self, val): self.present_flags = self.present_flags | (val << _EXT_SHIFT) + + tsft_present = property(_get_tsft_present, _set_tsft_present) + flags_present = property(_get_flags_present, _set_flags_present) + rate_present = property(_get_rate_present, _set_rate_present) + channel_present = property(_get_channel_present, _set_channel_present) + fhss_present = property(_get_fhss_present, _set_fhss_present) + ant_sig_present = property(_get_ant_sig_present, _set_ant_sig_present) + ant_noise_present = property(_get_ant_noise_present, _set_ant_noise_present) + lock_qual_present = property(_get_lock_qual_present, _set_lock_qual_present) + tx_attn_present = property(_get_tx_attn_present, _set_tx_attn_present) + db_tx_attn_present = property(_get_db_tx_attn_present, _set_db_tx_attn_present) + dbm_tx_power_present = property(_get_dbm_power_present, _set_dbm_power_present) + ant_present = property(_get_ant_present, _set_ant_present) + db_ant_sig_present = property(_get_db_ant_sig_present, _set_db_ant_sig_present) + db_ant_noise_present = property(_get_db_ant_noise_present, _set_db_ant_noise_present) + rx_flags_present = property(_get_rx_flags_present, _set_rx_flags_present) + chanplus_present = property(_get_chanplus_present, _set_chanplus_present) + ext_present = property(_get_ext_present, _set_ext_present) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = buf[socket.ntohs(self.length):] + + self.fields = [] + buf = buf[self.__hdr_len__:] + + # decode each field into self.<name> (eg. self.tsft) as well as append it self.fields list + field_decoder = [ + ('tsft', self.tsft_present, self.TSFT), + ('flags', self.flags_present, self.Flags), + ('rate', self.rate_present, self.Rate), + ('channel', self.channel_present, self.Channel), + ('fhss', self.fhss_present, self.FHSS), + ('ant_sig', self.ant_sig_present, self.AntennaSignal), + ('ant_noise', self.ant_noise_present, self.AntennaNoise), + ('lock_qual', self.lock_qual_present, self.LockQuality), + ('tx_attn', self.tx_attn_present, self.TxAttenuation), + ('db_tx_attn', self.db_tx_attn_present, self.DbTxAttenuation), + ('dbm_tx_power', self.dbm_tx_power_present, self.DbmTxPower), + ('ant', self.ant_present, self.Antenna), + ('db_ant_sig', self.db_ant_sig_present, self.DbAntennaSignal), + ('db_ant_noise', self.db_ant_noise_present, self.DbAntennaNoise), + ('rx_flags', self.rx_flags_present, self.RxFlags) + ] + for name, present_bit, parser in field_decoder: + if present_bit: + field = parser(buf) + field.data = '' + setattr(self, name, field) + self.fields.append(field) + buf = buf[len(field):] + + if len(self.data) > 0: + if self.flags_present and self.flags.fcs: + self.data = ieee80211.IEEE80211(self.data, fcs = self.flags.fcs) + else: + self.data = ieee80211.IEEE80211(self.data) + + class Antenna(dpkt.Packet): + __hdr__ = ( + ('index', 'B', 0), + ) + + class AntennaNoise(dpkt.Packet): + __hdr__ = ( + ('db', 'B', 0), + ) + + class AntennaSignal(dpkt.Packet): + __hdr__ = ( + ('db', 'B', 0), + ) + + class Channel(dpkt.Packet): + __hdr__ = ( + ('freq', 'H', 0), + ('flags', 'H', 0), + ) + + class FHSS(dpkt.Packet): + __hdr__ = ( + ('set', 'B', 0), + ('pattern', 'B', 0), + ) + + class Flags(dpkt.Packet): + __hdr__ = ( + ('val', 'B', 0), + ) + + def _get_fcs_present(self): return (self.val & _FCS_MASK) >> _FCS_SHIFT + + def _set_fcs_present(self, v): (v << _FCS_SHIFT) | (self.val & ~_FCS_MASK) + fcs = property(_get_fcs_present, _set_fcs_present) + + class LockQuality(dpkt.Packet): + __hdr__ = ( + ('val', 'H', 0), + ) + + class RxFlags(dpkt.Packet): + __hdr__ = ( + ('val', 'H', 0), + ) + + class Rate(dpkt.Packet): + __hdr__ = ( + ('val', 'B', 0), + ) + + class TSFT(dpkt.Packet): + __hdr__ = ( + ('usecs', 'Q', 0), + ) + + class TxAttenuation(dpkt.Packet): + __hdr__ = ( + ('val', 'H', 0), + ) + + class DbTxAttenuation(dpkt.Packet): + __hdr__ = ( + ('db', 'H', 0), + ) + + class DbAntennaNoise(dpkt.Packet): + __hdr__ = ( + ('db', 'B', 0), + ) + + class DbAntennaSignal(dpkt.Packet): + __hdr__ = ( + ('db', 'B', 0), + ) + + class DbmTxPower(dpkt.Packet): + __hdr__ = ( + ('dbm', 'B', 0), + ) + +if __name__ == '__main__': + import unittest + + class RadiotapTestCase(unittest.TestCase): + def test_Radiotap(self): + s = '\x00\x00\x00\x18\x6e\x48\x00\x00\x00\x02\x6c\x09\xa0\x00\xa8\x81\x02\x00\x00\x00\x00\x00\x00\x00' + rad = Radiotap(s) + self.failUnless(rad.version == 0) + self.failUnless(rad.present_flags == 0x6e480000) + self.failUnless(rad.tsft_present == 0) + self.failUnless(rad.flags_present == 1) + self.failUnless(rad.rate_present == 1) + self.failUnless(rad.channel_present == 1) + self.failUnless(rad.fhss_present == 0) + self.failUnless(rad.ant_sig_present == 1) + self.failUnless(rad.ant_noise_present == 1) + self.failUnless(rad.lock_qual_present == 0) + self.failUnless(rad.db_tx_attn_present == 0) + self.failUnless(rad.dbm_tx_power_present == 0) + self.failUnless(rad.ant_present == 1) + self.failUnless(rad.db_ant_sig_present == 0) + self.failUnless(rad.db_ant_noise_present == 0) + self.failUnless(rad.rx_flags_present == 1) + self.failUnless(rad.channel.freq == 0x6c09) + self.failUnless(rad.channel.flags == 0xa000) + self.failUnless(len(rad.fields) == 7) + + def test_fcs(self): + s = '\x00\x00\x1a\x00\x2f\x48\x00\x00\x34\x8f\x71\x09\x00\x00\x00\x00\x10\x0c\x85\x09\xc0\x00\xcc\x01\x00\x00' + rt = Radiotap(s) + self.failUnless(rt.flags_present == 1) + self.failUnless(rt.flags.fcs == 1) + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/radius.py b/scripts/external_libs/dpkt-1.8.6/dpkt/radius.py new file mode 100644 index 00000000..440f86f6 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/radius.py @@ -0,0 +1,88 @@ +# $Id: radius.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Remote Authentication Dial-In User Service.""" + +import dpkt + +# http://www.untruth.org/~josh/security/radius/radius-auth.html +# RFC 2865 + +class RADIUS(dpkt.Packet): + __hdr__ = ( + ('code', 'B', 0), + ('id', 'B', 0), + ('len', 'H', 4), + ('auth', '16s', '') + ) + attrs = '' + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.attrs = parse_attrs(self.data) + self.data = '' + +def parse_attrs(buf): + """Parse attributes buffer into a list of (type, data) tuples.""" + attrs = [] + while buf: + t = ord(buf[0]) + l = ord(buf[1]) + if l < 2: + break + d, buf = buf[2:l], buf[l:] + attrs.append((t, d)) + return attrs + +# Codes +RADIUS_ACCESS_REQUEST = 1 +RADIUS_ACCESS_ACCEPT = 2 +RADIUS_ACCESS_REJECT = 3 +RADIUS_ACCT_REQUEST = 4 +RADIUS_ACCT_RESPONSE = 5 +RADIUS_ACCT_STATUS = 6 +RADIUS_ACCESS_CHALLENGE = 11 + +# Attributes +RADIUS_USER_NAME = 1 +RADIUS_USER_PASSWORD = 2 +RADIUS_CHAP_PASSWORD = 3 +RADIUS_NAS_IP_ADDR = 4 +RADIUS_NAS_PORT = 5 +RADIUS_SERVICE_TYPE = 6 +RADIUS_FRAMED_PROTOCOL = 7 +RADIUS_FRAMED_IP_ADDR = 8 +RADIUS_FRAMED_IP_NETMASK = 9 +RADIUS_FRAMED_ROUTING = 10 +RADIUS_FILTER_ID = 11 +RADIUS_FRAMED_MTU = 12 +RADIUS_FRAMED_COMPRESSION = 13 +RADIUS_LOGIN_IP_HOST = 14 +RADIUS_LOGIN_SERVICE = 15 +RADIUS_LOGIN_TCP_PORT = 16 +# unassigned +RADIUS_REPLY_MESSAGE = 18 +RADIUS_CALLBACK_NUMBER = 19 +RADIUS_CALLBACK_ID = 20 +# unassigned +RADIUS_FRAMED_ROUTE = 22 +RADIUS_FRAMED_IPX_NETWORK = 23 +RADIUS_STATE = 24 +RADIUS_CLASS = 25 +RADIUS_VENDOR_SPECIFIC = 26 +RADIUS_SESSION_TIMEOUT = 27 +RADIUS_IDLE_TIMEOUT = 28 +RADIUS_TERMINATION_ACTION = 29 +RADIUS_CALLED_STATION_ID = 30 +RADIUS_CALLING_STATION_ID = 31 +RADIUS_NAS_ID = 32 +RADIUS_PROXY_STATE = 33 +RADIUS_LOGIN_LAT_SERVICE = 34 +RADIUS_LOGIN_LAT_NODE = 35 +RADIUS_LOGIN_LAT_GROUP = 36 +RADIUS_FRAMED_ATALK_LINK = 37 +RADIUS_FRAMED_ATALK_NETWORK = 38 +RADIUS_FRAMED_ATALK_ZONE = 39 +# 40-59 reserved for accounting +RADIUS_CHAP_CHALLENGE = 60 +RADIUS_NAS_PORT_TYPE = 61 +RADIUS_PORT_LIMIT = 62 +RADIUS_LOGIN_LAT_PORT = 63 diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/rfb.py b/scripts/external_libs/dpkt-1.8.6/dpkt/rfb.py new file mode 100644 index 00000000..f6d2a5d5 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/rfb.py @@ -0,0 +1,81 @@ +# $Id: rfb.py 47 2008-05-27 02:10:00Z jon.oberheide $ + +"""Remote Framebuffer Protocol.""" + +import dpkt + +# Remote Framebuffer Protocol +# http://www.realvnc.com/docs/rfbproto.pdf + +# Client to Server Messages +CLIENT_SET_PIXEL_FORMAT = 0 +CLIENT_SET_ENCODINGS = 2 +CLIENT_FRAMEBUFFER_UPDATE_REQUEST = 3 +CLIENT_KEY_EVENT = 4 +CLIENT_POINTER_EVENT = 5 +CLIENT_CUT_TEXT = 6 + +# Server to Client Messages +SERVER_FRAMEBUFFER_UPDATE = 0 +SERVER_SET_COLOUR_MAP_ENTRIES = 1 +SERVER_BELL = 2 +SERVER_CUT_TEXT = 3 + +class RFB(dpkt.Packet): + __hdr__ = ( + ('type', 'B', 0), + ) + +class SetPixelFormat(dpkt.Packet): + __hdr__ = ( + ('pad', '3s', ''), + ('pixel_fmt', '16s', '') + ) + +class SetEncodings(dpkt.Packet): + __hdr__ = ( + ('pad', '1s', ''), + ('num_encodings', 'H', 0) + ) + +class FramebufferUpdateRequest(dpkt.Packet): + __hdr__ = ( + ('incremental', 'B', 0), + ('x_position', 'H', 0), + ('y_position', 'H', 0), + ('width', 'H', 0), + ('height', 'H', 0) + ) + +class KeyEvent(dpkt.Packet): + __hdr__ = ( + ('down_flag', 'B', 0), + ('pad', '2s', ''), + ('key', 'I', 0) + ) + +class PointerEvent(dpkt.Packet): + __hdr__ = ( + ('button_mask', 'B', 0), + ('x_position', 'H', 0), + ('y_position', 'H', 0) + ) + +class FramebufferUpdate(dpkt.Packet): + __hdr__ = ( + ('pad', '1s', ''), + ('num_rects', 'H', 0) + ) + +class SetColourMapEntries(dpkt.Packet): + __hdr__ = ( + ('pad', '1s', ''), + ('first_colour', 'H', 0), + ('num_colours', 'H', 0) + ) + +class CutText(dpkt.Packet): + __hdr__ = ( + ('pad', '3s', ''), + ('length', 'I', 0) + ) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/rip.py b/scripts/external_libs/dpkt-1.8.6/dpkt/rip.py new file mode 100644 index 00000000..7542cb3d --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/rip.py @@ -0,0 +1,84 @@ +# $Id: rip.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Routing Information Protocol.""" + +import dpkt + +# RIP v2 - RFC 2453 +# http://tools.ietf.org/html/rfc2453 + +REQUEST = 1 +RESPONSE = 2 + +class RIP(dpkt.Packet): + __hdr__ = ( + ('cmd', 'B', REQUEST), + ('v', 'B', 2), + ('rsvd', 'H', 0) + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + l = [] + self.auth = None + while self.data: + rte = RTE(self.data[:20]) + if rte.family == 0xFFFF: + self.auth = Auth(self.data[:20]) + else: + l.append(rte) + self.data = self.data[20:] + self.data = self.rtes = l + + def __len__(self): + len = self.__hdr_len__ + if self.auth: + len += len(self.auth) + len += sum(map(len, self.rtes)) + return len + + def __str__(self): + auth = '' + if self.auth: + auth = str(self.auth) + return self.pack_hdr() + \ + auth + \ + ''.join(map(str, self.rtes)) + +class RTE(dpkt.Packet): + __hdr__ = ( + ('family', 'H', 2), + ('route_tag', 'H', 0), + ('addr', 'I', 0), + ('subnet', 'I', 0), + ('next_hop', 'I', 0), + ('metric', 'I', 1) + ) + +class Auth(dpkt.Packet): + __hdr__ = ( + ('rsvd', 'H', 0xFFFF), + ('type', 'H', 2), + ('auth', '16s', 0) + ) + +if __name__ == '__main__': + import unittest + + class RIPTestCase(unittest.TestCase): + def testPack(self): + r = RIP(self.s) + self.failUnless(self.s == str(r)) + + def testUnpack(self): + r = RIP(self.s) + self.failUnless(r.auth == None) + self.failUnless(len(r.rtes) == 2) + + rte = r.rtes[1] + self.failUnless(rte.family == 2) + self.failUnless(rte.route_tag == 0) + self.failUnless(rte.metric == 1) + + s = '\x02\x02\x00\x00\x00\x02\x00\x00\x01\x02\x03\x00\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x00\x00\xc0\xa8\x01\x08\xff\xff\xff\xfc\x00\x00\x00\x00\x00\x00\x00\x01' + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/rpc.py b/scripts/external_libs/dpkt-1.8.6/dpkt/rpc.py new file mode 100644 index 00000000..19281581 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/rpc.py @@ -0,0 +1,146 @@ +# $Id: rpc.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Remote Procedure Call.""" + +import struct +import dpkt + +# RPC.dir +CALL = 0 +REPLY = 1 + +# RPC.Auth.flavor +AUTH_NONE = AUTH_NULL = 0 +AUTH_UNIX = 1 +AUTH_SHORT = 2 +AUTH_DES = 3 + +# RPC.Reply.stat +MSG_ACCEPTED = 0 +MSG_DENIED = 1 + +# RPC.Reply.Accept.stat +SUCCESS = 0 +PROG_UNAVAIL = 1 +PROG_MISMATCH = 2 +PROC_UNAVAIL = 3 +GARBAGE_ARGS = 4 +SYSTEM_ERR = 5 + +# RPC.Reply.Reject.stat +RPC_MISMATCH = 0 +AUTH_ERROR = 1 + +class RPC(dpkt.Packet): + __hdr__ = ( + ('xid', 'I', 0), + ('dir', 'I', CALL) + ) + class Auth(dpkt.Packet): + __hdr__ = (('flavor', 'I', AUTH_NONE), ) + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + n = struct.unpack('>I', self.data[:4])[0] + self.data = self.data[4:4+n] + def __len__(self): + return 8 + len(self.data) + def __str__(self): + return self.pack_hdr() + struct.pack('>I', len(self.data)) + \ + str(self.data) + + class Call(dpkt.Packet): + __hdr__ = ( + ('rpcvers', 'I', 2), + ('prog', 'I', 0), + ('vers', 'I', 0), + ('proc', 'I', 0) + ) + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.cred = RPC.Auth(self.data) + self.verf = RPC.Auth(self.data[len(self.cred):]) + self.data = self.data[len(self.cred) + len(self.verf):] + def __len__(self): + return len(str(self)) # XXX + def __str__(self): + return dpkt.Packet.__str__(self) + \ + str(getattr(self, 'cred', RPC.Auth())) + \ + str(getattr(self, 'verf', RPC.Auth())) + \ + str(self.data) + + class Reply(dpkt.Packet): + __hdr__ = (('stat', 'I', MSG_ACCEPTED), ) + + class Accept(dpkt.Packet): + __hdr__ = (('stat', 'I', SUCCESS), ) + def unpack(self, buf): + self.verf = RPC.Auth(buf) + buf = buf[len(self.verf):] + self.stat = struct.unpack('>I', buf[:4])[0] + if self.stat == SUCCESS: + self.data = buf[4:] + elif self.stat == PROG_MISMATCH: + self.low, self.high = struct.unpack('>II', buf[4:12]) + self.data = buf[12:] + def __len__(self): + if self.stat == PROG_MISMATCH: n = 8 + else: n = 0 + return len(self.verf) + 4 + n + len(self.data) + def __str__(self): + if self.stat == PROG_MISMATCH: + return str(self.verf) + struct.pack('>III', self.stat, + self.low, self.high) + self.data + return str(self.verf) + dpkt.Packet.__str__(self) + + class Reject(dpkt.Packet): + __hdr__ = (('stat', 'I', AUTH_ERROR), ) + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + if self.stat == RPC_MISMATCH: + self.low, self.high = struct.unpack('>II', self.data[:8]) + self.data = self.data[8:] + elif self.stat == AUTH_ERROR: + self.why = struct.unpack('>I', self.data[:4])[0] + self.data = self.data[4:] + def __len__(self): + if self.stat == RPC_MISMATCH: n = 8 + elif self.stat == AUTH_ERROR: n =4 + else: n = 0 + return 4 + n + len(self.data) + def __str__(self): + if self.stat == RPC_MISMATCH: + return struct.pack('>III', self.stat, self.low, + self.high) + self.data + elif self.stat == AUTH_ERROR: + return struct.pack('>II', self.stat, self.why) + self.data + return dpkt.Packet.__str__(self) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + if self.stat == MSG_ACCEPTED: + self.data = self.accept = self.Accept(self.data) + elif self.status == MSG_DENIED: + self.data = self.reject = self.Reject(self.data) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + if self.dir == CALL: + self.data = self.call = self.Call(self.data) + elif self.dir == REPLY: + self.data = self.reply = self.Reply(self.data) + +def unpack_xdrlist(cls, buf): + l = [] + while buf: + if buf.startswith('\x00\x00\x00\x01'): + p = cls(buf[4:]) + l.append(p) + buf = p.data + elif buf.startswith('\x00\x00\x00\x00'): + break + else: + raise dpkt.UnpackError, 'invalid XDR list' + return l + +def pack_xdrlist(*args): + return '\x00\x00\x00\x01'.join(map(str, args)) + '\x00\x00\x00\x00' diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/rtp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/rtp.py new file mode 100644 index 00000000..65fd0b98 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/rtp.py @@ -0,0 +1,70 @@ +# $Id: rtp.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Real-Time Transport Protocol""" + +from dpkt import Packet + +# version 1100 0000 0000 0000 ! 0xC000 14 +# p 0010 0000 0000 0000 ! 0x2000 13 +# x 0001 0000 0000 0000 ! 0x1000 12 +# cc 0000 1111 0000 0000 ! 0x0F00 8 +# m 0000 0000 1000 0000 ! 0x0080 7 +# pt 0000 0000 0111 1111 ! 0x007F 0 +# + +_VERSION_MASK= 0xC000 +_P_MASK = 0x2000 +_X_MASK = 0x1000 +_CC_MASK = 0x0F00 +_M_MASK = 0x0080 +_PT_MASK = 0x007F +_VERSION_SHIFT=14 +_P_SHIFT = 13 +_X_SHIFT = 12 +_CC_SHIFT = 8 +_M_SHIFT = 7 +_PT_SHIFT = 0 + +VERSION = 2 + +class RTP(Packet): + __hdr__ = ( + ('_type', 'H', 0x8000), + ('seq', 'H', 0), + ('ts', 'I', 0), + ('ssrc', 'I', 0), + ) + csrc = '' + + def _get_version(self): return (self._type&_VERSION_MASK)>>_VERSION_SHIFT + def _set_version(self, ver): + self._type = (ver << _VERSION_SHIFT) | (self._type & ~_VERSION_MASK) + def _get_p(self): return (self._type & _P_MASK) >> _P_SHIFT + def _set_p(self, p): self._type = (p << _P_SHIFT) | (self._type & ~_P_MASK) + def _get_x(self): return (self._type & _X_MASK) >> _X_SHIFT + def _set_x(self, x): self._type = (x << _X_SHIFT) | (self._type & ~_X_MASK) + def _get_cc(self): return (self._type & _CC_MASK) >> _CC_SHIFT + def _set_cc(self, cc): self._type = (cc<<_CC_SHIFT)|(self._type&~_CC_MASK) + def _get_m(self): return (self._type & _M_MASK) >> _M_SHIFT + def _set_m(self, m): self._type = (m << _M_SHIFT) | (self._type & ~_M_MASK) + def _get_pt(self): return (self._type & _PT_MASK) >> _PT_SHIFT + def _set_pt(self, m): self._type = (m << _PT_SHIFT)|(self._type&~_PT_MASK) + + version = property(_get_version, _set_version) + p = property(_get_p, _set_p) + x = property(_get_x, _set_x) + cc = property(_get_cc, _set_cc) + m = property(_get_m, _set_m) + pt = property(_get_pt, _set_pt) + + def __len__(self): + return self.__hdr_len__ + len(self.csrc) + len(self.data) + + def __str__(self): + return self.pack_hdr() + self.csrc + str(self.data) + + def unpack(self, buf): + super(RTP, self).unpack(buf) + self.csrc = buf[self.__hdr_len__:self.__hdr_len__ + self.cc * 4] + self.data = buf[self.__hdr_len__ + self.cc * 4:] + diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/rx.py b/scripts/external_libs/dpkt-1.8.6/dpkt/rx.py new file mode 100644 index 00000000..5b898efc --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/rx.py @@ -0,0 +1,44 @@ +# $Id: rx.py 23 2006-11-08 15:45:33Z jonojono $ + +"""Rx Protocol.""" + +import dpkt + +# Types +DATA = 0x01 +ACK = 0x02 +BUSY = 0x03 +ABORT = 0x04 +ACKALL = 0x05 +CHALLENGE = 0x06 +RESPONSE = 0x07 +DEBUG = 0x08 + +# Flags +CLIENT_INITIATED = 0x01 +REQUEST_ACK = 0x02 +LAST_PACKET = 0x04 +MORE_PACKETS = 0x08 +SLOW_START_OK = 0x20 +JUMBO_PACKET = 0x20 + +# Security +SEC_NONE = 0x00 +SEC_BCRYPT = 0x01 +SEC_RXKAD = 0x02 +SEC_RXKAD_ENC = 0x03 + +class Rx(dpkt.Packet): + __hdr__ = ( + ('epoch', 'I', 0), + ('cid', 'I', 0), + ('call', 'I', 1), + ('seq', 'I', 0), + ('serial', 'I', 1), + ('type', 'B', 0), + ('flags', 'B', CLIENT_INITIATED), + ('status', 'B', 0), + ('security', 'B', 0), + ('sum', 'H', 0), + ('service', 'H', 0) + ) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/sccp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/sccp.py new file mode 100644 index 00000000..7a4ac084 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/sccp.py @@ -0,0 +1,196 @@ +# $Id: sccp.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Cisco Skinny Client Control Protocol.""" + +import dpkt + +KEYPAD_BUTTON = 0x00000003 +OFF_HOOK = 0x00000006 +ON_HOOK = 0x00000007 +OPEN_RECEIVE_CHANNEL_ACK= 0x00000022 +START_TONE = 0x00000082 +STOP_TONE = 0x00000083 +SET_LAMP = 0x00000086 +SET_SPEAKER_MODE = 0x00000088 +START_MEDIA_TRANSMIT = 0x0000008A +STOP_MEDIA_TRANSMIT = 0x0000008B +CALL_INFO = 0x0000008F +DEFINE_TIME_DATE = 0x00000094 +DISPLAY_TEXT = 0x00000099 +OPEN_RECEIVE_CHANNEL = 0x00000105 +CLOSE_RECEIVE_CHANNEL = 0x00000106 +SELECT_SOFTKEYS = 0x00000110 +CALL_STATE = 0x00000111 +DISPLAY_PROMPT_STATUS = 0x00000112 +CLEAR_PROMPT_STATUS = 0x00000113 +ACTIVATE_CALL_PLANE = 0x00000116 + +class ActivateCallPlane(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('line_instance', 'I', 0), + ) + +class CallInfo(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('calling_party_name', '40s', ''), + ('calling_party', '24s', ''), + ('called_party_name', '40s', ''), + ('called_party', '24s', ''), + ('line_instance', 'I', 0), + ('call_id', 'I', 0), + ('call_type', 'I', 0), + ('orig_called_party_name', '40s', ''), + ('orig_called_party', '24s', '') + ) + +class CallState(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('call_state', 'I', 12), # 12: Proceed, 15: Connected + ('line_instance', 'I', 1), + ('call_id', 'I', 0) + ) + +class ClearPromptStatus(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('line_instance', 'I', 1), + ('call_id', 'I', 0) + ) + +class CloseReceiveChannel(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('conference_id', 'I', 0), + ('passthruparty_id', 'I', 0), + ) + +class DisplayPromptStatus(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('msg_timeout', 'I', 0), + ('display_msg', '32s', ''), + ('line_instance', 'I', 1), + ('call_id', 'I', 0) + ) + +class DisplayText(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('display_msg', '36s', ''), + ) + +class KeypadButton(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('button', 'I', 0), + ) + +class OpenReceiveChannel(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('conference_id', 'I', 0), + ('passthruparty_id', 'I', 0), + ('ms_packet', 'I', 0), + ('payload_capability', 'I', 4), # 4: G.711 u-law 64k + ('echo_cancel_type', 'I', 4), + ('g723_bitrate', 'I', 0), + ) + +class OpenReceiveChannelAck(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('channel_status', 'I', 0), + ('ip', '4s', ''), + ('port', 'I', 0), + ('passthruparty_id', 'I', 0), + ) + +class SelectStartKeys(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('line_id', 'I', 1), + ('call_id', 'I', 0), + ('softkey_set', 'I', 8), + ('softkey_map', 'I', 0xffffffffL) + ) + +class SetLamp(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('stimulus', 'I', 9), # 9: Line + ('stimulus_instance', 'I', 1), + ('lamp_mode', 'I', 1), + ) + +class SetSpeakerMode(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('speaker', 'I', 2), # 2: SpeakerOff + ) + +class StartMediaTransmission(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('conference_id', 'I', 0), + ('passthruparty_id', 'I', 0), + ('remote_ip', '4s', ''), + ('remote_port', 'I', 0), + ('ms_packet', 'I', 0), + ('payload_capability', 'I', 4), # 4: G.711 u-law 64k + ('precedence', 'I', 0), + ('silence_suppression', 'I', 0), + ('max_frames_per_pkt', 'I', 1), + ('g723_bitrate', 'I', 0), + ) + +class StartTone(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('tone', 'I', 0x24), # 0x24: AlertingTone + ) + +class StopMediaTransmission(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('conference_id', 'I', 0), + ('passthruparty_id', 'I', 0), + ) + +class SCCP(dpkt.Packet): + __byte_order__ = '<' + __hdr__ = ( + ('len', 'I', 0), + ('rsvd', 'I', 0), + ('msgid', 'I', 0), + ('msg', '0s', ''), + ) + _msgsw = { + KEYPAD_BUTTON:KeypadButton, + OPEN_RECEIVE_CHANNEL_ACK:OpenReceiveChannelAck, + START_TONE:StartTone, + SET_LAMP:SetLamp, + START_MEDIA_TRANSMIT:StartMediaTransmission, + STOP_MEDIA_TRANSMIT:StopMediaTransmission, + CALL_INFO:CallInfo, + DISPLAY_TEXT:DisplayText, + OPEN_RECEIVE_CHANNEL:OpenReceiveChannel, + CLOSE_RECEIVE_CHANNEL:CloseReceiveChannel, + CALL_STATE:CallState, + DISPLAY_PROMPT_STATUS:DisplayPromptStatus, + CLEAR_PROMPT_STATUS:ClearPromptStatus, + ACTIVATE_CALL_PLANE:ActivateCallPlane, + } + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + n = self.len - 4 + if n > len(self.data): + raise dpkt.NeedData('not enough data') + self.msg, self.data = self.data[:n], self.data[n:] + try: + p = self._msgsw[self.msgid](self.msg) + setattr(self, p.__class__.__name__.lower(), p) + except (KeyError, dpkt.UnpackError): + pass diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/sctp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/sctp.py new file mode 100644 index 00000000..31b13e69 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/sctp.py @@ -0,0 +1,90 @@ +# $Id: sctp.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Stream Control Transmission Protocol.""" + +import dpkt, crc32c + +# Stream Control Transmission Protocol +# http://tools.ietf.org/html/rfc2960 + +# Chunk Types +DATA = 0 +INIT = 1 +INIT_ACK = 2 +SACK = 3 +HEARTBEAT = 4 +HEARTBEAT_ACK = 5 +ABORT = 6 +SHUTDOWN = 7 +SHUTDOWN_ACK = 8 +ERROR = 9 +COOKIE_ECHO = 10 +COOKIE_ACK = 11 +ECNE = 12 +CWR = 13 +SHUTDOWN_COMPLETE = 14 + +class SCTP(dpkt.Packet): + __hdr__ = ( + ('sport', 'H', 0), + ('dport', 'H', 0), + ('vtag', 'I', 0), + ('sum', 'I', 0) + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + l = [] + while self.data: + chunk = Chunk(self.data) + l.append(chunk) + self.data = self.data[len(chunk):] + self.data = self.chunks = l + + def __len__(self): + return self.__hdr_len__ + \ + sum(map(len, self.data)) + + def __str__(self): + l = [ str(x) for x in self.data ] + if self.sum == 0: + s = crc32c.add(0xffffffffL, self.pack_hdr()) + for x in l: + s = crc32c.add(s, x) + self.sum = crc32c.done(s) + return self.pack_hdr() + ''.join(l) + +class Chunk(dpkt.Packet): + __hdr__ = ( + ('type', 'B', INIT), + ('flags', 'B', 0), + ('len', 'H', 0) + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.data[:self.len - self.__hdr_len__] + +if __name__ == '__main__': + import unittest + + class SCTPTestCase(unittest.TestCase): + def testPack(self): + sctp = SCTP(self.s) + self.failUnless(self.s == str(sctp)) + sctp.sum = 0 + self.failUnless(self.s == str(sctp)) + + def testUnpack(self): + sctp = SCTP(self.s) + self.failUnless(sctp.sport == 32836) + self.failUnless(sctp.dport == 80) + self.failUnless(len(sctp.chunks) == 1) + self.failUnless(len(sctp) == 72) + + chunk = sctp.chunks[0] + self.failUnless(chunk.type == INIT) + self.failUnless(chunk.len == 60) + + s = '\x80\x44\x00\x50\x00\x00\x00\x00\x30\xba\xef\x54\x01\x00\x00\x3c\x3b\xb9\x9c\x46\x00\x01\xa0\x00\x00\x0a\xff\xff\x2b\x2d\x7e\xb2\x00\x05\x00\x08\x9b\xe6\x18\x9b\x00\x05\x00\x08\x9b\xe6\x18\x9c\x00\x0c\x00\x06\x00\x05\x00\x00\x80\x00\x00\x04\xc0\x00\x00\x04\xc0\x06\x00\x08\x00\x00\x00\x00' + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/sip.py b/scripts/external_libs/dpkt-1.8.6/dpkt/sip.py new file mode 100644 index 00000000..398eab8a --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/sip.py @@ -0,0 +1,32 @@ +# $Id: sip.py 48 2008-05-27 17:31:15Z yardley $ + +"""Session Initiation Protocol.""" + +import http + +class Request(http.Request): + """SIP request.""" + __hdr_defaults__ = { + 'method':'INVITE', + 'uri':'sip:user@example.com', + 'version':'2.0', + 'headers':{ 'To':'', 'From':'', 'Call-ID':'', 'CSeq':'', 'Contact':'' } + } + __methods = dict.fromkeys(( + 'ACK', 'BYE', 'CANCEL', 'INFO', 'INVITE', 'MESSAGE', 'NOTIFY', + 'OPTIONS', 'PRACK', 'PUBLISH', 'REFER', 'REGISTER', 'SUBSCRIBE', + 'UPDATE' + )) + __proto = 'SIP' + +class Response(http.Response): + """SIP response.""" + __hdr_defaults__ = { + 'version':'2.0', + 'status':'200', + 'reason':'OK', + 'headers':{ 'To':'', 'From':'', 'Call-ID':'', 'CSeq':'', 'Contact':'' } + } + __proto = 'SIP' + + diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/sll.py b/scripts/external_libs/dpkt-1.8.6/dpkt/sll.py new file mode 100644 index 00000000..dbe866f8 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/sll.py @@ -0,0 +1,23 @@ +# $Id: sll.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Linux libpcap "cooked" capture encapsulation.""" + +import arp, dpkt, ethernet + +class SLL(dpkt.Packet): + __hdr__ = ( + ('type', 'H', 0), # 0: to us, 1: bcast, 2: mcast, 3: other, 4: from us + ('hrd', 'H', arp.ARP_HRD_ETH), + ('hlen', 'H', 6), # hardware address length + ('hdr', '8s', ''), # first 8 bytes of link-layer header + ('ethtype', 'H', ethernet.ETH_TYPE_IP), + ) + _typesw = ethernet.Ethernet._typesw + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + try: + self.data = self._typesw[self.ethtype](self.data) + setattr(self, self.data.__class__.__name__.lower(), self.data) + except (KeyError, dpkt.UnpackError): + pass diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/smb.py b/scripts/external_libs/dpkt-1.8.6/dpkt/smb.py new file mode 100644 index 00000000..1964a535 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/smb.py @@ -0,0 +1,19 @@ +# $Id: smb.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Server Message Block.""" + +import dpkt + +class SMB(dpkt.Packet): + __hdr__ = [ + ('proto', '4s', ''), + ('cmd', 'B', 0), + ('err', 'I', 0), + ('flags1', 'B', 0), + ('flags2', 'B', 0), + ('pad', '6s', ''), + ('tid', 'H', 0), + ('pid', 'H', 0), + ('uid', 'H', 0), + ('mid', 'H', 0) + ] diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/snoop.py b/scripts/external_libs/dpkt-1.8.6/dpkt/snoop.py new file mode 100644 index 00000000..3374feb2 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/snoop.py @@ -0,0 +1,118 @@ +# $Id$ + +"""Snoop file format.""" + +import sys, time +import dpkt + +# RFC 1761 + +SNOOP_MAGIC = 0x736E6F6F70000000L + +SNOOP_VERSION = 2 + +SDL_8023 = 0 +SDL_8024 = 1 +SDL_8025 = 2 +SDL_8026 = 3 +SDL_ETHER = 4 +SDL_HDLC = 5 +SDL_CHSYNC = 6 +SDL_IBMCC = 7 +SDL_FDDI = 8 +SDL_OTHER = 9 + + +dltoff = { SDL_ETHER:14 } + +class PktHdr(dpkt.Packet): + """snoop packet header.""" + __byte_order__ = '!' + __hdr__ = ( + ('orig_len', 'I', 0), + ('incl_len', 'I', 0), + ('rec_len', 'I', 0), + ('cum_drops', 'I', 0), + ('ts_sec', 'I', 0), + ('ts_usec', 'I', 0), + ) + +class FileHdr(dpkt.Packet): + """snoop file header.""" + __byte_order__ = '!' + __hdr__ = ( + ('magic', 'Q', SNOOP_MAGIC), + ('v', 'I', SNOOP_VERSION), + ('linktype', 'I', SDL_ETHER), + ) + +class Writer(object): + """Simple snoop dumpfile writer.""" + def __init__(self, fileobj, linktype=SDL_ETHER): + self.__f = fileobj + fh = FileHdr(linktype=linktype) + self.__f.write(str(fh)) + + def writepkt(self, pkt, ts=None): + if ts is None: + ts = time.time() + s = str(pkt) + n = len(s) + pad_len = 4 - n % 4 if n % 4 else 0 + ph = PktHdr(orig_len=n,incl_len=n, + rec_len=PktHdr.__hdr_len__+n+pad_len, + ts_sec=int(ts), + ts_usec=int((int(ts) - float(ts)) * 1000000.0)) + self.__f.write(str(ph)) + self.__f.write(s + '\0' * pad_len) + + def close(self): + self.__f.close() + +class Reader(object): + """Simple pypcap-compatible snoop file reader.""" + + def __init__(self, fileobj): + self.name = fileobj.name + self.fd = fileobj.fileno() + self.__f = fileobj + buf = self.__f.read(FileHdr.__hdr_len__) + self.__fh = FileHdr(buf) + self.__ph = PktHdr + if self.__fh.magic != SNOOP_MAGIC: + raise ValueError, 'invalid snoop header' + self.dloff = dltoff[self.__fh.linktype] + self.filter = '' + + def fileno(self): + return self.fd + + def datalink(self): + return self.__fh.linktype + + def setfilter(self, value, optimize=1): + return NotImplementedError + + def readpkts(self): + return list(self) + + def dispatch(self, cnt, callback, *args): + if cnt > 0: + for i in range(cnt): + ts, pkt = self.next() + callback(ts, pkt, *args) + else: + for ts, pkt in self: + callback(ts, pkt, *args) + + def loop(self, callback, *args): + self.dispatch(0, callback, *args) + + def __iter__(self): + self.__f.seek(FileHdr.__hdr_len__) + while 1: + buf = self.__f.read(PktHdr.__hdr_len__) + if not buf: break + hdr = self.__ph(buf) + buf = self.__f.read(hdr.rec_len - PktHdr.__hdr_len__) + yield (hdr.ts_sec + (hdr.ts_usec / 1000000.0), buf[:hdr.incl_len]) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/ssl.py b/scripts/external_libs/dpkt-1.8.6/dpkt/ssl.py new file mode 100644 index 00000000..d741a99e --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/ssl.py @@ -0,0 +1,560 @@ +# $Id: ssl.py 90 2014-04-02 22:06:23Z andrewflnr@gmail.com $ +# Portion Copyright 2012 Google Inc. All rights reserved. + +"""Secure Sockets Layer / Transport Layer Security.""" + +import dpkt +import ssl_ciphersuites +import struct +import binascii +import traceback +import datetime + +# +# Note from April 2011: cde...@gmail.com added code that parses SSL3/TLS messages more in depth. +# +# Jul 2012: afleenor@google.com modified and extended SSL support further. +# + + +class SSL2(dpkt.Packet): + __hdr__ = ( + ('len', 'H', 0), + ('msg', 's', ''), + ('pad', 's', ''), + ) + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + if self.len & 0x8000: + n = self.len = self.len & 0x7FFF + self.msg, self.data = self.data[:n], self.data[n:] + else: + n = self.len = self.len & 0x3FFF + padlen = ord(self.data[0]) + self.msg = self.data[1:1+n] + self.pad = self.data[1+n:1+n+padlen] + self.data = self.data[1+n+padlen:] + + +# SSLv3/TLS versions +SSL3_V = 0x0300 +TLS1_V = 0x0301 +TLS11_V = 0x0302 +TLS12_V = 0x0303 + +ssl3_versions_str = { + SSL3_V: 'SSL3', + TLS1_V: 'TLS 1.0', + TLS11_V: 'TLS 1.1', + TLS12_V: 'TLS 1.2' +} + +SSL3_VERSION_BYTES = set(('\x03\x00', '\x03\x01', '\x03\x02', '\x03\x03')) + + +# Alert levels +SSL3_AD_WARNING = 1 +SSL3_AD_FATAL = 2 +alert_level_str = { + SSL3_AD_WARNING: 'SSL3_AD_WARNING', + SSL3_AD_FATAL: 'SSL3_AD_FATAL' +} + +# SSL3 alert descriptions +SSL3_AD_CLOSE_NOTIFY = 0 +SSL3_AD_UNEXPECTED_MESSAGE = 10 # fatal +SSL3_AD_BAD_RECORD_MAC = 20 # fatal +SSL3_AD_DECOMPRESSION_FAILURE = 30 # fatal +SSL3_AD_HANDSHAKE_FAILURE = 40 # fatal +SSL3_AD_NO_CERTIFICATE = 41 +SSL3_AD_BAD_CERTIFICATE = 42 +SSL3_AD_UNSUPPORTED_CERTIFICATE = 43 +SSL3_AD_CERTIFICATE_REVOKED = 44 +SSL3_AD_CERTIFICATE_EXPIRED = 45 +SSL3_AD_CERTIFICATE_UNKNOWN = 46 +SSL3_AD_ILLEGAL_PARAMETER = 47 # fatal + +# TLS1 alert descriptions +TLS1_AD_DECRYPTION_FAILED = 21 +TLS1_AD_RECORD_OVERFLOW = 22 +TLS1_AD_UNKNOWN_CA = 48 # fatal +TLS1_AD_ACCESS_DENIED = 49 # fatal +TLS1_AD_DECODE_ERROR = 50 # fatal +TLS1_AD_DECRYPT_ERROR = 51 +TLS1_AD_EXPORT_RESTRICTION = 60 # fatal +TLS1_AD_PROTOCOL_VERSION = 70 # fatal +TLS1_AD_INSUFFICIENT_SECURITY = 71 # fatal +TLS1_AD_INTERNAL_ERROR = 80 # fatal +TLS1_AD_USER_CANCELLED = 90 +TLS1_AD_NO_RENEGOTIATION = 100 +#/* codes 110-114 are from RFC3546 */ +TLS1_AD_UNSUPPORTED_EXTENSION = 110 +TLS1_AD_CERTIFICATE_UNOBTAINABLE = 111 +TLS1_AD_UNRECOGNIZED_NAME = 112 +TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE = 113 +TLS1_AD_BAD_CERTIFICATE_HASH_VALUE = 114 +TLS1_AD_UNKNOWN_PSK_IDENTITY = 115 # fatal + + +# Mapping alert types to strings +alert_description_str = { + SSL3_AD_CLOSE_NOTIFY: 'SSL3_AD_CLOSE_NOTIFY', + SSL3_AD_UNEXPECTED_MESSAGE: 'SSL3_AD_UNEXPECTED_MESSAGE', + SSL3_AD_BAD_RECORD_MAC: 'SSL3_AD_BAD_RECORD_MAC', + SSL3_AD_DECOMPRESSION_FAILURE: 'SSL3_AD_DECOMPRESSION_FAILURE', + SSL3_AD_HANDSHAKE_FAILURE: 'SSL3_AD_HANDSHAKE_FAILURE', + SSL3_AD_NO_CERTIFICATE: 'SSL3_AD_NO_CERTIFICATE', + SSL3_AD_BAD_CERTIFICATE: 'SSL3_AD_BAD_CERTIFICATE', + SSL3_AD_UNSUPPORTED_CERTIFICATE: 'SSL3_AD_UNSUPPORTED_CERTIFICATE', + SSL3_AD_CERTIFICATE_REVOKED: 'SSL3_AD_CERTIFICATE_REVOKED', + SSL3_AD_CERTIFICATE_EXPIRED: 'SSL3_AD_CERTIFICATE_EXPIRED', + SSL3_AD_CERTIFICATE_UNKNOWN: 'SSL3_AD_CERTIFICATE_UNKNOWN', + SSL3_AD_ILLEGAL_PARAMETER: 'SSL3_AD_ILLEGAL_PARAMETER', + TLS1_AD_DECRYPTION_FAILED: 'TLS1_AD_DECRYPTION_FAILED', + TLS1_AD_RECORD_OVERFLOW: 'TLS1_AD_RECORD_OVERFLOW', + TLS1_AD_UNKNOWN_CA: 'TLS1_AD_UNKNOWN_CA', + TLS1_AD_ACCESS_DENIED: 'TLS1_AD_ACCESS_DENIED', + TLS1_AD_DECODE_ERROR: 'TLS1_AD_DECODE_ERROR', + TLS1_AD_DECRYPT_ERROR: 'TLS1_AD_DECRYPT_ERROR', + TLS1_AD_EXPORT_RESTRICTION: 'TLS1_AD_EXPORT_RESTRICTION', + TLS1_AD_PROTOCOL_VERSION: 'TLS1_AD_PROTOCOL_VERSION', + TLS1_AD_INSUFFICIENT_SECURITY: 'TLS1_AD_INSUFFICIENT_SECURITY', + TLS1_AD_INTERNAL_ERROR: 'TLS1_AD_INTERNAL_ERROR', + TLS1_AD_USER_CANCELLED: 'TLS1_AD_USER_CANCELLED', + TLS1_AD_NO_RENEGOTIATION: 'TLS1_AD_NO_RENEGOTIATION', + TLS1_AD_UNSUPPORTED_EXTENSION: 'TLS1_AD_UNSUPPORTED_EXTENSION', + TLS1_AD_CERTIFICATE_UNOBTAINABLE: 'TLS1_AD_CERTIFICATE_UNOBTAINABLE', + TLS1_AD_UNRECOGNIZED_NAME: 'TLS1_AD_UNRECOGNIZED_NAME', + TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: 'TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE', + TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: 'TLS1_AD_BAD_CERTIFICATE_HASH_VALUE', + TLS1_AD_UNKNOWN_PSK_IDENTITY: 'TLS1_AD_UNKNOWN_PSK_IDENTITY' +} + + +# struct format strings for parsing buffer lengths +# don't forget, you have to pad a 3-byte value with \x00 +_SIZE_FORMATS = ['!B', '!H', '!I', '!I'] + +def parse_variable_array(buf, lenbytes): + """ + Parse an array described using the 'Type name<x..y>' syntax from the spec + + Read a length at the start of buf, and returns that many bytes + after, in a tuple with the TOTAL bytes consumed (including the size). This + does not check that the array is the right length for any given datatype. + """ + # first have to figure out how to parse length + assert lenbytes <= 4 # pretty sure 4 is impossible, too + size_format = _SIZE_FORMATS[lenbytes - 1] + padding = '\x00' if lenbytes == 3 else '' + # read off the length + size = struct.unpack(size_format, padding + buf[:lenbytes])[0] + # read the actual data + data = buf[lenbytes:lenbytes + size] + # if len(data) != size: insufficient data + return data, size + lenbytes + + +class SSL3Exception(Exception): + pass + + +class TLSRecord(dpkt.Packet): + """ + SSLv3 or TLSv1+ packet. + + In addition to the fields specified in the header, there are + compressed and decrypted fields, indicating whether, in the language + of the spec, this is a TLSPlaintext, TLSCompressed, or + TLSCiphertext. The application will have to figure out when it's + appropriate to change these values. + """ + + __hdr__ = ( + ('type', 'B', 0), + ('version', 'H', 0), + ('length', 'H', 0), + ) + + def __init__(self, *args, **kwargs): + # assume plaintext unless specified otherwise in arguments + self.compressed = kwargs.pop('compressed', False) + self.encrypted = kwargs.pop('encrypted', False) + # parent constructor + dpkt.Packet.__init__(self, *args, **kwargs) + # make sure length and data are consistent + self.length = len(self.data) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + header_length = self.__hdr_len__ + self.data = buf[header_length:header_length+self.length] + # make sure buffer was long enough + if len(self.data) != self.length: + raise dpkt.NeedData('TLSRecord data was too short.') + # assume compressed and encrypted when it's been parsed from + # raw data + self.compressed = True + self.encrypted = True + + +class TLSChangeCipherSpec(dpkt.Packet): + """ + ChangeCipherSpec message is just a single byte with value 1 + """ + __hdr__ = (('type', 'B', 1),) + + +class TLSAppData(str): + """ + As far as TLSRecord is concerned, AppData is just an opaque blob. + """ + pass + + +class TLSAlert(dpkt.Packet): + + __hdr__ = ( + ('level', 'B', 1), + ('description', 'B', 0), + ) + + +class TLSHelloRequest(dpkt.Packet): + __hdr__ = tuple() + + +class TLSClientHello(dpkt.Packet): + __hdr__ = ( + ('version', 'H', 0x0301), + ('random', '32s', '\x00'*32), + ) # the rest is variable-length and has to be done manually + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + # now session, cipher suites, extensions are in self.data + self.session_id, pointer = parse_variable_array(self.data, 1) +# print 'pointer',pointer + # handle ciphersuites + ciphersuites, parsed = parse_variable_array(self.data[pointer:], 2) + pointer += parsed + self.num_ciphersuites = len(ciphersuites) / 2 + # check len(ciphersuites) % 2 == 0 ? + # compression methods + compression_methods, parsed = parse_variable_array( + self.data[pointer:], 1) + pointer += parsed + self.num_compression_methods = parsed - 1 + self.compression_methods = map(ord, compression_methods) + # extensions + + +class TLSServerHello(dpkt.Packet): + __hdr__ = ( + ('version', 'H', '0x0301'), + ('random', '32s', '\x00'*32), + ) # session is variable, forcing rest to be manual + + def unpack(self, buf): + try: + dpkt.Packet.unpack(self, buf) + self.session_id, pointer = parse_variable_array(self.data, 1) + # single cipher suite + self.cipher_suite = struct.unpack('!H', self.data[pointer:pointer+2])[0] + pointer += 2 + # single compression method + self.compression = struct.unpack('!B', self.data[pointer:pointer+1])[0] + pointer += 1 + # ignore extensions for now + except struct.error: + # probably data too short + raise dpkt.NeedData + + +class TLSUnknownHandshake(dpkt.Packet): + __hdr__ = tuple() + +TLSCertificate = TLSUnknownHandshake +TLSServerKeyExchange = TLSUnknownHandshake +TLSCertificateRequest = TLSUnknownHandshake +TLSServerHelloDone = TLSUnknownHandshake +TLSCertificateVerify = TLSUnknownHandshake +TLSClientKeyExchange = TLSUnknownHandshake +TLSFinished = TLSUnknownHandshake + + +# mapping of handshake type ids to their names +# and the classes that implement them +HANDSHAKE_TYPES = { + 0: ('HelloRequest', TLSHelloRequest), + 1: ('ClientHello', TLSClientHello), + 2: ('ServerHello', TLSServerHello), + 11: ('Certificate', TLSCertificate), + 12: ('ServerKeyExchange', TLSServerKeyExchange), + 13: ('CertificateRequest', TLSCertificateRequest), + 14: ('ServerHelloDone', TLSServerHelloDone), + 15: ('CertificateVerify', TLSCertificateVerify), + 16: ('ClientKeyExchange', TLSClientKeyExchange), + 20: ('Finished', TLSFinished), +} + + +class TLSHandshake(dpkt.Packet): + ''' + A TLS Handshake message + + This goes for all messages encapsulated in the Record layer, but especially + important for handshakes and app data: A message may be spread across a + number of TLSRecords, in addition to the possibility of there being more + than one in a given Record. You have to put together the contents of + TLSRecord's yourself. + ''' + + # struct.unpack can't handle the 3-byte int, so we parse it as bytes + # (and store it as bytes so dpkt doesn't get confused), and turn it into + # an int in a user-facing property + __hdr__ = ( + ('type', 'B', 0), + ('length_bytes', '3s', 0), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + # Wait, might there be more than one message of self.type? + embedded_type = HANDSHAKE_TYPES.get(self.type, None) + if embedded_type is None: + raise SSL3Exception('Unknown or invalid handshake type %d' % + self.type) + # only take the right number of bytes + self.data = self.data[:self.length] + if len(self.data) != self.length: + raise dpkt.NeedData + # get class out of embedded_type tuple + self.data = embedded_type[1](self.data) + + @property + def length(self): + return struct.unpack('!I', '\x00' + self.length_bytes)[0] + + +RECORD_TYPES = { + 20: TLSChangeCipherSpec, + 21: TLSAlert, + 22: TLSHandshake, + 23: TLSAppData, +} + + +class SSLFactory(object): + def __new__(cls, buf): + v = buf[1:3] + if v in [ '\x03\x00', '\x03\x01', '\x03\x02' ]: + return SSL3(buf) + # SSL2 has no characteristic header or magic bytes, so we just assume + # that the msg is an SSL2 msg if it is not detected as SSL3+ + return SSL2(buf) + + +def TLSMultiFactory(buf): + ''' + Attempt to parse one or more TLSRecord's out of buf + + Args: + buf: string containing SSL/TLS messages. May have an incomplete record + on the end + + Returns: + [TLSRecord] + int, total bytes consumed, != len(buf) if an incomplete record was left at + the end. + + Raises SSL3Exception. + ''' + i, n = 0, len(buf) + msgs = [] + while i < n: + v = buf[i+1:i+3] + if v in SSL3_VERSION_BYTES: + try: + msg = TLSRecord(buf[i:]) + msgs.append(msg) + except dpkt.NeedData: + break + else: + raise SSL3Exception('Bad TLS version in buf: %r' % buf[i:i+5]) + i += len(msg) + return msgs, i + + +import unittest + + +_hexdecode = binascii.a2b_hex + + +class TLSRecordTest(unittest.TestCase): + """ + Test basic TLSRecord functionality + + For this test, the contents of the record doesn't matter, since we're not + parsing the next layer. + """ + def setUp(self): + # add some extra data, to make sure length is parsed correctly + self.p = TLSRecord('\x17\x03\x01\x00\x08abcdefghzzzzzzzzzzz') + def testContentType(self): + self.assertEqual(self.p.type, 23) + def testVersion(self): + self.assertEqual(self.p.version, 0x0301) + def testLength(self): + self.assertEqual(self.p.length, 8) + def testData(self): + self.assertEqual(self.p.data, 'abcdefgh') + def testInitialFlags(self): + self.assertTrue(self.p.compressed) + self.assertTrue(self.p.encrypted) + def testRepack(self): + p2 = TLSRecord(type=23, version=0x0301, data='abcdefgh') + self.assertEqual(p2.type, 23) + self.assertEqual(p2.version, 0x0301) + self.assertEqual(p2.length, 8) + self.assertEqual(p2.data, 'abcdefgh') + self.assertEqual(p2.pack(), self.p.pack()) + def testTotalLength(self): + # that len(p) includes header + self.assertEqual(len(self.p), 13) + def testRaisesNeedDataWhenBufIsShort(self): + self.assertRaises( + dpkt.NeedData, + TLSRecord, + '\x16\x03\x01\x00\x10abc') + + +class TLSChangeCipherSpecTest(unittest.TestCase): + "It's just a byte. This will be quick, I promise" + def setUp(self): + self.p = TLSChangeCipherSpec('\x01') + def testParses(self): + self.assertEqual(self.p.type, 1) + def testTotalLength(self): + self.assertEqual(len(self.p), 1) + + +class TLSAppDataTest(unittest.TestCase): + "AppData is basically just a string" + def testValue(self): + d = TLSAppData('abcdefgh') + self.assertEqual(d, 'abcdefgh') + + +class TLSHandshakeTest(unittest.TestCase): + def setUp(self): + self.h = TLSHandshake('\x00\x00\x00\x01\xff') + def testCreatedInsideMessage(self): + self.assertTrue(isinstance(self.h.data, TLSHelloRequest)) + def testLength(self): + self.assertEqual(self.h.length, 0x01) + def testRaisesNeedData(self): + self.assertRaises(dpkt.NeedData, TLSHandshake, '\x00\x00\x01\x01') + + +class ClientHelloTest(unittest.TestCase): + 'This data is extracted from and verified by Wireshark' + + def setUp(self): + self.data = _hexdecode( + "01000199" # handshake header + "0301" # version + "5008220ce5e0e78b6891afe204498c9363feffbe03235a2d9e05b7d990eb708d" # rand + "2009bc0192e008e6fa8fe47998fca91311ba30ddde14a9587dc674b11c3d3e5ed1" # session id + # cipher suites + "005400ffc00ac0140088008700390038c00fc00500840035c007c009c011c0130045004400330032c00cc00ec002c0040096004100050004002fc008c01200160013c00dc003feff000ac006c010c00bc00100020001" + "0100" # compresssion methods + # extensions + "00fc0000000e000c0000096c6f63616c686f7374000a00080006001700180019000b00020100002300d0a50b2e9f618a9ea9bf493ef49b421835cd2f6b05bbe1179d8edf70d58c33d656e8696d36d7e7e0b9d3ecc0e4de339552fa06c64c0fcb550a334bc43944e2739ca342d15a9ebbe981ac87a0d38160507d47af09bdc16c5f0ee4cdceea551539382333226048a026d3a90a0535f4a64236467db8fee22b041af986ad0f253bc369137cd8d8cd061925461d7f4d7895ca9a4181ab554dad50360ac31860e971483877c9335ac1300c5e78f3e56f3b8e0fc16358fcaceefd5c8d8aaae7b35be116f8832856ca61144fcdd95e071b94d0cf7233740000" + "FFFFFFFFFFFFFFFF") # random garbage + self.p = TLSHandshake(self.data) + + def testClientHelloConstructed(self): + 'Make sure the correct class was constructed' + #print self.p + self.assertTrue(isinstance(self.p.data, TLSClientHello)) + +# def testClientDateCorrect(self): +# self.assertEqual(self.p.random_unixtime, 1342710284) + + def testClientRandomCorrect(self): + self.assertEqual(self.p.data.random, + _hexdecode('5008220ce5e0e78b6891afe204498c9363feffbe03235a2d9e05b7d990eb708d')) + + def testCipherSuiteLength(self): + # we won't bother testing the identity of each cipher suite in the list. + self.assertEqual(self.p.data.num_ciphersuites, 42) + #self.assertEqual(len(self.p.ciphersuites), 42) + + def testSessionId(self): + self.assertEqual(self.p.data.session_id, + _hexdecode('09bc0192e008e6fa8fe47998fca91311ba30ddde14a9587dc674b11c3d3e5ed1')) + + def testCompressionMethods(self): + self.assertEqual(self.p.data.num_compression_methods, 1) + + def testTotalLength(self): + self.assertEqual(len(self.p), 413) + + +class ServerHelloTest(unittest.TestCase): + 'Again, from Wireshark' + + def setUp(self): + self.data = _hexdecode('0200004d03015008220c8ec43c5462315a7c99f5d5b6bff009ad285b51dc18485f352e9fdecd2009bc0192e008e6fa8fe47998fca91311ba30ddde14a9587dc674b11c3d3e5ed10002000005ff01000100') + self.p = TLSHandshake(self.data) + + def testConstructed(self): + self.assertTrue(isinstance(self.p.data, TLSServerHello)) + +# def testDateCorrect(self): +# self.assertEqual(self.p.random_unixtime, 1342710284) + + def testRandomCorrect(self): + self.assertEqual(self.p.data.random, + _hexdecode('5008220c8ec43c5462315a7c99f5d5b6bff009ad285b51dc18485f352e9fdecd')) + + def testCipherSuite(self): + self.assertEqual( + ssl_ciphersuites.BY_CODE[self.p.data.cipher_suite].name, + 'TLS_RSA_WITH_NULL_SHA') + + def testTotalLength(self): + self.assertEqual(len(self.p), 81) + + +class TLSMultiFactoryTest(unittest.TestCase): + "Made up test data" + + def setUp(self): + self.data = _hexdecode('1703010010' # header 1 + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' # data 1 + '1703010010' # header 2 + 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' # data 2 + '1703010010' # header 3 + 'CCCCCCCC') # data 3 (incomplete) + self.msgs, self.bytes_parsed = TLSMultiFactory(self.data) + + def testNumMessages(self): + # only complete messages should be parsed, incomplete ones left + # in buffer + self.assertEqual(len(self.msgs), 2) + + def testBytesParsed(self): + self.assertEqual(self.bytes_parsed, (5 + 16) * 2) + + def testFirstMsgData(self): + self.assertEqual(self.msgs[0].data, _hexdecode('AA' * 16)) + + def testSecondMsgData(self): + self.assertEqual(self.msgs[1].data, _hexdecode('BB' * 16)) + + +if __name__ == '__main__': + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/ssl_ciphersuites.py b/scripts/external_libs/dpkt-1.8.6/dpkt/ssl_ciphersuites.py new file mode 100644 index 00000000..49148a34 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/ssl_ciphersuites.py @@ -0,0 +1,76 @@ +# Copyright 2012 Google Inc. All rights reserved. + +""" +Nicely formatted cipher suite definitions for TLS + +A list of cipher suites in the form of CipherSuite objects. +These are supposed to be immutable; don't mess with them. +""" + + +class CipherSuite(object): + """ + Encapsulates a cipher suite. + + Members/args: + * code: two-byte ID code, as int + * name: as in 'TLS_RSA_WITH_RC4_40_MD5' + * kx: key exchange algorithm, string + * auth: authentication algorithm, string + * encoding: encoding algorithm + * mac: message authentication code algorithm + """ + + def __init__(self, code, name, kx, auth, encoding, mac): + self.code = code + self.name = name + self.kx = kx + self.auth = auth + self.encoding = encoding + self.mac = mac + + def __repr__(self): + return 'CipherSuite(%s)' % self.name + + MAC_SIZES = { + 'MD5': 16, + 'SHA': 20, + 'SHA256': 32, # I guess + } + + BLOCK_SIZES = { + 'AES_256_CBC': 16, + } + + @property + def mac_size(self): + """In bytes. Default to 0.""" + return self.MAC_SIZES.get(self.mac, 0) + + @property + def block_size(self): + """In bytes. Default to 1.""" + return self.BLOCK_SIZES.get(self.encoding, 1) + + +# master list of CipherSuite Objects +CIPHERSUITES = [ + # not a real cipher suite, can be ignored, see RFC5746 + CipherSuite(0xff, 'TLS_EMPTY_RENEGOTIATION_INFO', + 'NULL', 'NULL', 'NULL', 'NULL'), + CipherSuite(0x00, 'TLS_NULL_WITH_NULL_NULL', + 'NULL', 'NULL', 'NULL', 'NULL'), + CipherSuite(0x01, 'TLS_RSA_WITH_NULL_MD5', 'RSA', 'RSA', 'NULL', 'MD5'), + CipherSuite(0x02, 'TLS_RSA_WITH_NULL_SHA', 'RSA', 'RSA', 'NULL', 'SHA'), + CipherSuite(0x0039, 'TLS_DHE_RSA_WITH_AES_256_CBC_SHA', + 'DHE', 'RSA', 'AES_256_CBC', 'SHA'), # not sure I got the kx/auth thing right. + CipherSuite(0xffff, 'UNKNOWN_CIPHER', '', '', '', '') +] + +BY_CODE = dict( + (cipher.code, cipher) for cipher in CIPHERSUITES) + +BY_NAME = dict( + (suite.name, suite) for suite in CIPHERSUITES) + +NULL_SUITE = BY_CODE[0x00] diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/stp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/stp.py new file mode 100644 index 00000000..8fab28b3 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/stp.py @@ -0,0 +1,21 @@ +# $Id: stp.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Spanning Tree Protocol.""" + +import dpkt + +class STP(dpkt.Packet): + __hdr__ = ( + ('proto_id', 'H', 0), + ('v', 'B', 0), + ('type', 'B', 0), + ('flags', 'B', 0), + ('root_id', '8s', ''), + ('root_path', 'I', 0), + ('bridge_id', '8s', ''), + ('port_id', 'H', 0), + ('age', 'H', 0), + ('max_age', 'H', 0), + ('hello', 'H', 0), + ('fd', 'H', 0) + ) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/stun.py b/scripts/external_libs/dpkt-1.8.6/dpkt/stun.py new file mode 100644 index 00000000..5706f0ef --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/stun.py @@ -0,0 +1,45 @@ +# $Id: stun.py 47 2008-05-27 02:10:00Z jon.oberheide $ + +"""Simple Traversal of UDP through NAT.""" + +import struct +import dpkt + +# STUN - RFC 3489 +# http://tools.ietf.org/html/rfc3489 +# Each packet has a 20 byte header followed by 0 or more attribute TLVs. + +# Message Types +BINDING_REQUEST = 0x0001 +BINDING_RESPONSE = 0x0101 +BINDING_ERROR_RESPONSE = 0x0111 +SHARED_SECRET_REQUEST = 0x0002 +SHARED_SECRET_RESPONSE = 0x0102 +SHARED_SECRET_ERROR_RESPONSE = 0x0112 + +# Message Attributes +MAPPED_ADDRESS = 0x0001 +RESPONSE_ADDRESS = 0x0002 +CHANGE_REQUEST = 0x0003 +SOURCE_ADDRESS = 0x0004 +CHANGED_ADDRESS = 0x0005 +USERNAME = 0x0006 +PASSWORD = 0x0007 +MESSAGE_INTEGRITY = 0x0008 +ERROR_CODE = 0x0009 +UNKNOWN_ATTRIBUTES = 0x000a +REFLECTED_FROM = 0x000b + +class STUN(dpkt.Packet): + __hdr__ = ( + ('type', 'H', 0), + ('len', 'H', 0), + ('xid', '16s', 0) + ) + +def tlv(buf): + n = 4 + t, l = struct.unpack('>HH', buf[:n]) + v = buf[n:n+l] + buf = buf[n+l:] + return (t,l,v, buf) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/tcp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/tcp.py new file mode 100644 index 00000000..eaf10e3d --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/tcp.py @@ -0,0 +1,98 @@ +# $Id: tcp.py 42 2007-08-02 22:38:47Z jon.oberheide $ + +"""Transmission Control Protocol.""" + +import dpkt + +# TCP control flags +TH_FIN = 0x01 # end of data +TH_SYN = 0x02 # synchronize sequence numbers +TH_RST = 0x04 # reset connection +TH_PUSH = 0x08 # push +TH_ACK = 0x10 # acknowledgment number set +TH_URG = 0x20 # urgent pointer set +TH_ECE = 0x40 # ECN echo, RFC 3168 +TH_CWR = 0x80 # congestion window reduced + +TCP_PORT_MAX = 65535 # maximum port +TCP_WIN_MAX = 65535 # maximum (unscaled) window + +class TCP(dpkt.Packet): + __hdr__ = ( + ('sport', 'H', 0xdead), + ('dport', 'H', 0), + ('seq', 'I', 0xdeadbeefL), + ('ack', 'I', 0), + ('off_x2', 'B', ((5 << 4) | 0)), + ('flags', 'B', TH_SYN), + ('win', 'H', TCP_WIN_MAX), + ('sum', 'H', 0), + ('urp', 'H', 0) + ) + opts = '' + + def _get_off(self): return self.off_x2 >> 4 + def _set_off(self, off): self.off_x2 = (off << 4) | (self.off_x2 & 0xf) + off = property(_get_off, _set_off) + + def __len__(self): + return self.__hdr_len__ + len(self.opts) + len(self.data) + + def __str__(self): + return self.pack_hdr() + self.opts + str(self.data) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + ol = ((self.off_x2 >> 4) << 2) - self.__hdr_len__ + if ol < 0: + raise dpkt.UnpackError, 'invalid header length' + self.opts = buf[self.__hdr_len__:self.__hdr_len__ + ol] + self.data = buf[self.__hdr_len__ + ol:] + +# Options (opt_type) - http://www.iana.org/assignments/tcp-parameters +TCP_OPT_EOL = 0 # end of option list +TCP_OPT_NOP = 1 # no operation +TCP_OPT_MSS = 2 # maximum segment size +TCP_OPT_WSCALE = 3 # window scale factor, RFC 1072 +TCP_OPT_SACKOK = 4 # SACK permitted, RFC 2018 +TCP_OPT_SACK = 5 # SACK, RFC 2018 +TCP_OPT_ECHO = 6 # echo (obsolete), RFC 1072 +TCP_OPT_ECHOREPLY = 7 # echo reply (obsolete), RFC 1072 +TCP_OPT_TIMESTAMP = 8 # timestamp, RFC 1323 +TCP_OPT_POCONN = 9 # partial order conn, RFC 1693 +TCP_OPT_POSVC = 10 # partial order service, RFC 1693 +TCP_OPT_CC = 11 # connection count, RFC 1644 +TCP_OPT_CCNEW = 12 # CC.NEW, RFC 1644 +TCP_OPT_CCECHO = 13 # CC.ECHO, RFC 1644 +TCP_OPT_ALTSUM = 14 # alt checksum request, RFC 1146 +TCP_OPT_ALTSUMDATA = 15 # alt checksum data, RFC 1146 +TCP_OPT_SKEETER = 16 # Skeeter +TCP_OPT_BUBBA = 17 # Bubba +TCP_OPT_TRAILSUM = 18 # trailer checksum +TCP_OPT_MD5 = 19 # MD5 signature, RFC 2385 +TCP_OPT_SCPS = 20 # SCPS capabilities +TCP_OPT_SNACK = 21 # selective negative acks +TCP_OPT_REC = 22 # record boundaries +TCP_OPT_CORRUPT = 23 # corruption experienced +TCP_OPT_SNAP = 24 # SNAP +TCP_OPT_TCPCOMP = 26 # TCP compression filter +TCP_OPT_MAX = 27 + +def parse_opts(buf): + """Parse TCP option buffer into a list of (option, data) tuples.""" + opts = [] + while buf: + o = ord(buf[0]) + if o > TCP_OPT_NOP: + try: + l = ord(buf[1]) + d, buf = buf[2:l], buf[l:] + except ValueError: + #print 'bad option', repr(str(buf)) + opts.append(None) # XXX + break + else: + d, buf = '', buf[1:] + opts.append((o,d)) + return opts + diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/telnet.py b/scripts/external_libs/dpkt-1.8.6/dpkt/telnet.py new file mode 100644 index 00000000..9e8194d3 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/telnet.py @@ -0,0 +1,77 @@ +# $Id: telnet.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Telnet.""" + +IAC = 255 # interpret as command: +DONT = 254 # you are not to use option +DO = 253 # please, you use option +WONT = 252 # I won't use option +WILL = 251 # I will use option +SB = 250 # interpret as subnegotiation +GA = 249 # you may reverse the line +EL = 248 # erase the current line +EC = 247 # erase the current character +AYT = 246 # are you there +AO = 245 # abort output--but let prog finish +IP = 244 # interrupt process--permanently +BREAK = 243 # break +DM = 242 # data mark--for connect. cleaning +NOP = 241 # nop +SE = 240 # end sub negotiation +EOR = 239 # end of record (transparent mode) +ABORT = 238 # Abort process +SUSP = 237 # Suspend process +xEOF = 236 # End of file: EOF is already used... + +SYNCH = 242 # for telfunc calls + +def strip_options(buf): + """Return a list of lines and dict of options from telnet data.""" + l = buf.split(chr(IAC)) + #print l + b = [] + d = {} + subopt = False + for w in l: + if not w: + continue + o = ord(w[0]) + if o > SB: + #print 'WILL/WONT/DO/DONT/IAC', `w` + w = w[2:] + elif o == SE: + #print 'SE', `w` + w = w[1:] + subopt = False + elif o == SB: + #print 'SB', `w` + subopt = True + for opt in ('USER', 'DISPLAY', 'TERM'): + p = w.find(opt + '\x01') + if p != -1: + d[opt] = w[p+len(opt)+1:].split('\x00', 1)[0] + w = None + elif subopt: + w = None + if w: + w = w.replace('\x00', '\n').splitlines() + if not w[-1]: w.pop() + b.extend(w) + return b, d + +if __name__ == '__main__': + import unittest + + class TelnetTestCase(unittest.TestCase): + def test_telnet(self): + l = [] + s = "\xff\xfb%\xff\xfa%\x00\x00\x00\xff\xf0\xff\xfd&\xff\xfa&\x05\xff\xf0\xff\xfa&\x01\x01\x02\xff\xf0\xff\xfb\x18\xff\xfb \xff\xfb#\xff\xfb'\xff\xfc$\xff\xfa \x0038400,38400\xff\xf0\xff\xfa#\x00doughboy.citi.umich.edu:0.0\xff\xf0\xff\xfa'\x00\x00DISPLAY\x01doughboy.citi.umich.edu:0.0\x00USER\x01dugsong\xff\xf0\xff\xfa\x18\x00XTERM\xff\xf0\xff\xfd\x03\xff\xfc\x01\xff\xfb\x1f\xff\xfa\x1f\x00P\x00(\xff\xf0\xff\xfd\x05\xff\xfb!\xff\xfd\x01fugly\r\x00yoda\r\x00bashtard\r\x00" + l.append(s) + s = '\xff\xfd\x01\xff\xfd\x03\xff\xfb\x18\xff\xfb\x1f\xff\xfa\x1f\x00X\x002\xff\xf0admin\r\x00\xff\xfa\x18\x00LINUX\xff\xf0foobar\r\x00enable\r\x00foobar\r\x00\r\x00show ip int Vlan 666\r\x00' + l.append(s) + s = '\xff\xfb%\xff\xfa%\x00\x00\x00\xff\xf0\xff\xfd&\xff\xfa&\x05\xff\xf0\xff\xfa&\x01\x01\x02\xff\xf0\xff\xfb&\xff\xfb\x18\xff\xfb \xff\xfb#\xff\xfb\'\xff\xfc$\xff\xfa \x0038400,38400\xff\xf0\xff\xfa#\x00doughboy.citi.umich.edu:0.0\xff\xf0\xff\xfa\'\x00\x00DISPLAY\x01doughboy.citi.umich.edu:0.0\x00USER\x01dugsong\xff\xf0\xff\xfa\x18\x00XTERM\xff\xf0\xff\xfd\x03\xff\xfc\x01\xff\xfb"\xff\xfa"\x03\x01\x03\x00\x03b\x03\x04\x02\x0f\x05\x00\xff\xff\x07b\x1c\x08\x02\x04\tB\x1a\n\x02\x7f\x0b\x02\x15\x0c\x02\x17\r\x02\x12\x0e\x02\x16\x0f\x02\x11\x10\x02\x13\x11\x00\xff\xff\x12\x00\xff\xff\xff\xf0\xff\xfb\x1f\xff\xfa\x1f\x00P\x00(\xff\xf0\xff\xfd\x05\xff\xfb!\xff\xfa"\x01\x0f\xff\xf0\xff\xfd\x01\xff\xfe\x01\xff\xfa"\x03\x01\x80\x00\xff\xf0\xff\xfd\x01werd\r\n\xff\xfe\x01yoda\r\n\xff\xfd\x01darthvader\r\n\xff\xfe\x01' + l.append(s) + exp = [ (['fugly', 'yoda', 'bashtard'], {'USER': 'dugsong', 'DISPLAY': 'doughboy.citi.umich.edu:0.0'}), (['admin', 'foobar', 'enable', 'foobar', '', 'show ip int Vlan 666'], {}), (['werd', 'yoda', 'darthvader'], {'USER': 'dugsong', 'DISPLAY': 'doughboy.citi.umich.edu:0.0'}) ] + self.failUnless(map(strip_options, l) == exp) + + unittest.main() diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/tftp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/tftp.py new file mode 100644 index 00000000..046ae8d2 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/tftp.py @@ -0,0 +1,55 @@ +# $Id: tftp.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Trivial File Transfer Protocol.""" + +import struct +import dpkt + +# Opcodes +OP_RRQ = 1 # read request +OP_WRQ = 2 # write request +OP_DATA = 3 # data packet +OP_ACK = 4 # acknowledgment +OP_ERR = 5 # error code + +# Error codes +EUNDEF = 0 # not defined +ENOTFOUND = 1 # file not found +EACCESS = 2 # access violation +ENOSPACE = 3 # disk full or allocation exceeded +EBADOP = 4 # illegal TFTP operation +EBADID = 5 # unknown transfer ID +EEXISTS = 6 # file already exists +ENOUSER = 7 # no such user + +class TFTP(dpkt.Packet): + __hdr__ = (('opcode', 'H', 1), ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + if self.opcode in (OP_RRQ, OP_WRQ): + l = self.data.split('\x00') + self.filename = l[0] + self.mode = l[1] + self.data = '' + elif self.opcode in (OP_DATA, OP_ACK): + self.block = struct.unpack('>H', self.data[:2]) + self.data = self.data[2:] + elif self.opcode == OP_ERR: + self.errcode = struct.unpack('>H', self.data[:2]) + self.errmsg = self.data[2:].split('\x00')[0] + self.data = '' + + def __len__(self): + return len(str(self)) + + def __str__(self): + if self.opcode in (OP_RRQ, OP_WRQ): + s = '%s\x00%s\x00' % (self.filename, self.mode) + elif self.opcode in (OP_DATA, OP_ACK): + s = struct.pack('>H', self.block) + elif self.opcode == OP_ERR: + s = struct.pack('>H', self.errcode) + ('%s\x00' % self.errmsg) + else: + s = '' + return self.pack_hdr() + s + self.data diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/tns.py b/scripts/external_libs/dpkt-1.8.6/dpkt/tns.py new file mode 100644 index 00000000..7e092250 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/tns.py @@ -0,0 +1,24 @@ +# $Id: tns.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Transparent Network Substrate.""" + +import dpkt + +class TNS(dpkt.Packet): + __hdr__ = ( + ('length', 'H', 0), + ('pktsum', 'H', 0), + ('type', 'B', 0), + ('rsvd', 'B', 0), + ('hdrsum', 'H', 0), + ('msg', '0s', ''), + ) + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + n = self.length - self.__hdr_len__ + if n > len(self.data): + raise dpkt.NeedData('short message (missing %d bytes)' % + (n - len(self.data))) + self.msg = self.data[:n] + self.data = self.data[n:] + diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/tpkt.py b/scripts/external_libs/dpkt-1.8.6/dpkt/tpkt.py new file mode 100644 index 00000000..d81f7855 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/tpkt.py @@ -0,0 +1,15 @@ +# $Id: tpkt.py 23 2006-11-08 15:45:33Z dugsong $ + +"""ISO Transport Service on top of the TCP (TPKT).""" + +import dpkt + +# TPKT - RFC 1006 Section 6 +# http://www.faqs.org/rfcs/rfc1006.html + +class TPKT(dpkt.Packet): + __hdr__ = ( + ('v', 'B', 3), + ('rsvd', 'B', 0), + ('len', 'H', 0) + ) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/udp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/udp.py new file mode 100644 index 00000000..0fd6334b --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/udp.py @@ -0,0 +1,15 @@ +# $Id: udp.py 23 2006-11-08 15:45:33Z dugsong $ + +"""User Datagram Protocol.""" + +import dpkt + +UDP_PORT_MAX = 65535 + +class UDP(dpkt.Packet): + __hdr__ = ( + ('sport', 'H', 0xdead), + ('dport', 'H', 0), + ('ulen', 'H', 8), + ('sum', 'H', 0) + ) diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/vrrp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/vrrp.py new file mode 100644 index 00000000..fbb97937 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/vrrp.py @@ -0,0 +1,48 @@ +# $Id: vrrp.py 88 2013-03-05 19:43:17Z andrewflnr@gmail.com $ + +"""Virtual Router Redundancy Protocol.""" + +import dpkt + +class VRRP(dpkt.Packet): + __hdr__ = ( + ('vtype', 'B', 0x21), + ('vrid', 'B', 0), + ('priority', 'B', 0), + ('count', 'B', 0), + ('atype', 'B', 0), + ('advtime', 'B', 0), + ('sum', 'H', 0), + ) + addrs = () + auth = '' + def _get_v(self): + return self.vtype >> 4 + def _set_v(self, v): + self.vtype = (self.vtype & ~0xf) | (v << 4) + v = property(_get_v, _set_v) + + def _get_type(self): + return self.vtype & 0xf + def _set_type(self, v): + self.vtype = (self.vtype & ~0xf0) | (v & 0xf) + type = property(_get_type, _set_type) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + l = [] + off = 0 + for off in range(0, 4 * self.count, 4): + l.append(self.data[off:off+4]) + self.addrs = l + self.auth = self.data[off+4:] + self.data = '' + + def __len__(self): + return self.__hdr_len__ + (4 * self.count) + len(self.auth) + + def __str__(self): + data = ''.join(self.addrs) + self.auth + if not self.sum: + self.sum = dpkt.in_cksum(self.pack_hdr() + data) + return self.pack_hdr() + data diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/yahoo.py b/scripts/external_libs/dpkt-1.8.6/dpkt/yahoo.py new file mode 100644 index 00000000..726aeece --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/yahoo.py @@ -0,0 +1,29 @@ +# $Id: yahoo.py 23 2006-11-08 15:45:33Z dugsong $ + +"""Yahoo Messenger.""" + +import dpkt + +class YHOO(dpkt.Packet): + __hdr__ = [ + ('version', '8s', ' ' * 8), + ('length', 'I', 0), + ('service', 'I', 0), + ('connid', 'I', 0), + ('magic', 'I', 0), + ('unknown', 'I', 0), + ('type', 'I', 0), + ('nick1', '36s', ' ' * 36), + ('nick2', '36s', ' ' * 36) + ] + __byte_order__ = '<' + +class YMSG(dpkt.Packet): + __hdr__ = [ + ('version', '8s', ' ' * 8), + ('length', 'H', 0), + ('type', 'H', 0), + ('unknown1', 'I', 0), + ('unknown2', 'I', 0) + ] + diff --git a/scripts/external_libs/dpkt-1.8.6/setup.cfg b/scripts/external_libs/dpkt-1.8.6/setup.cfg new file mode 100644 index 00000000..56ffc205 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/setup.cfg @@ -0,0 +1,20 @@ +[bdist_wheel] +universal = 1 + +[aliases] +release = register clean --all sdist bdist_wheel upload + +[flake8] +max-line-length = 140 + +[pytest] +addopts = -v --cov-report term-missing +python_files = *.py +python_functions = test +norecursedirs = .tox .git *.egg-info __pycache__ dist build + +[egg_info] +tag_build = +tag_date = 0 +tag_svn_revision = 0 + diff --git a/scripts/external_libs/dpkt-1.8.6/setup.py b/scripts/external_libs/dpkt-1.8.6/setup.py new file mode 100644 index 00000000..fe4f84fa --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/setup.py @@ -0,0 +1,40 @@ +import os +import sys + +try: + from setuptools import setup, Command +except ImportError: + from distutils.core import setup, Command + +package_name = 'dpkt' +description = 'fast, simple packet creation / parsing, with definitions for the basic TCP/IP protocols' +readme = open('README.rst').read() +requirements = [ ] + +# PyPI Readme +long_description = open('README.rst').read() + +# Pull in the package +package = __import__(package_name) + +setup(name=package_name, + version=package.__version__, + author=package.__author__, + url=package.__url__, + description=description, + long_description=long_description, + packages=['dpkt'], + install_requires=requirements, + license='BSD', + zip_safe=False, + classifiers=[ + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: BSD License', + 'Natural Language :: English', + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: Implementation :: CPython', + 'Programming Language :: Python :: Implementation :: PyPy', + ] +) |