X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fbsd%2Fdevice.c;h=62e7e84b8e216f529f2075acea090798640807e9;hp=f6614b29a0b5e13e309fc2b9578e04d745a06b93;hb=3fae14fae5a347823679ef694ab630b4991a201d;hpb=985d19caf20058db3c764f0f6fbeafa8bcc59fcc;ds=sidebyside diff --git a/src/bsd/device.c b/src/bsd/device.c index f6614b29..62e7e84b 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -69,12 +69,14 @@ static device_type_t device_type = DEVICE_TYPE_TUN; #ifdef HAVE_NET_IF_UTUN_H static bool setup_utun(void) { device_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); + if(device_fd == -1) { logger(LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno)); return false; } struct ctl_info info = {}; + strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name)); if(ioctl(device_fd, CTLIOCGINFO, &info) == -1) { @@ -84,10 +86,13 @@ static bool setup_utun(void) { int unit = -1; char *p = strstr(device, "utun"), *e = NULL; + if(p) { unit = strtol(p + 4, &e, 10); - if(!e) + + if(!e) { unit = -1; + } } struct sockaddr_ctl sc = { @@ -105,6 +110,7 @@ static bool setup_utun(void) { char name[64] = ""; socklen_t len = sizeof(name); + if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) { iface = xstrdup(device); } else { @@ -123,10 +129,11 @@ static bool setup_device(void) { // Find out which device file to open if(!get_config_string(lookup_config(config_tree, "Device"), &device)) { - if(routing_mode == RMODE_ROUTER) + if(routing_mode == RMODE_ROUTER) { device = xstrdup(DEFAULT_TUN_DEVICE); - else + } else { device = xstrdup(DEFAULT_TAP_DEVICE); + } } // Find out if it's supposed to be a tun or a tap device @@ -135,33 +142,40 @@ static bool setup_device(void) { if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(!strcasecmp(type, "tun")) - /* use default */; + /* use default */; + #ifdef ENABLE_TUNEMU - else if(!strcasecmp(type, "tunemu")) + else if(!strcasecmp(type, "tunemu")) { device_type = DEVICE_TYPE_TUNEMU; + } + #endif #ifdef HAVE_NET_IF_UTUN_H - else if(!strcasecmp(type, "utun")) + else if(!strcasecmp(type, "utun")) { device_type = DEVICE_TYPE_UTUN; + } + #endif - else if(!strcasecmp(type, "tunnohead")) + else if(!strcasecmp(type, "tunnohead")) { device_type = DEVICE_TYPE_TUN; - else if(!strcasecmp(type, "tunifhead")) + } else if(!strcasecmp(type, "tunifhead")) { device_type = DEVICE_TYPE_TUNIFHEAD; - else if(!strcasecmp(type, "tap")) + } else if(!strcasecmp(type, "tap")) { device_type = DEVICE_TYPE_TAP; - else { + } else { logger(LOG_ERR, "Unknown device type %s!", type); return false; } } else { #ifdef HAVE_NET_IF_UTUN_H - if(strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0) + + if(strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0) { device_type = DEVICE_TYPE_UTUN; - else + } else #endif - if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) - device_type = DEVICE_TYPE_TAP; + if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) { + device_type = DEVICE_TYPE_TAP; + } } if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) { @@ -173,18 +187,21 @@ static bool setup_device(void) { switch(device_type) { #ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: { - char dynamic_name[256] = ""; - device_fd = tunemu_open(dynamic_name); - } - break; + + case DEVICE_TYPE_TUNEMU: { + char dynamic_name[256] = ""; + device_fd = tunemu_open(dynamic_name); + } + break; #endif #ifdef HAVE_NET_IF_UTUN_H - case DEVICE_TYPE_UTUN: - return setup_utun(); + + case DEVICE_TYPE_UTUN: + return setup_utun(); #endif - default: - device_fd = open(device, O_RDWR | O_NONBLOCK); + + default: + device_fd = open(device, O_RDWR | O_NONBLOCK); } if(device_fd < 0) { @@ -204,32 +221,40 @@ static bool setup_device(void) { realname = fdevname(device_fd); #elif defined(HAVE_DEVNAME) struct stat buf; - if(!fstat(device_fd, &buf)) + + if(!fstat(device_fd, &buf)) { realname = devname(buf.st_rdev, S_IFCHR); + } + #endif - if(!realname) + if(!realname) { realname = device; + } - if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) + 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)) + } 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; - case DEVICE_TYPE_TUN: + default: + device_type = DEVICE_TYPE_TUN; + + case DEVICE_TYPE_TUN: #ifdef TUNSIFHEAD - { + { const int zero = 0; + if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof(zero)) == -1) { logger(LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); return false; } } + #endif #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) { @@ -238,53 +263,66 @@ static bool setup_device(void) { } #endif - device_info = "Generic BSD tun device"; - break; - case DEVICE_TYPE_TUNIFHEAD: + device_info = "Generic BSD tun device"; + break; + + case DEVICE_TYPE_TUNIFHEAD: #ifdef TUNSIFHEAD { const int one = 1; + if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof(one)) == -1) { logger(LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); return false; } } + #endif #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) { - const int mode = IFF_BROADCAST | IFF_MULTICAST; - ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode)); + const int mode = IFF_BROADCAST | IFF_MULTICAST; + ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode)); } #endif - device_info = "Generic BSD tun device"; - break; - case DEVICE_TYPE_TAP: - if(routing_mode == RMODE_ROUTER) - overwrite_mac = true; - device_info = "Generic BSD tap device"; + device_info = "Generic BSD tun device"; + break; + + case DEVICE_TYPE_TAP: + 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); + { + struct ifreq ifr; + + if(ioctl(device_fd, TAPGIFNAME, (void *)&ifr) == 0) { + if(iface) { + free(iface); } + + iface = xstrdup(ifr.ifr_name); } - + } + #endif - break; + break; #ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - device_info = "BSD tunemu device"; - break; + + case DEVICE_TYPE_TUNEMU: + device_info = "BSD tunemu device"; + break; #endif } #ifdef SIOCGIFADDR - if(overwrite_mac) + + if(overwrite_mac) { ioctl(device_fd, SIOCGIFADDR, mymac.x); + } + #endif logger(LOG_INFO, "%s is a %s", device, device_info); @@ -295,12 +333,14 @@ static bool setup_device(void) { static void close_device(void) { switch(device_type) { #ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - tunemu_close(device_fd); - break; + + case DEVICE_TYPE_TUNEMU: + tunemu_close(device_fd); + break; #endif - default: - close(device_fd); + + default: + close(device_fd); } free(device); @@ -311,154 +351,165 @@ static bool read_packet(vpn_packet_t *packet) { int lenin; switch(device_type) { - case DEVICE_TYPE_TUN: + case DEVICE_TYPE_TUN: #ifdef ENABLE_TUNEMU - case DEVICE_TYPE_TUNEMU: - if(device_type == DEVICE_TYPE_TUNEMU) - lenin = tunemu_read(device_fd, packet->data + 14, MTU - 14); - else + case DEVICE_TYPE_TUNEMU: + if(device_type == DEVICE_TYPE_TUNEMU) { + lenin = tunemu_read(device_fd, packet->data + 14, MTU - 14); + } else #endif - lenin = read(device_fd, packet->data + 14, MTU - 14); + lenin = read(device_fd, packet->data + 14, MTU - 14); - if(lenin <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } + if(lenin <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; + } - switch(packet->data[14] >> 4) { - case 4: - packet->data[12] = 0x08; - packet->data[13] = 0x00; - break; - case 6: - packet->data[12] = 0x86; - packet->data[13] = 0xDD; - break; - default: - ifdebug(TRAFFIC) logger(LOG_ERR, - "Unknown IP version %d while reading packet from %s %s", - packet->data[14] >> 4, device_info, device); - return false; - } + switch(packet->data[14] >> 4) { + case 4: + packet->data[12] = 0x08; + packet->data[13] = 0x00; + break; - memset(packet->data, 0, 12); - packet->len = lenin + 14; + case 6: + packet->data[12] = 0x86; + packet->data[13] = 0xDD; break; - case DEVICE_TYPE_UTUN: - case DEVICE_TYPE_TUNIFHEAD: { - if((lenin = read(device_fd, packet->data + 10, MTU - 10)) <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } + default: + ifdebug(TRAFFIC) logger(LOG_ERR, + "Unknown IP version %d while reading packet from %s %s", + packet->data[14] >> 4, device_info, device); + return false; + } - switch(packet->data[14] >> 4) { - case 4: - packet->data[12] = 0x08; - packet->data[13] = 0x00; - break; - case 6: - packet->data[12] = 0x86; - packet->data[13] = 0xDD; - break; - default: - ifdebug(TRAFFIC) logger(LOG_ERR, - "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; - memset(packet->data, 0, 12); - packet->len = lenin + 10; - break; + case DEVICE_TYPE_UTUN: + case DEVICE_TYPE_TUNIFHEAD: { + if((lenin = read(device_fd, packet->data + 10, MTU - 10)) <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); + return false; } - case DEVICE_TYPE_TAP: - if((lenin = read(device_fd, packet->data, MTU)) <= 0) { - logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, - device, strerror(errno)); - return false; - } + switch(packet->data[14] >> 4) { + case 4: + packet->data[12] = 0x08; + packet->data[13] = 0x00; + break; - packet->len = lenin; + case 6: + packet->data[12] = 0x86; + packet->data[13] = 0xDD; break; default: + ifdebug(TRAFFIC) logger(LOG_ERR, + "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 + 10; + break; + } + + case DEVICE_TYPE_TAP: + if((lenin = read(device_fd, packet->data, MTU)) <= 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, + device, strerror(errno)); return false; + } + + packet->len = lenin; + break; + + default: + return false; } - + device_total_in += packet->len; ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", - packet->len, device_info); + packet->len, device_info); return true; } static bool write_packet(vpn_packet_t *packet) { ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s", - packet->len, device_info); + packet->len, device_info); switch(device_type) { - case DEVICE_TYPE_TUN: - if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { - logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } - break; + case DEVICE_TYPE_TUN: + if(write(device_fd, packet->data + 14, packet->len - 14) < 0) { + logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, + device, strerror(errno)); + return false; + } - case DEVICE_TYPE_UTUN: - case DEVICE_TYPE_TUNIFHEAD: { - int af = (packet->data[12] << 8) + packet->data[13]; - uint32_t type; - - switch (af) { - case 0x0800: - type = htonl(AF_INET); - break; - case 0x86DD: - type = htonl(AF_INET6); - break; - default: - ifdebug(TRAFFIC) logger(LOG_ERR, - "Unknown address family %x while writing packet to %s %s", - af, device_info, device); - return false; - } + break; - memcpy(packet->data + 10, &type, sizeof(type)); + case DEVICE_TYPE_UTUN: + case DEVICE_TYPE_TUNIFHEAD: { + int af = (packet->data[12] << 8) + packet->data[13]; + uint32_t type; - if(write(device_fd, packet->data + 10, packet->len - 10) < 0) { - logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, - strerror(errno)); - return false; - } - break; - } - - case DEVICE_TYPE_TAP: - if(write(device_fd, packet->data, packet->len) < 0) { - logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, - device, strerror(errno)); - return false; - } + switch(af) { + case 0x0800: + type = htonl(AF_INET); break; -#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, - device, strerror(errno)); - return false; - } + case 0x86DD: + type = htonl(AF_INET6); break; -#endif default: + ifdebug(TRAFFIC) logger(LOG_ERR, + "Unknown address family %x while writing packet to %s %s", + af, device_info, device); + return false; + } + + memcpy(packet->data + 10, &type, sizeof(type)); + + if(write(device_fd, packet->data + 10, packet->len - 10) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, + strerror(errno)); + return false; + } + + break; + } + + case DEVICE_TYPE_TAP: + if(write(device_fd, packet->data, packet->len) < 0) { + logger(LOG_ERR, "Error while writing to %s %s: %s", device_info, + device, strerror(errno)); return false; + } + + break; + +#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, + device, strerror(errno)); + return false; + } + + break; +#endif + + default: + return false; } device_total_out += packet->len;