/* test program for * https://community.openvpn.net/openvpn/ticket/1226 * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=248172 * * run as: "./tester tun0" or "tap3" etc. * it will open the named tun/tap device, "ifconfig" an inet6 address, * and then monitor the output of "ifconfig $dev" for the next 10 seconds * on whether IFDISABLED is set (which should not happen) */ #include #include #include #include #include #include #include void run_it(char *cmd) { printf("run cmd: '%s'\n", cmd); if(system(cmd)<0) { fprintf(stderr, "running system() failed: %s, exit\n", strerror(errno)); exit(10); } } int main(int argc, char ** argv) { if (argc != 2) { fprintf(stderr, "%s: need one argument, tun/tap device name ('tun0')\n", argv[0]); exit(1); } char *ifname = argv[1]; char devname[200]; snprintf(devname,sizeof(devname)-1,"/dev/%s",ifname); int tunfd = open(devname, O_RDWR); if (tunfd<0) { fprintf(stderr, "cannot open %s: %s\n", devname, strerror(errno)); exit(2); } printf( "%s open ok, fd=%d\n", devname, tunfd ); /* nonblocking mode, close on exec */ if (fcntl(tunfd, F_SETFL, O_NONBLOCK) < 0 || fcntl(tunfd, F_SETFD, FD_CLOEXEC) < 0 ) { fprintf(stderr, "cannot set tunfd to O_NONBLOCK & FD_CLOEXEC: %s\n", strerror(errno)); exit(3); } /* ifconfig an inet6 address */ char cmdbuf[1000]; snprintf(cmdbuf, sizeof(cmdbuf), "ifconfig %s inet6 fd00:abcd:204:4::1001/64 mtu 1500 up", ifname); run_it(cmdbuf); /* monitor "ifconfig $dev" output for IFDISABLED */ time_t start = time(NULL); while( time(NULL) < start+10 ) { snprintf(cmdbuf, sizeof(cmdbuf), "ifconfig %s", ifname); FILE * pfp = popen(cmdbuf, "r"); if (!pfp) { fprintf(stderr, "cannot popen('%s'): %s\n", cmdbuf, strerror(errno)); exit(3); } char pipebuf[2000]; int r = fread(pipebuf, 1, sizeof(pipebuf)-1, pfp); fclose(pfp); if (r<0) { fprintf(stderr, "error reading from pipe: %s\n", strerror(errno)); exit(3); } pipebuf[r] = 0; printf( "read %d bytes, time since start=%ds\n%s", r, (int)(time(NULL)-start), pipebuf); if (strstr(pipebuf, "IFDISABLED")) { printf( " *** FOUND ***\n" ); } sleep(1); } /* clean up: close fd, destroy device */ close(tunfd); snprintf(cmdbuf, sizeof(cmdbuf), "ifconfig %s destroy", ifname); run_it(cmdbuf); exit(0); }