簡體   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