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-2025 OpenVPN 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 along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 * Support routines for adding/deleting network routes.
39 #include "run_command.h"
44 #include "networking.h"
49 #if defined(TARGET_LINUX) || defined(TARGET_ANDROID)
50 #include <linux/rtnetlink.h> /* RTM_GETROUTE etc. */
53 #if defined(TARGET_NETBSD)
54 #include <net/route.h> /* RT_ROUNDUP(), RT_ADVANCE() */
58 #include "openvpn-msg.h"
60 #define METRIC_NOT_USED ((DWORD)-1)
61 static int add_route_service(const struct route_ipv4
*, const struct tuntap
*);
63 static bool del_route_service(const struct route_ipv4
*, const struct tuntap
*);
65 static int add_route_ipv6_service(const struct route_ipv6
*, const struct tuntap
*);
67 static bool del_route_ipv6_service(const struct route_ipv6
*, const struct tuntap
*);
69 static int route_ipv6_ipapi(bool add
, const struct route_ipv6
*, const struct tuntap
*);
71 static int add_route_ipapi(const struct route_ipv4
*r
, const struct tuntap
*tt
, DWORD adapter_index
);
73 static bool del_route_ipapi(const struct route_ipv4
*r
, const struct tuntap
*tt
);
78 static void delete_route(struct route_ipv4
*r
, const struct tuntap
*tt
, unsigned int flags
,
79 const struct route_gateway_info
*rgi
, const struct env_set
*es
,
80 openvpn_net_ctx_t
*ctx
);
82 static void get_bypass_addresses(struct route_bypass
*rb
, const unsigned int flags
);
87 print_bypass_addresses(const struct route_bypass
*rb
)
89 struct gc_arena gc
= gc_new();
91 for (i
= 0; i
< rb
->n_bypass
; ++i
)
93 msg(D_ROUTE
, "ROUTE: bypass_host_route[%d]=%s",
95 print_in_addr_t(rb
->bypass
[i
], 0, &gc
));
102 /* Route addition return status codes */
103 #define RTA_ERROR 0 /* route addition failed */
104 #define RTA_SUCCESS 1 /* route addition succeeded */
105 #define RTA_EEXIST 2 /* route not added as it already exists */
108 add_bypass_address(struct route_bypass
*rb
, const in_addr_t a
)
111 for (i
= 0; i
< rb
->n_bypass
; ++i
)
113 if (a
== rb
->bypass
[i
]) /* avoid duplicates */
118 if (rb
->n_bypass
< N_ROUTE_BYPASS
)
120 rb
->bypass
[rb
->n_bypass
++] = a
;
129 struct route_option_list
*
130 new_route_option_list(struct gc_arena
*a
)
132 struct route_option_list
*ret
;
133 ALLOC_OBJ_CLEAR_GC(ret
, struct route_option_list
, a
);
138 struct route_ipv6_option_list
*
139 new_route_ipv6_option_list(struct gc_arena
*a
)
141 struct route_ipv6_option_list
*ret
;
142 ALLOC_OBJ_CLEAR_GC(ret
, struct route_ipv6_option_list
, a
);
148 * NOTE: structs are cloned/copied shallow by design.
149 * The routes list from src will stay intact since it is allocated using
150 * the options->gc. The cloned/copied lists will share this common tail
151 * to avoid copying the data around between pulls. Pulled routes use
152 * the c2->gc so they get freed immediately after a reconnect.
154 struct route_option_list
*
155 clone_route_option_list(const struct route_option_list
*src
, struct gc_arena
*a
)
157 struct route_option_list
*ret
;
158 ALLOC_OBJ_GC(ret
, struct route_option_list
, a
);
163 struct route_ipv6_option_list
*
164 clone_route_ipv6_option_list(const struct route_ipv6_option_list
*src
, struct gc_arena
*a
)
166 struct route_ipv6_option_list
*ret
;
167 ALLOC_OBJ_GC(ret
, struct route_ipv6_option_list
, a
);
173 copy_route_option_list(struct route_option_list
*dest
, const struct route_option_list
*src
, struct gc_arena
*a
)
180 copy_route_ipv6_option_list(struct route_ipv6_option_list
*dest
,
181 const struct route_ipv6_option_list
*src
,
189 route_string(const struct route_ipv4
*r
, struct gc_arena
*gc
)
191 struct buffer out
= alloc_buf_gc(256, gc
);
192 buf_printf(&out
, "ROUTE network %s netmask %s gateway %s",
193 print_in_addr_t(r
->network
, 0, gc
),
194 print_in_addr_t(r
->netmask
, 0, gc
),
195 print_in_addr_t(r
->gateway
, 0, gc
)
197 if (r
->flags
& RT_METRIC_DEFINED
)
199 buf_printf(&out
, " metric %d", r
->metric
);
205 is_route_parm_defined(const char *parm
)
211 if (!strcmp(parm
, "default"))
219 setenv_route_addr(struct env_set
*es
, const char *key
, const in_addr_t addr
, int i
)
221 struct gc_arena gc
= gc_new();
222 struct buffer name
= alloc_buf_gc(256, &gc
);
225 buf_printf(&name
, "route_%s_%d", key
, i
);
229 buf_printf(&name
, "route_%s", key
);
231 setenv_str(es
, BSTR(&name
), print_in_addr_t(addr
, 0, &gc
));
236 get_special_addr(const struct route_list
*rl
,
245 if (!strcmp(string
, "vpn_gateway"))
249 if (rl
->spec
.flags
& RTSA_REMOTE_ENDPOINT
)
251 *out
= rl
->spec
.remote_endpoint
;
255 msg(M_INFO
, PACKAGE_NAME
" ROUTE: vpn_gateway undefined");
264 else if (!strcmp(string
, "net_gateway"))
268 if (rl
->rgi
.flags
& RGI_ADDR_DEFINED
)
270 *out
= rl
->rgi
.gateway
.addr
;
274 msg(M_INFO
, PACKAGE_NAME
" ROUTE: net_gateway undefined -- unable to get default gateway from system");
283 else if (!strcmp(string
, "remote_host"))
287 if (rl
->spec
.flags
& RTSA_REMOTE_HOST
)
289 *out
= rl
->spec
.remote_host
;
293 msg(M_INFO
, PACKAGE_NAME
" ROUTE: remote_host undefined");
306 is_special_addr(const char *addr_str
)
310 return get_special_addr(NULL
, addr_str
, NULL
, NULL
);
319 init_route(struct route_ipv4
*r
,
320 struct addrinfo
**network_list
,
321 const struct route_option
*ro
,
322 const struct route_list
*rl
)
324 const in_addr_t default_netmask
= IPV4_NETMASK_HOST
;
327 struct in_addr special
= {0};
333 if (!is_route_parm_defined(ro
->network
))
338 /* get_special_addr replaces specialaddr with a special ip addr
339 * like gw. getaddrinfo is called to convert a a addrinfo struct */
341 if (get_special_addr(rl
, ro
->network
, (in_addr_t
*) &special
.s_addr
, &status
))
347 special
.s_addr
= htonl(special
.s_addr
);
348 char buf
[INET_ADDRSTRLEN
];
349 inet_ntop(AF_INET
, &special
, buf
, sizeof(buf
));
350 ret
= openvpn_getaddrinfo(0, buf
, NULL
, 0, NULL
,
351 AF_INET
, network_list
);
355 ret
= openvpn_getaddrinfo(GETADDR_RESOLVE
| GETADDR_WARN_ON_SIGNAL
,
356 ro
->network
, NULL
, 0, NULL
, AF_INET
, network_list
);
368 if (is_route_parm_defined(ro
->netmask
))
370 r
->netmask
= getaddr(
372 | GETADDR_WARN_ON_SIGNAL
,
384 r
->netmask
= default_netmask
;
389 if (is_route_parm_defined(ro
->gateway
))
391 if (!get_special_addr(rl
, ro
->gateway
, &r
->gateway
, &status
))
393 r
->gateway
= getaddr(
396 | GETADDR_WARN_ON_SIGNAL
,
409 if (rl
->spec
.flags
& RTSA_REMOTE_ENDPOINT
)
411 r
->gateway
= rl
->spec
.remote_endpoint
;
415 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");
423 if (is_route_parm_defined(ro
->metric
))
425 r
->metric
= atoi(ro
->metric
);
428 msg(M_WARN
, PACKAGE_NAME
" ROUTE: route metric for network %s (%s) must be >= 0",
433 r
->flags
|= RT_METRIC_DEFINED
;
435 else if (rl
->spec
.flags
& RTSA_DEFAULT_METRIC
)
437 r
->metric
= rl
->spec
.default_metric
;
438 r
->flags
|= RT_METRIC_DEFINED
;
441 r
->flags
|= RT_DEFINED
;
443 /* routing table id */
444 r
->table_id
= ro
->table_id
;
449 msg(M_WARN
, PACKAGE_NAME
" ROUTE: failed to parse/resolve route for host/network: %s",
455 init_route_ipv6(struct route_ipv6
*r6
,
456 const struct route_ipv6_option
*r6o
,
457 const struct route_ipv6_list
*rl6
)
461 if (!get_ipv6_addr( r6o
->prefix
, &r6
->network
, &r6
->netbits
, M_WARN
))
467 if (is_route_parm_defined(r6o
->gateway
))
469 if (inet_pton( AF_INET6
, r6o
->gateway
, &r6
->gateway
) != 1)
471 msg( M_WARN
, PACKAGE_NAME
"ROUTE6: cannot parse gateway spec '%s'", r6o
->gateway
);
474 else if (rl6
->spec_flags
& RTSA_REMOTE_ENDPOINT
)
476 r6
->gateway
= rl6
->remote_endpoint_ipv6
;
482 if (is_route_parm_defined(r6o
->metric
))
484 r6
->metric
= atoi(r6o
->metric
);
487 msg(M_WARN
, PACKAGE_NAME
" ROUTE: route metric for network %s (%s) must be >= 0",
492 r6
->flags
|= RT_METRIC_DEFINED
;
494 else if (rl6
->spec_flags
& RTSA_DEFAULT_METRIC
)
496 r6
->metric
= rl6
->default_metric
;
497 r6
->flags
|= RT_METRIC_DEFINED
;
500 r6
->flags
|= RT_DEFINED
;
502 /* routing table id */
503 r6
->table_id
= r6o
->table_id
;
508 msg(M_WARN
, PACKAGE_NAME
" ROUTE: failed to parse/resolve route for host/network: %s",
514 add_route_to_option_list(struct route_option_list
*l
,
521 struct route_option
*ro
;
522 ALLOC_OBJ_GC(ro
, struct route_option
, l
->gc
);
523 ro
->network
= network
;
524 ro
->netmask
= netmask
;
525 ro
->gateway
= gateway
;
527 ro
->table_id
= table_id
;
528 ro
->next
= l
->routes
;
534 add_route_ipv6_to_option_list(struct route_ipv6_option_list
*l
,
540 struct route_ipv6_option
*ro
;
541 ALLOC_OBJ_GC(ro
, struct route_ipv6_option
, l
->gc
);
543 ro
->gateway
= gateway
;
545 ro
->table_id
= table_id
;
546 ro
->next
= l
->routes_ipv6
;
551 clear_route_list(struct route_list
*rl
)
558 clear_route_ipv6_list(struct route_ipv6_list
*rl6
)
565 route_list_add_vpn_gateway(struct route_list
*rl
,
567 const in_addr_t addr
)
570 rl
->spec
.remote_endpoint
= addr
;
571 rl
->spec
.flags
|= RTSA_REMOTE_ENDPOINT
;
572 setenv_route_addr(es
, "vpn_gateway", rl
->spec
.remote_endpoint
, -1);
576 add_block_local_item(struct route_list
*rl
,
577 const struct route_gateway_address
*gateway
,
580 if (rl
->rgi
.gateway
.netmask
< 0xFFFFFFFF)
582 struct route_ipv4
*r1
, *r2
;
585 ALLOC_OBJ_GC(r1
, struct route_ipv4
, &rl
->gc
);
586 ALLOC_OBJ_GC(r2
, struct route_ipv4
, &rl
->gc
);
588 /* split a route into two smaller blocking routes, and direct them to target */
589 l2
= ((~gateway
->netmask
)+1)>>1;
590 r1
->flags
= RT_DEFINED
;
591 r1
->gateway
= target
;
592 r1
->network
= gateway
->addr
& gateway
->netmask
;
593 r1
->netmask
= ~(l2
-1);
594 r1
->next
= rl
->routes
;
599 r2
->next
= rl
->routes
;
605 add_block_local_routes(struct route_list
*rl
)
607 #ifndef TARGET_ANDROID
608 /* add bypass for gateway addr */
609 add_bypass_address(&rl
->spec
.bypass
, rl
->rgi
.gateway
.addr
);
612 /* block access to local subnet */
613 add_block_local_item(rl
, &rl
->rgi
.gateway
, rl
->spec
.remote_endpoint
);
615 /* process additional subnets on gateway interface */
616 for (size_t i
= 0; i
< rl
->rgi
.n_addrs
; ++i
)
618 const struct route_gateway_address
*gwa
= &rl
->rgi
.addrs
[i
];
619 /* omit the add/subnet in &rl->rgi which we processed above */
620 if (!((rl
->rgi
.gateway
.addr
& rl
->rgi
.gateway
.netmask
) == (gwa
->addr
& gwa
->netmask
)
621 && rl
->rgi
.gateway
.netmask
== gwa
->netmask
))
623 add_block_local_item(rl
, gwa
, rl
->spec
.remote_endpoint
);
629 block_local_needed(const struct route_list
*rl
)
631 const int rgi_needed
= (RGI_ADDR_DEFINED
|RGI_NETMASK_DEFINED
);
632 return (rl
->flags
& RG_BLOCK_LOCAL
)
633 && (rl
->rgi
.flags
& rgi_needed
) == rgi_needed
634 && (rl
->spec
.flags
& RTSA_REMOTE_ENDPOINT
)
635 && rl
->spec
.remote_host_local
!= TLA_LOCAL
;
639 init_route_list(struct route_list
*rl
,
640 const struct route_option_list
*opt
,
641 const char *remote_endpoint
,
643 in_addr_t remote_host
,
645 openvpn_net_ctx_t
*ctx
)
647 struct gc_arena gc
= gc_new();
650 clear_route_list(rl
);
652 rl
->flags
= opt
->flags
;
654 if (remote_host
!= IPV4_INVALID_ADDR
)
656 rl
->spec
.remote_host
= remote_host
;
657 rl
->spec
.flags
|= RTSA_REMOTE_HOST
;
662 rl
->spec
.default_metric
= default_metric
;
663 rl
->spec
.flags
|= RTSA_DEFAULT_METRIC
;
666 get_default_gateway(&rl
->rgi
, remote_host
!= IPV4_INVALID_ADDR
? remote_host
: INADDR_ANY
, ctx
);
667 if (rl
->rgi
.flags
& RGI_ADDR_DEFINED
)
669 setenv_route_addr(es
, "net_gateway", rl
->rgi
.gateway
.addr
, -1);
670 #if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
671 print_default_gateway(D_ROUTE
, &rl
->rgi
, NULL
);
676 dmsg(D_ROUTE
, "ROUTE: default_gateway=UNDEF");
679 if (rl
->spec
.flags
& RTSA_REMOTE_HOST
)
681 rl
->spec
.remote_host_local
= test_local_addr(remote_host
, &rl
->rgi
);
684 if (is_route_parm_defined(remote_endpoint
))
686 bool defined
= false;
687 rl
->spec
.remote_endpoint
= getaddr(
690 | GETADDR_WARN_ON_SIGNAL
,
698 setenv_route_addr(es
, "vpn_gateway", rl
->spec
.remote_endpoint
, -1);
699 rl
->spec
.flags
|= RTSA_REMOTE_ENDPOINT
;
703 msg(M_WARN
, PACKAGE_NAME
" ROUTE: failed to parse/resolve default gateway: %s",
709 if (rl
->flags
& RG_ENABLE
)
711 if (block_local_needed(rl
))
713 add_block_local_routes(rl
);
715 get_bypass_addresses(&rl
->spec
.bypass
, rl
->flags
);
717 print_bypass_addresses(&rl
->spec
.bypass
);
721 /* parse the routes from opt to rl */
723 struct route_option
*ro
;
724 for (ro
= opt
->routes
; ro
; ro
= ro
->next
)
726 struct addrinfo
*netlist
= NULL
;
729 if (!init_route(&r
, &netlist
, ro
, rl
))
735 struct addrinfo
*curele
;
736 for (curele
= netlist
; curele
; curele
= curele
->ai_next
)
738 struct route_ipv4
*new;
739 ALLOC_OBJ_GC(new, struct route_ipv4
, &rl
->gc
);
741 new->network
= ntohl(((struct sockaddr_in
*)curele
->ai_addr
)->sin_addr
.s_addr
);
742 new->next
= rl
->routes
;
748 gc_addspecial(netlist
, &gc_freeaddrinfo_callback
, &gc
);
757 /* check whether an IPv6 host address is covered by a given route_ipv6
758 * (not the most beautiful implementation in the world, but portable and
762 route_ipv6_match_host( const struct route_ipv6
*r6
,
763 const struct in6_addr
*host
)
765 unsigned int bits
= r6
->netbits
;
774 for (i
= 0; bits
>= 8; i
++, bits
-= 8)
776 if (r6
->network
.s6_addr
[i
] != host
->s6_addr
[i
])
787 mask
= 0xff << (8-bits
);
789 if ( (r6
->network
.s6_addr
[i
] & mask
) == (host
->s6_addr
[i
] & mask
))
798 init_route_ipv6_list(struct route_ipv6_list
*rl6
,
799 const struct route_ipv6_option_list
*opt6
,
800 const char *remote_endpoint
,
802 const struct in6_addr
*remote_host_ipv6
,
804 openvpn_net_ctx_t
*ctx
)
806 struct gc_arena gc
= gc_new();
808 bool need_remote_ipv6_route
;
810 clear_route_ipv6_list(rl6
);
812 rl6
->flags
= opt6
->flags
;
814 if (remote_host_ipv6
)
816 rl6
->remote_host_ipv6
= *remote_host_ipv6
;
817 rl6
->spec_flags
|= RTSA_REMOTE_HOST
;
820 if (default_metric
>= 0)
822 rl6
->default_metric
= default_metric
;
823 rl6
->spec_flags
|= RTSA_DEFAULT_METRIC
;
826 msg(D_ROUTE
, "GDG6: remote_host_ipv6=%s",
827 remote_host_ipv6
? print_in6_addr(*remote_host_ipv6
, 0, &gc
) : "n/a" );
829 get_default_gateway_ipv6(&rl6
->rgi6
, remote_host_ipv6
, ctx
);
830 if (rl6
->rgi6
.flags
& RGI_ADDR_DEFINED
)
832 setenv_str(es
, "net_gateway_ipv6", print_in6_addr(rl6
->rgi6
.gateway
.addr_ipv6
, 0, &gc
));
833 #if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
834 print_default_gateway(D_ROUTE
, NULL
, &rl6
->rgi6
);
839 dmsg(D_ROUTE
, "ROUTE6: default_gateway=UNDEF");
842 if (is_route_parm_defined( remote_endpoint
))
844 if (inet_pton( AF_INET6
, remote_endpoint
,
845 &rl6
->remote_endpoint_ipv6
) == 1)
847 rl6
->spec_flags
|= RTSA_REMOTE_ENDPOINT
;
851 msg(M_WARN
, PACKAGE_NAME
" ROUTE: failed to parse/resolve VPN endpoint: %s", remote_endpoint
);
856 /* parse the routes from opt6 to rl6
857 * discovering potential overlaps with remote_host_ipv6 in the process
859 need_remote_ipv6_route
= false;
862 struct route_ipv6_option
*ro6
;
863 for (ro6
= opt6
->routes_ipv6
; ro6
; ro6
= ro6
->next
)
865 struct route_ipv6
*r6
;
866 ALLOC_OBJ_GC(r6
, struct route_ipv6
, &rl6
->gc
);
867 if (!init_route_ipv6(r6
, ro6
, rl6
))
873 r6
->next
= rl6
->routes_ipv6
;
874 rl6
->routes_ipv6
= r6
;
876 #ifndef TARGET_ANDROID
877 /* On Android the VPNService protect function call will take of
878 * avoiding routing loops, so ignore this part and let
879 * need_remote_ipv6_route always evaluate to false
882 && route_ipv6_match_host( r6
, remote_host_ipv6
) )
884 need_remote_ipv6_route
= true;
885 msg(D_ROUTE
, "ROUTE6: %s/%d overlaps IPv6 remote %s, adding host route to VPN endpoint",
886 print_in6_addr(r6
->network
, 0, &gc
), r6
->netbits
,
887 print_in6_addr(*remote_host_ipv6
, 0, &gc
));
894 /* add VPN server host route if needed */
895 if (need_remote_ipv6_route
)
897 if ( (rl6
->rgi6
.flags
& (RGI_ADDR_DEFINED
|RGI_IFACE_DEFINED
) ) ==
898 (RGI_ADDR_DEFINED
|RGI_IFACE_DEFINED
) )
900 struct route_ipv6
*r6
;
901 ALLOC_OBJ_CLEAR_GC(r6
, struct route_ipv6
, &rl6
->gc
);
903 r6
->network
= *remote_host_ipv6
;
905 if (!(rl6
->rgi6
.flags
& RGI_ON_LINK
) )
907 r6
->gateway
= rl6
->rgi6
.gateway
.addr_ipv6
;
911 r6
->adapter_index
= rl6
->rgi6
.adapter_index
;
913 r6
->iface
= rl6
->rgi6
.iface
;
915 r6
->flags
= RT_DEFINED
| RT_METRIC_DEFINED
;
917 r6
->next
= rl6
->routes_ipv6
;
918 rl6
->routes_ipv6
= r6
;
922 msg(M_WARN
, "ROUTE6: IPv6 route overlaps with IPv6 remote address, but could not determine IPv6 gateway address + interface, expect failure\n" );
931 add_route3(in_addr_t network
,
934 const struct tuntap
*tt
,
936 const struct route_gateway_info
*rgi
,
937 const struct env_set
*es
,
938 openvpn_net_ctx_t
*ctx
)
942 r
.flags
= RT_DEFINED
;
946 return add_route(&r
, tt
, flags
, rgi
, es
, ctx
);
950 del_route3(in_addr_t network
,
953 const struct tuntap
*tt
,
955 const struct route_gateway_info
*rgi
,
956 const struct env_set
*es
,
957 openvpn_net_ctx_t
*ctx
)
961 r
.flags
= RT_DEFINED
|RT_ADDED
;
965 delete_route(&r
, tt
, flags
, rgi
, es
, ctx
);
969 add_bypass_routes(struct route_bypass
*rb
,
971 const struct tuntap
*tt
,
973 const struct route_gateway_info
*rgi
,
974 const struct env_set
*es
,
975 openvpn_net_ctx_t
*ctx
)
978 for (int i
= 0; i
< rb
->n_bypass
; ++i
)
982 ret
= add_route3(rb
->bypass
[i
], IPV4_NETMASK_HOST
, gateway
, tt
,
983 flags
| ROUTE_REF_GW
, rgi
, es
, ctx
) && ret
;
990 del_bypass_routes(struct route_bypass
*rb
,
992 const struct tuntap
*tt
,
994 const struct route_gateway_info
*rgi
,
995 const struct env_set
*es
,
996 openvpn_net_ctx_t
*ctx
)
999 for (i
= 0; i
< rb
->n_bypass
; ++i
)
1003 del_route3(rb
->bypass
[i
],
1007 flags
| ROUTE_REF_GW
,
1016 redirect_default_route_to_vpn(struct route_list
*rl
, const struct tuntap
*tt
,
1017 unsigned int flags
, const struct env_set
*es
,
1018 openvpn_net_ctx_t
*ctx
)
1020 const char err
[] = "NOTE: unable to redirect IPv4 default gateway --";
1023 if (rl
&& rl
->flags
& RG_ENABLE
)
1025 bool local
= rl
->flags
& RG_LOCAL
;
1027 if (!(rl
->spec
.flags
& RTSA_REMOTE_ENDPOINT
) && (rl
->flags
& RG_REROUTE_GW
))
1029 msg(M_WARN
, "%s VPN gateway parameter (--route-gateway or --ifconfig) is missing", err
);
1033 * check if a default route is defined, unless:
1034 * - we are connecting to a remote host in our network
1035 * - we are connecting to a non-IPv4 remote host (i.e. we use IPv6)
1037 else if (!(rl
->rgi
.flags
& RGI_ADDR_DEFINED
) && !local
1038 && (rl
->spec
.flags
& RTSA_REMOTE_HOST
))
1040 msg(M_WARN
, "%s Cannot read current default gateway from system", err
);
1045 #ifndef TARGET_ANDROID
1046 if (rl
->flags
& RG_AUTO_LOCAL
)
1048 const int tla
= rl
->spec
.remote_host_local
;
1049 if (tla
== TLA_NONLOCAL
)
1051 dmsg(D_ROUTE
, "ROUTE remote_host is NOT LOCAL");
1054 else if (tla
== TLA_LOCAL
)
1056 dmsg(D_ROUTE
, "ROUTE remote_host is LOCAL");
1062 /* route remote host to original default gateway */
1063 /* if remote_host is not ipv4 (ie: ipv6), just skip
1064 * adding this special /32 route */
1065 if ((rl
->spec
.flags
& RTSA_REMOTE_HOST
)
1066 && rl
->spec
.remote_host
!= IPV4_INVALID_ADDR
)
1068 ret
= add_route3(rl
->spec
.remote_host
, IPV4_NETMASK_HOST
,
1069 rl
->rgi
.gateway
.addr
, tt
, flags
| ROUTE_REF_GW
,
1073 rl
->iflags
|= RL_DID_LOCAL
;
1078 dmsg(D_ROUTE
, "ROUTE remote_host protocol differs from tunneled");
1081 #endif /* ifndef TARGET_ANDROID */
1083 /* route DHCP/DNS server traffic through original default gateway */
1084 ret
= add_bypass_routes(&rl
->spec
.bypass
, rl
->rgi
.gateway
.addr
, tt
, flags
,
1085 &rl
->rgi
, es
, ctx
) && ret
;
1087 if (rl
->flags
& RG_REROUTE_GW
)
1089 if (rl
->flags
& RG_DEF1
)
1091 /* add new default route (1st component) */
1092 ret
= add_route3(0x00000000, 0x80000000, rl
->spec
.remote_endpoint
,
1093 tt
, flags
, &rl
->rgi
, es
, ctx
) && ret
;
1095 /* add new default route (2nd component) */
1096 ret
= add_route3(0x80000000, 0x80000000, rl
->spec
.remote_endpoint
,
1097 tt
, flags
, &rl
->rgi
, es
, ctx
) && ret
;
1101 /* don't try to remove the def route if it does not exist */
1102 if (rl
->rgi
.flags
& RGI_ADDR_DEFINED
)
1104 /* delete default route */
1105 del_route3(0, 0, rl
->rgi
.gateway
.addr
, tt
,
1106 flags
| ROUTE_REF_GW
, &rl
->rgi
, es
, ctx
);
1109 /* add new default route */
1110 ret
= add_route3(0, 0, rl
->spec
.remote_endpoint
, tt
,
1111 flags
, &rl
->rgi
, es
, ctx
) && ret
;
1115 /* set a flag so we can undo later */
1116 rl
->iflags
|= RL_DID_REDIRECT_DEFAULT_GATEWAY
;
1123 undo_redirect_default_route_to_vpn(struct route_list
*rl
,
1124 const struct tuntap
*tt
, unsigned int flags
,
1125 const struct env_set
*es
,
1126 openvpn_net_ctx_t
*ctx
)
1128 if (rl
&& rl
->iflags
& RL_DID_REDIRECT_DEFAULT_GATEWAY
)
1130 /* delete remote host route */
1131 if (rl
->iflags
& RL_DID_LOCAL
)
1133 del_route3(rl
->spec
.remote_host
,
1135 rl
->rgi
.gateway
.addr
,
1137 flags
| ROUTE_REF_GW
,
1141 rl
->iflags
&= ~RL_DID_LOCAL
;
1144 /* delete special DHCP/DNS bypass route */
1145 del_bypass_routes(&rl
->spec
.bypass
, rl
->rgi
.gateway
.addr
, tt
, flags
,
1148 if (rl
->flags
& RG_REROUTE_GW
)
1150 if (rl
->flags
& RG_DEF1
)
1152 /* delete default route (1st component) */
1153 del_route3(0x00000000,
1155 rl
->spec
.remote_endpoint
,
1162 /* delete default route (2nd component) */
1163 del_route3(0x80000000,
1165 rl
->spec
.remote_endpoint
,
1174 /* delete default route */
1177 rl
->spec
.remote_endpoint
,
1183 /* restore original default route if there was any */
1184 if (rl
->rgi
.flags
& RGI_ADDR_DEFINED
)
1186 add_route3(0, 0, rl
->rgi
.gateway
.addr
, tt
,
1187 flags
| ROUTE_REF_GW
, &rl
->rgi
, es
, ctx
);
1192 rl
->iflags
&= ~RL_DID_REDIRECT_DEFAULT_GATEWAY
;
1197 add_routes(struct route_list
*rl
, struct route_ipv6_list
*rl6
,
1198 const struct tuntap
*tt
, unsigned int flags
,
1199 const struct env_set
*es
, openvpn_net_ctx_t
*ctx
)
1201 bool ret
= redirect_default_route_to_vpn(rl
, tt
, flags
, es
, ctx
);
1202 if (rl
&& !(rl
->iflags
& RL_ROUTES_ADDED
) )
1204 struct route_ipv4
*r
;
1206 if (rl
->routes
&& !tt
->did_ifconfig_setup
)
1208 msg(M_INFO
, "WARNING: OpenVPN was configured to add an IPv4 "
1209 "route. However, no IPv4 has been configured for %s, "
1210 "therefore the route installation may fail or may not work "
1211 "as expected.", tt
->actual_name
);
1214 #ifdef ENABLE_MANAGEMENT
1215 if (management
&& rl
->routes
)
1217 management_set_state(management
,
1218 OPENVPN_STATE_ADD_ROUTES
,
1227 for (r
= rl
->routes
; r
; r
= r
->next
)
1229 if (flags
& ROUTE_DELETE_FIRST
)
1231 delete_route(r
, tt
, flags
, &rl
->rgi
, es
, ctx
);
1233 ret
= add_route(r
, tt
, flags
, &rl
->rgi
, es
, ctx
) && ret
;
1235 rl
->iflags
|= RL_ROUTES_ADDED
;
1237 if (rl6
&& !(rl6
->iflags
& RL_ROUTES_ADDED
) )
1239 struct route_ipv6
*r
;
1241 if (!tt
->did_ifconfig_ipv6_setup
)
1243 msg(M_INFO
, "WARNING: OpenVPN was configured to add an IPv6 "
1244 "route. However, no IPv6 has been configured for %s, "
1245 "therefore the route installation may fail or may not work "
1246 "as expected.", tt
->actual_name
);
1249 for (r
= rl6
->routes_ipv6
; r
; r
= r
->next
)
1251 if (flags
& ROUTE_DELETE_FIRST
)
1253 delete_route_ipv6(r
, tt
, es
, ctx
);
1255 ret
= add_route_ipv6(r
, tt
, flags
, es
, ctx
) && ret
;
1257 rl6
->iflags
|= RL_ROUTES_ADDED
;
1264 delete_routes(struct route_list
*rl
, struct route_ipv6_list
*rl6
,
1265 const struct tuntap
*tt
, unsigned int flags
,
1266 const struct env_set
*es
, openvpn_net_ctx_t
*ctx
)
1268 if (rl
&& rl
->iflags
& RL_ROUTES_ADDED
)
1270 struct route_ipv4
*r
;
1271 for (r
= rl
->routes
; r
; r
= r
->next
)
1273 delete_route(r
, tt
, flags
, &rl
->rgi
, es
, ctx
);
1275 rl
->iflags
&= ~RL_ROUTES_ADDED
;
1278 undo_redirect_default_route_to_vpn(rl
, tt
, flags
, es
, ctx
);
1282 clear_route_list(rl
);
1285 if (rl6
&& (rl6
->iflags
& RL_ROUTES_ADDED
) )
1287 struct route_ipv6
*r6
;
1288 for (r6
= rl6
->routes_ipv6
; r6
; r6
= r6
->next
)
1290 delete_route_ipv6(r6
, tt
, es
, ctx
);
1292 rl6
->iflags
&= ~RL_ROUTES_ADDED
;
1297 clear_route_ipv6_list(rl6
);
1301 #ifndef ENABLE_SMALL
1304 show_opt(const char *option
)
1308 return "default (not set)";
1317 print_route_option(const struct route_option
*ro
, int level
)
1319 msg(level
, " route %s/%s/%s/%s",
1320 show_opt(ro
->network
),
1321 show_opt(ro
->netmask
),
1322 show_opt(ro
->gateway
),
1323 show_opt(ro
->metric
));
1327 print_route_options(const struct route_option_list
*rol
,
1330 struct route_option
*ro
;
1331 if (rol
->flags
& RG_ENABLE
)
1333 msg(level
, " [redirect_default_gateway local=%d]",
1334 (rol
->flags
& RG_LOCAL
) != 0);
1336 for (ro
= rol
->routes
; ro
; ro
= ro
->next
)
1338 print_route_option(ro
, level
);
1343 print_default_gateway(const int msglevel
,
1344 const struct route_gateway_info
*rgi
,
1345 const struct route_ipv6_gateway_info
*rgi6
)
1347 struct gc_arena gc
= gc_new();
1348 if (rgi
&& (rgi
->flags
& RGI_ADDR_DEFINED
))
1350 struct buffer out
= alloc_buf_gc(256, &gc
);
1351 buf_printf(&out
, "ROUTE_GATEWAY");
1352 if (rgi
->flags
& RGI_ON_LINK
)
1354 buf_printf(&out
, " ON_LINK");
1358 buf_printf(&out
, " %s", print_in_addr_t(rgi
->gateway
.addr
, 0, &gc
));
1360 if (rgi
->flags
& RGI_NETMASK_DEFINED
)
1362 buf_printf(&out
, "/%s", print_in_addr_t(rgi
->gateway
.netmask
, 0, &gc
));
1365 if (rgi
->flags
& RGI_IFACE_DEFINED
)
1367 buf_printf(&out
, " I=%lu", rgi
->adapter_index
);
1370 if (rgi
->flags
& RGI_IFACE_DEFINED
)
1372 buf_printf(&out
, " IFACE=%s", rgi
->iface
);
1375 if (rgi
->flags
& RGI_HWADDR_DEFINED
)
1377 buf_printf(&out
, " HWADDR=%s", format_hex_ex(rgi
->hwaddr
, 6, 0, 1, ":", &gc
));
1379 msg(msglevel
, "%s", BSTR(&out
));
1382 if (rgi6
&& (rgi6
->flags
& RGI_ADDR_DEFINED
))
1384 struct buffer out
= alloc_buf_gc(256, &gc
);
1385 buf_printf(&out
, "ROUTE6_GATEWAY");
1386 buf_printf(&out
, " %s", print_in6_addr(rgi6
->gateway
.addr_ipv6
, 0, &gc
));
1387 if (rgi6
->flags
& RGI_ON_LINK
)
1389 buf_printf(&out
, " ON_LINK");
1391 if (rgi6
->flags
& RGI_NETMASK_DEFINED
)
1393 buf_printf(&out
, "/%d", rgi6
->gateway
.netbits_ipv6
);
1396 if (rgi6
->flags
& RGI_IFACE_DEFINED
)
1398 buf_printf(&out
, " I=%lu", rgi6
->adapter_index
);
1401 if (rgi6
->flags
& RGI_IFACE_DEFINED
)
1403 buf_printf(&out
, " IFACE=%s", rgi6
->iface
);
1406 if (rgi6
->flags
& RGI_HWADDR_DEFINED
)
1408 buf_printf(&out
, " HWADDR=%s", format_hex_ex(rgi6
->hwaddr
, 6, 0, 1, ":", &gc
));
1410 msg(msglevel
, "%s", BSTR(&out
));
1415 #endif /* ifndef ENABLE_SMALL */
1418 print_route(const struct route_ipv4
*r
, int level
)
1420 struct gc_arena gc
= gc_new();
1421 if (r
->flags
& RT_DEFINED
)
1423 msg(level
, "%s", route_string(r
, &gc
));
1429 print_routes(const struct route_list
*rl
, int level
)
1431 struct route_ipv4
*r
;
1432 for (r
= rl
->routes
; r
; r
= r
->next
)
1434 print_route(r
, level
);
1439 setenv_route(struct env_set
*es
, const struct route_ipv4
*r
, int i
)
1441 struct gc_arena gc
= gc_new();
1442 if (r
->flags
& RT_DEFINED
)
1444 setenv_route_addr(es
, "network", r
->network
, i
);
1445 setenv_route_addr(es
, "netmask", r
->netmask
, i
);
1446 setenv_route_addr(es
, "gateway", r
->gateway
, i
);
1448 if (r
->flags
& RT_METRIC_DEFINED
)
1450 struct buffer name
= alloc_buf_gc(256, &gc
);
1451 buf_printf(&name
, "route_metric_%d", i
);
1452 setenv_int(es
, BSTR(&name
), r
->metric
);
1459 setenv_routes(struct env_set
*es
, const struct route_list
*rl
)
1462 struct route_ipv4
*r
;
1463 for (r
= rl
->routes
; r
; r
= r
->next
)
1465 setenv_route(es
, r
, i
++);
1470 setenv_route_ipv6(struct env_set
*es
, const struct route_ipv6
*r6
, int i
)
1472 struct gc_arena gc
= gc_new();
1473 if (r6
->flags
& RT_DEFINED
)
1475 struct buffer name1
= alloc_buf_gc( 256, &gc
);
1476 struct buffer val
= alloc_buf_gc( 256, &gc
);
1477 struct buffer name2
= alloc_buf_gc( 256, &gc
);
1479 buf_printf( &name1
, "route_ipv6_network_%d", i
);
1480 buf_printf( &val
, "%s/%d", print_in6_addr( r6
->network
, 0, &gc
),
1482 setenv_str( es
, BSTR(&name1
), BSTR(&val
) );
1484 buf_printf( &name2
, "route_ipv6_gateway_%d", i
);
1485 setenv_str( es
, BSTR(&name2
), print_in6_addr( r6
->gateway
, 0, &gc
));
1487 if (r6
->flags
& RT_METRIC_DEFINED
)
1489 struct buffer name3
= alloc_buf_gc( 256, &gc
);
1490 buf_printf( &name3
, "route_ipv6_metric_%d", i
);
1491 setenv_int( es
, BSTR(&name3
), r6
->metric
);
1497 setenv_routes_ipv6(struct env_set
*es
, const struct route_ipv6_list
*rl6
)
1500 struct route_ipv6
*r6
;
1501 for (r6
= rl6
->routes_ipv6
; r6
; r6
= r6
->next
)
1503 setenv_route_ipv6(es
, r6
, i
++);
1508 * local_route() determines whether the gateway of a provided host
1509 * route is on the same interface that owns the default gateway.
1510 * It uses the data structure
1511 * returned by get_default_gateway() (struct route_gateway_info)
1512 * to determine this. If the route is local, LR_MATCH is returned.
1513 * When adding routes into the kernel, if LR_MATCH is defined for
1514 * a given route, the route should explicitly reference the default
1515 * gateway interface as the route destination. For example, here
1516 * is an example on Linux that uses LR_MATCH:
1518 * route add -net 10.10.0.1 netmask 255.255.255.255 dev eth0
1520 * This capability is needed by the "default-gateway block-local"
1521 * directive, to allow client access to the local subnet to be
1522 * blocked but still allow access to the local default gateway.
1525 /* local_route() return values */
1526 #define LR_NOMATCH 0 /* route is not local */
1527 #define LR_MATCH 1 /* route is local */
1528 #define LR_ERROR 2 /* caller should abort adding route */
1531 local_route(in_addr_t network
,
1534 const struct route_gateway_info
*rgi
)
1536 /* set LR_MATCH on local host routes */
1537 const int rgi_needed
= (RGI_ADDR_DEFINED
|RGI_NETMASK_DEFINED
|RGI_IFACE_DEFINED
);
1539 && (rgi
->flags
& rgi_needed
) == rgi_needed
1540 && gateway
== rgi
->gateway
.addr
1541 && netmask
== 0xFFFFFFFF)
1543 if (((network
^ rgi
->gateway
.addr
) & rgi
->gateway
.netmask
) == 0)
1549 /* examine additional subnets on gateway interface */
1551 for (i
= 0; i
< rgi
->n_addrs
; ++i
)
1553 const struct route_gateway_address
*gwa
= &rgi
->addrs
[i
];
1554 if (((network
^ gwa
->addr
) & gwa
->netmask
) == 0)
1564 /* Return true if the "on-link" form of the route should be used. This is when the gateway for
1565 * a route is specified as an interface rather than an address. */
1566 #if defined(TARGET_LINUX) || defined(_WIN32) || defined(TARGET_DARWIN)
1568 is_on_link(const int is_local_route
, const unsigned int flags
, const struct route_gateway_info
*rgi
)
1570 return rgi
&& (is_local_route
== LR_MATCH
|| ((flags
& ROUTE_REF_GW
) && (rgi
->flags
& RGI_ON_LINK
)));
1575 add_route(struct route_ipv4
*r
,
1576 const struct tuntap
*tt
,
1578 const struct route_gateway_info
*rgi
, /* may be NULL */
1579 const struct env_set
*es
,
1580 openvpn_net_ctx_t
*ctx
)
1585 if (!(r
->flags
& RT_DEFINED
))
1587 return true; /* no error */
1590 struct argv argv
= argv_new();
1591 struct gc_arena gc
= gc_new();
1593 #if !defined(TARGET_LINUX)
1594 const char *network
= print_in_addr_t(r
->network
, 0, &gc
);
1595 #if !defined(TARGET_AIX)
1596 const char *netmask
= print_in_addr_t(r
->netmask
, 0, &gc
);
1598 const char *gateway
= print_in_addr_t(r
->gateway
, 0, &gc
);
1601 is_local_route
= local_route(r
->network
, r
->netmask
, r
->gateway
, rgi
);
1602 if (is_local_route
== LR_ERROR
)
1607 #if defined(TARGET_LINUX)
1608 const char *iface
= NULL
;
1611 if (is_on_link(is_local_route
, flags
, rgi
))
1616 if (r
->flags
& RT_METRIC_DEFINED
)
1622 status
= RTA_SUCCESS
;
1623 int ret
= net_route_v4_add(ctx
, &r
->network
, netmask_to_netbits2(r
->netmask
),
1624 &r
->gateway
, iface
, r
->table_id
, metric
);
1627 msg(D_ROUTE
, "NOTE: Linux route add command failed because route exists");
1628 status
= RTA_EEXIST
;
1632 msg(M_WARN
, "ERROR: Linux route add command failed");
1636 #elif defined (TARGET_ANDROID)
1641 snprintf(out
, sizeof(out
), "%s %s %s dev %s", network
, netmask
, gateway
, rgi
->iface
);
1645 snprintf(out
, sizeof(out
), "%s %s %s", network
, netmask
, gateway
);
1647 bool ret
= management_android_control(management
, "ROUTE", out
);
1648 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
1650 #elif defined (_WIN32)
1652 DWORD ai
= TUN_ADAPTER_INDEX_INVALID
;
1653 argv_printf(&argv
, "%s%s ADD %s MASK %s %s",
1655 WIN_ROUTE_PATH_SUFFIX
,
1659 if (r
->flags
& RT_METRIC_DEFINED
)
1661 argv_printf_cat(&argv
, "METRIC %d", r
->metric
);
1663 if (is_on_link(is_local_route
, flags
, rgi
))
1665 ai
= rgi
->adapter_index
;
1666 argv_printf_cat(&argv
, "IF %lu", ai
);
1669 argv_msg(D_ROUTE
, &argv
);
1671 const char *method
= "service";
1672 if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_SERVICE
)
1674 status
= add_route_service(r
, tt
);
1676 else if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_IPAPI
)
1678 status
= add_route_ipapi(r
, tt
, ai
);
1681 else if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_EXE
)
1683 netcmd_semaphore_lock();
1684 bool ret
= openvpn_execve_check(&argv
, es
, 0,
1685 "ERROR: Windows route add command failed");
1686 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
1687 netcmd_semaphore_release();
1688 method
= "route.exe";
1690 else if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_ADAPTIVE
)
1692 status
= add_route_ipapi(r
, tt
, ai
);
1693 method
= "ipapi [adaptive]";
1694 if (status
== RTA_ERROR
)
1696 msg(D_ROUTE
, "Route addition fallback to route.exe");
1697 netcmd_semaphore_lock();
1698 bool ret
= openvpn_execve_check(&argv
, es
, 0,
1699 "ERROR: Windows route add command failed [adaptive]");
1700 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
1701 netcmd_semaphore_release();
1702 method
= "route.exe";
1709 if (status
!= RTA_ERROR
) /* error is logged upstream */
1711 msg(D_ROUTE
, "Route addition via %s %s", method
,
1712 (status
== RTA_SUCCESS
) ? "succeeded" : "failed because route exists");
1716 #elif defined (TARGET_SOLARIS)
1718 /* example: route add 192.0.2.32 -netmask 255.255.255.224 somegateway */
1720 argv_printf(&argv
, "%s add",
1723 argv_printf_cat(&argv
, "%s -netmask %s %s",
1728 /* Solaris can only distinguish between "metric 0" == "on-link on the
1729 * interface where the IP address given is configured" and "metric > 0"
1730 * == "use gateway specified" (no finer-grained route metrics available)
1732 * More recent versions of Solaris can also do "-interface", but that
1733 * would break backwards compatibility with older versions for no gain.
1735 if (r
->flags
& RT_METRIC_DEFINED
)
1737 argv_printf_cat(&argv
, "%d", r
->metric
);
1740 argv_msg(D_ROUTE
, &argv
);
1741 bool ret
= openvpn_execve_check(&argv
, es
, 0,
1742 "ERROR: Solaris route add command failed");
1743 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
1745 #elif defined(TARGET_FREEBSD)
1747 argv_printf(&argv
, "%s add",
1751 if (r
->flags
& RT_METRIC_DEFINED
)
1753 argv_printf_cat(&argv
, "-rtt %d", r
->metric
);
1757 argv_printf_cat(&argv
, "-net %s %s %s",
1762 /* FIXME -- add on-link support for FreeBSD */
1764 argv_msg(D_ROUTE
, &argv
);
1765 bool ret
= openvpn_execve_check(&argv
, es
, 0,
1766 "ERROR: FreeBSD route add command failed");
1767 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
1769 #elif defined(TARGET_DRAGONFLY)
1771 argv_printf(&argv
, "%s add",
1775 if (r
->flags
& RT_METRIC_DEFINED
)
1777 argv_printf_cat(&argv
, "-rtt %d", r
->metric
);
1781 argv_printf_cat(&argv
, "-net %s %s %s",
1786 /* FIXME -- add on-link support for Dragonfly */
1788 argv_msg(D_ROUTE
, &argv
);
1789 bool ret
= openvpn_execve_check(&argv
, es
, 0,
1790 "ERROR: DragonFly route add command failed");
1791 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
1793 #elif defined(TARGET_DARWIN)
1795 argv_printf(&argv
, "%s add",
1799 if (r
->flags
& RT_METRIC_DEFINED
)
1801 argv_printf_cat(&argv
, "-rtt %d", r
->metric
);
1805 if (is_on_link(is_local_route
, flags
, rgi
))
1807 /* Mac OS X route syntax for ON_LINK:
1808 * route add -cloning -net 10.10.0.1 -netmask 255.255.255.255 -interface en0 */
1809 argv_printf_cat(&argv
, "-cloning -net %s -netmask %s -interface %s",
1816 argv_printf_cat(&argv
, "-net %s %s %s",
1822 argv_msg(D_ROUTE
, &argv
);
1823 bool ret
= openvpn_execve_check(&argv
, es
, 0,
1824 "ERROR: OS X route add command failed");
1825 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
1827 #elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1829 argv_printf(&argv
, "%s add",
1833 if (r
->flags
& RT_METRIC_DEFINED
)
1835 argv_printf_cat(&argv
, "-rtt %d", r
->metric
);
1839 argv_printf_cat(&argv
, "-net %s %s -netmask %s",
1844 /* FIXME -- add on-link support for OpenBSD/NetBSD */
1846 argv_msg(D_ROUTE
, &argv
);
1847 bool ret
= openvpn_execve_check(&argv
, es
, 0,
1848 "ERROR: OpenBSD/NetBSD route add command failed");
1849 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
1851 #elif defined(TARGET_AIX)
1854 int netbits
= netmask_to_netbits2(r
->netmask
);
1855 argv_printf(&argv
, "%s add -net %s/%d %s",
1857 network
, netbits
, gateway
);
1858 argv_msg(D_ROUTE
, &argv
);
1859 bool ret
= openvpn_execve_check(&argv
, es
, 0,
1860 "ERROR: AIX route add command failed");
1861 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
1864 #elif defined(TARGET_HAIKU)
1866 /* ex: route add /dev/net/ipro1000/0 0.0.0.0 gw 192.168.1.1 netmask 128.0.0.0 */
1867 argv_printf(&argv
, "%s add %s inet %s gw %s netmask %s",
1873 argv_msg(D_ROUTE
, &argv
);
1874 bool ret
= openvpn_execve_check(&argv
, es
, 0,
1875 "ERROR: Haiku inet route add command failed");
1876 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
1878 #else /* if defined(TARGET_LINUX) */
1879 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");
1880 #endif /* if defined(TARGET_LINUX) */
1883 if (status
== RTA_SUCCESS
)
1885 r
->flags
|= RT_ADDED
;
1889 r
->flags
&= ~RT_ADDED
;
1893 /* release resources potentially allocated during route setup */
1896 return (status
!= RTA_ERROR
);
1901 route_ipv6_clear_host_bits( struct route_ipv6
*r6
)
1903 /* clear host bit parts of route
1904 * (needed if routes are specified improperly, or if we need to
1905 * explicitly setup/clear the "connected" network routes on some OSes)
1908 int bits_to_clear
= 128 - r6
->netbits
;
1910 while (byte
>= 0 && bits_to_clear
> 0)
1912 if (bits_to_clear
>= 8)
1914 r6
->network
.s6_addr
[byte
--] = 0; bits_to_clear
-= 8;
1918 r6
->network
.s6_addr
[byte
--] &= (0xff << bits_to_clear
); bits_to_clear
= 0;
1924 add_route_ipv6(struct route_ipv6
*r6
, const struct tuntap
*tt
,
1925 unsigned int flags
, const struct env_set
*es
,
1926 openvpn_net_ctx_t
*ctx
)
1929 bool gateway_needed
= false;
1931 if (!(r6
->flags
& RT_DEFINED
) )
1933 return true; /* no error */
1936 struct argv argv
= argv_new();
1937 struct gc_arena gc
= gc_new();
1940 const char *device
= tt
->actual_name
;
1941 if (r6
->iface
!= NULL
) /* vpn server special route */
1944 if (!IN6_IS_ADDR_UNSPECIFIED(&r6
->gateway
) )
1946 gateway_needed
= true;
1951 route_ipv6_clear_host_bits(r6
);
1952 const char *network
= print_in6_addr( r6
->network
, 0, &gc
);
1953 const char *gateway
= print_in6_addr( r6
->gateway
, 0, &gc
);
1955 #if defined(TARGET_DARWIN) \
1956 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
1957 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1959 /* the BSD platforms cannot specify gateway and interface independently,
1960 * but for link-local destinations, we MUST specify the interface, so
1961 * we build a combined "$gateway%$interface" gateway string
1963 if (r6
->iface
!= NULL
&& gateway_needed
1964 && IN6_IS_ADDR_LINKLOCAL(&r6
->gateway
) ) /* fe80::...%intf */
1966 int len
= strlen(gateway
) + 1 + strlen(r6
->iface
)+1;
1967 char *tmp
= gc_malloc( len
, true, &gc
);
1968 snprintf( tmp
, len
, "%s%%%s", gateway
, r6
->iface
);
1974 msg(D_ROUTE
, "add_route_ipv6(%s/%d -> %s metric %d) dev %s",
1975 network
, r6
->netbits
, gateway
, r6
->metric
, device
);
1977 msg(D_ROUTE
, "add_route_ipv6(%s/%d -> %s metric %d) IF %lu",
1978 network
, r6
->netbits
, gateway
, r6
->metric
,
1979 r6
->adapter_index
? r6
->adapter_index
: tt
->adapter_index
);
1983 * Filter out routes which are essentially no-ops
1984 * (not currently done for IPv6)
1987 /* On "tun" interface, we never set a gateway if the operating system
1988 * can do "route to interface" - it does not add value, as the target
1989 * dev already fully qualifies the route destination on point-to-point
1990 * interfaces. OTOH, on "tap" interface, we must always set the
1991 * gateway unless the route is to be an on-link network
1993 if (tt
->type
== DEV_TYPE_TAP
1994 && !( (r6
->flags
& RT_METRIC_DEFINED
) && r6
->metric
== 0 ) )
1996 gateway_needed
= true;
1999 if (gateway_needed
&& IN6_IS_ADDR_UNSPECIFIED(&r6
->gateway
))
2001 msg(M_WARN
, "ROUTE6 WARNING: " PACKAGE_NAME
" needs a gateway "
2002 "parameter for a --route-ipv6 option and no default was set via "
2003 "--ifconfig-ipv6 or --route-ipv6-gateway option. Not installing "
2004 "IPv6 route to %s/%d.", network
, r6
->netbits
);
2009 #if defined(TARGET_LINUX)
2011 if ((r6
->flags
& RT_METRIC_DEFINED
) && (r6
->metric
> 0))
2013 metric
= r6
->metric
;
2016 status
= RTA_SUCCESS
;
2017 int ret
= net_route_v6_add(ctx
, &r6
->network
, r6
->netbits
,
2018 gateway_needed
? &r6
->gateway
: NULL
,
2019 device
, r6
->table_id
, metric
);
2022 msg(D_ROUTE
, "NOTE: Linux route add command failed because route exists");
2023 status
= RTA_EEXIST
;
2027 msg(M_WARN
, "ERROR: Linux route add command failed");
2031 #elif defined (TARGET_ANDROID)
2034 snprintf(out
, sizeof(out
), "%s/%d %s", network
, r6
->netbits
, device
);
2036 status
= management_android_control(management
, "ROUTE6", out
);
2038 #elif defined (_WIN32)
2040 if (tt
->options
.msg_channel
)
2042 status
= add_route_ipv6_service(r6
, tt
);
2046 status
= route_ipv6_ipapi(true, r6
, tt
);
2048 #elif defined (TARGET_SOLARIS)
2050 /* example: route add -inet6 2001:db8::/32 somegateway 0 */
2052 /* for some reason, routes to tun/tap do not work for me unless I set
2053 * "metric 0" - otherwise, the routes will be nicely installed, but
2054 * packets will just disappear somewhere. So we always use "0" now,
2055 * unless the route points to "gateway on other interface"...
2057 * (Note: OpenSolaris can not specify host%interface gateways, so we just
2058 * use the GW addresses - it seems to still work for fe80:: addresses,
2059 * however this is done internally. NUD maybe?)
2061 argv_printf(&argv
, "%s add -inet6 %s/%d %s",
2067 /* on tun (not tap), not "elsewhere"? -> metric 0 */
2068 if (tt
->type
== DEV_TYPE_TUN
&& !r6
->iface
)
2070 argv_printf_cat(&argv
, "0");
2073 argv_msg(D_ROUTE
, &argv
);
2074 bool ret
= openvpn_execve_check(&argv
, es
, 0,
2075 "ERROR: Solaris route add -inet6 command failed");
2076 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
2078 #elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
2080 argv_printf(&argv
, "%s add -inet6 %s/%d",
2087 argv_printf_cat(&argv
, "%s", gateway
);
2091 argv_printf_cat(&argv
, "-iface %s", device
);
2094 argv_msg(D_ROUTE
, &argv
);
2095 bool ret
= openvpn_execve_check(&argv
, es
, 0,
2096 "ERROR: *BSD route add -inet6 command failed");
2097 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
2099 #elif defined(TARGET_DARWIN)
2101 argv_printf(&argv
, "%s add -inet6 %s -prefixlen %d",
2103 network
, r6
->netbits
);
2107 argv_printf_cat(&argv
, "%s", gateway
);
2111 argv_printf_cat(&argv
, "-iface %s", device
);
2114 argv_msg(D_ROUTE
, &argv
);
2115 bool ret
= openvpn_execve_check(&argv
, es
, 0,
2116 "ERROR: MacOS X route add -inet6 command failed");
2117 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
2119 #elif defined(TARGET_OPENBSD)
2121 argv_printf(&argv
, "%s add -inet6 %s -prefixlen %d %s",
2123 network
, r6
->netbits
, gateway
);
2125 argv_msg(D_ROUTE
, &argv
);
2126 bool ret
= openvpn_execve_check(&argv
, es
, 0,
2127 "ERROR: OpenBSD route add -inet6 command failed");
2128 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
2130 #elif defined(TARGET_NETBSD)
2132 argv_printf(&argv
, "%s add -inet6 %s/%d %s",
2134 network
, r6
->netbits
, gateway
);
2136 argv_msg(D_ROUTE
, &argv
);
2137 bool ret
= openvpn_execve_check(&argv
, es
, 0,
2138 "ERROR: NetBSD route add -inet6 command failed");
2139 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
2141 #elif defined(TARGET_AIX)
2143 argv_printf(&argv
, "%s add -inet6 %s/%d %s",
2145 network
, r6
->netbits
, gateway
);
2146 argv_msg(D_ROUTE
, &argv
);
2147 bool ret
= openvpn_execve_check(&argv
, es
, 0,
2148 "ERROR: AIX route add command failed");
2149 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
2151 #elif defined(TARGET_HAIKU)
2153 /* ex: route add /dev/net/ipro1000/0 inet6 :: gw beef::cafe prefixlen 64 */
2154 argv_printf(&argv
, "%s add %s inet6 %s gw %s prefixlen %d",
2160 argv_msg(D_ROUTE
, &argv
);
2161 bool ret
= openvpn_execve_check(&argv
, es
, 0,
2162 "ERROR: Haiku inet6 route add command failed");
2163 status
= ret
? RTA_SUCCESS
: RTA_ERROR
;
2165 #else /* if defined(TARGET_LINUX) */
2166 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");
2167 #endif /* if defined(TARGET_LINUX) */
2170 if (status
== RTA_SUCCESS
)
2172 r6
->flags
|= RT_ADDED
;
2176 r6
->flags
&= ~RT_ADDED
;
2180 /* release resources potentially allocated during route setup */
2183 return (status
!= RTA_ERROR
);
2187 delete_route(struct route_ipv4
*r
,
2188 const struct tuntap
*tt
,
2190 const struct route_gateway_info
*rgi
,
2191 const struct env_set
*es
,
2192 openvpn_net_ctx_t
*ctx
)
2194 #if !defined(TARGET_LINUX)
2195 const char *network
;
2196 #if !defined(TARGET_AIX)
2197 const char *netmask
;
2199 #if !defined(TARGET_ANDROID)
2200 const char *gateway
;
2202 #else /* if !defined(TARGET_LINUX) */
2207 if ((r
->flags
& (RT_DEFINED
|RT_ADDED
)) != (RT_DEFINED
|RT_ADDED
))
2212 struct gc_arena gc
= gc_new();
2213 struct argv argv
= argv_new();
2215 #if !defined(TARGET_LINUX)
2216 network
= print_in_addr_t(r
->network
, 0, &gc
);
2217 #if !defined(TARGET_AIX)
2218 netmask
= print_in_addr_t(r
->netmask
, 0, &gc
);
2220 #if !defined(TARGET_ANDROID)
2221 gateway
= print_in_addr_t(r
->gateway
, 0, &gc
);
2225 is_local_route
= local_route(r
->network
, r
->netmask
, r
->gateway
, rgi
);
2226 if (is_local_route
== LR_ERROR
)
2231 #if defined(TARGET_LINUX)
2233 if (r
->flags
& RT_METRIC_DEFINED
)
2238 if (net_route_v4_del(ctx
, &r
->network
, netmask_to_netbits2(r
->netmask
),
2239 &r
->gateway
, NULL
, r
->table_id
, metric
) < 0)
2241 msg(M_WARN
, "ERROR: Linux route delete command failed");
2243 #elif defined (_WIN32)
2245 argv_printf(&argv
, "%s%s DELETE %s MASK %s %s",
2247 WIN_ROUTE_PATH_SUFFIX
,
2252 argv_msg(D_ROUTE
, &argv
);
2254 if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_SERVICE
)
2256 const bool status
= del_route_service(r
, tt
);
2257 msg(D_ROUTE
, "Route deletion via service %s", status
? "succeeded" : "failed");
2259 else if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_IPAPI
)
2261 const bool status
= del_route_ipapi(r
, tt
);
2262 msg(D_ROUTE
, "Route deletion via IPAPI %s", status
? "succeeded" : "failed");
2264 else if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_EXE
)
2266 netcmd_semaphore_lock();
2267 openvpn_execve_check(&argv
, es
, 0, "ERROR: Windows route delete command failed");
2268 netcmd_semaphore_release();
2270 else if ((flags
& ROUTE_METHOD_MASK
) == ROUTE_METHOD_ADAPTIVE
)
2272 const bool status
= del_route_ipapi(r
, tt
);
2273 msg(D_ROUTE
, "Route deletion via IPAPI %s [adaptive]", status
? "succeeded" : "failed");
2276 msg(D_ROUTE
, "Route deletion fallback to route.exe");
2277 netcmd_semaphore_lock();
2278 openvpn_execve_check(&argv
, es
, 0, "ERROR: Windows route delete command failed [adaptive]");
2279 netcmd_semaphore_release();
2287 #elif defined (TARGET_SOLARIS)
2289 argv_printf(&argv
, "%s delete %s -netmask %s %s",
2295 argv_msg(D_ROUTE
, &argv
);
2296 openvpn_execve_check(&argv
, es
, 0, "ERROR: Solaris route delete command failed");
2298 #elif defined(TARGET_FREEBSD)
2300 argv_printf(&argv
, "%s delete -net %s %s %s",
2306 argv_msg(D_ROUTE
, &argv
);
2307 openvpn_execve_check(&argv
, es
, 0, "ERROR: FreeBSD route delete command failed");
2309 #elif defined(TARGET_DRAGONFLY)
2311 argv_printf(&argv
, "%s delete -net %s %s %s",
2317 argv_msg(D_ROUTE
, &argv
);
2318 openvpn_execve_check(&argv
, es
, 0, "ERROR: DragonFly route delete command failed");
2320 #elif defined(TARGET_DARWIN)
2322 if (is_on_link(is_local_route
, flags
, rgi
))
2324 argv_printf(&argv
, "%s delete -cloning -net %s -netmask %s -interface %s",
2332 argv_printf(&argv
, "%s delete -net %s %s %s",
2339 argv_msg(D_ROUTE
, &argv
);
2340 openvpn_execve_check(&argv
, es
, 0, "ERROR: OS X route delete command failed");
2342 #elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2344 argv_printf(&argv
, "%s delete -net %s %s -netmask %s",
2350 argv_msg(D_ROUTE
, &argv
);
2351 openvpn_execve_check(&argv
, es
, 0, "ERROR: OpenBSD/NetBSD route delete command failed");
2353 #elif defined(TARGET_ANDROID)
2354 msg(D_ROUTE_DEBUG
, "Deleting routes on Android is not possible/not "
2355 "needed. The VpnService API allows routes to be set "
2356 "on connect only and will clean up automatically.");
2357 #elif defined(TARGET_AIX)
2360 int netbits
= netmask_to_netbits2(r
->netmask
);
2361 argv_printf(&argv
, "%s delete -net %s/%d %s",
2363 network
, netbits
, gateway
);
2364 argv_msg(D_ROUTE
, &argv
);
2365 openvpn_execve_check(&argv
, es
, 0, "ERROR: AIX route delete command failed");
2368 #elif defined(TARGET_HAIKU)
2370 /* ex: route delete /dev/net/ipro1000/0 inet 192.168.0.0 gw 192.168.1.1 netmask 255.255.0.0 */
2371 argv_printf(&argv
, "%s delete %s inet %s gw %s netmask %s",
2377 argv_msg(D_ROUTE
, &argv
);
2378 openvpn_execve_check(&argv
, es
, 0, "ERROR: Haiku inet route delete command failed");
2380 #else /* if defined(TARGET_LINUX) */
2381 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");
2382 #endif /* if defined(TARGET_LINUX) */
2385 r
->flags
&= ~RT_ADDED
;
2388 /* release resources potentially allocated during route cleanup */
2393 delete_route_ipv6(const struct route_ipv6
*r6
, const struct tuntap
*tt
,
2394 const struct env_set
*es
,
2395 openvpn_net_ctx_t
*ctx
)
2397 const char *network
;
2399 if ((r6
->flags
& (RT_DEFINED
|RT_ADDED
)) != (RT_DEFINED
|RT_ADDED
))
2404 #if !defined(_WIN32)
2405 #if !defined(TARGET_LINUX)
2406 const char *gateway
;
2408 #if !defined(TARGET_SOLARIS)
2409 bool gateway_needed
= false;
2410 const char *device
= tt
->actual_name
;
2411 if (r6
->iface
!= NULL
) /* vpn server special route */
2414 gateway_needed
= true;
2417 /* if we used a gateway on "add route", we also need to specify it on
2418 * delete, otherwise some OSes will refuse to delete the route
2420 if (tt
->type
== DEV_TYPE_TAP
2421 && !( (r6
->flags
& RT_METRIC_DEFINED
) && r6
->metric
== 0 ) )
2423 gateway_needed
= true;
2428 struct gc_arena gc
= gc_new();
2429 struct argv argv
= argv_new();
2431 network
= print_in6_addr( r6
->network
, 0, &gc
);
2432 #if !defined(TARGET_LINUX) && !defined(_WIN32)
2433 gateway
= print_in6_addr( r6
->gateway
, 0, &gc
);
2436 #if defined(TARGET_DARWIN) \
2437 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
2438 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2440 /* the BSD platforms cannot specify gateway and interface independently,
2441 * but for link-local destinations, we MUST specify the interface, so
2442 * we build a combined "$gateway%$interface" gateway string
2444 if (r6
->iface
!= NULL
&& gateway_needed
2445 && IN6_IS_ADDR_LINKLOCAL(&r6
->gateway
) ) /* fe80::...%intf */
2447 int len
= strlen(gateway
) + 1 + strlen(r6
->iface
)+1;
2448 char *tmp
= gc_malloc( len
, true, &gc
);
2449 snprintf( tmp
, len
, "%s%%%s", gateway
, r6
->iface
);
2454 msg(D_ROUTE
, "delete_route_ipv6(%s/%d)", network
, r6
->netbits
);
2456 #if defined(TARGET_LINUX)
2458 if ((r6
->flags
& RT_METRIC_DEFINED
) && (r6
->metric
> 0))
2460 metric
= r6
->metric
;
2463 if (net_route_v6_del(ctx
, &r6
->network
, r6
->netbits
,
2464 gateway_needed
? &r6
->gateway
: NULL
, device
, r6
->table_id
,
2467 msg(M_WARN
, "ERROR: Linux route v6 delete command failed");
2470 #elif defined (_WIN32)
2472 if (tt
->options
.msg_channel
)
2474 del_route_ipv6_service(r6
, tt
);
2478 route_ipv6_ipapi(false, r6
, tt
);
2480 #elif defined (TARGET_SOLARIS)
2482 /* example: route delete -inet6 2001:db8::/32 somegateway */
2484 argv_printf(&argv
, "%s delete -inet6 %s/%d %s",
2490 argv_msg(D_ROUTE
, &argv
);
2491 openvpn_execve_check(&argv
, es
, 0, "ERROR: Solaris route delete -inet6 command failed");
2493 #elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
2495 argv_printf(&argv
, "%s delete -inet6 %s/%d",
2502 argv_printf_cat(&argv
, "%s", gateway
);
2506 argv_printf_cat(&argv
, "-iface %s", device
);
2509 argv_msg(D_ROUTE
, &argv
);
2510 openvpn_execve_check(&argv
, es
, 0, "ERROR: *BSD route delete -inet6 command failed");
2512 #elif defined(TARGET_DARWIN)
2514 argv_printf(&argv
, "%s delete -inet6 %s -prefixlen %d",
2516 network
, r6
->netbits
);
2520 argv_printf_cat(&argv
, "%s", gateway
);
2524 argv_printf_cat(&argv
, "-iface %s", device
);
2527 argv_msg(D_ROUTE
, &argv
);
2528 openvpn_execve_check(&argv
, es
, 0, "ERROR: MacOS X route delete -inet6 command failed");
2530 #elif defined(TARGET_OPENBSD)
2532 argv_printf(&argv
, "%s delete -inet6 %s -prefixlen %d %s",
2534 network
, r6
->netbits
, gateway
);
2536 argv_msg(D_ROUTE
, &argv
);
2537 openvpn_execve_check(&argv
, es
, 0, "ERROR: OpenBSD route delete -inet6 command failed");
2539 #elif defined(TARGET_NETBSD)
2541 argv_printf(&argv
, "%s delete -inet6 %s/%d %s",
2543 network
, r6
->netbits
, gateway
);
2545 argv_msg(D_ROUTE
, &argv
);
2546 openvpn_execve_check(&argv
, es
, 0, "ERROR: NetBSD route delete -inet6 command failed");
2548 #elif defined(TARGET_AIX)
2550 argv_printf(&argv
, "%s delete -inet6 %s/%d %s",
2552 network
, r6
->netbits
, gateway
);
2553 argv_msg(D_ROUTE
, &argv
);
2554 openvpn_execve_check(&argv
, es
, 0, "ERROR: AIX route add command failed");
2556 #elif defined(TARGET_ANDROID)
2557 msg(D_ROUTE_DEBUG
, "Deleting routes on Android is not possible/not "
2558 "needed. The VpnService API allows routes to be set "
2559 "on connect only and will clean up automatically.");
2560 #elif defined(TARGET_HAIKU)
2562 /* ex: route delete /dev/net/ipro1000/0 inet6 :: gw beef::cafe prefixlen 64 */
2563 argv_printf(&argv
, "%s delete %s inet6 %s gw %s prefixlen %d",
2569 argv_msg(D_ROUTE
, &argv
);
2570 openvpn_execve_check(&argv
, es
, 0, "ERROR: Haiku inet6 route delete command failed");
2572 #else /* if defined(TARGET_LINUX) */
2573 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");
2574 #endif /* if defined(TARGET_LINUX) */
2578 /* release resources potentially allocated during route cleanup */
2583 * The --redirect-gateway option requires OS-specific code below
2584 * to get the current default gateway.
2589 static const MIB_IPFORWARDTABLE
*
2590 get_windows_routing_table(struct gc_arena
*gc
)
2593 PMIB_IPFORWARDTABLE rt
= NULL
;
2596 status
= GetIpForwardTable(NULL
, &size
, TRUE
);
2597 if (status
== ERROR_INSUFFICIENT_BUFFER
)
2599 rt
= (PMIB_IPFORWARDTABLE
) gc_malloc(size
, false, gc
);
2600 status
= GetIpForwardTable(rt
, &size
, TRUE
);
2601 if (status
!= NO_ERROR
)
2603 msg(D_ROUTE
, "NOTE: GetIpForwardTable returned error: %s (code=%u)",
2604 strerror_win32(status
, gc
),
2605 (unsigned int)status
);
2613 test_route(const IP_ADAPTER_INFO
*adapters
,
2614 const in_addr_t gateway
,
2618 DWORD i
= adapter_index_of_ip(adapters
, gateway
, &count
, NULL
);
2627 test_route_helper(bool *ret
,
2631 const IP_ADAPTER_INFO
*adapters
,
2632 const in_addr_t gateway
)
2637 c
= test_route(adapters
, gateway
, NULL
);
2653 * If we tried to add routes now, would we succeed?
2656 test_routes(const struct route_list
*rl
, const struct tuntap
*tt
)
2658 struct gc_arena gc
= gc_new();
2659 const IP_ADAPTER_INFO
*adapters
= get_adapter_info_list(&gc
);
2665 bool adapter_up
= false;
2667 if (is_adapter_up(tt
, adapters
))
2672 /* we do this test only if we have IPv4 routes to install, and if
2673 * the tun/tap interface has seen IPv4 ifconfig - because if we
2674 * have no IPv4, the check will always fail, failing tun init
2676 if (rl
&& tt
->did_ifconfig_setup
)
2678 struct route_ipv4
*r
;
2679 for (r
= rl
->routes
, len
= 0; r
; r
= r
->next
, ++len
)
2681 test_route_helper(&ret
, &count
, &good
, &ambig
, adapters
, r
->gateway
);
2684 if ((rl
->flags
& RG_ENABLE
) && (rl
->spec
.flags
& RTSA_REMOTE_ENDPOINT
))
2686 test_route_helper(&ret
, &count
, &good
, &ambig
, adapters
, rl
->spec
.remote_endpoint
);
2691 msg(D_ROUTE
, "TEST ROUTES: %d/%d succeeded len=%d ret=%d a=%d u/d=%s",
2697 adapter_up
? "up" : "down");
2703 static const MIB_IPFORWARDROW
*
2704 get_default_gateway_row(const MIB_IPFORWARDTABLE
*routes
)
2706 struct gc_arena gc
= gc_new();
2707 DWORD lowest_metric
= MAXDWORD
;
2708 const MIB_IPFORWARDROW
*ret
= NULL
;
2713 for (DWORD i
= 0; i
< routes
->dwNumEntries
; ++i
)
2715 const MIB_IPFORWARDROW
*row
= &routes
->table
[i
];
2716 const in_addr_t net
= ntohl(row
->dwForwardDest
);
2717 const in_addr_t mask
= ntohl(row
->dwForwardMask
);
2718 const DWORD index
= row
->dwForwardIfIndex
;
2719 const DWORD metric
= row
->dwForwardMetric1
;
2721 dmsg(D_ROUTE_DEBUG
, "GDGR: route[%lu] %s/%s i=%d m=%d",
2723 print_in_addr_t((in_addr_t
) net
, 0, &gc
),
2724 print_in_addr_t((in_addr_t
) mask
, 0, &gc
),
2728 if (!net
&& !mask
&& metric
< lowest_metric
)
2731 lowest_metric
= metric
;
2737 dmsg(D_ROUTE_DEBUG
, "GDGR: best=%d lm=%u", best
, (unsigned int)lowest_metric
);
2744 * @brief Determines the best route to a destination for both IPv4 and IPv6.
2746 * Uses `GetBestInterfaceEx` and `GetBestRoute2` to find the optimal route
2747 * and network interface for the specified destination address.
2749 * @param gc Pointer to struct gc_arena for internal string allocation.
2750 * @param dest The destination IP address (IPv4 or IPv6).
2751 * @param best_route Pointer to a `MIB_IPFORWARD_ROW2` structure to store the best route.
2752 * @return DWORD `NO_ERROR` on success, or an error code.
2755 get_best_route(struct gc_arena
*gc
, SOCKADDR_INET
*dest
, MIB_IPFORWARD_ROW2
*best_route
)
2757 DWORD best_if_index
;
2762 /* get the best interface index to reach dest */
2763 status
= GetBestInterfaceEx((struct sockaddr
*)dest
, &best_if_index
);
2764 if (status
!= NO_ERROR
)
2766 msg(D_ROUTE
, "NOTE: GetBestInterfaceEx returned error: %s (code=%u)",
2767 strerror_win32(status
, gc
),
2768 (unsigned int)status
);
2772 msg(D_ROUTE_DEBUG
, "GetBestInterfaceEx() returned if=%d", (int)best_if_index
);
2774 /* get the routing information (such as NextHop) for the destination and interface */
2777 SOCKADDR_INET best_src
;
2779 status
= GetBestRoute2(&luid
, best_if_index
, NULL
,
2780 dest
, 0, best_route
, &best_src
);
2781 if (status
!= NO_ERROR
)
2783 msg(D_ROUTE
, "NOTE: GetIpForwardEntry2 returned error: %s (code=%u)",
2784 strerror_win32(status
, gc
),
2785 (unsigned int)status
);
2794 get_default_gateway(struct route_gateway_info
*rgi
, in_addr_t dest
, openvpn_net_ctx_t
*ctx
)
2798 struct gc_arena gc
= gc_new();
2800 /* convert in_addr_t into SOCKADDR_INET */
2803 sa
.si_family
= AF_INET
;
2804 sa
.Ipv4
.sin_addr
.s_addr
= htonl(dest
);
2806 /* get the best route to the destination */
2807 MIB_IPFORWARD_ROW2 best_route
;
2809 DWORD status
= get_best_route(&gc
, &sa
, &best_route
);
2810 if (status
!= NO_ERROR
)
2815 rgi
->flags
= RGI_ADDR_DEFINED
| RGI_IFACE_DEFINED
;
2816 rgi
->gateway
.addr
= ntohl(best_route
.NextHop
.Ipv4
.sin_addr
.S_un
.S_addr
);
2817 rgi
->adapter_index
= best_route
.InterfaceIndex
;
2819 if (rgi
->gateway
.addr
== INADDR_ANY
)
2821 rgi
->flags
|= RGI_ON_LINK
;
2824 /* get netmask and MAC address */
2825 const IP_ADAPTER_INFO
*adapters
= get_adapter_info_list(&gc
);
2826 const IP_ADAPTER_INFO
*ai
= get_adapter(adapters
, rgi
->adapter_index
);
2829 memcpy(rgi
->hwaddr
, ai
->Address
, 6);
2830 rgi
->flags
|= RGI_HWADDR_DEFINED
;
2832 /* get netmask for non-onlink routes */
2833 in_addr_t nm
= inet_addr(ai
->IpAddressList
.IpMask
.String
);
2834 if (!(rgi
->flags
& RGI_ON_LINK
) && (nm
!= INADDR_NONE
))
2836 rgi
->gateway
.netmask
= ntohl(nm
);
2837 rgi
->flags
|= RGI_NETMASK_DEFINED
;
2846 windows_route_find_if_index(const struct route_ipv4
*r
, const struct tuntap
*tt
)
2848 struct gc_arena gc
= gc_new();
2849 DWORD ret
= TUN_ADAPTER_INDEX_INVALID
;
2851 const IP_ADAPTER_INFO
*adapters
= get_adapter_info_list(&gc
);
2852 const IP_ADAPTER_INFO
*tun_adapter
= get_tun_adapter(tt
, adapters
);
2853 bool on_tun
= false;
2855 /* first test on tun interface */
2856 if (is_ip_in_adapter_subnet(tun_adapter
, r
->gateway
, NULL
))
2858 ret
= tun_adapter
->Index
;
2862 else /* test on other interfaces */
2864 count
= test_route(adapters
, r
->gateway
, &ret
);
2869 msg(M_WARN
, "Warning: route gateway is not reachable on any active network adapters: %s",
2870 print_in_addr_t(r
->gateway
, 0, &gc
));
2871 ret
= TUN_ADAPTER_INDEX_INVALID
;
2875 msg(M_WARN
, "Warning: route gateway is ambiguous: %s (%d matches)",
2876 print_in_addr_t(r
->gateway
, 0, &gc
),
2880 dmsg(D_ROUTE_DEBUG
, "DEBUG: route find if: on_tun=%d count=%d index=%d",
2889 /* IPv6 implementation using GetBestRoute2()
2890 * (TBD: dynamic linking so the binary can still run on XP?)
2891 * https://msdn.microsoft.com/en-us/library/windows/desktop/aa365922(v=vs.85).aspx
2892 * https://msdn.microsoft.com/en-us/library/windows/desktop/aa814411(v=vs.85).aspx
2895 get_default_gateway_ipv6(struct route_ipv6_gateway_info
*rgi6
,
2896 const struct in6_addr
*dest
, openvpn_net_ctx_t
*ctx
)
2898 struct gc_arena gc
= gc_new();
2901 SOCKADDR_INET DestinationAddress
;
2902 CLEAR(DestinationAddress
);
2903 DestinationAddress
.si_family
= AF_INET6
;
2906 DestinationAddress
.Ipv6
.sin6_addr
= *dest
;
2909 MIB_IPFORWARD_ROW2 BestRoute
;
2911 DWORD status
= get_best_route(&gc
, &DestinationAddress
, &BestRoute
);
2913 if (status
!= NO_ERROR
)
2918 msg( D_ROUTE
, "GDG6: II=%lu DP=%s/%d NH=%s",
2919 BestRoute
.InterfaceIndex
,
2920 print_in6_addr( BestRoute
.DestinationPrefix
.Prefix
.Ipv6
.sin6_addr
, 0, &gc
),
2921 BestRoute
.DestinationPrefix
.PrefixLength
,
2922 print_in6_addr( BestRoute
.NextHop
.Ipv6
.sin6_addr
, 0, &gc
) );
2923 msg( D_ROUTE
, "GDG6: Metric=%d, Loopback=%d, AA=%d, I=%d",
2924 (int) BestRoute
.Metric
,
2925 (int) BestRoute
.Loopback
,
2926 (int) BestRoute
.AutoconfigureAddress
,
2927 (int) BestRoute
.Immortal
);
2929 rgi6
->gateway
.addr_ipv6
= BestRoute
.NextHop
.Ipv6
.sin6_addr
;
2930 rgi6
->adapter_index
= BestRoute
.InterfaceIndex
;
2931 rgi6
->flags
|= RGI_ADDR_DEFINED
| RGI_IFACE_DEFINED
;
2933 /* on-link is signalled by receiving an empty (::) NextHop */
2934 if (IN6_IS_ADDR_UNSPECIFIED(&BestRoute
.NextHop
.Ipv6
.sin6_addr
) )
2936 rgi6
->flags
|= RGI_ON_LINK
;
2943 /* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
2945 add_route_ipapi(const struct route_ipv4
*r
, const struct tuntap
*tt
, DWORD adapter_index
)
2947 struct gc_arena gc
= gc_new();
2948 int ret
= RTA_ERROR
;
2950 const DWORD if_index
= (adapter_index
== TUN_ADAPTER_INDEX_INVALID
) ? windows_route_find_if_index(r
, tt
) : adapter_index
;
2952 if (if_index
!= TUN_ADAPTER_INDEX_INVALID
)
2954 MIB_IPFORWARDROW fr
;
2956 fr
.dwForwardDest
= htonl(r
->network
);
2957 fr
.dwForwardMask
= htonl(r
->netmask
);
2958 fr
.dwForwardPolicy
= 0;
2959 fr
.dwForwardNextHop
= htonl(r
->gateway
);
2960 fr
.dwForwardIfIndex
= if_index
;
2961 fr
.dwForwardType
= 4; /* the next hop is not the final dest */
2962 fr
.dwForwardProto
= 3; /* PROTO_IP_NETMGMT */
2963 fr
.dwForwardAge
= 0;
2964 fr
.dwForwardNextHopAS
= 0;
2965 fr
.dwForwardMetric1
= (r
->flags
& RT_METRIC_DEFINED
) ? r
->metric
: 1;
2966 fr
.dwForwardMetric2
= METRIC_NOT_USED
;
2967 fr
.dwForwardMetric3
= METRIC_NOT_USED
;
2968 fr
.dwForwardMetric4
= METRIC_NOT_USED
;
2969 fr
.dwForwardMetric5
= METRIC_NOT_USED
;
2971 if ((r
->network
& r
->netmask
) != r
->network
)
2973 msg(M_WARN
, "Warning: address %s is not a network address in relation to netmask %s",
2974 print_in_addr_t(r
->network
, 0, &gc
),
2975 print_in_addr_t(r
->netmask
, 0, &gc
));
2978 status
= CreateIpForwardEntry(&fr
);
2980 if (status
== NO_ERROR
)
2984 else if (status
== ERROR_OBJECT_ALREADY_EXISTS
)
2990 /* failed, try increasing the metric to work around Vista issue */
2991 const unsigned int forward_metric_limit
= 2048; /* iteratively retry higher metrics up to this limit */
2993 for (; fr
.dwForwardMetric1
<= forward_metric_limit
; ++fr
.dwForwardMetric1
)
2995 /* try a different forward type=3 ("the next hop is the final dest") in addition to 4.
2996 * --redirect-gateway over RRAS seems to need this. */
2997 for (fr
.dwForwardType
= 4; fr
.dwForwardType
>= 3; --fr
.dwForwardType
)
2999 status
= CreateIpForwardEntry(&fr
);
3000 if (status
== NO_ERROR
)
3002 msg(D_ROUTE
, "ROUTE: CreateIpForwardEntry succeeded with dwForwardMetric1=%u and dwForwardType=%u",
3003 (unsigned int)fr
.dwForwardMetric1
,
3004 (unsigned int)fr
.dwForwardType
);
3008 else if (status
!= ERROR_BAD_ARGUMENTS
)
3016 if (status
!= NO_ERROR
)
3018 if (status
== ERROR_OBJECT_ALREADY_EXISTS
)
3024 msg(M_WARN
, "ERROR: route addition failed using CreateIpForwardEntry: "
3025 "%s [status=%u if_index=%u]", strerror_win32(status
, &gc
),
3026 (unsigned int)status
, (unsigned int)if_index
);
3037 del_route_ipapi(const struct route_ipv4
*r
, const struct tuntap
*tt
)
3039 struct gc_arena gc
= gc_new();
3042 const DWORD if_index
= windows_route_find_if_index(r
, tt
);
3044 if (if_index
!= TUN_ADAPTER_INDEX_INVALID
)
3046 MIB_IPFORWARDROW fr
;
3049 fr
.dwForwardDest
= htonl(r
->network
);
3050 fr
.dwForwardMask
= htonl(r
->netmask
);
3051 fr
.dwForwardPolicy
= 0;
3052 fr
.dwForwardNextHop
= htonl(r
->gateway
);
3053 fr
.dwForwardIfIndex
= if_index
;
3055 status
= DeleteIpForwardEntry(&fr
);
3057 if (status
== NO_ERROR
)
3063 msg(M_WARN
, "ERROR: route deletion failed using DeleteIpForwardEntry: %s",
3064 strerror_win32(status
, &gc
));
3072 /* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
3074 do_route_service(const bool add
, const route_message_t
*rt
, const size_t size
, HANDLE pipe
)
3076 int ret
= RTA_ERROR
;
3078 struct gc_arena gc
= gc_new();
3080 if (!send_msg_iservice(pipe
, rt
, size
, &ack
, "ROUTE"))
3085 if (ack
.error_number
!= NO_ERROR
)
3087 ret
= (ack
.error_number
== ERROR_OBJECT_ALREADY_EXISTS
) ? RTA_EEXIST
: RTA_ERROR
;
3088 if (ret
== RTA_ERROR
)
3090 msg(M_WARN
, "ERROR: route %s failed using service: %s [status=%u if_index=%d]",
3091 (add
? "addition" : "deletion"), strerror_win32(ack
.error_number
, &gc
),
3092 ack
.error_number
, rt
->iface
.index
);
3104 /* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
3106 do_route_ipv4_service(const bool add
, const struct route_ipv4
*r
, const struct tuntap
*tt
)
3108 DWORD if_index
= windows_route_find_if_index(r
, tt
);
3114 route_message_t msg
= {
3116 (add
? msg_add_route
: msg_del_route
),
3117 sizeof(route_message_t
),
3121 .prefix
.ipv4
.s_addr
= htonl(r
->network
),
3122 .gateway
.ipv4
.s_addr
= htonl(r
->gateway
),
3123 .iface
= { .index
= if_index
, .name
= "" },
3124 .metric
= (r
->flags
& RT_METRIC_DEFINED
? r
->metric
: -1)
3127 netmask_to_netbits(r
->network
, r
->netmask
, &msg
.prefix_len
);
3128 if (msg
.prefix_len
== -1)
3130 msg
.prefix_len
= 32;
3133 return do_route_service(add
, &msg
, sizeof(msg
), tt
->options
.msg_channel
);
3136 /* Add or delete an ipv6 route
3137 * Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error
3140 route_ipv6_ipapi(const bool add
, const struct route_ipv6
*r
, const struct tuntap
*tt
)
3143 int ret
= RTA_ERROR
;
3144 PMIB_IPFORWARD_ROW2 fwd_row
;
3145 struct gc_arena gc
= gc_new();
3147 fwd_row
= gc_malloc(sizeof(*fwd_row
), true, &gc
);
3149 fwd_row
->ValidLifetime
= 0xffffffff;
3150 fwd_row
->PreferredLifetime
= 0xffffffff;
3151 fwd_row
->Protocol
= MIB_IPPROTO_NETMGMT
;
3152 fwd_row
->Metric
= ((r
->flags
& RT_METRIC_DEFINED
) ? r
->metric
: -1);
3153 fwd_row
->DestinationPrefix
.Prefix
.si_family
= AF_INET6
;
3154 fwd_row
->DestinationPrefix
.Prefix
.Ipv6
.sin6_addr
= r
->network
;
3155 fwd_row
->DestinationPrefix
.PrefixLength
= (UINT8
) r
->netbits
;
3156 fwd_row
->NextHop
.si_family
= AF_INET6
;
3157 fwd_row
->NextHop
.Ipv6
.sin6_addr
= r
->gateway
;
3158 fwd_row
->InterfaceIndex
= r
->adapter_index
? r
->adapter_index
: tt
->adapter_index
;
3160 /* In TUN mode we use a special link-local address as the next hop.
3161 * The tapdrvr knows about it and will answer neighbor discovery packets.
3162 * (only do this for routes actually using the tun/tap device)
3164 if (tt
->type
== DEV_TYPE_TUN
&& !r
->adapter_index
)
3166 inet_pton(AF_INET6
, "fe80::8", &fwd_row
->NextHop
.Ipv6
.sin6_addr
);
3169 /* Use LUID if interface index not available */
3170 if (fwd_row
->InterfaceIndex
== TUN_ADAPTER_INDEX_INVALID
&& strlen(tt
->actual_name
))
3173 err
= ConvertInterfaceAliasToLuid(wide_string(tt
->actual_name
, &gc
), &luid
);
3174 if (err
!= NO_ERROR
)
3178 fwd_row
->InterfaceLuid
= luid
;
3179 fwd_row
->InterfaceIndex
= 0;
3184 err
= CreateIpForwardEntry2(fwd_row
);
3188 err
= DeleteIpForwardEntry2(fwd_row
);
3192 if (err
!= NO_ERROR
)
3194 ret
= (err
== ERROR_OBJECT_ALREADY_EXISTS
) ? RTA_EEXIST
: RTA_ERROR
;
3195 if (ret
== RTA_ERROR
)
3197 msg(M_WARN
, "ERROR: route %s failed using ipapi: %s [status=%lu if_index=%lu]",
3198 (add
? "addition" : "deletion"), strerror_win32(err
, &gc
), err
,
3199 fwd_row
->InterfaceIndex
);
3203 msg(D_ROUTE
, "IPv6 route addition using ipapi failed because route exists");
3208 msg(D_ROUTE
, "IPv6 route %s using ipapi", add
? "added" : "deleted");
3215 /* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
3217 do_route_ipv6_service(const bool add
, const struct route_ipv6
*r
, const struct tuntap
*tt
)
3220 route_message_t msg
= {
3222 (add
? msg_add_route
: msg_del_route
),
3223 sizeof(route_message_t
),
3227 .prefix
.ipv6
= r
->network
,
3228 .prefix_len
= r
->netbits
,
3229 .gateway
.ipv6
= r
->gateway
,
3230 .iface
= { .index
= tt
->adapter_index
, .name
= "" },
3231 .metric
= ( (r
->flags
& RT_METRIC_DEFINED
) ? r
->metric
: -1)
3234 if (r
->adapter_index
) /* vpn server special route */
3236 msg
.iface
.index
= r
->adapter_index
;
3239 /* In TUN mode we use a special link-local address as the next hop.
3240 * The tapdrvr knows about it and will answer neighbor discovery packets.
3241 * (only do this for routes actually using the tun/tap device)
3243 if (tt
->type
== DEV_TYPE_TUN
3244 && msg
.iface
.index
== tt
->adapter_index
)
3246 inet_pton(AF_INET6
, "fe80::8", &msg
.gateway
.ipv6
);
3249 if (msg
.iface
.index
== TUN_ADAPTER_INDEX_INVALID
)
3251 strncpy(msg
.iface
.name
, tt
->actual_name
, sizeof(msg
.iface
.name
));
3252 msg
.iface
.name
[sizeof(msg
.iface
.name
) - 1] = '\0';
3255 status
= do_route_service(add
, &msg
, sizeof(msg
), tt
->options
.msg_channel
);
3256 if (status
!= RTA_ERROR
)
3258 msg(D_ROUTE
, "IPv6 route %s via service %s",
3259 add
? "addition" : "deletion",
3260 (status
== RTA_SUCCESS
) ? "succeeded" : "failed because route exists");
3265 /* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
3267 add_route_service(const struct route_ipv4
*r
, const struct tuntap
*tt
)
3269 return do_route_ipv4_service(true, r
, tt
);
3273 del_route_service(const struct route_ipv4
*r
, const struct tuntap
*tt
)
3275 return do_route_ipv4_service(false, r
, tt
);
3278 /* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
3280 add_route_ipv6_service(const struct route_ipv6
*r
, const struct tuntap
*tt
)
3282 return do_route_ipv6_service(true, r
, tt
);
3286 del_route_ipv6_service(const struct route_ipv6
*r
, const struct tuntap
*tt
)
3288 return do_route_ipv6_service(false, r
, tt
);
3292 format_route_entry(const MIB_IPFORWARDROW
*r
, struct gc_arena
*gc
)
3294 struct buffer out
= alloc_buf_gc(256, gc
);
3295 buf_printf(&out
, "%s %s %s p=%d i=%d t=%d pr=%d a=%d h=%d m=%d/%d/%d/%d/%d",
3296 print_in_addr_t(r
->dwForwardDest
, IA_NET_ORDER
, gc
),
3297 print_in_addr_t(r
->dwForwardMask
, IA_NET_ORDER
, gc
),
3298 print_in_addr_t(r
->dwForwardNextHop
, IA_NET_ORDER
, gc
),
3299 (int)r
->dwForwardPolicy
,
3300 (int)r
->dwForwardIfIndex
,
3301 (int)r
->dwForwardType
,
3302 (int)r
->dwForwardProto
,
3303 (int)r
->dwForwardAge
,
3304 (int)r
->dwForwardNextHopAS
,
3305 (int)r
->dwForwardMetric1
,
3306 (int)r
->dwForwardMetric2
,
3307 (int)r
->dwForwardMetric3
,
3308 (int)r
->dwForwardMetric4
,
3309 (int)r
->dwForwardMetric5
);
3314 * Show current routing table
3317 show_routes(int msglev
)
3319 struct gc_arena gc
= gc_new();
3321 const MIB_IPFORWARDTABLE
*rt
= get_windows_routing_table(&gc
);
3323 msg(msglev
, "SYSTEM ROUTING TABLE");
3326 for (DWORD i
= 0; i
< rt
->dwNumEntries
; ++i
)
3328 msg(msglev
, "%s", format_route_entry(&rt
->table
[i
], &gc
));
3334 #elif defined(TARGET_ANDROID)
3337 get_default_gateway(struct route_gateway_info
*rgi
, in_addr_t dest
, openvpn_net_ctx_t
*ctx
)
3339 /* Android, set some pseudo GW, addr is in host byte order,
3340 * Determining the default GW on Android 5.0+ is non trivial
3341 * and serves almost no purpose since OpenVPN only uses the
3342 * default GW address to add routes for networks that should
3343 * NOT be routed over the VPN. Using a well known address
3344 * (127.'d'.'g'.'w') for the default GW make detecting
3345 * these routes easier from the controlling app.
3349 rgi
->gateway
.addr
= 127 << 24 | 'd' << 16 | 'g' << 8 | 'w';
3350 rgi
->flags
= RGI_ADDR_DEFINED
| RGI_IFACE_DEFINED
;
3351 strcpy(rgi
->iface
, "android-gw");
3353 /* Skip scanning/fetching interface from loopback interface we do
3354 * normally on Linux.
3355 * It always fails and "ioctl(SIOCGIFCONF) failed" confuses users
3361 get_default_gateway_ipv6(struct route_ipv6_gateway_info
*rgi6
,
3362 const struct in6_addr
*dest
, openvpn_net_ctx_t
*ctx
)
3368 /* Use a fake link-local address */
3369 ASSERT(inet_pton(AF_INET6
, "fe80::ad", &rgi6
->addrs
->addr_ipv6
) == 1);
3370 rgi6
->addrs
->netbits_ipv6
= 64;
3371 rgi6
->flags
= RGI_ADDR_DEFINED
| RGI_IFACE_DEFINED
;
3372 strcpy(rgi6
->iface
, "android-gw");
3375 #elif defined(TARGET_LINUX)
3378 get_default_gateway(struct route_gateway_info
*rgi
, in_addr_t dest
, openvpn_net_ctx_t
*ctx
)
3380 struct gc_arena gc
= gc_new();
3382 char best_name
[IFNAMSIZ
];
3387 /* find best route to 'dest', get gateway IP addr + interface */
3388 if (net_route_v4_best_gw(ctx
, &dest
, &rgi
->gateway
.addr
, best_name
) == 0)
3390 rgi
->flags
|= RGI_ADDR_DEFINED
;
3391 if (!rgi
->gateway
.addr
&& best_name
[0])
3393 rgi
->flags
|= RGI_ON_LINK
;
3397 /* scan adapter list */
3398 if (rgi
->flags
& RGI_ADDR_DEFINED
)
3400 struct ifreq
*ifr
, *ifend
;
3401 in_addr_t addr
, netmask
;
3404 struct ifreq ifs
[20]; /* Maximum number of interfaces to scan */
3406 if ((sd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0)
3408 msg(M_WARN
, "GDG: socket() failed");
3411 ifc
.ifc_len
= sizeof(ifs
);
3413 if (ioctl(sd
, SIOCGIFCONF
, &ifc
) < 0)
3415 msg(M_WARN
, "GDG: ioctl(SIOCGIFCONF) failed");
3419 /* scan through interface list */
3420 ifend
= ifs
+ (ifc
.ifc_len
/ sizeof(struct ifreq
));
3421 for (ifr
= ifc
.ifc_req
; ifr
< ifend
; ifr
++)
3423 if (ifr
->ifr_addr
.sa_family
== AF_INET
)
3425 /* get interface addr */
3426 addr
= ntohl(((struct sockaddr_in
*) &ifr
->ifr_addr
)->sin_addr
.s_addr
);
3428 /* get interface name */
3429 strncpynt(ifreq
.ifr_name
, ifr
->ifr_name
, sizeof(ifreq
.ifr_name
));
3431 /* check that the interface is up */
3432 if (ioctl(sd
, SIOCGIFFLAGS
, &ifreq
) < 0)
3436 if (!(ifreq
.ifr_flags
& IFF_UP
))
3441 if (rgi
->flags
& RGI_ON_LINK
)
3443 /* check that interface name of current interface
3444 * matches interface name of best default route */
3445 if (strcmp(ifreq
.ifr_name
, best_name
))
3450 /* if point-to-point link, use remote addr as route gateway */
3451 if ((ifreq
.ifr_flags
& IFF_POINTOPOINT
) && ioctl(sd
, SIOCGIFDSTADDR
, &ifreq
) >= 0)
3453 rgi
->gateway
.addr
= ntohl(((struct sockaddr_in
*) &ifreq
.ifr_addr
)->sin_addr
.s_addr
);
3454 if (rgi
->gateway
.addr
)
3456 rgi
->flags
&= ~RGI_ON_LINK
;
3463 /* get interface netmask */
3464 if (ioctl(sd
, SIOCGIFNETMASK
, &ifreq
) < 0)
3468 netmask
= ntohl(((struct sockaddr_in
*) &ifreq
.ifr_addr
)->sin_addr
.s_addr
);
3470 /* check that interface matches default route */
3471 if (((rgi
->gateway
.addr
^ addr
) & netmask
) != 0)
3477 rgi
->gateway
.netmask
= netmask
;
3478 rgi
->flags
|= RGI_NETMASK_DEFINED
;
3481 /* save iface name */
3482 strncpynt(rgi
->iface
, ifreq
.ifr_name
, sizeof(rgi
->iface
));
3483 rgi
->flags
|= RGI_IFACE_DEFINED
;
3485 /* now get the hardware address. */
3486 memset(&ifreq
.ifr_hwaddr
, 0, sizeof(struct sockaddr
));
3487 if (ioctl(sd
, SIOCGIFHWADDR
, &ifreq
) < 0)
3489 msg(M_WARN
, "GDG: SIOCGIFHWADDR(%s) failed", ifreq
.ifr_name
);
3492 memcpy(rgi
->hwaddr
, &ifreq
.ifr_hwaddr
.sa_data
, 6);
3493 rgi
->flags
|= RGI_HWADDR_DEFINED
;
3508 /* IPv6 implementation using netlink
3509 * http://www.linuxjournal.com/article/7356
3510 * netlink(3), netlink(7), rtnetlink(7)
3511 * http://www.virtualbox.org/svn/vbox/trunk/src/VBox/NetworkServices/NAT/rtmon_linux.c
3520 get_default_gateway_ipv6(struct route_ipv6_gateway_info
*rgi6
,
3521 const struct in6_addr
*dest
, openvpn_net_ctx_t
*ctx
)
3527 if (net_route_v6_best_gw(ctx
, dest
, &rgi6
->gateway
.addr_ipv6
,
3530 if (!IN6_IS_ADDR_UNSPECIFIED(&rgi6
->gateway
.addr_ipv6
))
3532 rgi6
->flags
|= RGI_ADDR_DEFINED
;
3535 if (strlen(rgi6
->iface
) > 0)
3537 rgi6
->flags
|= RGI_IFACE_DEFINED
;
3541 /* if we have an interface but no gateway, the destination is on-link */
3542 flags
= rgi6
->flags
& (RGI_IFACE_DEFINED
| RGI_ADDR_DEFINED
);
3543 if (flags
== RGI_IFACE_DEFINED
)
3545 rgi6
->flags
|= (RGI_ADDR_DEFINED
| RGI_ON_LINK
);
3548 rgi6
->gateway
.addr_ipv6
= *dest
;
3553 #elif defined(TARGET_DARWIN) || defined(TARGET_SOLARIS) \
3554 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
3555 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
3557 #include <sys/types.h>
3558 #include <sys/socket.h>
3559 #include <netinet/in.h>
3560 #include <net/route.h>
3561 #include <net/if_dl.h>
3562 #if !defined(TARGET_SOLARIS)
3563 #include <ifaddrs.h>
3567 struct rt_msghdr m_rtm
;
3571 /* the route socket code is identical for all 4 supported BSDs and for
3572 * MacOS X (Darwin), with one crucial difference: when going from
3573 * 32 bit to 64 bit, FreeBSD/OpenBSD increased the structure size but kept
3574 * source code compatibility by keeping the use of "long", while
3575 * MacOS X decided to keep binary compatibility by *changing* the API
3576 * to use "uint32_t", thus 32 bit on all OS X variants
3578 * NetBSD does the MacOS way of "fixed number of bits, no matter if
3579 * 32 or 64 bit OS", but chose uint64_t. For maximum portability, we
3580 * just use the OS RT_ROUNDUP() macro, which is guaranteed to be correct.
3582 * We used to have a large amount of duplicate code here which really
3583 * differed only in this (long) vs. (uint32_t) - IMHO, worse than
3584 * having a combined block for all BSDs with this single #ifdef inside
3587 #if defined(TARGET_DARWIN)
3588 #define ROUNDUP(a) \
3589 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
3590 #elif defined(TARGET_NETBSD)
3591 #define ROUNDUP(a) RT_ROUNDUP(a)
3593 #define ROUNDUP(a) \
3594 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
3597 #if defined(TARGET_SOLARIS)
3598 #define NEXTADDR(w, u) \
3599 if (rtm_addrs & (w)) { \
3600 l = sizeof(u); memmove(cp, &(u), l); cp += ROUNDUP(l); \
3603 #define ADVANCE(x, n) (x += ROUNDUP(sizeof(struct sockaddr_in)))
3604 #else /* if defined(TARGET_SOLARIS) */
3605 #define NEXTADDR(w, u) \
3606 if (rtm_addrs & (w)) { \
3607 l = ((struct sockaddr *)&(u))->sa_len; memmove(cp, &(u), l); cp += ROUNDUP(l); \
3610 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
3613 #define max(a, b) ((a) > (b) ? (a) : (b))
3616 get_default_gateway(struct route_gateway_info
*rgi
, in_addr_t dest
, openvpn_net_ctx_t
*ctx
)
3618 struct gc_arena gc
= gc_new();
3619 struct rtmsg m_rtmsg
;
3621 int seq
, l
, pid
, rtm_addrs
;
3623 struct sockaddr so_dst
, so_mask
;
3624 char *cp
= m_rtmsg
.m_space
;
3625 struct sockaddr
*gate
= NULL
, *ifp
= NULL
, *sa
;
3626 struct rt_msghdr
*rtm_aux
;
3628 #define rtm m_rtmsg.m_rtm
3632 /* setup data to send to routing socket */
3635 #ifdef TARGET_OPENBSD
3636 rtm_addrs
= RTA_DST
| RTA_NETMASK
; /* Kernel refuses RTA_IFP */
3638 rtm_addrs
= RTA_DST
| RTA_NETMASK
| RTA_IFP
;
3641 bzero(&m_rtmsg
, sizeof(m_rtmsg
));
3642 bzero(&so_dst
, sizeof(so_dst
));
3643 bzero(&so_mask
, sizeof(so_mask
));
3644 bzero(&rtm
, sizeof(struct rt_msghdr
));
3646 rtm
.rtm_type
= RTM_GET
;
3647 rtm
.rtm_flags
= RTF_UP
| RTF_GATEWAY
;
3648 rtm
.rtm_version
= RTM_VERSION
;
3649 rtm
.rtm_seq
= ++seq
;
3650 #ifdef TARGET_OPENBSD
3651 rtm
.rtm_tableid
= getrtable();
3653 rtm
.rtm_addrs
= rtm_addrs
;
3655 so_dst
.sa_family
= AF_INET
;
3656 so_mask
.sa_family
= AF_INET
;
3658 #ifndef TARGET_SOLARIS
3659 so_dst
.sa_len
= sizeof(struct sockaddr_in
);
3660 so_mask
.sa_len
= sizeof(struct sockaddr_in
);
3663 NEXTADDR(RTA_DST
, so_dst
);
3664 NEXTADDR(RTA_NETMASK
, so_mask
);
3666 rtm
.rtm_msglen
= l
= cp
- (char *)&m_rtmsg
;
3668 /* transact with routing socket */
3669 sockfd
= socket(PF_ROUTE
, SOCK_RAW
, 0);
3672 msg(M_WARN
, "GDG: socket #1 failed");
3675 if (write(sockfd
, (char *)&m_rtmsg
, l
) < 0)
3677 msg(M_WARN
|M_ERRNO
, "GDG: problem writing to routing socket");
3682 l
= read(sockfd
, (char *)&m_rtmsg
, sizeof(m_rtmsg
));
3683 } while (l
> 0 && (rtm
.rtm_seq
!= seq
|| rtm
.rtm_pid
!= pid
));
3687 /* extract return data from routing socket */
3689 cp
= ((char *)(rtm_aux
+ 1));
3690 if (rtm_aux
->rtm_addrs
)
3692 for (i
= 1; i
; i
<<= 1)
3694 if (i
& rtm_aux
->rtm_addrs
)
3696 sa
= (struct sockaddr
*)cp
;
3697 if (i
== RTA_GATEWAY
)
3701 else if (i
== RTA_IFP
)
3714 /* get gateway addr and interface name */
3717 /* get default gateway addr */
3718 rgi
->gateway
.addr
= ntohl(((struct sockaddr_in
*)gate
)->sin_addr
.s_addr
);
3719 if (rgi
->gateway
.addr
)
3721 rgi
->flags
|= RGI_ADDR_DEFINED
;
3726 /* get interface name */
3727 const struct sockaddr_dl
*adl
= (struct sockaddr_dl
*) ifp
;
3728 if (adl
->sdl_nlen
&& adl
->sdl_nlen
< sizeof(rgi
->iface
))
3730 memcpy(rgi
->iface
, adl
->sdl_data
, adl
->sdl_nlen
);
3731 rgi
->iface
[adl
->sdl_nlen
] = '\0';
3732 rgi
->flags
|= RGI_IFACE_DEFINED
;
3737 /* get netmask of interface that owns default gateway */
3738 if (rgi
->flags
& RGI_IFACE_DEFINED
)
3742 sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
3745 msg(M_WARN
, "GDG: socket #2 failed");
3750 ifr
.ifr_addr
.sa_family
= AF_INET
;
3751 strncpynt(ifr
.ifr_name
, rgi
->iface
, IFNAMSIZ
);
3753 if (ioctl(sockfd
, SIOCGIFNETMASK
, (char *)&ifr
) < 0)
3755 msg(M_WARN
, "GDG: ioctl #1 failed");
3761 rgi
->gateway
.netmask
= ntohl(((struct sockaddr_in
*)&ifr
.ifr_addr
)->sin_addr
.s_addr
);
3762 rgi
->flags
|= RGI_NETMASK_DEFINED
;
3765 /* try to read MAC addr associated with interface that owns default gateway */
3766 if (rgi
->flags
& RGI_IFACE_DEFINED
)
3768 #if defined(TARGET_SOLARIS)
3769 /* OpenSolaris has getifaddrs(3), but it does not return AF_LINK */
3770 sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
3773 msg(M_WARN
, "GDG: socket #3 failed");
3777 struct ifreq ifreq
= { 0 };
3779 /* now get the hardware address. */
3780 strncpynt(ifreq
.ifr_name
, rgi
->iface
, sizeof(ifreq
.ifr_name
));
3781 if (ioctl(sockfd
, SIOCGIFHWADDR
, &ifreq
) < 0)
3783 msg(M_WARN
, "GDG: SIOCGIFHWADDR(%s) failed", ifreq
.ifr_name
);
3787 memcpy(rgi
->hwaddr
, &ifreq
.ifr_addr
.sa_data
, 6);
3788 rgi
->flags
|= RGI_HWADDR_DEFINED
;
3790 #else /* if defined(TARGET_SOLARIS) */
3791 struct ifaddrs
*ifap
, *ifa
;
3793 if (getifaddrs(&ifap
) != 0)
3795 msg(M_WARN
|M_ERRNO
, "GDG: getifaddrs() failed");
3799 for (ifa
= ifap
; ifa
; ifa
= ifa
->ifa_next
)
3801 if (ifa
->ifa_addr
!= NULL
3802 && ifa
->ifa_addr
->sa_family
== AF_LINK
3803 && !strncmp(ifa
->ifa_name
, rgi
->iface
, IFNAMSIZ
) )
3805 struct sockaddr_dl
*sdl
= (struct sockaddr_dl
*)ifa
->ifa_addr
;
3806 memcpy(rgi
->hwaddr
, LLADDR(sdl
), 6);
3807 rgi
->flags
|= RGI_HWADDR_DEFINED
;
3812 #endif /* if defined(TARGET_SOLARIS) */
3823 /* BSD implementation using routing socket (as does IPv4)
3824 * (the code duplication is somewhat unavoidable if we want this to
3825 * work on OpenSolaris as well. *sigh*)
3828 /* Solaris has no length field - this is ugly, but less #ifdef in total
3830 #if defined(TARGET_SOLARIS)
3832 #define ADVANCE(x, n) (x += ROUNDUP(sizeof(struct sockaddr_in6)))
3836 get_default_gateway_ipv6(struct route_ipv6_gateway_info
*rgi6
,
3837 const struct in6_addr
*dest
, openvpn_net_ctx_t
*ctx
)
3840 struct rtmsg m_rtmsg
;
3842 int seq
, l
, pid
, rtm_addrs
;
3844 struct sockaddr_in6 so_dst
, so_mask
;
3845 char *cp
= m_rtmsg
.m_space
;
3846 struct sockaddr
*gate
= NULL
, *ifp
= NULL
, *sa
;
3847 struct rt_msghdr
*rtm_aux
;
3851 /* setup data to send to routing socket */
3854 #ifdef TARGET_OPENBSD
3855 rtm_addrs
= RTA_DST
| RTA_NETMASK
; /* Kernel refuses RTA_IFP */
3857 rtm_addrs
= RTA_DST
| RTA_NETMASK
| RTA_IFP
;
3860 bzero(&m_rtmsg
, sizeof(m_rtmsg
));
3861 bzero(&so_dst
, sizeof(so_dst
));
3862 bzero(&so_mask
, sizeof(so_mask
));
3863 bzero(&rtm
, sizeof(struct rt_msghdr
));
3865 rtm
.rtm_type
= RTM_GET
;
3866 rtm
.rtm_flags
= RTF_UP
;
3867 rtm
.rtm_version
= RTM_VERSION
;
3868 rtm
.rtm_seq
= ++seq
;
3869 #ifdef TARGET_OPENBSD
3870 rtm
.rtm_tableid
= getrtable();
3873 so_dst
.sin6_family
= AF_INET6
;
3874 so_mask
.sin6_family
= AF_INET6
;
3876 if (dest
!= NULL
/* specific host? */
3877 && !IN6_IS_ADDR_UNSPECIFIED(dest
) )
3879 so_dst
.sin6_addr
= *dest
;
3880 /* :: needs /0 "netmask", host route wants "no netmask */
3881 rtm_addrs
&= ~RTA_NETMASK
;
3884 rtm
.rtm_addrs
= rtm_addrs
;
3886 #ifndef TARGET_SOLARIS
3887 so_dst
.sin6_len
= sizeof(struct sockaddr_in6
);
3888 so_mask
.sin6_len
= sizeof(struct sockaddr_in6
);
3891 NEXTADDR(RTA_DST
, so_dst
);
3892 NEXTADDR(RTA_NETMASK
, so_mask
);
3894 rtm
.rtm_msglen
= l
= cp
- (char *)&m_rtmsg
;
3896 /* transact with routing socket */
3897 sockfd
= socket(PF_ROUTE
, SOCK_RAW
, 0);
3900 msg(M_WARN
, "GDG6: socket #1 failed");
3903 if (write(sockfd
, (char *)&m_rtmsg
, l
) < 0)
3905 msg(M_WARN
|M_ERRNO
, "GDG6: problem writing to routing socket");
3911 l
= read(sockfd
, (char *)&m_rtmsg
, sizeof(m_rtmsg
));
3913 while (l
> 0 && (rtm
.rtm_seq
!= seq
|| rtm
.rtm_pid
!= pid
));
3918 /* extract return data from routing socket */
3920 cp
= ((char *)(rtm_aux
+ 1));
3921 if (rtm_aux
->rtm_addrs
)
3923 for (i
= 1; i
; i
<<= 1)
3925 if (i
& rtm_aux
->rtm_addrs
)
3927 sa
= (struct sockaddr
*)cp
;
3928 if (i
== RTA_GATEWAY
)
3932 else if (i
== RTA_IFP
)
3945 /* get gateway addr and interface name */
3948 struct sockaddr_in6
*s6
= (struct sockaddr_in6
*)gate
;
3949 struct in6_addr gw
= s6
->sin6_addr
;
3951 #ifndef TARGET_SOLARIS
3952 /* You do not really want to know... from FreeBSD's route.c
3953 * (KAME encodes the 16 bit scope_id in s6_addr[2] + [3],
3954 * but for a correct link-local address these must be :0000: )
3956 if (gate
->sa_len
== sizeof(struct sockaddr_in6
)
3957 && IN6_IS_ADDR_LINKLOCAL(&gw
) )
3959 gw
.s6_addr
[2] = gw
.s6_addr
[3] = 0;
3962 if (gate
->sa_len
!= sizeof(struct sockaddr_in6
)
3963 || IN6_IS_ADDR_UNSPECIFIED(&gw
) )
3965 rgi6
->flags
|= RGI_ON_LINK
;
3970 rgi6
->gateway
.addr_ipv6
= gw
;
3972 rgi6
->flags
|= RGI_ADDR_DEFINED
;
3976 /* get interface name */
3977 const struct sockaddr_dl
*adl
= (struct sockaddr_dl
*) ifp
;
3978 if (adl
->sdl_nlen
&& adl
->sdl_nlen
< sizeof(rgi6
->iface
))
3980 memcpy(rgi6
->iface
, adl
->sdl_data
, adl
->sdl_nlen
);
3981 rgi6
->flags
|= RGI_IFACE_DEFINED
;
3995 #elif defined(TARGET_HAIKU)
3998 get_default_gateway(struct route_gateway_info
*rgi
, in_addr_t dest
, openvpn_net_ctx_t
*ctx
)
4002 int sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
4005 msg(M_ERRNO
, "%s: Error opening socket for AF_INET", __func__
);
4009 struct ifconf config
;
4010 config
.ifc_len
= sizeof(config
.ifc_value
);
4011 if (ioctl(sockfd
, SIOCGRTSIZE
, &config
, sizeof(struct ifconf
)) < 0)
4013 msg(M_ERRNO
, "%s: Error getting routing table size", __func__
);
4017 uint32 size
= (uint32
)config
.ifc_value
;
4023 void *buffer
= malloc(size
);
4024 check_malloc_return(buffer
);
4026 config
.ifc_len
= size
;
4027 config
.ifc_buf
= buffer
;
4028 if (ioctl(sockfd
, SIOCGRTTABLE
, &config
, sizeof(struct ifconf
)) < 0)
4034 struct ifreq
*interface
= (struct ifreq
*)buffer
;
4035 struct ifreq
*end
= (struct ifreq
*)((uint8
*)buffer
+ size
);
4037 while (interface
< end
)
4039 struct route_entry route
= interface
->ifr_route
;
4040 if ((route
.flags
& RTF_GATEWAY
) != 0 && (route
.flags
& RTF_DEFAULT
) != 0)
4042 rgi
->gateway
.addr
= ntohl(((struct sockaddr_in
*)route
.gateway
)->sin_addr
.s_addr
);
4043 rgi
->flags
= RGI_ADDR_DEFINED
| RGI_IFACE_DEFINED
;
4044 strncpy(rgi
->iface
, interface
->ifr_name
, sizeof(rgi
->iface
));
4047 int32 address_size
= 0;
4048 if (route
.destination
!= NULL
)
4050 address_size
+= route
.destination
->sa_len
;
4052 if (route
.mask
!= NULL
)
4054 address_size
+= route
.mask
->sa_len
;
4056 if (route
.gateway
!= NULL
)
4058 address_size
+= route
.gateway
->sa_len
;
4061 interface
= (struct ifreq
*)((addr_t
)interface
+ IF_NAMESIZE
4062 + sizeof(struct route_entry
) + address_size
);
4068 get_default_gateway_ipv6(struct route_ipv6_gateway_info
*rgi6
,
4069 const struct in6_addr
*dest
, openvpn_net_ctx_t
*ctx
)
4071 /* TODO: Same for ipv6 with AF_INET6 */
4075 #else /* if defined(_WIN32) */
4078 * This is a platform-specific method that returns data about
4079 * the current default gateway. Return data is placed into
4080 * a struct route_gateway_info object provided by caller. The
4081 * implementation should CLEAR the structure before adding
4084 * Data returned includes:
4085 * 1. default gateway address (rgi->gateway.addr)
4086 * 2. netmask of interface that owns default gateway
4087 * (rgi->gateway.netmask)
4088 * 3. hardware address (i.e. MAC address) of interface that owns
4089 * default gateway (rgi->hwaddr)
4090 * 4. interface name (or adapter index on Windows) that owns default
4091 * gateway (rgi->iface or rgi->adapter_index)
4092 * 5. an array of additional address/netmask pairs defined by
4093 * interface that owns default gateway (rgi->addrs with length
4094 * given in rgi->n_addrs)
4096 * The flags RGI_x_DEFINED may be used to indicate which of the data
4097 * members were successfully returned (set in rgi->flags). All of
4098 * the data members are optional, however certain OpenVPN functionality
4099 * may be disabled by missing items.
4102 get_default_gateway(struct route_gateway_info
*rgi
, in_addr_t dest
, openvpn_net_ctx_t
*ctx
)
4107 get_default_gateway_ipv6(struct route_ipv6_gateway_info
*rgi6
,
4108 const struct in6_addr
*dest
, openvpn_net_ctx_t
*ctx
)
4110 msg(D_ROUTE
, "no support for get_default_gateway_ipv6() on this system");
4114 #endif /* if defined(_WIN32) */
4117 netmask_to_netbits(const in_addr_t network
, const in_addr_t netmask
, int *netbits
)
4120 const int addrlen
= sizeof(in_addr_t
) * 8;
4122 if ((network
& netmask
) == network
)
4124 for (i
= 0; i
<= addrlen
; ++i
)
4126 in_addr_t mask
= netbits_to_netmask(i
);
4127 if (mask
== netmask
)
4144 /* similar to netmask_to_netbits(), but don't mess with base address
4145 * etc., just convert to netbits - non-mappable masks are returned as "-1"
4148 netmask_to_netbits2(in_addr_t netmask
)
4151 const int addrlen
= sizeof(in_addr_t
) * 8;
4153 for (i
= 0; i
<= addrlen
; ++i
)
4155 in_addr_t mask
= netbits_to_netmask(i
);
4156 if (mask
== netmask
)
4166 * get_bypass_addresses() is used by the redirect-gateway bypass-x
4167 * functions to build a route bypass to selected DHCP/DNS servers,
4168 * so that outgoing packets to these servers don't end up in the tunnel.
4174 add_host_route_if_nonlocal(struct route_bypass
*rb
, const in_addr_t addr
)
4176 if (test_local_addr(addr
, NULL
) == TLA_NONLOCAL
&& addr
!= 0 && addr
!= IPV4_NETMASK_HOST
)
4178 add_bypass_address(rb
, addr
);
4183 add_host_route_array(struct route_bypass
*rb
, const IP_ADDR_STRING
*iplist
)
4187 bool succeed
= false;
4188 const in_addr_t ip
= getaddr(GETADDR_HOST_ORDER
, iplist
->IpAddress
.String
, 0, &succeed
, NULL
);
4191 add_host_route_if_nonlocal(rb
, ip
);
4193 iplist
= iplist
->Next
;
4198 get_bypass_addresses(struct route_bypass
*rb
, const unsigned int flags
)
4200 struct gc_arena gc
= gc_new();
4201 /*bool ret_bool = false;*/
4203 /* get full routing table */
4204 const MIB_IPFORWARDTABLE
*routes
= get_windows_routing_table(&gc
);
4206 /* get the route which represents the default gateway */
4207 const MIB_IPFORWARDROW
*row
= get_default_gateway_row(routes
);
4211 /* get the adapter which the default gateway is associated with */
4212 const IP_ADAPTER_INFO
*dgi
= get_adapter_info(row
->dwForwardIfIndex
, &gc
);
4214 /* get extra adapter info, such as DNS addresses */
4215 const IP_PER_ADAPTER_INFO
*pai
= get_per_adapter_info(row
->dwForwardIfIndex
, &gc
);
4217 /* Bypass DHCP server address */
4218 if ((flags
& RG_BYPASS_DHCP
) && dgi
&& dgi
->DhcpEnabled
)
4220 add_host_route_array(rb
, &dgi
->DhcpServer
);
4223 /* Bypass DNS server addresses */
4224 if ((flags
& RG_BYPASS_DNS
) && pai
)
4226 add_host_route_array(rb
, &pai
->DnsServerList
);
4233 #else /* if defined(_WIN32) */
4236 get_bypass_addresses(struct route_bypass
*rb
, const unsigned int flags
) /* PLATFORM-SPECIFIC */
4240 #endif /* if defined(_WIN32) */
4243 * Test if addr is reachable via a local interface (return ILA_LOCAL),
4244 * or if it needs to be routed via the default gateway (return
4245 * ILA_NONLOCAL). If the target platform doesn't implement this
4246 * function, return ILA_NOT_IMPLEMENTED.
4248 * Used by redirect-gateway autolocal feature
4254 test_local_addr(const in_addr_t addr
, const struct route_gateway_info
*rgi
)
4256 struct gc_arena gc
= gc_new();
4257 const in_addr_t nonlocal_netmask
= 0x80000000L
; /* routes with netmask <= to this are considered non-local */
4258 int ret
= TLA_NONLOCAL
;
4260 /* get full routing table */
4261 const MIB_IPFORWARDTABLE
*rt
= get_windows_routing_table(&gc
);
4264 for (DWORD i
= 0; i
< rt
->dwNumEntries
; ++i
)
4266 const MIB_IPFORWARDROW
*row
= &rt
->table
[i
];
4267 const in_addr_t net
= ntohl(row
->dwForwardDest
);
4268 const in_addr_t mask
= ntohl(row
->dwForwardMask
);
4269 if (mask
> nonlocal_netmask
&& (addr
& mask
) == net
)
4281 #else /* if defined(_WIN32) */
4284 test_local_addr(const in_addr_t addr
, const struct route_gateway_info
*rgi
) /* PLATFORM-SPECIFIC */
4288 if (local_route(addr
, 0xFFFFFFFF, rgi
->gateway
.addr
, rgi
))
4294 return TLA_NONLOCAL
;
4297 return TLA_NOT_IMPLEMENTED
;
4300 #endif /* if defined(_WIN32) */