#include #include #include #include #include #include #include #include #include #include const unsigned char mac_guest[6] = { 0xfe, 0xfd, 0, 0, 0, 1 }; const unsigned char ip_guest[4] = { 192, 168, 1, 10 }; const unsigned char ip_host[4] = { 192, 168, 1, 1 }; void die (const char *s1, const char *s2) { write(2, s1, strlen(s1)); write(2, ": ", 2); write(2, s2, strlen(s2)); write(2, "\n", 1); exit(111); } void usage () { die("usage", "tunconfig "); } int main (int argc, char **argv) { int ret, sock, i; struct sockaddr_in *sin; struct arpreq arr; struct ifreq ifr; if (argc != 2) usage(); if (strlen(argv[1]) != 4) usage(); if (strncmp(argv[1], "tun", 3)) usage(); if ((argv[1][3] < '0') || (argv[1][3] > '9')) usage(); memset(&arr, 0, sizeof(struct arpreq)); memset(&ifr, 0, sizeof(struct ifreq)); sock = socket(PF_INET, SOCK_DGRAM, 0); if (sock < 0) die("socket()", strerror(errno)); /* ifconfig up */ strncpy(ifr.ifr_ifrn.ifrn_name, argv[1], IF_NAMESIZE); sin = (struct sockaddr_in*) &ifr.ifr_ifru.ifru_addr; sin->sin_family = AF_INET; for (i = 3; i >= 0; --i) sin->sin_addr.s_addr = (sin->sin_addr.s_addr << 8) + ip_host[i]; ret = ioctl(sock, SIOCSIFADDR, &ifr); if (ret < 0) die("SIOCSIFADDR", strerror(errno)); ifr.ifr_ifru.ifru_flags = IFF_UP | IFF_PROMISC; ret = ioctl(sock, SIOCSIFFLAGS, &ifr); if (ret < 0) die("SIOCSIFFLAGS", strerror(errno)); /* arp */ arr.arp_flags = ATF_COM | ATF_PUBL | ATF_PERM; strncpy(arr.arp_dev, argv[1], 16); sin = (struct sockaddr_in*) &arr.arp_pa; sin->sin_family = AF_INET; for (i = 3; i >= 0; --i) sin->sin_addr.s_addr = (sin->sin_addr.s_addr << 8) + ip_guest[i]; for (i = 0; i < 6; ++i) arr.arp_ha.sa_data[i] = mac_guest[i]; ret = ioctl(sock, SIOCSARP, &arr); if (ret < 0) die("SIOCSARP", strerror(errno)); return 0; }