summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHanoh Haim <hhaim@cisco.com>2015-09-20 17:34:55 +0300
committerHanoh Haim <hhaim@cisco.com>2015-09-20 17:34:55 +0300
commit3fe28431157f7b2ed2ed8184ed85017c42a4cb6c (patch)
tree41fa17684842885e1664cc63ff1520157f191261
parent588bb20e9c8f8438db4eb3e8db85111f41bd7306 (diff)
parent28fef018f75b5a54ac69ac7c919127bf47f5b61f (diff)
Merge branch 'master' of csi-sceasr-b45:/auto/proj-pcube-b/apps/PL-b/tools/repo//trex-core into wen
-rwxr-xr-xVERSION2
-rwxr-xr-xlinux/ws_main.py5
-rw-r--r--scripts/automation/__init__.py0
-rwxr-xr-xscripts/automation/trex_control_plane/client/trex_client.py2
-rw-r--r--scripts/automation/trex_control_plane/client/trex_hltapi.py18
-rw-r--r--scripts/automation/trex_control_plane/client/trex_root_path.py15
-rw-r--r--scripts/automation/trex_control_plane/client/trex_stateless_client.py51
-rw-r--r--scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py14
-rw-r--r--scripts/automation/trex_control_plane/client_utils/outer_packages.py4
-rw-r--r--scripts/automation/trex_control_plane/client_utils/packet_builder.py720
-rwxr-xr-xscripts/automation/trex_control_plane/examples/client_interactive_example.py1
-rwxr-xr-xscripts/automation/trex_control_plane/server/extended_daemon_runner.py2
-rwxr-xr-xscripts/automation/trex_control_plane/server/trex_server.py2
-rw-r--r--scripts/cap2/asa_exploit.pcapbin0 -> 29728 bytes
-rw-r--r--scripts/cap2/asa_explot1.yaml23
-rw-r--r--scripts/cap2/jumbo.pcapbin0 -> 17791 bytes
-rw-r--r--scripts/cap2/jumbo.yaml23
-rw-r--r--scripts/cap2/wrong_ip.pcapbin0 -> 1530 bytes
-rw-r--r--scripts/cap2/wrong_ip.yaml23
-rw-r--r--scripts/external_libs/dpkt-1.8.6/AUTHORS60
-rw-r--r--scripts/external_libs/dpkt-1.8.6/CHANGES71
-rw-r--r--scripts/external_libs/dpkt-1.8.6/LICENSE28
-rw-r--r--scripts/external_libs/dpkt-1.8.6/MANIFEST.in2
-rw-r--r--scripts/external_libs/dpkt-1.8.6/PKG-INFO122
-rw-r--r--scripts/external_libs/dpkt-1.8.6/README.rst104
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/PKG-INFO122
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/SOURCES.txt80
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/dependency_links.txt1
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/not-zip-safe1
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt.egg-info/top_level.txt1
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/__init__.py70
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/ah.py31
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/aim.py47
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/aoe.py70
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/aoeata.py34
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/aoecfg.py24
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/arp.py31
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/asn1.py119
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/bgp.py760
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/cdp.py95
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/crc32c.py80
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/dhcp.py168
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/diameter.py181
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/dns.py342
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/dot1q.py1110
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/dpkt.py168
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/dtp.py23
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/esp.py11
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/ethernet.py140
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/gre.py103
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/gzip.py117
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/h225.py217
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/hsrp.py32
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/http.py237
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/icmp.py122
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/icmp6.py72
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/ieee80211.py706
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/igmp.py17
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/ip.py301
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/ip6.py307
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/ipx.py17
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/llc.py55
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/loopback.py20
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/mrt.py92
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/netbios.py154
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/netflow.py214
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/ntp.py83
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/ospf.py25
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/pcap.py164
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/pim.py24
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/pmap.py17
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/ppp.py63
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/pppoe.py38
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/qq.py224
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/radiotap.py292
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/radius.py88
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/rfb.py81
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/rip.py84
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/rpc.py146
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/rtp.py70
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/rx.py44
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/sccp.py196
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/sctp.py90
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/sip.py32
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/sll.py23
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/smb.py19
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/snoop.py118
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/ssl.py560
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/ssl_ciphersuites.py76
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/stp.py21
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/stun.py45
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/tcp.py98
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/telnet.py77
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/tftp.py55
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/tns.py24
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/tpkt.py15
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/udp.py15
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/vrrp.py48
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/yahoo.py29
-rw-r--r--scripts/external_libs/dpkt-1.8.6/setup.cfg20
-rw-r--r--scripts/external_libs/dpkt-1.8.6/setup.py40
-rwxr-xr-xsrc/bp_sim.cpp16
-rwxr-xr-xsrc/common/captureFile.cpp2
-rwxr-xr-xsrc/common/pcap.cpp3
-rw-r--r--src/gtest/rpc_test.cpp516
-rw-r--r--src/gtest/trex_stateless_gtest.cpp353
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_general.cpp230
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_stream.cpp47
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_test.cpp30
-rw-r--r--src/rpc-server/commands/trex_rpc_cmds.h47
-rw-r--r--src/rpc-server/trex_rpc_cmd.cpp39
-rw-r--r--src/rpc-server/trex_rpc_cmd_api.h30
-rw-r--r--src/rpc-server/trex_rpc_cmds_table.cpp11
-rw-r--r--src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp8
-rw-r--r--src/rpc-server/trex_rpc_jsonrpc_v2_parser.h9
-rw-r--r--src/rpc-server/trex_rpc_req_resp_server.cpp27
-rw-r--r--src/rpc-server/trex_rpc_req_resp_server.h4
-rw-r--r--src/rpc-server/trex_rpc_server.cpp1
-rw-r--r--src/rpc-server/trex_rpc_server_api.h26
-rw-r--r--src/stateless/trex_stateless.cpp53
-rw-r--r--src/stateless/trex_stateless_api.h99
-rw-r--r--src/stateless/trex_stream.cpp11
-rw-r--r--src/stateless/trex_stream_api.h24
123 files changed, 12165 insertions, 249 deletions
diff --git a/VERSION b/VERSION
index 917f0173..fe509dde 100755
--- a/VERSION
+++ b/VERSION
@@ -1,4 +1,4 @@
-v1.75
+v1.76
diff --git a/linux/ws_main.py b/linux/ws_main.py
index c5ec3cee..8ad3e5ba 100755
--- a/linux/ws_main.py
+++ b/linux/ws_main.py
@@ -109,8 +109,10 @@ main_src = SrcGroup(dir='src',
'utl_json.cpp',
'utl_cpuu.cpp',
'msg_manager.cpp',
+
'gtest/tuple_gen_test.cpp',
'gtest/nat_test.cpp',
+ 'gtest/trex_stateless_gtest.cpp',
'pal/linux/pal_utl.cpp',
'pal/linux/mbuf.cpp'
@@ -368,7 +370,8 @@ build_types = [
#build_option(name = "bp-sim", src = bp, debug_mode= RELEASE_,platform = PLATFORM_32, is_pie = False),
build_option(name = "bp-sim", src = bp, debug_mode= RELEASE_,platform = PLATFORM_64, is_pie = False),
- build_option(name = "mock-rpc-server", use = ['zmq'], src = rpc_server_mock, debug_mode= DEBUG_,platform = PLATFORM_64, is_pie = False, flags = ['-DTREX_RPC_MOCK_SERVER'],
+ build_option(name = "mock-rpc-server", use = ['zmq'], src = rpc_server_mock, debug_mode= DEBUG_,platform = PLATFORM_64, is_pie = False,
+ flags = ['-DTREX_RPC_MOCK_SERVER', '-Wall', '-Wno-sign-compare', '-Werror'],
rpath = ['.']),
]
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 b44b1268..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")
@@ -145,7 +144,7 @@ class JsonRpcClient(object):
return self.invoke_rpc_method("get_status")
def query_rpc_server(self):
- return self.invoke_rpc_method("get_reg_cmds")
+ return self.invoke_rpc_method("get_supported_cmds")
def set_verbose(self, mode):
@@ -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/cap2/asa_exploit.pcap b/scripts/cap2/asa_exploit.pcap
new file mode 100644
index 00000000..861d4037
--- /dev/null
+++ b/scripts/cap2/asa_exploit.pcap
Binary files differ
diff --git a/scripts/cap2/asa_explot1.yaml b/scripts/cap2/asa_explot1.yaml
new file mode 100644
index 00000000..6f08c49c
--- /dev/null
+++ b/scripts/cap2/asa_explot1.yaml
@@ -0,0 +1,23 @@
+- duration : 0.1
+ generator :
+ distribution : "seq"
+ clients_start : "16.0.0.1"
+ clients_end : "16.0.1.254"
+ servers_start : "48.0.0.1"
+ servers_end : "48.0.0.254"
+ clients_per_gb : 201
+ min_clients : 101
+ dual_port_mask : "1.0.0.0"
+ tcp_aging : 0
+ udp_aging : 0
+ mac : [0x00,0x00,0x00,0x01,0x00,0x00]
+ cap_ipg : false
+ cap_ipg_min : 100
+ cap_override_ipg : 1000
+ cap_info :
+ - name: cap2/asa_exploit.pcap
+ cps : 1.1
+ ipg : 1.1
+ rtt : 50000
+ w : 1
+
diff --git a/scripts/cap2/jumbo.pcap b/scripts/cap2/jumbo.pcap
new file mode 100644
index 00000000..2a7f7bde
--- /dev/null
+++ b/scripts/cap2/jumbo.pcap
Binary files differ
diff --git a/scripts/cap2/jumbo.yaml b/scripts/cap2/jumbo.yaml
new file mode 100644
index 00000000..b45a6ca3
--- /dev/null
+++ b/scripts/cap2/jumbo.yaml
@@ -0,0 +1,23 @@
+- duration : 10.0
+ generator :
+ distribution : "seq"
+ clients_start : "16.0.0.1"
+ clients_end : "16.0.1.255"
+ servers_start : "48.0.0.1"
+ servers_end : "48.0.0.255"
+ clients_per_gb : 201
+ min_clients : 101
+ dual_port_mask : "1.0.0.0"
+ tcp_aging : 1
+ udp_aging : 1
+ mac : [0x00,0x00,0x00,0x01,0x00,0x00]
+ #vlan : { enable : 1 , vlan0 : 100 , vlan1 : 200 }
+ #mac_override_by_ip : true
+ cap_info :
+ - name: cap2/jumbo.pcap
+ cps : 1.0
+ ipg : 10000
+ rtt : 10000
+ w : 1
+
+
diff --git a/scripts/cap2/wrong_ip.pcap b/scripts/cap2/wrong_ip.pcap
new file mode 100644
index 00000000..08cf8de8
--- /dev/null
+++ b/scripts/cap2/wrong_ip.pcap
Binary files differ
diff --git a/scripts/cap2/wrong_ip.yaml b/scripts/cap2/wrong_ip.yaml
new file mode 100644
index 00000000..7de3b82d
--- /dev/null
+++ b/scripts/cap2/wrong_ip.yaml
@@ -0,0 +1,23 @@
+- duration : 10.0
+ generator :
+ distribution : "seq"
+ clients_start : "16.0.0.1"
+ clients_end : "16.0.1.255"
+ servers_start : "48.0.0.1"
+ servers_end : "48.0.0.255"
+ clients_per_gb : 201
+ min_clients : 101
+ dual_port_mask : "1.0.0.0"
+ tcp_aging : 1
+ udp_aging : 1
+ mac : [0x00,0x00,0x00,0x01,0x00,0x00]
+ #vlan : { enable : 1 , vlan0 : 100 , vlan1 : 200 }
+ #mac_override_by_ip : true
+ cap_info :
+ - name: cap2/wrong_ip.pcap
+ cps : 1.0
+ ipg : 10000
+ rtt : 10000
+ w : 1
+
+
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&amp;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&amp;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="&#x2713;" /></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&amp;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="&#x2713;" /><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="&#x2713;" /><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="&#x2713;" /><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="&#x2713;" /><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&amp;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="&#x2713;" /><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&amp;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="&#x2713;" /><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&amp;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="&#x2713;" /><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&amp;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&amp;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="&#x2713;" /><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="&#x2713;" /><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">&quot;&quot;&quot;</span>IEEE 802.1q<span class="pl-pds">&quot;&quot;&quot;</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">&#39;</span>x2<span class="pl-pds">&#39;</span></span>, <span class="pl-s"><span class="pl-pds">&#39;</span>H<span class="pl-pds">&#39;</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">&#39;</span>type<span class="pl-pds">&#39;</span></span>, <span class="pl-s"><span class="pl-pds">&#39;</span>H<span class="pl-pds">&#39;</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">&gt;&gt;</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">&amp;</span> <span class="pl-c1">0x</span>1fff) <span class="pl-k">|</span> (pcp <span class="pl-k">&lt;&lt;</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">&gt;&gt;</span> <span class="pl-c1">12</span>) <span class="pl-k">&amp;</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">&amp;</span> <span class="pl-c1">61439</span>) <span class="pl-k">|</span> (dei <span class="pl-k">&lt;&lt;</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">&amp;</span> (<span class="pl-c1">65535</span> <span class="pl-k">&gt;&gt;</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">&amp;</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">&#39;</span>&gt;I<span class="pl-pds">&#39;</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">&amp;</span> MPLS_LABEL_MASK) <span class="pl-k">&gt;&gt;</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">&amp;</span> MPLS_QOS_MASK) <span class="pl-k">&gt;&gt;</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">&amp;</span> MPLS_TTL_MASK) <span class="pl-k">&gt;&gt;</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">&amp;</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">&#39;</span>ETH_TYPE_<span class="pl-pds">&#39;</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="&#x2713;" /></div>
+ <input class="linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line&hellip;" 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>&copy; 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',
+ ]
+)
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp
index fca517cf..7cbeb09d 100755
--- a/src/bp_sim.cpp
+++ b/src/bp_sim.cpp
@@ -1148,13 +1148,6 @@ void CPacketIndication::ProcessIpPacket(CPacketParser *parser,
}
offset += ip_header_length;
- if (!l3.m_ipv4->isChecksumOK() ){
- m_cnt->m_ip_checksum_error++;
- }
- if( l3.m_ipv4->isMulticast() ){
- m_cnt->m_ip_multicast_error++;
- return;
- }
if( l3.m_ipv4->getTimeToLive() ==0 ){
m_cnt->m_ip_ttl_is_zero_error++;
@@ -1177,10 +1170,19 @@ void CPacketIndication::ProcessIpPacket(CPacketParser *parser,
return;
}
+ if ( m_packet->pkt_len > MAX_BUF_SIZE -FIRST_PKT_SIZE ){
+ m_cnt->m_tcp_udp_pkt_length_error++;
+ printf("ERROR packet is too big, not supported jumbo packets that larger than %d \n",MAX_BUF_SIZE);
+ return;
+ }
+
// Set packet length and include padding if needed
m_packet->pkt_len = l3.m_ipv4->getTotalLength() + getIpOffset();
if (m_packet->pkt_len < 60) { m_packet->pkt_len = 60; }
+
+
+
m_cnt->m_valid_udp_tcp++;
m_payload_len = l3.m_ipv4->getTotalLength() - (payload_offset_from_ip);
m_payload = (uint8_t *)(packetBase +offset);
diff --git a/src/common/captureFile.cpp b/src/common/captureFile.cpp
index a4fe78be..00625181 100755
--- a/src/common/captureFile.cpp
+++ b/src/common/captureFile.cpp
@@ -110,7 +110,7 @@ void CCapPktRaw::CloneShalow(CCapPktRaw *obj){
}
void CCapPktRaw::Dump(FILE *fd,int verbose){
- fprintf(fd," =>pkt (%p) %llu , len %d, time [%x:%x] \n",raw,pkt_cnt,pkt_len,time_sec,time_nsec);
+ fprintf(fd," =>pkt (%p) %llu , len %d, time [%x:%x] \n",raw, (unsigned long long)pkt_cnt,pkt_len,time_sec,time_nsec);
if (verbose) {
utl_DumpBuffer(fd,raw,pkt_len,0);
}
diff --git a/src/common/pcap.cpp b/src/common/pcap.cpp
index 6dd54514..9b360a3e 100755
--- a/src/common/pcap.cpp
+++ b/src/common/pcap.cpp
@@ -156,7 +156,8 @@ bool LibPCapReader::ReadPacket(CCapPktRaw *lpPacket)
}
if (pkt_header.len > READER_MAX_PACKET_SIZE) {
/* cannot read this packet */
- assert(0);
+ printf("ERROR packet is too big, bigger than %d \n",READER_MAX_PACKET_SIZE);
+ exit(-1);
return false;
}
diff --git a/src/gtest/rpc_test.cpp b/src/gtest/rpc_test.cpp
index 8a7e9176..168ee936 100644
--- a/src/gtest/rpc_test.cpp
+++ b/src/gtest/rpc_test.cpp
@@ -25,12 +25,23 @@ limitations under the License.
#include <zmq.h>
#include <json/json.h>
#include <sstream>
+#include <vector>
+#include <algorithm>
using namespace std;
class RpcTest : public testing::Test {
+protected:
+
+ void set_verbose(bool verbose) {
+ m_verbose = verbose;
+ }
+
virtual void SetUp() {
+
+ m_verbose = false;
+
TrexRpcServerConfig cfg = TrexRpcServerConfig(TrexRpcServerConfig::RPC_PROT_TCP, 5050);
m_rpc = new TrexRpcServer(cfg);
@@ -39,6 +50,7 @@ class RpcTest : public testing::Test {
m_context = zmq_ctx_new ();
m_socket = zmq_socket (m_context, ZMQ_REQ);
zmq_connect (m_socket, "tcp://localhost:5050");
+
}
virtual void TearDown() {
@@ -50,8 +62,41 @@ class RpcTest : public testing::Test {
}
public:
+
+ void create_request(Json::Value &request, const string &method, int id = 1) {
+ request.clear();
+
+ request["jsonrpc"] = "2.0";
+ request["id"] = id;
+ request["method"] = method;
+
+ }
+
+ void send_request(const Json::Value &request, Json::Value &response) {
+ Json::FastWriter writer;
+ Json::Reader reader;
+
+ response.clear();
+
+ string request_str = writer.write(request);
+
+ if (m_verbose) {
+ cout << "\n" << request_str << "\n";
+ }
+
+ string ret = send_msg(request_str);
+
+ if (m_verbose) {
+ cout << "\n" << ret << "\n";
+ }
+
+ EXPECT_TRUE(reader.parse(ret, response, false));
+ EXPECT_EQ(response["jsonrpc"], "2.0");
+ EXPECT_EQ(response["id"], request["id"]);
+ }
+
string send_msg(const string &msg) {
- char buffer[512];
+ char buffer[1024 * 20];
zmq_send (m_socket, msg.c_str(), msg.size(), 0);
int len = zmq_recv(m_socket, buffer, sizeof(buffer), 0);
@@ -62,9 +107,64 @@ public:
TrexRpcServer *m_rpc;
void *m_context;
void *m_socket;
+ bool m_verbose;
};
-TEST_F(RpcTest, basic_rpc_test) {
+class RpcTestOwned : public RpcTest {
+public:
+
+ void create_request(Json::Value &request, const string &method, int id = 1, int port_id = 1, bool owned = true) {
+ RpcTest::create_request(request, method, id);
+ if (owned) {
+ request["params"]["port_id"] = port_id;
+ request["params"]["handler"] = m_ownership_handler[port_id];
+ }
+ }
+
+protected:
+
+ virtual void SetUp() {
+ RpcTest::SetUp();
+
+ for (int i = 0 ; i < 4; i++) {
+ m_ownership_handler[i] = take_ownership(i);
+ }
+ }
+
+
+ string take_ownership(uint8_t port_id) {
+ Json::Value request;
+ Json::Value response;
+
+ RpcTest::create_request(request, "acquire", 1);
+
+ request["params"]["port_id"] = port_id;
+ request["params"]["user"] = "test";
+ request["params"]["force"] = true;
+
+ send_request(request, response);
+
+ EXPECT_TRUE(response["result"] != Json::nullValue);
+ return response["result"].asString();
+ }
+
+ void release_ownership(uint8_t port_id) {
+ Json::Value request;
+ Json::Value response;
+
+ RpcTest::create_request(request, "release", 1);
+
+ request["params"]["handler"] = m_ownership_handler;
+ request["params"]["port_id"] = port_id;
+
+ send_request(request, response);
+ EXPECT_TRUE(response["result"] == "ACK");
+ }
+
+ string m_ownership_handler[4];
+};
+
+TEST_F(RpcTest, basic_rpc_negative_cases) {
Json::Value request;
Json::Value response;
Json::Reader reader;
@@ -121,55 +221,39 @@ TEST_F(RpcTest, basic_rpc_test) {
TEST_F(RpcTest, test_add_command) {
Json::Value request;
Json::Value response;
- Json::Reader reader;
- string req_str;
- string resp_str;
-
- /* simple add - missing paramters */
- req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"id\": 488}";
- resp_str = send_msg(req_str);
+ /* missing parameters */
+ create_request(request, "test_add");
+ send_request(request, response);
- EXPECT_TRUE(reader.parse(resp_str, response, false));
EXPECT_EQ(response["jsonrpc"], "2.0");
- EXPECT_EQ(response["id"], 488);
EXPECT_EQ(response["error"]["code"], -32602);
- /* simple add that works */
- req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"x\": 17, \"y\": -13} , \"id\": \"itay\"}";
- resp_str = send_msg(req_str);
-
- EXPECT_TRUE(reader.parse(resp_str, response, false));
- EXPECT_EQ(response["jsonrpc"], "2.0");
- EXPECT_EQ(response["id"], "itay");
- EXPECT_EQ(response["result"], 4);
-
- /* add with bad paratemers types */
- req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"x\": \"blah\", \"y\": -13} , \"id\": 17}";
- resp_str = send_msg(req_str);
+ /* bad paramters */
+ create_request(request, "test_add");
+ request["params"]["x"] = 5;
+ request["params"]["y"] = "itay";
+ send_request(request, response);
- EXPECT_TRUE(reader.parse(resp_str, response, false));
EXPECT_EQ(response["jsonrpc"], "2.0");
- EXPECT_EQ(response["id"], 17);
EXPECT_EQ(response["error"]["code"], -32602);
- /* add with invalid count of parameters */
- req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"y\": -13} , \"id\": 17}";
- resp_str = send_msg(req_str);
+ /* simple add that works */
+ create_request(request, "test_add");
+ request["params"]["x"] = 5;
+ request["params"]["y"] = -13;
+ send_request(request, response);
- EXPECT_TRUE(reader.parse(resp_str, response, false));
EXPECT_EQ(response["jsonrpc"], "2.0");
- EXPECT_EQ(response["id"], 17);
- EXPECT_EQ(response["error"]["code"], -32602);
-
+ EXPECT_EQ(response["result"], -8);
/* big numbers */
- req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"x\": 4827371, \"y\": -39181273} , \"id\": \"itay\"}";
- resp_str = send_msg(req_str);
+ create_request(request, "test_add");
+ request["params"]["x"] = 4827371;
+ request["params"]["y"] = -39181273;
+ send_request(request, response);
- EXPECT_TRUE(reader.parse(resp_str, response, false));
EXPECT_EQ(response["jsonrpc"], "2.0");
- EXPECT_EQ(response["id"], "itay");
EXPECT_EQ(response["result"], -34353902);
}
@@ -225,87 +309,351 @@ TEST_F(RpcTest, batch_rpc_test) {
return;
}
-TEST_F(RpcTest, add_stream) {
+/* ping command */
+TEST_F(RpcTest, ping) {
Json::Value request;
Json::Value response;
- Json::Reader reader;
- string resp_str;
+ create_request(request, "ping");
+ send_request(request, response);
+ EXPECT_TRUE(response["result"] == "ACK");
+}
+
+static bool
+find_member_in_array(const Json::Value &array, const string &member) {
+ for (auto x : array) {
+ if (x == member) {
+ return true;
+ }
+ }
- // check the stream does not exists
- string lookup_str = "{\"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"get_stream\", \"params\":{\"port_id\":1, \"stream_id\":5}}";
- resp_str = send_msg(lookup_str);
+ return false;
+}
+
+/* get registered commands */
+TEST_F(RpcTest, get_supported_cmds) {
+ Json::Value request;
+ Json::Value response;
+
+ create_request(request, "get_supported_cmds");
+ send_request(request, response);
+ EXPECT_TRUE(response["result"].size() > 0);
+
+ EXPECT_TRUE(find_member_in_array(response["result"], "ping"));
+ EXPECT_TRUE(find_member_in_array(response["result"], "get_supported_cmds"));
+}
+
+/* get version */
+TEST_F(RpcTest, get_version) {
+ Json::Value request;
+ Json::Value response;
+
+ create_request(request, "get_version");
+ send_request(request, response);
+
+ EXPECT_TRUE(response["result"] != Json::nullValue);
+ EXPECT_TRUE(response["result"]["built_by"] == "MOCK");
+ EXPECT_TRUE(response["result"]["version"] == "v0.0");
+}
+
+/* get system info */
+TEST_F(RpcTest, get_system_info) {
+ Json::Value request;
+ Json::Value response;
+
+ create_request(request, "get_system_info");
+ send_request(request, response);
+
+ EXPECT_TRUE(response["result"] != Json::nullValue);
+ EXPECT_TRUE(response["result"]["core_type"].isString());
+ EXPECT_TRUE(response["result"]["hostname"].isString());
+ EXPECT_TRUE(response["result"]["uptime"].isString());
+ EXPECT_TRUE(response["result"]["dp_core_count"] > 0);
+ EXPECT_TRUE(response["result"]["port_count"] > 0);
+
+ EXPECT_TRUE(response["result"]["ports"].isArray());
+
+ const Json::Value &ports = response["result"]["ports"];
+
+
+ for (int i = 0; i < ports.size(); i++) {
+ EXPECT_TRUE(ports[i]["index"] == i);
+ EXPECT_TRUE(ports[i]["driver"].isString());
+ EXPECT_TRUE(ports[i]["speed"].isString());
+ }
+}
+
+/* get owner, acquire and release */
+TEST_F(RpcTest, get_owner_acquire_release) {
+ Json::Value request;
+ Json::Value response;
+
+ /* no user before acquring */
+ create_request(request, "get_owner");
+ request["params"]["port_id"] = 1;
+ send_request(request, response);
+ EXPECT_TRUE(response["result"] != Json::nullValue);
+
+ EXPECT_TRUE(response["result"]["owner"] == "none");
+
+ /* soft acquire */
+ create_request(request, "acquire");
+ request["params"]["port_id"] = 1;
+ request["params"]["user"] = "itay";
+ request["params"]["force"] = false;
+
+ send_request(request, response);
+ EXPECT_TRUE(response["result"] != Json::nullValue);
+
+ create_request(request, "get_owner");
+ request["params"]["port_id"] = 1;
+ send_request(request, response);
+ EXPECT_TRUE(response["result"] != Json::nullValue);
+
+ EXPECT_TRUE(response["result"]["owner"] == "itay");
+
+ /* hard acquire */
+ create_request(request, "acquire");
+ request["params"]["port_id"] = 1;
+ request["params"]["user"] = "moshe";
+ request["params"]["force"] = false;
+
+ send_request(request, response);
+ EXPECT_TRUE(response["result"] == Json::nullValue);
+
+ request["params"]["force"] = true;
+
+ send_request(request, response);
+ EXPECT_TRUE(response["result"] != Json::nullValue);
+
+ string handler = response["result"].asString();
+
+ /* make sure */
+ create_request(request, "get_owner");
+ request["params"]["port_id"] = 1;
+ send_request(request, response);
+ EXPECT_TRUE(response["result"] != Json::nullValue);
+
+ EXPECT_TRUE(response["result"]["owner"] == "moshe");
+
+ /* release */
+ create_request(request, "release");
+ request["params"]["port_id"] = 1;
+ request["params"]["handler"] = handler;
+ send_request(request, response);
+
+ EXPECT_TRUE(response["result"] == "ACK");
+}
+
+
+static void
+create_simple_stream(Json::Value &obj) {
+ obj["mode"]["type"] = "continuous";
+ obj["mode"]["pps"] = (rand() % 1000 + 1) * 0.99;
+ obj["isg"] = (rand() % 100 + 1) * 0.99;;
+ obj["enabled"] = true;
+ obj["self_start"] = true;
+ obj["next_stream_id"] = -1;
+
+ obj["packet"]["meta"] = "dummy";
+
+ int packet_size = (rand() % 1500 + 1);
+ for (int i = 0; i < packet_size; i++) {
+ obj["packet"]["binary"][i] = (rand() % 0xff);
+ }
+
+ obj["vm"] = Json::arrayValue;
+ obj["rx_stats"]["enabled"] = false;
+}
+
+static bool
+compare_streams(const Json::Value &s1, const Json::Value &s2) {
+ return s1 == s2;
+}
+
+TEST_F(RpcTestOwned, add_remove_stream) {
+ Json::Value request;
+ Json::Value response;
+
+ /* verify no such stream */
+ create_request(request, "get_stream", 1, 1);
+
+ request["params"]["stream_id"] = 5;
+
+ send_request(request, response);
- EXPECT_TRUE(reader.parse(resp_str, response, false));
EXPECT_EQ(response["jsonrpc"], "2.0");
EXPECT_EQ(response["id"], 1);
+ EXPECT_EQ(response["error"]["code"], -32000);
+
+ /* add it */
+ create_request(request, "add_stream", 1, 1);
+ request["params"]["stream_id"] = 5;
+
+ Json::Value stream;
+ create_simple_stream(stream);
+
+ request["params"]["stream"] = stream;
+ send_request(request, response);
+
+ EXPECT_EQ(response["result"], "ACK");
+
+ /* get it */
+ create_request(request, "get_stream", 1, 1);
+
+ request["params"]["stream_id"] = 5;
+
+ send_request(request, response);
+
+ EXPECT_TRUE(compare_streams(stream, response["result"]["stream"]));
+
+ // remove it
+ create_request(request, "remove_stream", 1, 1);
+
+ request["params"]["stream_id"] = 5;
+
+ send_request(request, response);
+
+ EXPECT_EQ(response["result"], "ACK");
+
+ // should not be present anymore
+ send_request(request, response);
EXPECT_EQ(response["error"]["code"], -32000);
- // add it
+}
- string add_str = "{\"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"add_stream\", \"params\":"
- "{\"port_id\":1, \"stream_id\":5, \"stream\":{"
- "\"mode\": {\"type\":\"continuous\", \"pps\":3},"
- "\"isg\":4.3, \"enabled\":true, \"self_start\":true,"
- "\"next_stream_id\":-1,"
- "\"packet\":{\"binary\":[4,1,255], \"meta\":\"dummy\"},"
- "\"vm\":[],"
- "\"rx_stats\":{\"enabled\":false}}}}";
- resp_str = send_msg(add_str);
+TEST_F(RpcTestOwned, get_stream_id_list) {
+ Json::Value request;
+ Json::Value response;
+
+ /* add stream 1 */
+ create_request(request, "add_stream", 1);
+ request["params"]["port_id"] = 1;
- EXPECT_TRUE(reader.parse(resp_str, response, false));
- EXPECT_EQ(response["jsonrpc"], "2.0");
- EXPECT_EQ(response["id"], 1);
+ Json::Value stream;
+ create_simple_stream(stream);
+
+ request["params"]["stream"] = stream;
+ request["params"]["stream_id"] = 5;
+ send_request(request, response);
EXPECT_EQ(response["result"], "ACK");
- resp_str = send_msg(lookup_str);
+ request["params"]["stream_id"] = 12;
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
- EXPECT_TRUE(reader.parse(resp_str, response, false));
- EXPECT_EQ(response["jsonrpc"], "2.0");
- EXPECT_EQ(response["id"], 1);
+ request["params"]["stream_id"] = 19;
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
- const Json::Value &stream = response["result"]["stream"];
- EXPECT_EQ(stream["enabled"], true);
- EXPECT_EQ(stream["self_start"], true);
+ create_request(request, "get_stream_list");
+ request["params"]["port_id"] = 1;
+ send_request(request, response);
- EXPECT_EQ(stream["packet"]["binary"][0], 4);
- EXPECT_EQ(stream["packet"]["binary"][1], 1);
- EXPECT_EQ(stream["packet"]["binary"][2], 255);
+ EXPECT_TRUE(response["result"].isArray());
+ vector<int> vec;
+ for (auto x : response["result"]) {
+ vec.push_back(x.asInt());
+ }
- EXPECT_EQ(stream["packet"]["meta"], "dummy");
- EXPECT_EQ(stream["next_stream_id"], -1);
+ sort(vec.begin(), vec.end());
- double delta = stream["isg"].asDouble() - 4.3;
- EXPECT_TRUE(delta < 0.0001);
+ EXPECT_EQ(vec[0], 5);
+ EXPECT_EQ(vec[1], 12);
+ EXPECT_EQ(vec[2], 19);
- EXPECT_EQ(stream["mode"]["type"], "continuous");
- EXPECT_EQ(stream["mode"]["pps"], 3);
+ create_request(request, "remove_all_streams");
+ request["params"]["port_id"] = 1;
+ send_request(request, response);
- // remove it
+ EXPECT_TRUE(response["result"] == "ACK");
- string remove_str = "{\"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"remove_stream\", \"params\":{\"port_id\":1, \"stream_id\":5}}";
- resp_str = send_msg(remove_str);
+ /* make sure the lights are off ... */
+ create_request(request, "get_stream_list");
+ request["params"]["port_id"] = 1;
+ send_request(request, response);
- EXPECT_TRUE(reader.parse(resp_str, response, false));
- EXPECT_EQ(response["jsonrpc"], "2.0");
- EXPECT_EQ(response["id"], 1);
+ EXPECT_TRUE(response["result"].isArray());
+ EXPECT_TRUE(response["result"].size() == 0);
+}
+
+
+TEST_F(RpcTestOwned, start_stop_traffic) {
+ Json::Value request;
+ Json::Value response;
+ /* add stream #1 */
+ create_request(request, "add_stream", 1, 1);
+ request["params"]["stream_id"] = 5;
+
+ Json::Value stream;
+ create_simple_stream(stream);
+
+ request["params"]["stream"] = stream;
+
+ send_request(request, response);
EXPECT_EQ(response["result"], "ACK");
- resp_str = send_msg(remove_str);
+ /* add stream #1 */
+ create_request(request, "add_stream", 1, 3);
+ request["params"]["stream_id"] = 12;
+ request["params"]["stream"] = stream;
+
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
- // should not be present anymore
+ /* start port 1 */
+ create_request(request, "start_traffic", 1, 1);
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
- EXPECT_TRUE(reader.parse(resp_str, response, false));
- EXPECT_EQ(response["jsonrpc"], "2.0");
- EXPECT_EQ(response["id"], 1);
+ /* start port 3 */
+ create_request(request, "start_traffic", 1, 3);
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
+
+ /* start not configured port */
+ create_request(request, "start_traffic", 1, 2);
+ send_request(request, response);
EXPECT_EQ(response["error"]["code"], -32000);
-}
+ /* stop port 1 */
+ create_request(request, "stop_traffic", 1, 1);
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
+ /* stop port 3 */
+ create_request(request, "stop_traffic", 1, 3);
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
+
+ /* start 1 again */
+ create_request(request, "start_traffic", 1, 1);
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
+ /* start 1 twice (error) */
+ create_request(request, "start_traffic", 1, 1);
+ send_request(request, response);
+ EXPECT_EQ(response["error"]["code"], -32000);
+
+ /* make sure you cannot release while traffic is active */
+ create_request(request, "release", 1, 1);
+ send_request(request, response);
+ EXPECT_EQ(response["error"]["code"], -32000);
+
+ /* stop traffic on port #1 */
+ create_request(request, "stop_traffic",1 ,1);
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
+
+ /* release */
+ create_request(request, "release", 1, 1);
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
+}
diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp
new file mode 100644
index 00000000..0341516c
--- /dev/null
+++ b/src/gtest/trex_stateless_gtest.cpp
@@ -0,0 +1,353 @@
+/*
+ Hanoh Haim
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include "bp_sim.h"
+#include <common/gtest.h>
+#include <common/basic_utils.h>
+
+
+#define EXPECT_EQ_UINT32(a,b) EXPECT_EQ((uint32_t)(a),(uint32_t)(b))
+
+// one stream info with const packet , no VM
+class CTRexDpStatelessVM {
+
+};
+
+//- add dump function
+// - check one object
+// create frame work
+
+class CTRexDpStreamModeContinues{
+public:
+ void set_pps(double pps){
+ m_pps=pps;
+ }
+ double get_pps(){
+ return (m_pps);
+ }
+
+ void dump(FILE *fd);
+private:
+ double m_pps;
+};
+
+
+void CTRexDpStreamModeContinues::dump(FILE *fd){
+ fprintf (fd," pps : %f \n",m_pps);
+}
+
+
+class CTRexDpStreamModeSingleBurst{
+public:
+ void set_pps(double pps){
+ m_pps=pps;
+ }
+ double get_pps(){
+ return (m_pps);
+ }
+
+ void set_total_packets(uint64_t total_packets){
+ m_total_packets =total_packets;
+ }
+
+ uint64_t get_total_packets(){
+ return (m_total_packets);
+ }
+
+ void dump(FILE *fd);
+
+private:
+ double m_pps;
+ uint64_t m_total_packets;
+};
+
+
+void CTRexDpStreamModeSingleBurst::dump(FILE *fd){
+ fprintf (fd," pps : %f \n",m_pps);
+ fprintf (fd," total_packets : %llu \n",m_total_packets);
+}
+
+
+class CTRexDpStreamModeMultiBurst{
+public:
+ void set_pps(double pps){
+ m_pps=pps;
+ }
+ double get_pps(){
+ return (m_pps);
+ }
+
+ void set_pkts_per_burst(uint64_t pkts_per_burst){
+ m_pkts_per_burst =pkts_per_burst;
+ }
+
+ uint64_t get_pkts_per_burst(){
+ return (m_pkts_per_burst);
+ }
+
+ void set_ibg(double ibg){
+ m_ibg = ibg;
+ }
+
+ double get_ibg(){
+ return ( m_ibg );
+ }
+
+ void set_number_of_bursts(uint32_t number_of_bursts){
+ m_number_of_bursts = number_of_bursts;
+ }
+
+ uint32_t get_number_of_bursts(){
+ return (m_number_of_bursts);
+ }
+
+ void dump(FILE *fd);
+
+private:
+ double m_pps;
+ double m_ibg; // inter burst gap
+ uint64_t m_pkts_per_burst;
+ uint32_t m_number_of_bursts;
+};
+
+void CTRexDpStreamModeMultiBurst::dump(FILE *fd){
+ fprintf (fd," pps : %f \n",m_pps);
+ fprintf (fd," total_packets : %llu \n",m_pkts_per_burst);
+ fprintf (fd," ibg : %f \n",m_ibg);
+ fprintf (fd," num_of_bursts : %llu \n",m_number_of_bursts);
+}
+
+
+
+class CTRexDpStreamMode {
+public:
+ enum MODES {
+ moCONTINUES = 0x0,
+ moSINGLE_BURST = 0x1,
+ moMULTI_BURST = 0x2
+ } ;
+ typedef uint8_t MODE_TYPE_t;
+
+ void reset();
+
+ void set_mode(MODE_TYPE_t mode ){
+ m_type = mode;
+ }
+
+ MODE_TYPE_t get_mode(){
+ return (m_type);
+ }
+
+
+ CTRexDpStreamModeContinues & cont(void){
+ return (m_data.m_cont);
+ }
+ CTRexDpStreamModeSingleBurst & single_burst(void){
+ return (m_data.m_signle_burst);
+ }
+
+ CTRexDpStreamModeMultiBurst & multi_burst(void){
+ return (m_data.m_multi_burst);
+ }
+
+ void dump(FILE *fd);
+
+private:
+ uint8_t m_type;
+ union Data {
+ CTRexDpStreamModeContinues m_cont;
+ CTRexDpStreamModeSingleBurst m_signle_burst;
+ CTRexDpStreamModeMultiBurst m_multi_burst;
+ } m_data;
+};
+
+
+void CTRexDpStreamMode::reset(){
+ m_type =CTRexDpStreamMode::moCONTINUES;
+ memset(&m_data,0,sizeof(m_data));
+}
+
+void CTRexDpStreamMode::dump(FILE *fd){
+ const char * table[3] = {"CONTINUES","SINGLE_BURST","MULTI_BURST"};
+
+ fprintf(fd," mode : %s \n", (char*)table[m_type]);
+ switch (m_type) {
+ case CTRexDpStreamMode::moCONTINUES :
+ cont().dump(fd);
+ break;
+ case CTRexDpStreamMode::moSINGLE_BURST :
+ single_burst().dump(fd);
+ break;
+ case CTRexDpStreamMode::moMULTI_BURST :
+ multi_burst().dump(fd);
+ break;
+ default:
+ fprintf(fd," ERROR type if not valid %d \n",m_type);
+ break;
+ }
+}
+
+
+
+
+class CTRexDpStatelessStream {
+
+public:
+ enum FLAGS_0{
+ _ENABLE = 0,
+ _SELF_START = 1,
+ _VM_ENABLE =2,
+ _END_STREAM =-1
+ };
+
+ CTRexDpStatelessStream(){
+ reset();
+ }
+
+ void reset(){
+ m_packet =0;
+ m_vm=0;
+ m_flags=0;
+ m_isg_sec=0.0;
+ m_next_stream = CTRexDpStatelessStream::_END_STREAM ; // END
+ m_mode.reset();
+ }
+
+ void set_enable(bool enable){
+ btSetMaskBit32(m_flags,_ENABLE,_ENABLE,enable?1:0);
+ }
+
+ bool get_enabled(){
+ return (btGetMaskBit32(m_flags,_ENABLE,_ENABLE)?true:false);
+ }
+
+ void set_self_start(bool enable){
+ btSetMaskBit32(m_flags,_SELF_START,_SELF_START,enable?1:0);
+ }
+
+ bool get_self_start(bool enable){
+ return (btGetMaskBit32(m_flags,_SELF_START,_SELF_START)?true:false);
+ }
+
+
+ /* if we don't have VM we could just replicate the mbuf and allocate it once */
+ void set_vm_enable(bool enable){
+ btSetMaskBit32(m_flags,_VM_ENABLE,_VM_ENABLE,enable?1:0);
+ }
+
+ bool get_vm_enabled(bool enable){
+ return (btGetMaskBit32(m_flags,_VM_ENABLE,_VM_ENABLE)?true:false);
+ }
+
+ void set_inter_stream_gap(double isg_sec){
+ m_isg_sec =isg_sec;
+ }
+
+ double get_inter_stream_gap(){
+ return (m_isg_sec);
+ }
+
+ CTRexDpStreamMode & get_mode();
+
+
+ // CTRexDpStatelessStream::_END_STREAM for END
+ void set_next_stream(int32_t next_stream){
+ m_next_stream =next_stream;
+ }
+
+ int32_t get_next_stream(void){
+ return ( m_next_stream );
+ }
+
+ void dump(FILE *fd);
+
+private:
+ char * m_packet;
+ CTRexDpStatelessVM * m_vm;
+ uint32_t m_flags;
+ double m_isg_sec; // in second
+ CTRexDpStreamMode m_mode;
+ int32_t m_next_stream; // next stream id
+};
+
+//- list of streams info with const packet , no VM
+// - object that include the stream /scheduler/ packet allocation / need to create an object for one thread that works for test
+// generate pcap file and compare it
+
+#if 0
+void CTRexDpStatelessStream::dump(FILE *fd){
+
+ fprintf(fd," enabled : %d \n",get_enabled()?1:0);
+ fprintf(fd," self_start : %d \n",get_self_start()?1:0);
+ fprintf(fd," vm : %d \n",get_vm_enabled()?1:0);
+ fprintf(" isg : %f \n",m_isg_sec);
+ m_mode.dump(fd);
+ if (m_next_stream == CTRexDpStatelessStream::_END_STREAM ) {
+ fprintf(fd," action : End of Stream \n");
+ }else{
+ fprintf(" next : %d \n",m_next_stream);
+ }
+}
+
+
+
+class CTRexStatelessBasic {
+
+public:
+ CTRexStatelessBasic(){
+ m_threads=1;
+ }
+
+ bool init(void){
+ return (true);
+ }
+
+public:
+ bool m_threads;
+};
+
+
+/* stateless basic */
+class dp_sl_basic : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ }
+ virtual void TearDown() {
+ }
+public:
+};
+
+
+
+TEST_F(dp_sl_basic, test1) {
+ CTRexDpStatelessStream s1;
+ s1.set_enable(true);
+ s1.set_self_start(true);
+ s1.set_inter_stream_gap(0.77);
+ s1.get_mode().set_mode(CTRexDpStreamMode::moCONTINUES);
+ s1.get_mode().cont().set_pps(100.2);
+ s1.dump(stdout);
+}
+
+
+
+
+#endif
diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
index 32952b1a..106a167a 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
@@ -18,9 +18,15 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
+
#include "trex_rpc_cmds.h"
#include <trex_rpc_server_api.h>
#include <trex_stateless_api.h>
+#include <trex_rpc_cmds_table.h>
+
+#include <fstream>
+#include <iostream>
+#include <unistd.h>
#ifndef TREX_RPC_MOCK_SERVER
#include <../linux_dpdk/version.h>
@@ -29,37 +35,233 @@ limitations under the License.
using namespace std;
/**
- * get status
+ * ping command
+ */
+trex_rpc_cmd_rc_e
+TrexRpcCmdPing::_run(const Json::Value &params, Json::Value &result) {
+
+ result["result"] = "ACK";
+ return (TREX_RPC_CMD_OK);
+}
+
+/**
+ * query command
+ */
+trex_rpc_cmd_rc_e
+TrexRpcCmdGetCmds::_run(const Json::Value &params, Json::Value &result) {
+ vector<string> cmds;
+
+ TrexRpcCommandsTable::get_instance().query(cmds);
+
+ Json::Value test = Json::arrayValue;
+ for (auto cmd : cmds) {
+ test.append(cmd);
+ }
+
+ result["result"] = test;
+
+ return (TREX_RPC_CMD_OK);
+}
+
+/**
+ * get version
*
*/
trex_rpc_cmd_rc_e
-TrexRpcCmdGetStatus::_run(const Json::Value &params, Json::Value &result) {
+TrexRpcCmdGetVersion::_run(const Json::Value &params, Json::Value &result) {
Json::Value &section = result["result"];
#ifndef TREX_RPC_MOCK_SERVER
- section["general"]["version"] = VERSION_BUILD_NUM;
- section["general"]["build_date"] = get_build_date();
- section["general"]["build_time"] = get_build_time();
- section["general"]["built_by"] = VERSION_USER;
+ section["version"] = VERSION_BUILD_NUM;
+ section["build_date"] = get_build_date();
+ section["build_time"] = get_build_time();
+ section["built_by"] = VERSION_USER;
#else
- section["general"]["version"] = "v0.0";
- section["general"]["build_date"] = __DATE__;
- section["general"]["build_time"] = __TIME__;
- section["general"]["version_user"] = "MOCK";
+ section["version"] = "v0.0";
+ section["build_date"] = __DATE__;
+ section["build_time"] = __TIME__;
+ section["built_by"] = "MOCK";
#endif
- section["general"]["uptime"] = TrexRpcServer::get_server_uptime();
- section["general"]["owner"] = TrexRpcServer::get_owner();
+ return (TREX_RPC_CMD_OK);
+}
+
+/**
+ * get the CPU model
+ *
+ */
+std::string
+TrexRpcCmdGetSysInfo::get_cpu_model() {
+
+ static const string cpu_prefix = "model name";
+ std::ifstream cpuinfo("/proc/cpuinfo");
+
+ if (cpuinfo.is_open()) {
+ while (cpuinfo.good()) {
+
+ std::string line;
+ getline(cpuinfo, line);
+
+ int pos = line.find(cpu_prefix);
+ if (pos == string::npos) {
+ continue;
+ }
+
+ /* trim it */
+ int index = cpu_prefix.size() + 1;
+ while ( (line[index] == ' ') || (line[index] == ':') ) {
+ index++;
+ }
+
+ return line.substr(index);
+ }
+ }
+
+ return "unknown";
+}
+
+void
+TrexRpcCmdGetSysInfo::get_hostname(string &hostname) {
+ char buffer[256];
+ buffer[0] = 0;
+
+ gethostname(buffer, sizeof(buffer));
+
+ /* write hostname */
+ hostname = buffer;
+}
+
+/**
+ * get system info
+ *
+ */
+trex_rpc_cmd_rc_e
+TrexRpcCmdGetSysInfo::_run(const Json::Value &params, Json::Value &result) {
+ string hostname;
+
+ TrexStateless & instance = TrexStateless::get_instance();
+
+ Json::Value &section = result["result"];
+
+ get_hostname(hostname);
+ section["hostname"] = hostname;
+
+ section["uptime"] = TrexRpcServer::get_server_uptime();
+
+ /* FIXME: core count */
+ section["dp_core_count"] = 1;
+ section["core_type"] = get_cpu_model();
+
+ /* ports */
+
- // ports
+ section["port_count"] = instance.get_port_count();
- section["ports"]["count"] = TrexStateless::get_instance().get_port_count();
+ section["ports"] = Json::arrayValue;
+
+ for (int i = 0; i < instance.get_port_count(); i++) {
+ string driver;
+ string speed;
+
+ TrexStatelessPort *port = instance.get_port_by_id(i);
+ port->get_properties(driver, speed);
+
+ section["ports"][i]["index"] = i;
+ section["ports"][i]["driver"] = driver;
+ section["ports"][i]["speed"] = speed;
+
+ section["ports"][i]["owner"] = port->get_owner();
+
+ switch (port->get_state()) {
+ case TrexStatelessPort::PORT_STATE_DOWN:
+ section["ports"][i]["status"] = "down";
+ break;
+
+ case TrexStatelessPort::PORT_STATE_UP_IDLE:
+ section["ports"][i]["status"] = "idle";
+ break;
+
+ case TrexStatelessPort::PORT_STATE_TRANSMITTING:
+ section["ports"][i]["status"] = "transmitting";
+ break;
+ }
+
+ }
+
+ return (TREX_RPC_CMD_OK);
+}
+
+/**
+ * returns the current owner of the device
+ *
+ * @author imarom (08-Sep-15)
+ *
+ * @param params
+ * @param result
+ *
+ * @return trex_rpc_cmd_rc_e
+ */
+trex_rpc_cmd_rc_e
+TrexRpcCmdGetOwner::_run(const Json::Value &params, Json::Value &result) {
+ Json::Value &section = result["result"];
+
+ uint8_t port_id = parse_port(params, result);
+
+ TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id);
+ section["owner"] = port->get_owner();
return (TREX_RPC_CMD_OK);
}
+/**
+ * acquire device
+ *
+ */
+trex_rpc_cmd_rc_e
+TrexRpcCmdAcquire::_run(const Json::Value &params, Json::Value &result) {
+
+ uint8_t port_id = parse_port(params, result);
+
+ const string &new_owner = parse_string(params, "user", result);
+ bool force = parse_bool(params, "force", result);
+
+ /* if not free and not you and not force - fail */
+ TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id);
+
+ if ( (!port->is_free_to_aquire()) && (port->get_owner() != new_owner) && (!force)) {
+ generate_execute_err(result, "device is already taken by '" + port->get_owner() + "'");
+ }
+
+ port->set_owner(new_owner);
+
+ result["result"] = port->get_owner_handler();
+
+ return (TREX_RPC_CMD_OK);
+}
+
+/**
+ * release device
+ *
+ */
+trex_rpc_cmd_rc_e
+TrexRpcCmdRelease::_run(const Json::Value &params, Json::Value &result) {
+
+ uint8_t port_id = parse_port(params, result);
+
+ TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id);
+
+ if (port->get_state() == TrexStatelessPort::PORT_STATE_TRANSMITTING) {
+ generate_execute_err(result, "cannot release a port during transmission");
+ }
+
+ port->clear_owner();
+
+ result["result"] = "ACK";
+
+ return (TREX_RPC_CMD_OK);
+}
diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
index 90b55ea8..1450e1a9 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
@@ -63,6 +63,9 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
/* allocate a new stream based on the type */
TrexStream *stream = allocate_new_stream(section, port_id, stream_id, result);
+ /* save this for future queries */
+ stream->store_stream_json(section);
+
/* some fields */
stream->m_enabled = parse_bool(section, "enabled", result);
stream->m_self_start = parse_bool(section, "self_start", result);
@@ -130,19 +133,19 @@ TrexRpcCmdAddStream::allocate_new_stream(const Json::Value &section, uint8_t por
if (type == "continuous") {
- uint32_t pps = parse_int(mode, "pps", result);
+ double pps = parse_double(mode, "pps", result);
stream = new TrexStreamContinuous(port_id, stream_id, pps);
} else if (type == "single_burst") {
uint32_t total_pkts = parse_int(mode, "total_pkts", result);
- uint32_t pps = parse_int(mode, "pps", result);
+ double pps = parse_double(mode, "pps", result);
stream = new TrexStreamBurst(port_id, stream_id, total_pkts, pps);
} else if (type == "multi_burst") {
- uint32_t pps = parse_int(mode, "pps", result);
+ double pps = parse_double(mode, "pps", result);
double ibg_usec = parse_double(mode, "ibg", result);
uint32_t num_bursts = parse_int(mode, "number_of_bursts", result);
uint32_t pkts_per_burst = parse_int(mode, "pkts_per_burst", result);
@@ -413,30 +416,11 @@ TrexRpcCmdGetStream::_run(const Json::Value &params, Json::Value &result) {
generate_execute_err(result, ss.str());
}
- Json::Value stream_json;
-
- stream_json["enabled"] = stream->m_enabled;
- stream_json["self_start"] = stream->m_self_start;
-
- stream_json["isg"] = stream->m_isg_usec;
- stream_json["next_stream_id"] = stream->m_next_stream_id;
-
- stream_json["packet"]["binary"] = Json::arrayValue;
- for (int i = 0; i < stream->m_pkt.len; i++) {
- stream_json["packet"]["binary"].append(stream->m_pkt.binary[i]);
- }
-
- stream_json["packet"]["meta"] = stream->m_pkt.meta;
-
- if (TrexStreamContinuous *cont = dynamic_cast<TrexStreamContinuous *>(stream)) {
- stream_json["mode"]["type"] = "continuous";
- stream_json["mode"]["pps"] = cont->get_pps();
-
- }
-
- result["result"]["stream"] = stream_json;
+ /* return the stored stream json (instead of decoding it all over again) */
+ result["result"]["stream"] = stream->get_stream_json();
return (TREX_RPC_CMD_OK);
+
}
/***************************
@@ -445,7 +429,8 @@ TrexRpcCmdGetStream::_run(const Json::Value &params, Json::Value &result) {
**************************/
trex_rpc_cmd_rc_e
TrexRpcCmdStartTraffic::_run(const Json::Value &params, Json::Value &result) {
- uint8_t port_id = parse_byte(params, "port_id", result);
+
+ uint8_t port_id = parse_byte(params, "port_id", result);
if (port_id >= TrexStateless::get_instance().get_port_count()) {
std::stringstream ss;
@@ -455,17 +440,17 @@ TrexRpcCmdStartTraffic::_run(const Json::Value &params, Json::Value &result) {
TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id);
- TrexStatelessPort::traffic_rc_e rc = port->start_traffic();
+ TrexStatelessPort::rc_e rc = port->start_traffic();
- if (rc == TrexStatelessPort::TRAFFIC_OK) {
+ if (rc == TrexStatelessPort::RC_OK) {
result["result"] = "ACK";
} else {
std::stringstream ss;
switch (rc) {
- case TrexStatelessPort::TRAFFIC_ERR_ALREADY_STARTED:
- ss << "traffic has already started on that port";
+ case TrexStatelessPort::RC_ERR_BAD_STATE_FOR_OP:
+ ss << "bad state for operations: port is either transmitting traffic or down";
break;
- case TrexStatelessPort::TRAFFIC_ERR_NO_STREAMS:
+ case TrexStatelessPort::RC_ERR_NO_STREAMS:
ss << "no active streams on that port";
break;
default:
diff --git a/src/rpc-server/commands/trex_rpc_cmd_test.cpp b/src/rpc-server/commands/trex_rpc_cmd_test.cpp
index 3153317e..3cdddd31 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_test.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_test.cpp
@@ -21,7 +21,6 @@ limitations under the License.
#include "trex_rpc_cmds.h"
#include <iostream>
#include <sstream>
-#include <trex_rpc_cmds_table.h>
using namespace std;
@@ -50,32 +49,3 @@ TrexRpcCmdTestSub::_run(const Json::Value &params, Json::Value &result) {
return (TREX_RPC_CMD_OK);
}
-/**
- * ping command
- */
-trex_rpc_cmd_rc_e
-TrexRpcCmdPing::_run(const Json::Value &params, Json::Value &result) {
-
- result["result"] = "ACK";
- return (TREX_RPC_CMD_OK);
-}
-
-/**
- * query command
- */
-trex_rpc_cmd_rc_e
-TrexRpcCmdGetReg::_run(const Json::Value &params, Json::Value &result) {
- vector<string> cmds;
-
- TrexRpcCommandsTable::get_instance().query(cmds);
-
- Json::Value test = Json::arrayValue;
- for (auto cmd : cmds) {
- test.append(cmd);
- }
-
- result["result"] = test;
-
- return (TREX_RPC_CMD_OK);
-}
-
diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h
index f88631bc..e261d1c6 100644
--- a/src/rpc-server/commands/trex_rpc_cmds.h
+++ b/src/rpc-server/commands/trex_rpc_cmds.h
@@ -35,37 +35,52 @@ class TrexStream;
* syntactic sugar for creating a simple command
*/
-#define TREX_RPC_CMD_DEFINE_EXTENED(class_name, cmd_name, param_count, ext) \
+#define TREX_RPC_CMD_DEFINE_EXTENDED(class_name, cmd_name, param_count, needs_ownership, ext) \
class class_name : public TrexRpcCommand { \
public: \
- class_name () : TrexRpcCommand(cmd_name, param_count) {} \
+ class_name () : TrexRpcCommand(cmd_name, param_count, needs_ownership) {} \
protected: \
virtual trex_rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result); \
ext \
}
-#define TREX_RPC_CMD_DEFINE(class_name, cmd_name, param_count) TREX_RPC_CMD_DEFINE_EXTENED(class_name, cmd_name, param_count, ;)
+#define TREX_RPC_CMD_DEFINE(class_name, cmd_name, param_count, needs_ownership) TREX_RPC_CMD_DEFINE_EXTENDED(class_name, cmd_name, param_count, needs_ownership, ;)
/**
* test cmds
*/
-TREX_RPC_CMD_DEFINE(TrexRpcCmdTestAdd, "test_add", 2);
-TREX_RPC_CMD_DEFINE(TrexRpcCmdTestSub, "test_sub", 2);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdTestAdd, "test_add", 2, false);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdTestSub, "test_sub", 2, false);
/**
* general cmds
*/
-TREX_RPC_CMD_DEFINE(TrexRpcCmdPing, "ping", 0);
-TREX_RPC_CMD_DEFINE(TrexRpcCmdGetReg, "get_reg_cmds", 0);
-TREX_RPC_CMD_DEFINE(TrexRpcCmdGetStatus, "get_status", 0);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdPing, "ping", 0, false);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdGetCmds, "get_supported_cmds", 0, false);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdGetVersion, "get_version", 0, false);
+
+TREX_RPC_CMD_DEFINE_EXTENDED(TrexRpcCmdGetSysInfo, "get_system_info", 0, false,
+
+std::string get_cpu_model();
+void get_hostname(std::string &hostname);
+
+);
+
+/**
+ * ownership
+ */
+TREX_RPC_CMD_DEFINE(TrexRpcCmdGetOwner, "get_owner", 1, false);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdAcquire, "acquire", 3, false);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdRelease, "release", 1, true);
+
/**
* stream cmds
*/
-TREX_RPC_CMD_DEFINE(TrexRpcCmdRemoveAllStreams, "remove_all_streams", 1);
-TREX_RPC_CMD_DEFINE(TrexRpcCmdRemoveStream, "remove_stream", 2);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdRemoveAllStreams, "remove_all_streams", 1, true);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdRemoveStream, "remove_stream", 2, true);
-TREX_RPC_CMD_DEFINE_EXTENED(TrexRpcCmdAddStream, "add_stream", 3,
+TREX_RPC_CMD_DEFINE_EXTENDED(TrexRpcCmdAddStream, "add_stream", 3, true,
/* extended part */
TrexStream * allocate_new_stream(const Json::Value &section, uint8_t port_id, uint32_t stream_id, Json::Value &result);
@@ -77,11 +92,13 @@ void parse_vm_instr_write_flow_var(const Json::Value &inst, TrexStream *stream,
);
-TREX_RPC_CMD_DEFINE(TrexRpcCmdGetStreamList, "get_stream_list", 1);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdGetStreamList, "get_stream_list", 1, true);
+
+TREX_RPC_CMD_DEFINE(TrexRpcCmdGetStream, "get_stream", 2, true);
+
+TREX_RPC_CMD_DEFINE(TrexRpcCmdStartTraffic, "start_traffic", 1, true);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdStopTraffic, "stop_traffic", 1, true);
-TREX_RPC_CMD_DEFINE(TrexRpcCmdGetStream, "get_stream", 2);
-TREX_RPC_CMD_DEFINE(TrexRpcCmdStartTraffic, "start_traffic", 1);
-TREX_RPC_CMD_DEFINE(TrexRpcCmdStopTraffic, "stop_traffic", 1);
#endif /* __TREX_RPC_CMD_H__ */
diff --git a/src/rpc-server/trex_rpc_cmd.cpp b/src/rpc-server/trex_rpc_cmd.cpp
index 3fc77f71..6c355e70 100644
--- a/src/rpc-server/trex_rpc_cmd.cpp
+++ b/src/rpc-server/trex_rpc_cmd.cpp
@@ -19,6 +19,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
#include <trex_rpc_cmd_api.h>
+#include <trex_rpc_server_api.h>
+#include <trex_stateless_api.h>
trex_rpc_cmd_rc_e
TrexRpcCommand::run(const Json::Value &params, Json::Value &result) {
@@ -26,8 +28,16 @@ TrexRpcCommand::run(const Json::Value &params, Json::Value &result) {
/* the internal run can throw a parser error / other error */
try {
+
check_param_count(params, m_param_count, result);
+
+ if (m_needs_ownership) {
+ verify_ownership(params, result);
+ }
+
+ /* run the command itself*/
rc = _run(params, result);
+
} catch (TrexRpcCommandException &e) {
return e.get_rc();
}
@@ -45,6 +55,35 @@ TrexRpcCommand::check_param_count(const Json::Value &params, int expected, Json:
}
}
+void
+TrexRpcCommand::verify_ownership(const Json::Value &params, Json::Value &result) {
+ std::string handler = parse_string(params, "handler", result);
+ uint8_t port_id = parse_port(params, result);
+
+ TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id);
+
+ if (!port->verify_owner_handler(handler)) {
+ generate_execute_err(result, "invalid handler provided. please pass the handler given when calling 'acquire' or take ownership");
+ }
+}
+
+uint8_t
+TrexRpcCommand::parse_port(const Json::Value &params, Json::Value &result) {
+ uint8_t port_id = parse_byte(params, "port_id", result);
+ validate_port_id(port_id, result);
+
+ return (port_id);
+}
+
+void
+TrexRpcCommand::validate_port_id(uint8_t port_id, Json::Value &result) {
+ if (port_id >= TrexStateless::get_instance().get_port_count()) {
+ std::stringstream ss;
+ ss << "invalid port id - should be between 0 and " << (int)TrexStateless::get_instance().get_port_count() - 1;
+ generate_execute_err(result, ss.str());
+ }
+}
+
const char *
TrexRpcCommand::type_to_str(field_type_e type) {
switch (type) {
diff --git a/src/rpc-server/trex_rpc_cmd_api.h b/src/rpc-server/trex_rpc_cmd_api.h
index def52fca..3c718eaa 100644
--- a/src/rpc-server/trex_rpc_cmd_api.h
+++ b/src/rpc-server/trex_rpc_cmd_api.h
@@ -68,8 +68,15 @@ public:
/**
* method name and params
*/
- TrexRpcCommand(const std::string &method_name, int param_count) : m_name(method_name), m_param_count(param_count) {
-
+ TrexRpcCommand(const std::string &method_name, int param_count, bool needs_ownership) :
+ m_name(method_name),
+ m_param_count(param_count),
+ m_needs_ownership(needs_ownership) {
+
+ /* if needs ownership - another field is needed (handler) */
+ if (m_needs_ownership) {
+ m_param_count++;
+ }
}
/**
@@ -112,6 +119,18 @@ protected:
void check_param_count(const Json::Value &params, int expected, Json::Value &result);
/**
+ * verify ownership
+ *
+ */
+ void verify_ownership(const Json::Value &params, Json::Value &result);
+
+ /**
+ * validate port id
+ *
+ */
+ void validate_port_id(uint8_t port_id, Json::Value &result);
+
+ /**
* parse functions
*
*/
@@ -133,6 +152,9 @@ protected:
const Json::Value & parse_object(const Json::Value &parent, int index, Json::Value &result);
const Json::Value & parse_array(const Json::Value &parent, int index, Json::Value &result);
+ /* shortcut for parsing port id */
+ uint8_t parse_port(const Json::Value &params, Json::Value &result);
+
/**
* parse a field from choices
*
@@ -164,6 +186,9 @@ protected:
s.pop_back();
s += "]";
generate_parse_err(result, s);
+
+ /* dummy return value - does not matter, the above will throw exception */
+ return (*choices.begin());
}
/**
@@ -209,6 +234,7 @@ protected:
/* RPC command name */
std::string m_name;
int m_param_count;
+ bool m_needs_ownership;
};
#endif /* __TREX_RPC_CMD_API_H__ */
diff --git a/src/rpc-server/trex_rpc_cmds_table.cpp b/src/rpc-server/trex_rpc_cmds_table.cpp
index 71668994..170f0de1 100644
--- a/src/rpc-server/trex_rpc_cmds_table.cpp
+++ b/src/rpc-server/trex_rpc_cmds_table.cpp
@@ -30,9 +30,16 @@ TrexRpcCommandsTable::TrexRpcCommandsTable() {
/* add the test command (for gtest) */
register_command(new TrexRpcCmdTestAdd());
register_command(new TrexRpcCmdTestSub());
+
+
+ /* general */
register_command(new TrexRpcCmdPing());
- register_command(new TrexRpcCmdGetReg());
- register_command(new TrexRpcCmdGetStatus());
+ register_command(new TrexRpcCmdGetCmds());
+ register_command(new TrexRpcCmdGetVersion());
+ register_command(new TrexRpcCmdGetSysInfo());
+ register_command(new TrexRpcCmdGetOwner());
+ register_command(new TrexRpcCmdAcquire());
+ register_command(new TrexRpcCmdRelease());
/* stream commands */
register_command(new TrexRpcCmdAddStream());
diff --git a/src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp b/src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp
index 928baca6..9d9de53a 100644
--- a/src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp
+++ b/src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp
@@ -225,3 +225,11 @@ std::string TrexJsonRpcV2Parser::pretty_json_str(const std::string &json_str) {
return writer.write(value);
}
+void
+TrexJsonRpcV2Parser::generate_common_error(Json::Value &json, const std::string &specific_err) {
+ JsonRpcError err(Json::Value::null, JSONRPC_V2_ERR_INTERNAL_ERROR, specific_err, true);
+
+ err.execute(json);
+
+}
+
diff --git a/src/rpc-server/trex_rpc_jsonrpc_v2_parser.h b/src/rpc-server/trex_rpc_jsonrpc_v2_parser.h
index ebffaeb7..0563f21d 100644
--- a/src/rpc-server/trex_rpc_jsonrpc_v2_parser.h
+++ b/src/rpc-server/trex_rpc_jsonrpc_v2_parser.h
@@ -80,6 +80,15 @@ public:
void parse(std::vector<TrexJsonRpcV2ParsedObject *> &commands);
/**
+ * will generate a valid JSON RPC v2 error message with
+ * generic error code and message
+ *
+ * @author imarom (16-Sep-15)
+ *
+ */
+ static void generate_common_error(Json::Value &json, const std::string &specific_err);
+
+ /**
* *tries* to generate a pretty string from JSON
* if json_str is not a valid JSON string
* it will duplicate the source
diff --git a/src/rpc-server/trex_rpc_req_resp_server.cpp b/src/rpc-server/trex_rpc_req_resp_server.cpp
index c4d9dfdb..3d52686c 100644
--- a/src/rpc-server/trex_rpc_req_resp_server.cpp
+++ b/src/rpc-server/trex_rpc_req_resp_server.cpp
@@ -82,6 +82,13 @@ void TrexRpcServerReqRes::_rpc_thread_cb() {
}
}
+ if (msg_size >= sizeof(m_msg_buffer)) {
+ std::stringstream ss;
+ ss << "RPC request of '" << msg_size << "' exceeds maximum message size which is '" << sizeof(m_msg_buffer) << "'";
+ handle_server_error(ss.str());
+ continue;
+ }
+
/* transform it to a string */
std::string request((const char *)m_msg_buffer, msg_size);
@@ -145,3 +152,23 @@ void TrexRpcServerReqRes::handle_request(const std::string &request) {
zmq_send(m_socket, response_str.c_str(), response_str.size(), 0);
}
+
+/**
+ * handles a server error
+ *
+ */
+void
+TrexRpcServerReqRes::handle_server_error(const std::string &specific_err) {
+ Json::FastWriter writer;
+ Json::Value response;
+
+ /* generate error */
+ TrexJsonRpcV2Parser::generate_common_error(response, specific_err);
+
+ /* write the JSON to string and sever on ZMQ */
+ std::string response_str = writer.write(response);
+
+ verbose_json("Server Replied: ", response_str);
+
+ zmq_send(m_socket, response_str.c_str(), response_str.size(), 0);
+}
diff --git a/src/rpc-server/trex_rpc_req_resp_server.h b/src/rpc-server/trex_rpc_req_resp_server.h
index f12d0540..7c1d66d1 100644
--- a/src/rpc-server/trex_rpc_req_resp_server.h
+++ b/src/rpc-server/trex_rpc_req_resp_server.h
@@ -39,9 +39,11 @@ protected:
void _stop_rpc_thread();
private:
+
void handle_request(const std::string &request);
+ void handle_server_error(const std::string &specific_err);
- static const int RPC_MAX_MSG_SIZE = 2048;
+ static const int RPC_MAX_MSG_SIZE = (20 * 1024);
void *m_context;
void *m_socket;
uint8_t m_msg_buffer[RPC_MAX_MSG_SIZE];
diff --git a/src/rpc-server/trex_rpc_server.cpp b/src/rpc-server/trex_rpc_server.cpp
index 149bb668..6b8c200d 100644
--- a/src/rpc-server/trex_rpc_server.cpp
+++ b/src/rpc-server/trex_rpc_server.cpp
@@ -111,7 +111,6 @@ get_current_date_time() {
}
const std::string TrexRpcServer::s_server_uptime = get_current_date_time();
-std::string TrexRpcServer::s_owner = "none";
TrexRpcServer::TrexRpcServer(const TrexRpcServerConfig &req_resp_cfg) {
diff --git a/src/rpc-server/trex_rpc_server_api.h b/src/rpc-server/trex_rpc_server_api.h
index b4313670..06bbe10c 100644
--- a/src/rpc-server/trex_rpc_server_api.h
+++ b/src/rpc-server/trex_rpc_server_api.h
@@ -164,33 +164,17 @@ public:
}
- /**
- * query for ownership
- *
- */
- static const std::string &get_owner() {
- return s_owner;
- }
-
- /**
- * take ownership of the server array
- * this is static
- * ownership is total
- *
- */
- static void set_owner(const std::string &owner) {
- s_owner = owner;
- }
-
- static void clear_owner() {
- s_owner = "none";
- }
+
private:
+ static std::string generate_handler();
+
std::vector<TrexRpcServerInterface *> m_servers;
bool m_verbose;
static const std::string s_server_uptime;
+
static std::string s_owner;
+ static std::string s_owner_handler;
};
#endif /* __TREX_RPC_SERVER_API_H__ */
diff --git a/src/stateless/trex_stateless.cpp b/src/stateless/trex_stateless.cpp
index 2ab0c5d9..6a3169d4 100644
--- a/src/stateless/trex_stateless.cpp
+++ b/src/stateless/trex_stateless.cpp
@@ -20,6 +20,8 @@ limitations under the License.
*/
#include <trex_stateless_api.h>
+using namespace std;
+
/***********************************************************
* Trex stateless object
*
@@ -76,7 +78,8 @@ uint8_t TrexStateless::get_port_count() {
*
**************************/
TrexStatelessPort::TrexStatelessPort(uint8_t port_id) : m_port_id(port_id) {
- m_started = false;
+ m_port_state = PORT_STATE_UP_IDLE;
+ clear_owner();
}
@@ -84,25 +87,29 @@ TrexStatelessPort::TrexStatelessPort(uint8_t port_id) : m_port_id(port_id) {
* starts the traffic on the port
*
*/
-TrexStatelessPort::traffic_rc_e
+TrexStatelessPort::rc_e
TrexStatelessPort::start_traffic(void) {
- if (m_started) {
- return (TRAFFIC_ERR_ALREADY_STARTED);
+
+ if (m_port_state != PORT_STATE_UP_IDLE) {
+ return (RC_ERR_BAD_STATE_FOR_OP);
}
if (get_stream_table()->size() == 0) {
- return (TRAFFIC_ERR_NO_STREAMS);
+ return (RC_ERR_NO_STREAMS);
}
- m_started = true;
+ m_port_state = PORT_STATE_TRANSMITTING;
- return (TRAFFIC_OK);
+ /* real code goes here */
+ return (RC_OK);
}
void
TrexStatelessPort::stop_traffic(void) {
- if (m_started) {
- m_started = false;
+
+ /* real code goes here */
+ if (m_port_state == PORT_STATE_TRANSMITTING) {
+ m_port_state = PORT_STATE_UP_IDLE;
}
}
@@ -114,4 +121,32 @@ TrexStreamTable * TrexStatelessPort::get_stream_table() {
return &m_stream_table;
}
+void
+TrexStatelessPort::get_properties(string &driver, string &speed) {
+
+ /* take this from DPDK */
+ driver = "Unknown Driver";
+ speed = "Unknown Speed";
+}
+
+/**
+ * generate a random connection handler
+ *
+ */
+std::string
+TrexStatelessPort::generate_handler() {
+ std::stringstream ss;
+
+ static const char alphanum[] =
+ "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
+
+ /* generate 8 bytes of random handler */
+ for (int i = 0; i < 8; ++i) {
+ ss << alphanum[rand() % (sizeof(alphanum) - 1)];
+ }
+
+ return (ss.str());
+}
diff --git a/src/stateless/trex_stateless_api.h b/src/stateless/trex_stateless_api.h
index 358ab339..e02e93da 100644
--- a/src/stateless/trex_stateless_api.h
+++ b/src/stateless/trex_stateless_api.h
@@ -50,19 +50,36 @@ class TrexStatelessPort {
public:
/**
- * describess error codes for starting traffic
+ * port state
*/
- enum traffic_rc_e {
- TRAFFIC_OK,
- TRAFFIC_ERR_ALREADY_STARTED,
- TRAFFIC_ERR_NO_STREAMS,
- TRAFFIC_ERR_FAILED_TO_COMPILE_STREAMS
+ enum port_state_e {
+ PORT_STATE_DOWN,
+ PORT_STATE_UP_IDLE,
+ PORT_STATE_TRANSMITTING
+ };
+
+ /**
+ * describess different error codes for port operations
+ */
+ enum rc_e {
+ RC_OK,
+ RC_ERR_BAD_STATE_FOR_OP,
+ RC_ERR_NO_STREAMS,
+ RC_ERR_FAILED_TO_COMPILE_STREAMS
};
TrexStatelessPort(uint8_t port_id);
- traffic_rc_e start_traffic(void);
+ /**
+ * start traffic
+ *
+ */
+ rc_e start_traffic(void);
+ /**
+ * stop traffic
+ *
+ */
void stop_traffic(void);
/**
@@ -71,10 +88,76 @@ public:
*/
TrexStreamTable *get_stream_table();
+ /**
+ * get the port state
+ *
+ */
+ port_state_e get_state() {
+ return m_port_state;
+ }
+
+ /**
+ * fill up properties of the port
+ *
+ * @author imarom (16-Sep-15)
+ *
+ * @param driver
+ * @param speed
+ */
+ void get_properties(std::string &driver, std::string &speed);
+
+ /**
+ * query for ownership
+ *
+ */
+ const std::string &get_owner() {
+ return m_owner;
+ }
+
+ /**
+ * owner handler
+ * for the connection
+ *
+ */
+ const std::string &get_owner_handler() {
+ return m_owner_handler;
+ }
+
+ bool is_free_to_aquire() {
+ return (m_owner == "none");
+ }
+
+ /**
+ * take ownership of the server array
+ * this is static
+ * ownership is total
+ *
+ */
+ void set_owner(const std::string &owner) {
+ m_owner = owner;
+ m_owner_handler = generate_handler();
+ }
+
+ void clear_owner() {
+ m_owner = "none";
+ m_owner_handler = "";
+ }
+
+ bool verify_owner_handler(const std::string &handler) {
+
+ return ( (m_owner != "none") && (m_owner_handler == handler) );
+
+ }
+
private:
+
+ std::string generate_handler();
+
TrexStreamTable m_stream_table;
uint8_t m_port_id;
- bool m_started;
+ port_state_e m_port_state;
+ std::string m_owner;
+ std::string m_owner_handler;
};
/**
diff --git a/src/stateless/trex_stream.cpp b/src/stateless/trex_stream.cpp
index 2b5b2424..8bf04748 100644
--- a/src/stateless/trex_stream.cpp
+++ b/src/stateless/trex_stream.cpp
@@ -45,6 +45,17 @@ TrexStream::~TrexStream() {
}
}
+void
+TrexStream::store_stream_json(const Json::Value &stream_json) {
+ /* deep copy */
+ m_stream_json = stream_json;
+}
+
+const Json::Value &
+TrexStream::get_stream_json() {
+ return m_stream_json;
+}
+
/**************************************
* stream table
*************************************/
diff --git a/src/stateless/trex_stream_api.h b/src/stateless/trex_stream_api.h
index 26999751..d3c0fb29 100644
--- a/src/stateless/trex_stream_api.h
+++ b/src/stateless/trex_stream_api.h
@@ -26,6 +26,8 @@ limitations under the License.
#include <stdint.h>
#include <string>
+#include <json/json.h>
+
#include <trex_stream_vm.h>
class TrexRpcCmdAddStream;
@@ -48,7 +50,13 @@ public:
static const uint32_t MIN_PKT_SIZE_BYTES = 1;
static const uint32_t MAX_PKT_SIZE_BYTES = 9000;
-private:
+ /* provides storage for the stream json*/
+ void store_stream_json(const Json::Value &stream_json);
+
+ /* access the stream json */
+ const Json::Value & get_stream_json();
+
+protected:
/* basic */
uint8_t m_port_id;
uint32_t m_stream_id;
@@ -82,6 +90,8 @@ private:
} m_rx_check;
+ /* original template provided by requester */
+ Json::Value m_stream_json;
};
/**
@@ -90,15 +100,15 @@ private:
*/
class TrexStreamContinuous : public TrexStream {
public:
- TrexStreamContinuous(uint8_t port_id, uint32_t stream_id, uint32_t pps) : TrexStream(port_id, stream_id), m_pps(pps) {
+ TrexStreamContinuous(uint8_t port_id, uint32_t stream_id, double pps) : TrexStream(port_id, stream_id), m_pps(pps) {
}
- uint32_t get_pps() {
+ double get_pps() {
return m_pps;
}
protected:
- uint32_t m_pps;
+ double m_pps;
};
/**
@@ -107,7 +117,7 @@ protected:
*/
class TrexStreamBurst : public TrexStream {
public:
- TrexStreamBurst(uint8_t port_id, uint32_t stream_id, uint32_t total_pkts, uint32_t pps) :
+ TrexStreamBurst(uint8_t port_id, uint32_t stream_id, uint32_t total_pkts, double pps) :
TrexStream(port_id, stream_id),
m_total_pkts(total_pkts),
m_pps(pps) {
@@ -115,7 +125,7 @@ public:
protected:
uint32_t m_total_pkts;
- uint32_t m_pps;
+ double m_pps;
};
/**
@@ -127,7 +137,7 @@ public:
TrexStreamMultiBurst(uint8_t port_id,
uint32_t stream_id,
uint32_t pkts_per_burst,
- uint32_t pps,
+ double pps,
uint32_t num_bursts,
double ibg_usec) : TrexStreamBurst(port_id, stream_id, pkts_per_burst, pps), m_num_bursts(num_bursts), m_ibg_usec(ibg_usec) {