14#ifndef OPENVPN_TUN_LINUX_CLIENT_TUNSETUP_H
15#define OPENVPN_TUN_LINUX_CLIENT_TUNSETUP_H
21#include <linux/if_tun.h>
51template <
class TUNMETHODS>
76 Json::Value root(Json::objectValue);
78 root[
"layer"] = Json::Value(
layer.
str());
79 root[
"dev_name"] = Json::Value(
dev_name);
81 root[
"dco"] = Json::Value(
dco);
85 void from_json(
const Json::Value &root,
const std::string &title)
override
129 std::ostream &
os)
override
134 throw tun_linux_error(
"missing config");
173 static const char node[] =
"/dev/net/tun";
179 std::memset(&ifr, 0,
sizeof(ifr));
180 ifr.ifr_flags = IFF_ONE_QUEUE;
181 ifr.ifr_flags |= IFF_NO_PI;
183 ifr.ifr_flags |= IFF_TUN;
185 ifr.ifr_flags |= IFF_TAP;
187 throw tun_layer_error(
"unknown OSI layer");
191 if (fcntl(fd(), F_SETFL, O_NONBLOCK) < 0)
192 throw tun_fcntl_error(
errinfo(errno));
198 const ScopedFD ctl_fd(socket(AF_INET, SOCK_DGRAM, 0));
200 if (ctl_fd.defined())
202 std::memset(&netifr, 0,
sizeof(netifr));
203 strcpy(netifr.ifr_name, ifr.ifr_name);
205 if (ioctl(ctl_fd(), SIOCSIFTXQLEN, (
void *)&netifr) < 0)
206 throw tun_tx_queue_len_error(
errinfo(errno));
209 throw tun_tx_queue_len_error(
errinfo(errno));
221 const int max_units = 256;
222 for (
int unit = 0; unit < max_units; ++unit)
224 std::string n = name;
227 if (n.length() < IFNAMSIZ)
228 ::strcpy(ifr.ifr_name, n.c_str());
230 throw tun_name_error();
231 if (ioctl(fd(), TUNSETIFF, (
void *)&ifr) == 0)
234 const int eno = errno;
235 OPENVPN_THROW(tun_ioctl_error,
"failed to open tun device '" << name <<
"' after trying " << max_units <<
" units : " <<
errinfo(eno));
239 if (ioctl(fd(), TUNSETIFF, (
void *)&ifr) < 0)
241 const int eno = errno;
242 OPENVPN_THROW(tun_ioctl_error,
"failed to open tun device '" << name <<
"' : " <<
errinfo(eno));
virtual std::unordered_set< std::string > execute(std::ostream &os)
Executes a sequence of actions and returns marks of failed actions.
static Layer from_str(const std::string &str)
std::string to_string() const
Returns a string representation of the remote address.
RemoteAddress remote_address
std::string tun_iface_name
void open_unit(const std::string &name, struct ifreq &ifr, ScopedFD &fd)
ActionList::Ptr remove_cmds_bypass_gw
bool add_bypass_route(const std::string &address, bool ipv6, std::ostream &os)
void destroy(std::ostream &os) override
ActionListReversed::Ptr remove_cmds
int open_tun(Config *conf)
int establish(const TunBuilderCapture &pull, TunBuilderSetup::Config *config, Stop *stop, std::ostream &os) override
#define OPENVPN_EXCEPTION(C)
#define OPENVPN_THROW(exc, stuff)
void assert_dict(const Json::Value &obj, const TITLE &title)
void to_string(const Json::Value &root, std::string &dest, const NAME &name, const TITLE &title)
void to_int(const Json::Value &root, int &dest, const NAME &name, const TITLE &title)
void to_bool(const Json::Value &root, bool &dest, const NAME &name, const TITLE &title)
std::string get_string(const Json::Value &root, const NAME &name, const TITLE &title)
std::string to_string(const T &t)
Convert a value to a string.
std::string errinfo(ErrorCode err)
void from_json(const Json::Value &root, const std::string &title) override
bool add_bypass_routes_on_establish
Json::Value to_json() override
static const char config[]