• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <arpa/inet.h>
2 #include <sys/types.h>
3 #include <sys/socket.h>
4 #include <netinet/in.h>
5 #include <errno.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <netdb.h>
10 #include <unistd.h>
11 
12 static char *prog;
13 static int errors;
14 
15 static int join_group(int, char *, struct ip_mreq *);
16 static int leave_group(int, char *, struct ip_mreq *);
17 static void usage(void);
18 
main(int argc,char * argv[])19 int main(int argc, char *argv[])
20 {
21 	int s;
22 	struct ip_mreq imr;
23 
24 	char *group_list = NULL, *interface = NULL;
25 	unsigned i1, i2, i3, i4;
26 	struct hostent *hp, *gethostbyname();
27 	int c;
28 	int lflg = 0, jflg = 0, sflg = 0;
29 
30 	prog = argv[0];
31 	if (argc == 1)
32 		usage();
33 
34 	while ((c = getopt(argc, argv, "jlg:s:i:")) != EOF)
35 		switch (c) {
36 		case 'j':
37 			if (lflg)
38 				usage();
39 			else
40 				jflg++;
41 			break;
42 		case 'l':
43 			if (jflg)
44 				usage();
45 			else
46 				lflg++;
47 			break;
48 		case 'g':
49 			group_list = optarg;
50 			break;
51 		case 's':
52 			sflg = atoi(optarg);
53 			break;
54 		case 'i':
55 			interface = optarg;
56 			break;
57 		case '?':
58 			usage();
59 		}
60 
61 	if (optind != argc)
62 		usage();
63 
64 	if (access(group_list, R_OK) != 0) {
65 		printf("Unabled to read group file %s\n", group_list);
66 		exit(1);
67 	}
68 
69 	s = socket(AF_INET, SOCK_DGRAM, 0);
70 	if (s == -1) {
71 		perror("can not open socket");
72 		exit(1);
73 	}
74 
75 	hp = gethostbyname(interface);
76 	if (hp != NULL) {
77 		memcpy(&imr.imr_interface.s_addr, hp->h_addr, hp->h_length);
78 	} else if (sscanf(interface, "%u.%u.%u.%u", &i1, &i2, &i3, &i4) != 4) {
79 		fprintf(stderr, "bad group address\n");
80 		exit(1);
81 	} else {
82 		imr.imr_interface.s_addr =
83 		    htonl((i1 << 24) | (i2 << 16) | (i3 << 8) | i4);
84 	}
85 	/* verify socket options */
86 	if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF,
87 		       &imr.imr_interface.s_addr,
88 		       sizeof(imr.imr_interface.s_addr)) != 0) {
89 		fprintf(stderr,
90 			"Error: unable to set socket option IP_MULTICAST_IF\n");
91 		errors++;
92 	} else
93 		printf("Socket set for Multicasting on: %s\n", interface);
94 
95 	if ((!jflg && !lflg) || jflg)
96 		join_group(s, group_list, &imr);
97 
98 	sleep(sflg);
99 
100 	if ((!jflg && !lflg) || lflg)
101 		leave_group(s, group_list, &imr);
102 
103 	close(s);
104 	if (errors)
105 		exit(1);
106 	return 0;
107 }
108 
join_group(int s,char * glist,struct ip_mreq * imr)109 static int join_group(int s, char *glist, struct ip_mreq *imr)
110 {
111 	char buf[40];
112 	unsigned g1, g2, g3, g4;
113 	FILE *fd;
114 	char group[40], itf[40];
115 
116 	fd = fopen(glist, "r");
117 	if (fd == NULL)
118 		printf("Error: unable to open %s\n", glist);
119 
120 	while (fgets(buf, sizeof(buf), fd) != NULL) {
121 		if (sscanf(buf, "%u.%u.%u.%u", &g1, &g2, &g3, &g4) != 4) {
122 			fprintf(stderr, "bad group address\n");
123 			exit(1);
124 		}
125 
126 		imr->imr_multiaddr.s_addr =
127 		    htonl((g1 << 24) | (g2 << 16) | (g3 << 8) | g4);
128 
129 		if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
130 			       imr, sizeof(struct ip_mreq)) == -1) {
131 			fprintf(stderr, "errno is %d\n", errno);
132 			perror("can't join group");
133 			errors++;
134 		} else {
135 			strcpy(group, inet_ntoa(imr->imr_multiaddr));
136 			strcpy(itf, inet_ntoa(imr->imr_interface));
137 			printf("IPM group: %s added to interface: %s\n", group,
138 			       itf);
139 		}
140 	}
141 	return 0;
142 }
143 
leave_group(int s,char * glist,struct ip_mreq * imr)144 static int leave_group(int s, char *glist, struct ip_mreq *imr)
145 {
146 	char buf[40];
147 	unsigned g1, g2, g3, g4;
148 	FILE *fd;
149 	char group[40], itf[40];
150 
151 	fd = fopen(glist, "r");
152 	if (fd == NULL)
153 		printf("Error: unable to open %s\n", glist);
154 
155 	while (fgets(buf, sizeof(buf), fd) != NULL) {
156 		if (sscanf(buf, "%u.%u.%u.%u", &g1, &g2, &g3, &g4) != 4) {
157 			fprintf(stderr, "leave_group: bad group address\n");
158 			exit(1);
159 		}
160 
161 		imr->imr_multiaddr.s_addr =
162 		    htonl((g1 << 24) | (g2 << 16) | (g3 << 8) | g4);
163 
164 		if (setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP,
165 			       imr, sizeof(struct ip_mreq)) == -1) {
166 			perror("can't leave group");
167 			errors++;
168 		} else {
169 			strcpy(group, inet_ntoa(imr->imr_multiaddr));
170 			strcpy(itf, inet_ntoa(imr->imr_interface));
171 			printf("IPM group: %s dropped from interface: %s\n",
172 			       group, itf);
173 		}
174 	}
175 	return 0;
176 }
177 
usage(void)178 static void usage(void)
179 {
180 	fprintf(stderr,
181 		"usage: %s [ -j -l ] -g group_list [-s time_to_sleep] -i interface_name (or i.i.i.i)\n",
182 		prog);
183 	exit(1);
184 }
185