summaryrefslogtreecommitdiffstats
path: root/route.c
diff options
context:
space:
mode:
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2005-10-20 08:13:27 +0000
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2005-10-20 08:13:27 +0000
commitc9241348218c1837a4c26504ea4a5acda01ce6be (patch)
tree9d2e35a2f4dc785384baaa25ae8d631aa5b0351c /route.c
parent348fb443b62d3212ff6ce837b1d6ac9a5e41b7f7 (diff)
downloadopenvpn-c9241348218c1837a4c26504ea4a5acda01ce6be.tar.gz
openvpn-c9241348218c1837a4c26504ea4a5acda01ce6be.tar.xz
openvpn-c9241348218c1837a4c26504ea4a5acda01ce6be.zip
Modified get_default_gateway code for Linux
to return the route with the smallest metric if multiple 0.0.0.0/0.0.0.0 entries are present. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@692 e7ae566f-a301-0410-adde-c780ea21d3b5
Diffstat (limited to 'route.c')
-rw-r--r--route.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/route.c b/route.c
index 255d35c..a0ae19b 100644
--- a/route.c
+++ b/route.c
@@ -1347,6 +1347,9 @@ get_default_gateway (in_addr_t *ret)
{
char line[256];
int count = 0;
+ int best_count = 0;
+ unsigned int lowest_metric = ~0;
+ in_addr_t best_gw = 0;
while (fgets (line, sizeof (line), fp) != NULL)
{
if (count)
@@ -1354,33 +1357,44 @@ get_default_gateway (in_addr_t *ret)
unsigned int net_x = 0;
unsigned int mask_x = 0;
unsigned int gw_x = 0;
- const int np = sscanf (line, "%*s\t%x\t%x\t%*s\t%*s\t%*s\t%*s\t%x",
+ unsigned int metric = 0;
+ const int np = sscanf (line, "%*s\t%x\t%x\t%*s\t%*s\t%*s\t%d\t%x",
&net_x,
&gw_x,
+ &metric,
&mask_x);
- if (np == 3)
+ if (np == 4)
{
const in_addr_t net = ntohl (net_x);
const in_addr_t mask = ntohl (mask_x);
const in_addr_t gw = ntohl (gw_x);
-#if 0
- msg (M_INFO, "route %s %s %s",
- 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));
-#endif
- if (!net && !mask)
+
+ dmsg (D_ROUTE_DEBUG, "GDG: route[%d] %s/%s/%s m=%u",
+ 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);
+
+ if (!net && !mask && metric < lowest_metric)
{
- fclose (fp);
- *ret = gw;
- gc_free (&gc);
- return true;
+ best_gw = gw;
+ lowest_metric = metric;
+ best_count = count;
}
}
}
++count;
}
fclose (fp);
+
+ if (best_gw)
+ *ret = best_gw;
+
+ dmsg (D_ROUTE_DEBUG, "GDG: best=%s[%d] lm=%u",
+ print_in_addr_t ((in_addr_t) best_gw, 0, &gc),
+ best_count,
+ (unsigned int)lowest_metric);
}
gc_free (&gc);