Here are a few tips on working with multicast sockets and UNIX (FreeBSD).
struct sockaddr_in sockaddr_group; struct hostent *group; struct ip_mreq mreq; bzero(&mreq,sizeof(struct ip_mreq)); // set group if ((group = gethostbyname(ghost))==(struct hostent *)0) { cerr << "gethostbyname error: fails for host " << host << endl; exit(-1); } struct in_addr ia; bcopy((void*)group->h_addr, (void*)&ia, group->h_length); bcopy(&ia, &mreq.imr_multiaddr.s_addr, sizeof(struct in_addr)); // set interface mreq.imr_interface.s_addr = htonl(INADDR_ANY); // do membership call if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(struct ip_mreq)) == -1) { cerr << "error: setsockopt(IP_ADD_MEMBERSHIP) fails with errno " << errno << endl; exit(-1); }
IP_MULTICAST_IF /* u_char; set/get IP multicast i/f */ IP_MULTICAST_TTL /* u_char; set/get IP multicast ttl */ IP_MULTICAST_LOOP /* u_char; set/get IP multicast loopback */ IP_ADD_MEMBERSHIP /* ip_mreq; add an IP group membership */ IP_DROP_MEMBERSHIP /* ip_mreq; drop an IP group membership */
Use IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP to switch multicast groups "listened" for by the recieving socket. Use IP_MULTICAST_LOOP if you would like the sender to also receive a copy of what is sent to the group. I don't believe IP_MULTICAST_IF or IP_MULTICAST_TTL will be of interest for what we're doing.
/usr/include/netinet/in.h