如何将套接字绑定到特定的网络接口?我尝试在服务器端使用setsockopt,但客户端仍然可以通过eth0和lo接口访问服务。我可以通过使用serv_addr.sin_addr.s_addr设置特定的IP地址来实现这一点。但我怀疑我们可以只使用setsockopt绑定到一个接口(不提及IP地址)。
setsockopt
serv_addr.sin_addr.s_addr
vyu0f0g11#
您可以通过设置SO_BINDTODEVICE套接字选项绑定到特定接口。
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功能才能使用此选项。*
CAP_NET_RAW
第二种方法是,您可以使用getifaddrs()解析绑定到接口的IP地址。请点击后一个链接查看完整的示例。
apeeds0o2#
唯一的办法就是你说的-通过使用serv_addr.sin_addr.s_addr设置特定IP地址如果不知道要绑定的地址,就无法执行此操作。如果需要,可以使用ioctl s来确定当前的IP地址,尽管现在可能有更聪明的方法来做这件事--我最近在现代Linux发行版中做的不多。
ioctl
dbf7pr2w3#
也许有人会发现它很有用,所以我分享了适合我的解决方案(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;
型现在我们可以像往常一样通过“bind”将套接字绑定到接口。
3条答案
按热度按时间vyu0f0g11#
您可以通过设置
SO_BINDTODEVICE
套接字选项绑定到特定接口。字符串
警告:* 您必须是root用户或具有
CAP_NET_RAW
功能才能使用此选项。*第二种方法是,您可以使用getifaddrs()解析绑定到接口的IP地址。
请点击后一个链接查看完整的示例。
apeeds0o2#
唯一的办法就是你说的-
通过使用
serv_addr.sin_addr.s_addr
设置特定IP地址如果不知道要绑定的地址,就无法执行此操作。
如果需要,可以使用
ioctl
s来确定当前的IP地址,尽管现在可能有更聪明的方法来做这件事--我最近在现代Linux发行版中做的不多。dbf7pr2w3#
也许有人会发现它很有用,所以我分享了适合我的解决方案(Linux,C++):
字符串
其中“interfaceName”是我们要绑定的接口的名称,例如“eth0”(参见:https://linux.die.net/man/3/if_nametoindex)的值。现在我们可以通过“sin6_scope_id”在套接字地址结构中指定这个接口(如果我们使用IPv6):
型
现在我们可以像往常一样通过“bind”将套接字绑定到接口。