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-2005 OpenVPN Solutions LLC <info@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.
30 #include "config-win32.h"
46 static void add_route (struct route
*r
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
);
47 static void delete_route (const struct route
*r
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
);
48 static bool get_default_gateway (in_addr_t
*ret
);
50 struct route_option_list
*
51 new_route_option_list (struct gc_arena
*a
)
53 struct route_option_list
*ret
;
54 ALLOC_OBJ_CLEAR_GC (ret
, struct route_option_list
, a
);
59 new_route_list (struct gc_arena
*a
)
61 struct route_list
*ret
;
62 ALLOC_OBJ_CLEAR_GC (ret
, struct route_list
, a
);
67 route_string (const struct route
*r
, struct gc_arena
*gc
)
69 struct buffer out
= alloc_buf_gc (256, gc
);
70 buf_printf (&out
, "ROUTE network %s netmask %s gateway %s",
71 print_in_addr_t (r
->network
, 0, gc
),
72 print_in_addr_t (r
->netmask
, 0, gc
),
73 print_in_addr_t (r
->gateway
, 0, gc
)
75 if (r
->metric_defined
)
76 buf_printf (&out
, " metric %d", r
->metric
);
81 is_route_parm_defined (const char *parm
)
85 if (!strcmp (parm
, "default"))
91 setenv_route_addr (struct env_set
*es
, const char *key
, const in_addr_t addr
, int i
)
93 struct gc_arena gc
= gc_new ();
94 struct buffer name
= alloc_buf_gc (256, &gc
);
96 buf_printf (&name
, "route_%s_%d", key
, i
);
98 buf_printf (&name
, "route_%s", key
);
99 setenv_str (es
, BSTR (&name
), print_in_addr_t (addr
, 0, &gc
));
104 get_special_addr (const struct route_special_addr
*spec
,
110 if (!strcmp (string
, "vpn_gateway"))
112 if (spec
->remote_endpoint_defined
)
113 *out
= spec
->remote_endpoint
;
116 msg (M_INFO
, PACKAGE_NAME
" ROUTE: vpn_gateway undefined");
121 else if (!strcmp (string
, "net_gateway"))
123 if (spec
->net_gateway_defined
)
124 *out
= spec
->net_gateway
;
127 msg (M_INFO
, PACKAGE_NAME
" ROUTE: net_gateway undefined -- unable to get default gateway from system");
132 else if (!strcmp (string
, "remote_host"))
134 if (spec
->remote_host_defined
)
135 *out
= spec
->remote_host
;
138 msg (M_INFO
, PACKAGE_NAME
" ROUTE: remote_host undefined");
147 init_route (struct route
*r
,
148 const struct route_option
*ro
,
149 const struct route_special_addr
*spec
)
151 const in_addr_t default_netmask
= ~0;
159 if (!is_route_parm_defined (ro
->network
))
164 if (!get_special_addr (spec
, ro
->network
, &r
->network
, &status
))
166 r
->network
= getaddr (
169 | GETADDR_WARN_ON_SIGNAL
,
181 if (is_route_parm_defined (ro
->netmask
))
183 r
->netmask
= getaddr (
185 | GETADDR_WARN_ON_SIGNAL
,
194 r
->netmask
= default_netmask
;
198 if (is_route_parm_defined (ro
->gateway
))
200 if (!get_special_addr (spec
, ro
->gateway
, &r
->gateway
, &status
))
202 r
->gateway
= getaddr (
205 | GETADDR_WARN_ON_SIGNAL
,
216 if (spec
->remote_endpoint_defined
)
217 r
->gateway
= spec
->remote_endpoint
;
220 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");
227 r
->metric_defined
= false;
229 if (is_route_parm_defined (ro
->metric
))
231 r
->metric
= atoi (ro
->metric
);
234 msg (M_WARN
, PACKAGE_NAME
" ROUTE: route metric for network %s (%s) must be >= 0",
239 r
->metric_defined
= true;
244 r
->metric_defined
= false;
252 msg (M_WARN
, PACKAGE_NAME
" ROUTE: failed to parse/resolve route for host/network: %s",
259 add_route_to_option_list (struct route_option_list
*l
,
265 struct route_option
*ro
;
266 if (l
->n
>= MAX_ROUTES
)
267 msg (M_FATAL
, PACKAGE_NAME
" ROUTE: cannot add more than %d routes",
269 ro
= &l
->routes
[l
->n
];
270 ro
->network
= network
;
271 ro
->netmask
= netmask
;
272 ro
->gateway
= gateway
;
278 clear_route_list (struct route_list
*rl
)
284 init_route_list (struct route_list
*rl
,
285 const struct route_option_list
*opt
,
286 const char *remote_endpoint
,
287 in_addr_t remote_host
,
290 struct gc_arena gc
= gc_new ();
293 clear_route_list (rl
);
297 rl
->spec
.remote_host
= remote_host
;
298 rl
->spec
.remote_host_defined
= true;
301 rl
->spec
.net_gateway_defined
= get_default_gateway (&rl
->spec
.net_gateway
);
302 if (rl
->spec
.net_gateway_defined
)
304 setenv_route_addr (es
, "net_gateway", rl
->spec
.net_gateway
, -1);
305 dmsg (D_ROUTE_DEBUG
, "ROUTE: default_gateway=%s", print_in_addr_t (rl
->spec
.net_gateway
, 0, &gc
));
309 dmsg (D_ROUTE_DEBUG
, "ROUTE: default_gateway=UNDEF");
311 rl
->redirect_default_gateway
= opt
->redirect_default_gateway
;
312 rl
->redirect_local
= opt
->redirect_local
;
313 rl
->redirect_def1
= opt
->redirect_def1
;
315 if (is_route_parm_defined (remote_endpoint
))
317 rl
->spec
.remote_endpoint
= getaddr (
320 | GETADDR_WARN_ON_SIGNAL
,
323 &rl
->spec
.remote_endpoint_defined
,
326 if (rl
->spec
.remote_endpoint_defined
)
328 setenv_route_addr (es
, "vpn_gateway", rl
->spec
.remote_endpoint
, -1);
332 msg (M_WARN
, PACKAGE_NAME
" ROUTE: failed to parse/resolve default gateway: %s",
338 rl
->spec
.remote_endpoint_defined
= false;
340 ASSERT (opt
->n
>= 0 && opt
->n
< MAX_ROUTES
);
342 /* parse the routes from opt to rl */
345 for (i
= 0; i
< opt
->n
; ++i
)
347 if (!init_route (&rl
->routes
[j
],
362 add_route3 (in_addr_t network
,
365 const struct tuntap
*tt
,
367 const struct env_set
*es
)
375 add_route (&r
, tt
, flags
, es
);
379 del_route3 (in_addr_t network
,
382 const struct tuntap
*tt
,
384 const struct env_set
*es
)
392 delete_route (&r
, tt
, flags
, es
);
396 redirect_default_route_to_vpn (struct route_list
*rl
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
)
398 const char err
[] = "NOTE: unable to redirect default gateway --";
400 if (rl
->redirect_default_gateway
)
402 if (!rl
->spec
.remote_endpoint_defined
)
404 msg (M_WARN
, "%s VPN gateway parameter (--route-gateway or --ifconfig) is missing", err
);
406 else if (!rl
->spec
.net_gateway_defined
)
408 msg (M_WARN
, "%s Cannot read current default gateway from system", err
);
410 else if (!rl
->spec
.remote_host_defined
)
412 msg (M_WARN
, "%s Cannot obtain current remote host address", err
);
416 /* route remote host to original default gateway */
417 if (!rl
->redirect_local
)
418 add_route3 (rl
->spec
.remote_host
,
420 rl
->spec
.net_gateway
,
425 if (rl
->redirect_def1
)
427 /* add new default route (1st component) */
428 add_route3 (0x00000000,
430 rl
->spec
.remote_endpoint
,
435 /* add new default route (2nd component) */
436 add_route3 (0x80000000,
438 rl
->spec
.remote_endpoint
,
445 /* delete default route */
448 rl
->spec
.net_gateway
,
453 /* add new default route */
456 rl
->spec
.remote_endpoint
,
462 /* set a flag so we can undo later */
463 rl
->did_redirect_default_gateway
= true;
469 undo_redirect_default_route_to_vpn (struct route_list
*rl
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
)
471 if (rl
->did_redirect_default_gateway
)
473 /* delete remote host route */
474 if (!rl
->redirect_local
)
475 del_route3 (rl
->spec
.remote_host
,
477 rl
->spec
.net_gateway
,
482 if (rl
->redirect_def1
)
484 /* delete default route (1st component) */
485 del_route3 (0x00000000,
487 rl
->spec
.remote_endpoint
,
492 /* delete default route (2nd component) */
493 del_route3 (0x80000000,
495 rl
->spec
.remote_endpoint
,
502 /* delete default route */
505 rl
->spec
.remote_endpoint
,
510 /* restore original default route */
513 rl
->spec
.net_gateway
,
519 rl
->did_redirect_default_gateway
= false;
524 add_routes (struct route_list
*rl
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
)
526 redirect_default_route_to_vpn (rl
, tt
, flags
, es
);
527 if (!rl
->routes_added
)
531 #ifdef ENABLE_MANAGEMENT
532 if (management
&& rl
->n
)
534 management_set_state (management
,
535 OPENVPN_STATE_ADD_ROUTES
,
541 for (i
= 0; i
< rl
->n
; ++i
)
543 if (flags
& ROUTE_DELETE_FIRST
)
544 delete_route (&rl
->routes
[i
], tt
, flags
, es
);
545 add_route (&rl
->routes
[i
], tt
, flags
, es
);
547 rl
->routes_added
= true;
552 delete_routes (struct route_list
*rl
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
)
554 if (rl
->routes_added
)
557 for (i
= rl
->n
- 1; i
>= 0; --i
)
559 const struct route
*r
= &rl
->routes
[i
];
560 delete_route (r
, tt
, flags
, es
);
562 rl
->routes_added
= false;
564 undo_redirect_default_route_to_vpn (rl
, tt
, flags
, es
);
572 show_opt (const char *option
)
581 print_route_option (const struct route_option
*ro
, int level
)
583 msg (level
, " route %s/%s/%s/%s",
584 show_opt (ro
->network
),
585 show_opt (ro
->netmask
),
586 show_opt (ro
->gateway
),
587 show_opt (ro
->metric
));
591 print_route_options (const struct route_option_list
*rol
,
595 if (rol
->redirect_default_gateway
)
596 msg (level
, " [redirect_default_gateway local=%d]",
597 rol
->redirect_local
);
598 for (i
= 0; i
< rol
->n
; ++i
)
599 print_route_option (&rol
->routes
[i
], level
);
605 print_route (const struct route
*r
, int level
)
607 struct gc_arena gc
= gc_new ();
609 msg (level
, "%s", route_string (r
, &gc
));
614 print_routes (const struct route_list
*rl
, int level
)
617 for (i
= 0; i
< rl
->n
; ++i
)
618 print_route (&rl
->routes
[i
], level
);
622 setenv_route (struct env_set
*es
, const struct route
*r
, int i
)
624 struct gc_arena gc
= gc_new ();
627 setenv_route_addr (es
, "network", r
->network
, i
);
628 setenv_route_addr (es
, "netmask", r
->netmask
, i
);
629 setenv_route_addr (es
, "gateway", r
->gateway
, i
);
631 if (r
->metric_defined
)
633 struct buffer name
= alloc_buf_gc (256, &gc
);
634 buf_printf (&name
, "route_metric_%d", i
);
635 setenv_int (es
, BSTR (&name
), r
->metric
);
642 setenv_routes (struct env_set
*es
, const struct route_list
*rl
)
645 for (i
= 0; i
< rl
->n
; ++i
)
646 setenv_route (es
, &rl
->routes
[i
], i
+ 1);
650 add_route (struct route
*r
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
)
663 buf
= alloc_buf_gc (256, &gc
);
665 network
= print_in_addr_t (r
->network
, 0, &gc
);
666 netmask
= print_in_addr_t (r
->netmask
, 0, &gc
);
667 gateway
= print_in_addr_t (r
->gateway
, 0, &gc
);
670 * Filter out routes which are essentially no-ops
672 if (r
->network
== r
->gateway
&& r
->netmask
== 0xFFFFFFFF)
674 msg (M_INFO
, PACKAGE_NAME
" ROUTE: omitted no-op route: %s/%s -> %s",
675 network
, netmask
, gateway
);
679 #if defined(TARGET_LINUX)
680 #ifdef CONFIG_FEATURE_IPROUTE
681 buf_printf (&buf
, IPROUTE_PATH
" route add %s/%d via %s",
683 count_netmask_bits(netmask
),
685 if (r
->metric_defined
)
686 buf_printf (&buf
, " metric %d", r
->metric
);
689 buf_printf (&buf
, ROUTE_PATH
" add -net %s netmask %s gw %s",
693 if (r
->metric_defined
)
694 buf_printf (&buf
, " metric %d", r
->metric
);
695 #endif /*CONFIG_FEATURE_IPROUTE*/
696 msg (D_ROUTE
, "%s", BSTR (&buf
));
697 status
= system_check (BSTR (&buf
), es
, 0, "ERROR: Linux route add command failed");
699 #elif defined (WIN32)
701 buf_printf (&buf
, ROUTE_PATH
" ADD %s MASK %s %s",
705 if (r
->metric_defined
)
706 buf_printf (&buf
, " METRIC %d", r
->metric
);
708 msg (D_ROUTE
, "%s", BSTR (&buf
));
710 if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_IPAPI
)
712 status
= add_route_ipapi (r
, tt
);
713 msg (D_ROUTE
, "Route addition via IPAPI %s", status
? "succeeded" : "failed");
715 else if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_EXE
)
717 netcmd_semaphore_lock ();
718 status
= system_check (BSTR (&buf
), es
, 0, "ERROR: Windows route add command failed");
719 netcmd_semaphore_release ();
726 #elif defined (TARGET_SOLARIS)
728 /* example: route add 192.0.2.32 -netmask 255.255.255.224 somegateway */
730 buf_printf (&buf
, ROUTE_PATH
" add");
733 if (r
->metric_defined
)
734 buf_printf (&buf
, " -rtt %d", r
->metric
);
737 buf_printf (&buf
, " %s -netmask %s %s",
742 msg (D_ROUTE
, "%s", BSTR (&buf
));
743 status
= system_check (BSTR (&buf
), es
, 0, "ERROR: Solaris route add command failed");
745 #elif defined(TARGET_FREEBSD)
747 buf_printf (&buf
, ROUTE_PATH
" add");
750 if (r
->metric_defined
)
751 buf_printf (&buf
, " -rtt %d", r
->metric
);
754 buf_printf (&buf
, " -net %s %s %s",
759 msg (D_ROUTE
, "%s", BSTR (&buf
));
760 status
= system_check (BSTR (&buf
), es
, 0, "ERROR: FreeBSD route add command failed");
762 #elif defined(TARGET_DARWIN)
764 buf_printf (&buf
, ROUTE_PATH
" add");
767 if (r
->metric_defined
)
768 buf_printf (&buf
, " -rtt %d", r
->metric
);
771 buf_printf (&buf
, " -net %s %s %s",
776 msg (D_ROUTE
, "%s", BSTR (&buf
));
777 status
= system_check (BSTR (&buf
), es
, 0, "ERROR: OS X route add command failed");
779 #elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
781 buf_printf (&buf
, ROUTE_PATH
" add");
784 if (r
->metric_defined
)
785 buf_printf (&buf
, " -rtt %d", r
->metric
);
788 buf_printf (&buf
, " -net %s %s -netmask %s",
793 msg (D_ROUTE
, "%s", BSTR (&buf
));
794 status
= system_check (BSTR (&buf
), es
, 0, "ERROR: OpenBSD/NetBSD route add command failed");
797 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");
806 delete_route (const struct route
*r
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
)
819 buf
= alloc_buf_gc (256, &gc
);
820 network
= print_in_addr_t (r
->network
, 0, &gc
);
821 netmask
= print_in_addr_t (r
->netmask
, 0, &gc
);
822 gateway
= print_in_addr_t (r
->gateway
, 0, &gc
);
824 #if defined(TARGET_LINUX)
825 #ifdef CONFIG_FEATURE_IPROUTE
826 buf_printf (&buf
, IPROUTE_PATH
" route del %s/%d",
828 count_netmask_bits(netmask
));
831 buf_printf (&buf
, ROUTE_PATH
" del -net %s netmask %s",
834 #endif /*CONFIG_FEATURE_IPROUTE*/
835 if (r
->metric_defined
)
836 buf_printf (&buf
, " metric %d", r
->metric
);
837 msg (D_ROUTE
, "%s", BSTR (&buf
));
838 system_check (BSTR (&buf
), es
, 0, "ERROR: Linux route delete command failed");
840 #elif defined (WIN32)
842 buf_printf (&buf
, ROUTE_PATH
" DELETE %s MASK %s %s",
847 msg (D_ROUTE
, "%s", BSTR (&buf
));
849 if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_IPAPI
)
851 const bool status
= del_route_ipapi (r
, tt
);
852 msg (D_ROUTE
, "Route deletion via IPAPI %s", status
? "succeeded" : "failed");
854 else if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_EXE
)
856 netcmd_semaphore_lock ();
857 system_check (BSTR (&buf
), es
, 0, "ERROR: Windows route delete command failed");
858 netcmd_semaphore_release ();
865 #elif defined (TARGET_SOLARIS)
867 buf_printf (&buf
, ROUTE_PATH
" delete %s -netmask %s %s",
872 msg (D_ROUTE
, "%s", BSTR (&buf
));
873 system_check (BSTR (&buf
), es
, 0, "ERROR: Solaris route delete command failed");
875 #elif defined(TARGET_FREEBSD)
877 buf_printf (&buf
, ROUTE_PATH
" delete -net %s %s %s",
882 msg (D_ROUTE
, "%s", BSTR (&buf
));
883 system_check (BSTR (&buf
), es
, 0, "ERROR: FreeBSD route delete command failed");
885 #elif defined(TARGET_DARWIN)
887 buf_printf (&buf
, ROUTE_PATH
" delete -net %s %s %s",
892 msg (D_ROUTE
, "%s", BSTR (&buf
));
893 system_check (BSTR (&buf
), es
, 0, "ERROR: OS X route delete command failed");
895 #elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
897 buf_printf (&buf
, ROUTE_PATH
" delete -net %s %s -netmask %s",
902 msg (D_ROUTE
, "%s", BSTR (&buf
));
903 system_check (BSTR (&buf
), es
, 0, "ERROR: OpenBSD/NetBSD route delete command failed");
906 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");
913 * The --redirect-gateway option requires OS-specific code below
914 * to get the current default gateway.
919 static const MIB_IPFORWARDTABLE
*
920 get_windows_routing_table (struct gc_arena
*gc
)
923 PMIB_IPFORWARDTABLE rt
= NULL
;
926 status
= GetIpForwardTable (NULL
, &size
, TRUE
);
927 if (status
== ERROR_INSUFFICIENT_BUFFER
)
929 rt
= (PMIB_IPFORWARDTABLE
) gc_malloc (size
, false, gc
);
930 status
= GetIpForwardTable (rt
, &size
, TRUE
);
931 if (status
!= NO_ERROR
)
933 msg (D_ROUTE
, "NOTE: GetIpForwardTable returned error: %s (code=%u)",
934 strerror_win32 (status
, gc
),
935 (unsigned int)status
);
943 test_route (const IP_ADAPTER_INFO
*adapters
,
944 const in_addr_t gateway
,
948 DWORD i
= adapter_index_of_ip (adapters
, gateway
, &count
);
955 test_route_helper (bool *ret
,
959 const IP_ADAPTER_INFO
*adapters
,
960 const in_addr_t gateway
)
965 c
= test_route (adapters
, gateway
, NULL
);
975 * If we tried to add routes now, would we succeed?
978 test_routes (const struct route_list
*rl
, const struct tuntap
*tt
)
980 struct gc_arena gc
= gc_new ();
981 const IP_ADAPTER_INFO
*adapters
= get_adapter_info_list (&gc
);
986 bool adapter_up
= false;
988 if (is_adapter_up (tt
, adapters
))
996 for (i
= 0; i
< rl
->n
; ++i
)
997 test_route_helper (&ret
, &count
, &good
, &ambig
, adapters
, rl
->routes
[i
].gateway
);
999 if (rl
->redirect_default_gateway
&& rl
->spec
.remote_endpoint_defined
)
1000 test_route_helper (&ret
, &count
, &good
, &ambig
, adapters
, rl
->spec
.remote_endpoint
);
1004 msg (D_ROUTE
, "TEST ROUTES: %d/%d succeeded len=%d ret=%d a=%d u/d=%s",
1010 adapter_up
? "up" : "down");
1017 get_default_gateway (in_addr_t
*gateway
)
1019 struct gc_arena gc
= gc_new ();
1021 const MIB_IPFORWARDTABLE
*routes
= get_windows_routing_table (&gc
);
1022 DWORD lowest_metric
= ~0;
1029 for (i
= 0; i
< routes
->dwNumEntries
; ++i
)
1031 const MIB_IPFORWARDROW
*row
= &routes
->table
[i
];
1032 const in_addr_t net
= ntohl (row
->dwForwardDest
);
1033 const in_addr_t mask
= ntohl (row
->dwForwardMask
);
1034 const in_addr_t gw
= ntohl (row
->dwForwardNextHop
);
1035 const DWORD metric
= row
->dwForwardMetric1
;
1037 msg (D_ROUTE_DEBUG
, "GDG: route[%d] %s %s %s m=%u",
1039 print_in_addr_t ((in_addr_t
) net
, 0, &gc
),
1040 print_in_addr_t ((in_addr_t
) mask
, 0, &gc
),
1041 print_in_addr_t ((in_addr_t
) gw
, 0, &gc
),
1042 (unsigned int)metric
);
1044 if (!net
&& !mask
&& metric
< lowest_metric
)
1047 lowest_metric
= metric
;
1057 dmsg (D_ROUTE_DEBUG
, "GDGR: best=%d lm=%u", best
, (unsigned int)lowest_metric
);
1066 windows_route_find_if_index (const struct route
*r
, const struct tuntap
*tt
)
1068 struct gc_arena gc
= gc_new ();
1071 const IP_ADAPTER_INFO
*adapters
= get_adapter_info_list (&gc
);
1072 const IP_ADAPTER_INFO
*tun_adapter
= get_tun_adapter (tt
, adapters
);
1073 bool on_tun
= false;
1075 /* first test on tun interface */
1076 if (is_ip_in_adapter_subnet (tun_adapter
, r
->gateway
, NULL
))
1078 ret
= tun_adapter
->Index
;
1082 else /* test on other interfaces */
1084 count
= test_route (adapters
, r
->gateway
, &ret
);
1089 msg (M_WARN
, "Warning: route gateway is not reachable on any active network adapters: %s",
1090 print_in_addr_t (r
->gateway
, 0, &gc
));
1095 msg (M_WARN
, "Warning: route gateway is ambiguous: %s (%d matches)",
1096 print_in_addr_t (r
->gateway
, 0, &gc
),
1101 dmsg (D_ROUTE_DEBUG
, "DEBUG: route find if: on_tun=%d count=%d index=%d",
1111 add_route_ipapi (const struct route
*r
, const struct tuntap
*tt
)
1113 struct gc_arena gc
= gc_new ();
1116 const DWORD if_index
= windows_route_find_if_index (r
, tt
);
1120 MIB_IPFORWARDROW fr
;
1122 fr
.dwForwardDest
= htonl (r
->network
);
1123 fr
.dwForwardMask
= htonl (r
->netmask
);
1124 fr
.dwForwardPolicy
= 0;
1125 fr
.dwForwardNextHop
= htonl (r
->gateway
);
1126 fr
.dwForwardIfIndex
= if_index
;
1127 fr
.dwForwardType
= 4; /* the next hop is not the final dest */
1128 fr
.dwForwardProto
= 3; /* PROTO_IP_NETMGMT */
1129 fr
.dwForwardAge
= 0;
1130 fr
.dwForwardNextHopAS
= 0;
1131 fr
.dwForwardMetric1
= r
->metric_defined
? r
->metric
: 1;
1132 fr
.dwForwardMetric2
= ~0;
1133 fr
.dwForwardMetric3
= ~0;
1134 fr
.dwForwardMetric4
= ~0;
1135 fr
.dwForwardMetric5
= ~0;
1137 if ((r
->network
& r
->netmask
) != r
->network
)
1138 msg (M_WARN
, "Warning: address %s is not a network address in relation to netmask %s",
1139 print_in_addr_t (r
->network
, 0, &gc
),
1140 print_in_addr_t (r
->netmask
, 0, &gc
));
1142 status
= CreateIpForwardEntry (&fr
);
1144 if (status
== NO_ERROR
)
1148 /* failed, try a different forward type (--redirect-gateway over RRAS seems to need this) */
1149 fr
.dwForwardType
= 3; /* the next hop is the final dest */
1151 status
= CreateIpForwardEntry (&fr
);
1153 if (status
== NO_ERROR
)
1156 msg (M_WARN
, "ROUTE: route addition failed using CreateIpForwardEntry: %s [if_index=%u]",
1157 strerror_win32 (status
, &gc
),
1158 (unsigned int)if_index
);
1167 del_route_ipapi (const struct route
*r
, const struct tuntap
*tt
)
1169 struct gc_arena gc
= gc_new ();
1172 const DWORD if_index
= windows_route_find_if_index (r
, tt
);
1176 MIB_IPFORWARDROW fr
;
1179 fr
.dwForwardDest
= htonl (r
->network
);
1180 fr
.dwForwardMask
= htonl (r
->netmask
);
1181 fr
.dwForwardPolicy
= 0;
1182 fr
.dwForwardNextHop
= htonl (r
->gateway
);
1183 fr
.dwForwardIfIndex
= if_index
;
1185 status
= DeleteIpForwardEntry (&fr
);
1187 if (status
== NO_ERROR
)
1190 msg (M_WARN
, "ROUTE: route deletion failed using DeleteIpForwardEntry: %s",
1191 strerror_win32 (status
, &gc
));
1199 format_route_entry (const MIB_IPFORWARDROW
*r
, struct gc_arena
*gc
)
1201 struct buffer out
= alloc_buf_gc (256, gc
);
1202 buf_printf (&out
, "%s %s %s p=%d i=%d t=%d pr=%d a=%d h=%d m=%d/%d/%d/%d/%d",
1203 print_in_addr_t (r
->dwForwardDest
, IA_NET_ORDER
, gc
),
1204 print_in_addr_t (r
->dwForwardMask
, IA_NET_ORDER
, gc
),
1205 print_in_addr_t (r
->dwForwardNextHop
, IA_NET_ORDER
, gc
),
1206 (int)r
->dwForwardPolicy
,
1207 (int)r
->dwForwardIfIndex
,
1208 (int)r
->dwForwardType
,
1209 (int)r
->dwForwardProto
,
1210 (int)r
->dwForwardAge
,
1211 (int)r
->dwForwardNextHopAS
,
1212 (int)r
->dwForwardMetric1
,
1213 (int)r
->dwForwardMetric2
,
1214 (int)r
->dwForwardMetric3
,
1215 (int)r
->dwForwardMetric4
,
1216 (int)r
->dwForwardMetric5
);
1221 * Show current routing table
1224 show_routes (int msglev
)
1226 struct gc_arena gc
= gc_new ();
1229 const MIB_IPFORWARDTABLE
*rt
= get_windows_routing_table (&gc
);
1231 msg (msglev
, "SYSTEM ROUTING TABLE");
1234 for (i
= 0; i
< rt
->dwNumEntries
; ++i
)
1236 msg (msglev
, "%s", format_route_entry (&rt
->table
[i
], &gc
));
1242 #elif defined(TARGET_LINUX)
1245 get_default_gateway (in_addr_t
*gateway
)
1247 struct gc_arena gc
= gc_new ();
1249 FILE *fp
= fopen ("/proc/net/route", "r");
1255 unsigned int lowest_metric
= ~0;
1256 in_addr_t best_gw
= 0;
1257 while (fgets (line
, sizeof (line
), fp
) != NULL
)
1261 unsigned int net_x
= 0;
1262 unsigned int mask_x
= 0;
1263 unsigned int gw_x
= 0;
1264 unsigned int metric
= 0;
1265 const int np
= sscanf (line
, "%*s\t%x\t%x\t%*s\t%*s\t%*s\t%d\t%x",
1272 const in_addr_t net
= ntohl (net_x
);
1273 const in_addr_t mask
= ntohl (mask_x
);
1274 const in_addr_t gw
= ntohl (gw_x
);
1276 dmsg (D_ROUTE_DEBUG
, "GDG: route[%d] %s/%s/%s m=%u",
1278 print_in_addr_t ((in_addr_t
) net
, 0, &gc
),
1279 print_in_addr_t ((in_addr_t
) mask
, 0, &gc
),
1280 print_in_addr_t ((in_addr_t
) gw
, 0, &gc
),
1283 if (!net
&& !mask
&& metric
< lowest_metric
)
1286 lowest_metric
= metric
;
1301 dmsg (D_ROUTE_DEBUG
, "GDG: best=%s[%d] lm=%u",
1302 print_in_addr_t ((in_addr_t
) best_gw
, 0, &gc
),
1304 (unsigned int)lowest_metric
);
1311 #elif defined(TARGET_FREEBSD)
1313 #include <sys/types.h>
1314 #include <sys/socket.h>
1315 #include <netinet/in.h>
1317 /* all of this is taken from <net/route.h> in FreeBSD */
1319 #define RTA_GATEWAY 0x2
1320 #define RTA_NETMASK 0x4
1323 #define RTM_VERSION 5
1326 #define RTF_GATEWAY 0x2
1329 * These numbers are used by reliable protocols for determining
1330 * retransmission behavior and are included in the routing structure.
1333 u_long rmx_locks
; /* Kernel must leave these values alone */
1334 u_long rmx_mtu
; /* MTU for this path */
1335 u_long rmx_hopcount
; /* max hops expected */
1336 u_long rmx_expire
; /* lifetime for route, e.g. redirect */
1337 u_long rmx_recvpipe
; /* inbound delay-bandwidth product */
1338 u_long rmx_sendpipe
; /* outbound delay-bandwidth product */
1339 u_long rmx_ssthresh
; /* outbound gateway buffer limit */
1340 u_long rmx_rtt
; /* estimated round trip time */
1341 u_long rmx_rttvar
; /* estimated rtt variance */
1342 u_long rmx_pksent
; /* packets sent using this route */
1343 u_long rmx_filler
[4]; /* will be used for T/TCP later */
1347 * Structures for routing messages.
1350 u_short rtm_msglen
; /* to skip over non-understood messages */
1351 u_char rtm_version
; /* future binary compatibility */
1352 u_char rtm_type
; /* message type */
1353 u_short rtm_index
; /* index for associated ifp */
1354 int rtm_flags
; /* flags, incl. kern & message, e.g. DONE */
1355 int rtm_addrs
; /* bitmask identifying sockaddrs in msg */
1356 pid_t rtm_pid
; /* identify sender */
1357 int rtm_seq
; /* for sender to identify action */
1358 int rtm_errno
; /* why failed */
1359 int rtm_use
; /* from rtentry */
1360 u_long rtm_inits
; /* which metrics we are initializing */
1361 struct rt_metrics rtm_rmx
; /* metrics themselves */
1365 struct rt_msghdr m_rtm
;
1369 #define ROUNDUP(a) \
1370 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
1373 get_default_gateway (in_addr_t
*ret
)
1375 struct gc_arena gc
= gc_new ();
1376 int s
, seq
, l
, pid
, rtm_addrs
, i
;
1377 struct sockaddr so_dst
, so_mask
;
1378 char *cp
= m_rtmsg
.m_space
;
1379 struct sockaddr
*gate
= NULL
, *sa
;
1380 struct rt_msghdr
*rtm_aux
;
1382 #define NEXTADDR(w, u) \
1383 if (rtm_addrs & (w)) {\
1384 l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
1387 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
1389 #define rtm m_rtmsg.m_rtm
1393 rtm_addrs
= RTA_DST
| RTA_NETMASK
;
1395 bzero(&so_dst
, sizeof(so_dst
));
1396 bzero(&so_mask
, sizeof(so_mask
));
1397 bzero(&rtm
, sizeof(struct rt_msghdr
));
1399 rtm
.rtm_type
= RTM_GET
;
1400 rtm
.rtm_flags
= RTF_UP
| RTF_GATEWAY
;
1401 rtm
.rtm_version
= RTM_VERSION
;
1402 rtm
.rtm_seq
= ++seq
;
1403 rtm
.rtm_addrs
= rtm_addrs
;
1405 so_dst
.sa_family
= AF_INET
;
1406 so_dst
.sa_len
= sizeof(struct sockaddr_in
);
1407 so_mask
.sa_family
= AF_INET
;
1408 so_mask
.sa_len
= sizeof(struct sockaddr_in
);
1410 NEXTADDR(RTA_DST
, so_dst
);
1411 NEXTADDR(RTA_NETMASK
, so_mask
);
1413 rtm
.rtm_msglen
= l
= cp
- (char *)&m_rtmsg
;
1415 s
= socket(PF_ROUTE
, SOCK_RAW
, 0);
1417 if (write(s
, (char *)&m_rtmsg
, l
) < 0)
1419 warn("writing to routing socket");
1426 l
= read(s
, (char *)&m_rtmsg
, sizeof(m_rtmsg
));
1427 } while (l
> 0 && (rtm
.rtm_seq
!= seq
|| rtm
.rtm_pid
!= pid
));
1433 cp
= ((char *)(rtm_aux
+ 1));
1434 if (rtm_aux
->rtm_addrs
) {
1435 for (i
= 1; i
; i
<<= 1)
1436 if (i
& rtm_aux
->rtm_addrs
) {
1437 sa
= (struct sockaddr
*)cp
;
1438 if (i
== RTA_GATEWAY
)
1452 *ret
= ntohl(((struct sockaddr_in
*)gate
)->sin_addr
.s_addr
);
1454 msg (M_INFO
, "gw %s",
1455 print_in_addr_t ((in_addr_t
) *ret
, 0, &gc
));
1468 #elif defined(TARGET_DARWIN)
1470 #include <sys/types.h>
1471 #include <sys/socket.h>
1472 #include <netinet/in.h>
1474 /* all of this is taken from <net/route.h> in Darwin */
1476 #define RTA_GATEWAY 0x2
1477 #define RTA_NETMASK 0x4
1480 #define RTM_VERSION 5
1483 #define RTF_GATEWAY 0x2
1486 * These numbers are used by reliable protocols for determining
1487 * retransmission behavior and are included in the routing structure.
1490 u_long rmx_locks
; /* Kernel must leave these values alone */
1491 u_long rmx_mtu
; /* MTU for this path */
1492 u_long rmx_hopcount
; /* max hops expected */
1493 u_long rmx_expire
; /* lifetime for route, e.g. redirect */
1494 u_long rmx_recvpipe
; /* inbound delay-bandwidth product */
1495 u_long rmx_sendpipe
; /* outbound delay-bandwidth product */
1496 u_long rmx_ssthresh
; /* outbound gateway buffer limit */
1497 u_long rmx_rtt
; /* estimated round trip time */
1498 u_long rmx_rttvar
; /* estimated rtt variance */
1499 u_long rmx_pksent
; /* packets sent using this route */
1500 u_long rmx_filler
[4]; /* will be used for T/TCP later */
1504 * Structures for routing messages.
1507 u_short rtm_msglen
; /* to skip over non-understood messages */
1508 u_char rtm_version
; /* future binary compatibility */
1509 u_char rtm_type
; /* message type */
1510 u_short rtm_index
; /* index for associated ifp */
1511 int rtm_flags
; /* flags, incl. kern & message, e.g. DONE */
1512 int rtm_addrs
; /* bitmask identifying sockaddrs in msg */
1513 pid_t rtm_pid
; /* identify sender */
1514 int rtm_seq
; /* for sender to identify action */
1515 int rtm_errno
; /* why failed */
1516 int rtm_use
; /* from rtentry */
1517 u_long rtm_inits
; /* which metrics we are initializing */
1518 struct rt_metrics rtm_rmx
; /* metrics themselves */
1522 struct rt_msghdr m_rtm
;
1526 #define ROUNDUP(a) \
1527 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
1530 get_default_gateway (in_addr_t
*ret
)
1532 struct gc_arena gc
= gc_new ();
1533 int s
, seq
, l
, pid
, rtm_addrs
, i
;
1534 struct sockaddr so_dst
, so_mask
;
1535 char *cp
= m_rtmsg
.m_space
;
1536 struct sockaddr
*gate
= NULL
, *sa
;
1537 struct rt_msghdr
*rtm_aux
;
1539 #define NEXTADDR(w, u) \
1540 if (rtm_addrs & (w)) {\
1541 l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
1544 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
1546 #define rtm m_rtmsg.m_rtm
1550 rtm_addrs
= RTA_DST
| RTA_NETMASK
;
1552 bzero(&so_dst
, sizeof(so_dst
));
1553 bzero(&so_mask
, sizeof(so_mask
));
1554 bzero(&rtm
, sizeof(struct rt_msghdr
));
1556 rtm
.rtm_type
= RTM_GET
;
1557 rtm
.rtm_flags
= RTF_UP
| RTF_GATEWAY
;
1558 rtm
.rtm_version
= RTM_VERSION
;
1559 rtm
.rtm_seq
= ++seq
;
1560 rtm
.rtm_addrs
= rtm_addrs
;
1562 so_dst
.sa_family
= AF_INET
;
1563 so_dst
.sa_len
= sizeof(struct sockaddr_in
);
1564 so_mask
.sa_family
= AF_INET
;
1565 so_mask
.sa_len
= sizeof(struct sockaddr_in
);
1567 NEXTADDR(RTA_DST
, so_dst
);
1568 NEXTADDR(RTA_NETMASK
, so_mask
);
1570 rtm
.rtm_msglen
= l
= cp
- (char *)&m_rtmsg
;
1572 s
= socket(PF_ROUTE
, SOCK_RAW
, 0);
1574 if (write(s
, (char *)&m_rtmsg
, l
) < 0)
1576 msg (M_WARN
, "ROUTE: problem writing to routing socket");
1583 l
= read(s
, (char *)&m_rtmsg
, sizeof(m_rtmsg
));
1584 } while (l
> 0 && (rtm
.rtm_seq
!= seq
|| rtm
.rtm_pid
!= pid
));
1590 cp
= ((char *)(rtm_aux
+ 1));
1591 if (rtm_aux
->rtm_addrs
) {
1592 for (i
= 1; i
; i
<<= 1)
1593 if (i
& rtm_aux
->rtm_addrs
) {
1594 sa
= (struct sockaddr
*)cp
;
1595 if (i
== RTA_GATEWAY
)
1609 *ret
= ntohl(((struct sockaddr_in
*)gate
)->sin_addr
.s_addr
);
1611 msg (M_INFO
, "gw %s",
1612 print_in_addr_t ((in_addr_t
) *ret
, 0, &gc
));
1625 #elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1627 #include <sys/types.h>
1628 #include <sys/socket.h>
1629 #include <netinet/in.h>
1631 /* all of this is taken from <net/route.h> in OpenBSD 3.6 */
1632 #define RTA_DST 0x1 /* destination sockaddr present */
1633 #define RTA_GATEWAY 0x2 /* gateway sockaddr present */
1634 #define RTA_NETMASK 0x4 /* netmask sockaddr present */
1636 #define RTM_GET 0x4 /* Report Metrics */
1638 #define RTM_VERSION 3 /* Up the ante and ignore older versions */
1640 #define RTF_UP 0x1 /* route usable */
1641 #define RTF_GATEWAY 0x2 /* destination is a gateway */
1644 * Huge version for userland compatibility.
1647 u_long rmx_locks
; /* Kernel must leave these values alone */
1648 u_long rmx_mtu
; /* MTU for this path */
1649 u_long rmx_hopcount
; /* max hops expected */
1650 u_long rmx_expire
; /* lifetime for route, e.g. redirect */
1651 u_long rmx_recvpipe
; /* inbound delay-bandwidth product */
1652 u_long rmx_sendpipe
; /* outbound delay-bandwidth product */
1653 u_long rmx_ssthresh
; /* outbound gateway buffer limit */
1654 u_long rmx_rtt
; /* estimated round trip time */
1655 u_long rmx_rttvar
; /* estimated rtt variance */
1656 u_long rmx_pksent
; /* packets sent using this route */
1660 * Structures for routing messages.
1663 u_short rtm_msglen
; /* to skip over non-understood messages */
1664 u_char rtm_version
; /* future binary compatibility */
1665 u_char rtm_type
; /* message type */
1666 u_short rtm_index
; /* index for associated ifp */
1667 int rtm_flags
; /* flags, incl. kern & message, e.g. DONE */
1668 int rtm_addrs
; /* bitmask identifying sockaddrs in msg */
1669 pid_t rtm_pid
; /* identify sender */
1670 int rtm_seq
; /* for sender to identify action */
1671 int rtm_errno
; /* why failed */
1672 int rtm_use
; /* from rtentry */
1673 u_long rtm_inits
; /* which metrics we are initializing */
1674 struct rt_metrics rtm_rmx
; /* metrics themselves */
1678 struct rt_msghdr m_rtm
;
1682 #define ROUNDUP(a) \
1683 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
1686 get_default_gateway (in_addr_t
*ret
)
1688 struct gc_arena gc
= gc_new ();
1689 int s
, seq
, l
, rtm_addrs
, i
;
1691 struct sockaddr so_dst
, so_mask
;
1692 char *cp
= m_rtmsg
.m_space
;
1693 struct sockaddr
*gate
= NULL
, *sa
;
1694 struct rt_msghdr
*rtm_aux
;
1696 #define NEXTADDR(w, u) \
1697 if (rtm_addrs & (w)) {\
1698 l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
1701 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
1703 #define rtm m_rtmsg.m_rtm
1707 rtm_addrs
= RTA_DST
| RTA_NETMASK
;
1709 bzero(&so_dst
, sizeof(so_dst
));
1710 bzero(&so_mask
, sizeof(so_mask
));
1711 bzero(&rtm
, sizeof(struct rt_msghdr
));
1713 rtm
.rtm_type
= RTM_GET
;
1714 rtm
.rtm_flags
= RTF_UP
| RTF_GATEWAY
;
1715 rtm
.rtm_version
= RTM_VERSION
;
1716 rtm
.rtm_seq
= ++seq
;
1717 rtm
.rtm_addrs
= rtm_addrs
;
1719 so_dst
.sa_family
= AF_INET
;
1720 so_dst
.sa_len
= sizeof(struct sockaddr_in
);
1721 so_mask
.sa_family
= AF_INET
;
1722 so_mask
.sa_len
= sizeof(struct sockaddr_in
);
1724 NEXTADDR(RTA_DST
, so_dst
);
1725 NEXTADDR(RTA_NETMASK
, so_mask
);
1727 rtm
.rtm_msglen
= l
= cp
- (char *)&m_rtmsg
;
1729 s
= socket(PF_ROUTE
, SOCK_RAW
, 0);
1731 if (write(s
, (char *)&m_rtmsg
, l
) < 0)
1733 warn("writing to routing socket");
1740 l
= read(s
, (char *)&m_rtmsg
, sizeof(m_rtmsg
));
1741 } while (l
> 0 && (rtm
.rtm_seq
!= seq
|| rtm
.rtm_pid
!= pid
));
1747 cp
= ((char *)(rtm_aux
+ 1));
1748 if (rtm_aux
->rtm_addrs
) {
1749 for (i
= 1; i
; i
<<= 1)
1750 if (i
& rtm_aux
->rtm_addrs
) {
1751 sa
= (struct sockaddr
*)cp
;
1752 if (i
== RTA_GATEWAY
)
1766 *ret
= ntohl(((struct sockaddr_in
*)gate
)->sin_addr
.s_addr
);
1768 msg (M_INFO
, "gw %s",
1769 print_in_addr_t ((in_addr_t
) *ret
, 0, &gc
));
1785 get_default_gateway (in_addr_t
*ret
)
1793 netmask_to_netbits (const in_addr_t network
, const in_addr_t netmask
, int *netbits
)
1796 const int addrlen
= sizeof (in_addr_t
) * 8;
1798 if ((network
& netmask
) == network
)
1800 for (i
= 0; i
<= addrlen
; ++i
)
1802 in_addr_t mask
= netbits_to_netmask (i
);
1803 if (mask
== netmask
)