2009-07-23 10 views
2

特定のネットワークテストでは、eth1.900というVLANデバイスと、eth1.900:1とeth1.900.2の別名を作成しました。Linuxネットワークデバイスエイリアスを使用する場合のTCPソケットの送信元IPアドレスの指定

 
    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>アドレスオプションを使用して、使用するエイリアスを選択してpingできますが、余分なソケットなしで実行したいので、rawソケットを使用せずにコード内のTCPソケットを使用する方法はわかりません可能であれば、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 
+1

'ifconfig'ではなく' ip'コマンドを使うと、*::1、 ':2'などのエイリアスなしで、単一のインタフェースに複数のアドレスを持つことができることに注意してください。それは 'ifconfig'発明のものです... – ephemient

答えて

5

使用getifaddrs()とバインドするインターフェイスのIPアドレスを見つけます。次にconnect()を呼び出す前にbind()を使ってそのIPアドレスにバインドします。

+0

おかげでカフェ。面白いことに、私が試した最初のことでしたが、私はそれがうまくいかないことを誓っているので、途中でargsを混乱させているに違いありません。私を軌道に戻してくれてありがとう! – Wade

+0

注:sin_portを '0'に設定すると、クライアントソケットがシステムによって選択されたエフェメラルポートにバインドされます。 – Wade

3

とにかくエイリアスインターフェイスでパケットを送信することはできないため、SO_BINDTODEVICEを使用することは意味がありません。 SO_BINDTODEVICEは、この目的のためにルーティングが使用できない場合(たとえば、生のイーサネットフレームの場合など)、パケットを送信するデバイスを制御します。

1

あなたはdevnameの定義を示していないが、それは文字列ポインタ、例えばだ場合:

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

あなたは、この場合になりsizeof devnameを使用して、引数のサイズを、指定したので、その後、おそらくそれが失敗していますsizeof (char *)と同じです。つまり、32ビットシステムでは通常4です。

setsockopt()が引数の実際のサイズ、つまり文字列の長さを表示すると予想される場合、最初の4文字を検査して結果が無効なインターフェイス名であるため失敗する可能性があるため、

+0

提案していただきありがとうございますが、私はおそらく例を使用していました。 char devname [] = "eth1.900:1"; – Wade

関連する問題