recvfrom() returning wrong address
Hamish Moffatt
hamish at cloud.net.au
Thu Aug 23 05:55:29 UTC 2007
I'm using recvfrom() to receive UDP datagrams sent to the network
broadcast address, and then using from the from address to send a reply
directly to the originator.
Occasionally recvfrom() sets the from address to be my local interface
address instead though. Very weird.
Here's what I mean. I have three systems on my subnet, 192.168.1.118,
119 and .120. 118 is sending broadcasts to 192.168.1.255.
tcpdump shows (on either .119 or .120):
03:27:26.377061 IP 192.168.1.118.1025 > 192.168.1.255.65022: UDP, length 22
All are configured with a broadcast address of 192.168.1.255.
I wrote a little program to call recvfrom() and dump the reported
address the packets come from (source below); here's the output on .119:
# ./recvfrom
returned from recvfrom
received from: 192.168.1.118
However when I run it on .120,
# ./recvfrom
returned from recvfrom
received from: 192.168.1.120
How can this be?
Here's my recvfrom.c test program.
I'm running uClibc 0.9.28, but a quick glance at SVN shows that most of
the networking code hasn't changed in 18 months.
Thanks
Hamish
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <stdio.h>
int main(void) {
int sock;
struct sockaddr_in sa;
struct sockaddr_in from;
int fromlen;
char buf[4096];
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
perror("sock");
sa.sin_addr.s_addr = INADDR_ANY;
sa.sin_port = htons(65022);
sa.sin_family = AF_INET;
if (bind(sock, (struct sockaddr*)&sa, sizeof(sa)) < 0)
perror("bind");
fromlen = sizeof(from);
if (recvfrom(sock, buf, 4096, 0, (struct sockaddr*)&sa, &fromlen) < 0)
perror("recvfrom");
printf("returned from recvfrom\n");
printf("received from: %s\n", inet_ntoa(sa.sin_addr));
return 0;
}
--
Hamish Moffatt VK3SB <hamish at debian.org> <hamish at cloud.net.au>
More information about the uClibc
mailing list