[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 */
pbuf_free(p);
IP_STATS_INC(ip.lenerr);
IP_STATS_INC(ip.drop);
snmp_inc_ipindiscards();
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.