diff options
Diffstat (limited to 'src/linux')
-rw-r--r-- | src/linux/tunDevice.cpp | 14 | ||||
-rw-r--r-- | src/linux/tunDevice.h | 3 |
2 files changed, 13 insertions, 4 deletions
diff --git a/src/linux/tunDevice.cpp b/src/linux/tunDevice.cpp index 4185bef..3c9e180 100644 --- a/src/linux/tunDevice.cpp +++ b/src/linux/tunDevice.cpp @@ -90,7 +90,15 @@ TunDevice::~TunDevice() ::close(fd_); } -short TunDevice::read(u_int8_t* buf, u_int32_t len) +int TunDevice::fix_return(int ret, size_t pi_length) +{ + if(ret < 0) + return ret; + + return (static_cast<size_t>(ret) > pi_length ? (ret - pi_length) : 0); +} + +int TunDevice::read(u_int8_t* buf, u_int32_t len) { if(fd_ < 0) return -1; @@ -104,7 +112,7 @@ short TunDevice::read(u_int8_t* buf, u_int32_t len) iov[0].iov_len = sizeof(tpi); iov[1].iov_base = buf; iov[1].iov_len = len; - return(::readv(fd_, iov, 2) - sizeof(tpi)); + return(fix_return(::readv(fd_, iov, 2), sizeof(tpi))); } else return(::read(fd_, buf, len)); @@ -131,7 +139,7 @@ int TunDevice::write(u_int8_t* buf, u_int32_t len) iov[0].iov_len = sizeof(tpi); iov[1].iov_base = buf; iov[1].iov_len = len; - return(::writev(fd_, iov, 2) - sizeof(tpi)); + return(fix_return(::writev(fd_, iov, 2), sizeof(tpi))); } else return(::write(fd_, buf, len)); diff --git a/src/linux/tunDevice.h b/src/linux/tunDevice.h index d838dfc..18a030c 100644 --- a/src/linux/tunDevice.h +++ b/src/linux/tunDevice.h @@ -41,7 +41,7 @@ public: 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 read(u_int8_t* buf, u_int32_t len); int write(u_int8_t* buf, u_int32_t len); const char* getActualName(); @@ -53,6 +53,7 @@ private: TunDevice(const TunDevice &src); void do_ifconfig(); + int fix_return(int ret, size_t pi_length); int fd_; DeviceConfig conf_; |