5

My PC has several network cards and I'm trying to receive UDP data from several broadcast devices. Each device is isolated on a dedicated network and I'm trying to read UDP data from multiple devices at the same time. I'm using Boost version 1.67. Let's pretend in this post that I want to get data from one only specific device, so I want to bind on a local network interface.

On Windows the following code works, but on my Ubuntu 16.04 64bits machine it does not. Indeed, if I bind on one specific local IP address (192.168.1.1 in this example) I do not get any data. But if I use the ANY "0.0.0.0" address then I get what I want. Except that in that case I don't know where it comes from. It could be received by any network card!

Is it normal behavior ? Or do I need to read the sender_endpoint to know that information on Linux and filter afterwards?

#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>

using boost::asio::ip::udp;

int main(int argc, char* argv[])
{
  try
  {
    boost::asio::io_context io_context;

    // Setup UDP Socket
    udp::socket socket(io_context);
    socket.open(udp::v4());

    // Bind to specific network card and chosen port
    socket.bind(udp::endpoint(boost::asio::ip::address::from_string("192.168.1.1"), 2368));

    // Prepare to receive data
    boost::array<char, 128> recv_buf;
    udp::endpoint sender_endpoint;
    size_t len = socket.receive_from(boost::asio::buffer(recv_buf), sender_endpoint);

    // Write data to std output
    std::cout.write(recv_buf.data(), len);
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}
poukill
  • 540
  • 8
  • 18
  • Next step I'd try is snffing the network traffic using wireshark or some similar tools. – πάντα ῥεῖ Apr 15 '19 at 08:18
  • DId you check, if under Ubuntu that card has the same static ip as under Windows? You could also try a really high port number like 56789, I think I remember, that some Linuxes need su for ports below... i don't remember – nada Apr 15 '19 at 08:26
  • @πάνταῥεῖ already done that. I have a PCAP recording and it only shows broadcast normal traffic. @ nada I think the number you are referring to is 1024. The IP adresses were identical, global setup was identical as well. I can read data on that port 2368 if I bind to the ANY interface so not sure your point makes sense in my case. – poukill Apr 15 '19 at 14:02

1 Answers1

2

A little late but others might come to this as well as I have been attempting this with Boost and trying to figure out how it works. From reviewing this question: Fail to listen to UDP Port with boost::asio I went to this page: https://forums.codeguru.com/showthread.php?504427-boost-asio-receive-on-linux and it turns out on Linux that you need to bind to the "any address" in order to receive broadcast packets. So you would set this up as your receiving endpoint:

udp::endpoint(boost::asio::ip::address_v4::any(), port)

And then yes you would need to filter on the sender information. Seems a bit odd but seems to be the way Linux interfaces handle broadcasts.

Rob Baily
  • 2,770
  • 17
  • 26