diff options
author | Bin Jin <bjin@ctrl-d.org> | 2017-03-12 17:48:20 +0800 |
---|---|---|
committer | Bin Jin <bjin@ctrl-d.org> | 2017-03-12 17:48:20 +0800 |
commit | a2a3e540f2d1a507b34eccae26de09066a2a12fa (patch) | |
tree | 1e336189acd095d761eaad252f18ee6e32b7216b /cbits/tun-linux.c | |
download | wireguard-hs-a2a3e540f2d1a507b34eccae26de09066a2a12fa.tar.xz wireguard-hs-a2a3e540f2d1a507b34eccae26de09066a2a12fa.zip |
Initial commit
Diffstat (limited to 'cbits/tun-linux.c')
-rw-r--r-- | cbits/tun-linux.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/cbits/tun-linux.c b/cbits/tun-linux.c new file mode 100644 index 0000000..adbd7c2 --- /dev/null +++ b/cbits/tun-linux.c @@ -0,0 +1,40 @@ +#include <string.h> + +#include <fcntl.h> +#include <linux/if_tun.h> +#include <net/if.h> +#include <sys/ioctl.h> +#include <unistd.h> + +#include "tun.h" + +int tun_alloc(const char *dev_name, int threads, int *fds) { + struct ifreq ifr; + int fd, i; + + if (!dev_name) + return -1; + + memset(&ifr, 0, sizeof(ifr)); + + ifr.ifr_flags = IFF_TUN | IFF_NO_PI; + if (threads > 1) + ifr.ifr_flags |= IFF_MULTI_QUEUE; + strncpy(ifr.ifr_name, dev_name, IFNAMSIZ); + + for (i = 0; i < threads; i++) { + if ((fd = open("/dev/net/tun", O_RDWR)) < 0) + goto err; + if (ioctl(fd, TUNSETIFF, (void *)&ifr) != 0) { + close(fd); + goto err; + } + fds[i] = fd; + } + + return threads; +err: + for (--i; i >= 0; i--) + close(fds[i]); + return -1; +} |