#include "route.h"
#include "win32.h"
#include "block_dns.h"
+#include "networking.h"
#include "memdbg.h"
struct addrinfo *local_public,
struct addrinfo *remote_public,
const bool strict_warn,
- struct env_set *es)
+ struct env_set *es,
+ openvpn_net_ctx_t *ctx)
{
struct gc_arena gc = gc_new();
struct tuntap *tt;
* @param ifname the human readable interface name
* @param mtu the MTU value to set the interface to
* @param es the environment to be used when executing the commands
+ * @param ctx the networking API opaque context
*/
static void
do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
- const struct env_set *es)
+ const struct env_set *es, openvpn_net_ctx_t *ctx)
{
- const char *ifconfig_ipv6_local = NULL;
+#if defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
+ || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
+ || defined(TARGET_DRAGONFLY) || defined(TARGET_AIX) \
+ || defined(TARGET_SOLARIS) || defined(_WIN32)
struct argv argv = argv_new();
struct gc_arena gc = gc_new();
-
- ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
+ const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
+#endif
#if defined(TARGET_LINUX)
-#ifdef ENABLE_IPROUTE
- /* set the MTU for the device and bring it up */
- argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
- tun_mtu);
- argv_msg(M_INFO, &argv);
- openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
+ if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
+ {
+ msg(M_FATAL, "Linux can't set mtu (%d) on %s", tun_mtu, ifname);
+ }
- argv_printf(&argv, "%s -6 addr add %s/%d dev %s", iproute_path,
- ifconfig_ipv6_local, tt->netbits_ipv6, ifname);
- argv_msg(M_INFO, &argv);
- openvpn_execve_check(&argv, es, S_FATAL, "Linux ip -6 addr add failed");
-#else /* ifdef ENABLE_IPROUTE */
- argv_printf(&argv, "%s %s add %s/%d mtu %d up", IFCONFIG_PATH, ifname,
- ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
- argv_msg(M_INFO, &argv);
- openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
-#endif
+ if (net_iface_up(ctx, ifname, true) < 0)
+ {
+ msg(M_FATAL, "Linux can't bring %s up", ifname);
+ }
+
+ if (net_addr_v6_add(ctx, ifname, &tt->local_ipv6,
+ tt->netbits_ipv6) < 0)
+ {
+ msg(M_FATAL, "Linux can't add IPv6 to interface %s", ifname);
+ }
#elif defined(TARGET_ANDROID)
char out6[64];
msg(M_FATAL, "Sorry, but I don't know how to do IPv6 'ifconfig' commands on this operating system. You should ifconfig your TUN/TAP device manually or use an --up script.");
#endif /* outer "if defined(TARGET_xxx)" conditional */
+#if defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
+ || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
+ || defined(TARGET_DRAGONFLY) || defined(TARGET_AIX) \
+ || defined(TARGET_SOLARIS) || defined(_WIN32)
gc_free(&gc);
argv_reset(&argv);
+#endif
}
/**
* @param ifname the human readable interface name
* @param mtu the MTU value to set the interface to
* @param es the environment to be used when executing the commands
+ * @param ctx the networking API opaque context
*/
static void
do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
- const struct env_set *es)
+ const struct env_set *es, openvpn_net_ctx_t *ctx)
{
- bool tun = false;
+ /*
+ * We only handle TUN/TAP devices here, not --dev null devices.
+ */
+ bool tun = is_tun_p2p(tt);
+
+#if defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
+ || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
+ || defined(TARGET_DRAGONFLY) || defined(TARGET_AIX) \
+ || defined(TARGET_SOLARIS) || defined(_WIN32)
const char *ifconfig_local = NULL;
const char *ifconfig_remote_netmask = NULL;
const char *ifconfig_broadcast = NULL;
struct argv argv = argv_new();
struct gc_arena gc = gc_new();
- /*
- * We only handle TUN/TAP devices here, not --dev null devices.
- */
- tun = is_tun_p2p(tt);
-
/*
* Set ifconfig parameters
*/
{
ifconfig_broadcast = print_in_addr_t(tt->broadcast, 0, &gc);
}
+#endif
#if defined(TARGET_LINUX)
-#ifdef ENABLE_IPROUTE
- /*
- * Set the MTU for the device
- */
- argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
- tun_mtu);
- argv_msg(M_INFO, &argv);
- openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
-
- if (tun)
+ if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
{
-
- /*
- * Set the address for the device
- */
- argv_printf(&argv, "%s addr add dev %s local %s peer %s", iproute_path,
- ifname, ifconfig_local, ifconfig_remote_netmask);
- argv_msg(M_INFO, &argv);
- openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
+ msg(M_FATAL, "Linux can't set mtu (%d) on %s", tun_mtu, ifname);
}
- else
+
+ if (net_iface_up(ctx, ifname, true) < 0)
{
- argv_printf(&argv, "%s addr add dev %s %s/%d broadcast %s",
- iproute_path, ifname, ifconfig_local,
- netmask_to_netbits2(tt->remote_netmask),
- ifconfig_broadcast);
- argv_msg(M_INFO, &argv);
- openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
+ msg(M_FATAL, "Linux can't bring %s up", ifname);
}
-#else /* ifdef ENABLE_IPROUTE */
+
if (tun)
{
- argv_printf(&argv, "%s %s %s pointopoint %s mtu %d", IFCONFIG_PATH,
- ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
+ if (net_addr_ptp_v4_add(ctx, ifname, &tt->local,
+ &tt->remote_netmask) < 0)
+ {
+ msg(M_FATAL, "Linux can't add IP to TUN interface %s", ifname);
+ }
}
else
{
- argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s",
- IFCONFIG_PATH, ifname, ifconfig_local,
- ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
+ if (net_addr_v4_add(ctx, ifname, &tt->local,
+ netmask_to_netbits2(tt->remote_netmask),
+ &tt->remote_netmask) < 0)
+ {
+ msg(M_FATAL, "Linux can't add IP to TAP interface %s", ifname);
+ }
}
- argv_msg(M_INFO, &argv);
- openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig failed");
-
-#endif /*ENABLE_IPROUTE*/
#elif defined(TARGET_ANDROID)
char out[64];
msg(M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system. You should ifconfig your TUN/TAP device manually or use an --up script.");
#endif /* if defined(TARGET_LINUX) */
+#if defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
+ || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
+ || defined(TARGET_DRAGONFLY) || defined(TARGET_AIX) \
+ || defined(TARGET_SOLARIS) || defined(_WIN32)
gc_free(&gc);
argv_reset(&argv);
+#endif
}
/* execute the ifconfig command through the shell */
void
do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
- const struct env_set *es)
+ const struct env_set *es, openvpn_net_ctx_t *ctx)
{
msg(D_LOW, "do_ifconfig, ipv4=%d, ipv6=%d", tt->did_ifconfig_setup,
tt->did_ifconfig_ipv6_setup);
if (tt->did_ifconfig_setup)
{
- do_ifconfig_ipv4(tt, ifname, tun_mtu, es);
+ do_ifconfig_ipv4(tt, ifname, tun_mtu, es, ctx);
}
if (tt->did_ifconfig_ipv6_setup)
{
- do_ifconfig_ipv6(tt, ifname, tun_mtu, es);
+ do_ifconfig_ipv6(tt, ifname, tun_mtu, es, ctx);
}
}
}
void
-close_tun(struct tuntap *tt)
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
{
ASSERT(tt);
#ifdef ENABLE_FEATURE_TUN_PERSIST
void
-tuncfg(const char *dev, const char *dev_type, const char *dev_node, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options)
+tuncfg(const char *dev, const char *dev_type, const char *dev_node,
+ int persist_mode, const char *username, const char *groupname,
+ const struct tuntap_options *options, openvpn_net_ctx_t *ctx)
{
struct tuntap *tt;
msg(M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", groupname, dev);
}
}
- close_tun(tt);
+ close_tun(tt, ctx);
msg(M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF"));
}
#endif /* ENABLE_FEATURE_TUN_PERSIST */
void
-undo_ifconfig_ipv4(struct tuntap *tt, struct gc_arena *gc)
+undo_ifconfig_ipv4(struct tuntap *tt, struct gc_arena *gc,
+ openvpn_net_ctx_t *ctx)
{
- struct argv argv = argv_new();
+#if defined(TARGET_LINUX)
+ int netbits = netmask_to_netbits2(tt->remote_netmask);
-#ifdef ENABLE_IPROUTE
if (is_tun_p2p(tt))
{
- argv_printf(&argv, "%s addr del dev %s local %s peer %s", iproute_path,
- tt->actual_name, print_in_addr_t(tt->local, 0, gc),
- print_in_addr_t(tt->remote_netmask, 0, gc));
+ if (net_addr_ptp_v4_del(ctx, tt->actual_name, &tt->local,
+ &tt->remote_netmask) < 0)
+ {
+ msg(M_WARN, "Linux can't del IP from TUN iface %s",
+ tt->actual_name);
+ }
}
else
{
- argv_printf(&argv, "%s addr del dev %s %s/%d", iproute_path,
- tt->actual_name, print_in_addr_t(tt->local, 0, gc),
- netmask_to_netbits2(tt->remote_netmask));
+ if (net_addr_v4_del(ctx, tt->actual_name, &tt->local, netbits) < 0)
+ {
+ msg(M_WARN, "Linux can't del IP from TAP iface %s",
+ tt->actual_name);
+ }
}
-#else /* ifdef ENABLE_IPROUTE */
+#else /* ifdef TARGET_LINUX */
+ struct argv argv = argv_new();
+
argv_printf(&argv, "%s %s 0.0.0.0", IFCONFIG_PATH, tt->actual_name);
-#endif /* ifdef ENABLE_IPROUTE */
argv_msg(M_INFO, &argv);
- openvpn_execve_check(&argv, NULL, 0, "Linux ip addr del failed");
+ openvpn_execve_check(&argv, NULL, 0, "Generic ip addr del failed");
argv_reset(&argv);
+#endif /* ifdef TARGET_LINUX */
}
void
-undo_ifconfig_ipv6(struct tuntap *tt, struct gc_arena *gc)
+undo_ifconfig_ipv6(struct tuntap *tt, struct gc_arena *gc,
+ openvpn_net_ctx_t *ctx)
{
+#if defined(TARGET_LINUX)
+ if (net_addr_v6_del(ctx, tt->actual_name, &tt->local_ipv6,
+ tt->netbits_ipv6) < 0)
+ {
+ msg(M_WARN, "Linux can't del IPv6 from iface %s", tt->actual_name);
+ }
+#else /* ifdef TARGET_LINUX */
const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, gc);
struct argv argv = argv_new();
-#ifdef ENABLE_IPROUTE
- argv_printf(&argv, "%s -6 addr del %s/%d dev %s", iproute_path,
- ifconfig_ipv6_local, tt->netbits_ipv6, tt->actual_name);
-#else /* ifdef ENABLE_IPROUTE */
argv_printf(&argv, "%s %s del %s/%d", IFCONFIG_PATH, tt->actual_name,
ifconfig_ipv6_local, tt->netbits_ipv6);
-#endif
argv_msg(M_INFO, &argv);
openvpn_execve_check(&argv, NULL, 0, "Linux ip -6 addr del failed");
argv_reset(&argv);
+#endif /* ifdef TARGET_LINUX */
}
void
-close_tun(struct tuntap *tt)
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
{
ASSERT(tt);
if (tt->did_ifconfig_setup)
{
- undo_ifconfig_ipv4(tt, &gc);
+ undo_ifconfig_ipv4(tt, &gc, ctx);
}
if (tt->did_ifconfig_ipv6_setup)
{
- undo_ifconfig_ipv6(tt, &gc);
+ undo_ifconfig_ipv6(tt, &gc, ctx);
}
gc_free(&gc);
* Close TUN device.
*/
void
-close_tun(struct tuntap *tt)
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
{
ASSERT(tt);
argv_msg(M_INFO, &argv);
openvpn_execve_check(&argv, es, 0, "Solaris ifconfig unplumb failed");
- close_tun(tt);
+ close_tun(tt, NULL);
msg(M_FATAL, "Solaris ifconfig failed");
argv_reset(&argv);
}
*/
void
-close_tun(struct tuntap *tt)
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
{
ASSERT(tt);
* need to be explicitly destroyed
*/
void
-close_tun(struct tuntap *tt)
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
{
ASSERT(tt);
* we need to call "ifconfig ... destroy" for cleanup
*/
void
-close_tun(struct tuntap *tt)
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
{
ASSERT(tt);
}
void
-close_tun(struct tuntap *tt)
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
{
ASSERT(tt);
}
void
-close_tun(struct tuntap *tt)
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
{
ASSERT(tt);
/* tap devices need to be manually destroyed on AIX
*/
void
-close_tun(struct tuntap *tt)
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
{
ASSERT(tt);
}
void
-close_tun(struct tuntap *tt)
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
{
ASSERT(tt);
}
void
-close_tun(struct tuntap *tt)
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
{
ASSERT(tt);