#include #include #include #include #include #include #include #include #include #include #include int tun_alloc(char *dev); void usage(const char *msg); const char* argv0; const int debug = 1; int main(int argc, char **argv) { int fd_tun; char null_intf[260]; char scratch[1024]; int intf_no; argv0 = argv[0]; if (argc > 1) usage(0); if (geteuid()) usage("Must be run by root"); strcpy(null_intf, "null%d"); if ((fd_tun = tun_alloc(null_intf)) < 0) { perror("Could not alloc tun device"); exit(1); } intf_no = atoi(null_intf+4); printf("Using interface %s with address 169.254.%d.1.\n", null_intf, intf_no); /* Bring up the interface with a link local address */ sprintf(scratch, "/sbin/ip link set %s up", null_intf); system(scratch); sprintf(scratch, "/sbin/ip addr add 169.254.%d.1/32 dev %s", intf_no, null_intf); system(scratch); if (debug) { sprintf(scratch, "/sbin/ip addr ls dev %s", null_intf); system(scratch); } debug && puts("waiting for packets..."); while (1) { if (read(fd_tun, scratch, sizeof(scratch))<0) { perror("Error reading from tun device"); exit(1); } if (debug) { printf("."); fflush(stdout); } } /* never get here */ close(fd_tun); exit(0); } void usage(const char *msg) { if (msg) printf("Error: %s\n\n", msg); printf("Null interface, discard everything sent here.\n" "\n" "usage: %s [ ...]\n", argv0); exit(1); } int tun_alloc(char *dev) { struct ifreq ifr; int fd, err; if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) { /* return tun_alloc_old(dev); */ perror("Cannot open tun allocation device"); exit(1); } memset(&ifr, 0, sizeof(ifr)); /* Flags: IFF_TUN - TUN device (no Ethernet headers) * IFF_TAP - TAP device * * IFF_NO_PI - Do not provide packet information */ ifr.ifr_flags = IFF_TUN | IFF_NO_PI; if( *dev ) strncpy(ifr.ifr_name, dev, IFNAMSIZ); if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){ close(fd); return err; } strcpy(dev, ifr.ifr_name); return fd; }