summaryrefslogtreecommitdiff
path: root/external/construct/protocols/layer3/ipv4.py
diff options
context:
space:
mode:
Diffstat (limited to 'external/construct/protocols/layer3/ipv4.py')
-rw-r--r--external/construct/protocols/layer3/ipv4.py85
1 files changed, 85 insertions, 0 deletions
diff --git a/external/construct/protocols/layer3/ipv4.py b/external/construct/protocols/layer3/ipv4.py
new file mode 100644
index 0000000..82dfaa9
--- /dev/null
+++ b/external/construct/protocols/layer3/ipv4.py
@@ -0,0 +1,85 @@
+"""
+Internet Protocol version 4 (TCP/IP protocol stack)
+"""
+from construct import *
+import six
+from binascii import unhexlify
+
+try:
+ bytes
+except NameError:
+ bytes = str
+
+
+class IpAddressAdapter(Adapter):
+ def _encode(self, obj, context):
+ if bytes is str:
+ return "".join(chr(int(b)) for b in obj.split("."))
+ else:
+ return bytes(int(b) for b in obj.split("."))
+ def _decode(self, obj, context):
+ if bytes is str:
+ return ".".join(str(ord(b)) for b in obj)
+ else:
+ return ".".join("%d" % (b,) for b in obj)
+
+def IpAddress(name):
+ return IpAddressAdapter(Bytes(name, 4))
+
+def ProtocolEnum(code):
+ return Enum(code,
+ ICMP = 1,
+ TCP = 6,
+ UDP = 17,
+ )
+
+ipv4_header = Struct("ip_header",
+ EmbeddedBitStruct(
+ Const(Nibble("version"), 4),
+ ExprAdapter(Nibble("header_length"),
+ decoder = lambda obj, ctx: obj * 4,
+ encoder = lambda obj, ctx: obj / 4
+ ),
+ ),
+ BitStruct("tos",
+ Bits("precedence", 3),
+ Flag("minimize_delay"),
+ Flag("high_throuput"),
+ Flag("high_reliability"),
+ Flag("minimize_cost"),
+ Padding(1),
+ ),
+ UBInt16("total_length"),
+ Value("payload_length", lambda ctx: ctx.total_length - ctx.header_length),
+ UBInt16("identification"),
+ EmbeddedBitStruct(
+ Struct("flags",
+ Padding(1),
+ Flag("dont_fragment"),
+ Flag("more_fragments"),
+ ),
+ Bits("frame_offset", 13),
+ ),
+ UBInt8("ttl"),
+ ProtocolEnum(UBInt8("protocol")),
+ UBInt16("checksum"),
+ IpAddress("source"),
+ IpAddress("destination"),
+ Field("options", lambda ctx: ctx.header_length - 20),
+)
+
+
+if __name__ == "__main__":
+ cap = unhexlify(six.b("4500003ca0e3000080116185c0a80205d474a126"))
+ obj = ipv4_header.parse(cap)
+ print (obj)
+ print (repr(ipv4_header.build(obj)))
+
+
+
+
+
+
+
+
+