summaryrefslogtreecommitdiffstats
path: root/src/tuntap.c
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2015-03-22 04:13:01 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2015-03-22 04:13:01 +0100
commitd5efe1d64e977e76d38ec4f254396068d8a6cff1 (patch)
tree26b40291a21231d9f1b8ff047a6c3e62dbb56bc3 /src/tuntap.c
parent8d8af3aeab9af5b2f84eccc7355e7c9711fae6cb (diff)
downloadfastd-d5efe1d64e977e76d38ec4f254396068d8a6cff1.tar
fastd-d5efe1d64e977e76d38ec4f254396068d8a6cff1.zip
Rename tuntap to iface to match struct name
Diffstat (limited to 'src/tuntap.c')
-rw-r--r--src/tuntap.c441
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);
-}