对于某些特定的网络测试,我创建了一个VLAN设备eth1.900,以及一些别名eth1.900:1和eth1.900.2。
eth1.900 Link encap:Ethernet HWaddr 00:18:E7:17:2F:13 inet addr:1.0.1.120 Bcast:1.0.1.255 Mask:255.255.255.0 eth1.900:1 Link encap:Ethernet HWaddr 00:18:E7:17:2F:13 inet addr:1.0.1.200 Bcast:1.0.1.255 Mask:255.255.255.0 eth1.900:2 Link encap:Ethernet HWaddr 00:18:E7:17:2F:13 inet addr:1.0.1.201 Bcast:1.0.1.255 Mask:255.255.255.0
连接到服务器时,有没有办法指定将使用哪些别名?我可以使用-I< ip> ping地址选项,用于选择要使用的别名,但我无法看到如何在不使用原始套接字的情况下在代码中使用TCP套接字,因为我还希望在没有额外套接字权限的情况下运行,即如果可能的话,不以root身份运行
不幸的是,即使使用root,SO_BINDTODEVICE也不起作用,因为无法识别别名设备名称:
printf("Bind to %s\n", devname);
if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (char*)devname, sizeof(devname)) != 0)
{
perror("SO_BINDTODEVICE");
return 1;
}
输出:
Bind to eth1.900:1 SO_BINDTODEVICE: No such device
答案 0 :(得分:5)
使用getifaddrs()枚举所有接口并找到要绑定到的接口的IP地址。然后在调用connect()之前使用bind()绑定到该IP地址。
答案 1 :(得分:3)
由于无论如何都无法在别名接口上发送数据包,因此在一个数据包上使用SO_BINDTODEVICE是没有意义的。如果路由不能用于此目的(例如,如果它是原始以太网帧),则SO_BINDTODEVICE控制从哪个设备发送数据包。
答案 2 :(得分:1)
您没有显示devname
的定义,但如果它是字符串指针,例如:
char *devname = "eth1.900:1";
然后可能它失败了,因为您使用sizeof devname
指定参数大小,在这种情况下与sizeof (char *)
相同,即在32位系统上通常为4。
如果setsockopt()
期望看到参数的实际大小,即字符串的长度,这可以解释问题,因为它可能只是检查前四个字符而失败,因为结果是无效的接口名。