Malformed DHCP Packet Freertos + TCP

Malformed DHCP Packet Freertos + TCP

I’m trying to get freertos plus TCP working on a stm32f4. Everything seems to be working at the driver level but when I wireshark it I find this error.


What I’m seeing in wireshark is exactly what I can see if I view the memory of the chip. So at least I know my driver is working.

Here is the code I send with. Huge thanks in advance.

uint8_t sn = 0;
// Wait for space in the transmit buffer
    uint16_t freesize = getSn_TX_FSR(sn);
    if(getSn_SR(sn) == SOCK_CLOSED) {
        return -1;
    if (pxDescriptor->xDataLength <= freesize) break;

wiz_send_data(sn, pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength);
setSn_CR(sn, Sn_CR_SEND);

The code you have posted is very specific to your device, so you would probably get more knowledgeable information about the behaviour at this low level driver level from the vendor of the chip and/or driver itself. It would be interesting to know though if the packet being send using the code you posted matches what you are seeing on the wire in Wireshark. If the packet sent to that while loop matches what is on the wire then it is likely to be a configuration issue - on the other hand if the packet sent to the while loop is correct and only corrupt on the wire then it is likely to be something in the driver that is the issue.

I’m sorry, but I don’t know about the functions getSn_xxx().

It looks like pxDescriptor is declared as a pointer to NetworkBufferDescriptor_t. How did you allocate that descriptor?

Actually, using NetworkBufferDescriptor_t is reserved for internal use only: the IP-task and the network drivers make use of it.

At the application level, you supposed to use the BSD-style API interface, such as FreeRTOS_socket(), FreeRTOS_connect(), FreeRTOS_send() etc.

Beside that, if you want to share the output of WireShark, could you ZIP a PCAP file and attach it to your post?

One thing I do see in the picture is the send of give packet doesn’t have a MAC-address, it shows 6 zero’s only.

Have you already worked without DHCP, with a static IP-address? Can you ping your device? Can you connect to it?

Yep, It is specific so I double checked it against the memory location of the frame buffer and it’s correct.

trying to follow this guide.

As you are working on a stm32f4, I don’t think you need to port FreeRTOS+TCP.
There is a good driver here. Did you use that?

Can’t use it because I’m using an external PHY. All the drivers I can find are for the internal Ethernet of the f4 series. I don’t think it’s the driver though because wireshark is seeing the exact thing that is generated in “pxDescriptor->pucEthernetBuffer”. The PHY is in RAW mode which means it sends out exactly what it receives from freeRTOS and it seems to be working as such.

Thanks for everyone having a punt so far. Very appreciated. Here is a side by side of the broken DHCP request and a proper one. I’m 100% sure the driver is not at fault. It’s transmitting exactly what is generated by Plus TCP/FreeRTOS+TCP V2.2.1.
I probably have a error in the config file somewhere. Any one else use Plus TCP.

This go good up to the 16th byte where an extra 2 bytes are added. Then the alignment is out and it’s buggered.

Those zeros shouldn’t be there. Got to hunt down now where they are added in.

If I am not mistaken, the 2 zero’s you see are at offset 24, which is the 2-byte IP checksum.
I can not see a reason why 2 bytes are inserted at that place.
I already asked you before, can you please send PCAP files in a ZIP file, in stead of showing pictures of WireShark?

Here are 2 packets from my STM32F407, using the internal EMAC: (342 Bytes)
I don’t see a reason why the contents of the DHCP packets would be erroneous on a different system.
If you have doubts about your configuration, please send your FreeRTOSConfig.h and FreeRTOSIPConfig.h files. (8.3 KB)

Thanks for taking the time to look at this.

Yes, I also see that 2 bytes are inserted at offset 24.

When you disable DHCP, does everything else work properly?
Have you used TCP and UDP already? Can you ping the board when it uses a static IP-address?

I just synced with AWS/freertos master, but I can not replicate the DHCP problem.

You have included a file called FreeRTOSIPConfig.h, but that is a copy of FreeRTOSIPConfigDefaults.h.

Here is my version for STM32F4x: FreeRTOSIPConfig.h (21.0 KB)

Your FreeRTOSConfig.h seems OK to me.

What external MAC are you using? How do you communicate with it?

Communication is via SPI. I’d be suspicious of my driver implementation if i wasn’t able to read the memory of the STM chip and see that it is an accurate send of the data at that address. I think the problem apears at around line 146 of FreeRTOS_UDP_IP.c. If I put a watch on the heap address where the pucEthernetBuffer is placed I can see that is where the header is first placed into memory. At this line “pxIPHeader->ulDestinationIPAddress = pxNetworkBuffer->ulIPAddress;” i starts to form the rest of the buffer but it is all out by 2 bytes. Then when it drops in the checksum it’s out by 2 bytes also. Hope this helps. The codes a bit beyond me I’m afraid. I’m told freeRTOS is one of the easiest to read and i can dig into a little bit. But i get out of my depth pretty quick.

Doesn’t that board have the TCP/IP stack on the chip - i.e. in the silicon?

Yeah it does, but I’m using it in MACRAW mode so i can get the advantage of using the FreeRTOS features. Libraries for other freertos features are written to interface with the freertos TCP stack. I thought it would be better for future compatibility to go with the freertos stack instead. The problem is all my udp packets. as seen in this (444 Bytes)

Turning off DHCP doesn’t help because ARP packets are bugged as well.

Turning off DHCP doesn’t help because ARP packets
are bugged as well.

ARP doesn’t have an IPv4 header. Is it malformed in the same way, inserting 2 zero’s at offset 24?

Here is the declaration of the IP-header:

#include "pack_struct_start.h"
struct xIP_HEADER
	uint8_t ucVersionHeaderLength;        /*  0 + 1 =  1 */
	uint8_t ucDifferentiatedServicesCode; /*  1 + 1 =  2 */
	uint16_t usLength;                    /*  2 + 2 =  4 */
	uint16_t usIdentification;            /*  4 + 2 =  6 */
	uint16_t usFragmentOffset;            /*  6 + 2 =  8 */
	uint8_t ucTimeToLive;                 /*  8 + 1 =  9 */
	uint8_t ucProtocol;                   /*  9 + 1 = 10 */
	uint16_t usHeaderChecksum;            /* 10 + 2 = 12 */
	uint32_t ulSourceIPAddress;           /* 12 + 4 = 16 */
	uint32_t ulDestinationIPAddress;      /* 16 + 4 = 20 */
#include "pack_struct_end.h"

Although this is tested with configASSERT(), can you confirm that the struct is 20 bytes long?

Yes, I can see that in the code but i’m not sure how to test it’s length when the code is running sorry. I’m right at the edge of my understanding.
Yes ARP is not working either. I attached the test but here is a pic.
The two bytes in front of the are second mac address are where things get offset. Providing the opcode request is meant to be “00 01” then the problem in this case is byte 23 and 24.

I’ve updated all of the file to the latest versions on github. Except for the files in “CMSIS_RTOS_V2” Because the project was originally built with CubeIDE. I’m not sure where to get them from. Everything else i updated. I’ve also updates my freertosipconfig to look like this.
FreeRTOSIPConfig.h (21.0 KB)

Thanks again for all your help.

OK, I reckon i’ve made that many attempts to fix it i’ve made it worse. I’m regenerating the project and starting from scratch. I’ll let you know in 30 minutes if this fixes it.


Problem solved, I’m so sorry guys. I don’t have a clue what changed but the problem is gone. Ver appreciative of your help.

Very good, glad to hear. Thanks for taking the effort to report back.
The lesson to learn: sometimes it can be good to start a project all over again :slight_smile:
Thanks, Hein