From a8ebefbef31c2c098190582a94e6ae7504f5fc92 Mon Sep 17 00:00:00 2001 From: angt Date: Mon, 16 Nov 2015 15:44:16 +0100 Subject: [PATCH] Add tun.[ch] --- Makefile.am | 4 +- src/main.c | 182 +--------------------------------------------- src/tun.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/tun.h | 7 ++ 4 files changed, 214 insertions(+), 181 deletions(-) create mode 100644 src/tun.c create mode 100644 src/tun.h diff --git a/Makefile.am b/Makefile.am index ca16537..eed4735 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,4 +7,6 @@ glorytun_SOURCES = \ src/ip-static.h \ src/main.c \ src/option.c \ - src/option.h + src/option.h \ + src/tun.c \ + src/tun.h diff --git a/src/main.c b/src/main.c index 72bd38e..88bd0c4 100644 --- a/src/main.c +++ b/src/main.c @@ -4,29 +4,19 @@ #include #include -#include #include #include #include #include #include -#ifdef __linux__ -# include -# include -#endif - -#ifdef __APPLE__ -# include -# include -# include -#endif - #include #include "common-static.h" #include "ip-static.h" + #include "option.h" +#include "tun.h" #ifndef O_CLOEXEC #define O_CLOEXEC 0 @@ -35,10 +25,6 @@ #define GT_BUFFER_SIZE (4*1024*1024) #define GT_TIMEOUT (1000) -#if defined(__APPLE__) || defined(__OpenBSD__) -# define BSD_TUN 1 -#endif - struct netio { int fd; struct { @@ -297,93 +283,6 @@ static struct addrinfo *ai_create (const char *host, const char *port, int liste return NULL; } -#ifdef __linux__ -static int tun_create (char *name, int multiqueue) -{ - int fd = open("/dev/net/tun", O_RDWR); - - if (fd<0) { - perror("open /dev/net/tun"); - return -1; - } - - struct ifreq ifr = { - .ifr_flags = IFF_TUN|IFF_NO_PI, - }; - - if (multiqueue) { -#ifdef IFF_MULTI_QUEUE - ifr.ifr_flags |= IFF_MULTI_QUEUE; -#else - gt_not_available("IFF_MULTI_QUEUE"); -#endif - } - - str_cpy(ifr.ifr_name, name, IFNAMSIZ-1); - - int ret = ioctl(fd, TUNSETIFF, &ifr); - - if (ret<0) { - perror("ioctl TUNSETIFF"); - return -1; - } - - printf("tun name: %s\n", ifr.ifr_name); - - return fd; -} -#elif defined(__APPLE__) -static int tun_create (_unused_ char *name, _unused_ int mq) -{ - struct ctl_info ctlInfo; - struct sockaddr_ctl sc; - int fd; - - for (unsigned dev_id = 0U; dev_id<32U; dev_id++) { - byte_set(&ctlInfo, 0, sizeof(ctlInfo)); - str_cpy(ctlInfo.ctl_name, UTUN_CONTROL_NAME, sizeof(ctlInfo.ctl_name)); - fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); - if (fd==-1) - return -1; - if (ioctl(fd, CTLIOCGINFO, &ctlInfo)==-1) { - close(fd); - continue; - } - sc.sc_id = ctlInfo.ctl_id; - sc.sc_len = sizeof(sc); - sc.sc_family = AF_SYSTEM; - sc.ss_sysaddr = AF_SYS_CONTROL; - sc.sc_unit = dev_id+1; - if (connect(fd, (struct sockaddr *) &sc, sizeof(sc))==-1) { - close(fd); - continue; - } - printf("tun name: /dev/utun%u\n", dev_id); - - return fd; - } - return -1; -} -#else -static int tun_create (_unused_ char *name, _unused_ int mq) -{ - for (unsigned dev_id = 0U; dev_id<32U; dev_id++) { - char dev_path[11U]; - - snprintf(dev_path, sizeof(dev_path), "/dev/tun%u", dev_id); - - int fd = open(dev_path, O_RDWR); - - if (fd!=-1) { - printf("tun name: /dev/tun%u\n", dev_id); - return fd; - } - } - - return -1; -} -#endif - static void gt_sa_stop (int sig) { switch (sig) { @@ -503,83 +402,6 @@ static ssize_t fd_write_all (int fd, const void *data, size_t size) return done; } -static ssize_t tun_read (int fd, void *data, size_t size) -{ -#ifndef BSD_TUN - return fd_read(fd, data, size); -#else - if (!size) - return -2; - - uint32_t family; - struct iovec iov[2] = { - { .iov_base = &family, .iov_len = sizeof(family) }, - { .iov_base = data, .iov_len = size } - }; - - ssize_t ret = readv(fd, iov, 2); - - if (ret==-1) { - if (errno==EAGAIN || errno==EINTR) - return -1; - - if (errno) - perror("readv"); - - return 0; - } - if (ret<(ssize_t) sizeof(family)) - return 0; - - return ret-sizeof(family); -#endif -} - -static size_t tun_write (int fd, const void *data, size_t size) -{ -#ifndef BSD_TUN - return fd_write(fd, data, size); -#else - if (!size) - return -2; - - uint32_t family; - - switch (ip_get_version(data, size)) { - case 4: - family = htonl(AF_INET); - break; - case 6: - family = htonl(AF_INET6); - break; - default: - return -1; - } - - struct iovec iov[2] = { - { .iov_base = &family, .iov_len = sizeof(family) }, - { .iov_base = (void *) data, .iov_len = size }, - }; - - ssize_t ret = writev(fd, iov, 2); - - if (ret==-1) { - if (errno==EAGAIN || errno==EINTR) - return -1; - - if (errno) - perror("writev"); - - return 0; - } - - if (ret<(ssize_t) sizeof(family)) - return 0; - - return ret-sizeof(family); -#endif -} - static int encrypt_packet (struct crypto_ctx *ctx, uint8_t *packet, size_t size, buffer_t *buffer) { const size_t ws = size + crypto_aead_aes256gcm_ABYTES; diff --git a/src/tun.c b/src/tun.c new file mode 100644 index 0000000..fb51393 --- /dev/null +++ b/src/tun.c @@ -0,0 +1,202 @@ +#include "common-static.h" +#include "tun.h" + +#include +#include + +#include +#include + +#ifdef __linux__ +# include +# include +#endif + +#ifdef __APPLE__ +# include +# include +# include +#endif + +#if defined(__APPLE__) || defined(__OpenBSD__) +# define GT_BSD_TUN 1 +#endif + +#ifdef __linux__ +int tun_create (char *name, int multiqueue) +{ + int fd = open("/dev/net/tun", O_RDWR); + + if (fd<0) { + perror("open /dev/net/tun"); + return -1; + } + + struct ifreq ifr = { + .ifr_flags = IFF_TUN|IFF_NO_PI, + }; + + if (multiqueue) { +#ifdef IFF_MULTI_QUEUE + ifr.ifr_flags |= IFF_MULTI_QUEUE; +#else + gt_not_available("IFF_MULTI_QUEUE"); +#endif + } + + str_cpy(ifr.ifr_name, name, IFNAMSIZ-1); + + int ret = ioctl(fd, TUNSETIFF, &ifr); + + if (ret<0) { + perror("ioctl TUNSETIFF"); + return -1; + } + + printf("tun name: %s\n", ifr.ifr_name); + + return fd; +} +#elif defined(__APPLE__) +int tun_create (_unused_ char *name, _unused_ int mq) +{ + struct ctl_info ctlInfo; + struct sockaddr_ctl sc; + int fd; + + for (unsigned dev_id = 0U; dev_id<32U; dev_id++) { + byte_set(&ctlInfo, 0, sizeof(ctlInfo)); + str_cpy(ctlInfo.ctl_name, UTUN_CONTROL_NAME, sizeof(ctlInfo.ctl_name)); + fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); + + if (fd==-1) + return -1; + + if (ioctl(fd, CTLIOCGINFO, &ctlInfo)==-1) { + close(fd); + continue; + } + + sc.sc_id = ctlInfo.ctl_id; + sc.sc_len = sizeof(sc); + sc.sc_family = AF_SYSTEM; + sc.ss_sysaddr = AF_SYS_CONTROL; + sc.sc_unit = dev_id+1; + + if (connect(fd, (struct sockaddr *) &sc, sizeof(sc))==-1) { + close(fd); + continue; + } + + printf("tun name: /dev/utun%u\n", dev_id); + + return fd; + } + + return -1; +} +#else +int tun_create (_unused_ char *name, _unused_ int mq) +{ + for (unsigned dev_id = 0U; dev_id<32U; dev_id++) { + char dev_path[11U]; + + snprintf(dev_path, sizeof(dev_path), "/dev/tun%u", dev_id); + + int fd = open(dev_path, O_RDWR); + + if (fd!=-1) { + printf("tun name: /dev/tun%u\n", dev_id); + return fd; + } + } + + return -1; +} +#endif + +ssize_t tun_read (int fd, void *data, size_t size) +{ + if (!size) + return -2; + +#ifdef GT_BSD_TUN + uint32_t family; + struct iovec iov[2] = { + { .iov_base = &family, .iov_len = sizeof(family) }, + { .iov_base = data, .iov_len = size } + }; + + ssize_t ret = readv(fd, iov, 2); +#else + ssize_t ret = read(fd, data, size); +#endif + + if (ret==-1) { + if (errno==EAGAIN || errno==EINTR) + return -1; + + if (errno) + perror("readv"); + + return 0; + } + +#ifdef GT_BSD_TUN + if (ret<(ssize_t) sizeof(family)) + return 0; + + return ret-sizeof(family); +#else + return ret; +#endif +} + +ssize_t tun_write (int fd, const void *data, size_t size) +{ + if (!size) + return -2; + +#ifdef GT_BSD_TUN + uint32_t family; + + switch (ip_get_version(data, size)) { + case 4: + family = htonl(AF_INET); + break; + case 6: + family = htonl(AF_INET6); + break; + default: + return -1; + } + + struct iovec iov[2] = { + { .iov_base = &family, .iov_len = sizeof(family) }, + { .iov_base = (void *) data, .iov_len = size }, + }; + + ssize_t ret = writev(fd, iov, 2); +#else + ssize_t ret = write(fd, data, size); +#endif + + if (ret==-1) { + if (errno==EAGAIN || errno==EINTR) + return -1; + + if (errno) + perror("write"); + + return 0; + } + +#ifdef GT_BSD_TUN + if (ret<(ssize_t) sizeof(family)) + return 0; + + return ret-sizeof(family); +#else + return ret; +#endif +} diff --git a/src/tun.h b/src/tun.h new file mode 100644 index 0000000..172b332 --- /dev/null +++ b/src/tun.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +int tun_create (char *, int); +ssize_t tun_read (int, void *, size_t); +ssize_t tun_write (int, const void *, size_t);