summaryrefslogtreecommitdiff
path: root/src/openvpn/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn/route.c')
-rw-r--r--src/openvpn/route.c62
1 files changed, 39 insertions, 23 deletions
diff --git a/src/openvpn/route.c b/src/openvpn/route.c
index f127a90..5e1dca6 100644
--- a/src/openvpn/route.c
+++ b/src/openvpn/route.c
@@ -49,6 +49,10 @@
#include <linux/rtnetlink.h> /* RTM_GETROUTE etc. */
#endif
+#if defined(TARGET_NETBSD)
+#include <net/route.h> /* RT_ROUNDUP(), RT_ADVANCE() */
+#endif
+
#ifdef _WIN32
#include "openvpn-msg.h"
@@ -323,6 +327,10 @@ init_route(struct route_ipv4 *r,
if (get_special_addr(rl, ro->network, (in_addr_t *) &special.s_addr, &status))
{
+ if (!status)
+ {
+ goto fail;
+ }
special.s_addr = htonl(special.s_addr);
ret = openvpn_getaddrinfo(0, inet_ntoa(special), NULL, 0, NULL,
AF_INET, network_list);
@@ -619,7 +627,7 @@ init_route_list(struct route_list *rl,
rl->flags = opt->flags;
- if (remote_host)
+ if (remote_host != IPV4_INVALID_ADDR)
{
rl->spec.remote_host = remote_host;
rl->spec.flags |= RTSA_REMOTE_HOST;
@@ -1003,14 +1011,10 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt,
* - we are connecting to a non-IPv4 remote host (i.e. we use IPv6)
*/
else if (!(rl->rgi.flags & RGI_ADDR_DEFINED) && !local
- && (rl->spec.remote_host != IPV4_INVALID_ADDR))
+ && (rl->spec.flags & RTSA_REMOTE_HOST))
{
msg(M_WARN, "%s Cannot read current default gateway from system", err);
}
- else if (!(rl->spec.flags & RTSA_REMOTE_HOST))
- {
- msg(M_WARN, "%s Cannot obtain current remote host address", err);
- }
else
{
#ifndef TARGET_ANDROID
@@ -1033,7 +1037,8 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt,
/* route remote host to original default gateway */
/* if remote_host is not ipv4 (ie: ipv6), just skip
* adding this special /32 route */
- if (rl->spec.remote_host != IPV4_INVALID_ADDR)
+ if ((rl->spec.flags & RTSA_REMOTE_HOST)
+ && rl->spec.remote_host != IPV4_INVALID_ADDR)
{
add_route3(rl->spec.remote_host,
IPV4_NETMASK_HOST,
@@ -1471,6 +1476,13 @@ setenv_route_ipv6(struct env_set *es, const struct route_ipv6 *r6, int i)
buf_printf( &name2, "route_ipv6_gateway_%d", i );
setenv_str( es, BSTR(&name2), print_in6_addr( r6->gateway, 0, &gc ));
+
+ if (r6->flags & RT_METRIC_DEFINED)
+ {
+ struct buffer name3 = alloc_buf_gc( 256, &gc );
+ buf_printf( &name3, "route_ipv6_metric_%d", i) ;
+ setenv_int( es, BSTR(&name3), r6->metric);
+ }
}
gc_free(&gc);
}
@@ -1979,25 +1991,24 @@ add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt,
}
else
{
- struct buffer out = alloc_buf_gc(64, &gc);
+ DWORD adapter_index;
if (r6->adapter_index) /* vpn server special route */
{
- buf_printf(&out, "interface=%lu", r6->adapter_index );
+ adapter_index = r6->adapter_index;
gateway_needed = true;
}
else
{
- buf_printf(&out, "interface=%lu", tt->adapter_index );
+ adapter_index = tt->adapter_index;
}
- device = buf_bptr(&out);
- /* netsh interface ipv6 add route 2001:db8::/32 MyTunDevice */
- argv_printf(&argv, "%s%s interface ipv6 add route %s/%d %s",
+ /* netsh interface ipv6 add route 2001:db8::/32 42 */
+ argv_printf(&argv, "%s%s interface ipv6 add route %s/%d %lu",
get_win_sys_path(),
NETSH_PATH_SUFFIX,
network,
r6->netbits,
- device);
+ adapter_index);
/* next-hop depends on TUN or TAP mode:
* - in TAP mode, we use the "real" next-hop
@@ -2423,25 +2434,24 @@ delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt,
}
else
{
- struct buffer out = alloc_buf_gc(64, &gc);
+ DWORD adapter_index;
if (r6->adapter_index) /* vpn server special route */
{
- buf_printf(&out, "interface=%lu", r6->adapter_index );
+ adapter_index = r6->adapter_index;
gateway_needed = true;
}
else
{
- buf_printf(&out, "interface=%lu", tt->adapter_index );
+ adapter_index = tt->adapter_index;
}
- device = buf_bptr(&out);
- /* netsh interface ipv6 delete route 2001:db8::/32 MyTunDevice */
- argv_printf(&argv, "%s%s interface ipv6 delete route %s/%d %s",
+ /* netsh interface ipv6 delete route 2001:db8::/32 42 */
+ argv_printf(&argv, "%s%s interface ipv6 delete route %s/%d %lu",
get_win_sys_path(),
NETSH_PATH_SUFFIX,
network,
r6->netbits,
- device);
+ adapter_index);
/* next-hop depends on TUN or TAP mode:
* - in TAP mode, we use the "real" next-hop
@@ -3408,11 +3418,15 @@ struct rtmsg {
/* the route socket code is identical for all 4 supported BSDs and for
* MacOS X (Darwin), with one crucial difference: when going from
- * 32 bit to 64 bit, the BSDs increased the structure size but kept
+ * 32 bit to 64 bit, FreeBSD/OpenBSD increased the structure size but kept
* source code compatibility by keeping the use of "long", while
* MacOS X decided to keep binary compatibility by *changing* the API
* to use "uint32_t", thus 32 bit on all OS X variants
*
+ * NetBSD does the MacOS way of "fixed number of bits, no matter if
+ * 32 or 64 bit OS", but chose uint64_t. For maximum portability, we
+ * just use the OS RT_ROUNDUP() macro, which is guaranteed to be correct.
+ *
* We used to have a large amount of duplicate code here which really
* differed only in this (long) vs. (uint32_t) - IMHO, worse than
* having a combined block for all BSDs with this single #ifdef inside
@@ -3421,6 +3435,8 @@ struct rtmsg {
#if defined(TARGET_DARWIN)
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
+#elif defined(TARGET_NETBSD)
+#define ROUNDUP(a) RT_ROUNDUP(a)
#else
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
@@ -3729,7 +3745,7 @@ get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
}
if (write(sockfd, (char *)&m_rtmsg, l) < 0)
{
- msg(M_WARN, "GDG6: problem writing to routing socket");
+ msg(M_WARN|M_ERRNO, "GDG6: problem writing to routing socket");
goto done;
}