2009/6/29 Kieran Mansley <[email protected]>
>
> It is not your problem for sure, as lwIP receives the UDP packet, thinks
> the checksum is correct, and sends a response. The response gets lots
> somewhere in etharp_output() before making it onto the network though.
>
> I notice that in the udp_echo.trace.txt there is the following:
>
> <LF>find_entry: selecting empty entry 1
> <LF>etharp_request: sending ARP request.etharp_raw: sending raw ARP
> packet.etharp_query: queued packet 215bf0 on ARP entry 1
>
> This is odd for two reasons: (i) it should already have an entry for the
> PC's MAC address as it's updated that entry lots already from the other
> ARP requests seen on the network earlier; and (ii) the packet it sends
> is not an ARP request for the PC's MAC, but a gratuitous ARP of its own
> MAC. I think there is definitely something going wrong here.
>
>
So I find where it was not working. I will try to explain why it doesn't
work, sorry if it is not as clear as it should but my English is a bit
poor...
As you said, the response was lost somewhere in etharp_output. This is
actually done in ip_output_if (file src/core/ipv4/ip.c line 510) because
lwIP then write the destination ip in the ip header with the use of the
pointer dest.
This pointer was obtained at the beginning of the process by the function
and macro use :
buf = netconn_recv(conn);
addr = netbuf_fromaddr(buf);
addr is a copy of the buf->addr which is pointing on the source ip header
field. The buf is created by the netconn_recv call.
We use addr to connect to the remote port with netconn_connect(conn, addr,
port)
But if we don't set this buf->addr to NULL , then it will be used by the
do_send function (src/api/api_msg.c line 881) to send the packet.
But as buf->addr is a pointer to the source ip header, this value will be
overwrite by ip_output_if when writing the new source in the new header ip
(file src/core/ipv4/ip.c line 510). So the dest in this function which is
use at the end on the call netif->output(netif, p, dest) will be in fact the
source ip. It then result on an ARP gratuitous request which is never reply
and a lost of the packet.
So here is the solution :
===================
Add a line in the contrib/ports/unix/proj/unixsim/apps/udpecho.c example
which set buf->addr to NULL :
void
udpecho_thread(void *arg)
{
static struct netconn *conn;
static struct netbuf *buf;
static struct ip_addr *addr;
static unsigned short port;
char buffer[4096];
conn = netconn_new(NETCONN_UDP);
netconn_bind(conn, NULL, 7);
while (1) {
buf = netconn_recv(conn);
addr = netbuf_fromaddr(buf);
port = netbuf_fromport(buf);
netconn_connect(conn, addr, port);
netbuf_copy(buf, buffer, buf->p->tot_len);
buffer[buf->p->tot_len] = '\0';
buf->addr = NULL; // we must set addr to NULL, because addr is a pointer
on the source ip header which
// will be overwrite by ip_output_if function. This
lead to an ARP gratuitous request
// and a failure to send the buf.
// if we set buf-addr to NULL, then we force the
do_send function to use the
// udp_send which then will use the pcb->remote_ip
destination ip
netconn_send(conn, buf);
printf("got %s\n", buffer);
netbuf_delete(buf);
}
}
I didn't try to compile and test this example on a Linux station, but it
does'nt work without this modification on my embedded target.
If you have any suggestions on what should be better to do, please let me
know.
Thanks to Kieran for it's very valuated help.
Patrick.
_______________________________________________
lwip-users mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/lwip-users