aboutsummaryrefslogtreecommitdiffstats
path: root/cbits/tun-linux.c
diff options
context:
space:
mode:
authorBin Jin <bjin@ctrl-d.org>2017-03-12 17:48:20 +0800
committerBin Jin <bjin@ctrl-d.org>2017-03-12 17:48:20 +0800
commita2a3e540f2d1a507b34eccae26de09066a2a12fa (patch)
tree1e336189acd095d761eaad252f18ee6e32b7216b /cbits/tun-linux.c
downloadwireguard-hs-a2a3e540f2d1a507b34eccae26de09066a2a12fa.tar.xz
wireguard-hs-a2a3e540f2d1a507b34eccae26de09066a2a12fa.zip
Initial commit
Diffstat (limited to 'cbits/tun-linux.c')
-rw-r--r--cbits/tun-linux.c40
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;
+}