2

I run Ubuntu 12.04 and I am currently writing C++ code to create a UDP socket, which sends packets to various destinations with sendto. Now it happens that my laptop has both a wlan0 and a eth0 interface. If I bind it to either one of these, using the IP address, and the SO_BINDTODEVICE option, depending on the destination address, sendto will still decide to use the other interface if it suits him.

Specifically, if I bind a UDP socket to the eth0 interface, with its ip address and some port, and I send a packet to another laptop (locally, with only wifi access), it will decide to use my wlan0 interface.

I understand that this behaviour has pros, but I would like to be able to turn it off, i.e. I want to be able to say to the socket that it should only use the one interface I assigned it.

Suggestions?

EDIT:

struct sockaddr_storage sa = address;
fd = socket(address.get_family(), SOCK_DGRAM, 0);
char *devname = "wlan0";
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, devname, strlen(devname));
bind(fd, (sockaddr*)&sa, len);
Vincent Ketelaars
  • 1,069
  • 1
  • 14
  • 35
  • 1
    "If I bind it to either one of these, using the IP address, and the SO_BINDTODEVICE option" I always thought that SO_BINDTODEVICE gets an interface name (at least thats how I use it for multicast, and it works fine) – PlasmaHH Oct 21 '13 at 13:15
  • You're using `bind()` with the address of the interface, and that doesn't work? (I assume they have distinct addresses) – Hasturkun Oct 21 '13 at 13:19
  • @Hasturkun: they have distinct addresses – Vincent Ketelaars Oct 21 '13 at 13:31

1 Answers1

1

Binding a socket to an interface with SO_BINDTODEVICE or bind defines a filter for received packets. When a packet has not been received using the specified interface it is not passed to the socket's receive queue. See: http://linux.die.net/man/7/socket

But binding a socket to an interface does not affect the normal IP routing process. When you send a packet it's the responsibility of the network IP stack to find the best route and to send the IP packet over a hardware adapter. This can be an Ethernet adpter but it's not controller with and bind operation.

When you want to send a packet at a specific interface you need raw sockets. You construct the complete packet content including IP and hardware layer (probably Ethernet) and send it using the raw socket.

harper
  • 13,345
  • 8
  • 56
  • 105
  • What if I change my routing table dynamically? – Vincent Ketelaars Oct 22 '13 at 13:04
  • You can change the routing table. This would control how the packets are transmitted. If your router has an IP address for the WLAN port and a different for the cable port you can control the routing. But be careful since this affect the routing for packets from all processes. – harper Oct 22 '13 at 13:08
  • Using advanced routing, you can give UDP packets a MARK, direct them to a table of you choosing and there you can set the default gateway of choice. This does not affect non-marked packets. Interestingly I think that SO_BINDTODEVICE does force the specified interface on you. It is just that the main routing table has a default gateway (which I presume usually sets it to the eth0 gateway). So binding to wlan0 will not do you any good, if you don't supply a proper route. You can notice this by the incoming ICMP messages, HOST UNREACHABLE. – Vincent Ketelaars Oct 29 '13 at 08:15