#pragma once #include #include #include #include #include #include #include #include namespace llarp::vpn { class permission_error : public std::runtime_error { public: using std::runtime_error::runtime_error; }; struct IOCTL { const int _fd; explicit IOCTL(int af) : _fd{::socket(af, SOCK_DGRAM, IPPROTO_IP)} { if (_fd == -1) throw std::invalid_argument{strerror(errno)}; }; ~IOCTL() { ::close(_fd); } template void ioctl(Command cmd, Args&&... args) { if (::ioctl(_fd, cmd, std::forward(args)...) == -1) { if (errno == EACCES) { throw permission_error{"we are not allowed to call this ioctl"}; } else throw std::runtime_error("ioctl failed: " + std::string{strerror(errno)}); } } }; } // namespace llarp::vpn