2

I have this Python function which unpacks ethernet frame:

ethernet frame

def ethernet_frame(data):
        ipheader = struct.unpack('!6s6sH', data[0:14])
        dest_mac = binascii.hexlify(ipheader[0])
        src_mac = binascii.hexlify(ipheader[1])
        proto = ""

        protoType = ipheader[2]
        nextProto = hex(protoType)
        
        print(nextProto)
        if(nextProto == '0x800'):
            proto = 'IPV4'
        elif(nextProto == '0x86dd'):
            proto = 'IPV6'
        print(nextProto)
        
        return dest_mac, src_mac, proto, data[14:]

I was expecting to get 0x800 for IPV4 or 0x86dd for IPV6. But after unpacking the frame I got 0xc0a8. Can someone explain why I'm getting this unexpected data? and how to fix it to get correct data?

Muath
  • 4,351
  • 12
  • 42
  • 69
  • 1
    1. Please post the packet to our are parsing. 2. Have you considered using a library for this, like `scapy` for example? – kmaork Mar 28 '21 at 20:13

1 Answers1

1

Sounds like you may be reading an IP header as an ethernet header. 0x0800 is the last two bytes of the ethernet header -- data[12:13]. The IP header pre-addresses is 12 bytes long, and the next two bytes (ip_header[12:13]) are the first two bytes of the IP source address. 0xc0a8 in decimal is (192, 168) -- which looks to me like the first two bytes of an internal IP address, 192.168.x.x.

(IIRC), the IP header is embedded directly after the ethernet header in the yellow data segment of your diagram, so if you tried to read a second ethernet header after the first one, for example, this could happen.

(by the way -- you don't need to convert protoType into a string to compare it to a hex value -- you can simply do if protoType == 0x0800 / elif protoType == 0x86dd).

vgel
  • 3,225
  • 1
  • 21
  • 35