X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=src%2Fmctap.c;h=24efc121b1db32583b8c5b9127cc432728da9182;hb=b62b996ecc97dd059524a88a2aaf3a33222af4b0;hp=9fce9acf6c5d78ba557f6d5a6072a2001cc53490;hpb=1fefa40de9ff07accc7dcdde5e5f7a0a346328c3;p=mctap.git diff --git a/src/mctap.c b/src/mctap.c index 9fce9ac..24efc12 100644 --- a/src/mctap.c +++ b/src/mctap.c @@ -17,10 +17,11 @@ #include "utils.h" static int quit = 0; +static unsigned char macaddr[6]; static void usage(FILE *out) { - fprintf(out, "usage: mctap [-hdp] [-P PIDFILE] [-D TAPNAME] MCASTGROUP PORT\n"); + fprintf(out, "usage: mctap [-hdpk] [-P PIDFILE] [-D TAPNAME] MCASTGROUP PORT\n"); } static __attribute__ ((unused)) char *formataddress(struct sockaddr *arg, socklen_t arglen) @@ -145,6 +146,8 @@ static void bridge(int sock, int tap, struct sockaddr *dst, socklen_t dstlen) } else { if(sizeof(buf) - ret < sizeof(pi)) { /* Drop */ + } else if((ret < 12) || !memcmp(macaddr, buf + 6, 6)) { + /* Drop looped back */ } else { memmove(buf + sizeof(pi), buf, ret); pi.flags = 0; @@ -189,6 +192,9 @@ static int maketap(char *name) strncpy(rb.ifr_name, name, IFNAMSIZ); if(ioctl(fd, TUNSETIFF, &rb)) return(-1); + if(ioctl(fd, SIOCGIFHWADDR, &rb)) + return(-1); + memcpy(macaddr, rb.ifr_hwaddr.sa_data, 6); return(fd); } @@ -204,6 +210,23 @@ static void sighand(int sig) } } +static void killrunning(char *pidfile) +{ + FILE *pidfd; + int pid; + + if((pidfd = fopen(pidfile, "r")) == NULL) { + fprintf(stderr, "mctab -k: could not read PID file %s: %s\n", pidfile, strerror(errno)); + exit(1); + } + fscanf(pidfd, "%i", &pid); + if(kill(pid, SIGTERM)) { + fprintf(stderr, "mctab -k: could not kill %i: %s\n", pid, strerror(errno)); + exit(1); + } + fclose(pidfd); +} + int main(int argc, char **argv) { int c; @@ -212,14 +235,14 @@ int main(int argc, char **argv) int port; char *tapname; char *pidfile; - int daemonize; + int daemonize, killold; struct sockaddr_in dst; FILE *pidfd; tapname = "mctap"; - daemonize = 0; + daemonize = killold = 0; pidfile = NULL; - while((c = getopt(argc, argv, "hD:dpP:")) >= 0) { + while((c = getopt(argc, argv, "hD:dpP:k")) >= 0) { switch(c) { case 'D': tapname = optarg; @@ -233,6 +256,11 @@ int main(int argc, char **argv) case 'P': pidfile = optarg; break; + case 'k': + killold = 1; + if(pidfile == NULL) + pidfile = (void *)-1; + break; case 'h': usage(stdout); return(0); @@ -243,6 +271,10 @@ int main(int argc, char **argv) } if(pidfile == (void *)-1) pidfile = sprintf2("/var/run/mctap.%s.pid", tapname); + if(killold) { + killrunning(pidfile); + return(0); + } if(argc - optind < 2) { usage(stderr); exit(1); @@ -282,6 +314,7 @@ int main(int argc, char **argv) dst.sin_family = AF_INET; dst.sin_addr = group; dst.sin_port = htons(port); + syslog(LOG_INFO, "bridge created with MAC %02x:%02x:%02x:%02x:%02x:%02x", macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]); bridge(sock, tap, (struct sockaddr *)&dst, sizeof(dst)); syslog(LOG_INFO, "exiting");