Here is a new version of the patch that should get the other platforms
to at least compile and work as previously. The other platforms are
untested, though.
--
Lionel
Index: openvpn-2.1.0/route.c
===================================================================
--- openvpn-2.1.0.orig/route.c 2010-08-07 13:08:23.000000000 +0200
+++ openvpn-2.1.0/route.c 2010-08-07 16:33:23.000000000 +0200
@@ -140,7 +140,7 @@
}
static void
-setenv_route_addr (struct env_set *es, const char *key, const in_addr_t addr,
int i)
+setenv_route_str (struct env_set *es, const char *key, const char *str, int i)
{
struct gc_arena gc = gc_new ();
struct buffer name = alloc_buf_gc (256, &gc);
@@ -148,7 +148,15 @@
buf_printf (&name, "route_%s_%d", key, i);
else
buf_printf (&name, "route_%s", key);
- setenv_str (es, BSTR (&name), print_in_addr_t (addr, 0, &gc));
+ setenv_str (es, BSTR (&name), str);
+ gc_free (&gc);
+}
+
+static void
+setenv_route_addr (struct env_set *es, const char *key, const in_addr_t addr,
int i)
+{
+ struct gc_arena gc = gc_new ();
+ setenv_route_str (es, key, print_in_addr_t (addr, 0, &gc), i);
gc_free (&gc);
}
@@ -180,7 +188,7 @@
if (spec)
{
if (spec->net_gateway_defined)
- *out = spec->net_gateway;
+ *out = spec->net_gateway.net_gateway_addr;
else
{
msg (M_INFO, PACKAGE_NAME " ROUTE: net_gateway undefined --
unable to get default gateway from system");
@@ -397,8 +405,12 @@
rl->spec.net_gateway_defined = get_default_gateway (&rl->spec.net_gateway,
NULL);
if (rl->spec.net_gateway_defined)
{
- setenv_route_addr (es, "net_gateway", rl->spec.net_gateway, -1);
- dmsg (D_ROUTE, "ROUTE default_gateway=%s", print_in_addr_t
(rl->spec.net_gateway, 0, &gc));
+ setenv_route_addr (es, "net_gateway",
rl->spec.net_gateway.net_gateway_addr, -1);
+ setenv_route_str (es, "net_gateway_dev",
rl->spec.net_gateway.net_gateway_dev, -1);
+ dmsg (D_ROUTE,
+ "ROUTE default_gateway=%s dev=%s",
+ print_in_addr_t (rl->spec.net_gateway.net_gateway_addr, 0, &gc),
+ rl->spec.net_gateway.net_gateway_dev);
}
else
{
@@ -474,6 +486,7 @@
r.network = network;
r.netmask = netmask;
r.gateway = gateway;
+ r.dev[0] = '\0';
add_route (&r, tt, flags, es);
}
@@ -495,8 +508,44 @@
}
static void
+add_route4 (in_addr_t network,
+ in_addr_t netmask,
+ net_gateway_t gateway,
+ const struct tuntap *tt,
+ unsigned int flags,
+ const struct env_set *es)
+{
+ struct route r;
+ CLEAR (r);
+ r.defined = true;
+ r.network = network;
+ r.netmask = netmask;
+ r.gateway = gateway.net_gateway_addr;
+ strncpy(r.dev,gateway.net_gateway_dev, IF_NAME_SIZE);
+ add_route (&r, tt, flags, es);
+}
+
+static void
+del_route4 (in_addr_t network,
+ in_addr_t netmask,
+ net_gateway_t gateway,
+ const struct tuntap *tt,
+ unsigned int flags,
+ const struct env_set *es)
+{
+ struct route r;
+ CLEAR (r);
+ r.defined = true;
+ r.network = network;
+ r.netmask = netmask;
+ r.gateway = gateway.net_gateway_addr;
+ strncpy(r.dev,gateway.net_gateway_dev, IF_NAME_SIZE);
+ delete_route (&r, tt, flags, es);
+}
+
+static void
add_bypass_routes (struct route_bypass *rb,
- in_addr_t gateway,
+ net_gateway_t gateway,
const struct tuntap *tt,
unsigned int flags,
const struct env_set *es)
@@ -504,8 +553,8 @@
int i;
for (i = 0; i < rb->n_bypass; ++i)
{
- if (rb->bypass[i] != gateway)
- add_route3 (rb->bypass[i],
+ if (rb->bypass[i] != gateway.net_gateway_addr)
+ add_route4 (rb->bypass[i],
~0,
gateway,
tt,
@@ -516,7 +565,7 @@
static void
del_bypass_routes (struct route_bypass *rb,
- in_addr_t gateway,
+ net_gateway_t gateway,
const struct tuntap *tt,
unsigned int flags,
const struct env_set *es)
@@ -524,8 +573,8 @@
int i;
for (i = 0; i < rb->n_bypass; ++i)
{
- if (rb->bypass[i] != gateway)
- del_route3 (rb->bypass[i],
+ if (rb->bypass[i] != gateway.net_gateway_addr)
+ del_route4 (rb->bypass[i],
~0,
gateway,
tt,
@@ -577,7 +626,7 @@
* adding this special /32 route */
if (rl->spec.remote_host != IPV4_INVALID_ADDR) {
#endif
- add_route3 (rl->spec.remote_host,
+ add_route4 (rl->spec.remote_host,
~0,
rl->spec.net_gateway,
tt,
@@ -617,7 +666,7 @@
else
{
/* delete default route */
- del_route3 (0,
+ del_route4 (0,
0,
rl->spec.net_gateway,
tt,
@@ -648,7 +697,7 @@
/* delete remote host route */
if (rl->did_local)
{
- del_route3 (rl->spec.remote_host,
+ del_route4 (rl->spec.remote_host,
~0,
rl->spec.net_gateway,
tt,
@@ -691,7 +740,7 @@
es);
/* restore original default route */
- add_route3 (0,
+ add_route4 (0,
0,
rl->spec.net_gateway,
tt,
@@ -814,6 +863,7 @@
setenv_route_addr (es, "network", r->network, i);
setenv_route_addr (es, "netmask", r->netmask, i);
setenv_route_addr (es, "gateway", r->gateway, i);
+ setenv_route_str (es, "device", r->dev, i);
if (r->metric_defined)
{
@@ -870,15 +920,20 @@
network,
count_netmask_bits(netmask),
gateway);
+ if (r->dev[0])
+ argv_printf_cat (&argv, "dev %s", r->dev);
if (r->metric_defined)
argv_printf_cat (&argv, "metric %d", r->metric);
#else
- argv_printf (&argv, "%s add -net %s netmask %s gw %s",
+ argv_printf (&argv, "%s add -net %s netmask %s",
ROUTE_PATH,
network,
- netmask,
- gateway);
+ netmask);
+ if (r->gateway)
+ argv_printf_cat (&argv, "gw %s", gateway);
+ if (r->dev[0])
+ argv_printf_cat (&argv, "dev %s", r->dev);
if (r->metric_defined)
argv_printf_cat (&argv, "metric %d", r->metric);
#endif /*CONFIG_FEATURE_IPROUTE*/
@@ -887,6 +942,8 @@
#elif defined (WIN32)
+ /* FIXME: this ignores r->dev; check case gateway=0.0.0.0 works */
+
argv_printf (&argv, "%s%sc ADD %s MASK %s %s",
get_win_sys_path(),
WIN_ROUTE_PATH_SUFFIX,
@@ -928,6 +985,8 @@
#elif defined (TARGET_SOLARIS)
+ /* FIXME: this ignores r->dev; check case gateway=0.0.0.0 works */
+
/* example: route add 192.0.2.32 -netmask 255.255.255.224 somegateway */
argv_printf (&argv, "%s add",
@@ -948,6 +1007,8 @@
#elif defined(TARGET_FREEBSD)
+ /* FIXME: this ignores r->dev; check case gateway=0.0.0.0 works */
+
argv_printf (&argv, "%s add",
ROUTE_PATH);
@@ -966,6 +1027,8 @@
#elif defined(TARGET_DRAGONFLY)
+ /* FIXME: this ignores r->dev; check case gateway=0.0.0.0 works */
+
argv_printf (&argv, "%s add",
ROUTE_PATH);
@@ -984,6 +1047,8 @@
#elif defined(TARGET_DARWIN)
+ /* FIXME: this ignores r->dev; check case gateway=0.0.0.0 works */
+
argv_printf (&argv, "%s add",
ROUTE_PATH);
@@ -1002,6 +1067,8 @@
#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
+ /* FIXME: this ignores r->dev; check case gateway=0.0.0.0 works */
+
argv_printf (&argv, "%s add",
ROUTE_PATH);
@@ -1313,7 +1380,7 @@
}
bool
-get_default_gateway (in_addr_t *gw, in_addr_t *netmask)
+get_default_gateway (net_gateway_t *gw, in_addr_t *netmask)
{
struct gc_arena gc = gc_new ();
bool ret_bool = false;
@@ -1324,7 +1391,8 @@
if (row)
{
- *gw = ntohl (row->dwForwardNextHop);
+ gw->net_gateway_addr = ntohl (row->dwForwardNextHop);
+ snprintf(gw->net_gateway_dev, IF_NAME_SIZE, "%X", row->dwForwardIfIndex);
if (netmask)
{
if (adapter_index_of_ip (adapters, *gw, NULL, netmask) == ~0)
@@ -1389,6 +1457,7 @@
bool ret = false;
DWORD status;
const DWORD if_index = windows_route_find_if_index (r, tt);
+ /* FIXME: this ignores r->dev */
if (if_index != ~0)
{
@@ -1463,6 +1532,7 @@
bool ret = false;
DWORD status;
const DWORD if_index = windows_route_find_if_index (r, tt);
+ /* FIXME: this ignores r->dev */
if (if_index != ~0)
{
@@ -1535,7 +1605,7 @@
#elif defined(TARGET_LINUX)
bool
-get_default_gateway (in_addr_t *gateway, in_addr_t *netmask)
+get_default_gateway (net_gateway_t *gateway, in_addr_t *netmask)
{
struct gc_arena gc = gc_new ();
bool ret = false;
@@ -1546,7 +1616,7 @@
int count = 0;
int best_count = 0;
unsigned int lowest_metric = ~0;
- in_addr_t best_gw = 0;
+ net_gateway_t best_gw = NET_GATEWAY_NULL;
while (fgets (line, sizeof (line), fp) != NULL)
{
if (count)
@@ -1555,27 +1625,32 @@
unsigned int mask_x = 0;
unsigned int gw_x = 0;
unsigned int metric = 0;
- const int np = sscanf (line, "%*s\t%x\t%x\t%*s\t%*s\t%*s\t%d\t%x",
+ char dev[IF_NAME_SIZE];
+ dev[0] = '\0';
+ const int np = sscanf (line, "%s\t%x\t%x\t%*s\t%*s\t%*s\t%d\t%x",
+ dev,
&net_x,
&gw_x,
&metric,
&mask_x);
- if (np == 4)
+ if (np == 5)
{
const in_addr_t net = ntohl (net_x);
const in_addr_t mask = ntohl (mask_x);
- const in_addr_t gw = ntohl (gw_x);
+ const in_addr_t gw_addr = ntohl (gw_x);
- dmsg (D_ROUTE_DEBUG, "GDG: route[%d] %s/%s/%s m=%u",
+ dmsg (D_ROUTE_DEBUG, "GDG: route[%d] %s/%s/%s m=%u dev=%s",
count,
print_in_addr_t ((in_addr_t) net, 0, &gc),
print_in_addr_t ((in_addr_t) mask, 0, &gc),
- print_in_addr_t ((in_addr_t) gw, 0, &gc),
- metric);
+ print_in_addr_t ((in_addr_t) gw_addr, 0, &gc),
+ metric,
+ dev);
if (!net && !mask && metric < lowest_metric)
{
- best_gw = gw;
+ best_gw.net_gateway_addr = gw_addr;
+ strncpy(best_gw.net_gateway_dev, dev, IF_NAME_SIZE);
lowest_metric = metric;
best_count = count;
}
@@ -1585,7 +1660,7 @@
}
fclose (fp);
- if (best_gw)
+ if (best_gw.net_gateway_addr || best_gw.net_gateway_dev[0])
{
*gateway = best_gw;
if (netmask)
@@ -1595,8 +1670,9 @@
ret = true;
}
- dmsg (D_ROUTE_DEBUG, "GDG: best=%s[%d] lm=%u",
- print_in_addr_t ((in_addr_t) best_gw, 0, &gc),
+ dmsg (D_ROUTE_DEBUG, "GDG: best=%s dev '%s' [%d] lm=%u",
+ print_in_addr_t ((in_addr_t) best_gw.net_gateway_addr, 0, &gc),
+ best_gw.net_gateway_dev,
best_count,
(unsigned int)lowest_metric);
}
@@ -1667,7 +1743,7 @@
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
bool
-get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
+get_default_gateway (net_gateway_t *ret, in_addr_t *netmask)
{
struct gc_arena gc = gc_new ();
int s, seq, l, pid, rtm_addrs, i;
@@ -1746,10 +1822,12 @@
if (gate != NULL )
{
- *ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
+ ret->net_gateway_addr = ntohl(((struct sockaddr_in
*)gate)->sin_addr.s_addr);
+ // FIXME: fill in ret->net_gateway_dev
#if 0
- msg (M_INFO, "gw %s",
- print_in_addr_t ((in_addr_t) *ret, 0, &gc));
+ msg (M_INFO, "gw %s dev %s",
+ print_in_addr_t ((in_addr_t) ret->net_gateway_addr, 0, &gc)
+ ret->net_gateway_dev);
#endif
if (netmask)
@@ -1829,7 +1907,7 @@
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
bool
-get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
+get_default_gateway (net_gateway_t *ret, in_addr_t *netmask)
{
struct gc_arena gc = gc_new ();
int s, seq, l, pid, rtm_addrs, i;
@@ -1908,10 +1986,12 @@
if (gate != NULL )
{
- *ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
+ ret->net_gateway_addr = ntohl(((struct sockaddr_in
*)gate)->sin_addr.s_addr);
+ // FIXME: fill in ret->net_gateway_dev
#if 0
- msg (M_INFO, "gw %s",
- print_in_addr_t ((in_addr_t) *ret, 0, &gc));
+ msg (M_INFO, "gw %s dev %s",
+ print_in_addr_t ((in_addr_t) ret->net_gateway_addr, 0, &gc)
+ ret->net_gateway_dev);
#endif
if (netmask)
@@ -1990,7 +2070,7 @@
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
bool
-get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
+get_default_gateway (net_gateway_t *ret, in_addr_t *netmask)
{
struct gc_arena gc = gc_new ();
int s, seq, l, rtm_addrs, i;
@@ -2070,10 +2150,12 @@
if (gate != NULL )
{
- *ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
+ ret->net_gateway_addr = ntohl(((struct sockaddr_in
*)gate)->sin_addr.s_addr);
+ // FIXME: fill in ret->net_gateway_dev
#if 0
- msg (M_INFO, "gw %s",
- print_in_addr_t ((in_addr_t) *ret, 0, &gc));
+ msg (M_INFO, "gw %s dev %s",
+ print_in_addr_t ((in_addr_t) ret->net_gateway_addr, 0, &gc)
+ ret->net_gateway_dev);
#endif
if (netmask)
@@ -2094,7 +2176,7 @@
#else
bool
-get_default_gateway (in_addr_t *ret, in_addr_t *netmask) /* PLATFORM-SPECIFIC
*/
+get_default_gateway (net_gateway_t *ret, in_addr_t *netmask) /*
PLATFORM-SPECIFIC */
{
return false;
}
Index: openvpn-2.1.0/route.h
===================================================================
--- openvpn-2.1.0.orig/route.h 2010-08-07 13:08:03.000000000 +0200
+++ openvpn-2.1.0/route.h 2010-08-07 13:08:23.000000000 +0200
@@ -56,11 +56,18 @@
in_addr_t bypass[N_ROUTE_BYPASS];
};
+#define IF_NAME_SIZE 128
+typedef struct {
+ in_addr_t net_gateway_addr;
+ char net_gateway_dev[IF_NAME_SIZE];
+} net_gateway_t;
+#define NET_GATEWAY_NULL {0, ""}
+
struct route_special_addr
{
in_addr_t remote_endpoint;
bool remote_endpoint_defined;
- in_addr_t net_gateway;
+ net_gateway_t net_gateway;
bool net_gateway_defined;
in_addr_t remote_host;
bool remote_host_defined;
@@ -98,6 +105,7 @@
in_addr_t network;
in_addr_t netmask;
in_addr_t gateway;
+ char dev[IF_NAME_SIZE];
bool metric_defined;
int metric;
};
@@ -161,7 +169,7 @@
bool is_special_addr (const char *addr_str);
-bool get_default_gateway (in_addr_t *ip, in_addr_t *netmask);
+bool get_default_gateway (net_gateway_t *gateway, in_addr_t *netmask);
/*
* Test if addr is reachable via a local interface (return ILA_LOCAL),
Index: openvpn-2.1.0/tun.c
===================================================================
--- openvpn-2.1.0.orig/tun.c 2010-08-07 13:08:23.000000000 +0200
+++ openvpn-2.1.0/tun.c 2010-08-07 13:08:23.000000000 +0200
@@ -271,12 +271,12 @@
const char *prefix)
{
struct gc_arena gc = gc_new ();
- in_addr_t lan_gw = 0;
+ net_gateway_t lan_gw = NET_GATEWAY_NULL;
in_addr_t lan_netmask = 0;
if (get_default_gateway (&lan_gw, &lan_netmask))
{
- const in_addr_t lan_network = lan_gw & lan_netmask;
+ const in_addr_t lan_network = lan_gw.net_gateway_addr & lan_netmask;
const in_addr_t network = ip & netmask;
/* do the two subnets defined by network/netmask and
lan_network/lan_netmask intersect? */
@@ -298,12 +298,12 @@
warn_on_use_of_common_subnets (void)
{
struct gc_arena gc = gc_new ();
- in_addr_t lan_gw = 0;
+ net_gateway_t lan_gw = NET_GATEWAY_NULL;
in_addr_t lan_netmask = 0;
if (get_default_gateway (&lan_gw, &lan_netmask))
{
- const in_addr_t lan_network = lan_gw & lan_netmask;
+ const in_addr_t lan_network = lan_gw.net_gateway_addr & lan_netmask;
if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100)
msg (M_WARN, "NOTE: your local LAN uses the extremely common subnet
address 192.168.0.x or 192.168.1.x. Be aware that this might create routing
conflicts if you connect to the VPN server from public locations such as
internet cafes that use the same subnet.");
}