为什么netstat显示错误的外地地址

时间:2012-08-07 13:51:54

标签: linux network-programming

我在debian 6机箱上有几个物理网络接口,每个接口都有不同的子网IP地址。其中两个接口连接到交换机集线器,因此它们可以相互通信。我想在2个接口之间建立TCP连接。

这就是我所做的:我首先得到一个SOCK_STREAM套接字。然后我使用setsockopt(...,SO_BINDTODEVICE,...)将套接字绑定到特定接口eth4。然后我设置了一个sockaddr_in结构,并用该接口的端口和地址(eth4)填充它。然后我调用bind()将该本地地址/端口绑定到套接字。然后我做一个listen(),接着是accept()。这会阻止等待传入的连接请求。在这一点上,我可以做一个netstat,它显示我所期望的,即套接字确实处于LISTEN状态,本地地址正确显示eth4地址和端口。

然后在一个单独的程序中,我有一个获取套接字的例程,然后setsockopt(...,SO_BINDTODEVICE,...)将套接字绑定到另一个接口eth5。然后,我使用与eth4接口相同的端口号和eth4接口的地址设置sockaddr_in结构。然后我做一个connect()。一切顺利,连接成功,我的日志记录确实显示2个进程确实与此TCP连接相关联。

但是当我执行netstat时,它显示2个PID /程序正在连接,但是本地地址和外部地址都显示来自eth4的相同地址,即使我特意将连接端绑定到地址eth5。

所以,我的问题是为什么netstat为连接的两端显示相同的地址?

我能想到的唯一解释是,核心识别连接目标地址实际上是本地的,然后忽略我所做的SO_BINDTODEVICE绑定,并使TCP连接内部而不是实际输出eth5连接到eth4。 / p>

如果这是正确的,那么我如何在同一个Linux机箱上的两个独立接口之间实际建立TCP连接,但实际上是在外部而不是内部?

-Andres

1 个答案:

答案 0 :(得分:0)

您可以尝试在bind之前调用connect以使客户端套接字将其与您要使用的传出接口(eth5)的特定IP地址相关联(端口可以设置为0,因为在这种情况下,对于客户来说这是微不足道的)。这种方法似乎是使用SO_BINDTODEVICE选项的替代方法。

我找到了一个帖子,提供了几种设置此选项的方法(http://stackoverflow.com/a/6566111/276274)。第一个是使用设备名称将字符串传递给setsockopt,另一个传递struct ifreq,并通过ioctl填充接口索引。您可以尝试使用接口索引探索第二个。

另一个潜在的问题来源可能是设置此选项似乎需要root权限。

如果您可以在设置选项的位置发布代码段,则可能会有所帮助。