X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fbsd%2Fdevice.c;h=c91eb5e2079dc7867c971d0a6cd16d9bdc720118;hp=4dd2b57fd3b7733a8ed5453303dfd78367763552;hb=8793fb7d43161f4d5358ff73b7a4937ad7e642e2;hpb=4c85542894f7fca823b119b05e07179deb24229a diff --git a/src/bsd/device.c b/src/bsd/device.c index 4dd2b57f..c91eb5e2 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -1,7 +1,8 @@ /* device.c -- Interaction BSD tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2009 Guus Sliepen + 2001-2012 Guus Sliepen + 2009 Grzegorz Dymarek This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,6 +22,7 @@ #include "system.h" #include "conf.h" +#include "device.h" #include "logger.h" #include "net.h" #include "route.h" @@ -31,7 +33,12 @@ #include "bsd/tunemu.h" #endif -#define DEFAULT_DEVICE "/dev/tun0" +#define DEFAULT_TUN_DEVICE "/dev/tun0" +#if defined(HAVE_FREEBSD) || defined(HAVE_NETBSD) +#define DEFAULT_TAP_DEVICE "/dev/tap0" +#else +#define DEFAULT_TAP_DEVICE "/dev/tun0" +#endif typedef enum device_type { DEVICE_TYPE_TUN, @@ -46,24 +53,28 @@ int device_fd = -1; char *device = NULL; char *iface = NULL; static char *device_info = NULL; -static int device_total_in = 0; -static int device_total_out = 0; +static uint64_t device_total_in = 0; +static uint64_t device_total_out = 0; #if defined(TUNEMU) static device_type_t device_type = DEVICE_TYPE_TUNEMU; -#elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) +#elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY) static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD; #else static device_type_t device_type = DEVICE_TYPE_TUN; #endif -bool setup_device(void) { +static bool setup_device(void) { char *type; - 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(rindex(device, '/') ? rindex(device, '/') + 1 : device); + iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device); if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(!strcasecmp(type, "tun")) @@ -104,6 +115,10 @@ bool setup_device(void) { return false; } +#ifdef FD_CLOEXEC + fcntl(device_fd, F_SETFD, FD_CLOEXEC); +#endif + switch(device_type) { default: device_type = DEVICE_TYPE_TUN; @@ -149,6 +164,17 @@ bool setup_device(void) { if(routing_mode == RMODE_ROUTER) overwrite_mac = true; device_info = "Generic BSD tap device"; +#ifdef TAPGIFNAME + { + struct ifreq ifr; + if(ioctl(device_fd, TAPGIFNAME, (void*)&ifr) == 0) { + if(iface) + free(iface); + iface = xstrdup(ifr.ifr_name); + } + } + +#endif break; #ifdef HAVE_TUNEMU case DEVICE_TYPE_TUNEMU: @@ -162,7 +188,7 @@ bool setup_device(void) { return true; } -void close_device(void) { +static void close_device(void) { switch(device_type) { #ifdef HAVE_TUNEMU case DEVICE_TYPE_TUNEMU: @@ -177,7 +203,7 @@ 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) { @@ -187,9 +213,8 @@ bool read_packet(vpn_packet_t *packet) { if(device_type == DEVICE_TYPE_TUNEMU) lenin = tunemu_read(device_fd, packet->data + 14, MTU - 14); else -#else - lenin = read(device_fd, packet->data + 14, MTU - 14); #endif + lenin = read(device_fd, packet->data + 14, MTU - 14); if(lenin <= 0) { logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, @@ -208,11 +233,12 @@ bool read_packet(vpn_packet_t *packet) { break; default: ifdebug(TRAFFIC) logger(LOG_ERR, - _ ("Unknown IP version %d while reading packet from %s %s"), + "Unknown IP version %d while reading packet from %s %s", packet->data[14] >> 4, device_info, device); return false; } + memset(packet->data, 0, 12); packet->len = lenin + 14; break; @@ -239,11 +265,12 @@ bool read_packet(vpn_packet_t *packet) { default: ifdebug(TRAFFIC) logger(LOG_ERR, - _ ("Unknown address family %x while reading packet from %s %s"), + "Unknown address family %x while reading packet from %s %s", ntohl(type), device_info, device); return false; } + memset(packet->data, 0, 12); packet->len = lenin + 10; break; } @@ -267,11 +294,10 @@ bool read_packet(vpn_packet_t *packet) { ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info); - logger(LOG_INFO, "E:fd_read"); 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); @@ -340,8 +366,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: %10d", device_total_in); - logger(LOG_DEBUG, " total bytes out: %10d", device_total_out); + 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, +};