Updates to Tomato RAF including NGINX && PHP
[tomato.git] / release / src / router / openvpn / src / openvpn / route.c
blobdd69d8ed001c9a1c5b57ccfb77cdc82096d52cdb
1 /*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
8 * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 * Support routines for adding/deleting network routes.
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #elif defined(_MSC_VER)
32 #include "config-msvc.h"
33 #endif
35 #include "syshead.h"
37 #include "common.h"
38 #include "error.h"
39 #include "route.h"
40 #include "misc.h"
41 #include "socket.h"
42 #include "manage.h"
43 #include "win32.h"
44 #include "options.h"
46 #include "memdbg.h"
48 #ifdef WIN32
49 #define METRIC_NOT_USED ((DWORD)-1)
50 #endif
52 static void delete_route (struct route *r, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es);
54 static void get_bypass_addresses (struct route_bypass *rb, const unsigned int flags);
56 #ifdef ENABLE_DEBUG
58 static void
59 print_bypass_addresses (const struct route_bypass *rb)
61 struct gc_arena gc = gc_new ();
62 int i;
63 for (i = 0; i < rb->n_bypass; ++i)
65 msg (D_ROUTE, "ROUTE: bypass_host_route[%d]=%s",
67 print_in_addr_t (rb->bypass[i], 0, &gc));
69 gc_free (&gc);
72 #endif
74 static bool
75 add_bypass_address (struct route_bypass *rb, const in_addr_t a)
77 int i;
78 for (i = 0; i < rb->n_bypass; ++i)
80 if (a == rb->bypass[i]) /* avoid duplicates */
81 return true;
83 if (rb->n_bypass < N_ROUTE_BYPASS)
85 rb->bypass[rb->n_bypass++] = a;
86 return true;
88 else
90 return false;
94 struct route_option_list *
95 new_route_option_list (const int max_routes, struct gc_arena *a)
97 struct route_option_list *ret;
98 ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_option_list, struct route_option, max_routes, a);
99 ret->capacity = max_routes;
100 return ret;
103 struct route_ipv6_option_list *
104 new_route_ipv6_option_list (const int max_routes, struct gc_arena *a)
106 struct route_ipv6_option_list *ret;
107 ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_ipv6_option_list, struct route_ipv6_option, max_routes, a);
108 ret->capacity = max_routes;
109 return ret;
112 struct route_option_list *
113 clone_route_option_list (const struct route_option_list *src, struct gc_arena *a)
115 const size_t rl_size = array_mult_safe (sizeof(struct route_option), src->capacity, sizeof(struct route_option_list));
116 struct route_option_list *ret = gc_malloc (rl_size, false, a);
117 memcpy (ret, src, rl_size);
118 return ret;
121 struct route_ipv6_option_list *
122 clone_route_ipv6_option_list (const struct route_ipv6_option_list *src, struct gc_arena *a)
124 const size_t rl_size = array_mult_safe (sizeof(struct route_ipv6_option), src->capacity, sizeof(struct route_ipv6_option_list));
125 struct route_ipv6_option_list *ret = gc_malloc (rl_size, false, a);
126 memcpy (ret, src, rl_size);
127 return ret;
130 void
131 copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src)
133 const size_t src_size = array_mult_safe (sizeof(struct route_option), src->capacity, sizeof(struct route_option_list));
134 if (src->capacity > dest->capacity)
135 msg (M_FATAL, PACKAGE_NAME " ROUTE: (copy) number of route options in src (%d) is greater than route list capacity in dest (%d)", src->capacity, dest->capacity);
136 memcpy (dest, src, src_size);
139 void
140 copy_route_ipv6_option_list (struct route_ipv6_option_list *dest,
141 const struct route_ipv6_option_list *src)
143 const size_t src_size = array_mult_safe (sizeof(struct route_ipv6_option), src->capacity, sizeof(struct route_ipv6_option_list));
144 if (src->capacity > dest->capacity)
145 msg (M_FATAL, PACKAGE_NAME " ROUTE: (copy) number of route options in src (%d) is greater than route list capacity in dest (%d)", src->capacity, dest->capacity);
146 memcpy (dest, src, src_size);
149 struct route_list *
150 new_route_list (const int max_routes, struct gc_arena *a)
152 struct route_list *ret;
153 ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_list, struct route, max_routes, a);
154 ret->capacity = max_routes;
155 return ret;
158 struct route_ipv6_list *
159 new_route_ipv6_list (const int max_routes, struct gc_arena *a)
161 struct route_ipv6_list *ret;
162 ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_ipv6_list, struct route_ipv6, max_routes, a);
163 ret->capacity = max_routes;
164 return ret;
167 static const char *
168 route_string (const struct route *r, struct gc_arena *gc)
170 struct buffer out = alloc_buf_gc (256, gc);
171 buf_printf (&out, "ROUTE network %s netmask %s gateway %s",
172 print_in_addr_t (r->network, 0, gc),
173 print_in_addr_t (r->netmask, 0, gc),
174 print_in_addr_t (r->gateway, 0, gc)
176 if (r->flags & RT_METRIC_DEFINED)
177 buf_printf (&out, " metric %d", r->metric);
178 return BSTR (&out);
181 static bool
182 is_route_parm_defined (const char *parm)
184 if (!parm)
185 return false;
186 if (!strcmp (parm, "default"))
187 return false;
188 return true;
191 static void
192 setenv_route_addr (struct env_set *es, const char *key, const in_addr_t addr, int i)
194 struct gc_arena gc = gc_new ();
195 struct buffer name = alloc_buf_gc (256, &gc);
196 if (i >= 0)
197 buf_printf (&name, "route_%s_%d", key, i);
198 else
199 buf_printf (&name, "route_%s", key);
200 setenv_str (es, BSTR (&name), print_in_addr_t (addr, 0, &gc));
201 gc_free (&gc);
204 static bool
205 get_special_addr (const struct route_list *rl,
206 const char *string,
207 in_addr_t *out,
208 bool *status)
210 if (status)
211 *status = true;
212 if (!strcmp (string, "vpn_gateway"))
214 if (rl)
216 if (rl->spec.flags & RTSA_REMOTE_ENDPOINT)
217 *out = rl->spec.remote_endpoint;
218 else
220 msg (M_INFO, PACKAGE_NAME " ROUTE: vpn_gateway undefined");
221 if (status)
222 *status = false;
225 return true;
227 else if (!strcmp (string, "net_gateway"))
229 if (rl)
231 if (rl->rgi.flags & RGI_ADDR_DEFINED)
232 *out = rl->rgi.gateway.addr;
233 else
235 msg (M_INFO, PACKAGE_NAME " ROUTE: net_gateway undefined -- unable to get default gateway from system");
236 if (status)
237 *status = false;
240 return true;
242 else if (!strcmp (string, "remote_host"))
244 if (rl)
246 if (rl->spec.flags & RTSA_REMOTE_HOST)
247 *out = rl->spec.remote_host;
248 else
250 msg (M_INFO, PACKAGE_NAME " ROUTE: remote_host undefined");
251 if (status)
252 *status = false;
255 return true;
257 return false;
260 bool
261 is_special_addr (const char *addr_str)
263 if (addr_str)
264 return get_special_addr (NULL, addr_str, NULL, NULL);
265 else
266 return false;
269 static bool
270 init_route (struct route *r,
271 struct addrinfo **network_list,
272 const struct route_option *ro,
273 const struct route_list *rl)
275 const in_addr_t default_netmask = IPV4_NETMASK_HOST;
276 bool status;
277 int ret;
278 struct in_addr special;
280 CLEAR (*r);
281 r->option = ro;
283 /* network */
285 if (!is_route_parm_defined (ro->network))
287 goto fail;
291 /* get_special_addr replaces specialaddr with a special ip addr
292 like gw. getaddrinfo is called to convert a a addrinfo struct */
294 if(get_special_addr (rl, ro->network, &special.s_addr, &status))
296 special.s_addr = htonl(special.s_addr);
297 ret = openvpn_getaddrinfo(0, inet_ntoa(special), 0, NULL,
298 AF_INET, network_list);
300 else
301 ret = openvpn_getaddrinfo(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL,
302 ro->network, 0, NULL, AF_INET, network_list);
304 status = (ret == 0);
306 if (!status)
307 goto fail;
309 /* netmask */
311 if (is_route_parm_defined (ro->netmask))
313 r->netmask = getaddr (
314 GETADDR_HOST_ORDER
315 | GETADDR_WARN_ON_SIGNAL,
316 ro->netmask,
318 &status,
319 NULL);
320 if (!status)
321 goto fail;
323 else
324 r->netmask = default_netmask;
326 /* gateway */
328 if (is_route_parm_defined (ro->gateway))
330 if (!get_special_addr (rl, ro->gateway, &r->gateway, &status))
332 r->gateway = getaddr (
333 GETADDR_RESOLVE
334 | GETADDR_HOST_ORDER
335 | GETADDR_WARN_ON_SIGNAL,
336 ro->gateway,
338 &status,
339 NULL);
341 if (!status)
342 goto fail;
344 else
346 if (rl->spec.flags & RTSA_REMOTE_ENDPOINT)
347 r->gateway = rl->spec.remote_endpoint;
348 else
350 msg (M_WARN, PACKAGE_NAME " ROUTE: " PACKAGE_NAME " needs a gateway parameter for a --route option and no default was specified by either --route-gateway or --ifconfig options");
351 goto fail;
355 /* metric */
357 r->metric = 0;
358 if (is_route_parm_defined (ro->metric))
360 r->metric = atoi (ro->metric);
361 if (r->metric < 0)
363 msg (M_WARN, PACKAGE_NAME " ROUTE: route metric for network %s (%s) must be >= 0",
364 ro->network,
365 ro->metric);
366 goto fail;
368 r->flags |= RT_METRIC_DEFINED;
370 else if (rl->spec.flags & RTSA_DEFAULT_METRIC)
372 r->metric = rl->spec.default_metric;
373 r->flags |= RT_METRIC_DEFINED;
376 r->flags |= RT_DEFINED;
378 return true;
380 fail:
381 msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve route for host/network: %s",
382 ro->network);
383 return false;
386 static bool
387 init_route_ipv6 (struct route_ipv6 *r6,
388 const struct route_ipv6_option *r6o,
389 const struct route_ipv6_list *rl6 )
391 r6->defined = false;
393 if ( !get_ipv6_addr( r6o->prefix, &r6->network, &r6->netbits, NULL, M_WARN ))
394 goto fail;
396 /* gateway */
397 if (is_route_parm_defined (r6o->gateway))
399 if ( inet_pton( AF_INET6, r6o->gateway, &r6->gateway ) != 1 )
401 msg( M_WARN, PACKAGE_NAME "ROUTE6: cannot parse gateway spec '%s'", r6o->gateway );
404 else if (rl6->remote_endpoint_defined)
406 r6->gateway = rl6->remote_endpoint_ipv6;
408 else
410 msg (M_WARN, PACKAGE_NAME " ROUTE6: " PACKAGE_NAME " needs a gateway parameter for a --route-ipv6 option and no default was specified by either --route-ipv6-gateway or --ifconfig-ipv6 options");
411 goto fail;
414 /* metric */
416 r6->metric_defined = false;
417 r6->metric = -1;
418 if (is_route_parm_defined (r6o->metric))
420 r6->metric = atoi (r6o->metric);
421 if (r6->metric < 0)
423 msg (M_WARN, PACKAGE_NAME " ROUTE: route metric for network %s (%s) must be >= 0",
424 r6o->prefix,
425 r6o->metric);
426 goto fail;
428 r6->metric_defined = true;
430 else if (rl6->default_metric_defined)
432 r6->metric = rl6->default_metric;
433 r6->metric_defined = true;
436 r6->defined = true;
438 return true;
440 fail:
441 msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve route for host/network: %s",
442 r6o->prefix);
443 r6->defined = false;
444 return false;
447 void
448 add_route_to_option_list (struct route_option_list *l,
449 const char *network,
450 const char *netmask,
451 const char *gateway,
452 const char *metric)
454 struct route_option *ro;
455 if (l->n >= l->capacity)
456 msg (M_FATAL, PACKAGE_NAME " ROUTE: cannot add more than %d routes -- please increase the max-routes option in the client configuration file",
457 l->capacity);
458 ro = &l->routes[l->n];
459 ro->network = network;
460 ro->netmask = netmask;
461 ro->gateway = gateway;
462 ro->metric = metric;
463 ++l->n;
466 void
467 add_route_ipv6_to_option_list (struct route_ipv6_option_list *l,
468 const char *prefix,
469 const char *gateway,
470 const char *metric)
472 struct route_ipv6_option *ro;
473 if (l->n >= l->capacity)
474 msg (M_FATAL, PACKAGE_NAME " ROUTE: cannot add more than %d IPv6 routes -- please increase the max-routes option in the client configuration file",
475 l->capacity);
476 ro = &l->routes_ipv6[l->n];
477 ro->prefix = prefix;
478 ro->gateway = gateway;
479 ro->metric = metric;
480 ++l->n;
483 void
484 clear_route_list (struct route_list *rl)
486 const int capacity = rl->capacity;
487 const size_t rl_size = array_mult_safe (sizeof(struct route), capacity, sizeof(struct route_list));
488 memset(rl, 0, rl_size);
489 rl->capacity = capacity;
492 void
493 clear_route_ipv6_list (struct route_ipv6_list *rl6)
495 const int capacity = rl6->capacity;
496 const size_t rl6_size = array_mult_safe (sizeof(struct route_ipv6), capacity, sizeof(struct route_ipv6_list));
497 memset(rl6, 0, rl6_size);
498 rl6->capacity = capacity;
501 void
502 route_list_add_vpn_gateway (struct route_list *rl,
503 struct env_set *es,
504 const in_addr_t addr)
506 rl->spec.remote_endpoint = addr;
507 rl->spec.flags |= RTSA_REMOTE_ENDPOINT;
508 setenv_route_addr (es, "vpn_gateway", rl->spec.remote_endpoint, -1);
511 static void
512 add_block_local_item (struct route_list *rl,
513 const struct route_gateway_address *gateway,
514 in_addr_t target)
516 const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED);
517 if ((rl->rgi.flags & rgi_needed) == rgi_needed
518 && rl->rgi.gateway.netmask < 0xFFFFFFFF
519 && (rl->n)+2 <= rl->capacity)
521 struct route r;
522 unsigned int l2;
524 /* split a route into two smaller blocking routes, and direct them to target */
525 CLEAR(r);
526 r.flags = RT_DEFINED;
527 r.gateway = target;
528 r.network = gateway->addr & gateway->netmask;
529 l2 = ((~gateway->netmask)+1)>>1;
530 r.netmask = ~(l2-1);
531 rl->routes[rl->n++] = r;
532 r.network += l2;
533 rl->routes[rl->n++] = r;
537 static void
538 add_block_local (struct route_list *rl)
540 const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED);
541 if ((rl->flags & RG_BLOCK_LOCAL)
542 && (rl->rgi.flags & rgi_needed) == rgi_needed
543 && (rl->spec.flags & RTSA_REMOTE_ENDPOINT)
544 && rl->spec.remote_host_local != TLA_LOCAL)
546 size_t i;
548 /* add bypass for gateway addr */
549 add_bypass_address (&rl->spec.bypass, rl->rgi.gateway.addr);
551 /* block access to local subnet */
552 add_block_local_item (rl, &rl->rgi.gateway, rl->spec.remote_endpoint);
554 /* process additional subnets on gateway interface */
555 for (i = 0; i < rl->rgi.n_addrs; ++i)
557 const struct route_gateway_address *gwa = &rl->rgi.addrs[i];
558 /* omit the add/subnet in &rl->rgi which we processed above */
559 if (!((rl->rgi.gateway.addr & rl->rgi.gateway.netmask) == (gwa->addr & gwa->netmask)
560 && rl->rgi.gateway.netmask == gwa->netmask))
561 add_block_local_item (rl, gwa, rl->spec.remote_endpoint);
566 bool
567 init_route_list (struct route_list *rl,
568 const struct route_option_list *opt,
569 const char *remote_endpoint,
570 int default_metric,
571 in_addr_t remote_host,
572 struct env_set *es)
574 struct gc_arena gc = gc_new ();
575 bool ret = true;
577 clear_route_list (rl);
579 rl->flags = opt->flags;
581 if (remote_host)
583 rl->spec.remote_host = remote_host;
584 rl->spec.flags |= RTSA_REMOTE_HOST;
587 if (default_metric)
589 rl->spec.default_metric = default_metric;
590 rl->spec.flags |= RTSA_DEFAULT_METRIC;
593 get_default_gateway (&rl->rgi);
594 if (rl->rgi.flags & RGI_ADDR_DEFINED)
596 setenv_route_addr (es, "net_gateway", rl->rgi.gateway.addr, -1);
597 #ifdef ENABLE_DEBUG
598 print_default_gateway (D_ROUTE, &rl->rgi);
599 #endif
601 else
603 dmsg (D_ROUTE, "ROUTE: default_gateway=UNDEF");
606 if (rl->spec.flags & RTSA_REMOTE_HOST)
607 rl->spec.remote_host_local = test_local_addr (remote_host, &rl->rgi);
609 if (is_route_parm_defined (remote_endpoint))
611 bool defined = false;
612 rl->spec.remote_endpoint = getaddr (
613 GETADDR_RESOLVE
614 | GETADDR_HOST_ORDER
615 | GETADDR_WARN_ON_SIGNAL,
616 remote_endpoint,
618 &defined,
619 NULL);
621 if (defined)
623 setenv_route_addr (es, "vpn_gateway", rl->spec.remote_endpoint, -1);
624 rl->spec.flags |= RTSA_REMOTE_ENDPOINT;
626 else
628 msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve default gateway: %s",
629 remote_endpoint);
630 ret = false;
634 if (rl->flags & RG_ENABLE)
636 add_block_local (rl);
637 get_bypass_addresses (&rl->spec.bypass, rl->flags);
638 #ifdef ENABLE_DEBUG
639 print_bypass_addresses (&rl->spec.bypass);
640 #endif
643 /* parse the routes from opt to rl */
645 int i = 0;
646 int j = rl->n;
647 bool warned = false;
648 for (i = 0; i < opt->n; ++i)
650 struct addrinfo* netlist;
651 struct route r;
653 if (!init_route (&r,
654 &netlist,
655 &opt->routes[i],
656 rl))
657 ret = false;
658 else
660 struct addrinfo* curele;
661 for (curele = netlist; curele; curele = curele->ai_next)
663 if (j < rl->capacity)
665 r.network = ntohl(((struct sockaddr_in*)(curele)->ai_addr)->sin_addr.s_addr);
666 rl->routes[j++] = r;
668 else
670 if (!warned)
672 msg (M_WARN, PACKAGE_NAME " ROUTE: routes dropped because number of expanded routes is greater than route list capacity (%d)", rl->capacity);
673 warned = true;
677 freeaddrinfo(netlist);
680 rl->n = j;
683 gc_free (&gc);
684 return ret;
687 bool
688 init_route_ipv6_list (struct route_ipv6_list *rl6,
689 const struct route_ipv6_option_list *opt6,
690 const char *remote_endpoint,
691 int default_metric,
692 struct env_set *es)
694 struct gc_arena gc = gc_new ();
695 bool ret = true;
697 clear_route_ipv6_list (rl6);
699 rl6->flags = opt6->flags;
701 if (default_metric >= 0 )
703 rl6->default_metric = default_metric;
704 rl6->default_metric_defined = true;
707 /* "default_gateway" is stuff for "redirect-gateway", which we don't
708 * do for IPv6 yet -> TODO
711 dmsg (D_ROUTE, "ROUTE6: default_gateway=UNDEF");
714 if ( is_route_parm_defined( remote_endpoint ))
716 if ( inet_pton( AF_INET6, remote_endpoint,
717 &rl6->remote_endpoint_ipv6) == 1 )
719 rl6->remote_endpoint_defined = true;
721 else
723 msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve default gateway: %s", remote_endpoint);
724 ret = false;
727 else
728 rl6->remote_endpoint_defined = false;
731 if (!(opt6->n >= 0 && opt6->n <= rl6->capacity))
732 msg (M_FATAL, PACKAGE_NAME " ROUTE6: (init) number of route options (%d) is greater than route list capacity (%d)", opt6->n, rl6->capacity);
734 /* parse the routes from opt to rl6 */
736 int i, j = 0;
737 for (i = 0; i < opt6->n; ++i)
739 if (!init_route_ipv6 (&rl6->routes_ipv6[j],
740 &opt6->routes_ipv6[i],
741 rl6 ))
742 ret = false;
743 else
744 ++j;
746 rl6->n = j;
749 gc_free (&gc);
750 return ret;
753 static void
754 add_route3 (in_addr_t network,
755 in_addr_t netmask,
756 in_addr_t gateway,
757 const struct tuntap *tt,
758 unsigned int flags,
759 const struct route_gateway_info *rgi,
760 const struct env_set *es)
762 struct route r;
763 CLEAR (r);
764 r.flags = RT_DEFINED;
765 r.network = network;
766 r.netmask = netmask;
767 r.gateway = gateway;
768 add_route (&r, tt, flags, rgi, es);
771 static void
772 del_route3 (in_addr_t network,
773 in_addr_t netmask,
774 in_addr_t gateway,
775 const struct tuntap *tt,
776 unsigned int flags,
777 const struct route_gateway_info *rgi,
778 const struct env_set *es)
780 struct route r;
781 CLEAR (r);
782 r.flags = RT_DEFINED|RT_ADDED;
783 r.network = network;
784 r.netmask = netmask;
785 r.gateway = gateway;
786 delete_route (&r, tt, flags, rgi, es);
789 static void
790 add_bypass_routes (struct route_bypass *rb,
791 in_addr_t gateway,
792 const struct tuntap *tt,
793 unsigned int flags,
794 const struct route_gateway_info *rgi,
795 const struct env_set *es)
797 int i;
798 for (i = 0; i < rb->n_bypass; ++i)
800 if (rb->bypass[i])
801 add_route3 (rb->bypass[i],
802 IPV4_NETMASK_HOST,
803 gateway,
805 flags | ROUTE_REF_GW,
806 rgi,
807 es);
811 static void
812 del_bypass_routes (struct route_bypass *rb,
813 in_addr_t gateway,
814 const struct tuntap *tt,
815 unsigned int flags,
816 const struct route_gateway_info *rgi,
817 const struct env_set *es)
819 int i;
820 for (i = 0; i < rb->n_bypass; ++i)
822 if (rb->bypass[i])
823 del_route3 (rb->bypass[i],
824 IPV4_NETMASK_HOST,
825 gateway,
827 flags | ROUTE_REF_GW,
828 rgi,
829 es);
833 static void
834 redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
836 const char err[] = "NOTE: unable to redirect default gateway --";
838 if ( rl && rl->flags & RG_ENABLE )
840 if (!(rl->spec.flags & RTSA_REMOTE_ENDPOINT))
842 msg (M_WARN, "%s VPN gateway parameter (--route-gateway or --ifconfig) is missing", err);
844 else if (!(rl->rgi.flags & RGI_ADDR_DEFINED))
846 msg (M_WARN, "%s Cannot read current default gateway from system", err);
848 else if (!(rl->spec.flags & RTSA_REMOTE_HOST))
850 msg (M_WARN, "%s Cannot obtain current remote host address", err);
852 else
854 bool local = BOOL_CAST(rl->flags & RG_LOCAL);
855 if (rl->flags & RG_AUTO_LOCAL) {
856 const int tla = rl->spec.remote_host_local;
857 if (tla == TLA_NONLOCAL)
859 dmsg (D_ROUTE, "ROUTE remote_host is NOT LOCAL");
860 local = false;
862 else if (tla == TLA_LOCAL)
864 dmsg (D_ROUTE, "ROUTE remote_host is LOCAL");
865 local = true;
868 if (!local)
870 /* route remote host to original default gateway */
871 /* if remote_host is not ipv4 (ie: ipv6), just skip
872 * adding this special /32 route */
873 if (rl->spec.remote_host != IPV4_INVALID_ADDR) {
874 add_route3 (rl->spec.remote_host,
875 IPV4_NETMASK_HOST,
876 rl->rgi.gateway.addr,
878 flags | ROUTE_REF_GW,
879 &rl->rgi,
880 es);
881 rl->iflags |= RL_DID_LOCAL;
882 } else {
883 dmsg (D_ROUTE, "ROUTE remote_host protocol differs from tunneled");
887 /* route DHCP/DNS server traffic through original default gateway */
888 add_bypass_routes (&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es);
890 if (rl->flags & RG_REROUTE_GW)
892 if (rl->flags & RG_DEF1)
894 /* add new default route (1st component) */
895 add_route3 (0x00000000,
896 0x80000000,
897 rl->spec.remote_endpoint,
899 flags,
900 &rl->rgi,
901 es);
903 /* add new default route (2nd component) */
904 add_route3 (0x80000000,
905 0x80000000,
906 rl->spec.remote_endpoint,
908 flags,
909 &rl->rgi,
910 es);
912 else
914 /* delete default route */
915 del_route3 (0,
917 rl->rgi.gateway.addr,
919 flags | ROUTE_REF_GW,
920 &rl->rgi,
921 es);
923 /* add new default route */
924 add_route3 (0,
926 rl->spec.remote_endpoint,
928 flags,
929 &rl->rgi,
930 es);
934 /* set a flag so we can undo later */
935 rl->iflags |= RL_DID_REDIRECT_DEFAULT_GATEWAY;
940 static void
941 undo_redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
943 if ( rl && rl->iflags & RL_DID_REDIRECT_DEFAULT_GATEWAY )
945 /* delete remote host route */
946 if (rl->iflags & RL_DID_LOCAL)
948 del_route3 (rl->spec.remote_host,
949 IPV4_NETMASK_HOST,
950 rl->rgi.gateway.addr,
952 flags | ROUTE_REF_GW,
953 &rl->rgi,
954 es);
955 rl->iflags &= ~RL_DID_LOCAL;
958 /* delete special DHCP/DNS bypass route */
959 del_bypass_routes (&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es);
961 if (rl->flags & RG_REROUTE_GW)
963 if (rl->flags & RG_DEF1)
965 /* delete default route (1st component) */
966 del_route3 (0x00000000,
967 0x80000000,
968 rl->spec.remote_endpoint,
970 flags,
971 &rl->rgi,
972 es);
974 /* delete default route (2nd component) */
975 del_route3 (0x80000000,
976 0x80000000,
977 rl->spec.remote_endpoint,
979 flags,
980 &rl->rgi,
981 es);
983 else
985 /* delete default route */
986 del_route3 (0,
988 rl->spec.remote_endpoint,
990 flags,
991 &rl->rgi,
992 es);
994 /* restore original default route */
995 add_route3 (0,
997 rl->rgi.gateway.addr,
999 flags | ROUTE_REF_GW,
1000 &rl->rgi,
1001 es);
1005 rl->iflags &= ~RL_DID_REDIRECT_DEFAULT_GATEWAY;
1009 void
1010 add_routes (struct route_list *rl, struct route_ipv6_list *rl6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
1012 redirect_default_route_to_vpn (rl, tt, flags, es);
1013 if ( rl && !(rl->iflags & RL_ROUTES_ADDED) )
1015 int i;
1017 #ifdef ENABLE_MANAGEMENT
1018 if (management && rl->n)
1020 management_set_state (management,
1021 OPENVPN_STATE_ADD_ROUTES,
1022 NULL,
1026 #endif
1028 for (i = 0; i < rl->n; ++i)
1030 struct route *r = &rl->routes[i];
1031 check_subnet_conflict (r->network, r->netmask, "route");
1032 if (flags & ROUTE_DELETE_FIRST)
1033 delete_route (r, tt, flags, &rl->rgi, es);
1034 add_route (r, tt, flags, &rl->rgi, es);
1036 rl->iflags |= RL_ROUTES_ADDED;
1038 if (rl6 && !rl6->routes_added)
1040 int i;
1042 for (i = 0; i < rl6->n; ++i)
1044 struct route_ipv6 *r = &rl6->routes_ipv6[i];
1045 if (flags & ROUTE_DELETE_FIRST)
1046 delete_route_ipv6 (r, tt, flags, es);
1047 add_route_ipv6 (r, tt, flags, es);
1049 rl6->routes_added = true;
1053 void
1054 delete_routes (struct route_list *rl, struct route_ipv6_list *rl6,
1055 const struct tuntap *tt, unsigned int flags, const struct env_set *es)
1057 if ( rl && rl->iflags & RL_ROUTES_ADDED )
1059 int i;
1060 for (i = rl->n - 1; i >= 0; --i)
1062 struct route * r = &rl->routes[i];
1063 delete_route (r, tt, flags, &rl->rgi, es);
1065 rl->iflags &= ~RL_ROUTES_ADDED;
1068 undo_redirect_default_route_to_vpn (rl, tt, flags, es);
1070 if ( rl )
1072 clear_route_list (rl);
1075 if ( rl6 && rl6->routes_added )
1077 int i;
1078 for (i = rl6->n - 1; i >= 0; --i)
1080 const struct route_ipv6 *r6 = &rl6->routes_ipv6[i];
1081 delete_route_ipv6 (r6, tt, flags, es);
1083 rl6->routes_added = false;
1086 if ( rl6 )
1088 clear_route_ipv6_list (rl6);
1092 #ifdef ENABLE_DEBUG
1094 static const char *
1095 show_opt (const char *option)
1097 if (!option)
1098 return "nil";
1099 else
1100 return option;
1103 static void
1104 print_route_option (const struct route_option *ro, int level)
1106 msg (level, " route %s/%s/%s/%s",
1107 show_opt (ro->network),
1108 show_opt (ro->netmask),
1109 show_opt (ro->gateway),
1110 show_opt (ro->metric));
1113 void
1114 print_route_options (const struct route_option_list *rol,
1115 int level)
1117 int i;
1118 if (rol->flags & RG_ENABLE)
1119 msg (level, " [redirect_default_gateway local=%d]",
1120 (rol->flags & RG_LOCAL) != 0);
1121 for (i = 0; i < rol->n; ++i)
1122 print_route_option (&rol->routes[i], level);
1125 void
1126 print_default_gateway(const int msglevel, const struct route_gateway_info *rgi)
1128 struct gc_arena gc = gc_new ();
1129 if (rgi->flags & RGI_ADDR_DEFINED)
1131 struct buffer out = alloc_buf_gc (256, &gc);
1132 buf_printf (&out, "ROUTE_GATEWAY");
1133 if (rgi->flags & RGI_ON_LINK)
1134 buf_printf (&out, " ON_LINK");
1135 else
1136 buf_printf (&out, " %s", print_in_addr_t (rgi->gateway.addr, 0, &gc));
1137 if (rgi->flags & RGI_NETMASK_DEFINED)
1138 buf_printf (&out, "/%s", print_in_addr_t (rgi->gateway.netmask, 0, &gc));
1139 #ifdef WIN32
1140 if (rgi->flags & RGI_IFACE_DEFINED)
1141 buf_printf (&out, " I=%u", (unsigned int)rgi->adapter_index);
1142 #else
1143 if (rgi->flags & RGI_IFACE_DEFINED)
1144 buf_printf (&out, " IFACE=%s", rgi->iface);
1145 #endif
1146 if (rgi->flags & RGI_HWADDR_DEFINED)
1147 buf_printf (&out, " HWADDR=%s", format_hex_ex (rgi->hwaddr, 6, 0, 1, ":", &gc));
1148 msg (msglevel, "%s", BSTR (&out));
1150 gc_free (&gc);
1153 #endif
1155 static void
1156 print_route (const struct route *r, int level)
1158 struct gc_arena gc = gc_new ();
1159 if (r->flags & RT_DEFINED)
1160 msg (level, "%s", route_string (r, &gc));
1161 gc_free (&gc);
1164 void
1165 print_routes (const struct route_list *rl, int level)
1167 int i;
1168 for (i = 0; i < rl->n; ++i)
1169 print_route (&rl->routes[i], level);
1172 static void
1173 setenv_route (struct env_set *es, const struct route *r, int i)
1175 struct gc_arena gc = gc_new ();
1176 if (r->flags & RT_DEFINED)
1178 setenv_route_addr (es, "network", r->network, i);
1179 setenv_route_addr (es, "netmask", r->netmask, i);
1180 setenv_route_addr (es, "gateway", r->gateway, i);
1182 if (r->flags & RT_METRIC_DEFINED)
1184 struct buffer name = alloc_buf_gc (256, &gc);
1185 buf_printf (&name, "route_metric_%d", i);
1186 setenv_int (es, BSTR (&name), r->metric);
1189 gc_free (&gc);
1192 void
1193 setenv_routes (struct env_set *es, const struct route_list *rl)
1195 int i;
1196 for (i = 0; i < rl->n; ++i)
1197 setenv_route (es, &rl->routes[i], i + 1);
1200 static void
1201 setenv_route_ipv6 (struct env_set *es, const struct route_ipv6 *r6, int i)
1203 struct gc_arena gc = gc_new ();
1204 if (r6->defined)
1206 struct buffer name1 = alloc_buf_gc( 256, &gc );
1207 struct buffer val = alloc_buf_gc( 256, &gc );
1208 struct buffer name2 = alloc_buf_gc( 256, &gc );
1210 buf_printf( &name1, "route_ipv6_network_%d", i );
1211 buf_printf( &val, "%s/%d", print_in6_addr( r6->network, 0, &gc ),
1212 r6->netbits );
1213 setenv_str( es, BSTR(&name1), BSTR(&val) );
1215 buf_printf( &name2, "route_ipv6_gateway_%d", i );
1216 setenv_str( es, BSTR(&name2), print_in6_addr( r6->gateway, 0, &gc ));
1218 gc_free (&gc);
1220 void
1221 setenv_routes_ipv6 (struct env_set *es, const struct route_ipv6_list *rl6)
1223 int i;
1224 for (i = 0; i < rl6->n; ++i)
1225 setenv_route_ipv6 (es, &rl6->routes_ipv6[i], i + 1);
1229 * local_route() determines whether the gateway of a provided host
1230 * route is on the same interface that owns the default gateway.
1231 * It uses the data structure
1232 * returned by get_default_gateway() (struct route_gateway_info)
1233 * to determine this. If the route is local, LR_MATCH is returned.
1234 * When adding routes into the kernel, if LR_MATCH is defined for
1235 * a given route, the route should explicitly reference the default
1236 * gateway interface as the route destination. For example, here
1237 * is an example on Linux that uses LR_MATCH:
1239 * route add -net 10.10.0.1 netmask 255.255.255.255 dev eth0
1241 * This capability is needed by the "default-gateway block-local"
1242 * directive, to allow client access to the local subnet to be
1243 * blocked but still allow access to the local default gateway.
1246 /* local_route() return values */
1247 #define LR_NOMATCH 0 /* route is not local */
1248 #define LR_MATCH 1 /* route is local */
1249 #define LR_ERROR 2 /* caller should abort adding route */
1251 static int
1252 local_route (in_addr_t network,
1253 in_addr_t netmask,
1254 in_addr_t gateway,
1255 const struct route_gateway_info *rgi)
1257 /* set LR_MATCH on local host routes */
1258 const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED|RGI_IFACE_DEFINED);
1259 if (rgi
1260 && (rgi->flags & rgi_needed) == rgi_needed
1261 && gateway == rgi->gateway.addr
1262 && netmask == 0xFFFFFFFF)
1264 if (((network ^ rgi->gateway.addr) & rgi->gateway.netmask) == 0)
1265 return LR_MATCH;
1266 else
1268 /* examine additional subnets on gateway interface */
1269 size_t i;
1270 for (i = 0; i < rgi->n_addrs; ++i)
1272 const struct route_gateway_address *gwa = &rgi->addrs[i];
1273 if (((network ^ gwa->addr) & gwa->netmask) == 0)
1274 return LR_MATCH;
1278 return LR_NOMATCH;
1281 /* Return true if the "on-link" form of the route should be used. This is when the gateway for a
1282 a route is specified as an interface rather than an address. */
1283 static inline bool
1284 is_on_link (const int is_local_route, const unsigned int flags, const struct route_gateway_info *rgi)
1286 return rgi && (is_local_route == LR_MATCH || ((flags & ROUTE_REF_GW) && (rgi->flags & RGI_ON_LINK)));
1289 void
1290 add_route (struct route *r,
1291 const struct tuntap *tt,
1292 unsigned int flags,
1293 const struct route_gateway_info *rgi, /* may be NULL */
1294 const struct env_set *es)
1296 struct gc_arena gc;
1297 struct argv argv;
1298 const char *network;
1299 const char *netmask;
1300 const char *gateway;
1301 bool status = false;
1302 int is_local_route;
1304 if (!(r->flags & RT_DEFINED))
1305 return;
1307 gc_init (&gc);
1308 argv_init (&argv);
1310 network = print_in_addr_t (r->network, 0, &gc);
1311 netmask = print_in_addr_t (r->netmask, 0, &gc);
1312 gateway = print_in_addr_t (r->gateway, 0, &gc);
1314 is_local_route = local_route(r->network, r->netmask, r->gateway, rgi);
1315 if (is_local_route == LR_ERROR)
1316 goto done;
1318 #if defined(TARGET_LINUX)
1319 #ifdef ENABLE_IPROUTE
1320 /* FIXME -- add on-link support for ENABLE_IPROUTE */
1321 argv_printf (&argv, "%s route add %s/%d via %s",
1322 iproute_path,
1323 network,
1324 count_netmask_bits(netmask),
1325 gateway);
1326 if (r->flags & RT_METRIC_DEFINED)
1327 argv_printf_cat (&argv, "metric %d", r->metric);
1329 #else
1330 argv_printf (&argv, "%s add -net %s netmask %s",
1331 ROUTE_PATH,
1332 network,
1333 netmask);
1334 if (r->flags & RT_METRIC_DEFINED)
1335 argv_printf_cat (&argv, "metric %d", r->metric);
1336 if (is_on_link (is_local_route, flags, rgi))
1337 argv_printf_cat (&argv, "dev %s", rgi->iface);
1338 else
1339 argv_printf_cat (&argv, "gw %s", gateway);
1341 #endif /*ENABLE_IPROUTE*/
1342 argv_msg (D_ROUTE, &argv);
1343 status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route add command failed");
1345 #elif defined (WIN32)
1347 DWORD ai = TUN_ADAPTER_INDEX_INVALID;
1348 argv_printf (&argv, "%s%sc ADD %s MASK %s %s",
1349 get_win_sys_path(),
1350 WIN_ROUTE_PATH_SUFFIX,
1351 network,
1352 netmask,
1353 gateway);
1354 if (r->flags & RT_METRIC_DEFINED)
1355 argv_printf_cat (&argv, "METRIC %d", r->metric);
1356 if (is_on_link (is_local_route, flags, rgi))
1358 ai = rgi->adapter_index;
1359 argv_printf_cat (&argv, "IF %u", (unsigned int)ai);
1362 argv_msg (D_ROUTE, &argv);
1364 if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
1366 status = add_route_ipapi (r, tt, ai);
1367 msg (D_ROUTE, "Route addition via IPAPI %s", status ? "succeeded" : "failed");
1369 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_EXE)
1371 netcmd_semaphore_lock ();
1372 status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add command failed");
1373 netcmd_semaphore_release ();
1375 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_ADAPTIVE)
1377 status = add_route_ipapi (r, tt, ai);
1378 msg (D_ROUTE, "Route addition via IPAPI %s [adaptive]", status ? "succeeded" : "failed");
1379 if (!status)
1381 msg (D_ROUTE, "Route addition fallback to route.exe");
1382 netcmd_semaphore_lock ();
1383 status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add command failed [adaptive]");
1384 netcmd_semaphore_release ();
1387 else
1389 ASSERT (0);
1393 #elif defined (TARGET_SOLARIS)
1395 /* example: route add 192.0.2.32 -netmask 255.255.255.224 somegateway */
1397 argv_printf (&argv, "%s add",
1398 ROUTE_PATH);
1400 #if 0
1401 if (r->flags & RT_METRIC_DEFINED)
1402 argv_printf_cat (&argv, "-rtt %d", r->metric);
1403 #endif
1405 argv_printf_cat (&argv, "%s -netmask %s %s",
1406 network,
1407 netmask,
1408 gateway);
1410 /* FIXME -- add on-link support for Solaris */
1412 argv_msg (D_ROUTE, &argv);
1413 status = openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route add command failed");
1415 #elif defined(TARGET_FREEBSD)
1417 argv_printf (&argv, "%s add",
1418 ROUTE_PATH);
1420 #if 0
1421 if (r->flags & RT_METRIC_DEFINED)
1422 argv_printf_cat (&argv, "-rtt %d", r->metric);
1423 #endif
1425 argv_printf_cat (&argv, "-net %s %s %s",
1426 network,
1427 gateway,
1428 netmask);
1430 /* FIXME -- add on-link support for FreeBSD */
1432 argv_msg (D_ROUTE, &argv);
1433 status = openvpn_execve_check (&argv, es, 0, "ERROR: FreeBSD route add command failed");
1435 #elif defined(TARGET_DRAGONFLY)
1437 argv_printf (&argv, "%s add",
1438 ROUTE_PATH);
1440 #if 0
1441 if (r->flags & RT_METRIC_DEFINED)
1442 argv_printf_cat (&argv, "-rtt %d", r->metric);
1443 #endif
1445 argv_printf_cat (&argv, "-net %s %s %s",
1446 network,
1447 gateway,
1448 netmask);
1450 /* FIXME -- add on-link support for Dragonfly */
1452 argv_msg (D_ROUTE, &argv);
1453 status = openvpn_execve_check (&argv, es, 0, "ERROR: DragonFly route add command failed");
1455 #elif defined(TARGET_DARWIN)
1457 argv_printf (&argv, "%s add",
1458 ROUTE_PATH);
1460 #if 0
1461 if (r->flags & RT_METRIC_DEFINED)
1462 argv_printf_cat (&argv, "-rtt %d", r->metric);
1463 #endif
1465 if (is_on_link (is_local_route, flags, rgi))
1467 /* Mac OS X route syntax for ON_LINK:
1468 route add -cloning -net 10.10.0.1 -netmask 255.255.255.255 -interface en0 */
1469 argv_printf_cat (&argv, "-cloning -net %s -netmask %s -interface %s",
1470 network,
1471 netmask,
1472 rgi->iface);
1474 else
1476 argv_printf_cat (&argv, "-net %s %s %s",
1477 network,
1478 gateway,
1479 netmask);
1482 argv_msg (D_ROUTE, &argv);
1483 status = openvpn_execve_check (&argv, es, 0, "ERROR: OS X route add command failed");
1485 #elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1487 argv_printf (&argv, "%s add",
1488 ROUTE_PATH);
1490 #if 0
1491 if (r->flags & RT_METRIC_DEFINED)
1492 argv_printf_cat (&argv, "-rtt %d", r->metric);
1493 #endif
1495 argv_printf_cat (&argv, "-net %s %s -netmask %s",
1496 network,
1497 gateway,
1498 netmask);
1500 /* FIXME -- add on-link support for OpenBSD/NetBSD */
1502 argv_msg (D_ROUTE, &argv);
1503 status = openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD/NetBSD route add command failed");
1505 #else
1506 msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script");
1507 #endif
1509 done:
1510 if (status)
1511 r->flags |= RT_ADDED;
1512 else
1513 r->flags &= ~RT_ADDED;
1514 argv_reset (&argv);
1515 gc_free (&gc);
1519 static const char *
1520 print_in6_addr_netbits_only( struct in6_addr network_copy, int netbits,
1521 struct gc_arena * gc)
1523 /* clear host bit parts of route
1524 * (needed if routes are specified improperly, or if we need to
1525 * explicitely setup/clear the "connected" network routes on some OSes)
1527 int byte = 15;
1528 int bits_to_clear = 128 - netbits;
1530 while( byte >= 0 && bits_to_clear > 0 )
1532 if ( bits_to_clear >= 8 )
1533 { network_copy.s6_addr[byte--] = 0; bits_to_clear -= 8; }
1534 else
1535 { network_copy.s6_addr[byte--] &= (0xff << bits_to_clear); bits_to_clear = 0; }
1538 return print_in6_addr( network_copy, 0, gc);
1541 void
1542 add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
1544 struct gc_arena gc;
1545 struct argv argv;
1547 const char *network;
1548 const char *gateway;
1549 bool status = false;
1550 const char *device = tt->actual_name;
1552 bool gateway_needed = false;
1554 if (!r6->defined)
1555 return;
1557 gc_init (&gc);
1558 argv_init (&argv);
1560 network = print_in6_addr_netbits_only( r6->network, r6->netbits, &gc);
1561 gateway = print_in6_addr( r6->gateway, 0, &gc);
1563 if ( !tt->ipv6 )
1565 msg( M_INFO, "add_route_ipv6(): not adding %s/%d, no IPv6 on if %s",
1566 network, r6->netbits, device );
1567 return;
1570 msg( M_INFO, "add_route_ipv6(%s/%d -> %s metric %d) dev %s",
1571 network, r6->netbits, gateway, r6->metric, device );
1574 * Filter out routes which are essentially no-ops
1575 * (not currently done for IPv6)
1578 /* On "tun" interface, we never set a gateway if the operating system
1579 * can do "route to interface" - it does not add value, as the target
1580 * dev already fully qualifies the route destination on point-to-point
1581 * interfaces. OTOH, on "tap" interface, we must always set the
1582 * gateway unless the route is to be an on-link network
1584 if ( tt->type == DEV_TYPE_TAP &&
1585 !(r6->metric_defined && r6->metric == 0 ) )
1587 gateway_needed = true;
1590 #if defined(TARGET_LINUX)
1591 #ifdef ENABLE_IPROUTE
1592 argv_printf (&argv, "%s -6 route add %s/%d dev %s",
1593 iproute_path,
1594 network,
1595 r6->netbits,
1596 device);
1597 if (gateway_needed)
1598 argv_printf_cat (&argv, "via %s", gateway);
1599 if (r6->metric_defined && r6->metric > 0 )
1600 argv_printf_cat (&argv, " metric %d", r6->metric);
1602 #else
1603 argv_printf (&argv, "%s -A inet6 add %s/%d dev %s",
1604 ROUTE_PATH,
1605 network,
1606 r6->netbits,
1607 device);
1608 if (gateway_needed)
1609 argv_printf_cat (&argv, "gw %s", gateway);
1610 if (r6->metric_defined && r6->metric > 0 )
1611 argv_printf_cat (&argv, " metric %d", r6->metric);
1612 #endif /*ENABLE_IPROUTE*/
1613 argv_msg (D_ROUTE, &argv);
1614 status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route -6/-A inet6 add command failed");
1616 #elif defined (WIN32)
1618 /* netsh interface ipv6 add route 2001:db8::/32 MyTunDevice */
1619 argv_printf (&argv, "%s%sc interface ipv6 add route %s/%d %s",
1620 get_win_sys_path(),
1621 NETSH_PATH_SUFFIX,
1622 network,
1623 r6->netbits,
1624 device);
1626 /* next-hop depends on TUN or TAP mode:
1627 * - in TAP mode, we use the "real" next-hop
1628 * - in TUN mode we use a special-case link-local address that the tapdrvr
1629 * knows about and will answer ND (neighbor discovery) packets for
1631 if ( tt->type == DEV_TYPE_TUN )
1632 argv_printf_cat( &argv, " %s", "fe80::8" );
1633 else
1634 argv_printf_cat( &argv, " %s", gateway );
1636 #if 0
1637 if (r->metric_defined)
1638 argv_printf_cat (&argv, " METRIC %d", r->metric);
1639 #endif
1641 /* in some versions of Windows, routes are persistent across reboots by
1642 * default, unless "store=active" is set (pointed out by Tony Lim, thanks)
1644 argv_printf_cat( &argv, " store=active" );
1646 argv_msg (D_ROUTE, &argv);
1648 netcmd_semaphore_lock ();
1649 status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add ipv6 command failed");
1650 netcmd_semaphore_release ();
1652 #elif defined (TARGET_SOLARIS)
1654 /* example: route add -inet6 2001:db8::/32 somegateway 0 */
1656 /* for some weird reason, this does not work for me unless I set
1657 * "metric 0" - otherwise, the routes will be nicely installed, but
1658 * packets will just disappear somewhere. So we use "0" now...
1661 argv_printf (&argv, "%s add -inet6 %s/%d %s 0",
1662 ROUTE_PATH,
1663 network,
1664 r6->netbits,
1665 gateway );
1667 argv_msg (D_ROUTE, &argv);
1668 status = openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route add -inet6 command failed");
1670 #elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1672 argv_printf (&argv, "%s add -inet6 %s/%d",
1673 ROUTE_PATH,
1674 network,
1675 r6->netbits);
1677 if (gateway_needed)
1678 argv_printf_cat (&argv, "%s", gateway);
1679 else
1680 argv_printf_cat (&argv, "-iface %s", device);
1682 argv_msg (D_ROUTE, &argv);
1683 status = openvpn_execve_check (&argv, es, 0, "ERROR: *BSD route add -inet6 command failed");
1685 #elif defined(TARGET_DARWIN)
1687 argv_printf (&argv, "%s add -inet6 %s -prefixlen %d",
1688 ROUTE_PATH,
1689 network, r6->netbits );
1691 if (gateway_needed)
1692 argv_printf_cat (&argv, "%s", gateway);
1693 else
1694 argv_printf_cat (&argv, "-iface %s", device);
1696 argv_msg (D_ROUTE, &argv);
1697 status = openvpn_execve_check (&argv, es, 0, "ERROR: MacOS X route add -inet6 command failed");
1699 #elif defined(TARGET_OPENBSD)
1701 argv_printf (&argv, "%s add -inet6 %s -prefixlen %d %s",
1702 ROUTE_PATH,
1703 network, r6->netbits, gateway );
1705 argv_msg (D_ROUTE, &argv);
1706 status = openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD route add -inet6 command failed");
1708 #elif defined(TARGET_NETBSD)
1710 argv_printf (&argv, "%s add -inet6 %s/%d %s",
1711 ROUTE_PATH,
1712 network, r6->netbits, gateway );
1714 argv_msg (D_ROUTE, &argv);
1715 status = openvpn_execve_check (&argv, es, 0, "ERROR: NetBSD route add -inet6 command failed");
1717 #else
1718 msg (M_FATAL, "Sorry, but I don't know how to do 'route ipv6' commands on this operating system. Try putting your routes in a --route-up script");
1719 #endif
1721 r6->defined = status;
1722 argv_reset (&argv);
1723 gc_free (&gc);
1726 static void
1727 delete_route (struct route *r,
1728 const struct tuntap *tt,
1729 unsigned int flags,
1730 const struct route_gateway_info *rgi,
1731 const struct env_set *es)
1733 struct gc_arena gc;
1734 struct argv argv;
1735 const char *network;
1736 const char *netmask;
1737 const char *gateway;
1738 int is_local_route;
1740 if ((r->flags & (RT_DEFINED|RT_ADDED)) != (RT_DEFINED|RT_ADDED))
1741 return;
1743 gc_init (&gc);
1744 argv_init (&argv);
1746 network = print_in_addr_t (r->network, 0, &gc);
1747 netmask = print_in_addr_t (r->netmask, 0, &gc);
1748 gateway = print_in_addr_t (r->gateway, 0, &gc);
1750 is_local_route = local_route(r->network, r->netmask, r->gateway, rgi);
1751 if (is_local_route == LR_ERROR)
1752 goto done;
1754 #if defined(TARGET_LINUX)
1755 #ifdef ENABLE_IPROUTE
1756 argv_printf (&argv, "%s route del %s/%d",
1757 iproute_path,
1758 network,
1759 count_netmask_bits(netmask));
1760 #else
1761 argv_printf (&argv, "%s del -net %s netmask %s",
1762 ROUTE_PATH,
1763 network,
1764 netmask);
1765 #endif /*ENABLE_IPROUTE*/
1766 if (r->flags & RT_METRIC_DEFINED)
1767 argv_printf_cat (&argv, "metric %d", r->metric);
1768 argv_msg (D_ROUTE, &argv);
1769 openvpn_execve_check (&argv, es, 0, "ERROR: Linux route delete command failed");
1771 #elif defined (WIN32)
1773 argv_printf (&argv, "%s%sc DELETE %s MASK %s %s",
1774 get_win_sys_path(),
1775 WIN_ROUTE_PATH_SUFFIX,
1776 network,
1777 netmask,
1778 gateway);
1780 argv_msg (D_ROUTE, &argv);
1782 if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
1784 const bool status = del_route_ipapi (r, tt);
1785 msg (D_ROUTE, "Route deletion via IPAPI %s", status ? "succeeded" : "failed");
1787 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_EXE)
1789 netcmd_semaphore_lock ();
1790 openvpn_execve_check (&argv, es, 0, "ERROR: Windows route delete command failed");
1791 netcmd_semaphore_release ();
1793 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_ADAPTIVE)
1795 const bool status = del_route_ipapi (r, tt);
1796 msg (D_ROUTE, "Route deletion via IPAPI %s [adaptive]", status ? "succeeded" : "failed");
1797 if (!status)
1799 msg (D_ROUTE, "Route deletion fallback to route.exe");
1800 netcmd_semaphore_lock ();
1801 openvpn_execve_check (&argv, es, 0, "ERROR: Windows route delete command failed [adaptive]");
1802 netcmd_semaphore_release ();
1805 else
1807 ASSERT (0);
1810 #elif defined (TARGET_SOLARIS)
1812 argv_printf (&argv, "%s delete %s -netmask %s %s",
1813 ROUTE_PATH,
1814 network,
1815 netmask,
1816 gateway);
1818 argv_msg (D_ROUTE, &argv);
1819 openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route delete command failed");
1821 #elif defined(TARGET_FREEBSD)
1823 argv_printf (&argv, "%s delete -net %s %s %s",
1824 ROUTE_PATH,
1825 network,
1826 gateway,
1827 netmask);
1829 argv_msg (D_ROUTE, &argv);
1830 openvpn_execve_check (&argv, es, 0, "ERROR: FreeBSD route delete command failed");
1832 #elif defined(TARGET_DRAGONFLY)
1834 argv_printf (&argv, "%s delete -net %s %s %s",
1835 ROUTE_PATH,
1836 network,
1837 gateway,
1838 netmask);
1840 argv_msg (D_ROUTE, &argv);
1841 openvpn_execve_check (&argv, es, 0, "ERROR: DragonFly route delete command failed");
1843 #elif defined(TARGET_DARWIN)
1845 if (is_on_link (is_local_route, flags, rgi))
1847 argv_printf (&argv, "%s delete -cloning -net %s -netmask %s -interface %s",
1848 ROUTE_PATH,
1849 network,
1850 netmask,
1851 rgi->iface);
1853 else
1855 argv_printf (&argv, "%s delete -net %s %s %s",
1856 ROUTE_PATH,
1857 network,
1858 gateway,
1859 netmask);
1862 argv_msg (D_ROUTE, &argv);
1863 openvpn_execve_check (&argv, es, 0, "ERROR: OS X route delete command failed");
1865 #elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1867 argv_printf (&argv, "%s delete -net %s %s -netmask %s",
1868 ROUTE_PATH,
1869 network,
1870 gateway,
1871 netmask);
1873 argv_msg (D_ROUTE, &argv);
1874 openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD/NetBSD route delete command failed");
1876 #else
1877 msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script");
1878 #endif
1880 done:
1881 r->flags &= ~RT_ADDED;
1882 argv_reset (&argv);
1883 gc_free (&gc);
1886 void
1887 delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
1889 struct gc_arena gc;
1890 struct argv argv;
1891 const char *network;
1892 const char *gateway;
1893 const char *device = tt->actual_name;
1894 bool gateway_needed = false;
1896 if (!r6->defined)
1897 return;
1899 gc_init (&gc);
1900 argv_init (&argv);
1902 network = print_in6_addr_netbits_only( r6->network, r6->netbits, &gc);
1903 gateway = print_in6_addr( r6->gateway, 0, &gc);
1905 if ( !tt->ipv6 )
1907 msg( M_INFO, "delete_route_ipv6(): not deleting %s/%d, no IPv6 on if %s",
1908 network, r6->netbits, device );
1909 return;
1912 msg( M_INFO, "delete_route_ipv6(%s/%d)", network, r6->netbits );
1914 /* if we used a gateway on "add route", we also need to specify it on
1915 * delete, otherwise some OSes will refuse to delete the route
1917 if ( tt->type == DEV_TYPE_TAP &&
1918 !(r6->metric_defined && r6->metric == 0 ) )
1920 gateway_needed = true;
1924 #if defined(TARGET_LINUX)
1925 #ifdef ENABLE_IPROUTE
1926 argv_printf (&argv, "%s -6 route del %s/%d dev %s",
1927 iproute_path,
1928 network,
1929 r6->netbits,
1930 device);
1931 if (gateway_needed)
1932 argv_printf_cat (&argv, "via %s", gateway);
1933 #else
1934 argv_printf (&argv, "%s -A inet6 del %s/%d dev %s",
1935 ROUTE_PATH,
1936 network,
1937 r6->netbits,
1938 device);
1939 if (gateway_needed)
1940 argv_printf_cat (&argv, "gw %s", gateway);
1941 if (r6->metric_defined && r6->metric > 0 )
1942 argv_printf_cat (&argv, " metric %d", r6->metric);
1943 #endif /*ENABLE_IPROUTE*/
1944 argv_msg (D_ROUTE, &argv);
1945 openvpn_execve_check (&argv, es, 0, "ERROR: Linux route -6/-A inet6 del command failed");
1947 #elif defined (WIN32)
1949 /* netsh interface ipv6 delete route 2001:db8::/32 MyTunDevice */
1950 argv_printf (&argv, "%s%sc interface ipv6 delete route %s/%d %s",
1951 get_win_sys_path(),
1952 NETSH_PATH_SUFFIX,
1953 network,
1954 r6->netbits,
1955 device);
1957 /* next-hop depends on TUN or TAP mode:
1958 * - in TAP mode, we use the "real" next-hop
1959 * - in TUN mode we use a special-case link-local address that the tapdrvr
1960 * knows about and will answer ND (neighbor discovery) packets for
1961 * (and "route deletion without specifying next-hop" does not work...)
1963 if ( tt->type == DEV_TYPE_TUN )
1964 argv_printf_cat( &argv, " %s", "fe80::8" );
1965 else
1966 argv_printf_cat( &argv, " %s", gateway );
1968 #if 0
1969 if (r->metric_defined)
1970 argv_printf_cat (&argv, "METRIC %d", r->metric);
1971 #endif
1973 argv_msg (D_ROUTE, &argv);
1975 netcmd_semaphore_lock ();
1976 openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add ipv6 command failed");
1977 netcmd_semaphore_release ();
1979 #elif defined (TARGET_SOLARIS)
1981 /* example: route delete -inet6 2001:db8::/32 somegateway */
1982 /* GERT-TODO: this is untested, but should work */
1984 argv_printf (&argv, "%s delete -inet6 %s/%d %s",
1985 ROUTE_PATH,
1986 network,
1987 r6->netbits,
1988 gateway );
1990 argv_msg (D_ROUTE, &argv);
1991 openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route delete -inet6 command failed");
1993 #elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1995 argv_printf (&argv, "%s delete -inet6 %s/%d",
1996 ROUTE_PATH,
1997 network,
1998 r6->netbits );
2000 if (gateway_needed)
2001 argv_printf_cat (&argv, "%s", gateway);
2002 else
2003 argv_printf_cat (&argv, "-iface %s", device);
2005 argv_msg (D_ROUTE, &argv);
2006 openvpn_execve_check (&argv, es, 0, "ERROR: *BSD route delete -inet6 command failed");
2008 #elif defined(TARGET_DARWIN)
2010 argv_printf (&argv, "%s delete -inet6 %s -prefixlen %d",
2011 ROUTE_PATH,
2012 network, r6->netbits );
2014 if (gateway_needed)
2015 argv_printf_cat (&argv, "%s", gateway);
2016 else
2017 argv_printf_cat (&argv, "-iface %s", device);
2019 argv_msg (D_ROUTE, &argv);
2020 openvpn_execve_check (&argv, es, 0, "ERROR: MacOS X route delete -inet6 command failed");
2022 #elif defined(TARGET_OPENBSD)
2024 argv_printf (&argv, "%s delete -inet6 %s -prefixlen %d %s",
2025 ROUTE_PATH,
2026 network, r6->netbits, gateway );
2028 argv_msg (D_ROUTE, &argv);
2029 openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD route delete -inet6 command failed");
2031 #elif defined(TARGET_NETBSD)
2033 argv_printf (&argv, "%s delete -inet6 %s/%d %s",
2034 ROUTE_PATH,
2035 network, r6->netbits, gateway );
2037 argv_msg (D_ROUTE, &argv);
2038 openvpn_execve_check (&argv, es, 0, "ERROR: NetBSD route delete -inet6 command failed");
2040 #else
2041 msg (M_FATAL, "Sorry, but I don't know how to do 'route ipv6' commands on this operating system. Try putting your routes in a --route-down script");
2042 #endif
2044 argv_reset (&argv);
2045 gc_free (&gc);
2049 * The --redirect-gateway option requires OS-specific code below
2050 * to get the current default gateway.
2053 #if defined(WIN32)
2055 static const MIB_IPFORWARDTABLE *
2056 get_windows_routing_table (struct gc_arena *gc)
2058 ULONG size = 0;
2059 PMIB_IPFORWARDTABLE rt = NULL;
2060 DWORD status;
2062 status = GetIpForwardTable (NULL, &size, TRUE);
2063 if (status == ERROR_INSUFFICIENT_BUFFER)
2065 rt = (PMIB_IPFORWARDTABLE) gc_malloc (size, false, gc);
2066 status = GetIpForwardTable (rt, &size, TRUE);
2067 if (status != NO_ERROR)
2069 msg (D_ROUTE, "NOTE: GetIpForwardTable returned error: %s (code=%u)",
2070 strerror_win32 (status, gc),
2071 (unsigned int)status);
2072 rt = NULL;
2075 return rt;
2078 static int
2079 test_route (const IP_ADAPTER_INFO *adapters,
2080 const in_addr_t gateway,
2081 DWORD *index)
2083 int count = 0;
2084 DWORD i = adapter_index_of_ip (adapters, gateway, &count, NULL);
2085 if (index)
2086 *index = i;
2087 return count;
2090 static void
2091 test_route_helper (bool *ret,
2092 int *count,
2093 int *good,
2094 int *ambig,
2095 const IP_ADAPTER_INFO *adapters,
2096 const in_addr_t gateway)
2098 int c;
2100 ++*count;
2101 c = test_route (adapters, gateway, NULL);
2102 if (c == 0)
2103 *ret = false;
2104 else
2105 ++*good;
2106 if (c > 1)
2107 ++*ambig;
2111 * If we tried to add routes now, would we succeed?
2113 bool
2114 test_routes (const struct route_list *rl, const struct tuntap *tt)
2116 struct gc_arena gc = gc_new ();
2117 const IP_ADAPTER_INFO *adapters = get_adapter_info_list (&gc);
2118 bool ret = false;
2119 int count = 0;
2120 int good = 0;
2121 int ambig = 0;
2122 bool adapter_up = false;
2124 if (is_adapter_up (tt, adapters))
2126 ret = true;
2127 adapter_up = true;
2129 if (rl)
2131 int i;
2132 for (i = 0; i < rl->n; ++i)
2133 test_route_helper (&ret, &count, &good, &ambig, adapters, rl->routes[i].gateway);
2135 if ((rl->flags & RG_ENABLE) && (rl->spec.flags & RTSA_REMOTE_ENDPOINT))
2136 test_route_helper (&ret, &count, &good, &ambig, adapters, rl->spec.remote_endpoint);
2140 msg (D_ROUTE, "TEST ROUTES: %d/%d succeeded len=%d ret=%d a=%d u/d=%s",
2141 good,
2142 count,
2143 rl ? rl->n : -1,
2144 (int)ret,
2145 ambig,
2146 adapter_up ? "up" : "down");
2148 gc_free (&gc);
2149 return ret;
2152 static const MIB_IPFORWARDROW *
2153 get_default_gateway_row (const MIB_IPFORWARDTABLE *routes)
2155 struct gc_arena gc = gc_new ();
2156 DWORD lowest_metric = MAXDWORD;
2157 const MIB_IPFORWARDROW *ret = NULL;
2158 int i;
2159 int best = -1;
2161 if (routes)
2163 for (i = 0; i < routes->dwNumEntries; ++i)
2165 const MIB_IPFORWARDROW *row = &routes->table[i];
2166 const in_addr_t net = ntohl (row->dwForwardDest);
2167 const in_addr_t mask = ntohl (row->dwForwardMask);
2168 const DWORD index = row->dwForwardIfIndex;
2169 const DWORD metric = row->dwForwardMetric1;
2171 dmsg (D_ROUTE_DEBUG, "GDGR: route[%d] %s/%s i=%d m=%d",
2173 print_in_addr_t ((in_addr_t) net, 0, &gc),
2174 print_in_addr_t ((in_addr_t) mask, 0, &gc),
2175 (int)index,
2176 (int)metric);
2178 if (!net && !mask && metric < lowest_metric)
2180 ret = row;
2181 lowest_metric = metric;
2182 best = i;
2187 dmsg (D_ROUTE_DEBUG, "GDGR: best=%d lm=%u", best, (unsigned int)lowest_metric);
2189 gc_free (&gc);
2190 return ret;
2193 void
2194 get_default_gateway (struct route_gateway_info *rgi)
2196 struct gc_arena gc = gc_new ();
2198 const IP_ADAPTER_INFO *adapters = get_adapter_info_list (&gc);
2199 const MIB_IPFORWARDTABLE *routes = get_windows_routing_table (&gc);
2200 const MIB_IPFORWARDROW *row = get_default_gateway_row (routes);
2201 DWORD a_index;
2202 const IP_ADAPTER_INFO *ai;
2204 CLEAR(*rgi);
2206 if (row)
2208 rgi->gateway.addr = ntohl (row->dwForwardNextHop);
2209 if (rgi->gateway.addr)
2211 rgi->flags |= RGI_ADDR_DEFINED;
2212 a_index = adapter_index_of_ip (adapters, rgi->gateway.addr, NULL, &rgi->gateway.netmask);
2213 if (a_index != TUN_ADAPTER_INDEX_INVALID)
2215 rgi->adapter_index = a_index;
2216 rgi->flags |= (RGI_IFACE_DEFINED|RGI_NETMASK_DEFINED);
2217 ai = get_adapter (adapters, a_index);
2218 if (ai)
2220 memcpy (rgi->hwaddr, ai->Address, 6);
2221 rgi->flags |= RGI_HWADDR_DEFINED;
2227 gc_free (&gc);
2230 static DWORD
2231 windows_route_find_if_index (const struct route *r, const struct tuntap *tt)
2233 struct gc_arena gc = gc_new ();
2234 DWORD ret = TUN_ADAPTER_INDEX_INVALID;
2235 int count = 0;
2236 const IP_ADAPTER_INFO *adapters = get_adapter_info_list (&gc);
2237 const IP_ADAPTER_INFO *tun_adapter = get_tun_adapter (tt, adapters);
2238 bool on_tun = false;
2240 /* first test on tun interface */
2241 if (is_ip_in_adapter_subnet (tun_adapter, r->gateway, NULL))
2243 ret = tun_adapter->Index;
2244 count = 1;
2245 on_tun = true;
2247 else /* test on other interfaces */
2249 count = test_route (adapters, r->gateway, &ret);
2252 if (count == 0)
2254 msg (M_WARN, "Warning: route gateway is not reachable on any active network adapters: %s",
2255 print_in_addr_t (r->gateway, 0, &gc));
2256 ret = TUN_ADAPTER_INDEX_INVALID;
2258 else if (count > 1)
2260 msg (M_WARN, "Warning: route gateway is ambiguous: %s (%d matches)",
2261 print_in_addr_t (r->gateway, 0, &gc),
2262 count);
2263 ret = TUN_ADAPTER_INDEX_INVALID;
2266 dmsg (D_ROUTE_DEBUG, "DEBUG: route find if: on_tun=%d count=%d index=%d",
2267 on_tun,
2268 count,
2269 (int)ret);
2271 gc_free (&gc);
2272 return ret;
2275 bool
2276 add_route_ipapi (const struct route *r, const struct tuntap *tt, DWORD adapter_index)
2278 struct gc_arena gc = gc_new ();
2279 bool ret = false;
2280 DWORD status;
2281 const DWORD if_index = (adapter_index == TUN_ADAPTER_INDEX_INVALID) ? windows_route_find_if_index (r, tt) : adapter_index;
2283 if (if_index != TUN_ADAPTER_INDEX_INVALID)
2285 MIB_IPFORWARDROW fr;
2286 CLEAR (fr);
2287 fr.dwForwardDest = htonl (r->network);
2288 fr.dwForwardMask = htonl (r->netmask);
2289 fr.dwForwardPolicy = 0;
2290 fr.dwForwardNextHop = htonl (r->gateway);
2291 fr.dwForwardIfIndex = if_index;
2292 fr.dwForwardType = 4; /* the next hop is not the final dest */
2293 fr.dwForwardProto = 3; /* PROTO_IP_NETMGMT */
2294 fr.dwForwardAge = 0;
2295 fr.dwForwardNextHopAS = 0;
2296 fr.dwForwardMetric1 = (r->flags & RT_METRIC_DEFINED) ? r->metric : 1;
2297 fr.dwForwardMetric2 = METRIC_NOT_USED;
2298 fr.dwForwardMetric3 = METRIC_NOT_USED;
2299 fr.dwForwardMetric4 = METRIC_NOT_USED;
2300 fr.dwForwardMetric5 = METRIC_NOT_USED;
2302 if ((r->network & r->netmask) != r->network)
2303 msg (M_WARN, "Warning: address %s is not a network address in relation to netmask %s",
2304 print_in_addr_t (r->network, 0, &gc),
2305 print_in_addr_t (r->netmask, 0, &gc));
2307 status = CreateIpForwardEntry (&fr);
2309 if (status == NO_ERROR)
2310 ret = true;
2311 else
2313 /* failed, try increasing the metric to work around Vista issue */
2314 const unsigned int forward_metric_limit = 2048; /* iteratively retry higher metrics up to this limit */
2316 for ( ; fr.dwForwardMetric1 <= forward_metric_limit; ++fr.dwForwardMetric1)
2318 /* try a different forward type=3 ("the next hop is the final dest") in addition to 4.
2319 --redirect-gateway over RRAS seems to need this. */
2320 for (fr.dwForwardType = 4; fr.dwForwardType >= 3; --fr.dwForwardType)
2322 status = CreateIpForwardEntry (&fr);
2323 if (status == NO_ERROR)
2325 msg (D_ROUTE, "ROUTE: CreateIpForwardEntry succeeded with dwForwardMetric1=%u and dwForwardType=%u",
2326 (unsigned int)fr.dwForwardMetric1,
2327 (unsigned int)fr.dwForwardType);
2328 ret = true;
2329 goto doublebreak;
2331 else if (status != ERROR_BAD_ARGUMENTS)
2332 goto doublebreak;
2336 doublebreak:
2337 if (status != NO_ERROR)
2338 msg (M_WARN, "ROUTE: route addition failed using CreateIpForwardEntry: %s [status=%u if_index=%u]",
2339 strerror_win32 (status, &gc),
2340 (unsigned int)status,
2341 (unsigned int)if_index);
2345 gc_free (&gc);
2346 return ret;
2349 bool
2350 del_route_ipapi (const struct route *r, const struct tuntap *tt)
2352 struct gc_arena gc = gc_new ();
2353 bool ret = false;
2354 DWORD status;
2355 const DWORD if_index = windows_route_find_if_index (r, tt);
2357 if (if_index != TUN_ADAPTER_INDEX_INVALID)
2359 MIB_IPFORWARDROW fr;
2360 CLEAR (fr);
2362 fr.dwForwardDest = htonl (r->network);
2363 fr.dwForwardMask = htonl (r->netmask);
2364 fr.dwForwardPolicy = 0;
2365 fr.dwForwardNextHop = htonl (r->gateway);
2366 fr.dwForwardIfIndex = if_index;
2368 status = DeleteIpForwardEntry (&fr);
2370 if (status == NO_ERROR)
2371 ret = true;
2372 else
2373 msg (M_WARN, "ROUTE: route deletion failed using DeleteIpForwardEntry: %s",
2374 strerror_win32 (status, &gc));
2377 gc_free (&gc);
2378 return ret;
2381 static const char *
2382 format_route_entry (const MIB_IPFORWARDROW *r, struct gc_arena *gc)
2384 struct buffer out = alloc_buf_gc (256, gc);
2385 buf_printf (&out, "%s %s %s p=%d i=%d t=%d pr=%d a=%d h=%d m=%d/%d/%d/%d/%d",
2386 print_in_addr_t (r->dwForwardDest, IA_NET_ORDER, gc),
2387 print_in_addr_t (r->dwForwardMask, IA_NET_ORDER, gc),
2388 print_in_addr_t (r->dwForwardNextHop, IA_NET_ORDER, gc),
2389 (int)r->dwForwardPolicy,
2390 (int)r->dwForwardIfIndex,
2391 (int)r->dwForwardType,
2392 (int)r->dwForwardProto,
2393 (int)r->dwForwardAge,
2394 (int)r->dwForwardNextHopAS,
2395 (int)r->dwForwardMetric1,
2396 (int)r->dwForwardMetric2,
2397 (int)r->dwForwardMetric3,
2398 (int)r->dwForwardMetric4,
2399 (int)r->dwForwardMetric5);
2400 return BSTR (&out);
2404 * Show current routing table
2406 void
2407 show_routes (int msglev)
2409 struct gc_arena gc = gc_new ();
2410 int i;
2412 const MIB_IPFORWARDTABLE *rt = get_windows_routing_table (&gc);
2414 msg (msglev, "SYSTEM ROUTING TABLE");
2415 if (rt)
2417 for (i = 0; i < rt->dwNumEntries; ++i)
2419 msg (msglev, "%s", format_route_entry (&rt->table[i], &gc));
2422 gc_free (&gc);
2425 #elif defined(TARGET_LINUX)
2427 void
2428 get_default_gateway (struct route_gateway_info *rgi)
2430 struct gc_arena gc = gc_new ();
2431 int sd = -1;
2432 char best_name[16];
2433 best_name[0] = 0;
2435 CLEAR(*rgi);
2437 /* get default gateway IP addr */
2439 FILE *fp = fopen ("/proc/net/route", "r");
2440 if (fp)
2442 char line[256];
2443 int count = 0;
2444 unsigned int lowest_metric = UINT_MAX;
2445 in_addr_t best_gw = 0;
2446 bool found = false;
2447 while (fgets (line, sizeof (line), fp) != NULL)
2449 if (count)
2451 unsigned int net_x = 0;
2452 unsigned int mask_x = 0;
2453 unsigned int gw_x = 0;
2454 unsigned int metric = 0;
2455 unsigned int flags = 0;
2456 char name[16];
2457 name[0] = 0;
2458 const int np = sscanf (line, "%15s\t%x\t%x\t%x\t%*s\t%*s\t%d\t%x",
2459 name,
2460 &net_x,
2461 &gw_x,
2462 &flags,
2463 &metric,
2464 &mask_x);
2465 if (np == 6 && (flags & IFF_UP))
2467 const in_addr_t net = ntohl (net_x);
2468 const in_addr_t mask = ntohl (mask_x);
2469 const in_addr_t gw = ntohl (gw_x);
2471 if (!net && !mask && metric < lowest_metric)
2473 found = true;
2474 best_gw = gw;
2475 strcpy (best_name, name);
2476 lowest_metric = metric;
2480 ++count;
2482 fclose (fp);
2484 if (found)
2486 rgi->gateway.addr = best_gw;
2487 rgi->flags |= RGI_ADDR_DEFINED;
2488 if (!rgi->gateway.addr && best_name[0])
2489 rgi->flags |= RGI_ON_LINK;
2494 /* scan adapter list */
2495 if (rgi->flags & RGI_ADDR_DEFINED)
2497 struct ifreq *ifr, *ifend;
2498 in_addr_t addr, netmask;
2499 struct ifreq ifreq;
2500 struct ifconf ifc;
2501 struct ifreq ifs[20]; /* Maximum number of interfaces to scan */
2503 if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
2505 msg (M_WARN, "GDG: socket() failed");
2506 goto done;
2508 ifc.ifc_len = sizeof (ifs);
2509 ifc.ifc_req = ifs;
2510 if (ioctl (sd, SIOCGIFCONF, &ifc) < 0)
2512 msg (M_WARN, "GDG: ioctl(SIOCGIFCONF) failed");
2513 goto done;
2516 /* scan through interface list */
2517 ifend = ifs + (ifc.ifc_len / sizeof (struct ifreq));
2518 for (ifr = ifc.ifc_req; ifr < ifend; ifr++)
2520 if (ifr->ifr_addr.sa_family == AF_INET)
2522 /* get interface addr */
2523 addr = ntohl(((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr);
2525 /* get interface name */
2526 strncpynt (ifreq.ifr_name, ifr->ifr_name, sizeof (ifreq.ifr_name));
2528 /* check that the interface is up */
2529 if (ioctl (sd, SIOCGIFFLAGS, &ifreq) < 0)
2530 continue;
2531 if (!(ifreq.ifr_flags & IFF_UP))
2532 continue;
2534 if (rgi->flags & RGI_ON_LINK)
2536 /* check that interface name of current interface
2537 matches interface name of best default route */
2538 if (strcmp(ifreq.ifr_name, best_name))
2539 continue;
2540 #if 0
2541 /* if point-to-point link, use remote addr as route gateway */
2542 if ((ifreq.ifr_flags & IFF_POINTOPOINT) && ioctl (sd, SIOCGIFDSTADDR, &ifreq) >= 0)
2544 rgi->gateway.addr = ntohl(((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr);
2545 if (rgi->gateway.addr)
2546 rgi->flags &= ~RGI_ON_LINK;
2548 #endif
2550 else
2552 /* get interface netmask */
2553 if (ioctl (sd, SIOCGIFNETMASK, &ifreq) < 0)
2554 continue;
2555 netmask = ntohl(((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr);
2557 /* check that interface matches default route */
2558 if (((rgi->gateway.addr ^ addr) & netmask) != 0)
2559 continue;
2561 /* save netmask */
2562 rgi->gateway.netmask = netmask;
2563 rgi->flags |= RGI_NETMASK_DEFINED;
2566 /* save iface name */
2567 strncpynt (rgi->iface, ifreq.ifr_name, sizeof(rgi->iface));
2568 rgi->flags |= RGI_IFACE_DEFINED;
2570 /* now get the hardware address. */
2571 memset (&ifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
2572 if (ioctl (sd, SIOCGIFHWADDR, &ifreq) < 0)
2574 msg (M_WARN, "GDG: SIOCGIFHWADDR(%s) failed", ifreq.ifr_name);
2575 goto done;
2577 memcpy (rgi->hwaddr, &ifreq.ifr_hwaddr.sa_data, 6);
2578 rgi->flags |= RGI_HWADDR_DEFINED;
2580 break;
2585 done:
2586 if (sd >= 0)
2587 close (sd);
2588 gc_free (&gc);
2591 #elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)
2593 #include <sys/types.h>
2594 #include <sys/socket.h>
2595 #include <netinet/in.h>
2597 /* all of this is taken from <net/route.h> in FreeBSD */
2598 #define RTA_DST 0x1
2599 #define RTA_GATEWAY 0x2
2600 #define RTA_NETMASK 0x4
2602 #define RTM_GET 0x4
2603 #define RTM_VERSION 5
2605 #define RTF_UP 0x1
2606 #define RTF_GATEWAY 0x2
2609 * These numbers are used by reliable protocols for determining
2610 * retransmission behavior and are included in the routing structure.
2612 struct rt_metrics {
2613 u_long rmx_locks; /* Kernel must leave these values alone */
2614 u_long rmx_mtu; /* MTU for this path */
2615 u_long rmx_hopcount; /* max hops expected */
2616 u_long rmx_expire; /* lifetime for route, e.g. redirect */
2617 u_long rmx_recvpipe; /* inbound delay-bandwidth product */
2618 u_long rmx_sendpipe; /* outbound delay-bandwidth product */
2619 u_long rmx_ssthresh; /* outbound gateway buffer limit */
2620 u_long rmx_rtt; /* estimated round trip time */
2621 u_long rmx_rttvar; /* estimated rtt variance */
2622 u_long rmx_pksent; /* packets sent using this route */
2623 u_long rmx_filler[4]; /* will be used for T/TCP later */
2627 * Structures for routing messages.
2629 struct rt_msghdr {
2630 u_short rtm_msglen; /* to skip over non-understood messages */
2631 u_char rtm_version; /* future binary compatibility */
2632 u_char rtm_type; /* message type */
2633 u_short rtm_index; /* index for associated ifp */
2634 int rtm_flags; /* flags, incl. kern & message, e.g. DONE */
2635 int rtm_addrs; /* bitmask identifying sockaddrs in msg */
2636 pid_t rtm_pid; /* identify sender */
2637 int rtm_seq; /* for sender to identify action */
2638 int rtm_errno; /* why failed */
2639 int rtm_use; /* from rtentry */
2640 u_long rtm_inits; /* which metrics we are initializing */
2641 struct rt_metrics rtm_rmx; /* metrics themselves */
2644 struct {
2645 struct rt_msghdr m_rtm;
2646 char m_space[512];
2647 } m_rtmsg;
2649 #define ROUNDUP(a) \
2650 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
2653 * FIXME -- add support for netmask, hwaddr, and iface
2655 void
2656 get_default_gateway (struct route_gateway_info *rgi)
2658 struct gc_arena gc = gc_new ();
2659 int s, seq, l, pid, rtm_addrs, i;
2660 struct sockaddr so_dst, so_mask;
2661 char *cp = m_rtmsg.m_space;
2662 struct sockaddr *gate = NULL, *sa;
2663 struct rt_msghdr *rtm_aux;
2665 #define NEXTADDR(w, u) \
2666 if (rtm_addrs & (w)) {\
2667 l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
2670 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
2672 #define rtm m_rtmsg.m_rtm
2674 CLEAR(*rgi);
2676 pid = getpid();
2677 seq = 0;
2678 rtm_addrs = RTA_DST | RTA_NETMASK;
2680 bzero(&so_dst, sizeof(so_dst));
2681 bzero(&so_mask, sizeof(so_mask));
2682 bzero(&rtm, sizeof(struct rt_msghdr));
2684 rtm.rtm_type = RTM_GET;
2685 rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
2686 rtm.rtm_version = RTM_VERSION;
2687 rtm.rtm_seq = ++seq;
2688 rtm.rtm_addrs = rtm_addrs;
2690 so_dst.sa_family = AF_INET;
2691 so_dst.sa_len = sizeof(struct sockaddr_in);
2692 so_mask.sa_family = AF_INET;
2693 so_mask.sa_len = sizeof(struct sockaddr_in);
2695 NEXTADDR(RTA_DST, so_dst);
2696 NEXTADDR(RTA_NETMASK, so_mask);
2698 rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
2700 s = socket(PF_ROUTE, SOCK_RAW, 0);
2702 if (write(s, (char *)&m_rtmsg, l) < 0)
2704 msg(M_WARN|M_ERRNO, "Could not retrieve default gateway from route socket:");
2705 gc_free (&gc);
2706 close(s);
2707 return;
2710 do {
2711 l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
2712 } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
2714 close(s);
2716 rtm_aux = &rtm;
2718 cp = ((char *)(rtm_aux + 1));
2719 if (rtm_aux->rtm_addrs) {
2720 for (i = 1; i; i <<= 1)
2721 if (i & rtm_aux->rtm_addrs) {
2722 sa = (struct sockaddr *)cp;
2723 if (i == RTA_GATEWAY )
2724 gate = sa;
2725 ADVANCE(cp, sa);
2728 else
2730 gc_free (&gc);
2731 return;
2735 if (gate != NULL )
2737 rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
2738 rgi->flags |= RGI_ADDR_DEFINED;
2740 gc_free (&gc);
2742 else
2744 gc_free (&gc);
2748 #elif defined(TARGET_DARWIN)
2750 #include <sys/types.h>
2751 #include <sys/socket.h>
2752 #include <netinet/in.h>
2753 #include <net/route.h>
2754 #include <net/if_dl.h>
2756 struct rtmsg {
2757 struct rt_msghdr m_rtm;
2758 char m_space[512];
2761 #define ROUNDUP(a) \
2762 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
2764 #define NEXTADDR(w, u) \
2765 if (rtm_addrs & (w)) {\
2766 l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
2769 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
2771 #define max(a,b) ((a) > (b) ? (a) : (b))
2773 void
2774 get_default_gateway (struct route_gateway_info *rgi)
2776 struct gc_arena gc = gc_new ();
2777 struct rtmsg m_rtmsg;
2778 int sockfd = -1;
2779 int seq, l, pid, rtm_addrs, i;
2780 struct sockaddr so_dst, so_mask;
2781 char *cp = m_rtmsg.m_space;
2782 struct sockaddr *gate = NULL, *ifp = NULL, *sa;
2783 struct rt_msghdr *rtm_aux;
2785 # define rtm m_rtmsg.m_rtm
2787 CLEAR(*rgi);
2789 /* setup data to send to routing socket */
2790 pid = getpid();
2791 seq = 0;
2792 rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP;
2794 bzero(&m_rtmsg, sizeof(m_rtmsg));
2795 bzero(&so_dst, sizeof(so_dst));
2796 bzero(&so_mask, sizeof(so_mask));
2797 bzero(&rtm, sizeof(struct rt_msghdr));
2799 rtm.rtm_type = RTM_GET;
2800 rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
2801 rtm.rtm_version = RTM_VERSION;
2802 rtm.rtm_seq = ++seq;
2803 rtm.rtm_addrs = rtm_addrs;
2805 so_dst.sa_family = AF_INET;
2806 so_dst.sa_len = sizeof(struct sockaddr_in);
2807 so_mask.sa_family = AF_INET;
2808 so_mask.sa_len = sizeof(struct sockaddr_in);
2810 NEXTADDR(RTA_DST, so_dst);
2811 NEXTADDR(RTA_NETMASK, so_mask);
2813 rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
2815 /* transact with routing socket */
2816 sockfd = socket(PF_ROUTE, SOCK_RAW, 0);
2817 if (sockfd < 0)
2819 msg (M_WARN, "GDG: socket #1 failed");
2820 goto done;
2822 if (write(sockfd, (char *)&m_rtmsg, l) < 0)
2824 msg (M_WARN, "GDG: problem writing to routing socket");
2825 goto done;
2827 do {
2828 l = read(sockfd, (char *)&m_rtmsg, sizeof(m_rtmsg));
2829 } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
2830 close(sockfd);
2831 sockfd = -1;
2833 /* extract return data from routing socket */
2834 rtm_aux = &rtm;
2835 cp = ((char *)(rtm_aux + 1));
2836 if (rtm_aux->rtm_addrs)
2838 for (i = 1; i; i <<= 1)
2840 if (i & rtm_aux->rtm_addrs)
2842 sa = (struct sockaddr *)cp;
2843 if (i == RTA_GATEWAY )
2844 gate = sa;
2845 else if (i == RTA_IFP)
2846 ifp = sa;
2847 ADVANCE(cp, sa);
2851 else
2852 goto done;
2854 /* get gateway addr and interface name */
2855 if (gate != NULL )
2857 /* get default gateway addr */
2858 rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
2859 if (rgi->gateway.addr)
2860 rgi->flags |= RGI_ADDR_DEFINED;
2862 if (ifp)
2864 /* get interface name */
2865 const struct sockaddr_dl *adl = (struct sockaddr_dl *) ifp;
2866 int len = adl->sdl_nlen;
2867 if (adl->sdl_nlen && adl->sdl_nlen < sizeof(rgi->iface))
2869 memcpy (rgi->iface, adl->sdl_data, adl->sdl_nlen);
2870 rgi->iface[adl->sdl_nlen] = '\0';
2871 rgi->flags |= RGI_IFACE_DEFINED;
2876 /* get netmask of interface that owns default gateway */
2877 if (rgi->flags & RGI_IFACE_DEFINED) {
2878 struct ifreq ifr;
2880 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
2881 if (sockfd < 0)
2883 msg (M_WARN, "GDG: socket #2 failed");
2884 goto done;
2887 CLEAR(ifr);
2888 ifr.ifr_addr.sa_family = AF_INET;
2889 strncpynt(ifr.ifr_name, rgi->iface, IFNAMSIZ);
2891 if (ioctl(sockfd, SIOCGIFNETMASK, (char *)&ifr) < 0)
2893 msg (M_WARN, "GDG: ioctl #1 failed");
2894 goto done;
2896 close(sockfd);
2897 sockfd = -1;
2899 rgi->gateway.netmask = ntohl(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr);
2900 rgi->flags |= RGI_NETMASK_DEFINED;
2903 /* try to read MAC addr associated with interface that owns default gateway */
2904 if (rgi->flags & RGI_IFACE_DEFINED)
2906 struct ifconf ifc;
2907 struct ifreq *ifr;
2908 const int bufsize = 4096;
2909 char *buffer;
2911 buffer = (char *) gc_malloc (bufsize, true, &gc);
2912 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
2913 if (sockfd < 0)
2915 msg (M_WARN, "GDG: socket #3 failed");
2916 goto done;
2919 ifc.ifc_len = bufsize;
2920 ifc.ifc_buf = buffer;
2922 if (ioctl(sockfd, SIOCGIFCONF, (char *)&ifc) < 0)
2924 msg (M_WARN, "GDG: ioctl #2 failed");
2925 goto done;
2927 close(sockfd);
2928 sockfd = -1;
2930 for (cp = buffer; cp <= buffer + ifc.ifc_len - sizeof(struct ifreq); )
2932 ifr = (struct ifreq *)cp;
2933 const size_t len = sizeof(ifr->ifr_name) + max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len);
2934 if (!ifr->ifr_addr.sa_family)
2935 break;
2936 if (!strncmp(ifr->ifr_name, rgi->iface, IFNAMSIZ))
2938 if (ifr->ifr_addr.sa_family == AF_LINK)
2940 struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
2941 memcpy(rgi->hwaddr, LLADDR(sdl), 6);
2942 rgi->flags |= RGI_HWADDR_DEFINED;
2945 cp += len;
2949 done:
2950 if (sockfd >= 0)
2951 close(sockfd);
2952 gc_free (&gc);
2955 #undef max
2957 #elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2959 #include <sys/types.h>
2960 #include <sys/socket.h>
2961 #include <netinet/in.h>
2963 /* all of this is taken from <net/route.h> in OpenBSD 3.6 */
2964 #define RTA_DST 0x1 /* destination sockaddr present */
2965 #define RTA_GATEWAY 0x2 /* gateway sockaddr present */
2966 #define RTA_NETMASK 0x4 /* netmask sockaddr present */
2968 #define RTM_GET 0x4 /* Report Metrics */
2970 #define RTM_VERSION 3 /* Up the ante and ignore older versions */
2972 #define RTF_UP 0x1 /* route usable */
2973 #define RTF_GATEWAY 0x2 /* destination is a gateway */
2976 * Huge version for userland compatibility.
2978 struct rt_metrics {
2979 u_long rmx_locks; /* Kernel must leave these values alone */
2980 u_long rmx_mtu; /* MTU for this path */
2981 u_long rmx_hopcount; /* max hops expected */
2982 u_long rmx_expire; /* lifetime for route, e.g. redirect */
2983 u_long rmx_recvpipe; /* inbound delay-bandwidth product */
2984 u_long rmx_sendpipe; /* outbound delay-bandwidth product */
2985 u_long rmx_ssthresh; /* outbound gateway buffer limit */
2986 u_long rmx_rtt; /* estimated round trip time */
2987 u_long rmx_rttvar; /* estimated rtt variance */
2988 u_long rmx_pksent; /* packets sent using this route */
2992 * Structures for routing messages.
2994 struct rt_msghdr {
2995 u_short rtm_msglen; /* to skip over non-understood messages */
2996 u_char rtm_version; /* future binary compatibility */
2997 u_char rtm_type; /* message type */
2998 u_short rtm_index; /* index for associated ifp */
2999 int rtm_flags; /* flags, incl. kern & message, e.g. DONE */
3000 int rtm_addrs; /* bitmask identifying sockaddrs in msg */
3001 pid_t rtm_pid; /* identify sender */
3002 int rtm_seq; /* for sender to identify action */
3003 int rtm_errno; /* why failed */
3004 int rtm_use; /* from rtentry */
3005 u_long rtm_inits; /* which metrics we are initializing */
3006 struct rt_metrics rtm_rmx; /* metrics themselves */
3009 struct {
3010 struct rt_msghdr m_rtm;
3011 char m_space[512];
3012 } m_rtmsg;
3014 #define ROUNDUP(a) \
3015 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
3018 * FIXME -- add support for netmask, hwaddr, and iface
3020 void
3021 get_default_gateway (struct route_gateway_info *rgi)
3023 struct gc_arena gc = gc_new ();
3024 int s, seq, l, rtm_addrs, i;
3025 pid_t pid;
3026 struct sockaddr so_dst, so_mask;
3027 char *cp = m_rtmsg.m_space;
3028 struct sockaddr *gate = NULL, *sa;
3029 struct rt_msghdr *rtm_aux;
3031 #define NEXTADDR(w, u) \
3032 if (rtm_addrs & (w)) {\
3033 l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
3036 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
3038 #define rtm m_rtmsg.m_rtm
3040 CLEAR(*rgi);
3042 pid = getpid();
3043 seq = 0;
3044 rtm_addrs = RTA_DST | RTA_NETMASK;
3046 bzero(&so_dst, sizeof(so_dst));
3047 bzero(&so_mask, sizeof(so_mask));
3048 bzero(&rtm, sizeof(struct rt_msghdr));
3050 rtm.rtm_type = RTM_GET;
3051 rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
3052 rtm.rtm_version = RTM_VERSION;
3053 rtm.rtm_seq = ++seq;
3054 rtm.rtm_addrs = rtm_addrs;
3056 so_dst.sa_family = AF_INET;
3057 so_dst.sa_len = sizeof(struct sockaddr_in);
3058 so_mask.sa_family = AF_INET;
3059 so_mask.sa_len = sizeof(struct sockaddr_in);
3061 NEXTADDR(RTA_DST, so_dst);
3062 NEXTADDR(RTA_NETMASK, so_mask);
3064 rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
3066 s = socket(PF_ROUTE, SOCK_RAW, 0);
3068 if (write(s, (char *)&m_rtmsg, l) < 0)
3070 msg(M_WARN|M_ERRNO, "Could not retrieve default gateway from route socket:");
3071 gc_free (&gc);
3072 close(s);
3073 return;
3076 do {
3077 l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
3078 } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
3080 close(s);
3082 rtm_aux = &rtm;
3084 cp = ((char *)(rtm_aux + 1));
3085 if (rtm_aux->rtm_addrs) {
3086 for (i = 1; i; i <<= 1)
3087 if (i & rtm_aux->rtm_addrs) {
3088 sa = (struct sockaddr *)cp;
3089 if (i == RTA_GATEWAY )
3090 gate = sa;
3091 ADVANCE(cp, sa);
3094 else
3096 gc_free (&gc);
3097 return;
3101 if (gate != NULL )
3103 rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
3104 rgi->flags |= RGI_ADDR_DEFINED;
3106 gc_free (&gc);
3108 else
3110 gc_free (&gc);
3114 #else
3117 * This is a platform-specific method that returns data about
3118 * the current default gateway. Return data is placed into
3119 * a struct route_gateway_info object provided by caller. The
3120 * implementation should CLEAR the structure before adding
3121 * data to it.
3123 * Data returned includes:
3124 * 1. default gateway address (rgi->gateway.addr)
3125 * 2. netmask of interface that owns default gateway
3126 * (rgi->gateway.netmask)
3127 * 3. hardware address (i.e. MAC address) of interface that owns
3128 * default gateway (rgi->hwaddr)
3129 * 4. interface name (or adapter index on Windows) that owns default
3130 * gateway (rgi->iface or rgi->adapter_index)
3131 * 5. an array of additional address/netmask pairs defined by
3132 * interface that owns default gateway (rgi->addrs with length
3133 * given in rgi->n_addrs)
3135 * The flags RGI_x_DEFINED may be used to indicate which of the data
3136 * members were successfully returned (set in rgi->flags). All of
3137 * the data members are optional, however certain OpenVPN functionality
3138 * may be disabled by missing items.
3140 void
3141 get_default_gateway (struct route_gateway_info *rgi)
3143 CLEAR(*rgi);
3146 #endif
3148 bool
3149 netmask_to_netbits (const in_addr_t network, const in_addr_t netmask, int *netbits)
3151 int i;
3152 const int addrlen = sizeof (in_addr_t) * 8;
3154 if ((network & netmask) == network)
3156 for (i = 0; i <= addrlen; ++i)
3158 in_addr_t mask = netbits_to_netmask (i);
3159 if (mask == netmask)
3161 if (i == addrlen)
3162 *netbits = -1;
3163 else
3164 *netbits = i;
3165 return true;
3169 return false;
3173 * get_bypass_addresses() is used by the redirect-gateway bypass-x
3174 * functions to build a route bypass to selected DHCP/DNS servers,
3175 * so that outgoing packets to these servers don't end up in the tunnel.
3178 #if defined(WIN32)
3180 static void
3181 add_host_route_if_nonlocal (struct route_bypass *rb, const in_addr_t addr)
3183 if (test_local_addr(addr, NULL) == TLA_NONLOCAL && addr != 0 && addr != IPV4_NETMASK_HOST)
3184 add_bypass_address (rb, addr);
3187 static void
3188 add_host_route_array (struct route_bypass *rb, const IP_ADDR_STRING *iplist)
3190 while (iplist)
3192 bool succeed = false;
3193 const in_addr_t ip = getaddr (GETADDR_HOST_ORDER, iplist->IpAddress.String, 0, &succeed, NULL);
3194 if (succeed)
3196 add_host_route_if_nonlocal (rb, ip);
3198 iplist = iplist->Next;
3202 static void
3203 get_bypass_addresses (struct route_bypass *rb, const unsigned int flags)
3205 struct gc_arena gc = gc_new ();
3206 /*bool ret_bool = false;*/
3208 /* get full routing table */
3209 const MIB_IPFORWARDTABLE *routes = get_windows_routing_table (&gc);
3211 /* get the route which represents the default gateway */
3212 const MIB_IPFORWARDROW *row = get_default_gateway_row (routes);
3214 if (row)
3216 /* get the adapter which the default gateway is associated with */
3217 const IP_ADAPTER_INFO *dgi = get_adapter_info (row->dwForwardIfIndex, &gc);
3219 /* get extra adapter info, such as DNS addresses */
3220 const IP_PER_ADAPTER_INFO *pai = get_per_adapter_info (row->dwForwardIfIndex, &gc);
3222 /* Bypass DHCP server address */
3223 if ((flags & RG_BYPASS_DHCP) && dgi && dgi->DhcpEnabled)
3224 add_host_route_array (rb, &dgi->DhcpServer);
3226 /* Bypass DNS server addresses */
3227 if ((flags & RG_BYPASS_DNS) && pai)
3228 add_host_route_array (rb, &pai->DnsServerList);
3231 gc_free (&gc);
3234 #else
3236 static void
3237 get_bypass_addresses (struct route_bypass *rb, const unsigned int flags) /* PLATFORM-SPECIFIC */
3241 #endif
3244 * Test if addr is reachable via a local interface (return ILA_LOCAL),
3245 * or if it needs to be routed via the default gateway (return
3246 * ILA_NONLOCAL). If the target platform doesn't implement this
3247 * function, return ILA_NOT_IMPLEMENTED.
3249 * Used by redirect-gateway autolocal feature
3252 #if defined(WIN32)
3255 test_local_addr (const in_addr_t addr, const struct route_gateway_info *rgi)
3257 struct gc_arena gc = gc_new ();
3258 const in_addr_t nonlocal_netmask = 0x80000000L; /* routes with netmask <= to this are considered non-local */
3259 bool ret = TLA_NONLOCAL;
3261 /* get full routing table */
3262 const MIB_IPFORWARDTABLE *rt = get_windows_routing_table (&gc);
3263 if (rt)
3265 int i;
3266 for (i = 0; i < rt->dwNumEntries; ++i)
3268 const MIB_IPFORWARDROW *row = &rt->table[i];
3269 const in_addr_t net = ntohl (row->dwForwardDest);
3270 const in_addr_t mask = ntohl (row->dwForwardMask);
3271 if (mask > nonlocal_netmask && (addr & mask) == net)
3273 ret = TLA_LOCAL;
3274 break;
3279 gc_free (&gc);
3280 return ret;
3283 #else
3286 test_local_addr (const in_addr_t addr, const struct route_gateway_info *rgi) /* PLATFORM-SPECIFIC */
3288 if (rgi)
3290 if (local_route (addr, 0xFFFFFFFF, rgi->gateway.addr, rgi))
3291 return TLA_LOCAL;
3292 else
3293 return TLA_NONLOCAL;
3295 return TLA_NOT_IMPLEMENTED;
3298 #endif