23

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

我可以通过设置特定的 IP 地址来实现这一点 serv_addr.sin_addr.s_addr

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

4

3 回答 3

33

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 地址。

请按照后一个链接获取综合示例。

于 2013-01-23T11:31:07.603 回答
2

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

通过使用设置特定的 IP 地址serv_addr.sin_addr.s_addr

如果不知道要绑定的地址,您将无法执行此操作。

如果需要,您可以使用ioctls 来确定当前的 IP 地址,尽管这些天可能有更聪明的方法来执行此操作 - 我最近在现代 Linux 发行版中没有做太多事情。

于 2013-01-23T11:11:13.887 回答
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;

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

于 2019-06-04T16:44:48.847 回答