diff --git a/bindings/cpp/tuntap++.cc b/bindings/cpp/tuntap++.cc index cbd7420..87972f6 100644 --- a/bindings/cpp/tuntap++.cc +++ b/bindings/cpp/tuntap++.cc @@ -1,210 +1,115 @@ #include "tuntap++.hh" -#include -#include -#include - namespace tuntap { -tun::tun() - : _dev{tuntap_init()}, _started{true} +tuntap::tuntap(int mode, int id) + : _dev{::tuntap_init()} { - if (tuntap_start(_dev, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY) == -1) { - throw std::runtime_error("tuntap_start failed"); + if (mode != TUNTAP_MODE_ETHERNET && mode != TUNTAP_MODE_TUNNEL) { + throw std::invalid_argument("Unknown tuntap mode"); } -} - -tun::~tun() -{ - if (_started) { - tuntap_destroy(_dev); + if (id < 0 || id > TUNTAP_ID_MAX) { + throw std::invalid_argument("Tunnel ID is invalid"); } -} - -tun::tun(tun &&t) - : _dev(nullptr) -{ - std::swap(t._dev, this->_dev); -} - -void -tun::release() -{ - tuntap_release(_dev); - _started = false; -} - -std::string -tun::name() const -{ - return tuntap_get_ifname(_dev); -} - -void -tun::name(std::string const &s) -{ - tuntap_set_ifname(_dev, s.c_str()); -} - -t_tun -tun::native_handle() const -{ - return tuntap_get_fd(this->_dev); -} - -void -tun::up() -{ - tuntap_up(_dev); -} - -void -tun::down() -{ - tuntap_down(_dev); -} - -int -tun::mtu() const -{ - return tuntap_get_mtu(_dev); -} - -void -tun::mtu(int m) -{ - tuntap_set_mtu(_dev, m); -} - -void -tun::ip(std::string const &s, int netmask) -{ - tuntap_set_ip(_dev, s.c_str(), netmask); -} - -int -tun::read(void *buf, size_t len) -{ - return tuntap_read(_dev, buf, len); -} - -int -tun::write(void *buf, size_t len) -{ - return tuntap_write(_dev, buf, len); -} - -void -tun::nonblocking(bool b) -{ - tuntap_set_nonblocking(_dev, int(b)); -} - -tap::tap() - : _dev{tuntap_init()}, _started{true} -{ - if (tuntap_start(_dev, TUNTAP_MODE_ETHERNET, TUNTAP_ID_ANY) == -1) { + if (::tuntap_start(_dev.get(), mode, id)) { throw std::runtime_error("tuntap_start failed"); } } -tap::~tap() -{ - if (_started) { - tuntap_destroy(_dev); - } -} - -tap::tap(tap &&t) - : _dev(nullptr) -{ - std::swap(t._dev, this->_dev); -} - - -void -tap::release() -{ - tuntap_release(_dev); - _started = false; -} - -std::string -tap::name() const +tuntap::tuntap(tuntap &&t) noexcept + : _dev() { - return tuntap_get_ifname(_dev); + t._dev.swap(this->_dev); } void -tap::name(std::string const &s) +tuntap::release() noexcept { - tuntap_set_ifname(_dev, s.c_str()); + _dev.release(); } std::string -tap::hwaddr() const +tuntap::name() const noexcept { - return tuntap_get_hwaddr(_dev); + return std::string(::tuntap_get_ifname(_dev.get())); } void -tap::hwaddr(std::string const &s) +tuntap::name(std::string const &s) { - tuntap_set_hwaddr(_dev, s.c_str()); + if (::tuntap_set_ifname(_dev.get(), s.c_str())) { + throw std::runtime_error("Failed to set ifname"); + } } t_tun -tap::native_handle() const +tuntap::native_handle() const noexcept { - return tuntap_get_fd(this->_dev); + return ::tuntap_get_fd(_dev.get()); } void -tap::up() +tuntap::up() { - tuntap_up(_dev); + if (::tuntap_up(_dev.get())) { + throw std::runtime_error("Failed to bring up tuntap device"); + } } void -tap::down() +tuntap::down() { - tuntap_down(_dev); + if (::tuntap_down(_dev.get())) { + throw std::runtime_error("Failed to bring down tuntap device"); + } } int -tap::mtu() const +tuntap::mtu() const noexcept { - return tuntap_get_mtu(_dev); + return ::tuntap_get_mtu(_dev.get()); } void -tap::mtu(int m) +tuntap::mtu(int m) { - tuntap_set_mtu(_dev, m); + if (m < 1 || m > 65535) { + throw std::invalid_argument("Invalid mtu"); + } + if (::tuntap_set_mtu(_dev.get(), m)) { + throw std::runtime_error("Failed to set mtu for tuntap device"); + } } void -tap::ip(std::string const &s, int netmask) +tuntap::ip(std::string const &s, int netmask) { - tuntap_set_ip(_dev, s.c_str(), netmask); + if (netmask > 128) { + throw std::invalid_argument("Invalid netmask"); + } + if (::tuntap_set_ip(_dev.get(), s.c_str(), netmask)) { + throw std::runtime_error("Failed to set ip for tuntap device"); + } } int -tap::read(void *buf, size_t len) +tuntap::read(void *buf, std::size_t len) noexcept { - return tuntap_read(_dev, buf, len); + return ::tuntap_read(_dev.get(), buf, len); } int -tap::write(void *buf, size_t len) +tuntap::write(void *buf, std::size_t len) noexcept { - return tuntap_write(_dev, buf, len); + return ::tuntap_write(_dev.get(), buf, len); } void -tap::nonblocking(bool b) +tuntap::nonblocking(bool b) { - tuntap_set_nonblocking(_dev, int(b)); + if (::tuntap_set_nonblocking(_dev.get(), static_cast(b))) { + throw std::runtime_error("Failed to change non-blocking state for tuntap device"); + } } } /* tuntap */ diff --git a/bindings/cpp/tuntap++.hh b/bindings/cpp/tuntap++.hh index 18f23ac..ce2f5a2 100644 --- a/bindings/cpp/tuntap++.hh +++ b/bindings/cpp/tuntap++.hh @@ -2,62 +2,35 @@ #ifndef LIBTUNTAP_ALY0MA60 #define LIBTUNTAP_ALY0MA60 +#if __cplusplus >= 202002L + #define LIBTUNTAP_ALY0MA60_CONSTEXPR constexpr +#else + #define LIBTUNTAP_ALY0MA60_CONSTEXPR +#endif + #include +#include +#include +#include #include namespace tuntap { -class tun -{ - public: - tun(); - ~tun(); - tun(tun const &) = delete; - tun & operator = (tun const &) = delete; - tun(tun &&); - - // Properties - std::string name() const; - void name(std::string const &); - int mtu() const ; - void mtu(int); - t_tun native_handle() const; - - // Network - void up(); - void down(); - void ip(std::string const &presentation, int netmask); - - //IO - int read(void *buf, size_t len); - int write(void *buf, size_t len); - - // System - void release(); - void nonblocking(bool); - private: - struct device* _dev; - bool _started; -}; - -class tap +class tuntap { public: - tap(); - ~tap(); - tap(tap const &) = delete; - tap & operator = (tap const &) = delete; - tap(tap &&); + tuntap(int, int = TUNTAP_ID_ANY); + tuntap(tuntap const &) = delete; + tuntap & operator = (tuntap const &) = delete; + tuntap(tuntap &&) noexcept; // Properties - std::string name() const; + std::string name() const noexcept; void name(std::string const &); - std::string hwaddr() const; - void hwaddr(std::string const &); - int mtu() const; + int mtu() const noexcept; void mtu(int); - t_tun native_handle() const; + t_tun native_handle() const noexcept; // Network void up(); @@ -65,15 +38,21 @@ class tap void ip(std::string const &presentation, int netmask); //IO - int read(void *buf, size_t len); - int write(void *buf, size_t len); + int read(void *buf, std::size_t len) noexcept; + int write(void *buf, std::size_t len) noexcept; // System - void release(); + void release() noexcept; void nonblocking(bool); private: - struct device* _dev; - bool _started; + class TunTapDestroyer final { + public: + LIBTUNTAP_ALY0MA60_CONSTEXPR void operator()(device * dev) const noexcept { + if (dev) + ::tuntap_destroy(dev); + } + }; + std::unique_ptr _dev; }; } /* tuntap */