[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] IP packets getting dropped

From: David Empson
Subject: Re: [lwip-users] IP packets getting dropped
Date: Fri, 23 Apr 2010 10:45:03 +1200

Something is wrong with your p->tot_len. If you have received an IP packet with 20 byte header and the header says that the body length is 40 bytes, p->tot_len must be at least 60 when ip_input() is called. It should be exactly 60 in this case.

In our Ethernet driver for LWIP, received packets transition through a sequence like this:

1. Frame arrival is detected.

2. A pbuf is allocated to store the Ethernet frame. The usual call for this is pbuf_alloc(PBUF_RAW, packetlength+ETH_PAD_SIZE, PBUF_POOL).

At this point, p->tot_len is equal to packetlength+ETH_PAD_SIZE, and packetlength includes the Ethernet header.

In our port, ETH_PAD_SIZE is zero because our processor doesn't have any alignment restrictions. In yours it should be 2, as ARM needs 32-bit fields in the IP header aligned on 32-bit memory boundaries, and the Ethernet header is 14 bytes.

If you received an IP packet with 20 byte header and 40 byte body, with ETH_PAD_SIZE = 2, the allocated size of the pbuf (and p->tot_len) should be 2+14+20+40 = 76.

3. Frame data is copied from the Ethernet MAC into the pbuf.

4. Frame is passed to ARP to update its table.

5. Ethernet header and padding is deleted from the frame, with pbuf_header(p, -(14+ETH_PAD_SIZE)).

At this point p->tot_len is equal to the number of bytes in the frame after the Ethernet header. If the IP content of the frame was less than 46 bytes (20 byte IP header and 26 byte IP data), the sender must have padded it to the minimum frame length for Ethernet (60 bytes including Ethernet header), so p->tot_len will always be at least 46 bytes here for Ethernet frames. In your case, the IP header and data is 60 bytes, so no additional padding was required, and p->tot_len should be exactly 60 (but it wouldn't matter if it was greater than 60).

6. IP packet is passed to netif->input(), which is ip_input().

I suspect what has happened is that your initial allocation didn't allow for ETH_PAD_SIZE, which probably needs to be 2 on an ARM so that 4 byte fields in the IP header are correctly aligned, and after deletion of the IP header, p->tot_len ends up being 2 bytes too short.

----- Original Message ----- From: "Robert Schilling" <address@hidden>
To: <address@hidden>
Sent: Thursday, April 22, 2010 9:14 PM
Subject: [lwip-users] IP packets getting dropped

Hi Guys,

I'm trying to port lwIP 1.3.2 to a NXP LPC1768. I'm using CoOS (www.coocox.com) as my rtos. ARP is working fine. If I ping my device I get an ARP respond. But ICMP requests don't get a reply.

I found out that all IP packets getting dropped.

  if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) {
    if (iphdr_hlen > p->len)
LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
                               iphdr_hlen, p->len));
    if (iphdr_len > p->tot_len)
LWIP_DEBUGF(IP_DEBUG | 2, ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), "
                               "IP packet dropped.\n",
                               iphdr_len, p->tot_len));
    /* free (drop) packet pbufs */
    printf("Buffer Error\n");
    return ERR_OK;

This code snippet is out of ip.c at line 250. The if condition (iphdr_len > p->tot_len) is true and so the packet gets dropped. The IP packet is corect. Checked with Wireshark. The IP-Header length is 20 byte and IP-data is 40 byte (correct for ICMP-Pig Request). But p->tot_len is always 58 or 59 in order to be greater than 60 byte (whole IP packet).

I hope someone could help me.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]