/* fakeif - Sets the apparent hardware address of a network interface To compile: gcc -shared -o fakeif.so fakeif.c To run: HWADDR_eth0=11:22:33:44:55:66 export HWADDR_eth0 LD_PRELOAD=/path/to/fakeif.so program args... */ #include #include #include #include #include #include #include #include #include #include #define __NR_real_ioctl __NR_ioctl static inline _syscall3(int,real_ioctl,int,fd,unsigned int,cmd,unsigned long,arg); int ioctl(int fd, unsigned int cmd, unsigned long arg) { char var[IFNAMSIZ+8], *endptr; const char *hwtxt, *ptr; struct ifreq *req=(struct ifreq *)arg; unsigned char hwaddr[6]={0,0,0,0,0,0}; int byte; if (cmd!=SIOCGIFHWADDR) goto out; sprintf(var, "HWADDR_%.*s", IFNAMSIZ, req->ifr_name); if (!(ptr=hwtxt=getenv(var))) goto out; for (byte=0; byte<6; byte++) { unsigned long l=strtoul(ptr, &endptr, 16); hwaddr[byte]=l; if (ptr==endptr || l>255) goto fail; ptr=endptr; if (*ptr==':' || *ptr=='-') ptr++; } if (*endptr) goto fail; memcpy(&req->ifr_hwaddr.sa_data, hwaddr, 6); return 0; fail: fprintf(stderr, "fakeif: WARNING: %s is invalid (%s)\n", var, hwtxt); out: return real_ioctl(fd, cmd, arg); }