/* * multisend.c * * This program transmits a single multicast datagram on a specified * IP multicast group and port. Its one special feature is that it lets * you choose a given interface on which to transmit the packet, which * is necessary if you have a multi-homed host. * * compile with: cc -o multisend multisend.c */ #include #include #include #include #include #include #include #ifdef __FreeBSD__ #include #else #define err(x, y) \ { \ perror(y); \ exit(x); \ } #endif #include #include #include main() { struct ip_mreq mreq; struct ifreq ifreq; int sock; char buf[] = "This is a test"; struct sockaddr_in sin; bzero((char *)&ifreq, sizeof(ifreq)); bzero((char *)&mreq, sizeof(mreq)); bzero((char *)&sin, sizeof(sin)); /* Specify the multicast group and port you want to use here */ sin.sin_addr.s_addr = inet_addr("224.2.100.100"); sin.sin_port = htons(12345); sin.sin_family = AF_INET; mreq.imr_multiaddr.s_addr = sin.sin_addr.s_addr; /* Create socket. */ sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock == -1) err(1, "socket failed"); /* Specify the interface you want to use here. */ strcpy(ifreq.ifr_name, "vr0"); /* Get interface info. */ if (ioctl(sock, SIOCGIFADDR, &ifreq) == -1) err(1, "ioctl failed"); bcopy((char *)&((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr, (char *)&mreq.imr_interface, sizeof(struct in_addr)); /* Join the multicast group. */ if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq)) == -1) err(1, "join failed"); /* Select the interface. */ if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (void *)&mreq.imr_interface, sizeof(struct in_addr)) == -1) err(1, "set interface failed"); /* Transmit the datagram. */ if (sendto(sock, buf, strlen(buf), 0, (struct sockaddr *)&sin, sizeof(sin)) == -1) err(1, "sendto failed"); close(sock); exit(0); }