FreeRTOS-TCP arp reply has invalid checksum

I have integrated FreeRTOS-TCP into my project, and now I am trying to get it to communicate with my PC. When I try to ping the embedded device, the PC sends an arp request as expected. This is received and processed correctly by the embedded code, but Wireshark reports a problem with the Frame Check Sequence of the arp reply. At some point, FreeRTOS-TCP sends a gratuitous arp, and after that the PC is able to communicate with the embedded code. I suspect that the PC is rejecting the arp reply, due to the invalid checksum. I have attached a screenshot of Wireshark, showing the incorrect arp reply. In this screenshot, the PC has IP address 192.168.1.10 and the embedded code has 192.168.1.2 The relevant portion of my FreeRTOSIPConfig. is ~~~

define ipconfigIPTASKPRIORITY TASKPRIORITYIP

define ipconfigIPTASKSTACKSIZEWORDS configMINIMALSTACKSIZE

define ipconfigUSENETWORKEVENT_HOOK 1

define ipconfigNUMNETWORKBUFFER_DESCRIPTORS 45

define ipconfigEVENTQUEUELENGTH (ipconfigNUMNETWORKBUFFER_DESCRIPTORS + 5)

define ipconfigENABLEBACKWARDCOMPATIBILITY 0

define ipconfigREPLYTOINCOMING_PINGS 1

define ipconfigNETWORK_MTU 1500

define ipconfigUSE_DHCP 0

define ipconfigRAND32() rand()

define ipconfigDRIVERINCLUDEDTXIPCHECKSUM 0

~~~ Thank you, Peter

FreeRTOS-TCP arp reply has invalid checksum

Hi Peter, that is an interesting observation.
…but Wireshark reports a problem with the Frame Check Sequence of the arp reply.
Ok
At some point, FreeRTOS-TCP sends a gratuitous arp, and after that the PC is able to communicate with the embedded code.
Good. Sending gratuitous ARP’s has the advantage that double IP addresses can be discovered earlier, and also that your PC’s ARP- and routing-tables remain up to date.
I suspect that the PC is rejecting the ARP reply, due to the invalid checksum. I have attached a screenshot of Wireshark, showing the incorrect arp reply.
There are 3 types of checksums, belonging to 3 layers:
  • Protocol checksum, calculated by the IP-task or peripheral ( TCP or UDP layer )
  • IP checksum, calculated by the IP-task or peripheral ( IP layer )
  • Frame checksum, calculated by the Ethernet peripheral ( hardware layer )
The IP-stack is not responsible for the Frame checksum. I think there is a problem with the packet length: an ARP reply is normally 60 bytes long. In your case, the ARP reply is 64 bytes long, and the extra 4 bytes seem to have a random value. Those are interpreted as the Frame check-sum. Normally the Ethernet peripheral makes sure that all packets have the required minimum length of 60 bytes ( excluding the frame checksum, which is not visible in Wireshark ). If that doesn’t work, you can define in your FreeRTOSIPConfig.h: ~~~ #define ipconfigETHERNETMINIMUMPACKET_BYTES 60 ~~~ Do you have ipconfigETHERNET_MINIMUM_PACKET_BYTES defined? What hardware are you using?

FreeRTOS-TCP arp reply has invalid checksum

Thank you for your very quick reply. I didn’t expect a reply on a Sunday !! ipconfigETHERNETMINIMUMPACKET_BYTES was not defined in my software, but it is now. Why do you suggest setting it to 60? Isn’t the minimum Ethernet frame size 64? Perhaps this check should be added to FreeRTOSIPConfigDefaults.h There was no change in behaviour after I set ipconfigETHERNETMINIMUMPACKET_BYTES to 60 I am developing on an LPC4088 Quick Start Board from Embedded Artists. The LPC4088 processor is a Cortex-M4 type. I am using the latest FreeRTOS, v10.1.1. I am using BufferAllocation2.c and heap4.c as suggested in the documentation. I am developing my own NetworkInterface.c as the LPC4088 is not an officially supported architecture. Andy McClelland submitted a NetworkInterface.c for this chip to the forums in 2015 for an older version of FreeRTOS-TCP. I am updating his driver and fixing a small number of bugs I have found in his code. I intend to release this code publically once it is working reliably.

FreeRTOS-TCP arp reply has invalid checksum

Perhaps this check should be added to FreeRTOSIPConfigDefaults.h
for this macro, undefined means: do not bother to check the packet length. That is usual when the EMAC takes care of the minimum length.
I am developing my own NetworkInterface.c as the LPC4088
Could you check the LPC4088 manual if it says something about the minimum packet length? If you want can you attach NetworkInterface.c and the LPC4088 driver here, to see the code?

FreeRTOS-TCP arp reply has invalid checksum

I found a bit in the LPC4088 Ethernet Transmit Descriptor Control Word that will cause short frames to be automatically padded to 64 bytes. I will try this later. Please find the driver software attached. Thank you, Peter

FreeRTOS-TCP arp reply has invalid checksum

Thanks. A minimum packet length is 60 or 64 bytes? You are right, the standard is 64 bytes. The reason why there is a minimum length is interesting: packets travel through a LAN at a certain physical speed. When two short packets are sent simultaneously, both senders might not notice a collision. The first byte of the other packet would arrive only after that last byte was transmitted. So, the longer the minimum packet, the longer the cables of a LAN may be. Note that in a 1 Gbps LAN, a longer minimum length would be better ( like e.g. 512 bytes ) But if a packet is made longer, it must be padded with zero’s, not with random data. Have you also tried to set ipconfigETHERNET_MINIMUM_PACKET_BYTES to 64?

FreeRTOS-TCP arp reply has invalid checksum

Thank you for the factoid about minimum packet length. I diodn’t know that. Here is an update on the progress to date. I have looked at the LPC4088 chip configuration registers, and I have disabled packet padding and CRC generation from the chip. For now, these will be done in software – I can look at performance optimisation later. For now, ipconfigETHERNETMINIMUMPACKET_BYTES remains undefined. I put a breakpoint on xNetworkInterfaceOutput when it is called with an arp reply. The length of the supplied buffer is 64, and the strange extra 4 bytes are included in the supplied buffer. In other words, the buffer supplied from the stack is exactly the buffer that I can see in Wireshark, and is the source of the erroneous bytes. Analysing the code, I see that eARPProcessPacket is called from prvProcessEthernetPacket when an arp request is received. The function eARPProcessPacket modifies the buffer in place, which is then passed to xNetworkInterfaceOutput for transmission. The problem is that the xDataLength parameter of the pxNetworkBuffer is not updated. I think that the incoming arp request has been padded to 64 bytes (either by Windows, or the Ethernet switch that I am using). Wireshark reports the arp request length as 42 bytes, but I gues it has been paddded. The reply length is then 64 bytes, containing invalid data.