42 #include <arpa/inet.h> 
   44 #include <sys/socket.h> 
   45 #include <sys/ioctl.h> 
   47 #include <linux/if_packet.h> 
   48 #include <netinet/ether.h> 
   60   static const in_addr_t bcast = htonl(INADDR_BROADCAST);
 
   70                                 std::string iface_name)
 
   72   return SocketLinux(AF_INET, SOCK_DGRAM, IPPROTO_UDP, dst_ip, port,
 
   73                      std::move(iface_name));
 
   79   std::vector<SocketLinux> sockets;
 
   86   for(ifaddrs *addr = addrs;
 
   88       addr = addr->ifa_next)
 
   90     auto baddr = addr->ifa_ifu.ifu_broadaddr;
 
   91     if (addr->ifa_flags & IFF_UP &&
 
   92         addr->ifa_name != 
nullptr &&
 
   93         addr->ifa_addr != 
nullptr &&
 
   94         addr->ifa_addr->sa_family == AF_INET &&
 
   97       std::string name(addr->ifa_name);
 
   98       if (name.length() != 0 && name != 
"lo")
 
  100         const in_addr_t s_addr =
 
  101             reinterpret_cast<struct sockaddr_in *
>(addr->ifa_addr)->
 
  104         uint16_t local_port = 0;
 
  111           addr.sin_family = AF_INET;
 
  113           addr.sin_addr.s_addr = s_addr;
 
  114           sockets.back().bind(addr);
 
  119           struct sockaddr_in local_address;
 
  120           socklen_t address_length = 
sizeof(local_address);
 
  121           getsockname(sockets.back().sock_,
 
  122                       reinterpret_cast<sockaddr *
>(&local_address),
 
  124           local_port = local_address.sin_port;
 
  132           addr.sin_family = AF_INET;
 
  133           addr.sin_port = local_port;
 
  134           addr.sin_addr.s_addr = htonl(INADDR_ANY);
 
  135           sockets.back().bind(addr);
 
  140           sockets.emplace_back(
 
  142                   reinterpret_cast<struct sockaddr_in *
>(baddr)->
 
  143                   sin_addr.s_addr, port, name));
 
  145           addr.sin_family = AF_INET;
 
  146           addr.sin_port = local_port;
 
  147           addr.sin_addr.s_addr = htonl(INADDR_ANY);
 
  148           sockets.back().bind(addr);
 
  162 SocketLinux::SocketLinux(
int domain, 
int type, 
int protocol,
 
  163                          in_addr_t dst_ip, uint16_t port,
 
  164                          std::string iface_name) :
 
  165   Socket(std::move(iface_name)),
 
  169   sock_ = ::socket(domain, type, protocol);
 
  185   if (::setsockopt(
sock_,
 
  188                   reinterpret_cast<const char *
>(&yes),
 
  198   dst_addr_(std::move(other.dst_addr_))
 
  200   std::swap(
sock_, other.sock_);
 
  205   std::swap(
sock_, other.sock_);
 
  225              reinterpret_cast<const sockaddr *
>(&addr),
 
  226              sizeof(sockaddr)) == -1)
 
  235               static_cast<const void *
>(sendbuf.data()),
 
  238               reinterpret_cast<const sockaddr *
>(&
dst_addr_),
 
  239               static_cast<socklen_t
>(
sizeof(sockaddr_in))) == -1)
 
  241      if (errno == ENETUNREACH)
 
  244              "Error while sending data - network unreachable", errno);
 
  254   if (::setsockopt(
sock_,
 
  257                   reinterpret_cast<const char *
>(&yes),
 
  266   int flags = fcntl(
sock_, F_GETFL, 0);
 
  267   if (flags < 0 || fcntl(
sock_, F_SETFL, flags | O_RDWR | O_NONBLOCK) == -1)
 
  269     throw SocketException(
"Error while setting socket non-blocking", errno);
 
  275   if (::setsockopt(
sock_,
 
  279                    static_cast<socklen_t
>(device.size())) == -1)
 
  286     throw SocketException(
"Error while binding to device \"" + device + 
"\"",