Ethernet CRC in TCPDump – Understanding the Details

ethernet

I am testing the ethernet transmission on my Digilent Nexus4 DDR FPGA. I created a really simple packet with a broadcast destination address and some made up ethernet type. Here is the packet as captured in tcpdump.

05:58:22.148546 00:00:00:00:00:00 (oui Ethernet) > Broadcast, ethertype Unknown (0xebeb), length 66: 
    0x0000:  ffff ffff ffff 0000 0000 0000 ebeb 0000
    0x0010:  0000 dead beef 0000 0000 0000 0000 0000
    0x0020:  0000 0000 0000 0000 0000 0000 0000 0000
    0x0030:  0000 0000 0000 0000 0001 0203 0405 0607
    0x0040:  27ae

In the packet I am sending the last few bytes are 0x01 0x02 0x03 0x04 0x05 0x06 0x07 which I can clearly see in the packet. However instead of ending at 0x07 the captured packet includes 0x27ae which happens to be the first two bytes of my CRC code. When I check the output signals using chipscope it looks like I am just transmitting 0x07 and then another 4 bytes for the crc as expected. I have the ethernet from my fpga plugged into a usb ethernet adapter on my desktop since the ethernet port on my motherboard is used to connect to the internet through my router. The usb nic card is the "AmazonBasics USB 3.0 to 10/100/1000 Gigabit Ethernet Adapter".

I then thought that maybe the phy on the card was creating a crc for me so I purposefully flipped the bits in the first byte of the crc and I stopped getting packets. In ifconfig I could see errors packets being dropped. So it looks like that although the ethernet adapter on my pc is checking the full 4 byte crc it is also transmitting the first half of it to the computer.

The next experiment I tried was instead of connecting my FPGA to the usb ethernet adapter I plugged it directly into my router. Since I am using a broadcast ethernet destination I figured the packet would get routed back to my pc through the nic built into its motherboard thereby skipping the usb ethernet adapter. This worked and the last byte in the packet was in fact 0x07, and I did not see any of my crc in the dump. Then while keeping the fpga connected to the router I disconnected the motherboard from the router and connected the usb ethernet adapter to the router. Now when I received packets from the fpga -> router -> usb ethernet it included part of the crc again. So it looks like the problem lies with my usb adapter and not the FPGA.

I thought that maybe my usb adapter was having issues, but I can browse the internet with no issues over it. However, most protocols I can think of like TCP or UDP have a length field so they are probably ignoring the extra two bytes of data anyway. Is this a normal behavior for some nic cards? I am thinking it might have something to do with latency where the card just transmits part of the crc before realizing that it is in the crc.

Best Answer

This is likely a driver issue with the NIC in capture or promiscuous mode. It's also possible that it happens in normal mode as well since - as you've pointed out - most protocols keep track of their data themselves and trailed junk is just ignored.

The NIC has to recognize the FCS field in a reliable fashion, otherwise it'd drop all frames. On reception, FCS is calculated 'on the fly' over all bytes of the frame. When the end-of-frame is detected the FCS value has to the the CRC residue or "magic number" 0xC704DD7B. If correct the NIC then strips the last four bytes and passes the frame to the OS. Apparently, this NIC doesn't strip all FCS bytes.