From e9104d332552bc617b30bc8b7db0ccfac53bff72 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Fri, 9 May 2008 18:19:05 +0000 Subject: linux tun/tap device works now with tun *and* tap TODO: ifconfig --- src/linux/tunDevice.cpp | 83 +++++++++++++++++++++++++++---------------------- src/linux/tunDevice.h | 10 +++--- 2 files changed, 50 insertions(+), 43 deletions(-) (limited to 'src/linux') 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_; }; -- cgit v1.2.3