ネットワークインタフェース

マルチキャストの使用

IP マルチキャストは、タイプが SOCK_DGRAM または SOCK_RAW であるソケット AF_INET6 または AF_INET およびインタフェースドライバがマルチキャストをサポートするサブネットワーク上でだけサポートされます。

IPv4 マルチキャストデータグラムの送信

マルチキャストデータグラムを送信するには、sendto(3SOCKET) 呼び出しで宛先アドレスとして 224.0.0.0 〜 239.255.255.255 の範囲の IP マルチキャストアドレスを指定します。

デフォルトでは、IP マルチキャストデータグラムは存続期間 (TTL) 1 で送信されます。この場合、単一のサブネットワーク外にデータグラムが転送されることはありません。ソケットオプション IP_MULTICAST_TTL を指定すると、後続のマルチキャストデータグラムの TTL を 0 〜 255 の範囲の任意の値に設定してマルチキャストの配信範囲を制御できます。

    u_char ttl;
    setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,sizeof(ttl))

TTL 0 のマルチキャストデータグラムはいかなるサブネット上でも伝送されませんが、送信ホストが宛先グループに属しており、かつ送信側ソケットでマルチキャストループバックが無効になっていない場合は、ローカルに配信できます (下記を参照)。最初の配信先となるサブネットに 1 つ以上のマルチキャストルーターが接続されている場合は、1 を超える TTL を持つマルチキャストデータグラムを複数のサブネットに配信できます。意味のある配信範囲制御を提供するため、マルチキャストルーターは TTL に「しきい値」の概念をサポートします。この概念は、一定の TTL 未満のデータグラムが特定のサブネットを越えることを防止します。マルチキャストデータグラムの初期 TTL と、それらに対してしきい値が強制する規則を次に示します。

同じホストに制限される 

同じサブネットに制限される 

32 

同じサイトに制限される 

64 

同じ地域に制限される 

128 

同じ大陸に制限される 

255 

配信範囲内で制限されない 

「サイト」と「地域」は厳密には定義されません。サイトは、ローカルな事柄として、小さな管理単位にさらに分割できます。

アプリケーションは、上記の TTL 以外に初期 TTL を選択できます。たとえば、アプリケーションは、TTL シーケンス 0、1、2、4、8、16、32 を使用し、TTL 0 から開始して応答が得られるまでより大きな TTL のマルチキャスト照会を送ることによってネットワークリソースの「拡張リング検索」が行えます。

マルチキャストルーターは、224.0.0.0 〜 224.0.0.255 の範囲の宛先アドレスを持つマルチキャストデータグラムの転送を、TTL の値にかかわらず拒否します。この範囲のアドレスは、経路指定プロトコルとその他の低レベルトポロジの発見または保守プロトコル (ゲートウェイ発見、グループメンバーシップ報告など) の使用に予約されています。

ホストにマルチキャスト機能を持つ複数のインタフェースがある場合でも、各マルチキャスト伝送は単一のネットワークインタフェースから送信されます (ホストがマルチキャストルーターでもあり、TTL が 1 を超える場合には、発信インタフェース以外のインタフェースにマルチキャストを転送できる)。一定のソケットからの後続の伝送については、ソケットオプションを使用してデフォルトを無効にできます。

    struct in_addr addr;
    setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr))
addr は、使用する発信インタフェースのローカル IP アドレスです。デフォルトインタフェースに戻すには、アドレス INADDR_ANY を指定します。インタフェースのローカル IP アドレスは、SIOCGIFCONF ioctl を使用して取得します。インタフェースがマルチキャストをサポートするかどうかを確認するには、SIOCGIFFLAGS ioctl を使用してインタフェースフラグを取り出し、IFF_MULTICAST フラグが設定されているかどうかをテストしてください。このオプションは、インターネットトポロジと明確な関係があるマルチキャストルーターなどのシステムサービスを主な対象としています。

(発信インタフェース上で) 送信ホスト自体が属しているグループにマルチキャストデータグラムが送信されると、ローカル配信の IP 層によってデータグラムのコピーがデフォルトでループバックされます。後続のデータグラムがループバックされるかどうかにかかわらず、別のソケットオプションが送信側に明示的な制御を与えます。

    u_char loop;
    setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop))  
このコードの loop の値は、ループバックを無効にする場合は 0、ループバックを有効にする場合は 1 です。単一のホストにインスタンスを 1 つしか持たないアプリケーション (ルーターやメールデーモンなど) では、このオプションを使用するとアプリケーション自体の伝送を受信するオーバーヘッドが排除されるため、パフォーマンスが向上します。このオプションは、単一のホストに複数のインスタンスを持つアプリケーション (会議システムプログラムなど) や送信側が宛先グループに属さないアプリケーション (時間照会プログラムなど) には通常使用しないでください。

送信ホストが別のインタフェースの宛先グループに属している場合、1 を超える TTL で送信されたマルチキャストデータグラムは、他方のインタフェース上の送信ホストに配信できます。このような配信には、ループバック制御オプションは何の効果もありません。

IPv4 マルチキャストデータグラムの受信

ホストは、IP マルチキャストデータグラムを受信する前に、1 つ以上の IP マルチキャストグループのメンバーになる必要があります。プロセスは、次のソケットオプションを使用して、マルチキャストグループに加わるようにホストに求めることができます。

    struct ip_mreq mreq;
    setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) 
mreq は次の構造体です。
    struct ip_mreq {
        struct in_addr imr_multiaddr;   /* 加わるマルチキャストグループ */
        struct in_addr imr_interface;   /* 加わるインタフェース */
    }  
各メンバーシップは単一のインタフェースに関連付けられ、複数のインタフェース上の同じグループに加わることができます。imr_interfacein6addr_any になるように 指定してデフォルトのマルチキャストインタフェースを選択するか、あるいはホストのローカルアドレスの 1 つを指定して特定の (マルチキャスト機能を持った) インタフェースを選択してください。

メンバーシップを取り消すには、次のコードを使用します。

    struct ip_mreq mreq;
    setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq))  
mreq には、メンバーシップの追加に使用したのと同じ値が入ります。ソケットが閉じられるか、あるいはソケットを保持しているプロセスが停止される時には、ソケットに関連付けられたメンバーシップも取り消されます。特定のグループ内で複数のソケットがメンバーシップを要求でき、ホストは最後の要求が取り消されるまでそのグループのメンバーにとどまります。

ソケットのどれかがデータグラムの宛先グループ内でメンバーシップを要求した場合、カーネル IP 層が受信マルチキャストパケットを受け入れます。特定のソケットに対するマルチキャストデータグラムの配信は、単一キャストデータグラムの場合と同様に、宛先ポートと、ソケットに関連付けられたメンバーシップ (raw ソケットの場合はプロトコルタイプ) に基づいています。特定のポートに送信されたマルチキャストデータグラムを受信するには、ローカルアドレスを未指定のまま (INADDR_ANY などを指定) ローカルポートにバインドします。

次の指定が bind(3SOCKET) の前にあると、複数のプロセスを同じ SOCK_DGRAM UDP ポートにバインドできます。

    int one = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))  
この場合、共有ポートに向けられた各受信マルチキャストまたは受信ブロードキャスト UDP データグラムは、そのポートにバインドされているすべてのソケットに配信されます。下位互換性の理由から、これは単一キャストの受信データグラムには適用されません。データグラムの宛先ポートにバインドされているソケットの数にかかわらず、単一キャストデータグラムが複数のソケットに配信されることはありません。SOCK_RAW ソケットは、SO_REUSEADDR オプションがなくても単一の IP プロトコルタイプを共有できます。

マルチキャストに関連する新しいソケットオプションの説明は、<netinet/in.h> を参照してください。IP アドレスはすべて、ネットワークバイトオーダーで渡されます。

IPv6 マルチキャストデータグラムの送信

マルチキャストデータグラムを送信するには、sendto(3SOCKET) 呼び出しで宛先アドレスとして ff00::0/8 の範囲の IP マルチキャストアドレスを指定します。

デフォルトでは、IP マルチキャストデータグラムはホップ制限 1 で送信されます。この場合、単一のサブネットワーク外にデータグラムが転送されることはありません。ソケットオプション IPV6_MULTICAST_HOPS を指定すると、後続のマルチキャストデータグラムのホップ制限を 0 から 255 の範囲の任意の値に設定してマルチキャストの配信範囲を制御できます。

    uint_l;
    setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops,sizeof(hops))

ホップ制限 0 のマルチキャストデータグラムはどのサブネットにも伝送されませんが、送信ホストが宛先グループに属しており、送信側ソケットでマルチキャストループバックが無効になっていない場合は、ローカルに配信できます (次を参照)。最初の配信先となるサブネットに 1 つ以上のマルチキャストルーターが接続されている場合は、1 を超えるホップ制限を持つデータグラムを複数のサブネットに配信できます。IPv4 マルチキャストアドレスと異なり、IPv6 マルチキャストアドレスには、アドレスの最初の部分にコード化された明示的な配信範囲情報が含まれます。定義されている配信範囲を次に示します (X は未指定)。

ffX1::0/16

ノード - ローカルな配信範囲 - 同じノードに制限される

ffX2::0/16

リンク - ローカルな配信範囲

ffX5::0/16

サイト - ローカルな配信範囲

ffX8::0/16

組織 - ローカルな配信範囲

ffXe::0/16

全世界的な配信範囲

アプリケーションは、マルチキャストアドレスの配信範囲とは個別に、異なるホップ制限値を使用できます。たとえば、アプリケーションは、ホップ制限シーケンス 0、1、2、4、8、16、32 を使用し、ホップ制限 0 から開始して応答が受信されるまでより大きなホップ制限のマルチキャスト照会を送信することにより、ネットワークリソースの「拡張リング検索」を実行する場合があります。

ホストにマルチキャスト機能を持つ複数のインタフェースがある場合でも、各マルチキャスト伝送は単一のネットワークインタフェースから送信されます (ホストがマルチキャストルーターでもあり、ホップ制限 が 1 を超える場合には、発信インタフェース以外のインタフェースにマルチキャストを転送できる)。一定のソケットからの後続の伝送については、ソケットオプションを使用してデフォルトを無効にできます。

    uint_t ifindex;

    ifindex = if_nametoindex )"hme3");
    setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex))
ifindex は、希望する発信インタフェースのインタフェースインデックスです。デフォルトインタフェースに戻すには、値 0 を指定します。

(発信インタフェース上で) 送信ホスト自体が属しているグループにマルチキャストデータグラムが送信されると、ローカル配信の IP 層によってデータグラムのコピーがデフォルトでループバックされます。後続のデータグラムがループバックされるかどうかにかかわらず、別のソケットオプションが送信側に明示的な制御を与えます。

    uint_t loop;
    setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop))  
loop の値は、ループバックを無効にする場合は 0、ループバックを有効にする場合は 1 です。単一のホストにインスタンスを 1 つしか持たないアプリケーション (ルーターやメールデーモンなど) では、このオプションを使用するとアプリケーション自体の伝送を受信するオーバーヘッドが排除されるため、パフォーマンスが向上します。このオプションは、単一のホストに複数のインスタンスを持つアプリケーション (会議システムプログラムなど) や送信側が宛先グループに属さないアプリケーション (時間照会プログラムなど) に通常は使用しないでください。

送信ホストが別のインタフェースの宛先グループに属している場合、1 以上のホップ制限で送信されたマルチキャストデータグラムは、他方のインタフェース上の送信ホストに配信できます。このような配信には、ループバック制御オプションは何の効果もありません。

IPv6 マルチキャストデータグラムの受信

ホストは、IP マルチキャストデータグラムを受信する前に、1 つ以上の IP マルチキャストグループのメンバーになる必要があります。プロセスは、次のソケットオプションを使用して、マルチキャストグループに加わるようにホストに求めることができます。

    struct ipv6_mreq mreq;
    setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) 
mreq は次の構造体です。
    struct ipv6_mreq {
        struct in6_addr ipv6mr_multiaddr;   /* IPv6 マルチキャストアドレス */
        unsigned int    ipv6mr_interface;   /* インタフェースインデックス */
    }  
各メンバーシップは単一のインタフェースに関連付けられ、複数のインタフェース上の同じグループに加わることができます。ipv6_interface0 になるように指定してデフォルトのマルチキャストインタフェースを選択するか、あるいはホストのインタフェースの 1 つのインタフェースインデックスを指定してその (マルチキャスト機能を持った) インタフェースを選択してください。

グループから抜けるには、次のコードを使用します。

    struct ipv6_mreq mreq;
    setsockopt(sock, IPPROTO_IPV6, IP_LEAVE_GROUP, &mreq, sizeof(mreq))  
mreq には、メンバーシップの追加に使用した同じ値が入ります。ソケットが閉じられるか、あるいはソケットを保持しているプロセスが停止する時には、ソケットに関連付けられたメンバーシップも取り消されます。特定のグループ内で複数のソケットがメンバーシップを要求でき、ホストは最後の要求が取り消されるまでそのグループのメンバーにとどまります。

ソケットのどれかがデータグラムの宛先グループ内でメンバーシップを要求した場合、カーネル IP 層が受信マルチキャストパケットを受け入れます。特定のソケットに対するマルチキャストデータグラムの配信は、単一キャストデータグラムの場合と同様に、宛先ポートと、ソケットに関連付けられたメンバーシップ (raw ソケットの場合はプロトコルタイプ) に基づいています。特定のポートに送信されたマルチキャストデータグラムを受信するには、ローカルアドレスを未指定のまま (INADDR_ANY などに指定) ローカルポートにバインドします。

次の指定が bind(3SOCKET) の前にあると、複数のプロセスを同じ SOCK_DGRAM UDP ポートにバインドできます。

    int one = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))  
この場合、共有ポートに向けられた各受信マルチキャスト UDP データグラムは、そのポートにバインドされているすべてのソケットに配信されます。下位互換性の理由から、これは単一キャストの受信データグラムには適用されません。データグラムの宛先ポートにバインドされているソケットの数にかかわらず、単一キャストデータグラムが複数のソケットに配信されることはありません。SOCK_RAW ソケットは、SO_REUSEADDR オプションがなくても単一の IP プロトコルタイプを共有できます。

マルチキャストに関連する新しいソケットオプションの説明は、<netinet/in.h> を参照してください。IP アドレスはすべて、ネットワークバイトオーダーで渡されます。