summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorDan Klein <danklei@cisco.com>2015-09-10 13:39:18 +0300
committerDan Klein <danklei@cisco.com>2015-09-10 13:39:18 +0300
commitef520c7e3a18aeefe02ba0d3e6b16fafde3c1b91 (patch)
treee787cc29908a286129dd2134d2150bc56e775a04 /scripts
parent760710869405dbc3b5dadd6ce06015c72ea2ca44 (diff)
Major progress in Packet building module and VM instruction sets.
added dot1q into dpkt lib First abstractino of HLTAPI layer
Diffstat (limited to 'scripts')
-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_utils/packet_builder.py566
-rw-r--r--scripts/external_libs/dpkt-1.8.6/dpkt/dot1q.py1110
5 files changed, 1635 insertions, 76 deletions
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_utils/packet_builder.py b/scripts/automation/trex_control_plane/client_utils/packet_builder.py
index 0d31f28e..abe98dbb 100644
--- a/scripts/automation/trex_control_plane/client_utils/packet_builder.py
+++ b/scripts/automation/trex_control_plane/client_utils/packet_builder.py
@@ -5,23 +5,207 @@ import outer_packages
import dpkt
import socket
import binascii
+import copy
+import random
+import string
+import struct
+import re
class CTRexPktBuilder(object):
- """docstring for CTRexPktBuilder"""
- def __init__(self):
+ """
+ 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.vm = CTRexPktBuilder.CTRexVM(self.packet)
+ 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
- def add_l2_header(self):
- pass
+ :parameters:
+ layer_name: str
+ a string representing the name of the layer.
+ Example: "l2", "l4_tcp", etc.
- def add_l3_header(self):
- pass
+ pkt_layer : dpkt.Packet obj
+ a dpkt object, generally from higher layer, that will be added on top of existing layer.
- def add_pkt_payload(self):
- pass
+ """
+ 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(self, 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):
+ """
+ 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.
+
+ :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 obejct that is not dpkt.Packet is not allowed using "
+ "set_layer_attr method.\nUse set_payload method instead.")
+ if hasattr(layer, attr):
+ 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_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 enables the user to change a value of a previously defined packet layer.
+
+ :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.
+
+ """
+ if get_ptr:
+ self._pkt_by_hdr = {}
+ self._pkt_top_layer = None
+ return self._packet
+
+ else:
+ return copy.copy(self._packet)
# VM access methods
def set_vm_ip_range(self, ip_start, ip_end, ip_type="ipv4"):
@@ -37,7 +221,7 @@ class CTRexPktBuilder(object):
pass
def dump_pkt(self):
- pkt_in_hex = binascii.hexlify(str(self.packet))
+ pkt_in_hex = binascii.hexlify(str(self._packet))
return [pkt_in_hex[i:i+2] for i in range(0, len(pkt_in_hex), 2)]
# ----- useful shortcut methods ----- #
@@ -45,118 +229,334 @@ class CTRexPktBuilder(object):
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 _is_valid_ip_addr(ip_addr, ip_type):
+ 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:
- socket.inet_pton(socket.AF_INET, ip_addr)
+ return socket.inet_pton(socket.AF_INET, ip_addr)
except AttributeError: # no inet_pton here, sorry
- try:
- socket.inet_aton(ip_addr)
- except socket.error:
- return False
- return ip_addr.count('.') == 3
+ # try:
+ return socket.inet_aton(ip_addr)
+ # except socket.error:
+ # return False
+ # return ip_addr.count('.') == 3
except socket.error: # not a valid address
- return False
- return True
+ raise CTRexPktBuilder.IPAddressError()
elif ip_type == "ipv6":
try:
- socket.inet_pton(socket.AF_INET6, ip_addr)
+ return socket.inet_pton(socket.AF_INET6, ip_addr)
except socket.error: # not a valid address
- return False
- return True
+ raise CTRexPktBuilder.IPAddressError()
else:
raise CTRexPktBuilder.IPAddressError()
- # ------ private classes ------
+ # ------ 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):
- """docstring for CTRexVM"""
- def __init__(self, packet):
+ """
+ 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.packet = packet
self.vm_variables = {}
- def add_vm_variable(self, name):
+ 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 set_vm_var_field(self, var_name, field_name, val):
- pass
- return self.vm_variables[var_name].set_field(field_name, val)
+ 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.
- def fix_checksum_ipv4(self):
- pass
+ :return:
+ list holds variables data of VM
- def flow_man_simple(self):
- pass
-
- def write_to_pkt(self):
- pass
+ """
+ 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 var in self.vm_variables]
+ 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_TYPE = ["inc", "dec", "random"]
- VALID_CORE_MASK = ["split", "none"]
+ 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.type = "inc"
- self.core_mask = "none"
- self.init_addr = "10.0.0.1"
- self.min_addr = str(self.init_addr)
- self.max_addr = str(self.init_addr)
+ 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):
- if field_name == "size":
+ """
+ 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 == "type":
- if type(val) != str:
- raise CTRexPktBuilder.VMVarFieldTypeError("type", str)
- elif val not in self.VALID_TYPE:
- raise CTRexPktBuilder.VMVarValueError("type", self.VALID_TYPE)
- elif field_name == "core_mask":
+ 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("core_mask", str)
- elif val not in self.VALID_TYPE:
- raise CTRexPktBuilder.VMVarValueError("core_mask", self.VALID_CORE_MASK)
+ 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_TYPE:
- return False
- if self.core_mask not in self.VALID_CORE_MASK:
+ if self.type not in self.VALID_OPERATION:
return False
return True
def dump(self):
- return {"name" : self.name,
- "Size" : self.size,
- "big_endian" : self.big_endian,
- "type" : self.type,
- "core_mask" : self.core_mask,
- "init_addr" : self.init_addr,
- "min_addr" : self.min_addr,
- "max_addr" : self.max_addr}
+ """
+ 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 error exception class.
+ This is the general Packet Building error exception class.
"""
def __init__(self, code, message):
self.code = code
@@ -173,22 +573,40 @@ class CTRexPktBuilder(object):
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 of IP addressing has been provided.'
+ 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 an error on the IP addressing part of the packet.
+ 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._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 error on the IP addressing part of the packet.
+ 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}, \
@@ -196,11 +614,11 @@ class CTRexPktBuilder(object):
field_type=type(name).__name__,
allowed_type=ok_type.__name__)
self.message = message or self._default_message
- super(CTRexPktBuilder.VMVarNameExistsError, self).__init__(-31, self.message)
+ super(CTRexPktBuilder.VMVarFieldTypeError, self).__init__(-31, self.message)
class VMVarValueError(CPacketBuildException):
"""
- This exception is used to indicate an error on the IP addressing part of the packet.
+ 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 \
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>
+