From dc7966a32c7083f0b3c76db9dcd9bb5cd13d7a19 Mon Sep 17 00:00:00 2001 From: equinox Date: Fri, 9 May 2008 18:19:05 +0000 Subject: [PATCH] linux tun/tap device works now with tun *and* tap TODO: ifconfig git-svn-id: https://anytun.org/svn/anytun@519 2edecd69-f0ce-4815-94af-351a89d40aaa --- src/anytun.cpp | 32 ++++++------ src/{ovpn/tunDevice.h => deviceConfig.hpp} | 48 +++++++++-------- src/linux/tunDevice.cpp | 83 +++++++++++++++++------------- src/linux/tunDevice.h | 10 ++-- src/options.cpp | 5 +- src/ovpn/tunDevice.cpp | 2 +- src/ovpn/tunDevice.h | 3 +- 7 files changed, 99 insertions(+), 84 deletions(-) copy src/{ovpn/tunDevice.h => deviceConfig.hpp} (67%) diff --git a/src/anytun.cpp b/src/anytun.cpp index 281e09b..e10d6fb 100644 --- a/src/anytun.cpp +++ b/src/anytun.cpp @@ -140,9 +140,9 @@ void* sender(void* p) u_int32_t len = param->dev.read(plain_packet.getPayload(), plain_packet.getPayloadLength()); plain_packet.setPayloadLength(len); // set payload type - if(param->dev.getType() == TunDevice::TYPE_TUN) + if(param->dev.getType() == TYPE_TUN) plain_packet.setPayloadType(PAYLOAD_TYPE_TUN); - else if(param->dev.getType() == TunDevice::TYPE_TAP) + else if(param->dev.getType() == TYPE_TAP) plain_packet.setPayloadType(PAYLOAD_TYPE_TAP); else plain_packet.setPayloadType(0); @@ -303,9 +303,9 @@ void* receiver(void* p) c->decrypt(encrypted_packet, plain_packet); // check payload_type - if((param->dev.getType() == TunDevice::TYPE_TUN && plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN4 && - plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN6) || - (param->dev.getType() == TunDevice::TYPE_TAP && plain_packet.getPayloadType() != PAYLOAD_TYPE_TAP)) + if((param->dev.getType() == TYPE_TUN && plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN4 && + plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN6) || + (param->dev.getType() == TYPE_TAP && plain_packet.getPayloadType() != PAYLOAD_TYPE_TAP)) continue; // write it on the device @@ -443,8 +443,8 @@ int main(int argc, char* argv[]) } } - std::string dev_type(gOpt.getDevType()); - TunDevice dev(gOpt.getDevName().c_str(), dev_type=="" ? NULL : dev_type.c_str(), + TunDevice dev(gOpt.getDevName() =="" ? NULL : gOpt.getDevName().c_str(), + gOpt.getDevType() =="" ? NULL : gOpt.getDevType().c_str(), gOpt.getIfconfigParamLocal() =="" ? NULL : gOpt.getIfconfigParamLocal().c_str(), gOpt.getIfconfigParamRemoteNetmask() =="" ? NULL : gOpt.getIfconfigParamRemoteNetmask().c_str()); cLog.msg(Log::PRIO_NOTICE) << "dev created (opened)"; @@ -456,16 +456,16 @@ int main(int argc, char* argv[]) } -// Buffer buff(u_int32_t(1600)); -// int len; -// while(1) -// { -// len = dev.read(buff.getBuf(), buff.getLength()); -// std::cout << "read " << len << " bytes form interface " << dev.getActualName() << std::endl; -// dev.write(buff.getBuf(), len); -// } + Buffer buff(u_int32_t(1600)); + int len; + while(1) + { + len = dev.read(buff.getBuf(), buff.getLength()); + std::cout << "read " << len << " bytes form interface " << dev.getActualName() << std::endl; + dev.write(buff.getBuf(), len); + } -// exit(0); + exit(0); diff --git a/src/ovpn/tunDevice.h b/src/deviceConfig.hpp similarity index 67% copy from src/ovpn/tunDevice.h copy to src/deviceConfig.hpp index 56b06fd..22fb5d8 100644 --- a/src/ovpn/tunDevice.h +++ b/src/deviceConfig.hpp @@ -28,35 +28,39 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TUNDEVICE_H_ -#define _TUNDEVICE_H_ +#ifndef _DEVICE_CONFIG_HPP_ +#define _DEVICE_CONFIG_HPP_ -#include "buffer.h" -#include "threadUtils.hpp" +class TunDevice; -class TunDevice +enum device_type_t { TYPE_UNDEF, TYPE_TUN, TYPE_TAP }; + +class DeviceConfig { public: - static const u_int32_t TYPE_UNDEF = 0; - static const u_int32_t TYPE_TUN = 1; - static const u_int32_t TYPE_TAP = 2; - - TunDevice(const char* dev,const char* dev_type, const char* ifcfg_lp, const char* ifcfg_rnmp); - ~TunDevice(); - - short read(u_int8_t* buf, u_int32_t len); - int write(u_int8_t* buf, u_int32_t len); - - char* getActualName(); - u_int32_t getType(); - const char* getTypeString(); + DeviceConfig(const char* dev_name ,const char* dev_type, const char* ifcfg_lp, const char* ifcfg_rnmp) + { + type_ = TYPE_UNDEF; + if(dev_type) { + if(!strncmp(dev_type, "tun", 3)) + type_ = TYPE_TUN; + else if(!strncmp(dev_type, "tap", 3)) + type_ = TYPE_TAP; + } + else if(dev_name) + { + if(!strncmp(dev_name, "tun", 3)) + type_ = TYPE_TUN; + else if(!strncmp(dev_name, "tap", 3)) + type_ = TYPE_TAP; + } + + } private: - void operator=(const TunDevice &src); - TunDevice(const TunDevice &src); + device_type_t type_; - Mutex io_mutex_; - struct tuntap *dev_; + friend class TunDevice; }; #endif diff --git a/src/linux/tunDevice.cpp b/src/linux/tunDevice.cpp index eb678ac..24bad02 100644 --- a/src/linux/tunDevice.cpp +++ b/src/linux/tunDevice.cpp @@ -42,13 +42,9 @@ #include "threadUtils.hpp" -TunDevice::TunDevice(const char* dev_name, const char* dev_type, const char* ifcfg_lp, const char* ifcfg_rnmp) +TunDevice::TunDevice(const char* dev_name, const char* dev_type, const char* ifcfg_lp, const char* ifcfg_rnmp) : conf_(dev_name, dev_type, ifcfg_lp, ifcfg_rnmp) { - fd_ = -1; - type_ = TYPE_UNDEF; - fd_ = ::open(DEFAULT_DEVICE, O_RDWR); - if(fd_ < 0) { std::string msg("can't open device file: "); msg.append(strerror(errno)); @@ -58,13 +54,16 @@ TunDevice::TunDevice(const char* dev_name, const char* dev_type, const char* ifc struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); -// tun device - ifr.ifr_flags = IFF_TUN; - type_ = TYPE_TUN; - -// tap device -// ifr.ifr_flags = IFF_TAP | IFF_NO_PI; -// type_ = TYPE_TAP; + if(conf_.type_ == TYPE_TUN) { + ifr.ifr_flags = IFF_TUN; + with_pi_ = true; + } + else if(conf_.type_ == TYPE_TAP) { + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + with_pi_ = false; + } + else + throw std::runtime_error("unable to recognize type of device (tun or tap)"); if(dev_name) strncpy(ifr.ifr_name, dev_name, IFNAMSIZ); @@ -91,14 +90,19 @@ short TunDevice::read(u_int8_t* buf, u_int32_t len) if(fd_ < 0) return -1; - 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(::readv(fd_, iov, 2) - sizeof(tpi)); + 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(::readv(fd_, iov, 2) - sizeof(tpi)); + } + else + return(::read(fd_, buf, len)); } int TunDevice::write(u_int8_t* buf, u_int32_t len) @@ -106,21 +110,26 @@ int TunDevice::write(u_int8_t* buf, u_int32_t len) if(fd_ < 0) return -1; - struct iovec iov[2]; - struct tun_pi tpi; - struct iphdr *hdr = reinterpret_cast(buf); - - tpi.flags = 0; - if(hdr->version == 6) - tpi.proto = htons(ETH_P_IPV6); + if(with_pi_) + { + struct iovec iov[2]; + struct tun_pi tpi; + struct iphdr *hdr = reinterpret_cast(buf); + + tpi.flags = 0; + if(hdr->version == 6) + tpi.proto = htons(ETH_P_IPV6); + else + tpi.proto = htons(ETH_P_IP); + + iov[0].iov_base = &tpi; + iov[0].iov_len = sizeof(tpi); + iov[1].iov_base = buf; + iov[1].iov_len = len; + return(::writev(fd_, iov, 2) - sizeof(tpi)); + } else - tpi.proto = htons(ETH_P_IP); - - iov[0].iov_base = &tpi; - iov[0].iov_len = sizeof(tpi); - iov[1].iov_base = buf; - iov[1].iov_len = len; - return(writev(fd_, iov, 2) - sizeof(tpi)); + return(::write(fd_, buf, len)); } const char* TunDevice::getActualName() @@ -128,9 +137,9 @@ const char* TunDevice::getActualName() return actual_name_.c_str(); } -u_int32_t TunDevice::getType() +device_type_t TunDevice::getType() { - return type_; + return conf_.type_; } const char* TunDevice::getTypeString() @@ -138,7 +147,7 @@ const char* TunDevice::getTypeString() if(fd_ < 0) return NULL; - switch(type_) + switch(conf_.type_) { case TYPE_UNDEF: return "undef"; break; case TYPE_TUN: return "tun"; break; diff --git a/src/linux/tunDevice.h b/src/linux/tunDevice.h index 4588964..9f3557a 100644 --- a/src/linux/tunDevice.h +++ b/src/linux/tunDevice.h @@ -32,15 +32,12 @@ #define _TUNDEVICE_H_ #include "buffer.h" +#include "deviceConfig.hpp" #include "threadUtils.hpp" class TunDevice { public: - static const u_int32_t TYPE_UNDEF = 0; - static const u_int32_t TYPE_TUN = 1; - static const u_int32_t TYPE_TAP = 2; - TunDevice(const char* dev,const char* dev_type, const char* ifcfg_lp, const char* ifcfg_rnmp); ~TunDevice(); @@ -48,7 +45,7 @@ public: int write(u_int8_t* buf, u_int32_t len); const char* getActualName(); - u_int32_t getType(); + device_type_t getType(); const char* getTypeString(); private: @@ -56,7 +53,8 @@ private: TunDevice(const TunDevice &src); int fd_; - u_int32_t type_; + DeviceConfig conf_; + bool with_pi_; std::string actual_name_; }; diff --git a/src/options.cpp b/src/options.cpp index 3b7e468..798504b 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -66,7 +66,7 @@ Options::Options() : key_(u_int32_t(0)), salt_(u_int32_t(0)) remote_sync_addr_ = ""; remote_addr_ = ""; remote_port_ = 4444; - dev_name_ = "tun"; + dev_name_ = ""; dev_type_ = ""; ifconfig_param_local_ = ""; ifconfig_param_remote_netmask_ = ""; @@ -194,6 +194,9 @@ bool Options::parse(int argc, char* argv[]) if((cipher_ != "null" || auth_algo_ != "null") && kd_prf_ == "null") kd_prf_ = "aes-ctr"; + if(dev_name_ == "" && dev_type_ == "") + dev_type_ = "tun"; + while(!host_port_queue.empty()) { std::stringstream tmp_stream(host_port_queue.front()); diff --git a/src/ovpn/tunDevice.cpp b/src/ovpn/tunDevice.cpp index b3c07b0..032af29 100644 --- a/src/ovpn/tunDevice.cpp +++ b/src/ovpn/tunDevice.cpp @@ -144,7 +144,7 @@ char* TunDevice::getActualName() return dev_->actual_name; } -u_int32_t TunDevice::getType() +device_type_t TunDevice::getType() { if(!dev_) return TYPE_UNDEF; diff --git a/src/ovpn/tunDevice.h b/src/ovpn/tunDevice.h index 56b06fd..ba41cce 100644 --- a/src/ovpn/tunDevice.h +++ b/src/ovpn/tunDevice.h @@ -32,6 +32,7 @@ #define _TUNDEVICE_H_ #include "buffer.h" +#include "deviceConfig.hpp" #include "threadUtils.hpp" class TunDevice @@ -48,7 +49,7 @@ public: int write(u_int8_t* buf, u_int32_t len); char* getActualName(); - u_int32_t getType(); + device_type_t getType(); const char* getTypeString(); private: -- 2.11.4.GIT