将套接字绑定到网络接口

时间:2013-01-23 11:05:26

标签: c linux sockets

如何将套接字绑定到特定网络接口?我尝试在服务器端使用setsockopt,但客户端仍然可以通过eth0和lo接口访问服务。

我可以通过使用serv_addr.sin_addr.s_addr设置特定IP地址来实现此目的。

但我怀疑我们只能使用setsockopt绑定到一个接口(不提及IP地址)。

3 个答案:

答案 0 :(得分:22)

您可以通过设置SO_BINDTODEVICE套接字选项来绑定到特定接口。

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

警告您必须是root并具有CAP_NET_RAW功能才能使用此选项。

第二种方法是您可以解析绑定到getifaddrs()接口的IP地址。

请按照后一个链接获取全面的示例。

答案 1 :(得分:3)

你能做到的唯一方法就是你提到 -

  

使用serv_addr.sin_addr.s_addr

设置特定IP地址

如果不知道要绑定的地址,就无法做到。

如果需要,您可以使用ioctl来确定当前的IP地址,尽管这些天可能有更聪明的方法 - 我最近在现代Linux发行版中做得不多。

答案 2 :(得分:0)

也许有人会发现它有用,所以我将分享对我有用的解决方案(Linux,C ++):

uint32_t interfaceIndex = if_nametoindex(interfaceName);

其中“ interfaceName”是我们要绑定到的接口的名称,例如“ eth0”(请参阅​​:https://linux.die.net/man/3/if_nametoindex)。 现在,我们可以通过“ sin6_scope_id”在套接字地址结构中指定此接口(如果使用IPv6):

struct sockaddr_in6 socketAddress;
socketAddress.sin6_scope_id = interfaceIndex;

现在,我们可以像往常一样通过“绑定”将套接字绑定到接口了。