ipethernet

Constructing (a) valid and (b) minimal size unicast, broadcast & multicast ethernet frames


I have a "KSZ8851SNL eval board" (link) which is an ethernet device and is an "SPI slave" for my "SPI master" which is "ST Nucleo F429ZI" (link).

I have written a driver that runs on "SPI master". With the driver I initialize "SPI slave" with a MAC address 00:0b:00:00:00:00, loopback interface enabled and no address filtering. With this setup I can send a "blob of random bytes" (not a proper ethernet frame) which are returned back by the loopback interface so that I can read them and verify that all the sent bytes were received back.

But when I initialize "SPI slave" with a MAC address 00:0b:00:00:00:00, loopback interface enabled and address filtering, then I get problems, because "blob of random data" is not a proper ethernet frame and is filtered out so that I can't receive it back.

At this point I want to stop using a "blob of random data" and know how to construct a proper minimal size:

I have read a lot on Wikipedia (link) where I also found a nice image (link). But is it even possible to send a proper ethernet frame when you only have a MAC address and no IP address? There is no option to set an IP address of the "KSZ8851SNL" described in the reference manual (link)... One thing that crossed my mind was to send an ethernet frame with an empty payload. Is this possible?

Can someone show me, how to construct these frames? Are there any tools that I can use to help me with the construction?


Solution

  • Let's remember that the minimum size of an Ethernet frame is 64 bytes.

    ARP is an easy-to-build frame, we can use the ARP request as your broadcast/multicast message and the ARP reply as your unicast message.

    The structure of an ARP request packet is as follow (using box drawing characters):

    ┏━━━━━━━┳━━━━━┳━━━━━━━━┳━━━━━━━━┳━━━━━━━━┳━━━━━━━━┓
    ┃Offsets┃Octet┃ 0      ┃ 1      ┃ 2      ┃ 3      ┃
    ┣━━━━━━━╋━━━━━╋━━━━━━━━╋━━━━━━━━╋━━━━━━━━╋━━━━━━━━┫
    ┃ Octet ┃ Bit ┃01234567┃01234567┃01234567┃01234567┃
    ┣━━━━━━━╋━━━━━╋━━━━━━━━┻━━━━━━━━┻━━━━━━━━┻━━━━━━━━┩
    ┃     0 ┃   0 ┃ Destination MAC Address           │
    ┣━━━━━━━╋━━━━━┫                 ┌─────────────────┤
    ┃     4 ┃  32 ┃                 │                 │
    ┣━━━━━━━╋━━━━━╉─────────────────┘                 │
    ┃     8 ┃  64 ┃ Source MAC Address                │
    ┣━━━━━━━╋━━━━━╉─────────────────┬─────────────────┤
    ┃    12 ┃  96 ┃ Ethertype 0x0806│ HTYPE 0x0001    │
    ┣━━━━━━━╋━━━━━╉─────────────────┼────────┬────────┤
    ┃    16 ┃ 128 ┃ PTYPE 0x0800    │ HLEN 6 │ PLEN 4 │
    ┣━━━━━━━╋━━━━━╉─────────────────┼────────┴────────┤
    ┃    20 ┃ 160 ┃ Opcode 0x0001   │                 │
    ┣━━━━━━━╋━━━━━╉─────────────────┘                 │
    ┃    24 ┃ 192 ┃ Sender hardware (MAC) Address     │
    ┣━━━━━━━╋━━━━━╉───────────────────────────────────┤
    ┃    28 ┃ 224 ┃ Sender protocol (IP) address      │
    ┣━━━━━━━╋━━━━━╉───────────────────────────────────┤
    ┃    32 ┃ 256 ┃ Target hardware (MAC) Address     │
    ┣━━━━━━━╋━━━━━┫                 ┌─────────────────┤
    ┃    36 ┃ 288 ┃                 │Target protocol->│
    ┣━━━━━━━╋━━━━━╉─────────────────┼─────────────────┤
    ┃    40 ┃ 320 ┃-> (IP) address  │ Padding         │
    ┣━━━━━━━╋━━━━━╉─────────────────┘                 │
    ┃    44 ┃ 352 ┃                                   │
    ┃    48 ┃ 384 ┃                                   │
    ┃    52 ┃ 416 ┃                                   │
    ┃    56 ┃ 448 ┃                                   │
    ┣━━━━━━━╋━━━━━╉───────────────────────────────────┤
    ┃    60 ┃ 480 ┃ CRC32                             │
    ┗━━━━━━━┻━━━━━┹───────────────────────────────────┘
    

    Let's assume that your NIC MAC address is aa:bb:cc:dd:ee:ff so the following packets are:

    Broadcast: ARP request packet (opcode 0x0001) from your MAC address to ff:ff:ff:ff:ff:ff

    0000   ff ff ff ff ff ff aa bb cc dd ee ff 08 06 00 01
    0010   08 00 06 04 00 01 aa bb cc dd ee ff 00 00 00 00
    0020   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0030   00 00 00 00 00 00 00 00 00 00 00 00
    

    Multicast: ARP request packet (opcode 0x0001) from your MAC address to 01:00:5e:00:01:01 (more details at the end of my message)

    0000   01 00 5e 00 01 01 aa bb cc dd ee ff 08 06 00 01
    0010   08 00 06 04 00 01 aa bb cc dd ee ff 00 00 00 00
    0020   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0030   00 00 00 00 00 00 00 00 00 00 00 00
    

    Unicast: ARP reply packet (opcode 0x0002) from 22:22:22:22:22:22 to your MAC address

    0000   aa bb cc dd ee ff 22 22 22 22 22 22 08 06 00 01
    0010   08 00 06 04 00 02 22 22 22 22 22 22 00 00 00 00
    0020   aa bb cc dd ee ff 00 00 00 00 00 00 00 00 00 00
    0030   00 00 00 00 00 00 00 00 00 00 00 00
    

    Regarding multicast, the least significant bit in the most significant octet of a MAC address is the multicast bit, in other words if the MAC first octet looks like this: ???????1 (that's why broadcast is considered a special type of multicast). Note that in my example "your" MAC address starts with 0xaa == 0b10101010 so it is not a multicast MAC address.

    So to send a multicast I used the MAC address 01:00:5E:00:01:01, which is the MAC address that correspond to IPv4 multicast address 224.0.1.1.

    Those packets can be saved as a text file using K12 format (keep a blank line at the end of the file)

    +---------+---------------+----------+
    00:00:00,000,000   ETHER
    |0   |ff|ff|ff|ff|ff|ff|aa|bb|cc|dd|ee|ff|08|06|00|01|08|00|06|04|00|01|aa|bb|cc|dd|ee|ff|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|
    
    +---------+---------------+----------+
    00:00:00,000,000   ETHER
    |0   |01|00|5e|00|01|01|aa|bb|cc|dd|ee|ff|08|06|00|01|08|00|06|04|00|01|aa|bb|cc|dd|ee|ff|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|
    
    +---------+---------------+----------+
    00:00:00,000,000   ETHER
    |0   |aa|bb|cc|dd|ee|ff|22|22|22|22|22|22|08|06|00|01|08|00|06|04|00|02|22|22|22|22|22|22|00|00|00|00|aa|bb|cc|dd|ee|ff|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|
    
    

    If you want a simpler frame, you can probably use Ethertype 0x9000 (loopback) for broadcast and unicast. I am not familiar with this protocol and I don't know to tell if your hardware support it, but you can try and let me know so I will update my answer.

    The structure is as follow:

    Broadcast (for multicast replace the destination MAC ff:ff:ff:ff:ff:ff)

    0000   ff ff ff ff ff ff aa bb cc dd ee ff 90 00 00 00
    0010   01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0020   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0030   00 00 00 00 00 00 00 00 00 00 00 00
    

    Unicast

    0000   aa bb cc dd ee ff 22 22 22 22 22 22 90 00 00 00
    0010   01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0020   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0030   00 00 00 00 00 00 00 00 00 00 00 00