Question

I'm seeing some "interesting" behavior in my program's link-local IPv6 multicast routines. It seems that if I set any of the upper 16 bits of the 112-bit Group ID field, then MacOS/X will no longer accept those multicast packets. My question is, is this a bug in the MacOS/X network stack, or is there some reason why setting the upper 16 bits of the Group ID field would affect routing behavior?

More specific info follows:

  • Multicasting from one Mac to another Mac always works (tested on 10.5 and 10.6)

  • Multicasting from Linux to Windows always works

  • Multicasting from Mac to Windows, or Windows to Mac, or Linux to Mac, only works if the upper 16 bits of the Group ID in the multicast address are set to zero. For example:

  • ff02::666 works
  • ff02:0:ffff::666 works
  • ff02:1::666 doesn't work
  • ff02:8000::666 doesn't work

    • In the "doesn't work" cases, WireShark running on the Mac shows that the Mac has received the multicast packets, but those packets are never passed on to the receiving application(s) on the Mac. Does this mean that the Mac networking stack has a bug, or is there some deeper magic to multicast addressing that I'm not aware of?
  • Was it helpful?

    Solution

    Are you joining the multicast group first? You have to explicitly tell the OS the group that you want to join before it will deliver you a group's messages. There's a command you can access with setsockopt() to join a multicast group. From the Darwin ip6 manpage:

    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.
    

    I found some example code here:

    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));
    

    But maybe you're doing this already?

    Licensed under: CC-BY-SA with attribution
    Not affiliated with StackOverflow
    scroll top