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
8 * Copyright (C) 2002-2009 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.
41 static void delete_route (const struct route
*r
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
);
42 static void get_bypass_addresses (struct route_bypass
*rb
, const unsigned int flags
);
47 print_bypass_addresses (const struct route_bypass
*rb
)
49 struct gc_arena gc
= gc_new ();
51 for (i
= 0; i
< rb
->n_bypass
; ++i
)
53 msg (D_ROUTE
, "ROUTE: bypass_host_route[%d]=%s",
55 print_in_addr_t (rb
->bypass
[i
], 0, &gc
));
63 add_bypass_address (struct route_bypass
*rb
, const in_addr_t a
)
66 for (i
= 0; i
< rb
->n_bypass
; ++i
)
68 if (a
== rb
->bypass
[i
]) /* avoid duplicates */
71 if (rb
->n_bypass
< N_ROUTE_BYPASS
)
73 rb
->bypass
[rb
->n_bypass
++] = a
;
82 struct route_option_list
*
83 new_route_option_list (const int max_routes
, struct gc_arena
*a
)
85 struct route_option_list
*ret
;
86 ALLOC_VAR_ARRAY_CLEAR_GC (ret
, struct route_option_list
, struct route_option
, max_routes
, a
);
87 ret
->capacity
= max_routes
;
91 struct route_option_list
*
92 clone_route_option_list (const struct route_option_list
*src
, struct gc_arena
*a
)
94 const size_t rl_size
= array_mult_safe (sizeof(struct route_option
), src
->capacity
, sizeof(struct route_option_list
));
95 struct route_option_list
*ret
= gc_malloc (rl_size
, false, a
);
96 memcpy (ret
, src
, rl_size
);
101 copy_route_option_list (struct route_option_list
*dest
, const struct route_option_list
*src
)
103 const size_t src_size
= array_mult_safe (sizeof(struct route_option
), src
->capacity
, sizeof(struct route_option_list
));
104 if (src
->n
> dest
->capacity
)
105 msg (M_FATAL
, PACKAGE_NAME
" ROUTE: (copy) number of route options in src (%d) is greater than route list capacity in dest (%d)", src
->n
, dest
->capacity
);
106 memcpy (dest
, src
, src_size
);
110 new_route_list (const int max_routes
, struct gc_arena
*a
)
112 struct route_list
*ret
;
113 ALLOC_VAR_ARRAY_CLEAR_GC (ret
, struct route_list
, struct route
, max_routes
, a
);
114 ret
->capacity
= max_routes
;
119 route_string (const struct route
*r
, struct gc_arena
*gc
)
121 struct buffer out
= alloc_buf_gc (256, gc
);
122 buf_printf (&out
, "ROUTE network %s netmask %s gateway %s",
123 print_in_addr_t (r
->network
, 0, gc
),
124 print_in_addr_t (r
->netmask
, 0, gc
),
125 print_in_addr_t (r
->gateway
, 0, gc
)
127 if (r
->metric_defined
)
128 buf_printf (&out
, " metric %d", r
->metric
);
133 is_route_parm_defined (const char *parm
)
137 if (!strcmp (parm
, "default"))
143 setenv_route_addr (struct env_set
*es
, const char *key
, const in_addr_t addr
, int i
)
145 struct gc_arena gc
= gc_new ();
146 struct buffer name
= alloc_buf_gc (256, &gc
);
148 buf_printf (&name
, "route_%s_%d", key
, i
);
150 buf_printf (&name
, "route_%s", key
);
151 setenv_str (es
, BSTR (&name
), print_in_addr_t (addr
, 0, &gc
));
156 get_special_addr (const struct route_special_addr
*spec
,
163 if (!strcmp (string
, "vpn_gateway"))
167 if (spec
->remote_endpoint_defined
)
168 *out
= spec
->remote_endpoint
;
171 msg (M_INFO
, PACKAGE_NAME
" ROUTE: vpn_gateway undefined");
178 else if (!strcmp (string
, "net_gateway"))
182 if (spec
->net_gateway_defined
)
183 *out
= spec
->net_gateway
;
186 msg (M_INFO
, PACKAGE_NAME
" ROUTE: net_gateway undefined -- unable to get default gateway from system");
193 else if (!strcmp (string
, "remote_host"))
197 if (spec
->remote_host_defined
)
198 *out
= spec
->remote_host
;
201 msg (M_INFO
, PACKAGE_NAME
" ROUTE: remote_host undefined");
212 is_special_addr (const char *addr_str
)
215 return get_special_addr (NULL
, addr_str
, NULL
, NULL
);
221 init_route (struct route
*r
,
222 const struct route_option
*ro
,
223 const struct route_special_addr
*spec
)
225 const in_addr_t default_netmask
= ~0;
233 if (!is_route_parm_defined (ro
->network
))
238 if (!get_special_addr (spec
, ro
->network
, &r
->network
, &status
))
240 r
->network
= getaddr (
243 | GETADDR_WARN_ON_SIGNAL
,
255 if (is_route_parm_defined (ro
->netmask
))
257 r
->netmask
= getaddr (
259 | GETADDR_WARN_ON_SIGNAL
,
268 r
->netmask
= default_netmask
;
272 if (is_route_parm_defined (ro
->gateway
))
274 if (!get_special_addr (spec
, ro
->gateway
, &r
->gateway
, &status
))
276 r
->gateway
= getaddr (
279 | GETADDR_WARN_ON_SIGNAL
,
290 if (spec
->remote_endpoint_defined
)
291 r
->gateway
= spec
->remote_endpoint
;
294 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");
301 r
->metric_defined
= false;
303 if (is_route_parm_defined (ro
->metric
))
305 r
->metric
= atoi (ro
->metric
);
308 msg (M_WARN
, PACKAGE_NAME
" ROUTE: route metric for network %s (%s) must be >= 0",
313 r
->metric_defined
= true;
315 else if (spec
->default_metric_defined
)
317 r
->metric
= spec
->default_metric
;
318 r
->metric_defined
= true;
326 msg (M_WARN
, PACKAGE_NAME
" ROUTE: failed to parse/resolve route for host/network: %s",
333 add_route_to_option_list (struct route_option_list
*l
,
339 struct route_option
*ro
;
340 if (l
->n
>= l
->capacity
)
341 msg (M_FATAL
, PACKAGE_NAME
" ROUTE: cannot add more than %d routes -- please increase the max-routes option in the client configuration file",
343 ro
= &l
->routes
[l
->n
];
344 ro
->network
= network
;
345 ro
->netmask
= netmask
;
346 ro
->gateway
= gateway
;
352 clear_route_list (struct route_list
*rl
)
354 const int capacity
= rl
->capacity
;
355 const size_t rl_size
= array_mult_safe (sizeof(struct route
), capacity
, sizeof(struct route_list
));
356 memset(rl
, 0, rl_size
);
357 rl
->capacity
= capacity
;
361 route_list_add_default_gateway (struct route_list
*rl
,
363 const in_addr_t addr
)
365 rl
->spec
.remote_endpoint
= addr
;
366 rl
->spec
.remote_endpoint_defined
= true;
367 setenv_route_addr (es
, "vpn_gateway", rl
->spec
.remote_endpoint
, -1);
371 init_route_list (struct route_list
*rl
,
372 const struct route_option_list
*opt
,
373 const char *remote_endpoint
,
375 in_addr_t remote_host
,
378 struct gc_arena gc
= gc_new ();
381 clear_route_list (rl
);
383 rl
->flags
= opt
->flags
;
387 rl
->spec
.remote_host
= remote_host
;
388 rl
->spec
.remote_host_defined
= true;
393 rl
->spec
.default_metric
= default_metric
;
394 rl
->spec
.default_metric_defined
= true;
397 rl
->spec
.net_gateway_defined
= get_default_gateway (&rl
->spec
.net_gateway
, NULL
);
398 if (rl
->spec
.net_gateway_defined
)
400 setenv_route_addr (es
, "net_gateway", rl
->spec
.net_gateway
, -1);
401 dmsg (D_ROUTE
, "ROUTE default_gateway=%s", print_in_addr_t (rl
->spec
.net_gateway
, 0, &gc
));
405 dmsg (D_ROUTE
, "ROUTE: default_gateway=UNDEF");
408 if (rl
->flags
& RG_ENABLE
)
410 get_bypass_addresses (&rl
->spec
.bypass
, rl
->flags
);
412 print_bypass_addresses (&rl
->spec
.bypass
);
416 if (is_route_parm_defined (remote_endpoint
))
418 rl
->spec
.remote_endpoint
= getaddr (
421 | GETADDR_WARN_ON_SIGNAL
,
424 &rl
->spec
.remote_endpoint_defined
,
427 if (rl
->spec
.remote_endpoint_defined
)
429 setenv_route_addr (es
, "vpn_gateway", rl
->spec
.remote_endpoint
, -1);
433 msg (M_WARN
, PACKAGE_NAME
" ROUTE: failed to parse/resolve default gateway: %s",
439 rl
->spec
.remote_endpoint_defined
= false;
441 if (!(opt
->n
>= 0 && opt
->n
<= rl
->capacity
))
442 msg (M_FATAL
, PACKAGE_NAME
" ROUTE: (init) number of route options (%d) is greater than route list capacity (%d)", opt
->n
, rl
->capacity
);
444 /* parse the routes from opt to rl */
447 for (i
= 0; i
< opt
->n
; ++i
)
449 if (!init_route (&rl
->routes
[j
],
464 add_route3 (in_addr_t network
,
467 const struct tuntap
*tt
,
469 const struct env_set
*es
)
477 add_route (&r
, tt
, flags
, es
);
481 del_route3 (in_addr_t network
,
484 const struct tuntap
*tt
,
486 const struct env_set
*es
)
494 delete_route (&r
, tt
, flags
, es
);
498 add_bypass_routes (struct route_bypass
*rb
,
500 const struct tuntap
*tt
,
502 const struct env_set
*es
)
505 for (i
= 0; i
< rb
->n_bypass
; ++i
)
507 if (rb
->bypass
[i
] != gateway
)
508 add_route3 (rb
->bypass
[i
],
518 del_bypass_routes (struct route_bypass
*rb
,
520 const struct tuntap
*tt
,
522 const struct env_set
*es
)
525 for (i
= 0; i
< rb
->n_bypass
; ++i
)
527 if (rb
->bypass
[i
] != gateway
)
528 del_route3 (rb
->bypass
[i
],
538 redirect_default_route_to_vpn (struct route_list
*rl
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
)
540 const char err
[] = "NOTE: unable to redirect default gateway --";
542 if (rl
->flags
& RG_ENABLE
)
544 if (!rl
->spec
.remote_endpoint_defined
)
546 msg (M_WARN
, "%s VPN gateway parameter (--route-gateway or --ifconfig) is missing", err
);
548 else if (!rl
->spec
.net_gateway_defined
)
550 msg (M_WARN
, "%s Cannot read current default gateway from system", err
);
552 else if (!rl
->spec
.remote_host_defined
)
554 msg (M_WARN
, "%s Cannot obtain current remote host address", err
);
558 bool local
= BOOL_CAST(rl
->flags
& RG_LOCAL
);
559 if (rl
->flags
& RG_AUTO_LOCAL
) {
560 const int tla
= test_local_addr (rl
->spec
.remote_host
);
561 if (tla
== TLA_NONLOCAL
)
563 dmsg (D_ROUTE
, "ROUTE remote_host is NOT LOCAL");
566 else if (tla
== TLA_LOCAL
)
568 dmsg (D_ROUTE
, "ROUTE remote_host is LOCAL");
574 /* route remote host to original default gateway */
575 add_route3 (rl
->spec
.remote_host
,
577 rl
->spec
.net_gateway
,
581 rl
->did_local
= true;
584 /* route DHCP/DNS server traffic through original default gateway */
585 add_bypass_routes (&rl
->spec
.bypass
, rl
->spec
.net_gateway
, tt
, flags
, es
);
587 if (rl
->flags
& RG_REROUTE_GW
)
589 if (rl
->flags
& RG_DEF1
)
591 /* add new default route (1st component) */
592 add_route3 (0x00000000,
594 rl
->spec
.remote_endpoint
,
599 /* add new default route (2nd component) */
600 add_route3 (0x80000000,
602 rl
->spec
.remote_endpoint
,
609 /* delete default route */
612 rl
->spec
.net_gateway
,
617 /* add new default route */
620 rl
->spec
.remote_endpoint
,
627 /* set a flag so we can undo later */
628 rl
->did_redirect_default_gateway
= true;
634 undo_redirect_default_route_to_vpn (struct route_list
*rl
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
)
636 if (rl
->did_redirect_default_gateway
)
638 /* delete remote host route */
641 del_route3 (rl
->spec
.remote_host
,
643 rl
->spec
.net_gateway
,
647 rl
->did_local
= false;
650 /* delete special DHCP/DNS bypass route */
651 del_bypass_routes (&rl
->spec
.bypass
, rl
->spec
.net_gateway
, tt
, flags
, es
);
653 if (rl
->flags
& RG_REROUTE_GW
)
655 if (rl
->flags
& RG_DEF1
)
657 /* delete default route (1st component) */
658 del_route3 (0x00000000,
660 rl
->spec
.remote_endpoint
,
665 /* delete default route (2nd component) */
666 del_route3 (0x80000000,
668 rl
->spec
.remote_endpoint
,
675 /* delete default route */
678 rl
->spec
.remote_endpoint
,
683 /* restore original default route */
686 rl
->spec
.net_gateway
,
693 rl
->did_redirect_default_gateway
= false;
698 add_routes (struct route_list
*rl
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
)
700 redirect_default_route_to_vpn (rl
, tt
, flags
, es
);
701 if (!rl
->routes_added
)
705 #ifdef ENABLE_MANAGEMENT
706 if (management
&& rl
->n
)
708 management_set_state (management
,
709 OPENVPN_STATE_ADD_ROUTES
,
716 for (i
= 0; i
< rl
->n
; ++i
)
718 struct route
*r
= &rl
->routes
[i
];
719 check_subnet_conflict (r
->network
, r
->netmask
, "route");
720 if (flags
& ROUTE_DELETE_FIRST
)
721 delete_route (r
, tt
, flags
, es
);
722 add_route (r
, tt
, flags
, es
);
724 rl
->routes_added
= true;
729 delete_routes (struct route_list
*rl
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
)
731 if (rl
->routes_added
)
734 for (i
= rl
->n
- 1; i
>= 0; --i
)
736 const struct route
*r
= &rl
->routes
[i
];
737 delete_route (r
, tt
, flags
, es
);
739 rl
->routes_added
= false;
741 undo_redirect_default_route_to_vpn (rl
, tt
, flags
, es
);
743 clear_route_list (rl
);
749 show_opt (const char *option
)
758 print_route_option (const struct route_option
*ro
, int level
)
760 msg (level
, " route %s/%s/%s/%s",
761 show_opt (ro
->network
),
762 show_opt (ro
->netmask
),
763 show_opt (ro
->gateway
),
764 show_opt (ro
->metric
));
768 print_route_options (const struct route_option_list
*rol
,
772 if (rol
->flags
& RG_ENABLE
)
773 msg (level
, " [redirect_default_gateway local=%d]",
774 (rol
->flags
& RG_LOCAL
) != 0);
775 for (i
= 0; i
< rol
->n
; ++i
)
776 print_route_option (&rol
->routes
[i
], level
);
782 print_route (const struct route
*r
, int level
)
784 struct gc_arena gc
= gc_new ();
786 msg (level
, "%s", route_string (r
, &gc
));
791 print_routes (const struct route_list
*rl
, int level
)
794 for (i
= 0; i
< rl
->n
; ++i
)
795 print_route (&rl
->routes
[i
], level
);
799 setenv_route (struct env_set
*es
, const struct route
*r
, int i
)
801 struct gc_arena gc
= gc_new ();
804 setenv_route_addr (es
, "network", r
->network
, i
);
805 setenv_route_addr (es
, "netmask", r
->netmask
, i
);
806 setenv_route_addr (es
, "gateway", r
->gateway
, i
);
808 if (r
->metric_defined
)
810 struct buffer name
= alloc_buf_gc (256, &gc
);
811 buf_printf (&name
, "route_metric_%d", i
);
812 setenv_int (es
, BSTR (&name
), r
->metric
);
819 setenv_routes (struct env_set
*es
, const struct route_list
*rl
)
822 for (i
= 0; i
< rl
->n
; ++i
)
823 setenv_route (es
, &rl
->routes
[i
], i
+ 1);
827 add_route (struct route
*r
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
)
842 network
= print_in_addr_t (r
->network
, 0, &gc
);
843 netmask
= print_in_addr_t (r
->netmask
, 0, &gc
);
844 gateway
= print_in_addr_t (r
->gateway
, 0, &gc
);
847 * Filter out routes which are essentially no-ops
849 if (r
->network
== r
->gateway
&& r
->netmask
== 0xFFFFFFFF)
851 msg (M_INFO
, PACKAGE_NAME
" ROUTE: omitted no-op route: %s/%s -> %s",
852 network
, netmask
, gateway
);
856 #if defined(TARGET_LINUX)
857 #ifdef CONFIG_FEATURE_IPROUTE
858 argv_printf (&argv
, "%s route add %s/%d via %s",
861 count_netmask_bits(netmask
),
863 if (r
->metric_defined
)
864 argv_printf_cat (&argv
, "metric %d", r
->metric
);
867 argv_printf (&argv
, "%s add -net %s netmask %s gw %s",
872 if (r
->metric_defined
)
873 argv_printf_cat (&argv
, "metric %d", r
->metric
);
874 #endif /*CONFIG_FEATURE_IPROUTE*/
875 argv_msg (D_ROUTE
, &argv
);
876 status
= openvpn_execve_check (&argv
, es
, 0, "ERROR: Linux route add command failed");
878 #elif defined (WIN32)
880 argv_printf (&argv
, "%s%sc ADD %s MASK %s %s",
882 WIN_ROUTE_PATH_SUFFIX
,
886 if (r
->metric_defined
)
887 argv_printf_cat (&argv
, "METRIC %d", r
->metric
);
889 argv_msg (D_ROUTE
, &argv
);
891 if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_IPAPI
)
893 status
= add_route_ipapi (r
, tt
);
894 msg (D_ROUTE
, "Route addition via IPAPI %s", status
? "succeeded" : "failed");
896 else if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_EXE
)
898 netcmd_semaphore_lock ();
899 status
= openvpn_execve_check (&argv
, es
, 0, "ERROR: Windows route add command failed");
900 netcmd_semaphore_release ();
902 else if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_ADAPTIVE
)
904 status
= add_route_ipapi (r
, tt
);
905 msg (D_ROUTE
, "Route addition via IPAPI %s [adaptive]", status
? "succeeded" : "failed");
908 msg (D_ROUTE
, "Route addition fallback to route.exe");
909 netcmd_semaphore_lock ();
910 status
= openvpn_execve_check (&argv
, es
, 0, "ERROR: Windows route add command failed [adaptive]");
911 netcmd_semaphore_release ();
919 #elif defined (TARGET_SOLARIS)
921 /* example: route add 192.0.2.32 -netmask 255.255.255.224 somegateway */
923 argv_printf (&argv
, "%s add",
927 if (r
->metric_defined
)
928 argv_printf_cat (&argv
, "-rtt %d", r
->metric
);
931 argv_printf_cat (&argv
, "%s -netmask %s %s",
936 argv_msg (D_ROUTE
, &argv
);
937 status
= openvpn_execve_check (&argv
, es
, 0, "ERROR: Solaris route add command failed");
939 #elif defined(TARGET_FREEBSD)
941 argv_printf (&argv
, "%s add",
945 if (r
->metric_defined
)
946 argv_printf_cat (&argv
, "-rtt %d", r
->metric
);
949 argv_printf_cat (&argv
, "-net %s %s %s",
954 argv_msg (D_ROUTE
, &argv
);
955 status
= openvpn_execve_check (&argv
, es
, 0, "ERROR: FreeBSD route add command failed");
957 #elif defined(TARGET_DRAGONFLY)
959 argv_printf (&argv
, "%s add",
963 if (r
->metric_defined
)
964 argv_printf_cat (&argv
, "-rtt %d", r
->metric
);
967 argv_printf_cat (&argv
, "-net %s %s %s",
972 argv_msg (D_ROUTE
, &argv
);
973 status
= openvpn_execve_check (&argv
, es
, 0, "ERROR: DragonFly route add command failed");
975 #elif defined(TARGET_DARWIN)
977 argv_printf (&argv
, "%s add",
981 if (r
->metric_defined
)
982 argv_printf_cat (&argv
, "-rtt %d", r
->metric
);
985 argv_printf_cat (&argv
, "-net %s %s %s",
990 argv_msg (D_ROUTE
, &argv
);
991 status
= openvpn_execve_check (&argv
, es
, 0, "ERROR: OS X route add command failed");
993 #elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
995 argv_printf (&argv
, "%s add",
999 if (r
->metric_defined
)
1000 argv_printf_cat (&argv
, "-rtt %d", r
->metric
);
1003 argv_printf_cat (&argv
, "-net %s %s -netmask %s",
1008 argv_msg (D_ROUTE
, &argv
);
1009 status
= openvpn_execve_check (&argv
, es
, 0, "ERROR: OpenBSD/NetBSD route add command failed");
1012 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");
1016 r
->defined
= status
;
1022 delete_route (const struct route
*r
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
)
1026 const char *network
;
1027 const char *netmask
;
1028 const char *gateway
;
1036 network
= print_in_addr_t (r
->network
, 0, &gc
);
1037 netmask
= print_in_addr_t (r
->netmask
, 0, &gc
);
1038 gateway
= print_in_addr_t (r
->gateway
, 0, &gc
);
1040 #if defined(TARGET_LINUX)
1041 #ifdef CONFIG_FEATURE_IPROUTE
1042 argv_printf (&argv
, "%s route del %s/%d",
1045 count_netmask_bits(netmask
));
1048 argv_printf (&argv
, "%s del -net %s netmask %s",
1052 #endif /*CONFIG_FEATURE_IPROUTE*/
1053 if (r
->metric_defined
)
1054 argv_printf_cat (&argv
, "metric %d", r
->metric
);
1055 argv_msg (D_ROUTE
, &argv
);
1056 openvpn_execve_check (&argv
, es
, 0, "ERROR: Linux route delete command failed");
1058 #elif defined (WIN32)
1060 argv_printf (&argv
, "%s%sc DELETE %s MASK %s %s",
1062 WIN_ROUTE_PATH_SUFFIX
,
1067 argv_msg (D_ROUTE
, &argv
);
1069 if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_IPAPI
)
1071 const bool status
= del_route_ipapi (r
, tt
);
1072 msg (D_ROUTE
, "Route deletion via IPAPI %s", status
? "succeeded" : "failed");
1074 else if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_EXE
)
1076 netcmd_semaphore_lock ();
1077 openvpn_execve_check (&argv
, es
, 0, "ERROR: Windows route delete command failed");
1078 netcmd_semaphore_release ();
1080 else if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_ADAPTIVE
)
1082 const bool status
= del_route_ipapi (r
, tt
);
1083 msg (D_ROUTE
, "Route deletion via IPAPI %s [adaptive]", status
? "succeeded" : "failed");
1086 msg (D_ROUTE
, "Route deletion fallback to route.exe");
1087 netcmd_semaphore_lock ();
1088 openvpn_execve_check (&argv
, es
, 0, "ERROR: Windows route delete command failed [adaptive]");
1089 netcmd_semaphore_release ();
1097 #elif defined (TARGET_SOLARIS)
1099 argv_printf (&argv
, "%s delete %s -netmask %s %s",
1105 argv_msg (D_ROUTE
, &argv
);
1106 openvpn_execve_check (&argv
, es
, 0, "ERROR: Solaris route delete command failed");
1108 #elif defined(TARGET_FREEBSD)
1110 argv_printf (&argv
, "%s delete -net %s %s %s",
1116 argv_msg (D_ROUTE
, &argv
);
1117 openvpn_execve_check (&argv
, es
, 0, "ERROR: FreeBSD route delete command failed");
1119 #elif defined(TARGET_DRAGONFLY)
1121 argv_printf (&argv
, "%s delete -net %s %s %s",
1127 argv_msg (D_ROUTE
, &argv
);
1128 openvpn_execve_check (&argv
, es
, 0, "ERROR: DragonFly route delete command failed");
1130 #elif defined(TARGET_DARWIN)
1132 argv_printf (&argv
, "%s delete -net %s %s %s",
1138 argv_msg (D_ROUTE
, &argv
);
1139 openvpn_execve_check (&argv
, es
, 0, "ERROR: OS X route delete command failed");
1141 #elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1143 argv_printf (&argv
, "%s delete -net %s %s -netmask %s",
1149 argv_msg (D_ROUTE
, &argv
);
1150 openvpn_execve_check (&argv
, es
, 0, "ERROR: OpenBSD/NetBSD route delete command failed");
1153 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");
1161 * The --redirect-gateway option requires OS-specific code below
1162 * to get the current default gateway.
1167 static const MIB_IPFORWARDTABLE
*
1168 get_windows_routing_table (struct gc_arena
*gc
)
1171 PMIB_IPFORWARDTABLE rt
= NULL
;
1174 status
= GetIpForwardTable (NULL
, &size
, TRUE
);
1175 if (status
== ERROR_INSUFFICIENT_BUFFER
)
1177 rt
= (PMIB_IPFORWARDTABLE
) gc_malloc (size
, false, gc
);
1178 status
= GetIpForwardTable (rt
, &size
, TRUE
);
1179 if (status
!= NO_ERROR
)
1181 msg (D_ROUTE
, "NOTE: GetIpForwardTable returned error: %s (code=%u)",
1182 strerror_win32 (status
, gc
),
1183 (unsigned int)status
);
1191 test_route (const IP_ADAPTER_INFO
*adapters
,
1192 const in_addr_t gateway
,
1196 DWORD i
= adapter_index_of_ip (adapters
, gateway
, &count
, NULL
);
1203 test_route_helper (bool *ret
,
1207 const IP_ADAPTER_INFO
*adapters
,
1208 const in_addr_t gateway
)
1213 c
= test_route (adapters
, gateway
, NULL
);
1223 * If we tried to add routes now, would we succeed?
1226 test_routes (const struct route_list
*rl
, const struct tuntap
*tt
)
1228 struct gc_arena gc
= gc_new ();
1229 const IP_ADAPTER_INFO
*adapters
= get_adapter_info_list (&gc
);
1234 bool adapter_up
= false;
1236 if (is_adapter_up (tt
, adapters
))
1244 for (i
= 0; i
< rl
->n
; ++i
)
1245 test_route_helper (&ret
, &count
, &good
, &ambig
, adapters
, rl
->routes
[i
].gateway
);
1247 if ((rl
->flags
& RG_ENABLE
) && rl
->spec
.remote_endpoint_defined
)
1248 test_route_helper (&ret
, &count
, &good
, &ambig
, adapters
, rl
->spec
.remote_endpoint
);
1252 msg (D_ROUTE
, "TEST ROUTES: %d/%d succeeded len=%d ret=%d a=%d u/d=%s",
1258 adapter_up
? "up" : "down");
1264 static const MIB_IPFORWARDROW
*
1265 get_default_gateway_row (const MIB_IPFORWARDTABLE
*routes
)
1267 struct gc_arena gc
= gc_new ();
1268 DWORD lowest_metric
= ~0;
1269 const MIB_IPFORWARDROW
*ret
= NULL
;
1275 for (i
= 0; i
< routes
->dwNumEntries
; ++i
)
1277 const MIB_IPFORWARDROW
*row
= &routes
->table
[i
];
1278 const in_addr_t net
= ntohl (row
->dwForwardDest
);
1279 const in_addr_t mask
= ntohl (row
->dwForwardMask
);
1280 const DWORD index
= row
->dwForwardIfIndex
;
1281 const DWORD metric
= row
->dwForwardMetric1
;
1283 dmsg (D_ROUTE_DEBUG
, "GDGR: route[%d] %s/%s i=%d m=%d",
1285 print_in_addr_t ((in_addr_t
) net
, 0, &gc
),
1286 print_in_addr_t ((in_addr_t
) mask
, 0, &gc
),
1290 if (!net
&& !mask
&& metric
< lowest_metric
)
1293 lowest_metric
= metric
;
1299 dmsg (D_ROUTE_DEBUG
, "GDGR: best=%d lm=%u", best
, (unsigned int)lowest_metric
);
1306 get_default_gateway (in_addr_t
*gw
, in_addr_t
*netmask
)
1308 struct gc_arena gc
= gc_new ();
1309 bool ret_bool
= false;
1311 const IP_ADAPTER_INFO
*adapters
= get_adapter_info_list (&gc
);
1312 const MIB_IPFORWARDTABLE
*routes
= get_windows_routing_table (&gc
);
1313 const MIB_IPFORWARDROW
*row
= get_default_gateway_row (routes
);
1317 *gw
= ntohl (row
->dwForwardNextHop
);
1320 if (adapter_index_of_ip (adapters
, *gw
, NULL
, netmask
) == ~0)
1331 windows_route_find_if_index (const struct route
*r
, const struct tuntap
*tt
)
1333 struct gc_arena gc
= gc_new ();
1336 const IP_ADAPTER_INFO
*adapters
= get_adapter_info_list (&gc
);
1337 const IP_ADAPTER_INFO
*tun_adapter
= get_tun_adapter (tt
, adapters
);
1338 bool on_tun
= false;
1340 /* first test on tun interface */
1341 if (is_ip_in_adapter_subnet (tun_adapter
, r
->gateway
, NULL
))
1343 ret
= tun_adapter
->Index
;
1347 else /* test on other interfaces */
1349 count
= test_route (adapters
, r
->gateway
, &ret
);
1354 msg (M_WARN
, "Warning: route gateway is not reachable on any active network adapters: %s",
1355 print_in_addr_t (r
->gateway
, 0, &gc
));
1360 msg (M_WARN
, "Warning: route gateway is ambiguous: %s (%d matches)",
1361 print_in_addr_t (r
->gateway
, 0, &gc
),
1366 dmsg (D_ROUTE_DEBUG
, "DEBUG: route find if: on_tun=%d count=%d index=%d",
1376 add_route_ipapi (const struct route
*r
, const struct tuntap
*tt
)
1378 struct gc_arena gc
= gc_new ();
1381 const DWORD if_index
= windows_route_find_if_index (r
, tt
);
1385 MIB_IPFORWARDROW fr
;
1387 fr
.dwForwardDest
= htonl (r
->network
);
1388 fr
.dwForwardMask
= htonl (r
->netmask
);
1389 fr
.dwForwardPolicy
= 0;
1390 fr
.dwForwardNextHop
= htonl (r
->gateway
);
1391 fr
.dwForwardIfIndex
= if_index
;
1392 fr
.dwForwardType
= 4; /* the next hop is not the final dest */
1393 fr
.dwForwardProto
= 3; /* PROTO_IP_NETMGMT */
1394 fr
.dwForwardAge
= 0;
1395 fr
.dwForwardNextHopAS
= 0;
1396 fr
.dwForwardMetric1
= r
->metric_defined
? r
->metric
: 1;
1397 fr
.dwForwardMetric2
= ~0;
1398 fr
.dwForwardMetric3
= ~0;
1399 fr
.dwForwardMetric4
= ~0;
1400 fr
.dwForwardMetric5
= ~0;
1402 if ((r
->network
& r
->netmask
) != r
->network
)
1403 msg (M_WARN
, "Warning: address %s is not a network address in relation to netmask %s",
1404 print_in_addr_t (r
->network
, 0, &gc
),
1405 print_in_addr_t (r
->netmask
, 0, &gc
));
1407 status
= CreateIpForwardEntry (&fr
);
1409 if (status
== NO_ERROR
)
1413 /* failed, try increasing the metric to work around Vista issue */
1414 const unsigned int forward_metric_limit
= 2048; /* iteratively retry higher metrics up to this limit */
1416 for ( ; fr
.dwForwardMetric1
<= forward_metric_limit
; ++fr
.dwForwardMetric1
)
1418 /* try a different forward type=3 ("the next hop is the final dest") in addition to 4.
1419 --redirect-gateway over RRAS seems to need this. */
1420 for (fr
.dwForwardType
= 4; fr
.dwForwardType
>= 3; --fr
.dwForwardType
)
1422 status
= CreateIpForwardEntry (&fr
);
1423 if (status
== NO_ERROR
)
1425 msg (D_ROUTE
, "ROUTE: CreateIpForwardEntry succeeded with dwForwardMetric1=%u and dwForwardType=%u",
1426 (unsigned int)fr
.dwForwardMetric1
,
1427 (unsigned int)fr
.dwForwardType
);
1431 else if (status
!= ERROR_BAD_ARGUMENTS
)
1437 if (status
!= NO_ERROR
)
1438 msg (M_WARN
, "ROUTE: route addition failed using CreateIpForwardEntry: %s [status=%u if_index=%u]",
1439 strerror_win32 (status
, &gc
),
1440 (unsigned int)status
,
1441 (unsigned int)if_index
);
1450 del_route_ipapi (const struct route
*r
, const struct tuntap
*tt
)
1452 struct gc_arena gc
= gc_new ();
1455 const DWORD if_index
= windows_route_find_if_index (r
, tt
);
1459 MIB_IPFORWARDROW fr
;
1462 fr
.dwForwardDest
= htonl (r
->network
);
1463 fr
.dwForwardMask
= htonl (r
->netmask
);
1464 fr
.dwForwardPolicy
= 0;
1465 fr
.dwForwardNextHop
= htonl (r
->gateway
);
1466 fr
.dwForwardIfIndex
= if_index
;
1468 status
= DeleteIpForwardEntry (&fr
);
1470 if (status
== NO_ERROR
)
1473 msg (M_WARN
, "ROUTE: route deletion failed using DeleteIpForwardEntry: %s",
1474 strerror_win32 (status
, &gc
));
1482 format_route_entry (const MIB_IPFORWARDROW
*r
, struct gc_arena
*gc
)
1484 struct buffer out
= alloc_buf_gc (256, gc
);
1485 buf_printf (&out
, "%s %s %s p=%d i=%d t=%d pr=%d a=%d h=%d m=%d/%d/%d/%d/%d",
1486 print_in_addr_t (r
->dwForwardDest
, IA_NET_ORDER
, gc
),
1487 print_in_addr_t (r
->dwForwardMask
, IA_NET_ORDER
, gc
),
1488 print_in_addr_t (r
->dwForwardNextHop
, IA_NET_ORDER
, gc
),
1489 (int)r
->dwForwardPolicy
,
1490 (int)r
->dwForwardIfIndex
,
1491 (int)r
->dwForwardType
,
1492 (int)r
->dwForwardProto
,
1493 (int)r
->dwForwardAge
,
1494 (int)r
->dwForwardNextHopAS
,
1495 (int)r
->dwForwardMetric1
,
1496 (int)r
->dwForwardMetric2
,
1497 (int)r
->dwForwardMetric3
,
1498 (int)r
->dwForwardMetric4
,
1499 (int)r
->dwForwardMetric5
);
1504 * Show current routing table
1507 show_routes (int msglev
)
1509 struct gc_arena gc
= gc_new ();
1512 const MIB_IPFORWARDTABLE
*rt
= get_windows_routing_table (&gc
);
1514 msg (msglev
, "SYSTEM ROUTING TABLE");
1517 for (i
= 0; i
< rt
->dwNumEntries
; ++i
)
1519 msg (msglev
, "%s", format_route_entry (&rt
->table
[i
], &gc
));
1525 #elif defined(TARGET_LINUX)
1528 get_default_gateway (in_addr_t
*gateway
, in_addr_t
*netmask
)
1530 struct gc_arena gc
= gc_new ();
1532 FILE *fp
= fopen ("/proc/net/route", "r");
1538 unsigned int lowest_metric
= ~0;
1539 in_addr_t best_gw
= 0;
1540 while (fgets (line
, sizeof (line
), fp
) != NULL
)
1544 unsigned int net_x
= 0;
1545 unsigned int mask_x
= 0;
1546 unsigned int gw_x
= 0;
1547 unsigned int metric
= 0;
1548 const int np
= sscanf (line
, "%*s\t%x\t%x\t%*s\t%*s\t%*s\t%d\t%x",
1555 const in_addr_t net
= ntohl (net_x
);
1556 const in_addr_t mask
= ntohl (mask_x
);
1557 const in_addr_t gw
= ntohl (gw_x
);
1559 dmsg (D_ROUTE_DEBUG
, "GDG: route[%d] %s/%s/%s m=%u",
1561 print_in_addr_t ((in_addr_t
) net
, 0, &gc
),
1562 print_in_addr_t ((in_addr_t
) mask
, 0, &gc
),
1563 print_in_addr_t ((in_addr_t
) gw
, 0, &gc
),
1566 if (!net
&& !mask
&& metric
< lowest_metric
)
1569 lowest_metric
= metric
;
1583 *netmask
= 0xFFFFFF00; /* FIXME -- get the real netmask of the adapter containing the default gateway */
1588 dmsg (D_ROUTE_DEBUG
, "GDG: best=%s[%d] lm=%u",
1589 print_in_addr_t ((in_addr_t
) best_gw
, 0, &gc
),
1591 (unsigned int)lowest_metric
);
1598 #elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)
1600 #include <sys/types.h>
1601 #include <sys/socket.h>
1602 #include <netinet/in.h>
1604 /* all of this is taken from <net/route.h> in FreeBSD */
1606 #define RTA_GATEWAY 0x2
1607 #define RTA_NETMASK 0x4
1610 #define RTM_VERSION 5
1613 #define RTF_GATEWAY 0x2
1616 * These numbers are used by reliable protocols for determining
1617 * retransmission behavior and are included in the routing structure.
1620 u_long rmx_locks
; /* Kernel must leave these values alone */
1621 u_long rmx_mtu
; /* MTU for this path */
1622 u_long rmx_hopcount
; /* max hops expected */
1623 u_long rmx_expire
; /* lifetime for route, e.g. redirect */
1624 u_long rmx_recvpipe
; /* inbound delay-bandwidth product */
1625 u_long rmx_sendpipe
; /* outbound delay-bandwidth product */
1626 u_long rmx_ssthresh
; /* outbound gateway buffer limit */
1627 u_long rmx_rtt
; /* estimated round trip time */
1628 u_long rmx_rttvar
; /* estimated rtt variance */
1629 u_long rmx_pksent
; /* packets sent using this route */
1630 u_long rmx_filler
[4]; /* will be used for T/TCP later */
1634 * Structures for routing messages.
1637 u_short rtm_msglen
; /* to skip over non-understood messages */
1638 u_char rtm_version
; /* future binary compatibility */
1639 u_char rtm_type
; /* message type */
1640 u_short rtm_index
; /* index for associated ifp */
1641 int rtm_flags
; /* flags, incl. kern & message, e.g. DONE */
1642 int rtm_addrs
; /* bitmask identifying sockaddrs in msg */
1643 pid_t rtm_pid
; /* identify sender */
1644 int rtm_seq
; /* for sender to identify action */
1645 int rtm_errno
; /* why failed */
1646 int rtm_use
; /* from rtentry */
1647 u_long rtm_inits
; /* which metrics we are initializing */
1648 struct rt_metrics rtm_rmx
; /* metrics themselves */
1652 struct rt_msghdr m_rtm
;
1656 #define ROUNDUP(a) \
1657 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
1660 get_default_gateway (in_addr_t
*ret
, in_addr_t
*netmask
)
1662 struct gc_arena gc
= gc_new ();
1663 int s
, seq
, l
, pid
, rtm_addrs
, i
;
1664 struct sockaddr so_dst
, so_mask
;
1665 char *cp
= m_rtmsg
.m_space
;
1666 struct sockaddr
*gate
= NULL
, *sa
;
1667 struct rt_msghdr
*rtm_aux
;
1669 #define NEXTADDR(w, u) \
1670 if (rtm_addrs & (w)) {\
1671 l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
1674 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
1676 #define rtm m_rtmsg.m_rtm
1680 rtm_addrs
= RTA_DST
| RTA_NETMASK
;
1682 bzero(&so_dst
, sizeof(so_dst
));
1683 bzero(&so_mask
, sizeof(so_mask
));
1684 bzero(&rtm
, sizeof(struct rt_msghdr
));
1686 rtm
.rtm_type
= RTM_GET
;
1687 rtm
.rtm_flags
= RTF_UP
| RTF_GATEWAY
;
1688 rtm
.rtm_version
= RTM_VERSION
;
1689 rtm
.rtm_seq
= ++seq
;
1690 rtm
.rtm_addrs
= rtm_addrs
;
1692 so_dst
.sa_family
= AF_INET
;
1693 so_dst
.sa_len
= sizeof(struct sockaddr_in
);
1694 so_mask
.sa_family
= AF_INET
;
1695 so_mask
.sa_len
= sizeof(struct sockaddr_in
);
1697 NEXTADDR(RTA_DST
, so_dst
);
1698 NEXTADDR(RTA_NETMASK
, so_mask
);
1700 rtm
.rtm_msglen
= l
= cp
- (char *)&m_rtmsg
;
1702 s
= socket(PF_ROUTE
, SOCK_RAW
, 0);
1704 if (write(s
, (char *)&m_rtmsg
, l
) < 0)
1706 warn("writing to routing socket");
1713 l
= read(s
, (char *)&m_rtmsg
, sizeof(m_rtmsg
));
1714 } while (l
> 0 && (rtm
.rtm_seq
!= seq
|| rtm
.rtm_pid
!= pid
));
1720 cp
= ((char *)(rtm_aux
+ 1));
1721 if (rtm_aux
->rtm_addrs
) {
1722 for (i
= 1; i
; i
<<= 1)
1723 if (i
& rtm_aux
->rtm_addrs
) {
1724 sa
= (struct sockaddr
*)cp
;
1725 if (i
== RTA_GATEWAY
)
1739 *ret
= ntohl(((struct sockaddr_in
*)gate
)->sin_addr
.s_addr
);
1741 msg (M_INFO
, "gw %s",
1742 print_in_addr_t ((in_addr_t
) *ret
, 0, &gc
));
1747 *netmask
= 0xFFFFFF00; // FIXME -- get the real netmask of the adapter containing the default gateway
1760 #elif defined(TARGET_DARWIN)
1762 #include <sys/types.h>
1763 #include <sys/socket.h>
1764 #include <netinet/in.h>
1766 /* all of this is taken from <net/route.h> in Darwin */
1768 #define RTA_GATEWAY 0x2
1769 #define RTA_NETMASK 0x4
1772 #define RTM_VERSION 5
1775 #define RTF_GATEWAY 0x2
1778 * These numbers are used by reliable protocols for determining
1779 * retransmission behavior and are included in the routing structure.
1782 u_long rmx_locks
; /* Kernel must leave these values alone */
1783 u_long rmx_mtu
; /* MTU for this path */
1784 u_long rmx_hopcount
; /* max hops expected */
1785 u_long rmx_expire
; /* lifetime for route, e.g. redirect */
1786 u_long rmx_recvpipe
; /* inbound delay-bandwidth product */
1787 u_long rmx_sendpipe
; /* outbound delay-bandwidth product */
1788 u_long rmx_ssthresh
; /* outbound gateway buffer limit */
1789 u_long rmx_rtt
; /* estimated round trip time */
1790 u_long rmx_rttvar
; /* estimated rtt variance */
1791 u_long rmx_pksent
; /* packets sent using this route */
1792 u_long rmx_filler
[4]; /* will be used for T/TCP later */
1796 * Structures for routing messages.
1799 u_short rtm_msglen
; /* to skip over non-understood messages */
1800 u_char rtm_version
; /* future binary compatibility */
1801 u_char rtm_type
; /* message type */
1802 u_short rtm_index
; /* index for associated ifp */
1803 int rtm_flags
; /* flags, incl. kern & message, e.g. DONE */
1804 int rtm_addrs
; /* bitmask identifying sockaddrs in msg */
1805 pid_t rtm_pid
; /* identify sender */
1806 int rtm_seq
; /* for sender to identify action */
1807 int rtm_errno
; /* why failed */
1808 int rtm_use
; /* from rtentry */
1809 u_long rtm_inits
; /* which metrics we are initializing */
1810 struct rt_metrics rtm_rmx
; /* metrics themselves */
1814 struct rt_msghdr m_rtm
;
1818 #define ROUNDUP(a) \
1819 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
1822 get_default_gateway (in_addr_t
*ret
, in_addr_t
*netmask
)
1824 struct gc_arena gc
= gc_new ();
1825 int s
, seq
, l
, pid
, rtm_addrs
, i
;
1826 struct sockaddr so_dst
, so_mask
;
1827 char *cp
= m_rtmsg
.m_space
;
1828 struct sockaddr
*gate
= NULL
, *sa
;
1829 struct rt_msghdr
*rtm_aux
;
1831 #define NEXTADDR(w, u) \
1832 if (rtm_addrs & (w)) {\
1833 l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
1836 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
1838 #define rtm m_rtmsg.m_rtm
1842 rtm_addrs
= RTA_DST
| RTA_NETMASK
;
1844 bzero(&so_dst
, sizeof(so_dst
));
1845 bzero(&so_mask
, sizeof(so_mask
));
1846 bzero(&rtm
, sizeof(struct rt_msghdr
));
1848 rtm
.rtm_type
= RTM_GET
;
1849 rtm
.rtm_flags
= RTF_UP
| RTF_GATEWAY
;
1850 rtm
.rtm_version
= RTM_VERSION
;
1851 rtm
.rtm_seq
= ++seq
;
1852 rtm
.rtm_addrs
= rtm_addrs
;
1854 so_dst
.sa_family
= AF_INET
;
1855 so_dst
.sa_len
= sizeof(struct sockaddr_in
);
1856 so_mask
.sa_family
= AF_INET
;
1857 so_mask
.sa_len
= sizeof(struct sockaddr_in
);
1859 NEXTADDR(RTA_DST
, so_dst
);
1860 NEXTADDR(RTA_NETMASK
, so_mask
);
1862 rtm
.rtm_msglen
= l
= cp
- (char *)&m_rtmsg
;
1864 s
= socket(PF_ROUTE
, SOCK_RAW
, 0);
1866 if (write(s
, (char *)&m_rtmsg
, l
) < 0)
1868 msg (M_WARN
, "ROUTE: problem writing to routing socket");
1875 l
= read(s
, (char *)&m_rtmsg
, sizeof(m_rtmsg
));
1876 } while (l
> 0 && (rtm
.rtm_seq
!= seq
|| rtm
.rtm_pid
!= pid
));
1882 cp
= ((char *)(rtm_aux
+ 1));
1883 if (rtm_aux
->rtm_addrs
) {
1884 for (i
= 1; i
; i
<<= 1)
1885 if (i
& rtm_aux
->rtm_addrs
) {
1886 sa
= (struct sockaddr
*)cp
;
1887 if (i
== RTA_GATEWAY
)
1901 *ret
= ntohl(((struct sockaddr_in
*)gate
)->sin_addr
.s_addr
);
1903 msg (M_INFO
, "gw %s",
1904 print_in_addr_t ((in_addr_t
) *ret
, 0, &gc
));
1909 *netmask
= 0xFFFFFF00; // FIXME -- get the real netmask of the adapter containing the default gateway
1922 #elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1924 #include <sys/types.h>
1925 #include <sys/socket.h>
1926 #include <netinet/in.h>
1928 /* all of this is taken from <net/route.h> in OpenBSD 3.6 */
1929 #define RTA_DST 0x1 /* destination sockaddr present */
1930 #define RTA_GATEWAY 0x2 /* gateway sockaddr present */
1931 #define RTA_NETMASK 0x4 /* netmask sockaddr present */
1933 #define RTM_GET 0x4 /* Report Metrics */
1935 #define RTM_VERSION 3 /* Up the ante and ignore older versions */
1937 #define RTF_UP 0x1 /* route usable */
1938 #define RTF_GATEWAY 0x2 /* destination is a gateway */
1941 * Huge version for userland compatibility.
1944 u_long rmx_locks
; /* Kernel must leave these values alone */
1945 u_long rmx_mtu
; /* MTU for this path */
1946 u_long rmx_hopcount
; /* max hops expected */
1947 u_long rmx_expire
; /* lifetime for route, e.g. redirect */
1948 u_long rmx_recvpipe
; /* inbound delay-bandwidth product */
1949 u_long rmx_sendpipe
; /* outbound delay-bandwidth product */
1950 u_long rmx_ssthresh
; /* outbound gateway buffer limit */
1951 u_long rmx_rtt
; /* estimated round trip time */
1952 u_long rmx_rttvar
; /* estimated rtt variance */
1953 u_long rmx_pksent
; /* packets sent using this route */
1957 * Structures for routing messages.
1960 u_short rtm_msglen
; /* to skip over non-understood messages */
1961 u_char rtm_version
; /* future binary compatibility */
1962 u_char rtm_type
; /* message type */
1963 u_short rtm_index
; /* index for associated ifp */
1964 int rtm_flags
; /* flags, incl. kern & message, e.g. DONE */
1965 int rtm_addrs
; /* bitmask identifying sockaddrs in msg */
1966 pid_t rtm_pid
; /* identify sender */
1967 int rtm_seq
; /* for sender to identify action */
1968 int rtm_errno
; /* why failed */
1969 int rtm_use
; /* from rtentry */
1970 u_long rtm_inits
; /* which metrics we are initializing */
1971 struct rt_metrics rtm_rmx
; /* metrics themselves */
1975 struct rt_msghdr m_rtm
;
1979 #define ROUNDUP(a) \
1980 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
1983 get_default_gateway (in_addr_t
*ret
, in_addr_t
*netmask
)
1985 struct gc_arena gc
= gc_new ();
1986 int s
, seq
, l
, rtm_addrs
, i
;
1988 struct sockaddr so_dst
, so_mask
;
1989 char *cp
= m_rtmsg
.m_space
;
1990 struct sockaddr
*gate
= NULL
, *sa
;
1991 struct rt_msghdr
*rtm_aux
;
1993 #define NEXTADDR(w, u) \
1994 if (rtm_addrs & (w)) {\
1995 l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
1998 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
2000 #define rtm m_rtmsg.m_rtm
2004 rtm_addrs
= RTA_DST
| RTA_NETMASK
;
2006 bzero(&so_dst
, sizeof(so_dst
));
2007 bzero(&so_mask
, sizeof(so_mask
));
2008 bzero(&rtm
, sizeof(struct rt_msghdr
));
2010 rtm
.rtm_type
= RTM_GET
;
2011 rtm
.rtm_flags
= RTF_UP
| RTF_GATEWAY
;
2012 rtm
.rtm_version
= RTM_VERSION
;
2013 rtm
.rtm_seq
= ++seq
;
2014 rtm
.rtm_addrs
= rtm_addrs
;
2016 so_dst
.sa_family
= AF_INET
;
2017 so_dst
.sa_len
= sizeof(struct sockaddr_in
);
2018 so_mask
.sa_family
= AF_INET
;
2019 so_mask
.sa_len
= sizeof(struct sockaddr_in
);
2021 NEXTADDR(RTA_DST
, so_dst
);
2022 NEXTADDR(RTA_NETMASK
, so_mask
);
2024 rtm
.rtm_msglen
= l
= cp
- (char *)&m_rtmsg
;
2026 s
= socket(PF_ROUTE
, SOCK_RAW
, 0);
2028 if (write(s
, (char *)&m_rtmsg
, l
) < 0)
2030 warn("writing to routing socket");
2037 l
= read(s
, (char *)&m_rtmsg
, sizeof(m_rtmsg
));
2038 } while (l
> 0 && (rtm
.rtm_seq
!= seq
|| rtm
.rtm_pid
!= pid
));
2044 cp
= ((char *)(rtm_aux
+ 1));
2045 if (rtm_aux
->rtm_addrs
) {
2046 for (i
= 1; i
; i
<<= 1)
2047 if (i
& rtm_aux
->rtm_addrs
) {
2048 sa
= (struct sockaddr
*)cp
;
2049 if (i
== RTA_GATEWAY
)
2063 *ret
= ntohl(((struct sockaddr_in
*)gate
)->sin_addr
.s_addr
);
2065 msg (M_INFO
, "gw %s",
2066 print_in_addr_t ((in_addr_t
) *ret
, 0, &gc
));
2071 *netmask
= 0xFFFFFF00; // FIXME -- get the real netmask of the adapter containing the default gateway
2087 get_default_gateway (in_addr_t
*ret
, in_addr_t
*netmask
) /* PLATFORM-SPECIFIC */
2095 netmask_to_netbits (const in_addr_t network
, const in_addr_t netmask
, int *netbits
)
2098 const int addrlen
= sizeof (in_addr_t
) * 8;
2100 if ((network
& netmask
) == network
)
2102 for (i
= 0; i
<= addrlen
; ++i
)
2104 in_addr_t mask
= netbits_to_netmask (i
);
2105 if (mask
== netmask
)
2119 * get_bypass_addresses() is used by the redirect-gateway bypass-x
2120 * functions to build a route bypass to selected DHCP/DNS servers,
2121 * so that outgoing packets to these servers don't end up in the tunnel.
2127 add_host_route_if_nonlocal (struct route_bypass
*rb
, const in_addr_t addr
)
2129 if (test_local_addr(addr
) == TLA_NONLOCAL
&& addr
!= 0 && addr
!= ~0)
2130 add_bypass_address (rb
, addr
);
2134 add_host_route_array (struct route_bypass
*rb
, const IP_ADDR_STRING
*iplist
)
2138 bool succeed
= false;
2139 const in_addr_t ip
= getaddr (GETADDR_HOST_ORDER
, iplist
->IpAddress
.String
, 0, &succeed
, NULL
);
2142 add_host_route_if_nonlocal (rb
, ip
);
2144 iplist
= iplist
->Next
;
2149 get_bypass_addresses (struct route_bypass
*rb
, const unsigned int flags
)
2151 struct gc_arena gc
= gc_new ();
2152 /*bool ret_bool = false;*/
2154 /* get full routing table */
2155 const MIB_IPFORWARDTABLE
*routes
= get_windows_routing_table (&gc
);
2157 /* get the route which represents the default gateway */
2158 const MIB_IPFORWARDROW
*row
= get_default_gateway_row (routes
);
2162 /* get the adapter which the default gateway is associated with */
2163 const IP_ADAPTER_INFO
*dgi
= get_adapter_info (row
->dwForwardIfIndex
, &gc
);
2165 /* get extra adapter info, such as DNS addresses */
2166 const IP_PER_ADAPTER_INFO
*pai
= get_per_adapter_info (row
->dwForwardIfIndex
, &gc
);
2168 /* Bypass DHCP server address */
2169 if ((flags
& RG_BYPASS_DHCP
) && dgi
&& dgi
->DhcpEnabled
)
2170 add_host_route_array (rb
, &dgi
->DhcpServer
);
2172 /* Bypass DNS server addresses */
2173 if ((flags
& RG_BYPASS_DNS
) && pai
)
2174 add_host_route_array (rb
, &pai
->DnsServerList
);
2183 get_bypass_addresses (struct route_bypass
*rb
, const unsigned int flags
) /* PLATFORM-SPECIFIC */
2191 #if defined(TARGET_LINUX)
2194 get_default_gateway_mac_addr (unsigned char *macaddr
)
2196 struct ifreq
*ifr
, *ifend
;
2197 in_addr_t ina
, mask
;
2200 struct ifreq ifs
[20]; // Maximum number of interfaces to scan
2205 if (!get_default_gateway (&gwip
, NULL
))
2207 msg (M_WARN
, "GDGMA: get_default_gateway failed");
2211 if ((sd
= socket (AF_INET
, SOCK_DGRAM
, 0)) < 0)
2213 msg (M_WARN
, "GDGMA: socket() failed");
2217 ifc
.ifc_len
= sizeof (ifs
);
2219 if (ioctl (sd
, SIOCGIFCONF
, &ifc
) < 0)
2221 msg (M_WARN
, "GDGMA: ioctl(SIOCGIFCONF) failed");
2225 /* scan through interface list */
2226 ifend
= ifs
+ (ifc
.ifc_len
/ sizeof (struct ifreq
));
2227 for (ifr
= ifc
.ifc_req
; ifr
< ifend
; ifr
++)
2229 if (ifr
->ifr_addr
.sa_family
== AF_INET
)
2231 ina
= ntohl(((struct sockaddr_in
*) &ifr
->ifr_addr
)->sin_addr
.s_addr
);
2232 strncpynt (ifreq
.ifr_name
, ifr
->ifr_name
, sizeof (ifreq
.ifr_name
));
2234 dmsg (D_AUTO_USERID
, "GDGMA: %s", ifreq
.ifr_name
);
2236 /* check that the interface is up, and not point-to-point or loopback */
2237 if (ioctl (sd
, SIOCGIFFLAGS
, &ifreq
) < 0)
2239 dmsg (D_AUTO_USERID
, "GDGMA: SIOCGIFFLAGS(%s) failed", ifreq
.ifr_name
);
2243 if ((ifreq
.ifr_flags
& (IFF_UP
|IFF_LOOPBACK
)) != IFF_UP
)
2245 dmsg (D_AUTO_USERID
, "GDGMA: interface %s is down or loopback", ifreq
.ifr_name
);
2249 /* get interface netmask and check for correct subnet */
2250 if (ioctl (sd
, SIOCGIFNETMASK
, &ifreq
) < 0)
2252 dmsg (D_AUTO_USERID
, "GDGMA: SIOCGIFNETMASK(%s) failed", ifreq
.ifr_name
);
2256 mask
= ntohl(((struct sockaddr_in
*) &ifreq
.ifr_addr
)->sin_addr
.s_addr
);
2257 if (((gwip
^ ina
) & mask
) != 0)
2259 dmsg (D_AUTO_USERID
, "GDGMA: gwip=0x%08x ina=0x%08x mask=0x%08x",
2262 (unsigned int)mask
);
2270 msg (M_WARN
, "GDGMA: couldn't find gw interface");
2274 /* now get the hardware address. */
2275 memset (&ifreq
.ifr_hwaddr
, 0, sizeof (struct sockaddr
));
2276 if (ioctl (sd
, SIOCGIFHWADDR
, &ifreq
) < 0)
2278 msg (M_WARN
, "GDGMA: SIOCGIFHWADDR(%s) failed", ifreq
.ifr_name
);
2282 memcpy (macaddr
, &ifreq
.ifr_hwaddr
.sa_data
, 6);
2291 #elif defined(WIN32)
2294 get_default_gateway_mac_addr (unsigned char *macaddr
)
2296 struct gc_arena gc
= gc_new ();
2297 const IP_ADAPTER_INFO
*adapters
= get_adapter_info_list (&gc
);
2300 const IP_ADAPTER_INFO
*ai
;
2302 if (!get_default_gateway (&gwip
, NULL
))
2304 msg (M_WARN
, "GDGMA: get_default_gateway failed");
2308 a_index
= adapter_index_of_ip (adapters
, gwip
, NULL
, NULL
);
2309 ai
= get_adapter (adapters
, a_index
);
2313 msg (M_WARN
, "GDGMA: couldn't find gw interface");
2317 memcpy (macaddr
, ai
->Address
, 6);
2330 get_default_gateway_mac_addr (unsigned char *macaddr
) /* PLATFORM-SPECIFIC */
2336 #endif /* AUTO_USERID */
2339 * Test if addr is reachable via a local interface (return ILA_LOCAL),
2340 * or if it needs to be routed via the default gateway (return
2341 * ILA_NONLOCAL). If the target platform doesn't implement this
2342 * function, return ILA_NOT_IMPLEMENTED.
2344 * Used by redirect-gateway autolocal feature
2350 test_local_addr (const in_addr_t addr
)
2352 struct gc_arena gc
= gc_new ();
2353 const in_addr_t nonlocal_netmask
= 0x80000000L
; /* routes with netmask <= to this are considered non-local */
2354 bool ret
= TLA_NONLOCAL
;
2356 /* get full routing table */
2357 const MIB_IPFORWARDTABLE
*rt
= get_windows_routing_table (&gc
);
2361 for (i
= 0; i
< rt
->dwNumEntries
; ++i
)
2363 const MIB_IPFORWARDROW
*row
= &rt
->table
[i
];
2364 const in_addr_t net
= ntohl (row
->dwForwardDest
);
2365 const in_addr_t mask
= ntohl (row
->dwForwardMask
);
2366 if (mask
> nonlocal_netmask
&& (addr
& mask
) == net
)
2382 test_local_addr (const in_addr_t addr
) /* PLATFORM-SPECIFIC */
2384 return TLA_NOT_IMPLEMENTED
;