<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/testsuite/+/13222">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Kevin Harwell: Looks good to me, but someone else must approve
Joshua Colp: Looks good to me, but someone else must approve
George Joseph: Looks good to me, approved
Friendly Automation: Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">lib/python/asterisk/pcap/py Replace construct_legacy.protocols<br><br>The "protocols" module provides parsing for PCAP packets<br>layers 2-4 (Ethernet, IPv4/IPv6, UDP/TCP). The<br>Testsuite uses it to parse packets for the tests that<br>need that functionality.<br><br>It was originally part of the "construct" module but was removed<br>after v2.5.5. Unfortunately, it was and is the only<br>standalone/low overhead packet parsing module available.<br><br>This python package is an extract from the construct package v2.5.5.<br>Since construct itself underwent major API changes since v2.5.5,<br>the protocols code needed significant work to make it compatible<br>with the current construct version (2.9 at the time of this writing).<br>Since no functional changes were made, only API compatibility<br>changes, the original construct (license)[LICENSE.md] still<br>applies and is included here.<br><br>* Ported construct.protocols to construct 2.9 and added it<br> to lib/python.<br><br>* Updated pcap.py...<br>** Using /lib/python/PcapListener directly instead of through<br> test_case to make it a bit less complicated and to facilitate<br> standalone unit tests.<br>** Refactored for construct 2.9<br>** Removed references to construct.protcols<br>** Added a unit test.<br> cd <testsuite_dir>/lib/python/asterisk<br> PYTHONPATH=<testsuite_dir>/lib/python python2 pcap.py --help<br><br>* Updated tests that used construct_legacy to work with<br> construct 2.9<br><br>Change-Id: Id38d01a2cd073b240fde909a38c95d69313bbbe7<br>---<br>M lib/python/asterisk/pcap.py<br>M lib/python/asterisk/test_case.py<br>A lib/python/protocols/LICENSE.md<br>A lib/python/protocols/README.md<br>A lib/python/protocols/__init__.py<br>A lib/python/protocols/application/__init__.py<br>A lib/python/protocols/ipstack.py<br>A lib/python/protocols/layer2/__init__.py<br>A lib/python/protocols/layer2/arp.py<br>A lib/python/protocols/layer2/ethernet.py<br>A lib/python/protocols/layer2/mtp2.py<br>A lib/python/protocols/layer3/__init__.py<br>A lib/python/protocols/layer3/ipv4.py<br>A lib/python/protocols/layer3/ipv6.py<br>A lib/python/protocols/layer4/__init__.py<br>A lib/python/protocols/layer4/tcp.py<br>A lib/python/protocols/layer4/udp.py<br>A lib/python/protocols/unconverted/application/dns.py<br>A lib/python/protocols/unconverted/layer3/dhcpv4.py<br>A lib/python/protocols/unconverted/layer3/dhcpv6.py<br>A lib/python/protocols/unconverted/layer3/icmpv4.py<br>A lib/python/protocols/unconverted/layer3/igmpv2.py<br>A lib/python/protocols/unconverted/layer3/mtp3.py<br>A lib/python/protocols/unconverted/layer4/isup.py<br>M tests/channels/SIP/pcap_demo/run-test<br>M tests/channels/SIP/pcap_demo/test-config.yaml<br>M tests/channels/pjsip/rtp/rtp_keepalive/base/rtp.py<br>M tests/hep/hep_capture_node.py<br>28 files changed, 1,354 insertions(+), 144 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/lib/python/asterisk/pcap.py b/lib/python/asterisk/pcap.py</span><br><span>index cb5fa5c..536a7ca 100644</span><br><span>--- a/lib/python/asterisk/pcap.py</span><br><span>+++ b/lib/python/asterisk/pcap.py</span><br><span>@@ -13,18 +13,16 @@</span><br><span> </span><br><span> import sys</span><br><span> import logging</span><br><span style="color: hsl(120, 100%, 40%);">+import signal</span><br><span style="color: hsl(120, 100%, 40%);">+import argparse</span><br><span> import binascii</span><br><span> </span><br><span> sys.path.append('lib/python')</span><br><span> </span><br><span> from twisted.internet.protocol import DatagramProtocol</span><br><span> from twisted.internet import reactor</span><br><span style="color: hsl(0, 100%, 40%);">-try:</span><br><span style="color: hsl(0, 100%, 40%);">- from construct_legacy import *</span><br><span style="color: hsl(0, 100%, 40%);">- from construct_legacy.protocols.ipstack import ip_stack</span><br><span style="color: hsl(0, 100%, 40%);">-except ImportError:</span><br><span style="color: hsl(0, 100%, 40%);">- from construct import *</span><br><span style="color: hsl(0, 100%, 40%);">- from construct.protocols.ipstack import ip_stack</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from construct.core import *</span><br><span> try:</span><br><span> from yappcap import PcapOffline</span><br><span> PCAP_AVAILABLE = True</span><br><span>@@ -33,6 +31,9 @@</span><br><span> </span><br><span> import rlmi</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+from protocols.ipstack import ip_stack</span><br><span style="color: hsl(120, 100%, 40%);">+from pcap_listener import PcapListener as PacketCapturer</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> LOGGER = logging.getLogger(__name__)</span><br><span> </span><br><span> </span><br><span>@@ -59,18 +60,13 @@</span><br><span> filename = module_config.get('filename')</span><br><span> snaplen = module_config.get('snaplen')</span><br><span> buffer_size = module_config.get('buffer-size')</span><br><span style="color: hsl(0, 100%, 40%);">- if (module_config.get('register-observer')):</span><br><span style="color: hsl(0, 100%, 40%);">- test_object.register_pcap_observer(self.__pcap_callback)</span><br><span> self.debug_packets = module_config.get('debug-packets', False)</span><br><span> </span><br><span> # Let exceptions propagate - if we can't create the pcap, this should</span><br><span> # throw the exception to the pluggable module creation routines</span><br><span style="color: hsl(0, 100%, 40%);">- test_object.create_pcap_listener(</span><br><span style="color: hsl(0, 100%, 40%);">- device=device,</span><br><span style="color: hsl(0, 100%, 40%);">- bpf_filter=bpf_filter,</span><br><span style="color: hsl(0, 100%, 40%);">- dumpfile=filename,</span><br><span style="color: hsl(0, 100%, 40%);">- snaplen=snaplen,</span><br><span style="color: hsl(0, 100%, 40%);">- buffer_size=buffer_size)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ PacketCapturer(device, bpf_filter, filename, self.__pcap_callback,</span><br><span style="color: hsl(120, 100%, 40%);">+ snaplen, buffer_size)</span><br><span> </span><br><span> def __pcap_callback(self, packet):</span><br><span> """Private callback that logs packets if the configuration supports it</span><br><span>@@ -108,7 +104,6 @@</span><br><span> packet_type A text string describing what type of packet this is</span><br><span> raw_packet The bytes comprising the packet</span><br><span> """</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> self.packet_type = packet_type</span><br><span> self.raw_packet = raw_packet</span><br><span> if isinstance(self.raw_packet, str):</span><br><span>@@ -154,43 +149,45 @@</span><br><span> self.__parse_raw_data(self.transport_layer.next)</span><br><span> </span><br><span> def __parse_raw_data(self, binary_blob):</span><br><span style="color: hsl(0, 100%, 40%);">- header_def = Struct('rtcp_header',</span><br><span style="color: hsl(0, 100%, 40%);">- BitStruct('header',</span><br><span style="color: hsl(0, 100%, 40%);">- BitField('version', 2),</span><br><span style="color: hsl(120, 100%, 40%);">+ header_def = 'rtcp_header' / BitStruct(</span><br><span style="color: hsl(120, 100%, 40%);">+ 'header' / BitStruct(</span><br><span style="color: hsl(120, 100%, 40%);">+ 'version' / BitsInteger(2),</span><br><span> Padding(1),</span><br><span style="color: hsl(0, 100%, 40%);">- BitField('reception_report_count', 5),</span><br><span style="color: hsl(120, 100%, 40%);">+ 'reception_report_count' / BitsInteger(5),</span><br><span> ),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt8('packet_type'),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt16('length'),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('ssrc'))</span><br><span style="color: hsl(120, 100%, 40%);">+ 'packet_type' / Bytewise(Int8ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ 'length' / Bytewise(Int16ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ 'ssrc' / Bytewise(Int32ub)</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span> self.rtcp_header = header_def.parse(binary_blob)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> report_block_def = GreedyRange(</span><br><span style="color: hsl(0, 100%, 40%);">- Struct(</span><br><span style="color: hsl(0, 100%, 40%);">- 'report_block',</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('ssrc'),</span><br><span style="color: hsl(0, 100%, 40%);">- BitStruct(</span><br><span style="color: hsl(0, 100%, 40%);">- 'lost_counts',</span><br><span style="color: hsl(0, 100%, 40%);">- BitField('fraction_lost', 8),</span><br><span style="color: hsl(0, 100%, 40%);">- BitField('packets_lost', 24)),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('sequence_number_received'),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('interarrival_jitter'),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('last_sr'),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('delay_last_sr')</span><br><span style="color: hsl(120, 100%, 40%);">+ 'report_block' / BitStruct(</span><br><span style="color: hsl(120, 100%, 40%);">+ 'ssrc' / Bytewise(Int32ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ 'lost_counts' / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ 'fraction_lost' / BitsInteger(8),</span><br><span style="color: hsl(120, 100%, 40%);">+ 'packets_lost' / BitsInteger(24)</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ 'sequence_number_received' / Bytewise(Int32ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ 'interarrival_jitter' / Bytewise(Int32ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ 'last_sr' / Bytewise(Int32ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ 'delay_last_sr' / Bytewise(Int32ub)</span><br><span> )</span><br><span> )</span><br><span> if self.rtcp_header.packet_type == 200:</span><br><span> sender_def = Struct('sr',</span><br><span style="color: hsl(0, 100%, 40%);">- Struct('sender_info',</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('ntp_msw'),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('ntp_lsw'),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('rtp_timestamp'),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('sender_packet_count'),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('sender_octet_count')),</span><br><span style="color: hsl(120, 100%, 40%);">+ 'sender_info' / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ 'ntp_msw' / Int32ub,</span><br><span style="color: hsl(120, 100%, 40%);">+ 'ntp_lsw' / Int32ub,</span><br><span style="color: hsl(120, 100%, 40%);">+ 'rtp_timestamp' / Int32ub,</span><br><span style="color: hsl(120, 100%, 40%);">+ 'sender_packet_count' / Int32ub,</span><br><span style="color: hsl(120, 100%, 40%);">+ 'sender_octet_count' / Int32ub</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span> report_block_def)</span><br><span> </span><br><span> self.sender_report = sender_def.parse(binary_blob[8:])</span><br><span> elif self.rtcp_header.packet_type == 201:</span><br><span style="color: hsl(0, 100%, 40%);">- receiver_def = Struct('rr',</span><br><span style="color: hsl(120, 100%, 40%);">+ receiver_def = 'rr' / Struct(</span><br><span> report_block_def)</span><br><span> self.receiver_report = receiver_def.parse(binary_blob[8:])</span><br><span> </span><br><span>@@ -205,19 +202,16 @@</span><br><span> """An RTP Packet</span><br><span> """</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- rtp_header = Struct(</span><br><span style="color: hsl(0, 100%, 40%);">- "rtp_header",</span><br><span style="color: hsl(0, 100%, 40%);">- EmbeddedBitStruct(</span><br><span style="color: hsl(0, 100%, 40%);">- BitField("version", 2),</span><br><span style="color: hsl(0, 100%, 40%);">- Bit("padding"),</span><br><span style="color: hsl(0, 100%, 40%);">- Bit("extension"),</span><br><span style="color: hsl(0, 100%, 40%);">- Nibble("csrc_count"),</span><br><span style="color: hsl(0, 100%, 40%);">- Bit("marker"),</span><br><span style="color: hsl(0, 100%, 40%);">- BitField("payload_type", 7),</span><br><span style="color: hsl(0, 100%, 40%);">- ),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt16("sequence_number"),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32("timestamp"),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32("ssrc"),</span><br><span style="color: hsl(120, 100%, 40%);">+ rtp_header = "rtp_header" / BitStruct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "version" / BitsInteger(2),</span><br><span style="color: hsl(120, 100%, 40%);">+ "padding" / Bit,</span><br><span style="color: hsl(120, 100%, 40%);">+ "extension" / Bit,</span><br><span style="color: hsl(120, 100%, 40%);">+ "csrc_count" / Nibble,</span><br><span style="color: hsl(120, 100%, 40%);">+ "marker" / Bit,</span><br><span style="color: hsl(120, 100%, 40%);">+ "payload_type" / BitsInteger(7),</span><br><span style="color: hsl(120, 100%, 40%);">+ "sequence_number" / Bytewise(Int16ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "timestamp" / Bytewise(Int32ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "ssrc" / Bytewise(Int32ub),</span><br><span> # 'csrc' can be added later when needed</span><br><span> )</span><br><span> </span><br><span>@@ -748,6 +742,7 @@</span><br><span> """</span><br><span> (host, port) = addr</span><br><span> packet = self.packet_factory.interpret_packet(packet)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if packet is None:</span><br><span> return</span><br><span> </span><br><span>@@ -760,10 +755,12 @@</span><br><span> if host not in self.traces:</span><br><span> self.traces[host] = []</span><br><span> self.traces[host].append(packet)</span><br><span style="color: hsl(0, 100%, 40%);">- if packet.packet_type not in self.callbacks:</span><br><span style="color: hsl(0, 100%, 40%);">- return</span><br><span style="color: hsl(0, 100%, 40%);">- for callback in self.callbacks[packet.packet_type]:</span><br><span style="color: hsl(0, 100%, 40%);">- callback(packet)</span><br><span style="color: hsl(120, 100%, 40%);">+ if packet.packet_type in self.callbacks:</span><br><span style="color: hsl(120, 100%, 40%);">+ for callback in self.callbacks[packet.packet_type]:</span><br><span style="color: hsl(120, 100%, 40%);">+ callback(packet)</span><br><span style="color: hsl(120, 100%, 40%);">+ if "*" in self.callbacks:</span><br><span style="color: hsl(120, 100%, 40%);">+ for callback in self.callbacks["*"]:</span><br><span style="color: hsl(120, 100%, 40%);">+ callback(packet)</span><br><span> </span><br><span> def add_callback(self, packet_type, callback):</span><br><span> """Add a callback function for received packets of a particular type</span><br><span>@@ -872,11 +869,16 @@</span><br><span> module_config The module configuration for this pluggable module</span><br><span> test_object The object we will attach to</span><br><span> """</span><br><span style="color: hsl(0, 100%, 40%);">- if not 'register-observer' in module_config:</span><br><span style="color: hsl(0, 100%, 40%);">- raise Exception('VOIPListener needs register-observer to be set')</span><br><span style="color: hsl(0, 100%, 40%);">- VOIPSniffer.__init__(self, module_config, test_object)</span><br><span style="color: hsl(0, 100%, 40%);">- PcapListener.__init__(self, module_config, test_object)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ VOIPSniffer.__init__(self, module_config, test_object)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ packet_type = module_config.get("packet-type")</span><br><span style="color: hsl(120, 100%, 40%);">+ bpf = module_config.get("bpf-filter")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if packet_type:</span><br><span style="color: hsl(120, 100%, 40%);">+ self.add_callback(packet_type, module_config.get("callback"))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ PcapListener.__init__(self, module_config, test_object)</span><br><span> </span><br><span> def pcap_callback(self, packet):</span><br><span> """Packet capture callback function</span><br><span>@@ -888,5 +890,49 @@</span><br><span> Keyword Arguments:</span><br><span> packet A received packet from the pcap listener</span><br><span> """</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> self.process_packet(packet, (None, None))</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+# This is a unit test for capture and parsing.</span><br><span style="color: hsl(120, 100%, 40%);">+# By default it listens on the loopback interface</span><br><span style="color: hsl(120, 100%, 40%);">+# UDP port 5060.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def callback(packet):</span><br><span style="color: hsl(120, 100%, 40%);">+ print(packet)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def signal_handler(sig, frame):</span><br><span style="color: hsl(120, 100%, 40%);">+ print('You pressed Ctrl+C!')</span><br><span style="color: hsl(120, 100%, 40%);">+ reactor.stop()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ signal.signal(signal.SIGINT, signal_handler)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ parser = argparse.ArgumentParser(description="pcap unit test")</span><br><span style="color: hsl(120, 100%, 40%);">+ parser.add_argument("-i", "--interface", metavar="i", action="store",</span><br><span style="color: hsl(120, 100%, 40%);">+ type=str, dest="interface", default="lo",</span><br><span style="color: hsl(120, 100%, 40%);">+ help="Interface to listen on")</span><br><span style="color: hsl(120, 100%, 40%);">+ parser.add_argument("-f", "--filter", metavar="f", action="store",</span><br><span style="color: hsl(120, 100%, 40%);">+ type=str, dest="filter", default="udp port 5060",</span><br><span style="color: hsl(120, 100%, 40%);">+ help="BPF Filter")</span><br><span style="color: hsl(120, 100%, 40%);">+ parser.add_argument("-o", "--output", metavar="o", action="store",</span><br><span style="color: hsl(120, 100%, 40%);">+ type=str, dest="output", default="/tmp/pcap_unit_test.pcap",</span><br><span style="color: hsl(120, 100%, 40%);">+ help="Output file")</span><br><span style="color: hsl(120, 100%, 40%);">+ options = parser.parse_args()</span><br><span style="color: hsl(120, 100%, 40%);">+ print('Listening on "%s", using filter "%s", capturing to "%s"'</span><br><span style="color: hsl(120, 100%, 40%);">+ % (options.interface, options.filter, options.output))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ module_config = {</span><br><span style="color: hsl(120, 100%, 40%);">+ "device": options.interface,</span><br><span style="color: hsl(120, 100%, 40%);">+ "bpf-filter": options.filter,</span><br><span style="color: hsl(120, 100%, 40%);">+ "filename": options.output,</span><br><span style="color: hsl(120, 100%, 40%);">+ "snaplen": 65535,</span><br><span style="color: hsl(120, 100%, 40%);">+ "buffer-size": 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ "callback": callback,</span><br><span style="color: hsl(120, 100%, 40%);">+ "debug-packets": True,</span><br><span style="color: hsl(120, 100%, 40%);">+ "packet-type": "*"</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ pcap = VOIPListener(module_config, None)</span><br><span style="color: hsl(120, 100%, 40%);">+ reactor.run()</span><br><span>diff --git a/lib/python/asterisk/test_case.py b/lib/python/asterisk/test_case.py</span><br><span>index 7bf6d16..1c7edfa 100644</span><br><span>--- a/lib/python/asterisk/test_case.py</span><br><span>+++ b/lib/python/asterisk/test_case.py</span><br><span>@@ -138,7 +138,6 @@</span><br><span> self._stop_callbacks = []</span><br><span> self._ami_connect_callbacks = []</span><br><span> self._ami_reconnect_callbacks = []</span><br><span style="color: hsl(0, 100%, 40%);">- self._pcap_callbacks = []</span><br><span> self._stop_deferred = None</span><br><span> log_full = True</span><br><span> log_messages = True</span><br><span>@@ -396,7 +395,7 @@</span><br><span> # tests can create their own. Tests may only want to watch a specific</span><br><span> # port, while a general logger will want to watch more general traffic</span><br><span> # which can be filtered later.</span><br><span style="color: hsl(0, 100%, 40%);">- return PcapListener(device, bpf_filter, dumpfile, self._pcap_callback,</span><br><span style="color: hsl(120, 100%, 40%);">+ return PcapListener(device, bpf_filter, dumpfile, self.pcap_callback,</span><br><span> snaplen, buffer_size)</span><br><span> </span><br><span> def start_asterisk(self):</span><br><span>@@ -622,12 +621,6 @@</span><br><span> """Virtual method used to receive captured packets."""</span><br><span> pass</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- def _pcap_callback(self, packet):</span><br><span style="color: hsl(0, 100%, 40%);">- """Packet capture callback"""</span><br><span style="color: hsl(0, 100%, 40%);">- self.pcap_callback(packet)</span><br><span style="color: hsl(0, 100%, 40%);">- for callback in self._pcap_callbacks:</span><br><span style="color: hsl(0, 100%, 40%);">- callback(packet)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> def handle_originate_failure(self, reason):</span><br><span> """Fail the test on an Originate failure</span><br><span> </span><br><span>@@ -676,17 +669,6 @@</span><br><span> </span><br><span> return self.passed</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- def register_pcap_observer(self, callback):</span><br><span style="color: hsl(0, 100%, 40%);">- """Register an observer that will be called when a packet is received</span><br><span style="color: hsl(0, 100%, 40%);">- from a created pcap listener</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- Keyword Arguments:</span><br><span style="color: hsl(0, 100%, 40%);">- callback The callback to receive the packet. The callback function</span><br><span style="color: hsl(0, 100%, 40%);">- should take in a single parameter, which will be the packet</span><br><span style="color: hsl(0, 100%, 40%);">- received</span><br><span style="color: hsl(0, 100%, 40%);">- """</span><br><span style="color: hsl(0, 100%, 40%);">- self._pcap_callbacks.append(callback)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> def register_start_observer(self, callback):</span><br><span> """Register an observer that will be called when all Asterisk instances</span><br><span> have started</span><br><span>diff --git a/lib/python/protocols/LICENSE.md b/lib/python/protocols/LICENSE.md</span><br><span>new file mode 100644</span><br><span>index 0000000..366ed6e</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/LICENSE.md</span><br><span>@@ -0,0 +1,24 @@</span><br><span style="color: hsl(120, 100%, 40%);">+```</span><br><span style="color: hsl(120, 100%, 40%);">+Copyright (C) 2006-2018</span><br><span style="color: hsl(120, 100%, 40%);">+ Arkadiusz Bulski (arek.bulski@gmail.com)</span><br><span style="color: hsl(120, 100%, 40%);">+ Tomer Filiba (tomerfiliba@gmail.com)</span><br><span style="color: hsl(120, 100%, 40%);">+ Corbin Simpson (MostAwesomeDude@gmail.com)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Permission is hereby granted, free of charge, to any person obtaining a copy</span><br><span style="color: hsl(120, 100%, 40%);">+of this software and associated documentation files (the "Software"), to deal</span><br><span style="color: hsl(120, 100%, 40%);">+in the Software without restriction, including without limitation the rights</span><br><span style="color: hsl(120, 100%, 40%);">+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell</span><br><span style="color: hsl(120, 100%, 40%);">+copies of the Software, and to permit persons to whom the Software is</span><br><span style="color: hsl(120, 100%, 40%);">+furnished to do so, subject to the following conditions:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+The above copyright notice and this permission notice shall be included in all</span><br><span style="color: hsl(120, 100%, 40%);">+copies or substantial portions of the Software.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</span><br><span style="color: hsl(120, 100%, 40%);">+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</span><br><span style="color: hsl(120, 100%, 40%);">+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE</span><br><span style="color: hsl(120, 100%, 40%);">+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</span><br><span style="color: hsl(120, 100%, 40%);">+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,</span><br><span style="color: hsl(120, 100%, 40%);">+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE</span><br><span style="color: hsl(120, 100%, 40%);">+SOFTWARE.</span><br><span style="color: hsl(120, 100%, 40%);">+```</span><br><span>\ No newline at end of file</span><br><span>diff --git a/lib/python/protocols/README.md b/lib/python/protocols/README.md</span><br><span>new file mode 100644</span><br><span>index 0000000..171a5e1</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/README.md</span><br><span>@@ -0,0 +1,47 @@</span><br><span style="color: hsl(120, 100%, 40%);">+## protocols</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+The "protocols" module provides parsing for PCAP packets</span><br><span style="color: hsl(120, 100%, 40%);">+layers 2-4 (Ethernet, IPv4/IPv6, UDP/TCP). The</span><br><span style="color: hsl(120, 100%, 40%);">+Testsuite uses it to parse packets for the tests that</span><br><span style="color: hsl(120, 100%, 40%);">+need that functionality.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+It was originally part of the</span><br><span style="color: hsl(120, 100%, 40%);">+[construct](https://github.com/construct/construct)</span><br><span style="color: hsl(120, 100%, 40%);">+module but was removed after v2.5.5. Unfortunately,</span><br><span style="color: hsl(120, 100%, 40%);">+it was and is the only standalone/low overhead packet parsing</span><br><span style="color: hsl(120, 100%, 40%);">+module available.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+This python package is an extract from the</span><br><span style="color: hsl(120, 100%, 40%);">+[construct](https://github.com/construct/construct)</span><br><span style="color: hsl(120, 100%, 40%);">+package v2.5.5. Since construct itself underwent</span><br><span style="color: hsl(120, 100%, 40%);">+major API changes since v2.5.5, the protocols</span><br><span style="color: hsl(120, 100%, 40%);">+code needed significant work to make it compatible</span><br><span style="color: hsl(120, 100%, 40%);">+with the current construct version (2.9 at the</span><br><span style="color: hsl(120, 100%, 40%);">+time of this writing). Since no functional changes</span><br><span style="color: hsl(120, 100%, 40%);">+were made, only API compatibility changes, the</span><br><span style="color: hsl(120, 100%, 40%);">+original construct (license)[LICENSE.md] still</span><br><span style="color: hsl(120, 100%, 40%);">+applies and is included here.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+This module is compatible with both python2 and</span><br><span style="color: hsl(120, 100%, 40%);">+python3. It also contains unit tests for every</span><br><span style="color: hsl(120, 100%, 40%);">+parser including the top-level ipstack wrapper.</span><br><span style="color: hsl(120, 100%, 40%);">+To run the unit tests, you must add</span><br><span style="color: hsl(120, 100%, 40%);">+`<testsuite_path>/lib/python` to the `PYTHONPATH`</span><br><span style="color: hsl(120, 100%, 40%);">+environment variable.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Example</span><br><span style="color: hsl(120, 100%, 40%);">+```</span><br><span style="color: hsl(120, 100%, 40%);">+# cd /usr/src/asterisk/testsuite/lib/python</span><br><span style="color: hsl(120, 100%, 40%);">+# PYTHONPATH=/usr/src/asterisk/testsuite/lib/python python3</span><br><span style="color: hsl(120, 100%, 40%);">+./ipstack.py</span><br><span style="color: hsl(120, 100%, 40%);">+```</span><br><span style="color: hsl(120, 100%, 40%);">+Or...</span><br><span style="color: hsl(120, 100%, 40%);">+```</span><br><span style="color: hsl(120, 100%, 40%);">+# cd /usr/src/asterisk/testsuite/lib/python</span><br><span style="color: hsl(120, 100%, 40%);">+# PYTHONPATH=../ python3 ./ipstack.py</span><br><span style="color: hsl(120, 100%, 40%);">+```</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+There is also an "unconverted" directory in this</span><br><span style="color: hsl(120, 100%, 40%);">+module which contains parsers we don't use and</span><br><span style="color: hsl(120, 100%, 40%);">+therefore haven't been updated wo work with</span><br><span style="color: hsl(120, 100%, 40%);">+the latest construct.</span><br><span>diff --git a/lib/python/protocols/__init__.py b/lib/python/protocols/__init__.py</span><br><span>new file mode 100644</span><br><span>index 0000000..0ec215e</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/__init__.py</span><br><span>@@ -0,0 +1,4 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+protocols - a collection of network protocols</span><br><span style="color: hsl(120, 100%, 40%);">+unlike the formats package, protocols convey information between two sides</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span>diff --git a/lib/python/protocols/application/__init__.py b/lib/python/protocols/application/__init__.py</span><br><span>new file mode 100644</span><br><span>index 0000000..7ea61f7</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/application/__init__.py</span><br><span>@@ -0,0 +1,4 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+application layer (various) protocols</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/lib/python/protocols/ipstack.py b/lib/python/protocols/ipstack.py</span><br><span>new file mode 100644</span><br><span>index 0000000..cd63fce</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/ipstack.py</span><br><span>@@ -0,0 +1,146 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+TCP/IP Protocol Stack</span><br><span style="color: hsl(120, 100%, 40%);">+Note: before parsing the application layer over a TCP stream, you must</span><br><span style="color: hsl(120, 100%, 40%);">+first combine all the TCP frames into a stream. See utils.tcpip for</span><br><span style="color: hsl(120, 100%, 40%);">+some solutions</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+from binascii import unhexlify</span><br><span style="color: hsl(120, 100%, 40%);">+#import six</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import Struct, HexDump, Switch, Pass, Computed, Hex, Bytes, setGlobalPrintFullStrings</span><br><span style="color: hsl(120, 100%, 40%);">+from protocols.layer2.ethernet import ethernet_header</span><br><span style="color: hsl(120, 100%, 40%);">+from protocols.layer3.ipv4 import ipv4_header</span><br><span style="color: hsl(120, 100%, 40%);">+from protocols.layer3.ipv6 import ipv6_header</span><br><span style="color: hsl(120, 100%, 40%);">+from protocols.layer4.tcp import tcp_header</span><br><span style="color: hsl(120, 100%, 40%);">+from protocols.layer4.udp import udp_header</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+setGlobalPrintFullStrings(True)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+layer4_tcp = "layer4_tcp" / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "layer" / Computed(4),</span><br><span style="color: hsl(120, 100%, 40%);">+ "packet_type" / Computed("TCP"),</span><br><span style="color: hsl(120, 100%, 40%);">+ "header" / tcp_header,</span><br><span style="color: hsl(120, 100%, 40%);">+ "next" / Bytes(lambda ctx: ctx["_"]["header"].payload_length - ctx["header"].header_length)</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+layer4_udp = "layer4_udp" / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "layer" / Computed(4),</span><br><span style="color: hsl(120, 100%, 40%);">+ "packet_type" / Computed("UDP"),</span><br><span style="color: hsl(120, 100%, 40%);">+ "header" / udp_header,</span><br><span style="color: hsl(120, 100%, 40%);">+ "next" / Bytes(lambda ctx: ctx["header"].payload_length)</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+layer3_payload = "next" / Switch(lambda ctx: ctx["header"].protocol,</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+ "TCP" : layer4_tcp,</span><br><span style="color: hsl(120, 100%, 40%);">+ "UDP" : layer4_udp,</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ default = Pass</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+layer3_ipv4 = "layer3_ipv4" / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "layer" / Computed(3),</span><br><span style="color: hsl(120, 100%, 40%);">+ "packet_type" / Computed("IPv4"),</span><br><span style="color: hsl(120, 100%, 40%);">+ "header" / ipv4_header,</span><br><span style="color: hsl(120, 100%, 40%);">+ layer3_payload,</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+layer3_ipv6 = "layer3_ipv6" / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "layer" / Computed(3),</span><br><span style="color: hsl(120, 100%, 40%);">+ "packet_type" / Computed("IPv6"),</span><br><span style="color: hsl(120, 100%, 40%);">+ "header" / ipv6_header,</span><br><span style="color: hsl(120, 100%, 40%);">+ layer3_payload,</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+layer2_ethernet = "layer2_ethernet" / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "layer" / Computed(2),</span><br><span style="color: hsl(120, 100%, 40%);">+ "packet_type" / Computed("ETHERNET"),</span><br><span style="color: hsl(120, 100%, 40%);">+ "header" / ethernet_header,</span><br><span style="color: hsl(120, 100%, 40%);">+ "next" / Switch(lambda ctx: ctx["header"].type,</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+ "IPv4" : layer3_ipv4,</span><br><span style="color: hsl(120, 100%, 40%);">+ "IPv6" : layer3_ipv6,</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ default = Pass,</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ip_stack = "ip_stack" / layer2_ethernet</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+ cap1 = unhexlify(</span><br><span style="color: hsl(120, 100%, 40%);">+ "0011508c283c001150886b570800450001e971474000800684e4c0a80202525eedda11"</span><br><span style="color: hsl(120, 100%, 40%);">+ "2a0050d98ec61d54fe977d501844705dcc0000474554202f20485454502f312e310d0a"</span><br><span style="color: hsl(120, 100%, 40%);">+ "486f73743a207777772e707974686f6e2e6f72670d0a557365722d4167656e743a204d"</span><br><span style="color: hsl(120, 100%, 40%);">+ "6f7a696c6c612f352e30202857696e646f77733b20553b2057696e646f7773204e5420"</span><br><span style="color: hsl(120, 100%, 40%);">+ "352e313b20656e2d55533b2072763a312e382e302e3129204765636b6f2f3230303630"</span><br><span style="color: hsl(120, 100%, 40%);">+ "3131312046697265666f782f312e352e302e310d0a4163636570743a20746578742f78"</span><br><span style="color: hsl(120, 100%, 40%);">+ "6d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d"</span><br><span style="color: hsl(120, 100%, 40%);">+ "6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d"</span><br><span style="color: hsl(120, 100%, 40%);">+ "302e382c696d6167652f706e672c2a2f2a3b713d302e350d0a4163636570742d4c616e"</span><br><span style="color: hsl(120, 100%, 40%);">+ "67756167653a20656e2d75732c656e3b713d302e350d0a4163636570742d456e636f64"</span><br><span style="color: hsl(120, 100%, 40%);">+ "696e673a20677a69702c6465666c6174650d0a4163636570742d436861727365743a20"</span><br><span style="color: hsl(120, 100%, 40%);">+ "49534f2d383835392d312c7574662d383b713d302e372c2a3b713d302e370d0a4b6565"</span><br><span style="color: hsl(120, 100%, 40%);">+ "702d416c6976653a203330300d0a436f6e6e656374696f6e3a206b6565702d616c6976"</span><br><span style="color: hsl(120, 100%, 40%);">+ "650d0a507261676d613a206e6f2d63616368650d0a43616368652d436f6e74726f6c3a"</span><br><span style="color: hsl(120, 100%, 40%);">+ "206e6f2d63616368650d0a0d0a"</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ cap2 = unhexlify(</span><br><span style="color: hsl(120, 100%, 40%);">+ "0002e3426009001150f2c280080045900598fd22000036063291d149baeec0a8023c00"</span><br><span style="color: hsl(120, 100%, 40%);">+ "500cc33b8aa7dcc4e588065010ffffcecd0000485454502f312e3120323030204f4b0d"</span><br><span style="color: hsl(120, 100%, 40%);">+ "0a446174653a204672692c2031352044656320323030362032313a32363a323520474d"</span><br><span style="color: hsl(120, 100%, 40%);">+ "540d0a5033503a20706f6c6963797265663d22687474703a2f2f7033702e7961686f6f"</span><br><span style="color: hsl(120, 100%, 40%);">+ "2e636f6d2f7733632f7033702e786d6c222c2043503d2243414f2044535020434f5220"</span><br><span style="color: hsl(120, 100%, 40%);">+ "4355522041444d20444556205441492050534120505344204956416920495644692043"</span><br><span style="color: hsl(120, 100%, 40%);">+ "4f4e692054454c6f204f545069204f55522044454c692053414d69204f54526920554e"</span><br><span style="color: hsl(120, 100%, 40%);">+ "5269205055426920494e4420504859204f4e4c20554e49205055522046494e20434f4d"</span><br><span style="color: hsl(120, 100%, 40%);">+ "204e415620494e542044454d20434e542053544120504f4c204845412050524520474f"</span><br><span style="color: hsl(120, 100%, 40%);">+ "56220d0a43616368652d436f6e74726f6c3a20707269766174650d0a566172793a2055"</span><br><span style="color: hsl(120, 100%, 40%);">+ "7365722d4167656e740d0a5365742d436f6f6b69653a20443d5f796c683d58336f444d"</span><br><span style="color: hsl(120, 100%, 40%);">+ "54466b64476c6f5a7a567842463954417a49334d5459784e446b4563476c6b417a4578"</span><br><span style="color: hsl(120, 100%, 40%);">+ "4e6a59794d5463314e5463456447567a64414d7742485274634777446157356b5a5867"</span><br><span style="color: hsl(120, 100%, 40%);">+ "7462412d2d3b20706174683d2f3b20646f6d61696e3d2e7961686f6f2e636f6d0d0a43"</span><br><span style="color: hsl(120, 100%, 40%);">+ "6f6e6e656374696f6e3a20636c6f73650d0a5472616e736665722d456e636f64696e67"</span><br><span style="color: hsl(120, 100%, 40%);">+ "3a206368756e6b65640d0a436f6e74656e742d547970653a20746578742f68746d6c3b"</span><br><span style="color: hsl(120, 100%, 40%);">+ "20636861727365743d7574662d380d0a436f6e74656e742d456e636f64696e673a2067"</span><br><span style="color: hsl(120, 100%, 40%);">+ "7a69700d0a0d0a366263382020200d0a1f8b0800000000000003dcbd6977db38b200fa"</span><br><span style="color: hsl(120, 100%, 40%);">+ "f9fa9cf90f88326dd9b1169212b5d891739cd84ed2936d1277a7d3cbf1a1484a624c91"</span><br><span style="color: hsl(120, 100%, 40%);">+ "0c4979893bbfec7d7bbfec556121012eb29d65e6be7be7762c9240a1502854150a85c2"</span><br><span style="color: hsl(120, 100%, 40%);">+ "c37b87af9f9c7c7873449e9dbc7c41defcf2f8c5f327a4d1ee76dff79e74bb872787ec"</span><br><span style="color: hsl(120, 100%, 40%);">+ "43bfa3e9ddeed1ab06692cd234daed762f2e2e3a17bd4e18cfbb276fbb8b74e9f7bb49"</span><br><span style="color: hsl(120, 100%, 40%);">+ "1a7b76da7152a7b1bff110dfed3f5cb896030f4b37b508566dbb9f56def9a4f1240c52"</span><br><span style="color: hsl(120, 100%, 40%);">+ "3748db275791db20367b9a3452f732a5d0f688bdb0e2c44d27bf9c1cb7470830b1632f"</span><br><span style="color: hsl(120, 100%, 40%);">+ "4a490a3578c18fd6b9c5dec2f7732b2641783109dc0b7268a56e2bd527a931497b93b4"</span><br><span style="color: hsl(120, 100%, 40%);">+ "3f49cd493a98a4c3493a9aa4e349aa6bf01f7cd78d89d6b2ed49b3d9baf223f8b307b5"</span><br><span style="color: hsl(120, 100%, 40%);">+ "004a67eea627ded2dddadedb78d8656de428f856305f5973779223b0fff05ebbbde1db"</span><br><span style="color: hsl(120, 100%, 40%);">+ "67082a499289ae0f06863e1c8f4c0639eaccbdd9a3547abf798a1f0ec6c73fafd2e4f1"</span><br><span style="color: hsl(120, 100%, 40%);">+ "51ffd5f1c9e2f9e37ff74e74fbddd941b375eadb0942b3e3d5723a69f6060373a6cff4"</span><br><span style="color: hsl(120, 100%, 40%);">+ "9e6df586dac8b11c4d1f1afd81319b0df45e6fd4925a6cee6db4dbfb19e225bc1b12e5"</span><br><span style="color: hsl(120, 100%, 40%);">+ "6a098aed9309715c3b74dc5fde3e7f122ea3308061dac22f4018a4f8878367af5f4f2e"</span><br><span style="color: hsl(120, 100%, 40%);">+ "bcc001a2d187bfffbefeb2477f75026be9269165bb93d92ab0532f0cb68264fbda9b6d"</span><br><span style="color: hsl(120, 100%, 40%);">+ "dd0b92bfff867f3abe1bccd3c5f675eca6ab3820c1caf7f7be20e05363029f93c8f7d2"</span><br><span style="color: hsl(120, 100%, 40%);">+ "ad46a7b1bd475ff62614f2de2c8cb7f08537d93a35fed0fe9a4c1af44363fb91beabed"</span><br><span style="color: hsl(120, 100%, 40%);">+ "790f4f0d0e7a6f67c7dbbe3eedfd01e5bcbffe9a64bf289e00307bb1f7852371dadb13"</span><br><span style="color: hsl(120, 100%, 40%);">+ "3df0c3798efba9d93a1db44e87dbd7d8b4cf50e95c780e304be745389fbbf11ef4cddf"</span><br><span style="color: hsl(120, 100%, 40%);">+ "dcf4b162d629fa94d7defbe2fa892b3ece2c78d8fb221a84517003476a73dc3ad535d6"</span><br><span style="color: hsl(120, 100%, 40%);">+ "e22c7fbd0db8cf3a511ca6211d3e28933fed9d8ea54f381f66c0c7f2cb0e4c3898ad2b"</span><br><span style="color: hsl(120, 100%, 40%);">+ "3b0de3c9e918bf25abc88d6ddf02d65581418f94174addc9ebe94717e67ce557207b6d"</span><br><span style="color: hsl(120, 100%, 40%);">+ "45f892773ae393adc62af57c18ecd27b46e5aa2feea5b58c7c173e6d94be1d3bd5afa3"</span><br><span style="color: hsl(120, 100%, 40%);">+ "fcf571d409ded9b1eb06ef3d275d00c36f25f4916c6ed2a911cef88b0e4c0ecfa7a5b6"</span><br><span style="color: hsl(120, 100%, 40%);">+ "27936600b3d28d9bdbe411"</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ obj = ip_stack.parse(cap1)</span><br><span style="color: hsl(120, 100%, 40%);">+ print (obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ # Print just the payload</span><br><span style="color: hsl(120, 100%, 40%);">+ print (obj.next.next.next)</span><br><span style="color: hsl(120, 100%, 40%);">+ built = ip_stack.build(obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ assert built == cap1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ print ("-" * 80)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ obj = ip_stack.parse(cap2)</span><br><span style="color: hsl(120, 100%, 40%);">+ print (obj.next.next.header)</span><br><span style="color: hsl(120, 100%, 40%);">+ built = ip_stack.build(obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ assert built == cap2</span><br><span>diff --git a/lib/python/protocols/layer2/__init__.py b/lib/python/protocols/layer2/__init__.py</span><br><span>new file mode 100644</span><br><span>index 0000000..bdcdb4a</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/layer2/__init__.py</span><br><span>@@ -0,0 +1,4 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+layer 2 (data link) protocols</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/lib/python/protocols/layer2/arp.py b/lib/python/protocols/layer2/arp.py</span><br><span>new file mode 100644</span><br><span>index 0000000..a88acfa</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/layer2/arp.py</span><br><span>@@ -0,0 +1,103 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+Ethernet (TCP/IP protocol stack)</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+from binascii import unhexlify</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from construct.core import *</span><br><span style="color: hsl(120, 100%, 40%);">+from protocols.layer3.ipv4 import IpAddress</span><br><span style="color: hsl(120, 100%, 40%);">+from ethernet import MacAddress</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+'''</span><br><span style="color: hsl(120, 100%, 40%);">+def HwAddress(name):</span><br><span style="color: hsl(120, 100%, 40%);">+ return IfThenElse(name, lambda ctx: ctx.hardware_type == "ETHERNET",</span><br><span style="color: hsl(120, 100%, 40%);">+ MacAddressAdapter(Field("data", lambda ctx: ctx.hwaddr_length)),</span><br><span style="color: hsl(120, 100%, 40%);">+ Field("data", lambda ctx: ctx.hwaddr_length)</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def ProtoAddress(name):</span><br><span style="color: hsl(120, 100%, 40%);">+ return IfThenElse(name, lambda ctx: ctx.protocol_type == "IP",</span><br><span style="color: hsl(120, 100%, 40%);">+ IpAddressAdapter(Field("data", lambda ctx: ctx.protoaddr_length)),</span><br><span style="color: hsl(120, 100%, 40%);">+ Field("data", lambda ctx: ctx.protoaddr_length)</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+'''</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def HardwareTypeEnum(code):</span><br><span style="color: hsl(120, 100%, 40%);">+ return Enum(code,</span><br><span style="color: hsl(120, 100%, 40%);">+ ETHERNET = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ EXPERIMENTAL_ETHERNET = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ ProNET_TOKEN_RING = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ CHAOS = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+ IEEE802 = 6,</span><br><span style="color: hsl(120, 100%, 40%);">+ ARCNET = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+ HYPERCHANNEL = 8,</span><br><span style="color: hsl(120, 100%, 40%);">+ ULTRALINK = 13,</span><br><span style="color: hsl(120, 100%, 40%);">+ FRAME_RELAY = 15,</span><br><span style="color: hsl(120, 100%, 40%);">+ FIBRE_CHANNEL = 18,</span><br><span style="color: hsl(120, 100%, 40%);">+ IEEE1394 = 24,</span><br><span style="color: hsl(120, 100%, 40%);">+ HIPARP = 28,</span><br><span style="color: hsl(120, 100%, 40%);">+ ISO7816_3 = 29,</span><br><span style="color: hsl(120, 100%, 40%);">+ ARPSEC = 30,</span><br><span style="color: hsl(120, 100%, 40%);">+ IPSEC_TUNNEL = 31,</span><br><span style="color: hsl(120, 100%, 40%);">+ INFINIBAND = 32,</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def OpcodeEnum(code):</span><br><span style="color: hsl(120, 100%, 40%);">+ return Enum(code,</span><br><span style="color: hsl(120, 100%, 40%);">+ REQUEST = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ REPLY = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ REQUEST_REVERSE = 3,</span><br><span style="color: hsl(120, 100%, 40%);">+ REPLY_REVERSE = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ DRARP_REQUEST = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+ DRARP_REPLY = 6,</span><br><span style="color: hsl(120, 100%, 40%);">+ DRARP_ERROR = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+ InARP_REQUEST = 8,</span><br><span style="color: hsl(120, 100%, 40%);">+ InARP_REPLY = 9,</span><br><span style="color: hsl(120, 100%, 40%);">+ ARP_NAK = 10</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+arp_header = "arp_header" / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "hardware_type" / HardwareTypeEnum(Int16ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "protocol_type" / Enum(Int16ub,</span><br><span style="color: hsl(120, 100%, 40%);">+ IP = 0x0800,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ "hwaddr_length" / Int8ub,</span><br><span style="color: hsl(120, 100%, 40%);">+ "protoaddr_length" / Int8ub,</span><br><span style="color: hsl(120, 100%, 40%);">+ "opcode" / OpcodeEnum(Int16ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "source_hwaddr" / MacAddress(),</span><br><span style="color: hsl(120, 100%, 40%);">+ "source_protoaddr" / IpAddress(),</span><br><span style="color: hsl(120, 100%, 40%);">+ "dest_hwaddr" / MacAddress(),</span><br><span style="color: hsl(120, 100%, 40%);">+ "dest_protoaddr" / IpAddress(),</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+rarp_header = "rarp_header" / arp_header</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+ cap1 = unhexlify(b"00010800060400010002e3426009c0a80204000000000000c0a80201")</span><br><span style="color: hsl(120, 100%, 40%);">+ obj = arp_header.parse(cap1)</span><br><span style="color: hsl(120, 100%, 40%);">+ print (obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ built = arp_header.build(obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ print(repr(built))</span><br><span style="color: hsl(120, 100%, 40%);">+ assert built == cap1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ print ("-" * 80)</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+ cap2 = unhexlify(b"00010800060400020011508c283cc0a802010002e3426009c0a80204")</span><br><span style="color: hsl(120, 100%, 40%);">+ obj = arp_header.parse(cap2)</span><br><span style="color: hsl(120, 100%, 40%);">+ print (obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ built = arp_header.build(obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ print(repr(built))</span><br><span style="color: hsl(120, 100%, 40%);">+ assert built == cap2</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/lib/python/protocols/layer2/ethernet.py b/lib/python/protocols/layer2/ethernet.py</span><br><span>new file mode 100644</span><br><span>index 0000000..15a52aa</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/layer2/ethernet.py</span><br><span>@@ -0,0 +1,40 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+Ethernet (TCP/IP protocol stack)</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+from binascii import hexlify, unhexlify</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from construct.core import *</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class MacAddressAdapter(Adapter):</span><br><span style="color: hsl(120, 100%, 40%);">+ def _encode(self, obj, context, path):</span><br><span style="color: hsl(120, 100%, 40%);">+ return unhexlify(obj.replace("-", ""))</span><br><span style="color: hsl(120, 100%, 40%);">+ def _decode(self, obj, context, path):</span><br><span style="color: hsl(120, 100%, 40%);">+ return "-".join(hexlify(b) for b in obj)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def MacAddress():</span><br><span style="color: hsl(120, 100%, 40%);">+ return MacAddressAdapter(Bytes(6))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ethernet_header = "ethernet_header" / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "destination" / MacAddress(),</span><br><span style="color: hsl(120, 100%, 40%);">+ "source" / MacAddress(),</span><br><span style="color: hsl(120, 100%, 40%);">+ "type" / Enum(Int16ub,</span><br><span style="color: hsl(120, 100%, 40%);">+ IPv4=0x0800,</span><br><span style="color: hsl(120, 100%, 40%);">+ ARP=0x0806,</span><br><span style="color: hsl(120, 100%, 40%);">+ RARP=0x8035,</span><br><span style="color: hsl(120, 100%, 40%);">+ X25=0x0805,</span><br><span style="color: hsl(120, 100%, 40%);">+ IPX=0x8137,</span><br><span style="color: hsl(120, 100%, 40%);">+ IPv6=0x86DD</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+ cap = unhexlify(b"0011508c283c0002e34260090800")</span><br><span style="color: hsl(120, 100%, 40%);">+ obj = ethernet_header.parse(cap)</span><br><span style="color: hsl(120, 100%, 40%);">+ print (obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ built = ethernet_header.build(obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ print(repr(built))</span><br><span style="color: hsl(120, 100%, 40%);">+ assert built == cap</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/lib/python/protocols/layer2/mtp2.py b/lib/python/protocols/layer2/mtp2.py</span><br><span>new file mode 100644</span><br><span>index 0000000..c73ade9</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/layer2/mtp2.py</span><br><span>@@ -0,0 +1,30 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+Message Transport Part 2 (SS7 protocol stack)</span><br><span style="color: hsl(120, 100%, 40%);">+(untested)</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from binascii import unhexlify</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+mtp2_header = "mtp2_header" / BitStruct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "flag1" / Octet,</span><br><span style="color: hsl(120, 100%, 40%);">+ "bsn" / BitsInteger(7),</span><br><span style="color: hsl(120, 100%, 40%);">+ "bib" / Bit,</span><br><span style="color: hsl(120, 100%, 40%);">+ "fsn" / BitsInteger(7),</span><br><span style="color: hsl(120, 100%, 40%);">+ "sib" / Bit,</span><br><span style="color: hsl(120, 100%, 40%);">+ "length" / Octet,</span><br><span style="color: hsl(120, 100%, 40%);">+ "service_info" / Octet,</span><br><span style="color: hsl(120, 100%, 40%);">+ "signalling_info" / Octet,</span><br><span style="color: hsl(120, 100%, 40%);">+ "crc" / BitsInteger(16),</span><br><span style="color: hsl(120, 100%, 40%);">+ "flag2" / Octet,</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+ cap = unhexlify(b"0bcc003500280689aa")</span><br><span style="color: hsl(120, 100%, 40%);">+ obj = mtp2_header.parse(cap)</span><br><span style="color: hsl(120, 100%, 40%);">+ print (obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ built = mtp2_header.build(obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ print(repr(built))</span><br><span style="color: hsl(120, 100%, 40%);">+ assert cap == built</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/lib/python/protocols/layer3/__init__.py b/lib/python/protocols/layer3/__init__.py</span><br><span>new file mode 100644</span><br><span>index 0000000..4477713</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/layer3/__init__.py</span><br><span>@@ -0,0 +1,4 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+layer 3 (network) protocols</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/lib/python/protocols/layer3/ipv4.py b/lib/python/protocols/layer3/ipv4.py</span><br><span>new file mode 100644</span><br><span>index 0000000..2ea0ad9</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/layer3/ipv4.py</span><br><span>@@ -0,0 +1,73 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+Internet Protocol version 4 (TCP/IP protocol stack)</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+from binascii import unhexlify</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from construct.core import *</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class IpAddressAdapter(Adapter):</span><br><span style="color: hsl(120, 100%, 40%);">+ def _encode(self, obj, context, path):</span><br><span style="color: hsl(120, 100%, 40%);">+ return "".join(chr(int(b)) for b in obj.split("."))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def _decode(self, obj, context, path):</span><br><span style="color: hsl(120, 100%, 40%);">+ return ".".join(str(ord(b)) for b in obj)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def IpAddress():</span><br><span style="color: hsl(120, 100%, 40%);">+ return IpAddressAdapter(Bytes(4))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def ProtocolEnum(code):</span><br><span style="color: hsl(120, 100%, 40%);">+ return Enum(code,</span><br><span style="color: hsl(120, 100%, 40%);">+ ICMP = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ TCP = 6,</span><br><span style="color: hsl(120, 100%, 40%);">+ UDP = 17,</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ipv4_header = "ip_header" / BitStruct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "version" / Nibble,</span><br><span style="color: hsl(120, 100%, 40%);">+ "header_length" / ExprAdapter(Nibble,</span><br><span style="color: hsl(120, 100%, 40%);">+ lambda obj, ctx: obj * 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ lambda obj, ctx: obj / 4</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ "tos" / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "precedence" / BitsInteger(3),</span><br><span style="color: hsl(120, 100%, 40%);">+ "minimize_delay" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ "high_throuput" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ "high_reliability" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ "minimize_cost" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ Padding(1),</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ "total_length" / Bytewise(Int16ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "payload_length" / Computed(lambda ctx: ctx.total_length - ctx.header_length),</span><br><span style="color: hsl(120, 100%, 40%);">+ "identification" / Bytewise(Int16ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "flags" / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ Padding(1),</span><br><span style="color: hsl(120, 100%, 40%);">+ "dont_fragment" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ "more_fragments" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ "frame_offset" / BitsInteger(13),</span><br><span style="color: hsl(120, 100%, 40%);">+ "ttl" / Bytewise(Int8ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "protocol" / Bytewise(ProtocolEnum(Int8ub)),</span><br><span style="color: hsl(120, 100%, 40%);">+ "checksum" / Bytewise(Int16ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "source" / Bytewise(IpAddress()),</span><br><span style="color: hsl(120, 100%, 40%);">+ "destination" / Bytewise(IpAddress()),</span><br><span style="color: hsl(120, 100%, 40%);">+ "options" / Computed(lambda ctx: ctx.header_length - 20),</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+ cap = unhexlify(b"4600003ca0e3000080116185c0a80205d474a126")</span><br><span style="color: hsl(120, 100%, 40%);">+ obj = ipv4_header.parse(cap)</span><br><span style="color: hsl(120, 100%, 40%);">+ print (obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ built = ipv4_header.build(obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ print(repr(built))</span><br><span style="color: hsl(120, 100%, 40%);">+ assert built == cap</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/lib/python/protocols/layer3/ipv6.py b/lib/python/protocols/layer3/ipv6.py</span><br><span>new file mode 100644</span><br><span>index 0000000..cfc345b</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/layer3/ipv6.py</span><br><span>@@ -0,0 +1,39 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+Internet Protocol version 6 (TCP/IP protocol stack)</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+from binascii import unhexlify</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from construct.core import *</span><br><span style="color: hsl(120, 100%, 40%);">+from protocols.layer3.ipv4 import ProtocolEnum</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class Ipv6AddressAdapter(Adapter):</span><br><span style="color: hsl(120, 100%, 40%);">+ def _encode(self, obj, context, path):</span><br><span style="color: hsl(120, 100%, 40%);">+ return "".join(part.decode("hex") for part in obj.split(":"))</span><br><span style="color: hsl(120, 100%, 40%);">+ def _decode(self, obj, context, path):</span><br><span style="color: hsl(120, 100%, 40%);">+ return ":".join(b.encode("hex") for b in obj)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def Ipv6Address():</span><br><span style="color: hsl(120, 100%, 40%);">+ return Ipv6AddressAdapter(Bytes(16))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ipv6_header = "ip_header" / BitStruct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "version" / OneOf(BitsInteger(4), [6]),</span><br><span style="color: hsl(120, 100%, 40%);">+ "traffic_class" / BitsInteger(8),</span><br><span style="color: hsl(120, 100%, 40%);">+ "flow_label" / BitsInteger(20),</span><br><span style="color: hsl(120, 100%, 40%);">+ "payload_length" / Bytewise(Int16ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "protocol" / Bytewise(ProtocolEnum(Int8ub)),</span><br><span style="color: hsl(120, 100%, 40%);">+ "ttl" / Bytewise(Int8ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "source" / Bytewise(Ipv6Address()),</span><br><span style="color: hsl(120, 100%, 40%);">+ "destination" / Bytewise(Ipv6Address()),</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+ cap = unhexlify(b"6ff0000001020680" b"0123456789ABCDEF" b"FEDCBA9876543210" b"FEDCBA9876543210" b"0123456789ABCDEF")</span><br><span style="color: hsl(120, 100%, 40%);">+ obj = ipv6_header.parse(cap)</span><br><span style="color: hsl(120, 100%, 40%);">+ print (obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ built = ipv6_header.build(obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ print(repr(built))</span><br><span style="color: hsl(120, 100%, 40%);">+ assert built == cap</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/lib/python/protocols/layer4/__init__.py b/lib/python/protocols/layer4/__init__.py</span><br><span>new file mode 100644</span><br><span>index 0000000..38693c6</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/layer4/__init__.py</span><br><span>@@ -0,0 +1,4 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+layer 4 (transporation) protocols</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/lib/python/protocols/layer4/tcp.py b/lib/python/protocols/layer4/tcp.py</span><br><span>new file mode 100644</span><br><span>index 0000000..b2d3162</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/layer4/tcp.py</span><br><span>@@ -0,0 +1,63 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+Transmission Control Protocol (TCP/IP protocol stack)</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+from binascii import unhexlify</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from construct.core import *</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+setGlobalPrintFullStrings(True)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+tcp_header = "tcp_header" / BitStruct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "source" / Bytewise(Int16ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "destination" / Bytewise(Int16ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "seq" / Bytewise(Int32ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "ack" / Bytewise(Int32ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "header_length" / ExprAdapter(Nibble,</span><br><span style="color: hsl(120, 100%, 40%);">+ encoder = lambda obj, ctx: obj / 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ decoder = lambda obj, ctx: obj * 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ Padding(3),</span><br><span style="color: hsl(120, 100%, 40%);">+ "flags" / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "ns" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ "cwr" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ "ece" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ "urg" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ "ack" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ "psh" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ "rst" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ "syn" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ "fin" / Flag,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ "window" / Bytewise(Int16ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "checksum" / Bytewise(Int16ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "urgent" / Bytewise(Int16ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ "options" / Computed(lambda ctx: ctx.header_length - 20),</span><br><span style="color: hsl(120, 100%, 40%);">+# "_payload" / Bytewise(GreedyBytes),</span><br><span style="color: hsl(120, 100%, 40%);">+# "payload_length" / Computed(lambda ctx: len(ctx._payload)),</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+ cap = unhexlify(b"0db5005062303fb21836e9e650184470c9bc000031323334")</span><br><span style="color: hsl(120, 100%, 40%);">+ obj = tcp_header.parse(cap)</span><br><span style="color: hsl(120, 100%, 40%);">+ print (obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ built = tcp_header.build(obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ print(repr(built))</span><br><span style="color: hsl(120, 100%, 40%);">+ assert cap == built</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/lib/python/protocols/layer4/udp.py b/lib/python/protocols/layer4/udp.py</span><br><span>new file mode 100644</span><br><span>index 0000000..6b4bcb1</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/layer4/udp.py</span><br><span>@@ -0,0 +1,29 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+User Datagram Protocol (TCP/IP protocol stack)</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+from binascii import unhexlify</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from construct.core import *</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+udp_header = "udp_header" / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ "header_length" / Computed(lambda ctx: 8),</span><br><span style="color: hsl(120, 100%, 40%);">+ "source" / Int16ub,</span><br><span style="color: hsl(120, 100%, 40%);">+ "destination" / Int16ub,</span><br><span style="color: hsl(120, 100%, 40%);">+ "payload_length" / ExprAdapter(Int16ub,</span><br><span style="color: hsl(120, 100%, 40%);">+ encoder = lambda obj, ctx: obj + 8,</span><br><span style="color: hsl(120, 100%, 40%);">+ decoder = lambda obj, ctx: obj - 8,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ "checksum" / Int16ub,</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+ cap = unhexlify(b"0bcc003500280689")</span><br><span style="color: hsl(120, 100%, 40%);">+ obj = udp_header.parse(cap)</span><br><span style="color: hsl(120, 100%, 40%);">+ print (obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ built = udp_header.build(obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ print(repr(built))</span><br><span style="color: hsl(120, 100%, 40%);">+ assert cap == built</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/lib/python/protocols/unconverted/application/dns.py b/lib/python/protocols/unconverted/application/dns.py</span><br><span>new file mode 100644</span><br><span>index 0000000..d157227</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/unconverted/application/dns.py</span><br><span>@@ -0,0 +1,143 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+Domain Name System (TCP/IP protocol stack)</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+from binascii import unhexlify</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from construct.protocols.layer3.ipv4 import IpAddressAdapter</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class DnsStringAdapter(Adapter):</span><br><span style="color: hsl(120, 100%, 40%);">+ def _encode(self, obj, context):</span><br><span style="color: hsl(120, 100%, 40%);">+ parts = obj.split(".")</span><br><span style="color: hsl(120, 100%, 40%);">+ parts.append("")</span><br><span style="color: hsl(120, 100%, 40%);">+ return parts</span><br><span style="color: hsl(120, 100%, 40%);">+ def _decode(self, obj, context):</span><br><span style="color: hsl(120, 100%, 40%);">+ return ".".join(obj[:-1])</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+dns_record_class = Enum(UBInt16("class"),</span><br><span style="color: hsl(120, 100%, 40%);">+ RESERVED = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ INTERNET = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ CHAOS = 3,</span><br><span style="color: hsl(120, 100%, 40%);">+ HESIOD = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ NONE = 254,</span><br><span style="color: hsl(120, 100%, 40%);">+ ANY = 255,</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+dns_record_type = Enum(UBInt16("type"),</span><br><span style="color: hsl(120, 100%, 40%);">+ IPv4 = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ AUTHORITIVE_NAME_SERVER = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ CANONICAL_NAME = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+ NULL = 10,</span><br><span style="color: hsl(120, 100%, 40%);">+ MAIL_EXCHANGE = 15,</span><br><span style="color: hsl(120, 100%, 40%);">+ TEXT = 16,</span><br><span style="color: hsl(120, 100%, 40%);">+ X25 = 19,</span><br><span style="color: hsl(120, 100%, 40%);">+ ISDN = 20,</span><br><span style="color: hsl(120, 100%, 40%);">+ IPv6 = 28,</span><br><span style="color: hsl(120, 100%, 40%);">+ UNSPECIFIED = 103,</span><br><span style="color: hsl(120, 100%, 40%);">+ ALL = 255,</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+query_record = Struct("query_record",</span><br><span style="color: hsl(120, 100%, 40%);">+ DnsStringAdapter(</span><br><span style="color: hsl(120, 100%, 40%);">+ RepeatUntil(lambda obj, ctx: obj == "",</span><br><span style="color: hsl(120, 100%, 40%);">+ PascalString("name")</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ dns_record_type,</span><br><span style="color: hsl(120, 100%, 40%);">+ dns_record_class,</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+rdata = Field("rdata", lambda ctx: ctx.rdata_length)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+resource_record = Struct("resource_record",</span><br><span style="color: hsl(120, 100%, 40%);">+ CString("name", terminators = b"\xc0\x00"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Padding(1),</span><br><span style="color: hsl(120, 100%, 40%);">+ dns_record_type,</span><br><span style="color: hsl(120, 100%, 40%);">+ dns_record_class,</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt32("ttl"),</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt16("rdata_length"),</span><br><span style="color: hsl(120, 100%, 40%);">+ IfThenElse("data", lambda ctx: ctx.type == "IPv4",</span><br><span style="color: hsl(120, 100%, 40%);">+ IpAddressAdapter(rdata),</span><br><span style="color: hsl(120, 100%, 40%);">+ rdata</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+dns = Struct("dns",</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt16("id"),</span><br><span style="color: hsl(120, 100%, 40%);">+ BitStruct("flags",</span><br><span style="color: hsl(120, 100%, 40%);">+ Enum(Bit("type"),</span><br><span style="color: hsl(120, 100%, 40%);">+ QUERY = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ RESPONSE = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ Enum(Nibble("opcode"),</span><br><span style="color: hsl(120, 100%, 40%);">+ STANDARD_QUERY = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ INVERSE_QUERY = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ SERVER_STATUS_REQUEST = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ NOTIFY = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ UPDATE = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ Flag("authoritive_answer"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Flag("truncation"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Flag("recurssion_desired"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Flag("recursion_available"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Padding(1),</span><br><span style="color: hsl(120, 100%, 40%);">+ Flag("authenticated_data"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Flag("checking_disabled"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Enum(Nibble("response_code"),</span><br><span style="color: hsl(120, 100%, 40%);">+ SUCCESS = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ FORMAT_ERROR = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ SERVER_FAILURE = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ NAME_DOES_NOT_EXIST = 3,</span><br><span style="color: hsl(120, 100%, 40%);">+ NOT_IMPLEMENTED = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ REFUSED = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+ NAME_SHOULD_NOT_EXIST = 6,</span><br><span style="color: hsl(120, 100%, 40%);">+ RR_SHOULD_NOT_EXIST = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+ RR_SHOULD_EXIST = 8,</span><br><span style="color: hsl(120, 100%, 40%);">+ NOT_AUTHORITIVE = 9,</span><br><span style="color: hsl(120, 100%, 40%);">+ NOT_ZONE = 10,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt16("question_count"),</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt16("answer_count"),</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt16("authority_count"),</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt16("additional_count"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Array(lambda ctx: ctx.question_count,</span><br><span style="color: hsl(120, 100%, 40%);">+ Rename("questions", query_record),</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ Rename("answers",</span><br><span style="color: hsl(120, 100%, 40%);">+ Array(lambda ctx: ctx.answer_count, resource_record)</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ Rename("authorities",</span><br><span style="color: hsl(120, 100%, 40%);">+ Array(lambda ctx: ctx.authority_count, resource_record)</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ Array(lambda ctx: ctx.additional_count,</span><br><span style="color: hsl(120, 100%, 40%);">+ Rename("additionals", resource_record),</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+ cap1 = unhexlify(b"2624010000010000000000000377777706676f6f676c6503636f6d0000010001")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ cap2 = unhexlify(six.b(</span><br><span style="color: hsl(120, 100%, 40%);">+ "2624818000010005000600060377777706676f6f676c6503636f6d0000010001c00c00"</span><br><span style="color: hsl(120, 100%, 40%);">+ "05000100089065000803777777016cc010c02c0001000100000004000440e9b768c02c"</span><br><span style="color: hsl(120, 100%, 40%);">+ "0001000100000004000440e9b793c02c0001000100000004000440e9b763c02c000100"</span><br><span style="color: hsl(120, 100%, 40%);">+ "0100000004000440e9b767c030000200010000a88600040163c030c030000200010000"</span><br><span style="color: hsl(120, 100%, 40%);">+ "a88600040164c030c030000200010000a88600040165c030c030000200010000a88600"</span><br><span style="color: hsl(120, 100%, 40%);">+ "040167c030c030000200010000a88600040161c030c030000200010000a88600040162"</span><br><span style="color: hsl(120, 100%, 40%);">+ "c030c0c00001000100011d0c0004d8ef3509c0d0000100010000ca7c000440e9b309c0"</span><br><span style="color: hsl(120, 100%, 40%);">+ "80000100010000c4c5000440e9a109c0900001000100004391000440e9b709c0a00001"</span><br><span style="color: hsl(120, 100%, 40%);">+ "00010000ca7c000442660b09c0b00001000100000266000440e9a709"</span><br><span style="color: hsl(120, 100%, 40%);">+ ))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ obj = dns.parse(cap1)</span><br><span style="color: hsl(120, 100%, 40%);">+ print (obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ print (repr(dns.build(obj)))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ print ("-" * 80)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ obj = dns.parse(cap2)</span><br><span style="color: hsl(120, 100%, 40%);">+ print (obj)</span><br><span style="color: hsl(120, 100%, 40%);">+ print (repr(dns.build(obj)))</span><br><span>diff --git a/lib/python/protocols/unconverted/layer3/dhcpv4.py b/lib/python/protocols/unconverted/layer3/dhcpv4.py</span><br><span>new file mode 100644</span><br><span>index 0000000..d0e5a07</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/unconverted/layer3/dhcpv4.py</span><br><span>@@ -0,0 +1,195 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+Dynamic Host Configuration Protocol for IPv4</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+http://www.networksorcery.com/enp/protocol/dhcp.htm</span><br><span style="color: hsl(120, 100%, 40%);">+http://www.networksorcery.com/enp/protocol/bootp/options.htm</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+from binascii import unhexlify</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from ipv4 import IpAddress</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+dhcp_option = Struct("dhcp_option",</span><br><span style="color: hsl(120, 100%, 40%);">+ Enum(Byte("code"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Pad = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ Subnet_Mask = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ Time_Offset = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ Router = 3,</span><br><span style="color: hsl(120, 100%, 40%);">+ Time_Server = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ Name_Server = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+ Domain_Name_Server = 6,</span><br><span style="color: hsl(120, 100%, 40%);">+ Log_Server = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+ Quote_Server = 8,</span><br><span style="color: hsl(120, 100%, 40%);">+ LPR_Server = 9,</span><br><span style="color: hsl(120, 100%, 40%);">+ Impress_Server = 10,</span><br><span style="color: hsl(120, 100%, 40%);">+ Resource_Location_Server = 11,</span><br><span style="color: hsl(120, 100%, 40%);">+ Host_Name = 12,</span><br><span style="color: hsl(120, 100%, 40%);">+ Boot_File_Size = 13,</span><br><span style="color: hsl(120, 100%, 40%);">+ Merit_Dump_File = 14,</span><br><span style="color: hsl(120, 100%, 40%);">+ Domain_Name = 15,</span><br><span style="color: hsl(120, 100%, 40%);">+ Swap_Server = 16,</span><br><span style="color: hsl(120, 100%, 40%);">+ Root_Path = 17,</span><br><span style="color: hsl(120, 100%, 40%);">+ Extensions_Path = 18,</span><br><span style="color: hsl(120, 100%, 40%);">+ IP_Forwarding_enabledisable = 19,</span><br><span style="color: hsl(120, 100%, 40%);">+ Nonlocal_Source_Routing_enabledisable = 20,</span><br><span style="color: hsl(120, 100%, 40%);">+ Policy_Filter = 21,</span><br><span style="color: hsl(120, 100%, 40%);">+ Maximum_Datagram_Reassembly_Size = 22,</span><br><span style="color: hsl(120, 100%, 40%);">+ Default_IP_TTL = 23,</span><br><span style="color: hsl(120, 100%, 40%);">+ Path_MTU_Aging_Timeout = 24,</span><br><span style="color: hsl(120, 100%, 40%);">+ Path_MTU_Plateau_Table = 25,</span><br><span style="color: hsl(120, 100%, 40%);">+ Interface_MTU = 26,</span><br><span style="color: hsl(120, 100%, 40%);">+ All_Subnets_are_Local = 27,</span><br><span style="color: hsl(120, 100%, 40%);">+ Broadcast_Address = 28,</span><br><span style="color: hsl(120, 100%, 40%);">+ Perform_Mask_Discovery = 29,</span><br><span style="color: hsl(120, 100%, 40%);">+ Mask_supplier = 30,</span><br><span style="color: hsl(120, 100%, 40%);">+ Perform_router_discovery = 31,</span><br><span style="color: hsl(120, 100%, 40%);">+ Router_solicitation_address = 32,</span><br><span style="color: hsl(120, 100%, 40%);">+ Static_routing_table = 33,</span><br><span style="color: hsl(120, 100%, 40%);">+ Trailer_encapsulation = 34,</span><br><span style="color: hsl(120, 100%, 40%);">+ ARP_cache_timeout = 35,</span><br><span style="color: hsl(120, 100%, 40%);">+ Ethernet_encapsulation = 36,</span><br><span style="color: hsl(120, 100%, 40%);">+ Default_TCP_TTL = 37,</span><br><span style="color: hsl(120, 100%, 40%);">+ TCP_keepalive_interval = 38,</span><br><span style="color: hsl(120, 100%, 40%);">+ TCP_keepalive_garbage = 39,</span><br><span style="color: hsl(120, 100%, 40%);">+ Network_Information_Service_domain = 40,</span><br><span style="color: hsl(120, 100%, 40%);">+ Network_Information_Servers = 41,</span><br><span style="color: hsl(120, 100%, 40%);">+ NTP_servers = 42,</span><br><span style="color: hsl(120, 100%, 40%);">+ Vendor_specific_information = 43,</span><br><span style="color: hsl(120, 100%, 40%);">+ NetBIOS_over_TCPIP_name_server = 44,</span><br><span style="color: hsl(120, 100%, 40%);">+ NetBIOS_over_TCPIP_Datagram_Distribution_Server = 45,</span><br><span style="color: hsl(120, 100%, 40%);">+ NetBIOS_over_TCPIP_Node_Type = 46,</span><br><span style="color: hsl(120, 100%, 40%);">+ NetBIOS_over_TCPIP_Scope = 47,</span><br><span style="color: hsl(120, 100%, 40%);">+ X_Window_System_Font_Server = 48,</span><br><span style="color: hsl(120, 100%, 40%);">+ X_Window_System_Display_Manager = 49,</span><br><span style="color: hsl(120, 100%, 40%);">+ Requested_IP_Address = 50,</span><br><span style="color: hsl(120, 100%, 40%);">+ IP_address_lease_time = 51,</span><br><span style="color: hsl(120, 100%, 40%);">+ Option_overload = 52,</span><br><span style="color: hsl(120, 100%, 40%);">+ DHCP_message_type = 53,</span><br><span style="color: hsl(120, 100%, 40%);">+ Server_identifier = 54,</span><br><span style="color: hsl(120, 100%, 40%);">+ Parameter_request_list = 55,</span><br><span style="color: hsl(120, 100%, 40%);">+ Message = 56,</span><br><span style="color: hsl(120, 100%, 40%);">+ Maximum_DHCP_message_size = 57,</span><br><span style="color: hsl(120, 100%, 40%);">+ Renew_time_value = 58,</span><br><span style="color: hsl(120, 100%, 40%);">+ Rebinding_time_value = 59,</span><br><span style="color: hsl(120, 100%, 40%);">+ Class_identifier = 60,</span><br><span style="color: hsl(120, 100%, 40%);">+ Client_identifier = 61,</span><br><span style="color: hsl(120, 100%, 40%);">+ NetWareIP_Domain_Name = 62,</span><br><span style="color: hsl(120, 100%, 40%);">+ NetWareIP_information = 63,</span><br><span style="color: hsl(120, 100%, 40%);">+ Network_Information_Service_Domain = 64,</span><br><span style="color: hsl(120, 100%, 40%);">+ Network_Information_Service_Servers = 65,</span><br><span style="color: hsl(120, 100%, 40%);">+ TFTP_server_name = 66,</span><br><span style="color: hsl(120, 100%, 40%);">+ Bootfile_name = 67,</span><br><span style="color: hsl(120, 100%, 40%);">+ Mobile_IP_Home_Agent = 68,</span><br><span style="color: hsl(120, 100%, 40%);">+ Simple_Mail_Transport_Protocol_Server = 69,</span><br><span style="color: hsl(120, 100%, 40%);">+ Post_Office_Protocol_Server = 70,</span><br><span style="color: hsl(120, 100%, 40%);">+ Network_News_Transport_Protocol_Server = 71,</span><br><span style="color: hsl(120, 100%, 40%);">+ Default_World_Wide_Web_Server = 72,</span><br><span style="color: hsl(120, 100%, 40%);">+ Default_Finger_Server = 73,</span><br><span style="color: hsl(120, 100%, 40%);">+ Default_Internet_Relay_Chat_Server = 74,</span><br><span style="color: hsl(120, 100%, 40%);">+ StreetTalk_Server = 75,</span><br><span style="color: hsl(120, 100%, 40%);">+ StreetTalk_Directory_Assistance_Server = 76,</span><br><span style="color: hsl(120, 100%, 40%);">+ User_Class_Information = 77,</span><br><span style="color: hsl(120, 100%, 40%);">+ SLP_Directory_Agent = 78,</span><br><span style="color: hsl(120, 100%, 40%);">+ SLP_Service_Scope = 79,</span><br><span style="color: hsl(120, 100%, 40%);">+ Rapid_Commit = 80,</span><br><span style="color: hsl(120, 100%, 40%);">+ Fully_Qualified_Domain_Name = 81,</span><br><span style="color: hsl(120, 100%, 40%);">+ Relay_Agent_Information = 82,</span><br><span style="color: hsl(120, 100%, 40%);">+ Internet_Storage_Name_Service = 83,</span><br><span style="color: hsl(120, 100%, 40%);">+ NDS_servers = 85,</span><br><span style="color: hsl(120, 100%, 40%);">+ NDS_tree_name = 86,</span><br><span style="color: hsl(120, 100%, 40%);">+ NDS_context = 87,</span><br><span style="color: hsl(120, 100%, 40%);">+ BCMCS_Controller_Domain_Name_list = 88,</span><br><span style="color: hsl(120, 100%, 40%);">+ BCMCS_Controller_IPv4_address_list = 89,</span><br><span style="color: hsl(120, 100%, 40%);">+ Authentication = 90,</span><br><span style="color: hsl(120, 100%, 40%);">+ Client_last_transaction_time = 91,</span><br><span style="color: hsl(120, 100%, 40%);">+ Associated_ip = 92,</span><br><span style="color: hsl(120, 100%, 40%);">+ Client_System_Architecture_Type = 93,</span><br><span style="color: hsl(120, 100%, 40%);">+ Client_Network_Interface_Identifier = 94,</span><br><span style="color: hsl(120, 100%, 40%);">+ Lightweight_Directory_Access_Protocol = 95,</span><br><span style="color: hsl(120, 100%, 40%);">+ Client_Machine_Identifier = 97,</span><br><span style="color: hsl(120, 100%, 40%);">+ Open_Group_User_Authentication = 98,</span><br><span style="color: hsl(120, 100%, 40%);">+ Autonomous_System_Number = 109,</span><br><span style="color: hsl(120, 100%, 40%);">+ NetInfo_Parent_Server_Address = 112,</span><br><span style="color: hsl(120, 100%, 40%);">+ NetInfo_Parent_Server_Tag = 113,</span><br><span style="color: hsl(120, 100%, 40%);">+ URL = 114,</span><br><span style="color: hsl(120, 100%, 40%);">+ Auto_Configure = 116,</span><br><span style="color: hsl(120, 100%, 40%);">+ Name_Service_Search = 117,</span><br><span style="color: hsl(120, 100%, 40%);">+ Subnet_Selection = 118,</span><br><span style="color: hsl(120, 100%, 40%);">+ DNS_domain_search_list = 119,</span><br><span style="color: hsl(120, 100%, 40%);">+ SIP_Servers_DHCP_Option = 120,</span><br><span style="color: hsl(120, 100%, 40%);">+ Classless_Static_Route_Option = 121,</span><br><span style="color: hsl(120, 100%, 40%);">+ CableLabs_Client_Configuration = 122,</span><br><span style="color: hsl(120, 100%, 40%);">+ GeoConf = 123,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ Switch("value", lambda ctx: ctx.code,</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+ # codes without any value</span><br><span style="color: hsl(120, 100%, 40%);">+ "Pad" : Pass,</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ # codes followed by length and value fields</span><br><span style="color: hsl(120, 100%, 40%);">+ default = Struct("value",</span><br><span style="color: hsl(120, 100%, 40%);">+ Byte("length"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Field("data", lambda ctx: ctx.length),</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+dhcp_header = Struct("dhcp_header",</span><br><span style="color: hsl(120, 100%, 40%);">+ Enum(Byte("opcode"),</span><br><span style="color: hsl(120, 100%, 40%);">+ BootRequest = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ BootReply = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ Enum(Byte("hardware_type"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Ethernet = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ Experimental_Ethernet = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ ProNET_Token_Ring = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ Chaos = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+ IEEE_802 = 6,</span><br><span style="color: hsl(120, 100%, 40%);">+ ARCNET = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+ Hyperchannel = 8,</span><br><span style="color: hsl(120, 100%, 40%);">+ Lanstar = 9,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ Byte("hardware_address_length"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Byte("hop_count"),</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt32("transaction_id"),</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt16("elapsed_time"),</span><br><span style="color: hsl(120, 100%, 40%);">+ BitStruct("flags",</span><br><span style="color: hsl(120, 100%, 40%);">+ Flag("boardcast"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Padding(15),</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ IpAddress("client_addr"),</span><br><span style="color: hsl(120, 100%, 40%);">+ IpAddress("your_addr"),</span><br><span style="color: hsl(120, 100%, 40%);">+ IpAddress("server_addr"),</span><br><span style="color: hsl(120, 100%, 40%);">+ IpAddress("relay_addr"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Bytes("client_hardware_addr", 16),</span><br><span style="color: hsl(120, 100%, 40%);">+ Bytes("server_host_name", 64),</span><br><span style="color: hsl(120, 100%, 40%);">+ Bytes("boot_filename", 128),</span><br><span style="color: hsl(120, 100%, 40%);">+ # BOOTP/DHCP options</span><br><span style="color: hsl(120, 100%, 40%);">+ # "The first four bytes contain the (decimal) values 99, 130, 83 and 99"</span><br><span style="color: hsl(120, 100%, 40%);">+ Const(Bytes("magic", 4), b"\x63\x82\x53\x63"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Rename("options", OptionalGreedyRange(dhcp_option)),</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+ test = unhexlify(six.b(</span><br><span style="color: hsl(120, 100%, 40%);">+ "0101060167c05f5a00000000"</span><br><span style="color: hsl(120, 100%, 40%);">+ "0102030405060708090a0b0c"</span><br><span style="color: hsl(120, 100%, 40%);">+ "0d0e0f10"</span><br><span style="color: hsl(120, 100%, 40%);">+ "DEADBEEFBEEF"</span><br><span style="color: hsl(120, 100%, 40%);">+ "000000000000000000000000000000000000000000000000000000"</span><br><span style="color: hsl(120, 100%, 40%);">+ "000000000000000000000000000000000000000000000000000000"</span><br><span style="color: hsl(120, 100%, 40%);">+ "000000000000000000000000000000000000000000000000000000"</span><br><span style="color: hsl(120, 100%, 40%);">+ "000000000000000000000000000000000000000000000000000000"</span><br><span style="color: hsl(120, 100%, 40%);">+ "000000000000000000000000000000000000000000000000000000"</span><br><span style="color: hsl(120, 100%, 40%);">+ "000000000000000000000000000000000000000000000000000000"</span><br><span style="color: hsl(120, 100%, 40%);">+ "000000000000000000000000000000000000000000000000000000"</span><br><span style="color: hsl(120, 100%, 40%);">+ "00000000000000000000000000"</span><br><span style="color: hsl(120, 100%, 40%);">+ "63825363"</span><br><span style="color: hsl(120, 100%, 40%);">+ "3501083d0701DEADBEEFBEEF0c04417375733c084d53465420352e"</span><br><span style="color: hsl(120, 100%, 40%);">+ "30370d010f03062c2e2f1f2179f92bfc52210117566c616e333338"</span><br><span style="color: hsl(120, 100%, 40%);">+ "382b45746865726e6574312f302f32340206f8f0827348f9ff"</span><br><span style="color: hsl(120, 100%, 40%);">+ ))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ print (dhcp_header.parse(test))</span><br><span>diff --git a/lib/python/protocols/unconverted/layer3/dhcpv6.py b/lib/python/protocols/unconverted/layer3/dhcpv6.py</span><br><span>new file mode 100644</span><br><span>index 0000000..b9ff172</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/unconverted/layer3/dhcpv6.py</span><br><span>@@ -0,0 +1,111 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+the Dynamic Host Configuration Protocol (DHCP) for IPv6</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+http://www.networksorcery.com/enp/rfc/rfc3315.txt</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from ipv6 import Ipv6Address</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+dhcp_option = Struct("dhcp_option",</span><br><span style="color: hsl(120, 100%, 40%);">+ Enum(UBInt16("code"),</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_CLIENTID = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_SERVERID = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_IA_NA = 3,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_IA_TA = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_IAADDR = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_ORO = 6,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_PREFERENCE = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_ELAPSED_TIME = 8,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_RELAY_MSG = 9,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_AUTH = 11,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_UNICAST = 12,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_STATUS_CODE = 13,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_RAPID_COMMIT = 14,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_USER_CLASS = 15,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_VENDOR_CLASS = 16,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_VENDOR_OPTS = 17,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_INTERFACE_ID = 18,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_RECONF_MSG = 19,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_RECONF_ACCEPT = 20,</span><br><span style="color: hsl(120, 100%, 40%);">+ SIP_SERVERS_DOMAIN_NAME_LIST = 21,</span><br><span style="color: hsl(120, 100%, 40%);">+ SIP_SERVERS_IPV6_ADDRESS_LIST = 22,</span><br><span style="color: hsl(120, 100%, 40%);">+ DNS_RECURSIVE_NAME_SERVER = 23,</span><br><span style="color: hsl(120, 100%, 40%);">+ DOMAIN_SEARCH_LIST = 24,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_IA_PD = 25,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_IAPREFIX = 26,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_NIS_SERVERS = 27,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_NISP_SERVERS = 28,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_NIS_DOMAIN_NAME = 29,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_NISP_DOMAIN_NAME = 30,</span><br><span style="color: hsl(120, 100%, 40%);">+ SNTP_SERVER_LIST = 31,</span><br><span style="color: hsl(120, 100%, 40%);">+ INFORMATION_REFRESH_TIME = 32,</span><br><span style="color: hsl(120, 100%, 40%);">+ BCMCS_CONTROLLER_DOMAIN_NAME_LIST = 33,</span><br><span style="color: hsl(120, 100%, 40%);">+ BCMCS_CONTROLLER_IPV6_ADDRESS_LIST = 34,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_GEOCONF_CIVIC = 36,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_REMOTE_ID = 37,</span><br><span style="color: hsl(120, 100%, 40%);">+ RELAY_AGENT_SUBSCRIBER_ID = 38,</span><br><span style="color: hsl(120, 100%, 40%);">+ OPTION_CLIENT_FQDN = 39,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt16("length"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Field("data", lambda ctx: ctx.length),</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+client_message = Struct("client_message",</span><br><span style="color: hsl(120, 100%, 40%);">+ Bitwise(BitField("transaction_id", 24)),</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+relay_message = Struct("relay_message",</span><br><span style="color: hsl(120, 100%, 40%);">+ Byte("hop_count"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Ipv6Address("linkaddr"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Ipv6Address("peeraddr"),</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+dhcp_message = Struct("dhcp_message",</span><br><span style="color: hsl(120, 100%, 40%);">+ Enum(Byte("msgtype"),</span><br><span style="color: hsl(120, 100%, 40%);">+ # these are client-server messages</span><br><span style="color: hsl(120, 100%, 40%);">+ SOLICIT = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ ADVERTISE = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ REQUEST = 3,</span><br><span style="color: hsl(120, 100%, 40%);">+ CONFIRM = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ RENEW = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+ REBIND = 6,</span><br><span style="color: hsl(120, 100%, 40%);">+ REPLY = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+ RELEASE_ = 8,</span><br><span style="color: hsl(120, 100%, 40%);">+ DECLINE_ = 9,</span><br><span style="color: hsl(120, 100%, 40%);">+ RECONFIGURE = 10,</span><br><span style="color: hsl(120, 100%, 40%);">+ INFORMATION_REQUEST = 11,</span><br><span style="color: hsl(120, 100%, 40%);">+ # these two are relay messages</span><br><span style="color: hsl(120, 100%, 40%);">+ RELAY_FORW = 12,</span><br><span style="color: hsl(120, 100%, 40%);">+ RELAY_REPL = 13,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ # relay messages have a different structure from client-server messages</span><br><span style="color: hsl(120, 100%, 40%);">+ Switch("params", lambda ctx: ctx.msgtype,</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+ "RELAY_FORW" : relay_message,</span><br><span style="color: hsl(120, 100%, 40%);">+ "RELAY_REPL" : relay_message,</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ default = client_message,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ Rename("options", GreedyRange(dhcp_option)),</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+ test1 = b"\x03\x11\x22\x33\x00\x17\x00\x03ABC\x00\x05\x00\x05HELLO"</span><br><span style="color: hsl(120, 100%, 40%);">+ test2 = b"\x0c\x040123456789abcdef0123456789abcdef\x00\x09\x00\x0bhello world\x00\x01\x00\x00"</span><br><span style="color: hsl(120, 100%, 40%);">+ print (dhcp_message.parse(test1))</span><br><span style="color: hsl(120, 100%, 40%);">+ print (dhcp_message.parse(test2))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/lib/python/protocols/unconverted/layer3/icmpv4.py b/lib/python/protocols/unconverted/layer3/icmpv4.py</span><br><span>new file mode 100644</span><br><span>index 0000000..7a554d1</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/unconverted/layer3/icmpv4.py</span><br><span>@@ -0,0 +1,87 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+Internet Control Message Protocol for IPv4 (TCP/IP protocol stack)</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+from binascii import unhexlify</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from ipv4 import IpAddress</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+echo_payload = Struct("echo_payload",</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt16("identifier"),</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt16("sequence"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Bytes("data", 32), # length is implementation dependent... </span><br><span style="color: hsl(120, 100%, 40%);">+ # is anyone using more than 32 bytes?</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+dest_unreachable_payload = Struct("dest_unreachable_payload",</span><br><span style="color: hsl(120, 100%, 40%);">+ Padding(2),</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt16("next_hop_mtu"),</span><br><span style="color: hsl(120, 100%, 40%);">+ IpAddress("host"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Bytes("echo", 8),</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+dest_unreachable_code = Enum(Byte("code"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Network_unreachable_error = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ Host_unreachable_error = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ Protocol_unreachable_error = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ Port_unreachable_error = 3,</span><br><span style="color: hsl(120, 100%, 40%);">+ The_datagram_is_too_big = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ Source_route_failed_error = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+ Destination_network_unknown_error = 6,</span><br><span style="color: hsl(120, 100%, 40%);">+ Destination_host_unknown_error = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+ Source_host_isolated_error = 8,</span><br><span style="color: hsl(120, 100%, 40%);">+ Desination_administratively_prohibited = 9,</span><br><span style="color: hsl(120, 100%, 40%);">+ Host_administratively_prohibited2 = 10,</span><br><span style="color: hsl(120, 100%, 40%);">+ Network_TOS_unreachable = 11,</span><br><span style="color: hsl(120, 100%, 40%);">+ Host_TOS_unreachable = 12,</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+icmp_header = Struct("icmp_header",</span><br><span style="color: hsl(120, 100%, 40%);">+ Enum(Byte("type"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Echo_reply = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ Destination_unreachable = 3,</span><br><span style="color: hsl(120, 100%, 40%);">+ Source_quench = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ Redirect = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+ Alternate_host_address = 6,</span><br><span style="color: hsl(120, 100%, 40%);">+ Echo_request = 8,</span><br><span style="color: hsl(120, 100%, 40%);">+ Router_advertisement = 9,</span><br><span style="color: hsl(120, 100%, 40%);">+ Router_solicitation = 10,</span><br><span style="color: hsl(120, 100%, 40%);">+ Time_exceeded = 11,</span><br><span style="color: hsl(120, 100%, 40%);">+ Parameter_problem = 12,</span><br><span style="color: hsl(120, 100%, 40%);">+ Timestamp_request = 13,</span><br><span style="color: hsl(120, 100%, 40%);">+ Timestamp_reply = 14,</span><br><span style="color: hsl(120, 100%, 40%);">+ Information_request = 15,</span><br><span style="color: hsl(120, 100%, 40%);">+ Information_reply = 16,</span><br><span style="color: hsl(120, 100%, 40%);">+ Address_mask_request = 17,</span><br><span style="color: hsl(120, 100%, 40%);">+ Address_mask_reply = 18,</span><br><span style="color: hsl(120, 100%, 40%);">+ _default_ = Pass,</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ Switch("code", lambda ctx: ctx.type,</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+ "Destination_unreachable" : dest_unreachable_code,</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ default = Byte("code"),</span><br><span style="color: hsl(120, 100%, 40%);">+ ),</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt16("crc"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Switch("payload", lambda ctx: ctx.type,</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+ "Echo_reply" : echo_payload,</span><br><span style="color: hsl(120, 100%, 40%);">+ "Echo_request" : echo_payload,</span><br><span style="color: hsl(120, 100%, 40%);">+ "Destination_unreachable" : dest_unreachable_payload,</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ default = Pass</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+ cap1 = unhexlify(six.b("0800305c02001b006162636465666768696a6b6c6d6e6f70717273747576776162"</span><br><span style="color: hsl(120, 100%, 40%);">+ "63646566676869"))</span><br><span style="color: hsl(120, 100%, 40%);">+ cap2 = unhexlify(six.b("0000385c02001b006162636465666768696a6b6c6d6e6f70717273747576776162"</span><br><span style="color: hsl(120, 100%, 40%);">+ "63646566676869"))</span><br><span style="color: hsl(120, 100%, 40%);">+ cap3 = unhexlify(b"0301000000001122aabbccdd0102030405060708")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ print (icmp_header.parse(cap1))</span><br><span style="color: hsl(120, 100%, 40%);">+ print (icmp_header.parse(cap2))</span><br><span style="color: hsl(120, 100%, 40%);">+ print (icmp_header.parse(cap3))</span><br><span>diff --git a/lib/python/protocols/unconverted/layer3/igmpv2.py b/lib/python/protocols/unconverted/layer3/igmpv2.py</span><br><span>new file mode 100644</span><br><span>index 0000000..99ab6db</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/unconverted/layer3/igmpv2.py</span><br><span>@@ -0,0 +1,29 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+What : Internet Group Management Protocol, Version 2</span><br><span style="color: hsl(120, 100%, 40%);">+ How : http://www.ietf.org/rfc/rfc2236.txt</span><br><span style="color: hsl(120, 100%, 40%);">+ Who : jesse @ housejunkie . ca</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+from binascii import unhexlify</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import Byte, Enum,Struct, UBInt16</span><br><span style="color: hsl(120, 100%, 40%);">+from construct.protocols.layer3.ipv4 import IpAddress</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+igmp_type = Enum(Byte("igmp_type"),</span><br><span style="color: hsl(120, 100%, 40%);">+ MEMBERSHIP_QUERY = 0x11,</span><br><span style="color: hsl(120, 100%, 40%);">+ MEMBERSHIP_REPORT_V1 = 0x12,</span><br><span style="color: hsl(120, 100%, 40%);">+ MEMBERSHIP_REPORT_V2 = 0x16,</span><br><span style="color: hsl(120, 100%, 40%);">+ LEAVE_GROUP = 0x17,</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+igmpv2_header = Struct("igmpv2_header",</span><br><span style="color: hsl(120, 100%, 40%);">+ igmp_type,</span><br><span style="color: hsl(120, 100%, 40%);">+ Byte("max_resp_time"),</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt16("checksum"),</span><br><span style="color: hsl(120, 100%, 40%);">+ IpAddress("group_address"),</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == '__main__':</span><br><span style="color: hsl(120, 100%, 40%);">+ capture = unhexlify(b"1600FA01EFFFFFFD")</span><br><span style="color: hsl(120, 100%, 40%);">+ print (igmpv2_header.parse(capture))</span><br><span>diff --git a/lib/python/protocols/unconverted/layer3/mtp3.py b/lib/python/protocols/unconverted/layer3/mtp3.py</span><br><span>new file mode 100644</span><br><span>index 0000000..7f712f2</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/unconverted/layer3/mtp3.py</span><br><span>@@ -0,0 +1,12 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+Message Transport Part 3 (SS7 protocol stack)</span><br><span style="color: hsl(120, 100%, 40%);">+(untested)</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+mtp3_header = BitStruct("mtp3_header",</span><br><span style="color: hsl(120, 100%, 40%);">+ Nibble("service_indicator"),</span><br><span style="color: hsl(120, 100%, 40%);">+ Nibble("subservice"),</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/lib/python/protocols/unconverted/layer4/isup.py b/lib/python/protocols/unconverted/layer4/isup.py</span><br><span>new file mode 100644</span><br><span>index 0000000..8111b60</span><br><span>--- /dev/null</span><br><span>+++ b/lib/python/protocols/unconverted/layer4/isup.py</span><br><span>@@ -0,0 +1,15 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+ISDN User Part (SS7 protocol stack)</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+isup_header = Struct("isup_header",</span><br><span style="color: hsl(120, 100%, 40%);">+ Bytes("routing_label", 5),</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt16("cic"),</span><br><span style="color: hsl(120, 100%, 40%);">+ UBInt8("message_type"),</span><br><span style="color: hsl(120, 100%, 40%);">+ # mandatory fixed parameters</span><br><span style="color: hsl(120, 100%, 40%);">+ # mandatory variable parameters</span><br><span style="color: hsl(120, 100%, 40%);">+ # optional parameters</span><br><span style="color: hsl(120, 100%, 40%);">+)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/tests/channels/SIP/pcap_demo/run-test b/tests/channels/SIP/pcap_demo/run-test</span><br><span>index 8400a85..ecb2bb0 100755</span><br><span>--- a/tests/channels/SIP/pcap_demo/run-test</span><br><span>+++ b/tests/channels/SIP/pcap_demo/run-test</span><br><span>@@ -9,10 +9,7 @@</span><br><span> from sip_message import SIPMessage, SIPMessageTest</span><br><span> </span><br><span> from twisted.internet import reactor</span><br><span style="color: hsl(0, 100%, 40%);">-try:</span><br><span style="color: hsl(0, 100%, 40%);">- from construct_legacy.protocols.ipstack import ip_stack</span><br><span style="color: hsl(0, 100%, 40%);">-except ImportError:</span><br><span style="color: hsl(0, 100%, 40%);">- from construct.protocols.ipstack import ip_stack</span><br><span style="color: hsl(120, 100%, 40%);">+from protocols.ipstack import ip_stack</span><br><span> </span><br><span> logger = logging.getLogger(__name__)</span><br><span> test1 = [</span><br><span>diff --git a/tests/channels/SIP/pcap_demo/test-config.yaml b/tests/channels/SIP/pcap_demo/test-config.yaml</span><br><span>index 6a5111a..ec151be 100644</span><br><span>--- a/tests/channels/SIP/pcap_demo/test-config.yaml</span><br><span>+++ b/tests/channels/SIP/pcap_demo/test-config.yaml</span><br><span>@@ -16,7 +16,6 @@</span><br><span> properties:</span><br><span> dependencies:</span><br><span> - python : 'twisted'</span><br><span style="color: hsl(0, 100%, 40%);">- - python : 'construct'</span><br><span> - 'pcap'</span><br><span> - asterisk : 'chan_sip'</span><br><span> tags:</span><br><span>diff --git a/tests/channels/pjsip/rtp/rtp_keepalive/base/rtp.py b/tests/channels/pjsip/rtp/rtp_keepalive/base/rtp.py</span><br><span>index 2e325f5..633971d 100644</span><br><span>--- a/tests/channels/pjsip/rtp/rtp_keepalive/base/rtp.py</span><br><span>+++ b/tests/channels/pjsip/rtp/rtp_keepalive/base/rtp.py</span><br><span>@@ -12,11 +12,7 @@</span><br><span> </span><br><span> from twisted.internet.protocol import DatagramProtocol</span><br><span> from twisted.internet import reactor</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-try:</span><br><span style="color: hsl(0, 100%, 40%);">- from construct_legacy import *</span><br><span style="color: hsl(0, 100%, 40%);">-except ImportError:</span><br><span style="color: hsl(0, 100%, 40%);">- from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from asterisk.pcap import RTPPacket</span><br><span> </span><br><span> sys.path.append('lib/python')</span><br><span> </span><br><span>@@ -30,22 +26,9 @@</span><br><span> self.test_object.register_stop_observer(self.asterisk_stopped)</span><br><span> </span><br><span> def datagramReceived(self, data, (host, port)):</span><br><span style="color: hsl(0, 100%, 40%);">- header = Struct('rtp_packet',</span><br><span style="color: hsl(0, 100%, 40%);">- BitStruct('header',</span><br><span style="color: hsl(0, 100%, 40%);">- BitField('version', 2),</span><br><span style="color: hsl(0, 100%, 40%);">- Bit('padding'),</span><br><span style="color: hsl(0, 100%, 40%);">- Bit('extension'),</span><br><span style="color: hsl(0, 100%, 40%);">- Nibble('csrc_count'),</span><br><span style="color: hsl(0, 100%, 40%);">- Bit('marker'),</span><br><span style="color: hsl(0, 100%, 40%);">- BitField('payload', 7)</span><br><span style="color: hsl(0, 100%, 40%);">- ),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt16('sequence_number'),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('timestamp'),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('ssrc')</span><br><span style="color: hsl(0, 100%, 40%);">- )</span><br><span style="color: hsl(0, 100%, 40%);">- rtp_header = header.parse(data)</span><br><span style="color: hsl(120, 100%, 40%);">+ rtp_header = RTPPacket.rtp_header.parse(data)</span><br><span> LOGGER.debug("Parsed RTP packet is {0}".format(rtp_header))</span><br><span style="color: hsl(0, 100%, 40%);">- if rtp_header.header.payload == 13:</span><br><span style="color: hsl(120, 100%, 40%);">+ if rtp_header.payload_type == 13:</span><br><span> current_time = time.time()</span><br><span> # Don't compare intervals on the first received CNG</span><br><span> if self.last_rx_time:</span><br><span>diff --git a/tests/hep/hep_capture_node.py b/tests/hep/hep_capture_node.py</span><br><span>index 0fb081e..010756a 100644</span><br><span>--- a/tests/hep/hep_capture_node.py</span><br><span>+++ b/tests/hep/hep_capture_node.py</span><br><span>@@ -20,10 +20,8 @@</span><br><span> from twisted.internet.protocol import DatagramProtocol</span><br><span> from twisted.internet import reactor</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-try:</span><br><span style="color: hsl(0, 100%, 40%);">- from construct_legacy import *</span><br><span style="color: hsl(0, 100%, 40%);">-except ImportError:</span><br><span style="color: hsl(0, 100%, 40%);">- from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from construct import *</span><br><span style="color: hsl(120, 100%, 40%);">+from construct.core import *</span><br><span> </span><br><span> LOGGER = logging.getLogger(__name__)</span><br><span> </span><br><span>@@ -107,40 +105,40 @@</span><br><span> </span><br><span> self.module = module</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- self.hep_chunk = Struct('hep_chunk',</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt16('vendor_id'),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt16('type_id'),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt16('length'))</span><br><span style="color: hsl(0, 100%, 40%);">- hep_ctrl = Struct('hep_ctrl',</span><br><span style="color: hsl(0, 100%, 40%);">- Array(4, UBInt8('id')),</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt16('length'))</span><br><span style="color: hsl(0, 100%, 40%);">- hep_ip_family = Struct('hep_ip_family',</span><br><span style="color: hsl(120, 100%, 40%);">+ self.hep_chunk = 'hep_chunk' / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ 'vendor_id' / Int16ub,</span><br><span style="color: hsl(120, 100%, 40%);">+ 'type_id' / Int16ub,</span><br><span style="color: hsl(120, 100%, 40%);">+ 'length' / Int16ub)</span><br><span style="color: hsl(120, 100%, 40%);">+ hep_ctrl = 'hep_ctrl' / Struct(</span><br><span style="color: hsl(120, 100%, 40%);">+ 'id' / Array(4, Int8ub),</span><br><span style="color: hsl(120, 100%, 40%);">+ 'length' / Int16ub)</span><br><span style="color: hsl(120, 100%, 40%);">+ hep_ip_family = 'hep_ip_family' / Struct(</span><br><span> self.hep_chunk,</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt8('ip_family'));</span><br><span style="color: hsl(0, 100%, 40%);">- hep_ip_id = Struct('hep_ip_id',</span><br><span style="color: hsl(120, 100%, 40%);">+ 'ip_family' / Int8ub);</span><br><span style="color: hsl(120, 100%, 40%);">+ hep_ip_id = 'hep_ip_id' / Struct(</span><br><span> self.hep_chunk,</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt8('ip_id'))</span><br><span style="color: hsl(0, 100%, 40%);">- hep_port = Struct('hep_port',</span><br><span style="color: hsl(120, 100%, 40%);">+ 'ip_id' / Int8ub)</span><br><span style="color: hsl(120, 100%, 40%);">+ hep_port = 'hep_port' / Struct(</span><br><span> self.hep_chunk,</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt16('port'))</span><br><span style="color: hsl(0, 100%, 40%);">- hep_timestamp_sec = Struct('hep_timestamp_sec',</span><br><span style="color: hsl(120, 100%, 40%);">+ 'port' / Int16ub)</span><br><span style="color: hsl(120, 100%, 40%);">+ hep_timestamp_sec = 'hep_timestamp_sec' / Struct(</span><br><span> self.hep_chunk,</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('timestamp_sec'))</span><br><span style="color: hsl(0, 100%, 40%);">- hep_timestamp_usec = Struct('hep_timestamp_usec',</span><br><span style="color: hsl(120, 100%, 40%);">+ 'timestamp_sec' / Int32ub)</span><br><span style="color: hsl(120, 100%, 40%);">+ hep_timestamp_usec = 'hep_timestamp_usec' / Struct(</span><br><span> self.hep_chunk,</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('timestamp_usec'))</span><br><span style="color: hsl(0, 100%, 40%);">- hep_protocol_type = Struct('hep_protocol_type',</span><br><span style="color: hsl(120, 100%, 40%);">+ 'timestamp_usec' / Int32ub)</span><br><span style="color: hsl(120, 100%, 40%);">+ hep_protocol_type = 'hep_protocol_type' / Struct(</span><br><span> self.hep_chunk,</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt8('protocol_type'))</span><br><span style="color: hsl(0, 100%, 40%);">- hep_capture_agent_id = Struct('hep_capture_agent_id',</span><br><span style="color: hsl(120, 100%, 40%);">+ 'protocol_type' / Int8ub)</span><br><span style="color: hsl(120, 100%, 40%);">+ hep_capture_agent_id = 'hep_capture_agent_id' / Struct(</span><br><span> self.hep_chunk,</span><br><span style="color: hsl(0, 100%, 40%);">- UBInt32('capture_agent_id'))</span><br><span style="color: hsl(0, 100%, 40%);">- self.hep_generic_msg = Struct('hep_generic',</span><br><span style="color: hsl(120, 100%, 40%);">+ 'capture_agent_id' / Int32ub)</span><br><span style="color: hsl(120, 100%, 40%);">+ self.hep_generic_msg = 'hep_generic' / Struct(</span><br><span> hep_ctrl,</span><br><span> hep_ip_family,</span><br><span> hep_ip_id,</span><br><span style="color: hsl(0, 100%, 40%);">- Struct('src_port', hep_port),</span><br><span style="color: hsl(0, 100%, 40%);">- Struct('dst_port', hep_port),</span><br><span style="color: hsl(120, 100%, 40%);">+ 'src_port' / Struct(hep_port),</span><br><span style="color: hsl(120, 100%, 40%);">+ 'dst_port' / Struct(hep_port),</span><br><span> hep_timestamp_sec,</span><br><span> hep_timestamp_usec,</span><br><span> hep_protocol_type,</span><br><span>@@ -161,18 +159,18 @@</span><br><span> dst_addr = None</span><br><span> if parsed_hdr.hep_ip_family.ip_family == IP_FAMILY.v4:</span><br><span> # IPv4</span><br><span style="color: hsl(0, 100%, 40%);">- hep_ipv4_addr = Struct('hep_ipv4_addr',</span><br><span style="color: hsl(120, 100%, 40%);">+ hep_ipv4_addr = 'hep_ipv4_addr' / Struct(</span><br><span> self.hep_chunk,</span><br><span style="color: hsl(0, 100%, 40%);">- String('ipv4_addr', 4))</span><br><span style="color: hsl(120, 100%, 40%);">+ 'ipv4_addr' / PaddedString(4, "ascii"))</span><br><span> src_addr = hep_ipv4_addr.parse(data[length:])</span><br><span> length += hep_ipv4_addr.sizeof()</span><br><span> dst_addr = hep_ipv4_addr.parse(data[length:])</span><br><span> length += hep_ipv4_addr.sizeof()</span><br><span> elif parsed_hdr.hep_ip_family.ip_family == IP_FAMILY.v6:</span><br><span> # IPv6</span><br><span style="color: hsl(0, 100%, 40%);">- hep_ipv6_addr = Struct('hep_ipv6_addr',</span><br><span style="color: hsl(120, 100%, 40%);">+ hep_ipv6_addr = 'hep_ipv6_addr' / Struct(</span><br><span> self.hep_chunk,</span><br><span style="color: hsl(0, 100%, 40%);">- String('ipv6_addr', 16))</span><br><span style="color: hsl(120, 100%, 40%);">+ 'ipv6_addr' / PaddedString(16, "ascii"))</span><br><span> src_addr = hep_ipv6_addr.parse(data[length:])</span><br><span> length += hep_ipv6_addr.sizeof()</span><br><span> dst_addr = hep_ipv6_addr.parse(data[length:])</span><br><span>@@ -185,20 +183,20 @@</span><br><span> hdr = self.hep_chunk.parse(data[length:])</span><br><span> length += self.hep_chunk.sizeof()</span><br><span> if hdr.type_id == HEP_VARIABLE_TYPES.auth_key:</span><br><span style="color: hsl(0, 100%, 40%);">- hep_auth_key = String('hep_auth_key',</span><br><span style="color: hsl(0, 100%, 40%);">- hdr.length - self.hep_chunk.sizeof())</span><br><span style="color: hsl(120, 100%, 40%);">+ hep_auth_key = 'hep_auth_key' / PaddedString(</span><br><span style="color: hsl(120, 100%, 40%);">+ hdr.length - self.hep_chunk.sizeof(), "ascii")</span><br><span> packet.auth_key = hep_auth_key.parse(data[length:])</span><br><span> length += hep_auth_key.sizeof() - self.hep_chunk.sizeof()</span><br><span> elif hdr.type_id == HEP_VARIABLE_TYPES.payload:</span><br><span style="color: hsl(0, 100%, 40%);">- hep_payload = String('hep_payload',</span><br><span style="color: hsl(0, 100%, 40%);">- hdr.length - self.hep_chunk.sizeof())</span><br><span style="color: hsl(120, 100%, 40%);">+ hep_payload = 'hep_payload' / PaddedString(</span><br><span style="color: hsl(120, 100%, 40%);">+ hdr.length - self.hep_chunk.sizeof(), "ascii")</span><br><span> packet.payload = hep_payload.parse(data[length:])</span><br><span> length += hep_payload.sizeof() - self.hep_chunk.sizeof()</span><br><span> </span><br><span> LOGGER.debug('Packet payload: %s' % packet.payload)</span><br><span> elif hdr.type_id == HEP_VARIABLE_TYPES.uuid:</span><br><span style="color: hsl(0, 100%, 40%);">- hep_uuid = String('hep_uuid',</span><br><span style="color: hsl(0, 100%, 40%);">- hdr.length - self.hep_chunk.sizeof())</span><br><span style="color: hsl(120, 100%, 40%);">+ hep_uuid = 'hep_uuid' / PaddedString(</span><br><span style="color: hsl(120, 100%, 40%);">+ hdr.length - self.hep_chunk.sizeof(), "ascii")</span><br><span> packet.uuid = hep_uuid.parse(data[length:])</span><br><span> length += hep_uuid.sizeof() - self.hep_chunk.sizeof()</span><br><span> self.module.verify_packet(packet)</span><br><span>@@ -379,4 +377,3 @@</span><br><span> LOGGER.error('Failed to match packet %d: %s' %</span><br><span> (self.current_packet, str(packet.__dict__)))</span><br><span> self.test_object.set_passed(False)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/testsuite/+/13222">change 13222</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/testsuite/+/13222"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: testsuite </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-Change-Id: Id38d01a2cd073b240fde909a38c95d69313bbbe7 </div>
<div style="display:none"> Gerrit-Change-Number: 13222 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>