#include "TAP.h" char tap_name[IFNAMSIZ]; extern bool verbose; extern bool noipv6; extern bool set_ipv4; extern bool set_netmask; extern bool noup; extern int mtu; extern int device_type; extern char if_name[IFNAMSIZ]; extern char* ipv4_addr; extern char* netmask; extern void cleanup(); int open_tap(void) { struct ifreq ifr; int fd = open("/dev/net/tun", O_RDWR); if (fd < 0) { perror("Could not open clone device"); exit(1); } else { memset(&ifr, 0, sizeof(ifr)); // TODO: Enable PI header again? if (device_type == IF_TAP) { ifr.ifr_flags = IFF_TAP | IFF_NO_PI; } else if (device_type == IF_TUN) { ifr.ifr_flags = IFF_TUN; } else { printf("Error: Unsupported interface type\r\n"); cleanup(); exit(1); } strcpy(tap_name, "tnc%d"); strncpy(ifr.ifr_name, tap_name, IFNAMSIZ); if (ioctl(fd, TUNSETIFF, &ifr) < 0) { perror("Could not configure network interface"); exit(1); } else { strcpy(if_name, ifr.ifr_name); int inet = socket(AF_INET, SOCK_DGRAM, 0); if (inet == -1) { perror("Could not open AF_INET socket\r\n"); cleanup(); exit(1); } else { if (ioctl(inet, SIOCGIFFLAGS, &ifr) < 0) { perror("Could not get interface flags from kernel"); close(inet); cleanup(); exit(1); } else { ifr.ifr_mtu = mtu; if (ioctl(inet, SIOCSIFMTU, &ifr) < 0) { perror("Could not configure interface MTU"); close(inet); cleanup(); exit(1); } if (!noup) { ifr.ifr_flags |= IFF_UP | IFF_RUNNING; if (ioctl(inet, SIOCSIFFLAGS, &ifr) < 0) { perror("Could not bring up interface"); close(inet); cleanup(); exit(1); } else { if (set_ipv4) { struct ifreq a_ifr; struct sockaddr_in addr, snm; memset(&a_ifr, 0, sizeof(a_ifr)); memset(&addr, 0, sizeof(addr)); memset(&snm, 0, sizeof(addr)); strncpy(a_ifr.ifr_name, ifr.ifr_name, IFNAMSIZ); addr.sin_family = AF_INET; snm.sin_family = AF_INET; int addr_conversion = inet_pton(AF_INET, ipv4_addr, &(addr.sin_addr)); if (addr_conversion != 1) { printf("Error: Invalid IPv4 address specified\r\n"); close(inet); cleanup(); exit(1); } else { a_ifr.ifr_addr = *(struct sockaddr*)&addr; if (ioctl(inet, SIOCSIFADDR, &a_ifr) < 0) { perror("Could not set IP-address"); close(inet); cleanup(); exit(1); } else { if (set_netmask) { int snm_conversion = inet_pton(AF_INET, netmask, &(snm.sin_addr)); if (snm_conversion != 1) { printf("Error: Invalid subnet mask specified\r\n"); close(inet); cleanup(); exit(1); } else { a_ifr.ifr_addr = *(struct sockaddr*)&snm; if (ioctl(inet, SIOCSIFNETMASK, &a_ifr) < 0) { perror("Could not set subnet mask"); close(inet); cleanup(); exit(1); } } } } } } } } } } return fd; } } } int close_tap(int tap_fd) { return close(tap_fd); }