2

プログラムのリンクローカル IPv6 マルチキャスト ルーチンで「興味深い」動作が見られます。112 ビットのグループ ID フィールドの上位 16 ビットのいずれかを設定すると、MacOS/X はそれらのマルチキャスト パケットを受け入れなくなります。私の質問は、これは MacOS/X ネットワーク スタックのバグですか、それともグループ ID フィールドの上位 16 ビットを設定するとルーティングの動作に影響する何らかの理由があるのでしょうか?

より具体的な情報は次のとおりです。

  • ある Mac から別の Mac へのマルチキャストは常に機能します (10.5 および 10.6 でテスト済み)。

  • Linux から Windows へのマルチキャストは常に機能します

  • Mac から Windows、Windows から Mac、または Linux から Mac へのマルチキャストは、マルチキャスト アドレスのグループ ID の上位 16 ビットがゼロに設定されている場合にのみ機能します。例えば:

  • ff02::666 作品
  • ff02:0:ffff::666 は動作します
  • ff02:1::666 は機能しません
  • ff02:8000::666 は機能しません

    • 「動作しない」場合、Mac で実行されている WireShark は、Mac がマルチキャスト パケットを受信したことを示しますが、それらのパケットは Mac 上の受信アプリケーションに渡されません。これは、Mac のネットワーク スタックにバグがあるということですか、それとも、私が気付いていないマルチキャスト アドレッシングのより深い魔法があるということですか?
  • 4

    1 に答える 1

    1

    最初にマルチキャストグループに参加していますか?グループのメッセージを配信する前に、参加するグループをOSに明示的に通知する必要があります。setsockopt()マルチキャストグループに参加するためにアクセスできるコマンドがあります。Darwin ip6のマンページから:

    IPV6_JOIN_GROUP struct ipv6_mreq *
        Join a multicast group.  A host must become a member of a multicast group before it can receive
        datagrams sent to the group.
    
        struct ipv6_mreq {
                struct in6_addr ipv6mr_multiaddr;
                unsigned int    ipv6mr_interface;
        };
    
        ipv6mr_interface may be set to zeroes to choose the default multicast interface or to the index
        of a particular multicast-capable interface if the host is multihomed.  Membership is associ-
        ated with a single interface; programs running on multihomed hosts may need to join the same
        group on more than one interface.
    
        If the multicast address is unspecified (i.e., all zeroes), messages from all multicast
        addresses will be accepted by this group.  Note that setting to this value requires superuser
        privileges.
    

    私はここにいくつかのサンプルコードを見つけました:

    struct ipv6_mreq mreq6;
    memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr),
           sizeof(struct in6_addr));
    mreq6.ipv6mr_interface= 0;
    
    err = setsockopt(sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6, sizeof(mreq6));
    if (err) fprintf(stderr, "setsockopt IPV6_JOIN_GROUP: %s\n", strerror (errno));
    

    しかし、多分あなたはすでにこれをやっていますか?

    于 2009-10-04T22:53:12.140 に答える