X-Git-Url: https://git.syn-net.org/debian/?a=blobdiff_plain;ds=sidebyside;f=src%2Flinux%2FtunDevice.cpp;h=97a7ede020a49d064a82d2f70e0c9af4b51d0f48;hb=refs%2Fheads%2Fupstream;hp=b34ae9db46849fe666608904fe9de9fec7b86307;hpb=058ae090a970436caec3b3059e9e18b310dd6b0d;p=anytun.git diff --git a/src/linux/tunDevice.cpp b/src/linux/tunDevice.cpp index b34ae9d..97a7ede 100644 --- a/src/linux/tunDevice.cpp +++ b/src/linux/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,11 +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 @@ -46,128 +61,131 @@ #include "threadUtils.hpp" #include "log.h" #include "anytunError.h" +#include "sysExec.h" -TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifcfg_addr, u_int16_t 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) { - struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); if(conf_.type_ == TYPE_TUN) { ifr.ifr_flags = IFF_TUN; with_pi_ = true; - } - else if(conf_.type_ == TYPE_TAP) { + } else if(conf_.type_ == TYPE_TAP) { ifr.ifr_flags = IFF_TAP | IFF_NO_PI; with_pi_ = false; - } - else + } else { AnytunError::throwErr() << "unable to recognize type of device (tun or tap)"; + } - if(dev_name != "") - strncpy(ifr.ifr_name, dev_name.c_str(), IFNAMSIZ); + if(dev_name != "") { + strncpy(ifr.ifr_name, dev_name.c_str(), IFNAMSIZ-1); + } - fd_ = ::open(DEFAULT_DEVICE, O_RDWR); - if(fd_ < 0) + fd_ = ::open(DEFAULT_DEVICE, O_RDWR); + if(fd_ < 0) { AnytunError::throwErr() << "can't open device file (" << DEFAULT_DEVICE << "): " << AnytunErrno(errno); + } - if(!ioctl(fd_, TUNSETIFF, &ifr)) { - actual_name_ = ifr.ifr_name; - } else if(!ioctl(fd_, (('T' << 8) | 202), &ifr)) { - actual_name_ = ifr.ifr_name; - } else { + if(!ioctl(fd_, TUNSETIFF, &ifr)) { + actual_name_ = ifr.ifr_name; + } else if(!ioctl(fd_, (('T' << 8) | 202), &ifr)) { + actual_name_ = ifr.ifr_name; + } else { ::close(fd_); AnytunError::throwErr() << "tun/tap device ioctl failed: " << AnytunErrno(errno); } actual_node_ = DEFAULT_DEVICE; - if(ifcfg_addr != "") + if(ifcfg_addr != "") { do_ifconfig(); + } } TunDevice::~TunDevice() { - if(fd_ > 0) + if(fd_ > 0) { ::close(fd_); + } } int TunDevice::fix_return(int ret, size_t pi_length) const { - if(ret < 0) + if(ret < 0) { return ret; + } 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_) - { + if(with_pi_) { struct iovec iov[2]; struct tun_pi tpi; - + iov[0].iov_base = &tpi; iov[0].iov_len = sizeof(tpi); iov[1].iov_base = buf; iov[1].iov_len = len; return(fix_return(::readv(fd_, iov, 2), sizeof(tpi))); - } - 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_) - { + if(with_pi_) { struct iovec iov[2]; struct tun_pi tpi; - struct iphdr *hdr = reinterpret_cast(buf); - + struct iphdr* hdr = reinterpret_cast(buf); + tpi.flags = 0; - if(hdr->version == 4) + if(hdr->version == 4) { tpi.proto = htons(ETH_P_IP); - else + } else { tpi.proto = htons(ETH_P_IPV6); - + } + iov[0].iov_base = &tpi; iov[0].iov_len = sizeof(tpi); iov[1].iov_base = buf; iov[1].iov_len = len; return(fix_return(::writev(fd_, iov, 2), sizeof(tpi))); - } - else + } else { return(::write(fd_, buf, len)); + } } void TunDevice::init_post() { -// nothing to be done here + // nothing to be done here } void TunDevice::do_ifconfig() { - std::ostringstream command; - command << "/sbin/ifconfig " << actual_name_ << " " << conf_.addr_.toString() - << " netmask " << conf_.netmask_.toString() << " mtu " << conf_.mtu_; - - 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"; + 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()); + sys_exec_ = new SysExec("/sbin/ifconfig", args); +} + +void TunDevice::waitUntilReady() +{ + if(sys_exec_) { + SysExec::waitAndDestroy(sys_exec_); } }