1

I have a hardware device connected on one of the available network interfaces (in general don't know which one) that answers to UDP broadcast messages with UDP broadcast messages. I need to be able to send a message and receive the broadcast answer.

From other topics on stackoverflow, I've been able to get part of it to work, but not both send and receive simultaneously. Currently I do the following:

  • For each interface listed by getifaddrs(&ifaces) with iface->ifa_addr->sa_family == AF_INET
  • Create a socket with socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
  • Set the socket to broadcast with setsockopt(sock, SOL_SOCKET, SO_BROADCAST, ...)
  • bind() to the address in ifaces->ifa_addr of getifaddrs() with 0 as port (first free port)
  • Send, with sendto(), a packet to INADDR_BROADCAST from each of the opened sockets
  • In n parallel threads (one for each socket) I wait for answers with recvfrom()

So, I fired up wireshark and the message gets sent correctly to all interfaces, the hardware answers in broadcast (255.255.255.255) correctly on the same port from which the packet was sent, but recvfrom() never returns data, it just waits. With the same code, if I bind to INADDR_ANY instead of ifaces->ifa_addr and run sendto() on the actual IP of the hardware instead of INADDR_BROADCAST, the broadcast answer gets caught without problems.

What exactly is going on? Why isn't the answer caught in the first case? How can send and receive in broadcast on multiple interfaces?

By the way, root access is not an option, so I can't do setsockopt(..., SOL_SOCKET, SO_BINDTODEVICE, "ifacename"). And the OS is Linux.

srskko
  • 11
  • 1
  • 3
  • The concept doesn't seem wrong, so a minimal program with the same behavior might be more useful. As to sending and receiving, you'll need to use something like `select()` to poll the socket(s) to see which have data pending to read. Otherwise, there's not much special about the process. – John C Apr 01 '14 at 22:36
  • I found this thread http://developerweb.net/viewtopic.php?id=5722 which actually has a take on this problem (with a code example). Apparently, on Linux, if you bind to an address which is not `INADDR_ANY` you're not going to be able to receive broadcast UDP messages. I'll be damned if I know why. I can replicate the problem by running ./bcast 127.0.0.1 and ./bcast - on another shell. Interestingly on OS X it does work, though. – srskko Apr 01 '14 at 23:29
  • So, another hack/solution that comes to mind is to bind all the sockets to the same port by using `setsockopt(..., SO_REUSEPORT, ...)`, and then bind an extra one to `INADDR_ANY`, again with the same port. Hopefully all the broadcast answers would be multiplexed to the last socket? – srskko Apr 01 '14 at 23:33
  • You can checkout my answer http://stackoverflow.com/questions/32623057/udp-broadcast-using-gcdasyncudpsocket-through-all-available-network-interfaces May this helps you out. – Prashant Sep 23 '15 at 03:08

0 Answers0