X-Git-Url: https://git.syn-net.org/debian/?a=blobdiff_plain;f=src%2Fbsd%2FtunDevice.cpp;h=66812cf365315d8fa4d5529b6e6e3ca885e5b703;hb=012bc15ee82b75957d9284160fb0a0089396f0d4;hp=408434e242c08705eb26bb4f997f3030098cfe4c;hpb=058ae090a970436caec3b3059e9e18b310dd6b0d;p=anytun.git diff --git a/src/bsd/tunDevice.cpp b/src/bsd/tunDevice.cpp index 408434e..66812cf 100644 --- a/src/bsd/tunDevice.cpp +++ b/src/bsd/tunDevice.cpp @@ -6,19 +6,20 @@ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel * mode and allows tunneling of every ETHER TYPE protocol (e.g. * ethernet, ip, arp ...). satp directly includes cryptography and - * message authentication based on the methodes used by SRTP. It is + * message authentication based on the methods used by SRTP. It is * intended to deliver a generic, scaleable and secure solution for * tunneling and relaying of packets of any protocol. * * - * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Copyright (C) 2007-2014 Markus Grüneis, Othmar Gsenger, Erwin Nindl, * Christian Pointner * * This file is part of Anytun. * * Anytun is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as - * published by the Free Software Foundation. + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. * * Anytun is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -26,9 +27,25 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with anytun. If not, see . + * along with Anytun. If not, see . + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. */ +#include +#include + #include #include #include @@ -42,16 +59,15 @@ #include #include -#include - #include "tunDevice.h" #include "threadUtils.hpp" #include "log.h" #include "anytunError.h" +#include "sysExec.h" #define DEVICE_FILE_MAX 255 -TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifcfg_addr, std::string ifcfg_prefix) : conf_(dev_name, dev_type, ifcfg_addr, ifcfg_prefix, 1400) +TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifcfg_addr, uint16_t ifcfg_prefix) : conf_(dev_name, dev_type, ifcfg_addr, ifcfg_prefix, 1400),sys_exec_(NULL) { std::string device_file = "/dev/"; bool dynamic = true; @@ -68,34 +84,36 @@ TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifc else if(conf_.type_ == TYPE_TUN) { device_file.append("tun"); actual_name_ = "tun"; - } - else if(conf_.type_ == TYPE_TAP) { + } else if(conf_.type_ == TYPE_TAP) { device_file.append("tap"); actual_name_ = "tap"; } #endif - else + else { AnytunError::throwErr() << "unable to recognize type of device (tun or tap)"; + } - u_int32_t dev_id=0; + uint32_t dev_id=0; if(dynamic) { for(; dev_id <= DEVICE_FILE_MAX; ++dev_id) { std::ostringstream ds; ds << device_file; ds << dev_id; fd_ = ::open(ds.str().c_str(), O_RDWR); - if(fd_ >= 0) + if(fd_ >= 0) { break; + } } - } - else + } else { fd_ = ::open(device_file.c_str(), O_RDWR); + } if(fd_ < 0) { - if(dynamic) + if(dynamic) { AnytunError::throwErr() << "can't open device file dynamically: no unused node left"; - else + } else { AnytunError::throwErr() << "can't open device file (" << device_file << "): " << AnytunErrno(errno); + } } if(dynamic) { @@ -103,22 +121,24 @@ TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifc s << actual_name_; s << dev_id; actual_name_ = s.str(); - } - else + } else { actual_name_ = dev_name; - + } + actual_node_ = device_file; init_post(); - if(ifcfg_addr != "") + if(ifcfg_addr != "") { do_ifconfig(); + } } TunDevice::~TunDevice() { - if(fd_ > 0) + if(fd_ > 0) { ::close(fd_); + } } #if defined(__GNUC__) && defined(__OpenBSD__) @@ -126,50 +146,53 @@ TunDevice::~TunDevice() void TunDevice::init_post() { with_pi_ = true; - if(conf_.type_ == TYPE_TAP) + if(conf_.type_ == TYPE_TAP) { with_pi_ = false; - - struct tuninfo ti; + } - if (ioctl(fd_, TUNGIFINFO, &ti) < 0) { + struct tuninfo ti; + + if(ioctl(fd_, TUNGIFINFO, &ti) < 0) { ::close(fd_); AnytunError::throwErr() << "can't enable multicast for interface: " << AnytunErrno(errno); } - + ti.flags |= IFF_MULTICAST; - if(conf_.type_ == TYPE_TUN) + if(conf_.type_ == TYPE_TUN) { ti.flags &= ~IFF_POINTOPOINT; - - if (ioctl(fd_, TUNSIFINFO, &ti) < 0) { + } + + if(ioctl(fd_, TUNSIFINFO, &ti) < 0) { ::close(fd_); AnytunError::throwErr() << "can't enable multicast for interface: " << AnytunErrno(errno); } } -#elif defined(__GNUC__) && defined(__FreeBSD__) +#elif defined(__GNUC__) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) void TunDevice::init_post() { with_pi_ = true; - if(conf_.type_ == TYPE_TAP) + if(conf_.type_ == TYPE_TAP) { with_pi_ = false; + } - if(dev->type_ == TYPE_TUN) { + if(conf_.type_ == TYPE_TUN) { int arg = 0; - if(ioctl(dev->fd_, TUNSLMODE, &arg) < 0) { + if(ioctl(fd_, TUNSLMODE, &arg) < 0) { ::close(fd_); AnytunError::throwErr() << "can't disable link-layer mode for interface: " << AnytunErrno(errno); } arg = 1; - if(ioctl(dev->fd_, TUNSIFHEAD, &arg) < 0) { + if(ioctl(fd_, TUNSIFHEAD, &arg) < 0) { ::close(fd_); AnytunError::throwErr() << "can't enable multi-af modefor interface: " << AnytunErrno(errno); } arg = IFF_BROADCAST; arg |= IFF_MULTICAST; - if(ioctl(dev->fd_, TUNSIFMODE, &arg) < 0) { + if(ioctl(fd_, TUNSIFMODE, &arg) < 0) { ::close(fd_); AnytunError::throwErr() << "can't enable multicast for interface: " << AnytunErrno(errno); } @@ -189,95 +212,96 @@ void TunDevice::init_post() } #else - #error This Device works just for OpenBSD, FreeBSD or NetBSD +#error This Device works just for OpenBSD, FreeBSD or NetBSD #endif int TunDevice::fix_return(int ret, size_t pi_length) const { - if(ret < 0) + if(ret < 0) { return ret; + } - return (static_cast(ret) > type_length ? (ret - type_length) : 0); + return (static_cast(ret) > pi_length ? (ret - pi_length) : 0); } -int TunDevice::read(u_int8_t* buf, u_int32_t len) +int TunDevice::read(uint8_t* buf, uint32_t len) { - if(fd_ < 0) + if(fd_ < 0) { return -1; - + } + if(with_pi_) { struct iovec iov[2]; - u_int32_t type; - + uint32_t type; + iov[0].iov_base = &type; iov[0].iov_len = sizeof(type); iov[1].iov_base = buf; iov[1].iov_len = len; return(fix_return(::readv(fd_, iov, 2), sizeof(type))); - } - else + } else { return(::read(fd_, buf, len)); + } } -int TunDevice::write(u_int8_t* buf, u_int32_t len) +int TunDevice::write(uint8_t* buf, uint32_t len) { - if(fd_ < 0) + if(fd_ < 0) { return -1; - - if(!buf) + } + + if(!buf) { return 0; + } if(with_pi_) { struct iovec iov[2]; - u_int32_t type; - struct ip *hdr = reinterpret_cast(buf); - + uint32_t type; + struct ip* hdr = reinterpret_cast(buf); + type = 0; - if(hdr->ip_v == 4) + if(hdr->ip_v == 4) { type = htonl(AF_INET); - else + } else { type = htonl(AF_INET6); - + } + iov[0].iov_base = &type; iov[0].iov_len = sizeof(type); iov[1].iov_base = buf; iov[1].iov_len = len; return(fix_return(::writev(fd_, iov, 2), sizeof(type))); - } - else + } else { return(::write(fd_, buf, len)); + } } void TunDevice::do_ifconfig() { - std::ostringstream command; - command << "/sbin/ifconfig " << actual_name_ << " " << conf_.addr_.toString() - << " netmask " << conf_.netmask_.toString() << " mtu " << conf_.mtu_; + std::ostringstream mtu_ss; + mtu_ss << conf_.mtu_; + StringVector args = boost::assign::list_of(actual_name_)(conf_.addr_.toString())("netmask")(conf_.netmask_.toString())("mtu")(mtu_ss.str()); - if(conf_.type_ == TYPE_TUN) - command << " up"; - else { + if(conf_.type_ == TYPE_TUN) { + args.push_back("up"); + } else { #if defined(__GNUC__) && defined(__OpenBSD__) - command << " link0"; -#elif defined(__GNUC__) && defined(__FreeBSD__) - command << " up"; + args.push_back("link0"); +#elif defined(__GNUC__) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) + args.push_back("up"); #elif defined(__GNUC__) && defined(__NetBSD__) - command << ""; + // nothing to be done here #else - #error This Device works just for OpenBSD, FreeBSD or NetBSD +#error This Device works just for OpenBSD, FreeBSD or NetBSD #endif } + sys_exec_ = new SysExec("/sbin/ifconfig", args); +} - int result = system(command.str().c_str()); - if(result == -1) - cLog.msg(Log::PRIO_ERROR) << "Execution of ifconfig failed" << AnytunErrno(errno); - else { - if(WIFEXITED(result)) - cLog.msg(Log::PRIO_NOTICE) << "ifconfig returned " << WEXITSTATUS(result); - else if(WIFSIGNALED(result)) - cLog.msg(Log::PRIO_NOTICE) << "ifconfig terminated after signal " << WTERMSIG(result); - else - cLog.msg(Log::PRIO_ERROR) << "Execution of ifconfig: unkown error"; +void TunDevice::waitUntilReady() +{ + if(sys_exec_) { + SysExec::waitAndDestroy(sys_exec_); } - } +