diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-03-22 04:13:01 +0100 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-03-22 04:13:01 +0100 |
commit | d5efe1d64e977e76d38ec4f254396068d8a6cff1 (patch) | |
tree | 26b40291a21231d9f1b8ff047a6c3e62dbb56bc3 /src/tuntap.c | |
parent | 8d8af3aeab9af5b2f84eccc7355e7c9711fae6cb (diff) | |
download | fastd-d5efe1d64e977e76d38ec4f254396068d8a6cff1.tar fastd-d5efe1d64e977e76d38ec4f254396068d8a6cff1.zip |
Rename tuntap to iface to match struct name
Diffstat (limited to 'src/tuntap.c')
-rw-r--r-- | src/tuntap.c | 441 |
1 files changed, 0 insertions, 441 deletions
diff --git a/src/tuntap.c b/src/tuntap.c deleted file mode 100644 index a817090..0000000 --- a/src/tuntap.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - Copyright (c) 2012-2015, Matthias Schiffer <mschiffer@universe-factory.net> - All rights reserved. - - Android port contributor: - Copyright (c) 2014-2015, Haofeng "Rick" Lei <ricklei@gmail.com> - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/** - \file - - Management of the TUN/TAP interface -*/ - -#include "fastd.h" -#include "poll.h" - -#include <net/if.h> -#include <sys/ioctl.h> - -#ifdef __linux__ - -#include <linux/if_tun.h> - -#else - -#ifndef __APPLE__ -#include <net/if_tun.h> -#endif - -#ifdef __FreeBSD__ -#include <net/if_tap.h> -#endif - -#endif - - -/** Defines if the platform uses an address family header on TUN interfaces */ -#if defined(__linux__) || defined(__APPLE__) -static const bool multiaf_tun = false; -#else -static const bool multiaf_tun = true; -#endif - -#ifdef __linux__ - -/** Opens the TUN/TAP device helper shared by Android and Linux targets */ -static void tuntap_open_linux(fastd_iface_t *iface, const char *dev_name) { - struct ifreq ifr = {}; - - iface->fd = FASTD_POLL_FD(POLL_TYPE_IFACE, open(dev_name, O_RDWR|O_NONBLOCK)); - if (iface->fd.fd < 0) - exit_errno("could not open tun/tap device file"); - - if (conf.ifname) - strncpy(ifr.ifr_name, conf.ifname, IFNAMSIZ-1); - - switch (conf.mode) { - case MODE_TAP: - ifr.ifr_flags = IFF_TAP; - break; - - case MODE_TUN: - ifr.ifr_flags = IFF_TUN; - break; - - default: - exit_bug("invalid mode"); - } - - ifr.ifr_flags |= IFF_NO_PI; - if (ioctl(iface->fd.fd, TUNSETIFF, &ifr) < 0) - exit_errno("TUNSETIFF ioctl failed"); - - iface->name = fastd_strndup(ifr.ifr_name, IFNAMSIZ-1); - - int ctl_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (ctl_sock < 0) - exit_errno("socket"); - - if (ioctl(ctl_sock, SIOCGIFMTU, &ifr) < 0) - exit_errno("SIOCGIFMTU ioctl failed"); - - if (ifr.ifr_mtu != conf.mtu) { - ifr.ifr_mtu = conf.mtu; - if (ioctl(ctl_sock, SIOCSIFMTU, &ifr) < 0) - exit_errno("SIOCSIFMTU ioctl failed"); - } - - if (close(ctl_sock)) - pr_error_errno("close"); - -} - -#endif - -#if defined(__ANDROID__) - -/** Opens the TUN/TAP device */ -static void tuntap_open(fastd_iface_t *iface) { - if (conf.android_integration) { - if (conf.mode != MODE_TUN) - exit_error("Non root Android supports only TUN mode"); - - pr_debug("using android TUN fd"); - iface->fd = FASTD_POLL_FD(POLL_TYPE_IFACE, fastd_android_receive_tunfd()); - - fastd_android_send_pid(); - } else { - /* this requires root on Android */ - tuntap_open_linux(iface, "/dev/tun"); - } -} - -#elif defined(__linux__) - -/** Opens the TUN/TAP device */ -static void tuntap_open(fastd_iface_t *iface) { - tuntap_open_linux(iface, "/dev/net/tun"); -} - -#elif defined(__FreeBSD__) || defined(__OpenBSD__) - -/** Sets the MTU of the TUN/TAP device */ -static void set_tun_mtu(fastd_iface_t *iface) { - struct tuninfo tuninfo; - - if (ioctl(iface->fd.fd, TUNGIFINFO, &tuninfo) < 0) - exit_errno("TUNGIFINFO ioctl failed"); - - tuninfo.mtu = conf.mtu; - - if (ioctl(iface->fd.fd, TUNSIFINFO, &tuninfo) < 0) - exit_errno("TUNSIFINFO ioctl failed"); -} - - -#ifdef __FreeBSD__ - -/** Sets the MTU of the TAP device */ -static void set_tap_mtu(fastd_iface_t *iface) { - struct tapinfo tapinfo; - - if (ioctl(iface->fd.fd, TAPGIFINFO, &tapinfo) < 0) - exit_errno("TAPGIFINFO ioctl failed"); - - tapinfo.mtu = conf.mtu; - - if (ioctl(iface->fd.fd, TAPSIFINFO, &tapinfo) < 0) - exit_errno("TAPSIFINFO ioctl failed"); -} - -/** Sets up the TUN device */ -static void setup_tun(fastd_iface_t *iface) { - int one = 1; - if (ioctl(iface->fd.fd, TUNSIFHEAD, &one) < 0) - exit_errno("TUNSIFHEAD ioctl failed"); - - set_tun_mtu(iface); -} - -/** Sets up the TAP device */ -static void setup_tap(fastd_iface_t *iface) { - struct ifreq ifr = {}; - - if (ioctl(iface->fd.fd, TAPGIFNAME, &ifr) < 0) - exit_errno("TAPGIFNAME ioctl failed"); - - free(iface->name); - iface->name = fastd_strndup(ifr.ifr_name, IFNAMSIZ-1); - - set_tap_mtu(iface); -} - -/** Opens the TUN/TAP device */ -static void tuntap_open(fastd_iface_t *iface) { - char ifname[5+IFNAMSIZ] = "/dev/"; - const char *type; - - switch (conf.mode) { - case MODE_TAP: - type = "tap"; - break; - - case MODE_TUN: - type = "tun"; - break; - - default: - exit_bug("invalid mode"); - } - - if (conf.ifname) { - if (strncmp(conf.ifname, type, 3) != 0) - exit_error("`%s' doesn't seem to be a %s device", conf.ifname, type); - - strncat(ifname, conf.ifname, IFNAMSIZ-1); - } - else { - strncat(ifname, type, IFNAMSIZ-1); - } - - iface->fd = FASTD_POLL_FD(POLL_TYPE_IFACE, open(ifname, O_RDWR|O_NONBLOCK)); - if (iface->fd.fd < 0) - exit_errno("could not open tun/tap device file"); - - if (!(iface->name = fdevname_r(iface->fd.fd, fastd_alloc(IFNAMSIZ), IFNAMSIZ))) - exit_errno("could not get tun/tap interface name"); - - switch (conf.mode) { - case MODE_TAP: - setup_tap(iface); - break; - - case MODE_TUN: - setup_tun(iface); - break; - - default: - exit_bug("invalid mode"); - } -} - -#else /* __OpenBSD__ */ - -static void set_link0(fastd_iface_t *iface, bool set) { - struct ifreq ifr = {}; - - int ctl_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (ctl_sock < 0) - exit_errno("socket"); - - strncpy(ifr.ifr_name, iface->name, IFNAMSIZ-1); - if (ioctl(ctl_sock, SIOCGIFFLAGS, &ifr) < 0) - exit_errno("SIOCGIFFLAGS ioctl failed"); - - if (set) - ifr.ifr_flags |= IFF_LINK0; - else - ifr.ifr_flags &= ~IFF_LINK0; - - if (ioctl(ctl_sock, SIOCSIFFLAGS, &ifr) < 0) - exit_errno("SIOCSIFFLAGS ioctl failed"); - - if (close(ctl_sock)) - pr_error_errno("close"); -} - -/** Sets up the TUN device */ -static void setup_tun(fastd_iface_t *iface) { - set_link0(iface, false); - set_tun_mtu(iface); -} - -/** Sets up the TAP device */ -static void setup_tap(fastd_iface_t *iface) { - set_link0(iface, true); - set_tun_mtu(iface); -} - -/** Opens the TUN/TAP device */ -static void tuntap_open(fastd_iface_t *iface) { - char ifname[5+IFNAMSIZ] = "/dev/"; - if (!conf.ifname) - exit_error("config error: no interface name given."); - else if (strncmp(conf.ifname, "tun", 3) != 0) - exit_error("config error: `%s' doesn't seem to be a tun device", conf.ifname); - else - strncat(ifname, conf.ifname, IFNAMSIZ-1); - - iface->fd = FASTD_POLL_FD(POLL_TYPE_IFACE, open(ifname, O_RDWR|O_NONBLOCK)); - if (iface->fd.fd < 0) - exit_errno("could not open tun device file"); - - iface->name = fastd_strndup(conf.ifname, IFNAMSIZ-1); - - switch (conf.mode) { - case MODE_TAP: - setup_tap(iface); - break; - - case MODE_TUN: - setup_tun(iface); - break; - - default: - exit_bug("invalid mode"); - } -} - -#endif - -#elif __APPLE__ - -/** Opens the TUN/TAP device */ -static void tuntap_open(fastd_iface_t *iface) { - const char *devtype; - switch (conf.mode) { - case MODE_TAP: - devtype = "tap"; - break; - - case MODE_TUN: - devtype = "tun"; - break; - - default: - exit_bug("invalid mode"); - } - - char ifname[5+IFNAMSIZ] = "/dev/"; - if (!conf.ifname) - exit_error("config error: no interface name given."); - else if (strncmp(conf.ifname, devtype, 3) != 0) - exit_error("config error: `%s' doesn't seem to be a %s device", conf.ifname, devtype); - else - strncat(ifname, conf.ifname, IFNAMSIZ-1); - - iface->fd = FASTD_POLL_FD(POLL_TYPE_IFACE, open(ifname, O_RDWR|O_NONBLOCK)); - if (iface->fd.fd < 0) - exit_errno("could not open tun device file"); - - iface->name = fastd_strndup(conf.ifname, IFNAMSIZ-1); - - int ctl_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (ctl_sock < 0) - exit_errno("socket"); - - struct ifreq ifr = {}; - strncpy(ifr.ifr_name, conf.ifname, IFNAMSIZ-1); - ifr.ifr_mtu = conf.mtu; - if (ioctl(ctl_sock, SIOCSIFMTU, &ifr) < 0) - exit_errno("SIOCSIFMTU ioctl failed"); - - if (close(ctl_sock)) - pr_error_errno("close"); -} - -#else - -#error unknown tun/tap implementation - -#endif - - -/** Reads a packet from the TUN/TAP device */ -void fastd_tuntap_handle(fastd_iface_t *iface) { - size_t max_len = fastd_max_payload(); - - fastd_buffer_t buffer; - if (multiaf_tun && conf.mode == MODE_TUN) - buffer = fastd_buffer_alloc(max_len+4, conf.min_encrypt_head_space+12, conf.min_encrypt_tail_space); - else - buffer = fastd_buffer_alloc(max_len, conf.min_encrypt_head_space, conf.min_encrypt_tail_space); - - ssize_t len = read(iface->fd.fd, buffer.data, max_len); - if (len < 0) - exit_errno("read"); - - buffer.len = len; - - if (multiaf_tun && conf.mode == MODE_TUN) - fastd_buffer_push_head(&buffer, 4); - - fastd_send_data(buffer, iface->peer); -} - -/** Writes a packet to the TUN/TAP device */ -void fastd_tuntap_write(fastd_iface_t *iface, fastd_buffer_t buffer) { - if (multiaf_tun && conf.mode == MODE_TUN) { - uint8_t version = *((uint8_t *)buffer.data) >> 4; - uint32_t af; - - switch (version) { - case 4: - af = htonl(AF_INET); - break; - - case 6: - af = htonl(AF_INET6); - break; - - default: - pr_warn("fastd_tuntap_write: unknown IP version %u", version); - return; - } - - fastd_buffer_pull_head(&buffer, 4); - memcpy(buffer.data, &af, 4); - } - - if (write(iface->fd.fd, buffer.data, buffer.len) < 0) - pr_debug2_errno("write"); -} - -fastd_iface_t * fastd_tuntap_open(fastd_peer_t *peer) { - fastd_iface_t *iface = fastd_new(fastd_iface_t); - iface->peer = peer; - - pr_debug("initializing tun/tap device..."); - tuntap_open(iface); - - if (iface->name) - pr_debug("tun/tap device `%s' initialized.", iface->name); - else - pr_debug("tun/tap device initialized."); - - fastd_poll_fd_register(&iface->fd); - - return iface; -} - -/** Closes the TUN/TAP device */ -void fastd_tuntap_close(fastd_iface_t *iface) { - if (!fastd_poll_fd_close(&iface->fd)) - pr_warn_errno("closing tun/tap: close"); - - free(iface->name); - free(iface); -} |