Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Receiving UDP broadcast packets on Linux

We have existing software that periodically broadcasts UDP packets to a specific port (7125) on the local subnet (x.x.x.255). We have monitoring software running on HP-UX (11.11) that is able to receive these packets no problem. However, after porting the monitoring software to Linux (RHEL 6.1) we have found that it does not receive the broadcast packets. tcpdump shows the packets arriving at the Linux host, but the kernel does not send them through to our software.

I've been using a couple of python 2.x scripts that mimic the socket API calls the monitoring software uses to test different scenarios. The Linux kernel passes the packets to the receiver software if the sender uses unicast (10.1.0.5), but not broadcast (10.1.0.255). I've been searching the web for several days and have not found anyone with the same problem. Any ideas?

receiver.py

from __future__ import print_function
import socket

localHost = ''
localPort = 7125
remoteHost = '10.1.0.5'
remotePort = 19100

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.bind((localHost, localPort))
s.connect((remoteHost, remotePort))
print('Listening on {0}:{1} for traffic from {2}:{3}'.format(localHost, localPort, remoteHost, remotePort))
data = s.recv(1024)
print('Received: {0}'.format(data))
s.close()

sender.py

from __future__ import print_function
import socket
import time

localHost = ''
localPort = 19100
remoteHost = '10.1.0.255'
remotePort = 7125

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.bind((localHost, localPort))
s.connect((remoteHost, remotePort))
data = 'sending this from {0}:{1} to {2}:{3}'.format(localHost, localPort, remoteHost, remotePort)
print(data)
print('2')
time.sleep(1)
print('1')
time.sleep(1)
s.send(data)
print('sent at {0}'.format(time.ctime()))
s.close()
like image 207
goose Avatar asked Dec 02 '12 05:12

goose


People also ask

Does Linux use UDP?

By default, Linux UDP does path MTU (Maximum Transmission Unit) discovery. This means the kernel will keep track of the MTU to a specific target IP address and return EMSGSIZE when a UDP packet write exceeds it. When this happens, the application should decrease the packet size.

How do I enable UDP broadcast?

To configure and enable UDP broadcast forwarding on the switch: Enable routing. Globally enable UDP broadcast forwarding. On a per-VLAN basis, configure a forwarding address and UDP port type for each type of incoming UDP broadcast you want routed to other VLANs.

How do I get UDP packets in Linux?

Use nc command for sending and receiving UDP packets through network. Send some human readable sentences through nc command. Capture the UDP packet sent by nc command. Check network packet in Wireshark.

Can Broadcasting take place using UDP?

UDP broadcast. All of our examples so far have utilized a transmission mode called unicast, defined as the sending of messages to a single network destination identified by a unique address. This mode is supported by both connected and connectionless protocols.


1 Answers

Well, I suggested this answer in a comment, and it proved correct in practice. I would like to investigate surrounding nuances further with my own code, but this is the canonical case-closer.

In addition to setting the SO_BROADCAST socket option on both sides (as you are already correctly doing), you must also bind your receiver to the broadcast address (e.g., INADDR_BROADCAST, which is 255.255.255.255 and essentially serves the same role as INADDR_ANY for unicast).

Apparently, in the HP-UX configuration of the original poster, a UDP socket bound to a unicast address (or INADDR_ANY, specifically) but with the SO_BROADCAST socket option set will still receive all UDP datagrams addressed to the local broadcast address as well as unicast traffic directed at the host.

Under Linux, this is not the case. Binding a UDP socket, even when SO_BROADCAST-enabled, to INADDR_ANY is insufficient to receive both unicast and broadcast datagrams on the bound port. One can use a separate INADDR_BROADCAST-bound SO_BROADCAST socket for the broadcast traffic.

like image 106
Matthew Hall Avatar answered Sep 20 '22 09:09

Matthew Hall