#include #ifdef LINUX #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #define INADDR_MCAST_TEST1 (u_int32_t)0xe0010101 /* 224.1.1.1 */ #define INADDR_MCAST_TEST2 (u_int32_t)0xe0010102 /* 224.1.1.2 */ #define INADDR_MCAST_SRCTEST1 (u_int32_t)0x0a010101 /* 10.1.1.1 */ #define INADDR_MCAST_SRCTEST2 (u_int32_t)0x0a010102 /* 10.1.1.2 */ #define INADDR_MCAST_SRCTEST3 (u_int32_t)0x0a010103 /* 10.1.1.3 */ /* * Fetch the first two available interfaces' addresses. */ int mtest_ifaceaddrs(struct in_addr *if_addrs, int ifadrsn) { int i, ifnc; char *if_name, *pif; struct ifaddrs *ifap, *ifa; struct sockaddr_in *sin; if (ifadrsn < 2) return (-1); if ((if_name = (char *) malloc(IFNAMSIZ * ifadrsn)) == NULL) err(1, "fetch if addrs: malloc failed"); memset(if_name, 0, IFNAMSIZ * ifadrsn); memset(if_addrs, 0, sizeof(*if_addrs) * ifadrsn); if (getifaddrs(&ifap) != 0) err(1, "fetch if addrs: getifaddrs failed"); for (ifa = ifap, ifnc = 0, pif = if_name; ifa != NULL && ifnc < ifadrsn; ifa = ifa->ifa_next) { if (ifa->ifa_addr->sa_family != AF_INET) continue; sin = (struct sockaddr_in *)ifa->ifa_addr; /* Check if we already have an address for this interface. */ for (i = 0; i <= ifnc; i++) { if (strncmp(if_name + i * IFNAMSIZ, ifa->ifa_name, IFNAMSIZ) == 0) break; } if (ifnc == 0 || i > ifnc) { if_addrs[ifnc].s_addr = sin->sin_addr.s_addr; strlcpy(pif, ifa->ifa_name, IFNAMSIZ); ++ifnc; pif += IFNAMSIZ; } } freeifaddrs(ifap); free(if_name); return (ifnc + 1); } struct mctest { int sock; struct in_addr group[2]; struct in_addr if_addr[2]; struct in_addr src_addr[3]; struct ip_mreq mreq; struct ip_mreq_source smreq; struct sockaddr_in bind_addr; }; static int mctest_init(struct mctest *mt) { int ifan; memset(mt, 0, sizeof (*mt)); if ((ifan = mtest_ifaceaddrs(mt->if_addr, 2)) < 2) err(1, "Could not fetch iface addreses"); mt->group[0].s_addr = htonl(INADDR_MCAST_TEST1); mt->group[1].s_addr = htonl(INADDR_MCAST_TEST2); mt->src_addr[0].s_addr = htonl(INADDR_MCAST_SRCTEST1); mt->src_addr[1].s_addr = htonl(INADDR_MCAST_SRCTEST1); mt->src_addr[2].s_addr = htonl(INADDR_MCAST_SRCTEST1); if ((mt->sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_IP)) == -1) err(1, "socket failed"); mt->mreq.imr_multiaddr.s_addr = mt->group->s_addr; mt->mreq.imr_interface.s_addr= mt->if_addr->s_addr; mt->smreq.imr_multiaddr.s_addr = mt->mreq.imr_multiaddr.s_addr; mt->smreq.imr_sourceaddr.s_addr = mt->src_addr->s_addr; mt->smreq.imr_interface.s_addr = mt->mreq.imr_interface.s_addr; return (0); } struct mctest mctest; #define sock (mctest.sock) #define group1 (mctest.group) #define group2 (mctest.group + 1) #define if_addr1 (mctest.if_addr) #define if_addr2 (mctest.if_addr + 1) #define src_addr1 (mctest.src_addr) #define src_addr2 (mctest.src_addr + 1) #define src_addr3 (mctest.src_addr + 2) #define mreq (&(mctest.mreq)) #define smreq (&(mctest.smreq)) #define bind_addr (&(mctest.bind_addr) int main (int argc, char **argv) { int result; if (argc > 1) exit (0); mctest_init(&mctest); result = setsockopt (sock, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, smreq, sizeof(*smreq)); smreq->imr_interface.s_addr = if_addr2->s_addr; result = setsockopt(sock, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, smreq, sizeof(*smreq)); smreq->imr_interface.s_addr = if_addr1->s_addr; /* result = setsockopt (sock, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, smreq, sizeof(*smreq)); result = setsockopt (sock, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, smreq, sizeof(*smreq)); */ result = setsockopt (sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, mreq, sizeof(*mreq)); // sleep(100); // if (0) result = setsockopt (sock, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, smreq, sizeof(*smreq)); exit (0); }