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