使用 Linux 网络设备别名时为 TCP 套接字指定源 IP 地址 [英] Specify source IP address for TCP socket when using Linux network device aliases

查看:73
本文介绍了使用 Linux 网络设备别名时为 TCP 套接字指定源 IP 地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于某些特定的网络测试,我创建了一个 VLAN 设备 eth1.900 和几个别名 eth1.900:1 和 eth1.900.2.

<前>eth1.900 链接封装:以太网 HWaddr 00:18:E7:17:2F:13inet 地址:1.0.1.120 广播:1.0.1.255 掩码:255.255.255.0eth1.900:1 链接封装:以太网 HWaddr 00:18:E7:17:2F:13inet 地址:1.0.1.200 广播:1.0.1.255 掩码:255.255.255.0eth1.900:2 链接封装:以太网 HWaddr 00:18:E7:17:2F:13inet 地址:1.0.1.201 广播:1.0.1.255 掩码:255.255.255.0

当连接到服务器时,有没有办法指定将使用这些别名中的哪一个?我可以使用 -I <ip> pingaddress 选项来选择要使用的别名,但我看不到如何在不使用原始套接字的情况下使用代码中的 TCP 套接字来执行此操作,因为我也希望在没有额外套接字权限的情况下运行,即,如果可能,不以 root 身份运行.

不幸的是,即使使用 root,SO_BINDTODEVICE 也无法工作,因为无法识别别名设备名称:

printf("绑定到 %s\n", devname);if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (char*)devname, sizeof(devname)) != 0){perror("SO_BINDTODEVICE");返回 1;}

输出:

<前>绑定到 eth1.900:1SO_BINDTODEVICE:没有这样的设备

解决方案

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

For some specific networking tests, I've created a VLAN device, eth1.900, and a couple of aliases, eth1.900:1 and 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

When connecting to a server, is there a way to specify which of these aliases will be used? I can ping using the -I <ip> address option to select which alias to use, but I can't see how to do it with a TCP socket in code without using raw sockets, since I would also like to run without extra socket privileges, i.e. not running as root, if possible.

Unfortunately, even with root, SO_BINDTODEVICE doesn't work because the alias device name is not recognized:

printf("Bind to %s\n", devname);
if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (char*)devname, sizeof(devname)) != 0)
{
    perror("SO_BINDTODEVICE");
    return 1;
}

Output:

    Bind to eth1.900:1
    SO_BINDTODEVICE: No such device

解决方案

Use getifaddrs() to enumerate all the interfaces and find the IP address for the interface you want to bind to. Then use bind() to bind to that IP address, before you call connect().

这篇关于使用 Linux 网络设备别名时为 TCP 套接字指定源 IP 地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆