From db275b1477273e2ede04264daa35ab5722ed9a7e Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 29 Aug 2012 15:30:10 +0200 Subject: [PATCH 1/1] Ported tun_device de-/initialization to FreeBSD --- src/libstrongswan/utils/tun_device.c | 52 ++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/src/libstrongswan/utils/tun_device.c b/src/libstrongswan/utils/tun_device.c index 53d1f26..36f3359 100644 --- a/src/libstrongswan/utils/tun_device.c +++ b/src/libstrongswan/utils/tun_device.c @@ -25,16 +25,17 @@ #include #include #include +#include #ifdef __APPLE__ -#include #include #include #include -#else /* !__APPLE__ */ -#include +#elif defined(__linux__) #include -#endif /* !__APPLE__ */ +#else +#include +#endif #include "tun_device.h" @@ -193,6 +194,8 @@ METHOD(tun_device_t, set_mtu, bool, 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; @@ -286,6 +289,20 @@ METHOD(tun_device_t, destroy, void, 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) { @@ -347,7 +364,7 @@ static bool init_tun(private_tun_device_t *this, const char *name_tmpl) } return TRUE; -#else /* !__APPLE__ */ +#elif defined(IFF_TUN) struct ifreq ifr; @@ -376,6 +393,31 @@ static bool init_tun(private_tun_device_t *this, const char *name_tmpl) 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__ */ } -- 2.7.4