diff options
Diffstat (limited to 'external/construct/protocols/layer3/ipv4.py')
-rw-r--r-- | external/construct/protocols/layer3/ipv4.py | 85 |
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))) + + + + + + + + + |