This commit is contained in:
Adrien Gallouët
2016-12-05 14:47:22 +00:00
parent 0645f0d4d0
commit 0d97df6b50
7 changed files with 272 additions and 220 deletions

View File

@@ -1,11 +1,11 @@
#include "common.h"
#include "tun.h"
#include "str.h"
#include "ip.h"
#include "str.h"
#include "tun.h"
#include <stdio.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
@@ -18,9 +18,9 @@
#endif
#ifdef __APPLE__
#include <sys/sys_domain.h>
#include <sys/kern_control.h>
#include <net/if_utun.h>
#include <sys/kern_control.h>
#include <sys/sys_domain.h>
#endif
#if defined(__APPLE__) || defined(__OpenBSD__)
@@ -29,17 +29,18 @@
#ifdef __APPLE__
static int tun_create_by_id (char *name, size_t size, unsigned id)
static int
tun_create_by_id(char *name, size_t size, unsigned id)
{
int fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
if (fd==-1)
if (fd == -1)
return -1;
struct ctl_info ci;
memset(&ci, 0, sizeof(ci));
str_cpy(ci.ctl_name, UTUN_CONTROL_NAME, sizeof(ci.ctl_name)-1);
str_cpy(ci.ctl_name, UTUN_CONTROL_NAME, sizeof(ci.ctl_name) - 1);
if (ioctl(fd, CTLIOCGINFO, &ci)) {
close(fd);
@@ -51,7 +52,7 @@ static int tun_create_by_id (char *name, size_t size, unsigned id)
.sc_len = sizeof(sc),
.sc_family = AF_SYSTEM,
.ss_sysaddr = AF_SYS_CONTROL,
.sc_unit = id+1,
.sc_unit = id + 1,
};
if (connect(fd, (struct sockaddr *)&sc, sizeof(sc))) {
@@ -64,11 +65,12 @@ static int tun_create_by_id (char *name, size_t size, unsigned id)
return fd;
}
static int tun_create_by_name (char *name, size_t size, char *dev_name)
static int
tun_create_by_name(char *name, size_t size, char *dev_name)
{
unsigned id = 0;
if (sscanf(dev_name, "utun%u", &id)!=1)
if (sscanf(dev_name, "utun%u", &id) != 1)
return -1;
return tun_create_by_id(name, size, id);
@@ -78,44 +80,47 @@ static int tun_create_by_name (char *name, size_t size, char *dev_name)
#ifdef __linux__
static int tun_create_by_name (char *name, size_t size, char *dev_name)
static int
tun_create_by_name(char *name, size_t size, char *dev_name)
{
int fd = open("/dev/net/tun", O_RDWR);
if (fd==-1)
if (fd == -1)
return -1;
struct ifreq ifr = {
.ifr_flags = IFF_TUN|IFF_NO_PI,
.ifr_flags = IFF_TUN | IFF_NO_PI,
};
str_cpy(ifr.ifr_name, dev_name, IFNAMSIZ-1);
str_cpy(ifr.ifr_name, dev_name, IFNAMSIZ - 1);
if (ioctl(fd, TUNSETIFF, &ifr)) {
close(fd);
return -1;
}
str_cpy(name, ifr.ifr_name, size-1);
str_cpy(name, ifr.ifr_name, size - 1);
return fd;
}
#else /* not __linux__ not __APPLE__ */
static int tun_create_by_name (char *name, size_t size, char *dev_name)
static int
tun_create_by_name(char *name, size_t size, char *dev_name)
{
char path[64];
snprintf(path, sizeof(path), "/dev/%s", dev_name);
str_cpy(name, dev_name, size-1);
str_cpy(name, dev_name, size - 1);
return open(path, O_RDWR);
}
#endif /* not __APPLE__ */
static int tun_create_by_id (char *name, size_t size, unsigned id)
static int
tun_create_by_id(char *name, size_t size, unsigned id)
{
char dev_name[64];
@@ -126,25 +131,27 @@ static int tun_create_by_id (char *name, size_t size, unsigned id)
#endif
int tun_create (char *dev_name, char **ret_name)
int
tun_create(char *dev_name, char **ret_name)
{
char name[64] = {0};
int fd = -1;
if (str_empty(dev_name)) {
for (unsigned id=0; id<32 && fd==-1; id++)
for (unsigned id = 0; id < 32 && fd == -1; id++)
fd = tun_create_by_id(name, sizeof(name), id);
} else {
fd = tun_create_by_name(name, sizeof(name), dev_name);
}
if (fd!=-1 && ret_name)
if (fd != -1 && ret_name)
*ret_name = strdup(name);
return fd;
}
ssize_t tun_read (int fd, void *data, size_t size)
ssize_t
tun_read(int fd, void *data, size_t size)
{
if (!size)
return -1;
@@ -153,8 +160,14 @@ ssize_t tun_read (int fd, void *data, size_t size)
uint32_t family;
struct iovec iov[2] = {
{ .iov_base = &family, .iov_len = sizeof(family) },
{ .iov_base = data, .iov_len = size }
{
.iov_base = &family,
.iov_len = sizeof(family),
},
{
.iov_base = data,
.iov_len = size,
},
};
ssize_t ret = readv(fd, iov, 2);
@@ -162,8 +175,8 @@ ssize_t tun_read (int fd, void *data, size_t size)
ssize_t ret = read(fd, data, size);
#endif
if (ret==-1) {
if (errno==EAGAIN || errno==EINTR)
if (ret == -1) {
if (errno == EAGAIN || errno == EINTR)
return -1;
if (errno)
@@ -173,16 +186,17 @@ ssize_t tun_read (int fd, void *data, size_t size)
}
#ifdef GT_BSD_TUN
if (ret<(ssize_t) sizeof(family))
if (ret < (ssize_t)sizeof(family))
return 0;
return ret-sizeof(family);
return ret - sizeof(family);
#else
return ret;
#endif
}
ssize_t tun_write (int fd, const void *data, size_t size)
ssize_t
tun_write(int fd, const void *data, size_t size)
{
if (!size)
return -1;
@@ -202,8 +216,14 @@ ssize_t tun_write (int fd, const void *data, size_t size)
}
struct iovec iov[2] = {
{ .iov_base = &family, .iov_len = sizeof(family) },
{ .iov_base = (void *) data, .iov_len = size },
{
.iov_base = &family,
.iov_len = sizeof(family),
},
{
.iov_base = (void *)data,
.iov_len = size,
},
};
ssize_t ret = writev(fd, iov, 2);
@@ -211,8 +231,8 @@ ssize_t tun_write (int fd, const void *data, size_t size)
ssize_t ret = write(fd, data, size);
#endif
if (ret==-1) {
if (errno==EAGAIN || errno==EINTR)
if (ret == -1) {
if (errno == EAGAIN || errno == EINTR)
return -1;
if (errno)
@@ -222,26 +242,27 @@ ssize_t tun_write (int fd, const void *data, size_t size)
}
#ifdef GT_BSD_TUN
if (ret<(ssize_t) sizeof(family))
if (ret < (ssize_t)sizeof(family))
return 0;
return ret-sizeof(family);
return ret - sizeof(family);
#else
return ret;
#endif
}
int tun_set_mtu (char *dev_name, int mtu)
int
tun_set_mtu(char *dev_name, int mtu)
{
struct ifreq ifr = {
.ifr_mtu = mtu,
};
str_cpy(ifr.ifr_name, dev_name, IFNAMSIZ-1);
str_cpy(ifr.ifr_name, dev_name, IFNAMSIZ - 1);
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd==-1)
if (fd == -1)
return -1;
int ret = ioctl(fd, SIOCSIFMTU, &ifr);