31

How can I bind a socket to a particular network interface? I tried using setsockopt on server side, but the clients can still access the service through both eth0 and lo interfaces.

I can achieve this by setting the particular IP address using serv_addr.sin_addr.s_addr.

But I suspect that we can bind to an interface using only setsockopt (without mentioning the IP address).

3 Answers 3

46

You can bind to a specific interface by setting SO_BINDTODEVICE socket option.

struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0"); if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) { ... error handling ... } 

Warning: You have to be root or have the CAP_NET_RAW capability in order to use this option.

The second method is that you can resolv IP address tied to an interface with getifaddrs().

Follow the latter link for a comprehensive example.

Sign up to request clarification or add additional context in comments.

3 Comments

I have a new question, so does it matter eth0 and eth1 have same IP address using your method?
I'm pretty sure that it should say "You have to be root OR have the CAP_NET_RAW capability", you don't need both.
Hi linux.die.net/man/3/setsockopt does not list SO_BINDTODEVICE is it no longer supported?
3

The only way you can do it is as you mention -

by setting the particular IP address using serv_addr.sin_addr.s_addr

You can't do it without knowing the address to bind to.

You can use ioctls to determine the current IP address if you need, though there may be a cleverer way to do this these days - I've not done much in modern Linux distros lately.

1 Comment

Thnks joe. can i know the usage of setsockopt with SO_BINDTODEVICE?
2

Maybe someone will find it useful, so I am sharing the solution that worked for me (Linux, C++):

uint32_t interfaceIndex = if_nametoindex(interfaceName); 

Where "interfaceName" is the name of the interface we want to bind to, e.g. "eth0" (see: https://linux.die.net/man/3/if_nametoindex). Now we can specify this interface in the socket address structure via "sin6_scope_id" (in case we use IPv6):

struct sockaddr_in6 socketAddress; socketAddress.sin6_scope_id = interfaceIndex; 

Now we can bind the socket to the interface via "bind" as usual.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.