5 #include <sys/socket.h>
6 #include <netinet/in.h>
12 static void usage(FILE *out)
14 fprintf(out, "usage: mctap [-h] MCASTGROUP PORT\n");
17 static char *formataddress(struct sockaddr *arg, socklen_t arglen)
19 struct sockaddr_in *ipv4;
20 struct sockaddr_in6 *ipv6;
21 static char *ret = NULL;
27 switch(arg->sa_family)
30 ret = strdup("Unix socket");
33 ipv4 = (struct sockaddr_in *)arg;
34 if(inet_ntop(AF_INET, &ipv4->sin_addr, buf, sizeof(buf)) == NULL)
36 ret = sprintf2("%s:%i", buf, (int)ntohs(ipv4->sin_port));
39 ipv6 = (struct sockaddr_in6 *)arg;
40 if(inet_ntop(AF_INET6, &ipv6->sin6_addr, buf, sizeof(buf)) == NULL)
42 ret = sprintf2("[%s]:%i", buf, (int)ntohs(ipv6->sin6_port));
51 static int mkmcastsk4(struct in_addr group, int port)
55 struct sockaddr_in nm;
58 fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
60 if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &soval, sizeof(soval)))
62 memset(&nm, 0, sizeof(nm));
63 nm.sin_family = AF_INET;
64 nm.sin_port = htons(port);
65 if(bind(fd, (struct sockaddr *)&nm, sizeof(nm)))
67 memset(&mreq, 0, sizeof(mreq));
68 mreq.imr_multiaddr = group;
69 if(setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)))
74 static void test(int fd)
78 struct sockaddr_storage nm;
83 ret = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&nm, &nmlen);
85 fprintf(stderr, "mctap: recvfrom: %s\n", strerror(ret));
88 printf("%s %i:\n", formataddress((struct sockaddr *)&nm, nmlen), ret);
92 int main(int argc, char **argv)
99 while((c = getopt(argc, argv, "h")) >= 0) {
109 if(argc - optind < 2) {
113 if(!inet_aton(argv[optind], &group)) {
114 fprintf(stderr, "mctap: invalid group address: %s\n", argv[optind]);
117 port = atoi(argv[optind + 1]);
118 if((sock = mkmcastsk4(group, port)) < 0) {
119 fprintf(stderr, "mctap: could not create multicast socket: %s\n", strerror(errno));