"""
Ethernet (TCP/IP protocol stack)
"""
from construct import *
from ethernet import MacAddressAdapter
from construct.protocols.layer3.ipv4 import IpAddressAdapter
from binascii import unhexlify
import six
def HwAddress(name):
return IfThenElse(name, lambda ctx: ctx.hardware_type == "ETHERNET",
MacAddressAdapter(Field("data", lambda ctx: ctx.hwaddr_length)),
Field("data", lambda ctx: ctx.hwaddr_length)
)
def ProtoAddress(name):
return IfThenElse(name, lambda ctx: ctx.protocol_type == "IP",
IpAddressAdapter(Field("data", lambda ctx: ctx.protoaddr_length)),
Field("data", lambda ctx: ctx.protoaddr_length)
)
arp_header = Struct("arp_header",
Enum(UBInt16("hardware_type"),
ETHERNET = 1,
EXPERIMENTAL_ETHERNET = 2,
ProNET_TOKEN_RING = 4,
CHAOS = 5,
IEEE802 = 6,
ARCNET = 7,
HYPERCHANNEL = 8,
ULTRALINK = 13,
FRAME_RELAY = 15,
FIBRE_CHANNEL = 18,
IEEE1394 = 24,
HIPARP = 28,
ISO7816_3 = 29,
ARPSEC = 30,
IPSEC_TUNNEL = 31,
INFINIBAND = 32,
),
Enum(UBInt16("protocol_type"),
IP = 0x0800,
),
UBInt8("hwaddr_length"),
UBInt8("protoaddr_length"),
Enum(UBInt16("opcode"),
REQUEST = 1,
REPLY = 2,
REQUEST_REVERSE = 3,
REPLY_REVERSE = 4,
DRARP_REQUEST = 5,
DRARP_REPLY = 6,
DRARP_ERROR = 7,
InARP_REQUEST = 8,
InARP_REPLY = 9,
ARP_NAK = 10
),
HwAddress("source_hwaddr"),
ProtoAddress("source_protoaddr"),
HwAddress("dest_hwaddr"),
ProtoAddress("dest_protoaddr"),
)
rarp_header = Rename("rarp_header", arp_header)
if __name__ == "__main__":
cap1 = unhexlify(six.b("00010800060400010002e3426009c0a80204000000000000c0a80201"))
obj = arp_header.parse(cap1)
print (obj)
print (repr(arp_header.build(obj)))
print ("-" * 80)
cap2 = unhexlify(six.b("00010800060400020011508c283cc0a802010002e3426009c0a80204"))
obj = arp_header.parse(cap2)
print (obj)
print (repr(arp_header.build(obj)))