blob: 45bd61715cfeb3a2a4761e9511a67301f9fad15b [file] [log] [blame]
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
char *prog;
int errors=0;
int ttl_no=255;
int join_group (int, char *, struct ip_mreq *);
int leave_group (int, char *, struct ip_mreq *);
void usage(void);
int main(argc, argv)
int argc;
char *argv[];
{
int s;
struct ip_mreq imr;
char *group_list=NULL, *interface=NULL;
unsigned i1, i2, i3, i4;
struct hostent *hp, *gethostbyname();
int c, n;
/*int errors=0;*/
int lflg=0, jflg=0, sflg=0;
extern int optind;
extern char *optarg;
prog = argv[0];
if (argc == 1)
usage ();
while ((c = getopt(argc,argv,"jlg:s:i:")) != EOF)
switch (c)
{
case 'j':
if (lflg)
usage();
else
jflg++;
break;
case 'l':
if (jflg)
usage();
else
lflg++;
break;
case 'g':
group_list = optarg;
break;
case 's':
sflg=atoi(optarg);
break;
case 'i':
interface = optarg;
break;
case '?':
usage();
}
if (optind != argc)
usage ();
if (access (group_list, R_OK) != 0) {
printf ("Unabled to read group file %s\n",group_list);
exit (1);
}
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror( "can not open socket" );
exit(1);
}
if ((hp = gethostbyname(interface))) {
memcpy(&imr.imr_interface.s_addr, hp->h_addr, hp->h_length);
} else
if ((n = sscanf(interface, "%u.%u.%u.%u", &i1, &i2, &i3, &i4)) != 4) {
fprintf(stderr, "bad group address\n" );
exit (1);
} else
imr.imr_interface.s_addr =
htonl((i1<<24) | (i2<<16) | (i3<<8) | i4);
/* verify socket options */
if ( setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF,
&imr.imr_interface.s_addr,
sizeof(imr.imr_interface.s_addr)) != 0 ) {
fprintf(stderr,"Error: unable to set socket option IP_MULTICAST_IF\n");
errors++;
} else
printf("Socket set for Multicasting on: %s\n",interface);
if ((!jflg && !lflg) || jflg)
join_group ( s, group_list, &imr );
sleep (sflg);
if ((!jflg && !lflg) || lflg)
leave_group ( s, group_list, &imr );
close (s);
if (errors)
exit (1);
return (0);
}
int join_group (int s, char *glist, struct ip_mreq *imr)
{
char buf[40];
unsigned g1, g2, g3, g4;
FILE *fd;
char group[40], itf[40];
if ((fd = fopen(glist,"r")) == NULL)
printf ("Error: unable to open %s\n",glist);
while (fgets(buf, sizeof(buf), fd) != NULL) {
if (sscanf(buf, "%u.%u.%u.%u", &g1, &g2, &g3, &g4) != 4) {
fprintf(stderr, "bad group address\n" );
exit(1);
}
imr->imr_multiaddr.s_addr = htonl((g1<<24) | (g2<<16) | (g3<<8) | g4);
if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
imr, sizeof(struct ip_mreq)) == -1) {
fprintf(stderr, "errno is %d \n", errno);
perror("can't join group");
errors++;
} else {
strcpy (group,inet_ntoa(imr->imr_multiaddr));
strcpy (itf,inet_ntoa(imr->imr_interface));
printf ("IPM group: %s added to interface: %s\n",group,itf);
}
}
return (0);
}
int leave_group (int s, char *glist, struct ip_mreq *imr)
{
char buf[40];
unsigned g1, g2, g3, g4;
FILE *fd;
char group[40], itf[40];
if ((fd = fopen(glist,"r")) == NULL)
printf ("Error: unable to open %s\n",glist);
while (fgets(buf, sizeof(buf), fd) != NULL) {
if (sscanf(buf, "%u.%u.%u.%u", &g1, &g2, &g3, &g4) != 4) {
fprintf(stderr, "leave_group: bad group address\n" );
exit(1);
}
imr->imr_multiaddr.s_addr =
htonl((g1<<24) | (g2<<16) | (g3<<8) | g4);
if (setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP,
imr, sizeof(struct ip_mreq)) == -1) {
perror("can't leave group");
errors++;
} else {
strcpy (group,inet_ntoa(imr->imr_multiaddr));
strcpy (itf,inet_ntoa(imr->imr_interface));
printf ("IPM group: %s dropped from interface: %s\n",group,itf);
}
}
return (0);
}
void usage()
{
fprintf(stderr,
"usage: %s [ -j -l ] -g group_list [-s time_to_sleep] -i interface_name (or i.i.i.i)\n",prog);
exit( 1);
}