Networking Forums

Networking Forums > Computer Networking > Linux Networking > Problem receiving UDP broadcast packets.

Reply
Thread Tools Display Modes

Problem receiving UDP broadcast packets.

 
 
Grant Edwards
Guest
Posts: n/a

 
      04-19-2011, 11:19 PM
I'm trying to receive UDP broadcast packets. It's not working, and
I'm stumped.

Here's my test program:

------------------------------------------------------------------------
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <stdio.h>

void error(const char *msg)
{
perror(msg);
exit(0);
}

int main(int argc, char *argv[])
{
int sock, n;
struct sockaddr_in server;
char buf[1024];
int one = 1;

if (argc < 2)
{
fprintf(stderr, "ERROR, no port provided\n");
exit(0);
}

sock=socket(AF_INET, SOCK_DGRAM, 0);

if (sock < 0)
error("Opening socket");

if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one))
error("setsockopt SO_REUSEADDR");

if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &one, sizeof one))
error("setsockopt SO_BROADCAST");

bzero(&server, sizeof server);
server.sin_family=AF_INET;
server.sin_addr.s_addr=INADDR_ANY;
server.sin_port=htons(atoi(argv[1]));

if (bind(sock,(struct sockaddr *)&server, sizeof server)<0)
error("binding");

while (1)
{
n = recv(sock,buf,(sizeof buf)-1,0);
if (n < 0)
error("recv");
buf[n] = '\0';
printf("rx: '%s'\n",buf);
}
}
------------------------------------------------------------------------

Here's the tcpdump output showing that broadcast packets are being
received on the eth1 interface on the receiving machine:

04:01:37.329967 IP 10.0.0.1.5010 > 255.255.255.255.5010: UDP, length 13
0x0000: ffff ffff ffff 0018 e708 2033 0800 4500
0x0010: 0029 0000 4000 4011 30c4 0a00 0001 ffff
0x0020: ffff 1392 1392 0015 7165 3133 3033 3235
0x0030: 3435 3639 2e30 3100 0000
04:01:38.149948 IP 10.0.0.1.5010 > 255.255.255.255.5010: UDP, length 13
0x0000: ffff ffff ffff 0018 e708 2033 0800 4500
0x0010: 0029 0000 4000 4011 30c4 0a00 0001 ffff
0x0020: ffff 1392 1392 0015 6f5d 3133 3033 3235
0x0030: 3435 3639 2e38 3300 0000

But, the test program doesn't never sees the broadcast packets unless
the source IP address in the broadcast packets is on the same subnet
as the receiving machine's interface.

In the test case above the sending machine is 10.0.0.1/8 and the
receiving machine is 172.16.12.34/16. But, since the packets are
destined for IP address 255.255.255.255, they should be received since
255.255.255.255 matches 172.16.12.34/16. Right?

I know the're being received by the interface, since tcpdump sees
them. They should be passed up the stack, since iptables says
everything is being accepted:

# /sbin/iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

So I'm stumped as to why my program isn't receiving the broadcast
packet.

Any ideas?

--
Grant Edwards grant.b.edwards Yow! Eisenhower!! Your
at mimeograph machine upsets
gmail.com my stomach!!
 
Reply With Quote
 
 
 
 
Bill Marcum
Guest
Posts: n/a

 
      04-20-2011, 04:11 PM
On 2011-04-19, Grant Edwards <(E-Mail Removed)> wrote:
> Here's the tcpdump output showing that broadcast packets are being
> received on the eth1 interface on the receiving machine:
>
> 04:01:37.329967 IP 10.0.0.1.5010 > 255.255.255.255.5010: UDP, length 13
> 0x0000: ffff ffff ffff 0018 e708 2033 0800 4500
> 0x0010: 0029 0000 4000 4011 30c4 0a00 0001 ffff
> 0x0020: ffff 1392 1392 0015 7165 3133 3033 3235
> 0x0030: 3435 3639 2e30 3100 0000
> 04:01:38.149948 IP 10.0.0.1.5010 > 255.255.255.255.5010: UDP, length 13
> 0x0000: ffff ffff ffff 0018 e708 2033 0800 4500
> 0x0010: 0029 0000 4000 4011 30c4 0a00 0001 ffff
> 0x0020: ffff 1392 1392 0015 6f5d 3133 3033 3235
> 0x0030: 3435 3639 2e38 3300 0000
>
> But, the test program doesn't never sees the broadcast packets unless
> the source IP address in the broadcast packets is on the same subnet
> as the receiving machine's interface.
>

I think you need to set the interface to promiscuous mode.



--
A wise man cannot be insulted. If the insult has no meaning, he ignores
it. If the insult does have meaning, he deserves it.
 
Reply With Quote
 
Tauno Voipio
Guest
Posts: n/a

 
      04-20-2011, 06:47 PM
Grant Edwards wrote:
> I'm trying to receive UDP broadcast packets. It's not working, and
> I'm stumped.
>
> Here's the tcpdump output showing that broadcast packets are being
> received on the eth1 interface on the receiving machine:
>
> 04:01:37.329967 IP 10.0.0.1.5010 > 255.255.255.255.5010: UDP, length 13
> 0x0000: ffff ffff ffff 0018 e708 2033 0800 4500
> 0x0010: 0029 0000 4000 4011 30c4 0a00 0001 ffff
> 0x0020: ffff 1392 1392 0015 7165 3133 3033 3235
> 0x0030: 3435 3639 2e30 3100 0000
> 04:01:38.149948 IP 10.0.0.1.5010 > 255.255.255.255.5010: UDP, length 13
> 0x0000: ffff ffff ffff 0018 e708 2033 0800 4500
> 0x0010: 0029 0000 4000 4011 30c4 0a00 0001 ffff
> 0x0020: ffff 1392 1392 0015 6f5d 3133 3033 3235
> 0x0030: 3435 3639 2e38 3300 0000
>
> But, the test program doesn't never sees the broadcast packets unless
> the source IP address in the broadcast packets is on the same subnet
> as the receiving machine's interface.
>
> In the test case above the sending machine is 10.0.0.1/8 and the
> receiving machine is 172.16.12.34/16. But, since the packets are
> destined for IP address 255.255.255.255, they should be received since
> 255.255.255.255 matches 172.16.12.34/16. Right?



The IP address 255.255.255.255 is the local subnet broadcast
address, this time equivalent to 10.255.255.255. It must not
traverse routers, and the receiving IP stack in a different
subnet is free to ignore them as martians.

You should not have two local subnets running in the
same physical local net segment, and suppose that they
will be routed as a single local net.

--

Tauno Voipio
 
Reply With Quote
 
Grant Edwards
Guest
Posts: n/a

 
      04-20-2011, 09:20 PM
On 2011-04-20, Bill Marcum <(E-Mail Removed)> wrote:
> On 2011-04-19, Grant Edwards <(E-Mail Removed)> wrote:
>> Here's the tcpdump output showing that broadcast packets are being
>> received on the eth1 interface on the receiving machine:
>>
>> 04:01:37.329967 IP 10.0.0.1.5010 > 255.255.255.255.5010: UDP, length 13
>> 0x0000: ffff ffff ffff 0018 e708 2033 0800 4500
>> 0x0010: 0029 0000 4000 4011 30c4 0a00 0001 ffff
>> 0x0020: ffff 1392 1392 0015 7165 3133 3033 3235
>> 0x0030: 3435 3639 2e30 3100 0000
>> 04:01:38.149948 IP 10.0.0.1.5010 > 255.255.255.255.5010: UDP, length 13
>> 0x0000: ffff ffff ffff 0018 e708 2033 0800 4500
>> 0x0010: 0029 0000 4000 4011 30c4 0a00 0001 ffff
>> 0x0020: ffff 1392 1392 0015 6f5d 3133 3033 3235
>> 0x0030: 3435 3639 2e38 3300 0000
>>
>> But, the test program doesn't never sees the broadcast packets unless
>> the source IP address in the broadcast packets is on the same subnet
>> as the receiving machine's interface.

>
> I think you need to set the interface to promiscuous mode.


Nope. The interface is already receiving the packets or tcpdump
wouldn't see them.

What I had to do was disable reverse-path filtering:


# echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
# echo 0 > /proc/sys/net/ipv4/conf/ethN/rp_filter


--
Grant Edwards grant.b.edwards Yow! Are we wet yet?
at
gmail.com
 
Reply With Quote
 
Grant Edwards
Guest
Posts: n/a

 
      04-20-2011, 09:32 PM
On 2011-04-20, Tauno Voipio <(E-Mail Removed)> wrote:
> Grant Edwards wrote:
>> I'm trying to receive UDP broadcast packets. It's not working, and
>> I'm stumped.
>>
>> Here's the tcpdump output showing that broadcast packets are being
>> received on the eth1 interface on the receiving machine:
>>
>> 04:01:37.329967 IP 10.0.0.1.5010 > 255.255.255.255.5010: UDP, length 13
>> 0x0000: ffff ffff ffff 0018 e708 2033 0800 4500
>> 0x0010: 0029 0000 4000 4011 30c4 0a00 0001 ffff
>> 0x0020: ffff 1392 1392 0015 7165 3133 3033 3235
>> 0x0030: 3435 3639 2e30 3100 0000
>> 04:01:38.149948 IP 10.0.0.1.5010 > 255.255.255.255.5010: UDP, length 13
>> 0x0000: ffff ffff ffff 0018 e708 2033 0800 4500
>> 0x0010: 0029 0000 4000 4011 30c4 0a00 0001 ffff
>> 0x0020: ffff 1392 1392 0015 6f5d 3133 3033 3235
>> 0x0030: 3435 3639 2e38 3300 0000
>>
>> But, the test program doesn't never sees the broadcast packets unless
>> the source IP address in the broadcast packets is on the same subnet
>> as the receiving machine's interface.
>>
>> In the test case above the sending machine is 10.0.0.1/8 and the
>> receiving machine is 172.16.12.34/16. But, since the packets are
>> destined for IP address 255.255.255.255, they should be received since
>> 255.255.255.255 matches 172.16.12.34/16. Right?

>
> The IP address 255.255.255.255 is the local subnet broadcast address,
> this time equivalent to 10.255.255.255.


Hmm. I don't understand what you mean by that. 255.255.255.255 is
definitely different than 10.255.255.255 -- sending to the two
produces different packets and different results in the receiving
device.

> It must not traverse routers, and the receiving IP stack in a
> different subnet is free to ignore them as martians.


Indeed. Disabling reverse-path filtering [which was the $64 answer]
allows me to receive on the 172.16.12.34 device the "martians" sent to
255.255.255.255 from 10.0.0.1.

> You should not have two local subnets running in the same physical
> local net segment, and suppose that they will be routed as a single
> local net.


Standard Excuse #17B: I didn't invent the protocol, I'm just
implementing it.

FWIW, I don't suppose they are routed at all -- all I'm worried about
are devices on a single Ethernet segment. The whole point of the
exercise is to implement a UDP-based device discovery and
configuration protocol that's used to find unconfigured or
misconfigured devices [which are running Linux] on an Ethernet segment
and configure them so they _are_ all on the right subnet.

In some ways (at least under Linux) it would be simpler and easier to
use a custom non-IP protocol at the Ethernet datagram level. However,
doing stuff like that under Windows seems to cause sufficient pain and
suffering that jumping through hoops to get UDP to work in the desired
manner is a net win.

--
Grant Edwards grant.b.edwards Yow! HUMAN REPLICAS are
at inserted into VATS of
gmail.com NUTRITIONAL YEAST ...
 
Reply With Quote
 
David Schwartz
Guest
Posts: n/a

 
      04-20-2011, 10:48 PM
On Apr 19, 4:19*pm, Grant Edwards <inva...@invalid.invalid> wrote:

> So I'm stumped as to why my program isn't receiving the broadcast
> packet.
>
> Any ideas?


RFC919 specifies that the behavior of broadcasting to 255.255.255.255
be identical to the effect of broadcasting to the subnet-local
broadcast address. RFC922 clarified this rule -- in the absence of
VLSM, there is no difference between a subnet broadcast address and
the all one's address.

"Thus, a host on net 36, for example, may:
- broadcast to all of its immediate neighbors by using
255.255.255.255
- broadcast to all of net 36 by using 36.255.255.255
without knowing if the net is subnetted; if it is not, then both
addresses have the same effect."
- RFC 922 "Broadcasting Internet Datagrams in the Presence of Subnets"

In effect, 255.255.255.255 means *this* subnet, not *any* subnet.

DS
 
Reply With Quote
 
David Schwartz
Guest
Posts: n/a

 
      04-20-2011, 10:50 PM
On Apr 20, 2:32*pm, Grant Edwards <inva...@invalid.invalid> wrote:

> FWIW, I don't suppose they are routed at all -- all I'm worried about
> are devices on a single Ethernet segment. *The whole point of the
> exercise is to implement a UDP-based device discovery and
> configuration protocol that's used to find unconfigured or
> misconfigured devices [which are running Linux] on an Ethernet segment
> and configure them so they _are_ all on the right subnet.


Wrong tool for the job. How can you expect subnet-local broadcasts to
find devices that are configured in the wrong subnet?

DS
 
Reply With Quote
 
Rick Jones
Guest
Posts: n/a

 
      04-22-2011, 05:26 PM
Grant Edwards <(E-Mail Removed)> wrote:
> On 2011-04-20, Bill Marcum <(E-Mail Removed)> wrote:
> > I think you need to set the interface to promiscuous mode.


> Nope. The interface is already receiving the packets or tcpdump
> wouldn't see them.


Tcpdump tends to put the interface into promiscuous mode.

rick jones
--
portable adj, code that compiles under more than one compiler
these opinions are mine, all mine; HP might not want them anyway...
feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...
 
Reply With Quote
 
Grant Edwards
Guest
Posts: n/a

 
      04-23-2011, 03:01 PM
On 2011-04-22, Rick Jones <(E-Mail Removed)> wrote:
> Grant Edwards <(E-Mail Removed)> wrote:
>> On 2011-04-20, Bill Marcum <(E-Mail Removed)> wrote:
>> > I think you need to set the interface to promiscuous mode.

>
>> Nope. The interface is already receiving the packets or tcpdump
>> wouldn't see them.

>
> Tcpdump tends to put the interface into promiscuous mode.


Not if you use the -p option.

--
Grant


 
Reply With Quote
 
Junior Member
Join Date: May 2012
Posts: 3

 
      05-07-2012, 08:10 AM
Hi,
I am facing the same problem as Grant has quoted in this thread.
I am using Linux. I have my interface up and running, but it is not configured with an IP address, intentionally. So, it should be able to accept broadcast messages.

[root@sreeramb-linux Network]# uname -a
Linux sreeramb-linux 2.6.35.6-45.fc14.i686 #1 SMP Mon Oct 18 23:56:17 UTC 2010 i686 i686 i386 GNU/Linux
[root@sreeramb-linux Network]# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 08:00:27:9D:13:EE
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:161628 errors:0 dropped:0 overruns:0 frame:0
TX packets:32748 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:23403260 (22.3 MiB) TX bytes:2727456 (2.6 MiB)

[root@sreeramb-linux Network]#

The rp-filter is also set to 0.

[root@sreeramb-linux Network]# cat /proc/sys/net/ipv4/conf/eth0/rp_filter
0
[root@sreeramb-linux Network]# cat /proc/sys/net/ipv4/conf/all/rp_filter
0
[root@sreeramb-linux Network]#

In my program, I am doing the following:
1. Open a UDP socket.
2. Set SO_DEBUG and SO_REUSEADDR.
3. Set SO_BROADCAST flag.
4. Bind to port 68 (I have made sure that there is no other dhcp client running).
5. Perform SO_BINDTODEVICE to eth0
6. recvfrom() on the socket.

I elicit a broadcast response from the server, which I expect to read from my application. The response is reaching my PC since I am able to see it from wireshark, but my application is not catching it.

Should I use any more socket options to accept the broadcast packets?
Should I make any changes to any of the files in the system to obtain broadcast pkts?
Kindly suggest.

My program:
-------------------
[root@sreeramb-linux DHCP]# cat dhcp.c
/* This is a test program to bind a socket to an interface
* instead of to an IP address(which is done normally).
* Also, broadcasting is enabled for this socket so that
* any broadcast packet is sent over this socket.
*/

#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>

#define SA struct sockaddr
#define IFC "eth0"
#define PORT 67
#define IFCSZ sizeof(IFC)

struct dhcp_header {
unsigned char op;
unsigned char htype;
unsigned char hlen;
unsigned char hops;
int xid;
short secs;
short flags;
struct in_addr ciaddr;
struct in_addr yiaddr;
struct in_addr siaddr;
struct in_addr giaddr;
unsigned char chaddr[16];
unsigned char sname[64];
unsigned char file[128];
unsigned char opts[128];
};

int main(int argc, char **argv) {
int sock, retn;
struct sockaddr_in peer, addr;
char mesg[] = "Hello World!";
int val=1, size = sizeof(val);

/* Create an UDP socket first. */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("Socket");
exit(-1);
}
printf("Created socket successfully.\n");

/* Enable the SO_DEBUG option for this socket. */
retn = setsockopt(sock, SOL_SOCKET, SO_DEBUG, &val, size);
if (retn < 0) {
perror("SO_DEBUG");
close(sock);
exit(-1);
}
printf("Successfully enabled the SO_DEBUG flag for the socket.\n");

/* Now, set the SO_REUSEADDR flag for this socket. */
retn = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, size);
if (retn < 0) {
perror("SO_REUSEADDR");
close(sock);
exit(-1);
}
printf("Successfully set the SO_REUSEADDR flag to this socket.\n");

/* Now, set the broadcast flag for this socket. */
val = 1, size = sizeof(val);
retn = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &val, size);
if (retn < 0) {
perror("SO_BROADCAST");
close(sock);
exit(-1);
}
printf("Successfully set the broadcast flag to this socket.\n");

/* Now, bind to device, eth0 */
retn = setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, IFC, IFCSZ);
if (retn < 0) {
perror("SO_BINDTODEVICE:eth0");
close(sock);
exit(-1);
}
printf("Successfully bound to device '%s'\n", IFC);

/* Set the structure to send to the broadcast address. */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(68);
retn = bind(sock, (SA *)&addr, sizeof(SA));
if (retn < 0) {
perror("BIND_TO_PORT");
close(sock);
exit(-3);
}
printf("Successfully bound to port 68 also.\n");

/* Set the structure to send to the broadcast address. */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
inet_aton("255.255.255.255", &addr.sin_addr);

send_dhcp_discover(sock, addr);
recv_dhcp_offer(sock);
}

int send_dhcp_discover(int sock, struct sockaddr_in addr) {
int retn, i = 0;
struct dhcp_header hdr;

memset(&hdr, 0, sizeof(hdr));
hdr.op = 1;
hdr.htype = 1;
hdr.hlen = 6;
hdr.xid = 1;
hdr.flags = 128;
hdr.chaddr[0] = 0x08;
hdr.chaddr[1] = 0x00;
hdr.chaddr[2] = 0x27;
hdr.chaddr[3] = 0x9D;
hdr.chaddr[4] = 0x13;
hdr.chaddr[5] = 0xEE;


/* The first four octets are supposed to be magic number. */
hdr.opts[i++] = 99;
hdr.opts[i++] = 130;
hdr.opts[i++] = 83;
hdr.opts[i++] = 99;

/* The next option depicts the message type. */
hdr.opts[i++] = 53; // DHCP message type.
hdr.opts[i++] = 1; // Length = 1
hdr.opts[i++] = 1; // DHCP Discover message.

/* Let the client make a wish that it be assigned 192.168.1.25 */
hdr.opts[i++] = 50; // Preferred IP address
hdr.opts[i++] = 4; // Length = 4
inet_aton("192.168.1.25", (struct in_addr *)&hdr.opts[i]);
i += 4;

hdr.opts[i++] = 255; // End of options.

/* Now, broadcast the message. */
retn = sendto(sock, &hdr, sizeof(hdr), 0, (SA *)&addr, sizeof(SA));
if (retn < 0) {
perror("sendto");
close(sock);
exit(-2);
}
printf("Successfully broadcasted the message.\n");

printf("IFC size is %d\n", IFCSZ);
return 0;
}

/* This program will receive the DHCP offer message */
int recv_dhcp_offer(int sock) {
int retn, size = sizeof(SA);
struct sockaddr_in server;
unsigned char mesg[sizeof(struct dhcp_header)];

/* Receive the message */
printf("About to call recvfrom().\n");
retn = recvfrom(sock, mesg, sizeof(mesg), 0, (SA *)&server, &size);
if (retn < 0) {
perror("recvfrom");
exit(-1);
}

printf("Received message: DHCP OFFER\n");
return 0;
}

[root@sreeramb-linux DHCP]#

Please guide.

Regards,
Sreeram
 
Reply With Quote
 
 
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Linux box doesn't send tcp ACK in handshake when receiving SYN/ACK toa broadcast address Adam Linux Networking 3 06-11-2011 12:10 PM
Broadcast packets in C killua Linux Networking 4 06-06-2007 08:58 PM
Connected but not receiving packets mismith5 Wireless Networks 1 02-14-2007 11:08 PM
I'm receiving TCP packets via a raw socket. Is this normal? Boltar Linux Networking 0 12-29-2006 09:55 AM
Linksys WUSB54G not receiving packets in XP brkptr Wireless Internet 0 09-07-2004 07:47 PM



1 2 3 4 5 6 7 8 9 10 11