マルチキャストで送信も受信もできない問題に遭遇しました


マルチキャストで通信する小さな自作プログラムを実行したところ、WireSharkで見ていても、何もパケットが流れない現象に遭遇しました。原因は、NICが複数装着されており、1枚目(デフォルトで使われるNIC)がNAT設定だったためのようです。ひょっとすると、VirtualBoxのNAT設定したNICだけの現象かもしれませんが、念のために記しておきます。

環境

  • Windows 7(ホストOS)
  • VirtualBox 4.3.20
  • CentOS 6.5(ゲストOS。送受信別々のマシンではあるが同一のバージョン)

ネットワーク

現象

ホストOS上でWireSharkを使い、図中の物理Adpt.とHostOnly Adpt.をパケット・キャプチャしてみたのですが、マルチキャストアドレス225.1.1.1にパケットが流れている(送出されている)ように見えません。

思ったようにならないコードの一部を抜粋:
sock = socket(AF_INET, SOCK_DGRAM, 0);

 addr.sin_family = AF_INET;
 addr.sin_port = htons(5555);
 addr.sin_addr.s_addr = inet_addr("225.1.1.1");

 ipaddr = inet_addr("127.0.0.1");
 if (setsockopt(sock,
        IPPROTO_IP,
        IP_MULTICAST_IF,
        (char *)&ipaddr, sizeof(ipaddr)) != 0) {
    perror("setsockopt");
    return 1;
 }

 sendto(sock, "HELLO", 5, 0, (struct sockaddr *)&addr, sizeof(addr));

マルチキャストアドレスがどのNICを使っているか確かめてみると、eth0が使われていました。

マルチキャストで使用するNICを調べる
$ netstat -g

そこで、マルチキャストで使用するNICは、192.168.56.100が割り当てられているNIC、すなわちeth1を使うように変更して解決しました。

うまくいったコードの抜粋
 ipaddr = inet_addr("192.168.56.100"); // eth1に変更
 if (setsockopt(sock,
        IPPROTO_IP,
        IP_MULTICAST_IF,
        (char *)&ipaddr, sizeof(ipaddr)) != 0) {
    perror("setsockopt");
    return 1;
 }