X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fbsd%2Fdevice.c;h=70e0b0b12fee0646dced9a624a0d98e6d2ed500f;hp=d6ef0e8259f6141999e66226b121696da2d2d6fc;hb=ac685f112deb7eafc047c718da094a8b160182ad;hpb=67766d65f06854ee894d784f638c5c9cd2b50bca diff --git a/src/bsd/device.c b/src/bsd/device.c index d6ef0e82..70e0b0b1 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction BSD tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2011 Guus Sliepen + 2001-2016 Guus Sliepen 2009 Grzegorz Dymarek This program is free software; you can redistribute it and/or modify @@ -19,26 +19,28 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" -#include "conf.h" -#include "logger.h" -#include "net.h" -#include "route.h" -#include "utils.h" -#include "xalloc.h" +#include "../conf.h" +#include "../device.h" +#include "../logger.h" +#include "../net.h" +#include "../route.h" +#include "../utils.h" +#include "../xalloc.h" -#ifdef HAVE_TUNEMU -#include "bsd/tunemu.h" +#ifdef ENABLE_TUNEMU +#include "tunemu.h" #endif -#define DEFAULT_DEVICE "/dev/tun0" +#define DEFAULT_TUN_DEVICE "/dev/tun0" +#define DEFAULT_TAP_DEVICE "/dev/tap0" typedef enum device_type { DEVICE_TYPE_TUN, DEVICE_TYPE_TUNIFHEAD, DEVICE_TYPE_TAP, -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU DEVICE_TYPE_TUNEMU, #endif } device_type_t; @@ -49,7 +51,7 @@ char *iface = NULL; static char *device_info = NULL; static uint64_t device_total_in = 0; static uint64_t device_total_out = 0; -#if defined(TUNEMU) +#if defined(ENABLE_TUNEMU) static device_type_t device_type = DEVICE_TYPE_TUNEMU; #elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY) static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD; @@ -57,19 +59,24 @@ static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD; static device_type_t device_type = DEVICE_TYPE_TUN; #endif -bool setup_device(void) { - char *type; +static bool setup_device(void) { + // Find out which device file to open - if(!get_config_string(lookup_config(config_tree, "Device"), &device)) - device = xstrdup(DEFAULT_DEVICE); + if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { + if(routing_mode == RMODE_ROUTER) + device = xstrdup(DEFAULT_TUN_DEVICE); + else + device = xstrdup(DEFAULT_TAP_DEVICE); + } - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) - iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); + // Find out if it's supposed to be a tun or a tap device + + char *type; if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(!strcasecmp(type, "tun")) /* use default */; -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU else if(!strcasecmp(type, "tunemu")) device_type = DEVICE_TYPE_TUNEMU; #endif @@ -88,8 +95,10 @@ bool setup_device(void) { device_type = DEVICE_TYPE_TAP; } + // Open the device + switch(device_type) { -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: { char dynamic_name[256] = ""; device_fd = tunemu_open(dynamic_name); @@ -105,6 +114,31 @@ bool setup_device(void) { return false; } +#ifdef FD_CLOEXEC + fcntl(device_fd, F_SETFD, FD_CLOEXEC); +#endif + + // Guess what the corresponding interface is called + + char *realname; + +#if defined(HAVE_FDEVNAME) + realname = fdevname(device_fd) ? : device; +#elif defined(HAVE_DEVNAME) + struct stat buf; + if(!fstat(device_fd, &buf)) + realname = devname(buf.st_rdev, S_IFCHR) ? : device; +#else + realname = device; +#endif + + if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) + iface = xstrdup(strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname); + else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) + logger(LOG_WARNING, "Warning: Interface does not match Device. $INTERFACE might be set incorrectly."); + + // Configure the device as best as we can + switch(device_type) { default: device_type = DEVICE_TYPE_TUN; @@ -162,7 +196,7 @@ bool setup_device(void) { #endif break; -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: device_info = "BSD tunemu device"; break; @@ -174,9 +208,9 @@ bool setup_device(void) { return true; } -void close_device(void) { +static void close_device(void) { switch(device_type) { -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: tunemu_close(device_fd); break; @@ -189,12 +223,12 @@ void close_device(void) { free(iface); } -bool read_packet(vpn_packet_t *packet) { +static bool read_packet(vpn_packet_t *packet) { int lenin; switch(device_type) { case DEVICE_TYPE_TUN: -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: if(device_type == DEVICE_TYPE_TUNEMU) lenin = tunemu_read(device_fd, packet->data + 14, MTU - 14); @@ -224,6 +258,7 @@ bool read_packet(vpn_packet_t *packet) { return false; } + memset(packet->data, 0, 12); packet->len = lenin + 14; break; @@ -255,6 +290,7 @@ bool read_packet(vpn_packet_t *packet) { return false; } + memset(packet->data, 0, 12); packet->len = lenin + 10; break; } @@ -281,7 +317,7 @@ bool read_packet(vpn_packet_t *packet) { return true; } -bool write_packet(vpn_packet_t *packet) { +static bool write_packet(vpn_packet_t *packet) { ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); @@ -331,7 +367,7 @@ bool write_packet(vpn_packet_t *packet) { } break; -#ifdef HAVE_TUNEMU +#ifdef ENABLE_TUNEMU case DEVICE_TYPE_TUNEMU: if(tunemu_write(device_fd, packet->data + 14, packet->len - 14) < 0) { logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, @@ -350,8 +386,16 @@ bool write_packet(vpn_packet_t *packet) { return true; } -void dump_device_stats(void) { +static void dump_device_stats(void) { logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device); logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in); logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out); } + +const devops_t os_devops = { + .setup = setup_device, + .close = close_device, + .read = read_packet, + .write = write_packet, + .dump_stats = dump_device_stats, +};