[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lwip-users] Incoming packet bigger than PBUF_POOL_BUFSIZE
From: |
Gary Spivey |
Subject: |
Re: [lwip-users] Incoming packet bigger than PBUF_POOL_BUFSIZE |
Date: |
Fri, 9 Dec 2011 01:18:28 +0000 |
So ... I did some more debugging with WireShark and a hub, and here is what I
am finding ...
When I have the ETH_PAD_SIZE set to 2, I see the following sent out ..
20 4.468790 ff:ff:bc:9a:78:56 CamtecEl_ff:ff:ff 0x3412
352 Ethernet II
The actual packet is ...
0000 00 00 ff ff ff ff ff ff bc 9a 78 56 34 12 08 00 ..........xV4...
0010 45 00 01 50 00 01 00 00 ff 11 f8 f1 c0 a8 01 02 E..P............
0020 ff ff ff ff 00 44 00 43 01 3c 21 f9 01 01 06 00 .....D.C.<!.....
0030 ab cd 00 01 00 00 00 00 00 00 00 00 00 00 00 00 ................
0040 00 00 00 00 00 00 00 00 bc 9a 78 56 34 12 00 00 ..........xV4...
0050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0110 00 00 00 00 00 00 00 00 63 82 53 63 35 01 01 39 ........c.Sc5..9
0120 02 06 00 37 04 01 03 1c 06 ff 00 00 00 00 00 00 ...7............
0130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
................
In etharp.h, the eth_hdr is defined as:
/** Ethernet header */
struct eth_hdr {
#if ETH_PAD_SIZE
PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]);
#endif
PACK_STRUCT_FIELD(struct eth_addr dest);
PACK_STRUCT_FIELD(struct eth_addr src);
PACK_STRUCT_FIELD(u16_t type);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
Which apparently is packing 2 bytes worth of 0 into the ethernet header.
So ... the ethernet header is padding the packet with ETH_PAD_SIZE bytes of 0.
In etharp.c, there is:
static err_t
etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src,
struct eth_addr *dst)
{
struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload;
LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for
etharp!",
(netif->hwaddr_len == ETHARP_HWADDR_LEN));
ETHADDR32_COPY(ðhdr->dest, dst);
ETHADDR16_COPY(ðhdr->src, src);
ethhdr->type = PP_HTONS(ETHTYPE_IP);
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet
%p\n", (void *)p));
/* send the packet */
return netif->linkoutput(netif, p);
}
Which seems to be sending the pointer to the padding rather than the pointer to
the start of the data that the linkoutput function is supposed to send. I
changed my linkoutput function and saw the correct ethernet header go out, and
then I see DHCP Offers coming back, but apparently there are some other
responses that need to go out that don't want me to change payload pointer.
Have I stumbled onto a bug or am I missing something (not that these are
mutually exclusive in any way :-)
Anyway - I changed my send and receive functions (added below), and this seems
to get me past DHCP with the ETH_PAD_SIZE set to 2. In fact, it seems to solve
all of my problems. I am now sending and receiving packets. Cool.
So - is this the advised way to handle this? (It works :-)
-Gary
//==============================================================================
static err_t ethernetif_send(ethernetif_t *ethernetif, struct pbuf *p)
{
err_t retval = ERR_OK;
void * payload;
// Send the packet - we don't need the ethernetif info as we just have the one
// interface. Also, we don't need to check the total bytes as this is just
// double-checking the lwip structs.
while ( (NULL != p) && (ERR_OK == retval) )
{
payload = p->payload + ETH_PAD_SIZE;
//if (SUCCESS(emac_send(p->payload, p->len)))
if (SUCCESS(emac_send(payload, p->len)))
{
retval = ERR_OK;
}
else
{
retval = ! ERR_OK;
}
p = p->next;
}
return retval;
}
//==============================================================================
static void ethernetif_receive(ethernetif_t * ethernetif)
{
struct eth_hdr *ethhdr;
struct pbuf *p, *chainp;
uint32_t bufsize;
uint32_t bytes_read;
uint32_t bytes_to_read;
void * payload;
// See if there is a packet to get
if (FALSE(emac_checkReceiveIndex()))
{
p = NULL;
}
else
{
// See how much data we need to allocate
bufsize = emac_getReceiveDataSize();
// If there is data (and there should be ...)
if (bufsize)
{
// Allocate a chain of pbufs big enough to hold it
p = pbuf_alloc(PBUF_RAW, bufsize, PBUF_POOL);
// Set up our linked-list index
chainp = p;
// Now let's copy the data into our chain
while (bufsize)
{
// Don't read more than one buffer at a time
bytes_to_read = MINIMUM(bufsize, PBUF_POOL_BUFSIZE);
payload = chainp->payload + ETH_PAD_SIZE;
//bytes_read = emac_receive(chainp->payload, bytes_to_read);
bytes_read = emac_receive(payload, bytes_to_read);
// If something goes wrong, we will bail
// I don't know what this will mean to the rest of the system
if ( bytes_read == 0)
{
pbuf_free(p);
p = NULL;
bufsize = 0;
}
// If we successfully read, advance the chain and decrement the amount
// of data left to read.
else
{
chainp = chainp->next;
bufsize -= bytes_read;
}
}
}
}
// If we have a packet,
if (p != NULL) {
// points to packet payload, which starts with an Ethernet header
ethhdr = (struct eth_hdr *) p->payload;
switch (htons(ethhdr->type)) {
// IP or ARP packet?
case ETHTYPE_IP:
case ETHTYPE_ARP:
#if PPPOE_SUPPORT
// PPPoE packet?
case ETHTYPE_PPPOEDISC:
case ETHTYPE_PPPOE:
#endif // PPPOE_SUPPORT
// send complete packet to tcpip_thread to process
if (ethernetif->input(p, ethernetif)!=ERR_OK)
{
// If there was a problem with the packet, free it up
pbuf_free(p);
}
break;
default:
pbuf_free(p);
break;
}
}
}
-Gary
On 8 Dec 2011, at 18:51, Gary Spivey wrote:
> What is the preferred way to configure lwip so that I can either accept
> packets larger than PBUF_POOL_BUFSIZE or ensure that I don't receive them?
To accept packets larger than PBUF_POOL_BUFSIZE you should, when you receive
them, copy them into the chain of pbufs that you get when you alloc, being
careful to split the received data across the pbufs as necessary.
To ensure that you don't receive packets larger than PBUF_POOL_BUFSIZE, set
that value larger than the biggest packet you can receive. This is a property
of the LAN you are connected to (i.e. it is a value that should be known by all
the hosts and configured the same) and can vary, so I can't tell you a good
value.
In the default, we assume that the largest value on the network is
MSS+40+PBUF_LINK_HLEN, where the 40 is for IP and TCP headers. It is possible
for TCP headers to be bigger than that (if there are options included for
example) or for another host on the network to have a larger MSS and MTU than
lwIP's default, and so you may need to adjust PBUF_POOL_BUFSIZE to match if you
want to fit a frame into a single buffer.
I'm not sure whey DHCP didn't work when you started splitting packets across
buffers. It should. It's either a bug in lwIP or a bug in the way you were
filling the buffers. If you can get more information on the reason for the
failure that would be useful.
Note that you should also handle chains of pbufs on the send path in your
driver. With a relatively small PBUF_POOL_BUFSIZE lwIP can pass packets for
transmission to the driver as a chain as well.
Hope that helps,
Kieran
_______________________________________________
lwip-users mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/lwip-users
_______________________________________________
lwip-users mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/lwip-users
- [lwip-users] Incoming packet bigger than PBUF_POOL_BUFSIZE, Gary Spivey, 2011/12/07
- Re: [lwip-users] Incoming packet bigger than PBUF_POOL_BUFSIZE, web, 2011/12/07
- Re: [lwip-users] Incoming packet bigger than PBUF_POOL_BUFSIZE, Gary Spivey, 2011/12/07
- Re: [lwip-users] Incoming packet bigger than PBUF_POOL_BUFSIZE, Bill Auerbach, 2011/12/08
- Re: [lwip-users] Incoming packet bigger than PBUF_POOL_BUFSIZE, Gary Spivey, 2011/12/08
- Re: [lwip-users] Incoming packet bigger than PBUF_POOL_BUFSIZE, Kieran Mansley, 2011/12/08
- Re: [lwip-users] Incoming packet bigger than PBUF_POOL_BUFSIZE, Gary Spivey, 2011/12/08
- Re: [lwip-users] Incoming packet bigger than PBUF_POOL_BUFSIZE,
Gary Spivey <=
- Re: [lwip-users] Incoming packet bigger than PBUF_POOL_BUFSIZE, address@hidden, 2011/12/09
- Re: [lwip-users] Incoming packet bigger than PBUF_POOL_BUFSIZE, Simon Goldschmidt, 2011/12/09
- Re: [lwip-users] Incoming packet bigger than PBUF_POOL_BUFSIZE, Simon Goldschmidt, 2011/12/09