繁体   English   中英

使用Linux网络设备别名时,指定TCP套接字的源IP地址

[英]Specify source IP address for TCP socket when using Linux network device aliases

对于某些特定的网络测试,我创建了一个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>地址选项来选择使用哪个别名,但我不知道如何在不使用原始套接字的情况下使用代码中的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

使用getifaddrs()枚举所有接口并找到要绑定到的接口的IP地址。 然后在调用connect()之前使用bind()绑定到该IP地址。

由于无论如何都无法在别名接口上发送数据包,因此在一个上使用SO_BINDTODEVICE是没有意义的。 如果路由不能用于此目的(例如,如果它是原始以太网帧),则SO_BINDTODEVICE控制从哪个设备发送数据包。

您没有显示devname的定义,但如果它是一个字符串指针,例如:

char *devname = "eth1.900:1";

然后它可能失败,因为你使用sizeof devname指定参数大小,在这种情况下,它与sizeof (char *) ,即在32位系统上通常为4。

如果setsockopt()希望看到参数的实际大小,即字符串的长度,这可以解释问题,因为它可能只是检查前四个字符而失败,因为结果是无效的接口名称。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM