2

I'm developing a C++ program listening to multiple UDP ports and need to retrieve the TTL of received packets. Boost ASIO does not provide access to that.

I added raw sockets to the program with boost raw sockets instead of udp sockets. After some struggle, I'm able to send and receive UDP packets setting myself the IP and UDP headers.

The issue is that the program receives on each socket as many duplicate packets as the number of created sockets. If I open 3 sockets, I receive 3 packets on each, open 4 receive 4... Wireshark shows me that everything is fine on the network.

Here is how I initiate the sockets :

sockstr_.sin_family       = AF_INET;
sockstr_.sin_port         = htons(localendpoint.port());
sockstr_.sin_addr.s_addr  = inet_addr(localendpoint.address().to_string().c_str());
socklen_t socklen         = (socklen_t) sizeof(sockstr_);

if ((raw_socket_ = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) == -1) {
    throw std::runtime_error("Failed to open socket! ");
}
        
int on = 1;
setsockopt(raw_socket_, IPPROTO_IP, IP_HDRINCL , &on, sizeof(on));

if (bind(raw_socket_, (struct sockaddr*) &sockstr_, socklen) == -1) {
    close(raw_socket_);
    throw std::runtime_error("Failed to bind socket! ");
}

// udp_socket_ defined in header file
// boost::asio::ip::raw_udp::socket udp_socket_;
udp_socket_.assign(boost::asio::ip::raw_udp::v4(), raw_socket_);

// Then I simply use boost functions
udp_socket_.async_send_to(boost::asio::buffer(ST), ref_endpoint_ ...
udp_socket_.async_receive_from(boost::asio::buffer(RT), ref_endpoint_ ...

In the log, I saw that all the raw sockets share the same port number 17, but my program sends and receives on the ports I choose and wireshark shows me that. Si I guess that's the source of the problem. Any idea how to change the raw socket port ? or another solution to fix the issue :

[10:06:09.966254][0014][debug]:  Socket : 11
[10:06:09.966301][0015][debug]: UDP Source endpoint:            10.20.100.121:17
[10:06:09.966347][0016][debug]: Client [0] starting test session [0] with endless duration !
[10:06:09.966652][0017][debug]:  Socket : 12
[10:06:09.966696][0018][debug]: UDP Source endpoint:            10.20.100.121:17
[10:06:09.966731][0019][debug]: Client [0] starting test session [1] with endless duration !
[10:06:09.967040][001a][debug]:  Socket : 13
[10:06:09.967078][001b][debug]: UDP Source endpoint:            10.20.100.121:17
[10:06:09.967112][001c][debug]: Client [0] starting test session [2] with endless duration !

Here is the raw_udp code:

namespace boost {
namespace asio {
namespace ip {

class raw_udp
{
public:
  
  typedef basic_endpoint<raw_udp> endpoint;

  static raw_udp v4()
  {
    return raw_udp(IPPROTO_UDP, AF_INET);
  }

  static raw_udp v6()
  {
    return raw_udp(IPPROTO_UDP, AF_INET);
  }

  int type() const
  {
    return SOCK_RAW;
  }

  int protocol() const
  {
    return protocol_;
  }

  int family() const
  {
    return family_;
  }

  typedef basic_raw_socket<raw_udp> socket;

  typedef basic_resolver<raw_udp> resolver;

  friend bool operator==(const raw_udp& p1, const raw_udp& p2)
  {
    return p1.protocol_ == p2.protocol_ && p1.family_ == p2.family_;
  }

  friend bool operator!=(const raw_udp& p1, const raw_udp& p2)
  {
    return p1.protocol_ != p2.protocol_ || p1.family_ != p2.family_;
  }

private:
  explicit raw_udp(int protocol_id, int protocol_family)
    : protocol_(protocol_id),
      family_(protocol_family)
  {
  }

  int protocol_;
  int family_;
};

} // namespace ip
} // namespace asio
} // namespace boost
selladvis
  • 21
  • 2
  • What is `boost::asio::ip::raw_udp`? No such thing [exists](https://www.google.com/search?q=asio+%2B%22raw_udp%22). If you make your sample self-contained, we can look at it. Here's a start: http://coliru.stacked-crooked.com/ – sehe Apr 06 '21 at 14:10
  • It's a boost asio basic datagram socket protocol. It's should provide access to UDP and IP headers. I edited the post to include the code. – selladvis Apr 07 '21 at 17:39
  • Is `htons(localendpoint.port())` the same for each socket? If so, that's why they all have the same local port. – David Schwartz Apr 07 '21 at 17:44
  • No they share the same ip address but different ports I set myself manually. I see the trafic coming and going through these ports using these ports. The only issue is that the packets are duplicated. However the raw socket port is the same and always 17 ! – selladvis Apr 09 '21 at 13:27

0 Answers0