bind socket to network interface

前端 未结 3 729
天涯浪人
天涯浪人 2020-12-02 17:49

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 et

相关标签:
3条回答
  • 2020-12-02 18:04

    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 and 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.

    0 讨论(0)
  • 2020-12-02 18:15

    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.

    0 讨论(0)
  • 2020-12-02 18:28

    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.

    0 讨论(0)
提交回复
热议问题