2012-08-07 86 views
0

我在debian 6盒上有幾個物理網絡接口,每個接口都有不同的子網IP地址。其中兩個接口連接到交換機集線器,以便它們可以相互通信。我想在兩個接口之間建立一個TCP連接。爲什麼netstat顯示錯誤的國外地址

這就是我所做的:我首先得到一個SOCK_STREAM套接字。然後,我使用setsockopt(...,SO_BINDTODEVICE,...)將套接字綁定到特定的接口eth4。然後我設置一個sockaddr_in結構,並使用該接口的端口和地址(eth4)填充它。然後我調用bind()將該本地地址/端口綁定到套接字。然後我做一個listen(),然後是一個accept()。這阻止了等待傳入的連接請求。在這一點上,我可以做一個netstat,它顯示了我所期望的,也就是說,套接字確實處於LISTEN狀態,本地地址正確顯示eth4地址和端口。

然後在一個單獨的程序中,我有一個例程獲取套接字,然後setsockopt(...,SO_BINDTODEVICE,...)將套接字綁定到不同的接口eth5。然後使用我用於eth4接口的相同端口號和eth4接口的地址設置sockaddr_in結構。然後我做一個連接()。一切順利,連接成功,我的日誌確實表明這2個進程確實與這個TCP連接相連接。

但是當我執行netstat時,它顯示2個PID /程序被連接,但本地地址和外部地址都顯示來自eth4的相同地址,即使我特別將連接端綁定到地址的eth5。

所以,我的問題是爲什麼netstat顯示連接兩端的地址相同?

我能想出的唯一解釋是kernal認識到連接目標地址實際上是本地的,然後忽略了我做的SO_BINDTODEVICE綁定,並使TCP連接內部而不是實際發出eth5連接到eth4。

如果這是正確的,那我該如何在兩個不同的接口之間建立一個TCP連接,在同一個Linux機器上,但實際上是外部而不是內部?

-Andres

回答

0

您可以嘗試connect之前調用bind的客戶端套接字將它與您要使用的輸出接口(eth5)的特定IP地址相關聯(端口可以設置爲0,因爲這對客戶而言是微不足道的)。這種方法似乎是使用SO_BINDTODEVICE選項的替代方法。

我發現一個帖子提供了幾種設置此選項的方法(http://stackoverflow.com/a/6566111/276274)。第一個是將字符串傳遞到設備名稱setsockopt,另一個傳遞struct ifreq,通過ioctl填充接口索引。您可以嘗試使用接口索引來探索第二個。

另一個潛在的問題可能是設置此選項似乎需要root權限。

如果您可以在設置選項的位置發佈代碼段,這可能會有所幫助。

+0

感謝您的回覆 – 2012-08-27 23:30:50