diff options
Diffstat (limited to 'src/libstrongswan/utils')
-rw-r--r-- | src/libstrongswan/utils/packet.c | 163 | ||||
-rw-r--r-- | src/libstrongswan/utils/packet.h | 121 | ||||
-rw-r--r-- | src/libstrongswan/utils/tun_device.c | 461 | ||||
-rw-r--r-- | src/libstrongswan/utils/tun_device.h | 112 |
4 files changed, 0 insertions, 857 deletions
diff --git a/src/libstrongswan/utils/packet.c b/src/libstrongswan/utils/packet.c deleted file mode 100644 index a2c329d60..000000000 --- a/src/libstrongswan/utils/packet.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2012 Tobias Brunner - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter - * Hochschule fuer Technik Rapperswil - * - * 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 the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include "packet.h" - -typedef struct private_packet_t private_packet_t; - -/** - * Private data of an packet_t object. - */ -struct private_packet_t { - - /** - * Public part of a packet_t object. - */ - packet_t public; - - /** - * source address - */ - host_t *source; - - /** - * destination address - */ - host_t *destination; - - /** - * message data - */ - chunk_t data; - - /** - * actual chunk returned from get_data, adjusted when skip_bytes is called - */ - chunk_t adjusted_data; -}; - -METHOD(packet_t, set_source, void, - private_packet_t *this, host_t *source) -{ - DESTROY_IF(this->source); - this->source = source; -} - -METHOD(packet_t, set_destination, void, - private_packet_t *this, host_t *destination) -{ - DESTROY_IF(this->destination); - this->destination = destination; -} - -METHOD(packet_t, get_source, host_t*, - private_packet_t *this) -{ - return this->source; -} - -METHOD(packet_t, get_destination, host_t*, - private_packet_t *this) -{ - return this->destination; -} - -METHOD(packet_t, get_data, chunk_t, - private_packet_t *this) -{ - return this->adjusted_data; -} - -METHOD(packet_t, set_data, void, - private_packet_t *this, chunk_t data) -{ - free(this->data.ptr); - this->adjusted_data = this->data = data; -} - -METHOD(packet_t, skip_bytes, void, - private_packet_t *this, size_t bytes) -{ - this->adjusted_data = chunk_skip(this->adjusted_data, bytes); -} - -METHOD(packet_t, destroy, void, - private_packet_t *this) -{ - DESTROY_IF(this->source); - DESTROY_IF(this->destination); - free(this->data.ptr); - free(this); -} - -METHOD(packet_t, clone_, packet_t*, - private_packet_t *this) -{ - packet_t *other; - - other = packet_create(); - if (this->destination) - { - other->set_destination(other, - this->destination->clone(this->destination)); - } - if (this->source) - { - other->set_source(other, this->source->clone(this->source)); - } - if (this->data.ptr) - { - other->set_data(other, chunk_clone(this->adjusted_data)); - } - return other; -} - -/** - * Described in header. - */ -packet_t *packet_create_from_data(host_t *src, host_t *dst, chunk_t data) -{ - private_packet_t *this; - - INIT(this, - .public = { - .set_data = _set_data, - .get_data = _get_data, - .set_source = _set_source, - .get_source = _get_source, - .set_destination = _set_destination, - .get_destination = _get_destination, - .skip_bytes = _skip_bytes, - .clone = _clone_, - .destroy = _destroy, - }, - .source = src, - .destination = dst, - .adjusted_data = data, - .data = data, - ); - - return &this->public; -} - -/* - * Described in header. - */ -packet_t *packet_create() -{ - return packet_create_from_data(NULL, NULL, chunk_empty); -} diff --git a/src/libstrongswan/utils/packet.h b/src/libstrongswan/utils/packet.h deleted file mode 100644 index b6e28199a..000000000 --- a/src/libstrongswan/utils/packet.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2012 Tobias Brunner - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter - * Hochschule fuer Technik Rapperswil - * - * 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 the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -/** - * @defgroup packet packet - * @{ @ingroup utils - */ - -#ifndef PACKET_H_ -#define PACKET_H_ - -typedef struct packet_t packet_t; - -#include <library.h> -#include <networking/host.h> - -/** - * Abstraction of an IP/UDP-Packet, contains data, sender and receiver. - */ -struct packet_t { - - /** - * Set the source address. - * - * @param source address to set as source (gets owned) - */ - void (*set_source)(packet_t *packet, host_t *source); - - /** - * Set the destination address. - * - * @param source address to set as destination (gets owned) - */ - void (*set_destination)(packet_t *packet, host_t *destination); - - /** - * Get the source address. - * - * @return source address (internal data) - */ - host_t *(*get_source)(packet_t *packet); - - /** - * Get the destination address. - * - * @return destination address (internal data) - */ - host_t *(*get_destination)(packet_t *packet); - - /** - * Get the data from the packet. - * - * @return chunk containing the data (internal data) - */ - chunk_t (*get_data)(packet_t *packet); - - /** - * Set the data in the packet. - * - * @param data chunk with data to set (gets owned) - */ - void (*set_data)(packet_t *packet, chunk_t data); - - /** - * Increase the offset where the actual packet data starts. - * - * The total offset applies to future calls of get_data() and clone(). - * - * @note The offset is reset to 0 when set_data() is called. - * - * @param bytes the number of additional bytes to skip - */ - void (*skip_bytes)(packet_t *packet, size_t bytes); - - /** - * Clones a packet_t object. - * - * @note Data is cloned without skipped bytes. - * - * @param clone clone of the packet - */ - packet_t* (*clone)(packet_t *packet); - - /** - * Destroy the packet, freeing contained data. - */ - void (*destroy)(packet_t *packet); -}; - -/** - * Create an empty packet - * - * @return packet_t object - */ -packet_t *packet_create(); - -/** - * Create a packet from the supplied data - * - * @param src source address (gets owned) - * @param dst destination address (gets owned) - * @param data packet data (gets owned) - * @return packet_t object - */ -packet_t *packet_create_from_data(host_t *src, host_t *dst, chunk_t data); - -#endif /** PACKET_H_ @}*/ diff --git a/src/libstrongswan/utils/tun_device.c b/src/libstrongswan/utils/tun_device.c deleted file mode 100644 index 36f3359c0..000000000 --- a/src/libstrongswan/utils/tun_device.c +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright (C) 2012 Tobias Brunner - * Copyright (C) 2012 Giuliano Grassi - * Copyright (C) 2012 Ralf Sager - * Hochschule fuer Technik Rapperswil - * Copyright (C) 2012 Martin Willi - * - * 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 the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include <errno.h> -#include <fcntl.h> -#include <netinet/in.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <unistd.h> -#include <net/if.h> - -#ifdef __APPLE__ -#include <net/if_utun.h> -#include <netinet/in_var.h> -#include <sys/kern_control.h> -#elif defined(__linux__) -#include <linux/if_tun.h> -#else -#include <net/if_tun.h> -#endif - -#include "tun_device.h" - -#include <library.h> -#include <debug.h> -#include <threading/thread.h> - -#define TUN_DEFAULT_MTU 1500 - -typedef struct private_tun_device_t private_tun_device_t; - -struct private_tun_device_t { - - /** - * Public interface - */ - tun_device_t public; - - /** - * The TUN device's file descriptor - */ - int tunfd; - - /** - * Name of the TUN device - */ - char if_name[IFNAMSIZ]; - - /** - * Socket used for ioctl() to set interface addr, ... - */ - int sock; - - /** - * The current MTU - */ - int mtu; -}; - -/** - * Set the sockaddr_t from the given netmask - */ -static void set_netmask(struct ifreq *ifr, int family, u_int8_t netmask) -{ - int len, bytes, bits; - char *target; - - switch (family) - { - case AF_INET: - { - struct sockaddr_in *addr = (struct sockaddr_in*)&ifr->ifr_addr; - addr->sin_family = AF_INET; - target = (char*)&addr->sin_addr; - len = 4; - break; - } - case AF_INET6: - { - struct sockaddr_in6 *addr = (struct sockaddr_in6*)&ifr->ifr_addr; - addr->sin6_family = AF_INET6; - target = (char*)&addr->sin6_addr; - len = 16; - break; - } - default: - return; - } - - bytes = (netmask + 7) / 8; - bits = (bytes * 8) - netmask; - - memset(target, 0xff, bytes); - memset(target + bytes, 0x00, len - bytes); - target[bytes - 1] = bits ? (u_int8_t)(0xff << bits) : 0xff; -} - -METHOD(tun_device_t, set_address, bool, - private_tun_device_t *this, host_t *addr, u_int8_t netmask) -{ - struct ifreq ifr; - int family; - - family = addr->get_family(addr); - if ((netmask > 32 && family == AF_INET) || netmask > 128) - { - DBG1(DBG_LIB, "failed to set address on %s: invalid netmask", - this->if_name); - return FALSE; - } - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ); - memcpy(&ifr.ifr_addr, addr->get_sockaddr(addr), sizeof(sockaddr_t)); - - if (ioctl(this->sock, SIOCSIFADDR, &ifr) < 0) - { - DBG1(DBG_LIB, "failed to set address on %s: %s", - this->if_name, strerror(errno)); - return FALSE; - } -#ifdef __APPLE__ - if (ioctl(this->sock, SIOCSIFDSTADDR, &ifr) < 0) - { - DBG1(DBG_LIB, "failed to set dest address on %s: %s", - this->if_name, strerror(errno)); - return FALSE; - } -#endif /* __APPLE__ */ - - set_netmask(&ifr, family, netmask); - - if (ioctl(this->sock, SIOCSIFNETMASK, &ifr) < 0) - { - DBG1(DBG_LIB, "failed to set netmask on %s: %s", - this->if_name, strerror(errno)); - return FALSE; - } - return TRUE; -} - -METHOD(tun_device_t, up, bool, - private_tun_device_t *this) -{ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ); - - if (ioctl(this->sock, SIOCGIFFLAGS, &ifr) < 0) - { - DBG1(DBG_LIB, "failed to get interface flags for %s: %s", this->if_name, - strerror(errno)); - return FALSE; - } - - ifr.ifr_flags |= IFF_RUNNING | IFF_UP; - - if (ioctl(this->sock, SIOCSIFFLAGS, &ifr) < 0) - { - DBG1(DBG_LIB, "failed to set interface flags on %s: %s", this->if_name, - strerror(errno)); - return FALSE; - } - return TRUE; -} - -METHOD(tun_device_t, set_mtu, bool, - private_tun_device_t *this, int mtu) -{ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ); - ifr.ifr_mtu = mtu; - - if (ioctl(this->sock, SIOCSIFMTU, &ifr) < 0) - { - DBG1(DBG_LIB, "failed to set MTU on %s: %s", this->if_name, - strerror(errno)); - return FALSE; - } - this->mtu = mtu; - return TRUE; -} - -METHOD(tun_device_t, get_mtu, int, - private_tun_device_t *this) -{ - struct ifreq ifr; - - if (this->mtu > 0) - { - return this->mtu; - } - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ); - this->mtu = TUN_DEFAULT_MTU; - - if (ioctl(this->sock, SIOCGIFMTU, &ifr) == 0) - { - this->mtu = ifr.ifr_mtu; - } - return this->mtu; -} - -METHOD(tun_device_t, get_name, char*, - private_tun_device_t *this) -{ - return this->if_name; -} - -METHOD(tun_device_t, write_packet, bool, - private_tun_device_t *this, chunk_t packet) -{ - ssize_t s; - - s = write(this->tunfd, packet.ptr, packet.len); - if (s < 0) - { - DBG1(DBG_LIB, "failed to write packet to TUN device %s: %s", - this->if_name, strerror(errno)); - return FALSE; - } - else if (s != packet.len) - { - return FALSE; - } - return TRUE; -} - -METHOD(tun_device_t, read_packet, bool, - private_tun_device_t *this, chunk_t *packet) -{ - ssize_t len; - fd_set set; - bool old; - - FD_ZERO(&set); - FD_SET(this->tunfd, &set); - - old = thread_cancelability(TRUE); - len = select(this->tunfd + 1, &set, NULL, NULL, NULL); - thread_cancelability(old); - - if (len < 0) - { - DBG1(DBG_LIB, "select on TUN device %s failed: %s", this->if_name, - strerror(errno)); - return FALSE; - } - /* FIXME: this is quite expensive for lots of small packets, copy from - * local buffer instead? */ - *packet = chunk_alloc(get_mtu(this)); - len = read(this->tunfd, packet->ptr, packet->len); - if (len < 0) - { - DBG1(DBG_LIB, "reading from TUN device %s failed: %s", this->if_name, - strerror(errno)); - chunk_free(packet); - return FALSE; - } - packet->len = len; - return TRUE; -} - -METHOD(tun_device_t, destroy, void, - private_tun_device_t *this) -{ - if (this->tunfd > 0) - { - close(this->tunfd); -#ifdef __FreeBSD__ - /* tun(4) says the following: "These network interfaces persist until - * the if_tun.ko module is unloaded, or until removed with the - * ifconfig(8) command." So simply closing the FD is not enough. */ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ); - if (ioctl(this->sock, SIOCIFDESTROY, &ifr) < 0) - { - DBG1(DBG_LIB, "failed to destroy %s: %s", this->if_name, - strerror(errno)); - } -#endif /* __FreeBSD__ */ - } - if (this->sock > 0) - { - close(this->sock); - } - free(this); -} - -/** - * Initialize the tun device - */ -static bool init_tun(private_tun_device_t *this, const char *name_tmpl) -{ -#ifdef __APPLE__ - - struct ctl_info info; - struct sockaddr_ctl addr; - socklen_t size = IFNAMSIZ; - - memset(&info, 0, sizeof(info)); - memset(&addr, 0, sizeof(addr)); - - this->tunfd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); - if (this->tunfd < 0) - { - DBG1(DBG_LIB, "failed to open tundevice PF_SYSTEM socket: %s", - strerror(errno)); - return FALSE; - } - - /* get a control identifier for the utun kernel extension */ - strncpy(info.ctl_name, UTUN_CONTROL_NAME, strlen(UTUN_CONTROL_NAME)); - if (ioctl(this->tunfd, CTLIOCGINFO, &info) < 0) - { - DBG1(DBG_LIB, "failed to ioctl tundevice: %s", strerror(errno)); - close(this->tunfd); - return FALSE; - } - - addr.sc_id = info.ctl_id; - addr.sc_len = sizeof(addr); - addr.sc_family = AF_SYSTEM; - addr.ss_sysaddr = AF_SYS_CONTROL; - /* allocate identifier dynamically */ - addr.sc_unit = 0; - - if (connect(this->tunfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) - { - DBG1(DBG_LIB, "failed to connect tundevice: %s", strerror(errno)); - close(this->tunfd); - return FALSE; - } - if (getsockopt(this->tunfd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, - this->if_name, &size) < 0) - { - DBG1(DBG_LIB, "getting tundevice name failed: %s", strerror(errno)); - close(this->tunfd); - return FALSE; - } - return TRUE; - -#elif defined(IFF_TUN) - - struct ifreq ifr; - - strncpy(this->if_name, name_tmpl ?: "tun%d", IFNAMSIZ); - this->if_name[IFNAMSIZ-1] = '\0'; - - this->tunfd = open("/dev/net/tun", O_RDWR); - if (this->tunfd < 0) - { - DBG1(DBG_LIB, "failed to open /dev/net/tun: %s", strerror(errno)); - return FALSE; - } - - memset(&ifr, 0, sizeof(ifr)); - - /* TUN device, no packet info */ - ifr.ifr_flags = IFF_TUN | IFF_NO_PI; - - strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ); - if (ioctl(this->tunfd, TUNSETIFF, (void*)&ifr) < 0) - { - DBG1(DBG_LIB, "failed to configure TUN device: %s", strerror(errno)); - close(this->tunfd); - return FALSE; - } - strncpy(this->if_name, ifr.ifr_name, IFNAMSIZ); - return TRUE; - -#else /* !IFF_TUN */ - - /* this works on FreeBSD and might also work on Linux with older TUN - * driver versions (no IFF_TUN) */ - char devname[IFNAMSIZ]; - int i; - - if (name_tmpl) - { - DBG1(DBG_LIB, "arbitrary naming of TUN devices is not supported"); - } - - for (i = 0; i < 256; i++) - { - snprintf(devname, IFNAMSIZ, "/dev/tun%d", i); - this->tunfd = open(devname, O_RDWR); - if (this->tunfd > 0) - { /* for ioctl(2) calls only the interface name is used */ - snprintf(this->if_name, IFNAMSIZ, "tun%d", i); - break; - } - DBG1(DBG_LIB, "failed to open %s: %s", this->if_name, strerror(errno)); - } - return this->tunfd > 0; - -#endif /* !__APPLE__ */ -} - -/* - * Described in header - */ -tun_device_t *tun_device_create(const char *name_tmpl) -{ - private_tun_device_t *this; - - INIT(this, - .public = { - .read_packet = _read_packet, - .write_packet = _write_packet, - .get_mtu = _get_mtu, - .set_mtu = _set_mtu, - .get_name = _get_name, - .set_address = _set_address, - .up = _up, - .destroy = _destroy, - }, - .tunfd = -1, - .sock = -1, - ); - - if (!init_tun(this, name_tmpl)) - { - free(this); - return NULL; - } - DBG1(DBG_LIB, "created TUN device: %s", this->if_name); - - this->sock = socket(AF_INET, SOCK_DGRAM, 0); - if (this->sock < 0) - { - DBG1(DBG_LIB, "failed to open socket to configure TUN device"); - destroy(this); - return NULL; - } - return &this->public; -} diff --git a/src/libstrongswan/utils/tun_device.h b/src/libstrongswan/utils/tun_device.h deleted file mode 100644 index be97432ff..000000000 --- a/src/libstrongswan/utils/tun_device.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2012 Tobias Brunner - * Copyright (C) 2012 Giuliano Grassi - * Copyright (C) 2012 Ralf Sager - * Hochschule fuer Technik Rapperswil - * - * 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 the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -/** - * @defgroup tun_device tun_device - * @{ @ingroup utils - */ - -#ifndef TUN_DEVICE_H_ -#define TUN_DEVICE_H_ - -#include <library.h> -#include <networking/host.h> - -typedef struct tun_device_t tun_device_t; - -/** - * Class to create TUN devices - * - * Creating such a device requires the CAP_NET_ADMIN capability. - * - * @note The implementation is currently very Linux specific - */ -struct tun_device_t { - - /** - * Read a packet from the TUN device - * - * @note This call blocks until a packet is available. It is a thread - * cancellation point. - * - * @param packet the packet read from the device - * @return TRUE if successful - */ - bool (*read_packet)(tun_device_t *this, chunk_t *packet); - - /** - * Write a packet to the TUN device - * - * @param packet the packet to write to the TUN device - * @return TRUE if successful - */ - bool (*write_packet)(tun_device_t *this, chunk_t packet); - - /** - * Set the IP address of the device - * - * @param addr the desired interface address - * @param netmask the netmask to use - * @return TRUE if operation successful - */ - bool (*set_address)(tun_device_t *this, host_t *addr, u_int8_t netmask); - - /** - * Bring the TUN device up - * - * @return TRUE if operation successful - */ - bool (*up)(tun_device_t *this); - - /** - * Set the MTU for this TUN device - * - * @param mtu new MTU - * @return TRUE if operation successful - */ - bool (*set_mtu)(tun_device_t *this, int mtu); - - /** - * Get the current MTU for this TUN device - * - * @return current MTU - */ - int (*get_mtu)(tun_device_t *this); - - /** - * Get the interface name of this device - * - * @return interface name - */ - char *(*get_name)(tun_device_t *this); - - /** - * Destroy a tun_device_t - */ - void (*destroy)(tun_device_t *this); - -}; - -/** - * Create a TUN device using the given name template. - * - * @param name_tmpl name template, defaults to "tun%d" if not given - * @return TUN device - */ -tun_device_t *tun_device_create(const char *name_tmpl); - -#endif /** TUN_DEVICE_H_ @}*/ |