OpenVPN
route.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2024 OpenVPN Inc <sales@openvpn.net>
9 *
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.
13 *
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.
18 *
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.
22 */
23
24/*
25 * Support routines for adding/deleting network routes.
26 */
27#include <stddef.h>
28#include <stdbool.h>
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#include "syshead.h"
35
36#include "common.h"
37#include "error.h"
38#include "route.h"
39#include "run_command.h"
40#include "socket.h"
41#include "manage.h"
42#include "win32.h"
43#include "options.h"
44#include "networking.h"
45#include "integer.h"
46
47#include "memdbg.h"
48
49#if defined(TARGET_LINUX) || defined(TARGET_ANDROID)
50#include <linux/rtnetlink.h> /* RTM_GETROUTE etc. */
51#endif
52
53#if defined(TARGET_NETBSD)
54#include <net/route.h> /* RT_ROUNDUP(), RT_ADVANCE() */
55#endif
56
57#ifdef _WIN32
58#include "openvpn-msg.h"
59
60#define METRIC_NOT_USED ((DWORD)-1)
61static int add_route_service(const struct route_ipv4 *, const struct tuntap *);
62
63static bool del_route_service(const struct route_ipv4 *, const struct tuntap *);
64
65static int add_route_ipv6_service(const struct route_ipv6 *, const struct tuntap *);
66
67static bool del_route_ipv6_service(const struct route_ipv6 *, const struct tuntap *);
68
69static int route_ipv6_ipapi(bool add, const struct route_ipv6 *, const struct tuntap *);
70
71static int add_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt, DWORD adapter_index);
72
73static bool del_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt);
74
75
76#endif
77
78static 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,
81
82static void get_bypass_addresses(struct route_bypass *rb, const unsigned int flags);
83
84#ifdef ENABLE_DEBUG
85
86static void
87print_bypass_addresses(const struct route_bypass *rb)
88{
89 struct gc_arena gc = gc_new();
90 int i;
91 for (i = 0; i < rb->n_bypass; ++i)
92 {
93 msg(D_ROUTE, "ROUTE: bypass_host_route[%d]=%s",
94 i,
95 print_in_addr_t(rb->bypass[i], 0, &gc));
96 }
97 gc_free(&gc);
98}
99
100#endif
101
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 */
106
107static bool
108add_bypass_address(struct route_bypass *rb, const in_addr_t a)
109{
110 int i;
111 for (i = 0; i < rb->n_bypass; ++i)
112 {
113 if (a == rb->bypass[i]) /* avoid duplicates */
114 {
115 return true;
116 }
117 }
118 if (rb->n_bypass < N_ROUTE_BYPASS)
119 {
120 rb->bypass[rb->n_bypass++] = a;
121 return true;
122 }
123 else
124 {
125 return false;
126 }
127}
128
129struct route_option_list *
131{
132 struct route_option_list *ret;
134 ret->gc = a;
135 return ret;
136}
137
140{
141 struct route_ipv6_option_list *ret;
143 ret->gc = a;
144 return ret;
145}
146
147/*
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.
153 */
154struct route_option_list *
156{
157 struct route_option_list *ret;
158 ALLOC_OBJ_GC(ret, struct route_option_list, a);
159 *ret = *src;
160 return ret;
161}
162
165{
166 struct route_ipv6_option_list *ret;
167 ALLOC_OBJ_GC(ret, struct route_ipv6_option_list, a);
168 *ret = *src;
169 return ret;
170}
171
172void
173copy_route_option_list(struct route_option_list *dest, const struct route_option_list *src, struct gc_arena *a)
174{
175 *dest = *src;
176 dest->gc = a;
177}
178
179void
181 const struct route_ipv6_option_list *src,
182 struct gc_arena *a)
183{
184 *dest = *src;
185 dest->gc = a;
186}
187
188static const char *
189route_string(const struct route_ipv4 *r, struct gc_arena *gc)
190{
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)
196 );
197 if (r->flags & RT_METRIC_DEFINED)
198 {
199 buf_printf(&out, " metric %d", r->metric);
200 }
201 return BSTR(&out);
202}
203
204static bool
206{
207 if (!parm)
208 {
209 return false;
210 }
211 if (!strcmp(parm, "default"))
212 {
213 return false;
214 }
215 return true;
216}
217
218static void
219setenv_route_addr(struct env_set *es, const char *key, const in_addr_t addr, int i)
220{
221 struct gc_arena gc = gc_new();
222 struct buffer name = alloc_buf_gc(256, &gc);
223 if (i >= 0)
224 {
225 buf_printf(&name, "route_%s_%d", key, i);
226 }
227 else
228 {
229 buf_printf(&name, "route_%s", key);
230 }
231 setenv_str(es, BSTR(&name), print_in_addr_t(addr, 0, &gc));
232 gc_free(&gc);
233}
234
235static bool
237 const char *string,
238 in_addr_t *out,
239 bool *status)
240{
241 if (status)
242 {
243 *status = true;
244 }
245 if (!strcmp(string, "vpn_gateway"))
246 {
247 if (rl)
248 {
249 if (rl->spec.flags & RTSA_REMOTE_ENDPOINT)
250 {
251 *out = rl->spec.remote_endpoint;
252 }
253 else
254 {
255 msg(M_INFO, PACKAGE_NAME " ROUTE: vpn_gateway undefined");
256 if (status)
257 {
258 *status = false;
259 }
260 }
261 }
262 return true;
263 }
264 else if (!strcmp(string, "net_gateway"))
265 {
266 if (rl)
267 {
268 if (rl->rgi.flags & RGI_ADDR_DEFINED)
269 {
270 *out = rl->rgi.gateway.addr;
271 }
272 else
273 {
274 msg(M_INFO, PACKAGE_NAME " ROUTE: net_gateway undefined -- unable to get default gateway from system");
275 if (status)
276 {
277 *status = false;
278 }
279 }
280 }
281 return true;
282 }
283 else if (!strcmp(string, "remote_host"))
284 {
285 if (rl)
286 {
287 if (rl->spec.flags & RTSA_REMOTE_HOST)
288 {
289 *out = rl->spec.remote_host;
290 }
291 else
292 {
293 msg(M_INFO, PACKAGE_NAME " ROUTE: remote_host undefined");
294 if (status)
295 {
296 *status = false;
297 }
298 }
299 }
300 return true;
301 }
302 return false;
303}
304
305bool
307{
308 if (addr_str)
309 {
311 }
312 else
313 {
314 return false;
315 }
316}
317
318static bool
320 struct addrinfo **network_list,
321 const struct route_option *ro,
322 const struct route_list *rl)
323{
325 bool status;
326 int ret;
327 struct in_addr special = {0};
328
329 CLEAR(*r);
330 r->option = ro;
331
332 /* network */
333
335 {
336 goto fail;
337 }
338
339
340 /* get_special_addr replaces specialaddr with a special ip addr
341 * like gw. getaddrinfo is called to convert a a addrinfo struct */
342
343 if (get_special_addr(rl, ro->network, (in_addr_t *) &special.s_addr, &status))
344 {
345 if (!status)
346 {
347 goto fail;
348 }
349 special.s_addr = htonl(special.s_addr);
350 char buf[INET_ADDRSTRLEN];
351 inet_ntop(AF_INET, &special, buf, sizeof(buf));
352 ret = openvpn_getaddrinfo(0, buf, NULL, 0, NULL,
353 AF_INET, network_list);
354 }
355 else
356 {
358 ro->network, NULL, 0, NULL, AF_INET, network_list);
359 }
360
361 status = (ret == 0);
362
363 if (!status)
364 {
365 goto fail;
366 }
367
368 /* netmask */
369
371 {
372 r->netmask = getaddr(
375 ro->netmask,
376 0,
377 &status,
378 NULL);
379 if (!status)
380 {
381 goto fail;
382 }
383 }
384 else
385 {
386 r->netmask = default_netmask;
387 }
388
389 /* gateway */
390
392 {
393 if (!get_special_addr(rl, ro->gateway, &r->gateway, &status))
394 {
395 r->gateway = getaddr(
399 ro->gateway,
400 0,
401 &status,
402 NULL);
403 }
404 if (!status)
405 {
406 goto fail;
407 }
408 }
409 else
410 {
412 {
414 }
415 else
416 {
417 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");
418 goto fail;
419 }
420 }
421
422 /* metric */
423
424 r->metric = 0;
426 {
427 r->metric = atoi(ro->metric);
428 if (r->metric < 0)
429 {
430 msg(M_WARN, PACKAGE_NAME " ROUTE: route metric for network %s (%s) must be >= 0",
431 ro->network,
432 ro->metric);
433 goto fail;
434 }
436 }
437 else if (rl->spec.flags & RTSA_DEFAULT_METRIC)
438 {
439 r->metric = rl->spec.default_metric;
441 }
442
443 r->flags |= RT_DEFINED;
444
445 return true;
446
447fail:
448 msg(M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve route for host/network: %s",
449 ro->network);
450 return false;
451}
452
453static bool
455 const struct route_ipv6_option *r6o,
456 const struct route_ipv6_list *rl6 )
457{
458 CLEAR(*r6);
459
460 if (!get_ipv6_addr( r6o->prefix, &r6->network, &r6->netbits, M_WARN ))
461 {
462 goto fail;
463 }
464
465 /* gateway */
467 {
468 if (inet_pton( AF_INET6, r6o->gateway, &r6->gateway ) != 1)
469 {
470 msg( M_WARN, PACKAGE_NAME "ROUTE6: cannot parse gateway spec '%s'", r6o->gateway );
471 }
472 }
473 else if (rl6->spec_flags & RTSA_REMOTE_ENDPOINT)
474 {
475 r6->gateway = rl6->remote_endpoint_ipv6;
476 }
477
478 /* metric */
479
480 r6->metric = -1;
482 {
483 r6->metric = atoi(r6o->metric);
484 if (r6->metric < 0)
485 {
486 msg(M_WARN, PACKAGE_NAME " ROUTE: route metric for network %s (%s) must be >= 0",
487 r6o->prefix,
488 r6o->metric);
489 goto fail;
490 }
492 }
493 else if (rl6->spec_flags & RTSA_DEFAULT_METRIC)
494 {
495 r6->metric = rl6->default_metric;
497 }
498
499 r6->flags |= RT_DEFINED;
500
501 return true;
502
503fail:
504 msg(M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve route for host/network: %s",
505 r6o->prefix);
506 return false;
507}
508
509void
511 const char *network,
512 const char *netmask,
513 const char *gateway,
514 const char *metric)
515{
516 struct route_option *ro;
517 ALLOC_OBJ_GC(ro, struct route_option, l->gc);
518 ro->network = network;
519 ro->netmask = netmask;
520 ro->gateway = gateway;
521 ro->metric = metric;
522 ro->next = l->routes;
523 l->routes = ro;
524
525}
526
527void
529 const char *prefix,
530 const char *gateway,
531 const char *metric)
532{
533 struct route_ipv6_option *ro;
534 ALLOC_OBJ_GC(ro, struct route_ipv6_option, l->gc);
535 ro->prefix = prefix;
536 ro->gateway = gateway;
537 ro->metric = metric;
538 ro->next = l->routes_ipv6;
539 l->routes_ipv6 = ro;
540}
541
542static void
544{
545 gc_free(&rl->gc);
546 CLEAR(*rl);
547}
548
549static void
551{
552 gc_free(&rl6->gc);
553 CLEAR(*rl6);
554}
555
556void
558 struct env_set *es,
559 const in_addr_t addr)
560{
561 ASSERT(rl);
562 rl->spec.remote_endpoint = addr;
564 setenv_route_addr(es, "vpn_gateway", rl->spec.remote_endpoint, -1);
565}
566
567static void
569 const struct route_gateway_address *gateway,
570 in_addr_t target)
571{
572 if (rl->rgi.gateway.netmask < 0xFFFFFFFF)
573 {
574 struct route_ipv4 *r1, *r2;
575 unsigned int l2;
576
577 ALLOC_OBJ_GC(r1, struct route_ipv4, &rl->gc);
578 ALLOC_OBJ_GC(r2, struct route_ipv4, &rl->gc);
579
580 /* split a route into two smaller blocking routes, and direct them to target */
581 l2 = ((~gateway->netmask)+1)>>1;
582 r1->flags = RT_DEFINED;
583 r1->gateway = target;
584 r1->network = gateway->addr & gateway->netmask;
585 r1->netmask = ~(l2-1);
586 r1->next = rl->routes;
587 rl->routes = r1;
588
589 *r2 = *r1;
590 r2->network += l2;
591 r2->next = rl->routes;
592 rl->routes = r2;
593 }
594}
595
596static void
598{
599#ifndef TARGET_ANDROID
600 /* add bypass for gateway addr */
602#endif
603
604 /* block access to local subnet */
606
607 /* process additional subnets on gateway interface */
608 for (size_t i = 0; i < rl->rgi.n_addrs; ++i)
609 {
610 const struct route_gateway_address *gwa = &rl->rgi.addrs[i];
611 /* omit the add/subnet in &rl->rgi which we processed above */
612 if (!((rl->rgi.gateway.addr & rl->rgi.gateway.netmask) == (gwa->addr & gwa->netmask)
613 && rl->rgi.gateway.netmask == gwa->netmask))
614 {
616 }
617 }
618}
619
620bool
622{
623 const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED);
624 return (rl->flags & RG_BLOCK_LOCAL)
625 && (rl->rgi.flags & rgi_needed) == rgi_needed
628}
629
630bool
632 const struct route_option_list *opt,
633 const char *remote_endpoint,
634 int default_metric,
635 in_addr_t remote_host,
636 struct env_set *es,
638{
639 struct gc_arena gc = gc_new();
640 bool ret = true;
641
643
644 rl->flags = opt->flags;
645
646 if (remote_host != IPV4_INVALID_ADDR)
647 {
648 rl->spec.remote_host = remote_host;
650 }
651
652 if (default_metric)
653 {
654 rl->spec.default_metric = default_metric;
656 }
657
658 get_default_gateway(&rl->rgi, remote_host != IPV4_INVALID_ADDR ? remote_host : INADDR_ANY, ctx);
659 if (rl->rgi.flags & RGI_ADDR_DEFINED)
660 {
661 setenv_route_addr(es, "net_gateway", rl->rgi.gateway.addr, -1);
662#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
663 print_default_gateway(D_ROUTE, &rl->rgi, NULL);
664#endif
665 }
666 else
667 {
668 dmsg(D_ROUTE, "ROUTE: default_gateway=UNDEF");
669 }
670
671 if (rl->spec.flags & RTSA_REMOTE_HOST)
672 {
673 rl->spec.remote_host_local = test_local_addr(remote_host, &rl->rgi);
674 }
675
676 if (is_route_parm_defined(remote_endpoint))
677 {
678 bool defined = false;
683 remote_endpoint,
684 0,
685 &defined,
686 NULL);
687
688 if (defined)
689 {
690 setenv_route_addr(es, "vpn_gateway", rl->spec.remote_endpoint, -1);
692 }
693 else
694 {
695 msg(M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve default gateway: %s",
696 remote_endpoint);
697 ret = false;
698 }
699 }
700
701 if (rl->flags & RG_ENABLE)
702 {
703 if (block_local_needed(rl))
704 {
706 }
708#ifdef ENABLE_DEBUG
709 print_bypass_addresses(&rl->spec.bypass);
710#endif
711 }
712
713 /* parse the routes from opt to rl */
714 {
715 struct route_option *ro;
716 for (ro = opt->routes; ro; ro = ro->next)
717 {
718 struct addrinfo *netlist = NULL;
719 struct route_ipv4 r;
720
721 if (!init_route(&r, &netlist, ro, rl))
722 {
723 ret = false;
724 }
725 else
726 {
727 struct addrinfo *curele;
728 for (curele = netlist; curele; curele = curele->ai_next)
729 {
730 struct route_ipv4 *new;
731 ALLOC_OBJ_GC(new, struct route_ipv4, &rl->gc);
732 *new = r;
733 new->network = ntohl(((struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
734 new->next = rl->routes;
735 rl->routes = new;
736 }
737 }
738 if (netlist)
739 {
741 }
742 }
743 }
744
745 gc_free(&gc);
746 return ret;
747}
748
749/* check whether an IPv6 host address is covered by a given route_ipv6
750 * (not the most beautiful implementation in the world, but portable and
751 * "good enough")
752 */
753static bool
755 const struct in6_addr *host )
756{
757 unsigned int bits = r6->netbits;
758 int i;
759 unsigned int mask;
760
761 if (bits>128)
762 {
763 return false;
764 }
765
766 for (i = 0; bits >= 8; i++, bits -= 8)
767 {
768 if (r6->network.s6_addr[i] != host->s6_addr[i])
769 {
770 return false;
771 }
772 }
773
774 if (bits == 0)
775 {
776 return true;
777 }
778
779 mask = 0xff << (8-bits);
780
781 if ( (r6->network.s6_addr[i] & mask) == (host->s6_addr[i] & mask ))
782 {
783 return true;
784 }
785
786 return false;
787}
788
789bool
791 const struct route_ipv6_option_list *opt6,
792 const char *remote_endpoint,
793 int default_metric,
794 const struct in6_addr *remote_host_ipv6,
795 struct env_set *es,
797{
798 struct gc_arena gc = gc_new();
799 bool ret = true;
800 bool need_remote_ipv6_route;
801
803
804 rl6->flags = opt6->flags;
805
806 if (remote_host_ipv6)
807 {
808 rl6->remote_host_ipv6 = *remote_host_ipv6;
810 }
811
812 if (default_metric >= 0)
813 {
814 rl6->default_metric = default_metric;
816 }
817
818 msg(D_ROUTE, "GDG6: remote_host_ipv6=%s",
819 remote_host_ipv6 ? print_in6_addr(*remote_host_ipv6, 0, &gc) : "n/a" );
820
821 get_default_gateway_ipv6(&rl6->rgi6, remote_host_ipv6, ctx);
822 if (rl6->rgi6.flags & RGI_ADDR_DEFINED)
823 {
824 setenv_str(es, "net_gateway_ipv6", print_in6_addr(rl6->rgi6.gateway.addr_ipv6, 0, &gc));
825#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
826 print_default_gateway(D_ROUTE, NULL, &rl6->rgi6);
827#endif
828 }
829 else
830 {
831 dmsg(D_ROUTE, "ROUTE6: default_gateway=UNDEF");
832 }
833
834 if (is_route_parm_defined( remote_endpoint ))
835 {
836 if (inet_pton( AF_INET6, remote_endpoint,
837 &rl6->remote_endpoint_ipv6) == 1)
838 {
840 }
841 else
842 {
843 msg(M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve VPN endpoint: %s", remote_endpoint);
844 ret = false;
845 }
846 }
847
848 /* parse the routes from opt6 to rl6
849 * discovering potential overlaps with remote_host_ipv6 in the process
850 */
851 need_remote_ipv6_route = false;
852
853 {
854 struct route_ipv6_option *ro6;
855 for (ro6 = opt6->routes_ipv6; ro6; ro6 = ro6->next)
856 {
857 struct route_ipv6 *r6;
858 ALLOC_OBJ_GC(r6, struct route_ipv6, &rl6->gc);
859 if (!init_route_ipv6(r6, ro6, rl6))
860 {
861 ret = false;
862 }
863 else
864 {
865 r6->next = rl6->routes_ipv6;
866 rl6->routes_ipv6 = r6;
867
868#ifndef TARGET_ANDROID
869 /* On Android the VPNService protect function call will take of
870 * avoiding routing loops, so ignore this part and let
871 * need_remote_ipv6_route always evaluate to false
872 */
873 if (remote_host_ipv6
874 && route_ipv6_match_host( r6, remote_host_ipv6 ) )
875 {
876 need_remote_ipv6_route = true;
877 msg(D_ROUTE, "ROUTE6: %s/%d overlaps IPv6 remote %s, adding host route to VPN endpoint",
878 print_in6_addr(r6->network, 0, &gc), r6->netbits,
879 print_in6_addr(*remote_host_ipv6, 0, &gc));
880 }
881#endif
882 }
883 }
884 }
885
886 /* add VPN server host route if needed */
887 if (need_remote_ipv6_route)
888 {
889 if ( (rl6->rgi6.flags & (RGI_ADDR_DEFINED|RGI_IFACE_DEFINED) ) ==
891 {
892 struct route_ipv6 *r6;
893 ALLOC_OBJ_CLEAR_GC(r6, struct route_ipv6, &rl6->gc);
894
895 r6->network = *remote_host_ipv6;
896 r6->netbits = 128;
897 if (!(rl6->rgi6.flags & RGI_ON_LINK) )
898 {
899 r6->gateway = rl6->rgi6.gateway.addr_ipv6;
900 }
901 r6->metric = 1;
902#ifdef _WIN32
904#else
905 r6->iface = rl6->rgi6.iface;
906#endif
908
909 r6->next = rl6->routes_ipv6;
910 rl6->routes_ipv6 = r6;
911 }
912 else
913 {
914 msg(M_WARN, "ROUTE6: IPv6 route overlaps with IPv6 remote address, but could not determine IPv6 gateway address + interface, expect failure\n" );
915 }
916 }
917
918 gc_free(&gc);
919 return ret;
920}
921
922static bool
924 in_addr_t netmask,
925 in_addr_t gateway,
926 const struct tuntap *tt,
927 unsigned int flags,
928 const struct route_gateway_info *rgi,
929 const struct env_set *es,
931{
932 struct route_ipv4 r;
933 CLEAR(r);
934 r.flags = RT_DEFINED;
935 r.network = network;
936 r.netmask = netmask;
937 r.gateway = gateway;
938 return add_route(&r, tt, flags, rgi, es, ctx);
939}
940
941static void
943 in_addr_t netmask,
944 in_addr_t gateway,
945 const struct tuntap *tt,
946 unsigned int flags,
947 const struct route_gateway_info *rgi,
948 const struct env_set *es,
950{
951 struct route_ipv4 r;
952 CLEAR(r);
954 r.network = network;
955 r.netmask = netmask;
956 r.gateway = gateway;
957 delete_route(&r, tt, flags, rgi, es, ctx);
958}
959
960static bool
962 in_addr_t gateway,
963 const struct tuntap *tt,
964 unsigned int flags,
965 const struct route_gateway_info *rgi,
966 const struct env_set *es,
968{
969 int ret = true;
970 for (int i = 0; i < rb->n_bypass; ++i)
971 {
972 if (rb->bypass[i])
973 {
974 ret = add_route3(rb->bypass[i], IPV4_NETMASK_HOST, gateway, tt,
975 flags | ROUTE_REF_GW, rgi, es, ctx) && ret;
976 }
977 }
978 return ret;
979}
980
981static void
983 in_addr_t gateway,
984 const struct tuntap *tt,
985 unsigned int flags,
986 const struct route_gateway_info *rgi,
987 const struct env_set *es,
989{
990 int i;
991 for (i = 0; i < rb->n_bypass; ++i)
992 {
993 if (rb->bypass[i])
994 {
995 del_route3(rb->bypass[i],
997 gateway,
998 tt,
1000 rgi,
1001 es,
1002 ctx);
1003 }
1004 }
1005}
1006
1007static bool
1009 unsigned int flags, const struct env_set *es,
1010 openvpn_net_ctx_t *ctx)
1011{
1012 const char err[] = "NOTE: unable to redirect IPv4 default gateway --";
1013 bool ret = true;
1014
1015 if (rl && rl->flags & RG_ENABLE)
1016 {
1017 bool local = rl->flags & RG_LOCAL;
1018
1019 if (!(rl->spec.flags & RTSA_REMOTE_ENDPOINT) && (rl->flags & RG_REROUTE_GW))
1020 {
1021 msg(M_WARN, "%s VPN gateway parameter (--route-gateway or --ifconfig) is missing", err);
1022 ret = false;
1023 }
1024 /*
1025 * check if a default route is defined, unless:
1026 * - we are connecting to a remote host in our network
1027 * - we are connecting to a non-IPv4 remote host (i.e. we use IPv6)
1028 */
1029 else if (!(rl->rgi.flags & RGI_ADDR_DEFINED) && !local
1030 && (rl->spec.flags & RTSA_REMOTE_HOST))
1031 {
1032 msg(M_WARN, "%s Cannot read current default gateway from system", err);
1033 ret = false;
1034 }
1035 else
1036 {
1037#ifndef TARGET_ANDROID
1038 if (rl->flags & RG_AUTO_LOCAL)
1039 {
1040 const int tla = rl->spec.remote_host_local;
1041 if (tla == TLA_NONLOCAL)
1042 {
1043 dmsg(D_ROUTE, "ROUTE remote_host is NOT LOCAL");
1044 local = false;
1045 }
1046 else if (tla == TLA_LOCAL)
1047 {
1048 dmsg(D_ROUTE, "ROUTE remote_host is LOCAL");
1049 local = true;
1050 }
1051 }
1052 if (!local)
1053 {
1054 /* route remote host to original default gateway */
1055 /* if remote_host is not ipv4 (ie: ipv6), just skip
1056 * adding this special /32 route */
1057 if ((rl->spec.flags & RTSA_REMOTE_HOST)
1059 {
1061 rl->rgi.gateway.addr, tt, flags | ROUTE_REF_GW,
1062 &rl->rgi, es, ctx);
1063 if (ret)
1064 {
1065 rl->iflags |= RL_DID_LOCAL;
1066 }
1067 }
1068 else
1069 {
1070 dmsg(D_ROUTE, "ROUTE remote_host protocol differs from tunneled");
1071 }
1072 }
1073#endif /* ifndef TARGET_ANDROID */
1074
1075 /* route DHCP/DNS server traffic through original default gateway */
1076 ret = add_bypass_routes(&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags,
1077 &rl->rgi, es, ctx) && ret;
1078
1079 if (rl->flags & RG_REROUTE_GW)
1080 {
1081 if (rl->flags & RG_DEF1)
1082 {
1083 /* add new default route (1st component) */
1084 ret = add_route3(0x00000000, 0x80000000, rl->spec.remote_endpoint,
1085 tt, flags, &rl->rgi, es, ctx) && ret;
1086
1087 /* add new default route (2nd component) */
1088 ret = add_route3(0x80000000, 0x80000000, rl->spec.remote_endpoint,
1089 tt, flags, &rl->rgi, es, ctx) && ret;
1090 }
1091 else
1092 {
1093 /* don't try to remove the def route if it does not exist */
1094 if (rl->rgi.flags & RGI_ADDR_DEFINED)
1095 {
1096 /* delete default route */
1097 del_route3(0, 0, rl->rgi.gateway.addr, tt,
1098 flags | ROUTE_REF_GW, &rl->rgi, es, ctx);
1099 }
1100
1101 /* add new default route */
1102 ret = add_route3(0, 0, rl->spec.remote_endpoint, tt,
1103 flags, &rl->rgi, es, ctx) && ret;
1104 }
1105 }
1106
1107 /* set a flag so we can undo later */
1109 }
1110 }
1111 return ret;
1112}
1113
1114static void
1116 const struct tuntap *tt, unsigned int flags,
1117 const struct env_set *es,
1118 openvpn_net_ctx_t *ctx)
1119{
1121 {
1122 /* delete remote host route */
1123 if (rl->iflags & RL_DID_LOCAL)
1124 {
1127 rl->rgi.gateway.addr,
1128 tt,
1130 &rl->rgi,
1131 es,
1132 ctx);
1133 rl->iflags &= ~RL_DID_LOCAL;
1134 }
1135
1136 /* delete special DHCP/DNS bypass route */
1138 &rl->rgi, es, ctx);
1139
1140 if (rl->flags & RG_REROUTE_GW)
1141 {
1142 if (rl->flags & RG_DEF1)
1143 {
1144 /* delete default route (1st component) */
1145 del_route3(0x00000000,
1146 0x80000000,
1148 tt,
1149 flags,
1150 &rl->rgi,
1151 es,
1152 ctx);
1153
1154 /* delete default route (2nd component) */
1155 del_route3(0x80000000,
1156 0x80000000,
1158 tt,
1159 flags,
1160 &rl->rgi,
1161 es,
1162 ctx);
1163 }
1164 else
1165 {
1166 /* delete default route */
1167 del_route3(0,
1168 0,
1170 tt,
1171 flags,
1172 &rl->rgi,
1173 es,
1174 ctx);
1175 /* restore original default route if there was any */
1176 if (rl->rgi.flags & RGI_ADDR_DEFINED)
1177 {
1178 add_route3(0, 0, rl->rgi.gateway.addr, tt,
1179 flags | ROUTE_REF_GW, &rl->rgi, es, ctx);
1180 }
1181 }
1182 }
1183
1184 rl->iflags &= ~RL_DID_REDIRECT_DEFAULT_GATEWAY;
1185 }
1186}
1187
1188bool
1189add_routes(struct route_list *rl, struct route_ipv6_list *rl6,
1190 const struct tuntap *tt, unsigned int flags,
1191 const struct env_set *es, openvpn_net_ctx_t *ctx)
1192{
1193 bool ret = redirect_default_route_to_vpn(rl, tt, flags, es, ctx);
1194 if (rl && !(rl->iflags & RL_ROUTES_ADDED) )
1195 {
1196 struct route_ipv4 *r;
1197
1198 if (rl->routes && !tt->did_ifconfig_setup)
1199 {
1200 msg(M_INFO, "WARNING: OpenVPN was configured to add an IPv4 "
1201 "route. However, no IPv4 has been configured for %s, "
1202 "therefore the route installation may fail or may not work "
1203 "as expected.", tt->actual_name);
1204 }
1205
1206#ifdef ENABLE_MANAGEMENT
1207 if (management && rl->routes)
1208 {
1211 NULL,
1212 NULL,
1213 NULL,
1214 NULL,
1215 NULL);
1216 }
1217#endif
1218
1219 for (r = rl->routes; r; r = r->next)
1220 {
1222 {
1223 delete_route(r, tt, flags, &rl->rgi, es, ctx);
1224 }
1225 ret = add_route(r, tt, flags, &rl->rgi, es, ctx) && ret;
1226 }
1227 rl->iflags |= RL_ROUTES_ADDED;
1228 }
1229 if (rl6 && !(rl6->iflags & RL_ROUTES_ADDED) )
1230 {
1231 struct route_ipv6 *r;
1232
1233 if (!tt->did_ifconfig_ipv6_setup)
1234 {
1235 msg(M_INFO, "WARNING: OpenVPN was configured to add an IPv6 "
1236 "route. However, no IPv6 has been configured for %s, "
1237 "therefore the route installation may fail or may not work "
1238 "as expected.", tt->actual_name);
1239 }
1240
1241 for (r = rl6->routes_ipv6; r; r = r->next)
1242 {
1244 {
1245 delete_route_ipv6(r, tt, es, ctx);
1246 }
1247 ret = add_route_ipv6(r, tt, flags, es, ctx) && ret;
1248 }
1249 rl6->iflags |= RL_ROUTES_ADDED;
1250 }
1251
1252 return ret;
1253}
1254
1255void
1257 const struct tuntap *tt, unsigned int flags,
1258 const struct env_set *es, openvpn_net_ctx_t *ctx)
1259{
1260 if (rl && rl->iflags & RL_ROUTES_ADDED)
1261 {
1262 struct route_ipv4 *r;
1263 for (r = rl->routes; r; r = r->next)
1264 {
1265 delete_route(r, tt, flags, &rl->rgi, es, ctx);
1266 }
1267 rl->iflags &= ~RL_ROUTES_ADDED;
1268 }
1269
1271
1272 if (rl)
1273 {
1274 clear_route_list(rl);
1275 }
1276
1277 if (rl6 && (rl6->iflags & RL_ROUTES_ADDED) )
1278 {
1279 struct route_ipv6 *r6;
1280 for (r6 = rl6->routes_ipv6; r6; r6 = r6->next)
1281 {
1282 delete_route_ipv6(r6, tt, es, ctx);
1283 }
1284 rl6->iflags &= ~RL_ROUTES_ADDED;
1285 }
1286
1287 if (rl6)
1288 {
1290 }
1291}
1292
1293#ifndef ENABLE_SMALL
1294
1295static const char *
1296show_opt(const char *option)
1297{
1298 if (!option)
1299 {
1300 return "default (not set)";
1301 }
1302 else
1303 {
1304 return option;
1305 }
1306}
1307
1308static void
1309print_route_option(const struct route_option *ro, int level)
1310{
1311 msg(level, " route %s/%s/%s/%s",
1312 show_opt(ro->network),
1313 show_opt(ro->netmask),
1314 show_opt(ro->gateway),
1315 show_opt(ro->metric));
1316}
1317
1318void
1320 int level)
1321{
1322 struct route_option *ro;
1323 if (rol->flags & RG_ENABLE)
1324 {
1325 msg(level, " [redirect_default_gateway local=%d]",
1326 (rol->flags & RG_LOCAL) != 0);
1327 }
1328 for (ro = rol->routes; ro; ro = ro->next)
1329 {
1330 print_route_option(ro, level);
1331 }
1332}
1333
1334void
1335print_default_gateway(const int msglevel,
1336 const struct route_gateway_info *rgi,
1337 const struct route_ipv6_gateway_info *rgi6)
1338{
1339 struct gc_arena gc = gc_new();
1340 if (rgi && (rgi->flags & RGI_ADDR_DEFINED))
1341 {
1342 struct buffer out = alloc_buf_gc(256, &gc);
1343 buf_printf(&out, "ROUTE_GATEWAY");
1344 if (rgi->flags & RGI_ON_LINK)
1345 {
1346 buf_printf(&out, " ON_LINK");
1347 }
1348 else
1349 {
1350 buf_printf(&out, " %s", print_in_addr_t(rgi->gateway.addr, 0, &gc));
1351 }
1352 if (rgi->flags & RGI_NETMASK_DEFINED)
1353 {
1354 buf_printf(&out, "/%s", print_in_addr_t(rgi->gateway.netmask, 0, &gc));
1355 }
1356#ifdef _WIN32
1357 if (rgi->flags & RGI_IFACE_DEFINED)
1358 {
1359 buf_printf(&out, " I=%lu", rgi->adapter_index);
1360 }
1361#else
1362 if (rgi->flags & RGI_IFACE_DEFINED)
1363 {
1364 buf_printf(&out, " IFACE=%s", rgi->iface);
1365 }
1366#endif
1367 if (rgi->flags & RGI_HWADDR_DEFINED)
1368 {
1369 buf_printf(&out, " HWADDR=%s", format_hex_ex(rgi->hwaddr, 6, 0, 1, ":", &gc));
1370 }
1371 msg(msglevel, "%s", BSTR(&out));
1372 }
1373
1374 if (rgi6 && (rgi6->flags & RGI_ADDR_DEFINED))
1375 {
1376 struct buffer out = alloc_buf_gc(256, &gc);
1377 buf_printf(&out, "ROUTE6_GATEWAY");
1378 buf_printf(&out, " %s", print_in6_addr(rgi6->gateway.addr_ipv6, 0, &gc));
1379 if (rgi6->flags & RGI_ON_LINK)
1380 {
1381 buf_printf(&out, " ON_LINK");
1382 }
1383 if (rgi6->flags & RGI_NETMASK_DEFINED)
1384 {
1385 buf_printf(&out, "/%d", rgi6->gateway.netbits_ipv6);
1386 }
1387#ifdef _WIN32
1388 if (rgi6->flags & RGI_IFACE_DEFINED)
1389 {
1390 buf_printf(&out, " I=%lu", rgi6->adapter_index);
1391 }
1392#else
1393 if (rgi6->flags & RGI_IFACE_DEFINED)
1394 {
1395 buf_printf(&out, " IFACE=%s", rgi6->iface);
1396 }
1397#endif
1398 if (rgi6->flags & RGI_HWADDR_DEFINED)
1399 {
1400 buf_printf(&out, " HWADDR=%s", format_hex_ex(rgi6->hwaddr, 6, 0, 1, ":", &gc));
1401 }
1402 msg(msglevel, "%s", BSTR(&out));
1403 }
1404 gc_free(&gc);
1405}
1406
1407#endif /* ifndef ENABLE_SMALL */
1408
1409static void
1410print_route(const struct route_ipv4 *r, int level)
1411{
1412 struct gc_arena gc = gc_new();
1413 if (r->flags & RT_DEFINED)
1414 {
1415 msg(level, "%s", route_string(r, &gc));
1416 }
1417 gc_free(&gc);
1418}
1419
1420void
1421print_routes(const struct route_list *rl, int level)
1422{
1423 struct route_ipv4 *r;
1424 for (r = rl->routes; r; r = r->next)
1425 {
1426 print_route(r, level);
1427 }
1428}
1429
1430static void
1431setenv_route(struct env_set *es, const struct route_ipv4 *r, int i)
1432{
1433 struct gc_arena gc = gc_new();
1434 if (r->flags & RT_DEFINED)
1435 {
1436 setenv_route_addr(es, "network", r->network, i);
1437 setenv_route_addr(es, "netmask", r->netmask, i);
1438 setenv_route_addr(es, "gateway", r->gateway, i);
1439
1440 if (r->flags & RT_METRIC_DEFINED)
1441 {
1442 struct buffer name = alloc_buf_gc(256, &gc);
1443 buf_printf(&name, "route_metric_%d", i);
1444 setenv_int(es, BSTR(&name), r->metric);
1445 }
1446 }
1447 gc_free(&gc);
1448}
1449
1450void
1451setenv_routes(struct env_set *es, const struct route_list *rl)
1452{
1453 int i = 1;
1454 struct route_ipv4 *r;
1455 for (r = rl->routes; r; r = r->next)
1456 {
1457 setenv_route(es, r, i++);
1458 }
1459}
1460
1461static void
1462setenv_route_ipv6(struct env_set *es, const struct route_ipv6 *r6, int i)
1463{
1464 struct gc_arena gc = gc_new();
1465 if (r6->flags & RT_DEFINED)
1466 {
1467 struct buffer name1 = alloc_buf_gc( 256, &gc );
1468 struct buffer val = alloc_buf_gc( 256, &gc );
1469 struct buffer name2 = alloc_buf_gc( 256, &gc );
1470
1471 buf_printf( &name1, "route_ipv6_network_%d", i );
1472 buf_printf( &val, "%s/%d", print_in6_addr( r6->network, 0, &gc ),
1473 r6->netbits );
1474 setenv_str( es, BSTR(&name1), BSTR(&val) );
1475
1476 buf_printf( &name2, "route_ipv6_gateway_%d", i );
1477 setenv_str( es, BSTR(&name2), print_in6_addr( r6->gateway, 0, &gc ));
1478
1479 if (r6->flags & RT_METRIC_DEFINED)
1480 {
1481 struct buffer name3 = alloc_buf_gc( 256, &gc );
1482 buf_printf( &name3, "route_ipv6_metric_%d", i);
1483 setenv_int( es, BSTR(&name3), r6->metric);
1484 }
1485 }
1486 gc_free(&gc);
1487}
1488void
1490{
1491 int i = 1;
1492 struct route_ipv6 *r6;
1493 for (r6 = rl6->routes_ipv6; r6; r6 = r6->next)
1494 {
1495 setenv_route_ipv6(es, r6, i++);
1496 }
1497}
1498
1499/*
1500 * local_route() determines whether the gateway of a provided host
1501 * route is on the same interface that owns the default gateway.
1502 * It uses the data structure
1503 * returned by get_default_gateway() (struct route_gateway_info)
1504 * to determine this. If the route is local, LR_MATCH is returned.
1505 * When adding routes into the kernel, if LR_MATCH is defined for
1506 * a given route, the route should explicitly reference the default
1507 * gateway interface as the route destination. For example, here
1508 * is an example on Linux that uses LR_MATCH:
1509 *
1510 * route add -net 10.10.0.1 netmask 255.255.255.255 dev eth0
1511 *
1512 * This capability is needed by the "default-gateway block-local"
1513 * directive, to allow client access to the local subnet to be
1514 * blocked but still allow access to the local default gateway.
1515 */
1516
1517/* local_route() return values */
1518#define LR_NOMATCH 0 /* route is not local */
1519#define LR_MATCH 1 /* route is local */
1520#define LR_ERROR 2 /* caller should abort adding route */
1521
1522static int
1524 in_addr_t netmask,
1525 in_addr_t gateway,
1526 const struct route_gateway_info *rgi)
1527{
1528 /* set LR_MATCH on local host routes */
1530 if (rgi
1531 && (rgi->flags & rgi_needed) == rgi_needed
1532 && gateway == rgi->gateway.addr
1533 && netmask == 0xFFFFFFFF)
1534 {
1535 if (((network ^ rgi->gateway.addr) & rgi->gateway.netmask) == 0)
1536 {
1537 return LR_MATCH;
1538 }
1539 else
1540 {
1541 /* examine additional subnets on gateway interface */
1542 size_t i;
1543 for (i = 0; i < rgi->n_addrs; ++i)
1544 {
1545 const struct route_gateway_address *gwa = &rgi->addrs[i];
1546 if (((network ^ gwa->addr) & gwa->netmask) == 0)
1547 {
1548 return LR_MATCH;
1549 }
1550 }
1551 }
1552 }
1553 return LR_NOMATCH;
1554}
1555
1556/* Return true if the "on-link" form of the route should be used. This is when the gateway for
1557 * a route is specified as an interface rather than an address. */
1558#if defined(TARGET_LINUX) || defined(_WIN32) || defined(TARGET_DARWIN)
1559static inline bool
1560is_on_link(const int is_local_route, const unsigned int flags, const struct route_gateway_info *rgi)
1561{
1562 return rgi && (is_local_route == LR_MATCH || ((flags & ROUTE_REF_GW) && (rgi->flags & RGI_ON_LINK)));
1563}
1564#endif
1565
1566bool
1568 const struct tuntap *tt,
1569 unsigned int flags,
1570 const struct route_gateway_info *rgi, /* may be NULL */
1571 const struct env_set *es,
1572 openvpn_net_ctx_t *ctx)
1573{
1574 int status = 0;
1575 int is_local_route;
1576
1577 if (!(r->flags & RT_DEFINED))
1578 {
1579 return true; /* no error */
1580 }
1581
1582 struct argv argv = argv_new();
1583 struct gc_arena gc = gc_new();
1584
1585#if !defined(TARGET_LINUX)
1586 const char *network = print_in_addr_t(r->network, 0, &gc);
1587#if !defined(TARGET_AIX)
1588 const char *netmask = print_in_addr_t(r->netmask, 0, &gc);
1589#endif
1590 const char *gateway = print_in_addr_t(r->gateway, 0, &gc);
1591#endif
1592
1593 is_local_route = local_route(r->network, r->netmask, r->gateway, rgi);
1594 if (is_local_route == LR_ERROR)
1595 {
1596 goto done;
1597 }
1598
1599#if defined(TARGET_LINUX)
1600 const char *iface = NULL;
1601 int metric = -1;
1602
1603 if (is_on_link(is_local_route, flags, rgi))
1604 {
1605 iface = rgi->iface;
1606 }
1607
1608 if (r->flags & RT_METRIC_DEFINED)
1609 {
1610 metric = r->metric;
1611 }
1612
1614 int ret = net_route_v4_add(ctx, &r->network, netmask_to_netbits2(r->netmask),
1615 &r->gateway, iface, 0, metric);
1616 if (ret == -EEXIST)
1617 {
1618 msg(D_ROUTE, "NOTE: Linux route add command failed because route exists");
1620 }
1621 else if (ret < 0)
1622 {
1623 msg(M_WARN, "ERROR: Linux route add command failed");
1624 status = RTA_ERROR;
1625 }
1626
1627#elif defined (TARGET_ANDROID)
1628 char out[128];
1629
1630 if (rgi)
1631 {
1632 snprintf(out, sizeof(out), "%s %s %s dev %s", network, netmask, gateway, rgi->iface);
1633 }
1634 else
1635 {
1636 snprintf(out, sizeof(out), "%s %s %s", network, netmask, gateway);
1637 }
1638 bool ret = management_android_control(management, "ROUTE", out);
1639 status = ret ? RTA_SUCCESS : RTA_ERROR;
1640
1641#elif defined (_WIN32)
1642 {
1643 DWORD ai = TUN_ADAPTER_INDEX_INVALID;
1644 argv_printf(&argv, "%s%s ADD %s MASK %s %s",
1647 network,
1648 netmask,
1649 gateway);
1650 if (r->flags & RT_METRIC_DEFINED)
1651 {
1652 argv_printf_cat(&argv, "METRIC %d", r->metric);
1653 }
1654 if (is_on_link(is_local_route, flags, rgi))
1655 {
1656 ai = rgi->adapter_index;
1657 argv_printf_cat(&argv, "IF %lu", ai);
1658 }
1659
1661
1662 const char *method = "service";
1663 if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_SERVICE)
1664 {
1665 status = add_route_service(r, tt);
1666 }
1667 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
1668 {
1669 status = add_route_ipapi(r, tt, ai);
1670 method = "ipapi";
1671 }
1672 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_EXE)
1673 {
1675 bool ret = openvpn_execve_check(&argv, es, 0,
1676 "ERROR: Windows route add command failed");
1677 status = ret ? RTA_SUCCESS : RTA_ERROR;
1679 method = "route.exe";
1680 }
1681 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_ADAPTIVE)
1682 {
1683 status = add_route_ipapi(r, tt, ai);
1684 method = "ipapi [adaptive]";
1685 if (status == RTA_ERROR)
1686 {
1687 msg(D_ROUTE, "Route addition fallback to route.exe");
1689 bool ret = openvpn_execve_check(&argv, es, 0,
1690 "ERROR: Windows route add command failed [adaptive]");
1691 status = ret ? RTA_SUCCESS : RTA_ERROR;
1693 method = "route.exe";
1694 }
1695 }
1696 else
1697 {
1698 ASSERT(0);
1699 }
1700 if (status != RTA_ERROR) /* error is logged upstream */
1701 {
1702 msg(D_ROUTE, "Route addition via %s %s", method,
1703 (status == RTA_SUCCESS) ? "succeeded" : "failed because route exists");
1704 }
1705 }
1706
1707#elif defined (TARGET_SOLARIS)
1708
1709 /* example: route add 192.0.2.32 -netmask 255.255.255.224 somegateway */
1710
1711 argv_printf(&argv, "%s add",
1712 ROUTE_PATH);
1713
1714 argv_printf_cat(&argv, "%s -netmask %s %s",
1715 network,
1716 netmask,
1717 gateway);
1718
1719 /* Solaris can only distinguish between "metric 0" == "on-link on the
1720 * interface where the IP address given is configured" and "metric > 0"
1721 * == "use gateway specified" (no finer-grained route metrics available)
1722 *
1723 * More recent versions of Solaris can also do "-interface", but that
1724 * would break backwards compatibility with older versions for no gain.
1725 */
1726 if (r->flags & RT_METRIC_DEFINED)
1727 {
1728 argv_printf_cat(&argv, "%d", r->metric);
1729 }
1730
1732 bool ret = openvpn_execve_check(&argv, es, 0,
1733 "ERROR: Solaris route add command failed");
1734 status = ret ? RTA_SUCCESS : RTA_ERROR;
1735
1736#elif defined(TARGET_FREEBSD)
1737
1738 argv_printf(&argv, "%s add",
1739 ROUTE_PATH);
1740
1741#if 0
1742 if (r->flags & RT_METRIC_DEFINED)
1743 {
1744 argv_printf_cat(&argv, "-rtt %d", r->metric);
1745 }
1746#endif
1747
1748 argv_printf_cat(&argv, "-net %s %s %s",
1749 network,
1750 gateway,
1751 netmask);
1752
1753 /* FIXME -- add on-link support for FreeBSD */
1754
1756 bool ret = openvpn_execve_check(&argv, es, 0,
1757 "ERROR: FreeBSD route add command failed");
1758 status = ret ? RTA_SUCCESS : RTA_ERROR;
1759
1760#elif defined(TARGET_DRAGONFLY)
1761
1762 argv_printf(&argv, "%s add",
1763 ROUTE_PATH);
1764
1765#if 0
1766 if (r->flags & RT_METRIC_DEFINED)
1767 {
1768 argv_printf_cat(&argv, "-rtt %d", r->metric);
1769 }
1770#endif
1771
1772 argv_printf_cat(&argv, "-net %s %s %s",
1773 network,
1774 gateway,
1775 netmask);
1776
1777 /* FIXME -- add on-link support for Dragonfly */
1778
1780 bool ret = openvpn_execve_check(&argv, es, 0,
1781 "ERROR: DragonFly route add command failed");
1782 status = ret ? RTA_SUCCESS : RTA_ERROR;
1783
1784#elif defined(TARGET_DARWIN)
1785
1786 argv_printf(&argv, "%s add",
1787 ROUTE_PATH);
1788
1789#if 0
1790 if (r->flags & RT_METRIC_DEFINED)
1791 {
1792 argv_printf_cat(&argv, "-rtt %d", r->metric);
1793 }
1794#endif
1795
1796 if (is_on_link(is_local_route, flags, rgi))
1797 {
1798 /* Mac OS X route syntax for ON_LINK:
1799 * route add -cloning -net 10.10.0.1 -netmask 255.255.255.255 -interface en0 */
1800 argv_printf_cat(&argv, "-cloning -net %s -netmask %s -interface %s",
1801 network,
1802 netmask,
1803 rgi->iface);
1804 }
1805 else
1806 {
1807 argv_printf_cat(&argv, "-net %s %s %s",
1808 network,
1809 gateway,
1810 netmask);
1811 }
1812
1814 bool ret = openvpn_execve_check(&argv, es, 0,
1815 "ERROR: OS X route add command failed");
1816 status = ret ? RTA_SUCCESS : RTA_ERROR;
1817
1818#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1819
1820 argv_printf(&argv, "%s add",
1821 ROUTE_PATH);
1822
1823#if 0
1824 if (r->flags & RT_METRIC_DEFINED)
1825 {
1826 argv_printf_cat(&argv, "-rtt %d", r->metric);
1827 }
1828#endif
1829
1830 argv_printf_cat(&argv, "-net %s %s -netmask %s",
1831 network,
1832 gateway,
1833 netmask);
1834
1835 /* FIXME -- add on-link support for OpenBSD/NetBSD */
1836
1838 bool ret = openvpn_execve_check(&argv, es, 0,
1839 "ERROR: OpenBSD/NetBSD route add command failed");
1840 status = ret ? RTA_SUCCESS : RTA_ERROR;
1841
1842#elif defined(TARGET_AIX)
1843
1844 {
1845 int netbits = netmask_to_netbits2(r->netmask);
1846 argv_printf(&argv, "%s add -net %s/%d %s",
1847 ROUTE_PATH,
1848 network, netbits, gateway);
1850 bool ret = openvpn_execve_check(&argv, es, 0,
1851 "ERROR: AIX route add command failed");
1852 status = ret ? RTA_SUCCESS : RTA_ERROR;
1853 }
1854
1855#elif defined(TARGET_HAIKU)
1856
1857 /* ex: route add /dev/net/ipro1000/0 0.0.0.0 gw 192.168.1.1 netmask 128.0.0.0 */
1858 argv_printf(&argv, "%s add %s inet %s gw %s netmask %s",
1859 ROUTE_PATH,
1860 rgi->iface,
1861 network,
1862 gateway,
1863 netmask);
1865 bool ret = openvpn_execve_check(&argv, es, 0,
1866 "ERROR: Haiku inet route add command failed");
1867 status = ret ? RTA_SUCCESS : RTA_ERROR;
1868
1869#else /* if defined(TARGET_LINUX) */
1870 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");
1871#endif /* if defined(TARGET_LINUX) */
1872
1873done:
1874 if (status == RTA_SUCCESS)
1875 {
1876 r->flags |= RT_ADDED;
1877 }
1878 else
1879 {
1880 r->flags &= ~RT_ADDED;
1881 }
1882 argv_free(&argv);
1883 gc_free(&gc);
1884 /* release resources potentially allocated during route setup */
1885 net_ctx_reset(ctx);
1886
1887 return (status != RTA_ERROR);
1888}
1889
1890
1891void
1893{
1894 /* clear host bit parts of route
1895 * (needed if routes are specified improperly, or if we need to
1896 * explicitly setup/clear the "connected" network routes on some OSes)
1897 */
1898 int byte = 15;
1899 int bits_to_clear = 128 - r6->netbits;
1900
1901 while (byte >= 0 && bits_to_clear > 0)
1902 {
1903 if (bits_to_clear >= 8)
1904 {
1905 r6->network.s6_addr[byte--] = 0; bits_to_clear -= 8;
1906 }
1907 else
1908 {
1909 r6->network.s6_addr[byte--] &= (0xff << bits_to_clear); bits_to_clear = 0;
1910 }
1911 }
1912}
1913
1914bool
1915add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt,
1916 unsigned int flags, const struct env_set *es,
1917 openvpn_net_ctx_t *ctx)
1918{
1919 int status = 0;
1920 bool gateway_needed = false;
1921
1922 if (!(r6->flags & RT_DEFINED) )
1923 {
1924 return true; /* no error */
1925 }
1926
1927 struct argv argv = argv_new();
1928 struct gc_arena gc = gc_new();
1929
1930#ifndef _WIN32
1931 const char *device = tt->actual_name;
1932 if (r6->iface != NULL) /* vpn server special route */
1933 {
1934 device = r6->iface;
1935 if (!IN6_IS_ADDR_UNSPECIFIED(&r6->gateway) )
1936 {
1937 gateway_needed = true;
1938 }
1939 }
1940#endif
1941
1943 const char *network = print_in6_addr( r6->network, 0, &gc);
1944 const char *gateway = print_in6_addr( r6->gateway, 0, &gc);
1945
1946#if defined(TARGET_DARWIN) \
1947 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
1948 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1949
1950 /* the BSD platforms cannot specify gateway and interface independently,
1951 * but for link-local destinations, we MUST specify the interface, so
1952 * we build a combined "$gateway%$interface" gateway string
1953 */
1954 if (r6->iface != NULL && gateway_needed
1955 && IN6_IS_ADDR_LINKLOCAL(&r6->gateway) ) /* fe80::...%intf */
1956 {
1957 int len = strlen(gateway) + 1 + strlen(r6->iface)+1;
1958 char *tmp = gc_malloc( len, true, &gc );
1959 snprintf( tmp, len, "%s%%%s", gateway, r6->iface );
1960 gateway = tmp;
1961 }
1962#endif
1963
1964#ifndef _WIN32
1965 msg(D_ROUTE, "add_route_ipv6(%s/%d -> %s metric %d) dev %s",
1966 network, r6->netbits, gateway, r6->metric, device );
1967#else
1968 msg(D_ROUTE, "add_route_ipv6(%s/%d -> %s metric %d) IF %lu",
1969 network, r6->netbits, gateway, r6->metric,
1970 r6->adapter_index ? r6->adapter_index : tt->adapter_index);
1971#endif
1972
1973 /*
1974 * Filter out routes which are essentially no-ops
1975 * (not currently done for IPv6)
1976 */
1977
1978 /* On "tun" interface, we never set a gateway if the operating system
1979 * can do "route to interface" - it does not add value, as the target
1980 * dev already fully qualifies the route destination on point-to-point
1981 * interfaces. OTOH, on "tap" interface, we must always set the
1982 * gateway unless the route is to be an on-link network
1983 */
1984 if (tt->type == DEV_TYPE_TAP
1985 && !( (r6->flags & RT_METRIC_DEFINED) && r6->metric == 0 ) )
1986 {
1987 gateway_needed = true;
1988 }
1989
1990 if (gateway_needed && IN6_IS_ADDR_UNSPECIFIED(&r6->gateway))
1991 {
1992 msg(M_WARN, "ROUTE6 WARNING: " PACKAGE_NAME " needs a gateway "
1993 "parameter for a --route-ipv6 option and no default was set via "
1994 "--ifconfig-ipv6 or --route-ipv6-gateway option. Not installing "
1995 "IPv6 route to %s/%d.", network, r6->netbits);
1996 status = 0;
1997 goto done;
1998 }
1999
2000#if defined(TARGET_LINUX)
2001 int metric = -1;
2002 if ((r6->flags & RT_METRIC_DEFINED) && (r6->metric > 0))
2003 {
2004 metric = r6->metric;
2005 }
2006
2008 int ret = net_route_v6_add(ctx, &r6->network, r6->netbits,
2009 gateway_needed ? &r6->gateway : NULL,
2010 device, 0, metric);
2011 if (ret == -EEXIST)
2012 {
2013 msg(D_ROUTE, "NOTE: Linux route add command failed because route exists");
2015 }
2016 else if (ret < 0)
2017 {
2018 msg(M_WARN, "ERROR: Linux route add command failed");
2019 status = RTA_ERROR;
2020 }
2021
2022#elif defined (TARGET_ANDROID)
2023 char out[64];
2024
2025 snprintf(out, sizeof(out), "%s/%d %s", network, r6->netbits, device);
2026
2027 status = management_android_control(management, "ROUTE6", out);
2028
2029#elif defined (_WIN32)
2030
2031 if (tt->options.msg_channel)
2032 {
2034 }
2035 else
2036 {
2037 status = route_ipv6_ipapi(true, r6, tt);
2038 }
2039#elif defined (TARGET_SOLARIS)
2040
2041 /* example: route add -inet6 2001:db8::/32 somegateway 0 */
2042
2043 /* for some reason, routes to tun/tap do not work for me unless I set
2044 * "metric 0" - otherwise, the routes will be nicely installed, but
2045 * packets will just disappear somewhere. So we always use "0" now,
2046 * unless the route points to "gateway on other interface"...
2047 *
2048 * (Note: OpenSolaris can not specify host%interface gateways, so we just
2049 * use the GW addresses - it seems to still work for fe80:: addresses,
2050 * however this is done internally. NUD maybe?)
2051 */
2052 argv_printf(&argv, "%s add -inet6 %s/%d %s",
2053 ROUTE_PATH,
2054 network,
2055 r6->netbits,
2056 gateway );
2057
2058 /* on tun (not tap), not "elsewhere"? -> metric 0 */
2059 if (tt->type == DEV_TYPE_TUN && !r6->iface)
2060 {
2061 argv_printf_cat(&argv, "0");
2062 }
2063
2065 bool ret = openvpn_execve_check(&argv, es, 0,
2066 "ERROR: Solaris route add -inet6 command failed");
2067 status = ret ? RTA_SUCCESS : RTA_ERROR;
2068
2069#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
2070
2071 argv_printf(&argv, "%s add -inet6 %s/%d",
2072 ROUTE_PATH,
2073 network,
2074 r6->netbits);
2075
2076 if (gateway_needed)
2077 {
2078 argv_printf_cat(&argv, "%s", gateway);
2079 }
2080 else
2081 {
2082 argv_printf_cat(&argv, "-iface %s", device);
2083 }
2084
2086 bool ret = openvpn_execve_check(&argv, es, 0,
2087 "ERROR: *BSD route add -inet6 command failed");
2088 status = ret ? RTA_SUCCESS : RTA_ERROR;
2089
2090#elif defined(TARGET_DARWIN)
2091
2092 argv_printf(&argv, "%s add -inet6 %s -prefixlen %d",
2093 ROUTE_PATH,
2094 network, r6->netbits );
2095
2096 if (gateway_needed)
2097 {
2098 argv_printf_cat(&argv, "%s", gateway);
2099 }
2100 else
2101 {
2102 argv_printf_cat(&argv, "-iface %s", device);
2103 }
2104
2106 bool ret = openvpn_execve_check(&argv, es, 0,
2107 "ERROR: MacOS X route add -inet6 command failed");
2108 status = ret ? RTA_SUCCESS : RTA_ERROR;
2109
2110#elif defined(TARGET_OPENBSD)
2111
2112 argv_printf(&argv, "%s add -inet6 %s -prefixlen %d %s",
2113 ROUTE_PATH,
2114 network, r6->netbits, gateway );
2115
2117 bool ret = openvpn_execve_check(&argv, es, 0,
2118 "ERROR: OpenBSD route add -inet6 command failed");
2119 status = ret ? RTA_SUCCESS : RTA_ERROR;
2120
2121#elif defined(TARGET_NETBSD)
2122
2123 argv_printf(&argv, "%s add -inet6 %s/%d %s",
2124 ROUTE_PATH,
2125 network, r6->netbits, gateway );
2126
2128 bool ret = openvpn_execve_check(&argv, es, 0,
2129 "ERROR: NetBSD route add -inet6 command failed");
2130 status = ret ? RTA_SUCCESS : RTA_ERROR;
2131
2132#elif defined(TARGET_AIX)
2133
2134 argv_printf(&argv, "%s add -inet6 %s/%d %s",
2135 ROUTE_PATH,
2136 network, r6->netbits, gateway);
2138 bool ret = openvpn_execve_check(&argv, es, 0,
2139 "ERROR: AIX route add command failed");
2140 status = ret ? RTA_SUCCESS : RTA_ERROR;
2141
2142#elif defined(TARGET_HAIKU)
2143
2144 /* ex: route add /dev/net/ipro1000/0 inet6 :: gw beef::cafe prefixlen 64 */
2145 argv_printf(&argv, "%s add %s inet6 %s gw %s prefixlen %d",
2146 ROUTE_PATH,
2147 r6->iface,
2148 network,
2149 gateway,
2150 r6->netbits);
2152 bool ret = openvpn_execve_check(&argv, es, 0,
2153 "ERROR: Haiku inet6 route add command failed");
2154 status = ret ? RTA_SUCCESS : RTA_ERROR;
2155
2156#else /* if defined(TARGET_LINUX) */
2157 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");
2158#endif /* if defined(TARGET_LINUX) */
2159
2160done:
2161 if (status == RTA_SUCCESS)
2162 {
2163 r6->flags |= RT_ADDED;
2164 }
2165 else
2166 {
2167 r6->flags &= ~RT_ADDED;
2168 }
2169 argv_free(&argv);
2170 gc_free(&gc);
2171 /* release resources potentially allocated during route setup */
2172 net_ctx_reset(ctx);
2173
2174 return (status != RTA_ERROR);
2175}
2176
2177static void
2179 const struct tuntap *tt,
2180 unsigned int flags,
2181 const struct route_gateway_info *rgi,
2182 const struct env_set *es,
2183 openvpn_net_ctx_t *ctx)
2184{
2185#if !defined(TARGET_LINUX)
2186 const char *network;
2187#if !defined(TARGET_AIX)
2188 const char *netmask;
2189#endif
2190#if !defined(TARGET_ANDROID)
2191 const char *gateway;
2192#endif
2193#else /* if !defined(TARGET_LINUX) */
2194 int metric;
2195#endif
2196 int is_local_route;
2197
2198 if ((r->flags & (RT_DEFINED|RT_ADDED)) != (RT_DEFINED|RT_ADDED))
2199 {
2200 return;
2201 }
2202
2203 struct gc_arena gc = gc_new();
2204 struct argv argv = argv_new();
2205
2206#if !defined(TARGET_LINUX)
2207 network = print_in_addr_t(r->network, 0, &gc);
2208#if !defined(TARGET_AIX)
2209 netmask = print_in_addr_t(r->netmask, 0, &gc);
2210#endif
2211#if !defined(TARGET_ANDROID)
2212 gateway = print_in_addr_t(r->gateway, 0, &gc);
2213#endif
2214#endif
2215
2216 is_local_route = local_route(r->network, r->netmask, r->gateway, rgi);
2217 if (is_local_route == LR_ERROR)
2218 {
2219 goto done;
2220 }
2221
2222#if defined(TARGET_LINUX)
2223 metric = -1;
2224 if (r->flags & RT_METRIC_DEFINED)
2225 {
2226 metric = r->metric;
2227 }
2228
2229 if (net_route_v4_del(ctx, &r->network, netmask_to_netbits2(r->netmask),
2230 &r->gateway, NULL, 0, metric) < 0)
2231 {
2232 msg(M_WARN, "ERROR: Linux route delete command failed");
2233 }
2234#elif defined (_WIN32)
2235
2236 argv_printf(&argv, "%s%s DELETE %s MASK %s %s",
2239 network,
2240 netmask,
2241 gateway);
2242
2244
2245 if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_SERVICE)
2246 {
2247 const bool status = del_route_service(r, tt);
2248 msg(D_ROUTE, "Route deletion via service %s", status ? "succeeded" : "failed");
2249 }
2250 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
2251 {
2252 const bool status = del_route_ipapi(r, tt);
2253 msg(D_ROUTE, "Route deletion via IPAPI %s", status ? "succeeded" : "failed");
2254 }
2255 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_EXE)
2256 {
2258 openvpn_execve_check(&argv, es, 0, "ERROR: Windows route delete command failed");
2260 }
2261 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_ADAPTIVE)
2262 {
2263 const bool status = del_route_ipapi(r, tt);
2264 msg(D_ROUTE, "Route deletion via IPAPI %s [adaptive]", status ? "succeeded" : "failed");
2265 if (!status)
2266 {
2267 msg(D_ROUTE, "Route deletion fallback to route.exe");
2269 openvpn_execve_check(&argv, es, 0, "ERROR: Windows route delete command failed [adaptive]");
2271 }
2272 }
2273 else
2274 {
2275 ASSERT(0);
2276 }
2277
2278#elif defined (TARGET_SOLARIS)
2279
2280 argv_printf(&argv, "%s delete %s -netmask %s %s",
2281 ROUTE_PATH,
2282 network,
2283 netmask,
2284 gateway);
2285
2287 openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route delete command failed");
2288
2289#elif defined(TARGET_FREEBSD)
2290
2291 argv_printf(&argv, "%s delete -net %s %s %s",
2292 ROUTE_PATH,
2293 network,
2294 gateway,
2295 netmask);
2296
2298 openvpn_execve_check(&argv, es, 0, "ERROR: FreeBSD route delete command failed");
2299
2300#elif defined(TARGET_DRAGONFLY)
2301
2302 argv_printf(&argv, "%s delete -net %s %s %s",
2303 ROUTE_PATH,
2304 network,
2305 gateway,
2306 netmask);
2307
2309 openvpn_execve_check(&argv, es, 0, "ERROR: DragonFly route delete command failed");
2310
2311#elif defined(TARGET_DARWIN)
2312
2313 if (is_on_link(is_local_route, flags, rgi))
2314 {
2315 argv_printf(&argv, "%s delete -cloning -net %s -netmask %s -interface %s",
2316 ROUTE_PATH,
2317 network,
2318 netmask,
2319 rgi->iface);
2320 }
2321 else
2322 {
2323 argv_printf(&argv, "%s delete -net %s %s %s",
2324 ROUTE_PATH,
2325 network,
2326 gateway,
2327 netmask);
2328 }
2329
2331 openvpn_execve_check(&argv, es, 0, "ERROR: OS X route delete command failed");
2332
2333#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2334
2335 argv_printf(&argv, "%s delete -net %s %s -netmask %s",
2336 ROUTE_PATH,
2337 network,
2338 gateway,
2339 netmask);
2340
2342 openvpn_execve_check(&argv, es, 0, "ERROR: OpenBSD/NetBSD route delete command failed");
2343
2344#elif defined(TARGET_ANDROID)
2345 msg(D_ROUTE_DEBUG, "Deleting routes on Android is not possible/not "
2346 "needed. The VpnService API allows routes to be set "
2347 "on connect only and will clean up automatically.");
2348#elif defined(TARGET_AIX)
2349
2350 {
2351 int netbits = netmask_to_netbits2(r->netmask);
2352 argv_printf(&argv, "%s delete -net %s/%d %s",
2353 ROUTE_PATH,
2354 network, netbits, gateway);
2356 openvpn_execve_check(&argv, es, 0, "ERROR: AIX route delete command failed");
2357 }
2358
2359#elif defined(TARGET_HAIKU)
2360
2361 /* ex: route delete /dev/net/ipro1000/0 inet 192.168.0.0 gw 192.168.1.1 netmask 255.255.0.0 */
2362 argv_printf(&argv, "%s delete %s inet %s gw %s netmask %s",
2363 ROUTE_PATH,
2364 rgi->iface,
2365 network,
2366 gateway,
2367 netmask);
2369 openvpn_execve_check(&argv, es, 0, "ERROR: Haiku inet route delete command failed");
2370
2371#else /* if defined(TARGET_LINUX) */
2372 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");
2373#endif /* if defined(TARGET_LINUX) */
2374
2375done:
2376 r->flags &= ~RT_ADDED;
2377 argv_free(&argv);
2378 gc_free(&gc);
2379 /* release resources potentially allocated during route cleanup */
2380 net_ctx_reset(ctx);
2381}
2382
2383void
2384delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt,
2385 const struct env_set *es,
2386 openvpn_net_ctx_t *ctx)
2387{
2388 const char *network;
2389
2390 if ((r6->flags & (RT_DEFINED|RT_ADDED)) != (RT_DEFINED|RT_ADDED))
2391 {
2392 return;
2393 }
2394
2395#if !defined(_WIN32)
2396#if !defined(TARGET_LINUX)
2397 const char *gateway;
2398#endif
2399#if !defined(TARGET_SOLARIS)
2400 bool gateway_needed = false;
2401 const char *device = tt->actual_name;
2402 if (r6->iface != NULL) /* vpn server special route */
2403 {
2404 device = r6->iface;
2405 gateway_needed = true;
2406 }
2407
2408 /* if we used a gateway on "add route", we also need to specify it on
2409 * delete, otherwise some OSes will refuse to delete the route
2410 */
2411 if (tt->type == DEV_TYPE_TAP
2412 && !( (r6->flags & RT_METRIC_DEFINED) && r6->metric == 0 ) )
2413 {
2414 gateway_needed = true;
2415 }
2416#endif
2417#endif
2418
2419 struct gc_arena gc = gc_new();
2420 struct argv argv = argv_new();
2421
2422 network = print_in6_addr( r6->network, 0, &gc);
2423#if !defined(TARGET_LINUX) && !defined(_WIN32)
2424 gateway = print_in6_addr( r6->gateway, 0, &gc);
2425#endif
2426
2427#if defined(TARGET_DARWIN) \
2428 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
2429 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2430
2431 /* the BSD platforms cannot specify gateway and interface independently,
2432 * but for link-local destinations, we MUST specify the interface, so
2433 * we build a combined "$gateway%$interface" gateway string
2434 */
2435 if (r6->iface != NULL && gateway_needed
2436 && IN6_IS_ADDR_LINKLOCAL(&r6->gateway) ) /* fe80::...%intf */
2437 {
2438 int len = strlen(gateway) + 1 + strlen(r6->iface)+1;
2439 char *tmp = gc_malloc( len, true, &gc );
2440 snprintf( tmp, len, "%s%%%s", gateway, r6->iface );
2441 gateway = tmp;
2442 }
2443#endif
2444
2445 msg(D_ROUTE, "delete_route_ipv6(%s/%d)", network, r6->netbits );
2446
2447#if defined(TARGET_LINUX)
2448 int metric = -1;
2449 if ((r6->flags & RT_METRIC_DEFINED) && (r6->metric > 0))
2450 {
2451 metric = r6->metric;
2452 }
2453
2454 if (net_route_v6_del(ctx, &r6->network, r6->netbits,
2455 gateway_needed ? &r6->gateway : NULL, device, 0,
2456 metric) < 0)
2457 {
2458 msg(M_WARN, "ERROR: Linux route v6 delete command failed");
2459 }
2460
2461#elif defined (_WIN32)
2462
2463 if (tt->options.msg_channel)
2464 {
2465 del_route_ipv6_service(r6, tt);
2466 }
2467 else
2468 {
2469 route_ipv6_ipapi(false, r6, tt);
2470 }
2471#elif defined (TARGET_SOLARIS)
2472
2473 /* example: route delete -inet6 2001:db8::/32 somegateway */
2474
2475 argv_printf(&argv, "%s delete -inet6 %s/%d %s",
2476 ROUTE_PATH,
2477 network,
2478 r6->netbits,
2479 gateway );
2480
2482 openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route delete -inet6 command failed");
2483
2484#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
2485
2486 argv_printf(&argv, "%s delete -inet6 %s/%d",
2487 ROUTE_PATH,
2488 network,
2489 r6->netbits );
2490
2491 if (gateway_needed)
2492 {
2493 argv_printf_cat(&argv, "%s", gateway);
2494 }
2495 else
2496 {
2497 argv_printf_cat(&argv, "-iface %s", device);
2498 }
2499
2501 openvpn_execve_check(&argv, es, 0, "ERROR: *BSD route delete -inet6 command failed");
2502
2503#elif defined(TARGET_DARWIN)
2504
2505 argv_printf(&argv, "%s delete -inet6 %s -prefixlen %d",
2506 ROUTE_PATH,
2507 network, r6->netbits );
2508
2509 if (gateway_needed)
2510 {
2511 argv_printf_cat(&argv, "%s", gateway);
2512 }
2513 else
2514 {
2515 argv_printf_cat(&argv, "-iface %s", device);
2516 }
2517
2519 openvpn_execve_check(&argv, es, 0, "ERROR: MacOS X route delete -inet6 command failed");
2520
2521#elif defined(TARGET_OPENBSD)
2522
2523 argv_printf(&argv, "%s delete -inet6 %s -prefixlen %d %s",
2524 ROUTE_PATH,
2525 network, r6->netbits, gateway );
2526
2528 openvpn_execve_check(&argv, es, 0, "ERROR: OpenBSD route delete -inet6 command failed");
2529
2530#elif defined(TARGET_NETBSD)
2531
2532 argv_printf(&argv, "%s delete -inet6 %s/%d %s",
2533 ROUTE_PATH,
2534 network, r6->netbits, gateway );
2535
2537 openvpn_execve_check(&argv, es, 0, "ERROR: NetBSD route delete -inet6 command failed");
2538
2539#elif defined(TARGET_AIX)
2540
2541 argv_printf(&argv, "%s delete -inet6 %s/%d %s",
2542 ROUTE_PATH,
2543 network, r6->netbits, gateway);
2545 openvpn_execve_check(&argv, es, 0, "ERROR: AIX route add command failed");
2546
2547#elif defined(TARGET_ANDROID)
2548 msg(D_ROUTE_DEBUG, "Deleting routes on Android is not possible/not "
2549 "needed. The VpnService API allows routes to be set "
2550 "on connect only and will clean up automatically.");
2551#elif defined(TARGET_HAIKU)
2552
2553 /* ex: route delete /dev/net/ipro1000/0 inet6 :: gw beef::cafe prefixlen 64 */
2554 argv_printf(&argv, "%s delete %s inet6 %s gw %s prefixlen %d",
2555 ROUTE_PATH,
2556 r6->iface,
2557 network,
2558 gateway,
2559 r6->netbits);
2561 openvpn_execve_check(&argv, es, 0, "ERROR: Haiku inet6 route delete command failed");
2562
2563#else /* if defined(TARGET_LINUX) */
2564 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");
2565#endif /* if defined(TARGET_LINUX) */
2566
2567 argv_free(&argv);
2568 gc_free(&gc);
2569 /* release resources potentially allocated during route cleanup */
2570 net_ctx_reset(ctx);
2571}
2572
2573/*
2574 * The --redirect-gateway option requires OS-specific code below
2575 * to get the current default gateway.
2576 */
2577
2578#if defined(_WIN32)
2579
2580static const MIB_IPFORWARDTABLE *
2582{
2583 ULONG size = 0;
2584 PMIB_IPFORWARDTABLE rt = NULL;
2585 DWORD status;
2586
2587 status = GetIpForwardTable(NULL, &size, TRUE);
2588 if (status == ERROR_INSUFFICIENT_BUFFER)
2589 {
2590 rt = (PMIB_IPFORWARDTABLE) gc_malloc(size, false, gc);
2591 status = GetIpForwardTable(rt, &size, TRUE);
2592 if (status != NO_ERROR)
2593 {
2594 msg(D_ROUTE, "NOTE: GetIpForwardTable returned error: %s (code=%u)",
2596 (unsigned int)status);
2597 rt = NULL;
2598 }
2599 }
2600 return rt;
2601}
2602
2603static int
2604test_route(const IP_ADAPTER_INFO *adapters,
2605 const in_addr_t gateway,
2606 DWORD *index)
2607{
2608 int count = 0;
2609 DWORD i = adapter_index_of_ip(adapters, gateway, &count, NULL);
2610 if (index)
2611 {
2612 *index = i;
2613 }
2614 return count;
2615}
2616
2617static void
2619 int *count,
2620 int *good,
2621 int *ambig,
2622 const IP_ADAPTER_INFO *adapters,
2623 const in_addr_t gateway)
2624{
2625 int c;
2626
2627 ++*count;
2628 c = test_route(adapters, gateway, NULL);
2629 if (c == 0)
2630 {
2631 *ret = false;
2632 }
2633 else
2634 {
2635 ++*good;
2636 }
2637 if (c > 1)
2638 {
2639 ++*ambig;
2640 }
2641}
2642
2643/*
2644 * If we tried to add routes now, would we succeed?
2645 */
2646bool
2647test_routes(const struct route_list *rl, const struct tuntap *tt)
2648{
2649 struct gc_arena gc = gc_new();
2650 const IP_ADAPTER_INFO *adapters = get_adapter_info_list(&gc);
2651 bool ret = false;
2652 int count = 0;
2653 int good = 0;
2654 int ambig = 0;
2655 int len = -1;
2656 bool adapter_up = false;
2657
2658 if (is_adapter_up(tt, adapters))
2659 {
2660 ret = true;
2661 adapter_up = true;
2662
2663 /* we do this test only if we have IPv4 routes to install, and if
2664 * the tun/tap interface has seen IPv4 ifconfig - because if we
2665 * have no IPv4, the check will always fail, failing tun init
2666 */
2667 if (rl && tt->did_ifconfig_setup)
2668 {
2669 struct route_ipv4 *r;
2670 for (r = rl->routes, len = 0; r; r = r->next, ++len)
2671 {
2672 test_route_helper(&ret, &count, &good, &ambig, adapters, r->gateway);
2673 }
2674
2675 if ((rl->flags & RG_ENABLE) && (rl->spec.flags & RTSA_REMOTE_ENDPOINT))
2676 {
2677 test_route_helper(&ret, &count, &good, &ambig, adapters, rl->spec.remote_endpoint);
2678 }
2679 }
2680 }
2681
2682 msg(D_ROUTE, "TEST ROUTES: %d/%d succeeded len=%d ret=%d a=%d u/d=%s",
2683 good,
2684 count,
2685 len,
2686 (int)ret,
2687 ambig,
2688 adapter_up ? "up" : "down");
2689
2690 gc_free(&gc);
2691 return ret;
2692}
2693
2694static const MIB_IPFORWARDROW *
2695get_default_gateway_row(const MIB_IPFORWARDTABLE *routes)
2696{
2697 struct gc_arena gc = gc_new();
2698 DWORD lowest_metric = MAXDWORD;
2699 const MIB_IPFORWARDROW *ret = NULL;
2700 int best = -1;
2701
2702 if (routes)
2703 {
2704 for (DWORD i = 0; i < routes->dwNumEntries; ++i)
2705 {
2706 const MIB_IPFORWARDROW *row = &routes->table[i];
2707 const in_addr_t net = ntohl(row->dwForwardDest);
2708 const in_addr_t mask = ntohl(row->dwForwardMask);
2709 const DWORD index = row->dwForwardIfIndex;
2710 const DWORD metric = row->dwForwardMetric1;
2711
2712 dmsg(D_ROUTE_DEBUG, "GDGR: route[%lu] %s/%s i=%d m=%d",
2713 i,
2714 print_in_addr_t((in_addr_t) net, 0, &gc),
2715 print_in_addr_t((in_addr_t) mask, 0, &gc),
2716 (int)index,
2717 (int)metric);
2718
2719 if (!net && !mask && metric < lowest_metric)
2720 {
2721 ret = row;
2722 lowest_metric = metric;
2723 best = i;
2724 }
2725 }
2726 }
2727
2728 dmsg(D_ROUTE_DEBUG, "GDGR: best=%d lm=%u", best, (unsigned int)lowest_metric);
2729
2730 gc_free(&gc);
2731 return ret;
2732}
2733
2745static DWORD
2746get_best_route(struct gc_arena *gc, SOCKADDR_INET *dest, MIB_IPFORWARD_ROW2 *best_route)
2747{
2748 DWORD best_if_index;
2749 DWORD status;
2750
2751 CLEAR(*best_route);
2752
2753 /* get the best interface index to reach dest */
2754 status = GetBestInterfaceEx((struct sockaddr *)dest, &best_if_index);
2755 if (status != NO_ERROR)
2756 {
2757 msg(D_ROUTE, "NOTE: GetBestInterfaceEx returned error: %s (code=%u)",
2759 (unsigned int)status);
2760 goto done;
2761 }
2762
2763 msg(D_ROUTE_DEBUG, "GetBestInterfaceEx() returned if=%d", (int)best_if_index);
2764
2765 /* get the routing information (such as NextHop) for the destination and interface */
2766 NET_LUID luid;
2767 CLEAR(luid);
2768 SOCKADDR_INET best_src;
2769 CLEAR(best_src);
2770 status = GetBestRoute2(&luid, best_if_index, NULL,
2771 dest, 0, best_route, &best_src);
2772 if (status != NO_ERROR)
2773 {
2774 msg(D_ROUTE, "NOTE: GetIpForwardEntry2 returned error: %s (code=%u)",
2776 (unsigned int)status);
2777 goto done;
2778 }
2779
2780done:
2781 return status;
2782}
2783
2784void
2786{
2787 CLEAR(*rgi);
2788
2789 struct gc_arena gc = gc_new();
2790
2791 /* convert in_addr_t into SOCKADDR_INET */
2792 SOCKADDR_INET sa;
2793 CLEAR(sa);
2794 sa.si_family = AF_INET;
2795 sa.Ipv4.sin_addr.s_addr = htonl(dest);
2796
2797 /* get the best route to the destination */
2798 MIB_IPFORWARD_ROW2 best_route;
2799 CLEAR(best_route);
2800 DWORD status = get_best_route(&gc, &sa, &best_route);
2801 if (status != NO_ERROR)
2802 {
2803 goto done;
2804 }
2805
2807 rgi->gateway.addr = ntohl(best_route.NextHop.Ipv4.sin_addr.S_un.S_addr);
2808 rgi->adapter_index = best_route.InterfaceIndex;
2809
2810 if (rgi->gateway.addr == INADDR_ANY)
2811 {
2812 rgi->flags |= RGI_ON_LINK;
2813 }
2814
2815 /* get netmask and MAC address */
2816 const IP_ADAPTER_INFO *adapters = get_adapter_info_list(&gc);
2817 const IP_ADAPTER_INFO *ai = get_adapter(adapters, rgi->adapter_index);
2818 if (ai)
2819 {
2820 memcpy(rgi->hwaddr, ai->Address, 6);
2821 rgi->flags |= RGI_HWADDR_DEFINED;
2822
2823 /* get netmask for non-onlink routes */
2824 in_addr_t nm = inet_addr(ai->IpAddressList.IpMask.String);
2825 if (!(rgi->flags & RGI_ON_LINK) && (nm != INADDR_NONE))
2826 {
2827 rgi->gateway.netmask = ntohl(nm);
2828 rgi->flags |= RGI_NETMASK_DEFINED;
2829 }
2830 }
2831
2832done:
2833 gc_free(&gc);
2834}
2835
2836static DWORD
2837windows_route_find_if_index(const struct route_ipv4 *r, const struct tuntap *tt)
2838{
2839 struct gc_arena gc = gc_new();
2840 DWORD ret = TUN_ADAPTER_INDEX_INVALID;
2841 int count = 0;
2842 const IP_ADAPTER_INFO *adapters = get_adapter_info_list(&gc);
2843 const IP_ADAPTER_INFO *tun_adapter = get_tun_adapter(tt, adapters);
2844 bool on_tun = false;
2845
2846 /* first test on tun interface */
2847 if (is_ip_in_adapter_subnet(tun_adapter, r->gateway, NULL))
2848 {
2849 ret = tun_adapter->Index;
2850 count = 1;
2851 on_tun = true;
2852 }
2853 else /* test on other interfaces */
2854 {
2855 count = test_route(adapters, r->gateway, &ret);
2856 }
2857
2858 if (count == 0)
2859 {
2860 msg(M_WARN, "Warning: route gateway is not reachable on any active network adapters: %s",
2861 print_in_addr_t(r->gateway, 0, &gc));
2863 }
2864 else if (count > 1)
2865 {
2866 msg(M_WARN, "Warning: route gateway is ambiguous: %s (%d matches)",
2867 print_in_addr_t(r->gateway, 0, &gc),
2868 count);
2869 }
2870
2871 dmsg(D_ROUTE_DEBUG, "DEBUG: route find if: on_tun=%d count=%d index=%d",
2872 on_tun,
2873 count,
2874 (int)ret);
2875
2876 gc_free(&gc);
2877 return ret;
2878}
2879
2880/* IPv6 implementation using GetBestRoute2()
2881 * (TBD: dynamic linking so the binary can still run on XP?)
2882 * https://msdn.microsoft.com/en-us/library/windows/desktop/aa365922(v=vs.85).aspx
2883 * https://msdn.microsoft.com/en-us/library/windows/desktop/aa814411(v=vs.85).aspx
2884 */
2885void
2887 const struct in6_addr *dest, openvpn_net_ctx_t *ctx)
2888{
2889 struct gc_arena gc = gc_new();
2890 CLEAR(*rgi6);
2891
2892 SOCKADDR_INET DestinationAddress;
2893 CLEAR(DestinationAddress);
2894 DestinationAddress.si_family = AF_INET6;
2895 if (dest)
2896 {
2897 DestinationAddress.Ipv6.sin6_addr = *dest;
2898 }
2899
2900 MIB_IPFORWARD_ROW2 BestRoute;
2901 CLEAR(BestRoute);
2902 DWORD status = get_best_route(&gc, &DestinationAddress, &BestRoute);
2903
2904 if (status != NO_ERROR)
2905 {
2906 goto done;
2907 }
2908
2909 msg( D_ROUTE, "GDG6: II=%lu DP=%s/%d NH=%s",
2910 BestRoute.InterfaceIndex,
2911 print_in6_addr( BestRoute.DestinationPrefix.Prefix.Ipv6.sin6_addr, 0, &gc),
2912 BestRoute.DestinationPrefix.PrefixLength,
2913 print_in6_addr( BestRoute.NextHop.Ipv6.sin6_addr, 0, &gc) );
2914 msg( D_ROUTE, "GDG6: Metric=%d, Loopback=%d, AA=%d, I=%d",
2915 (int) BestRoute.Metric,
2916 (int) BestRoute.Loopback,
2917 (int) BestRoute.AutoconfigureAddress,
2918 (int) BestRoute.Immortal );
2919
2920 rgi6->gateway.addr_ipv6 = BestRoute.NextHop.Ipv6.sin6_addr;
2921 rgi6->adapter_index = BestRoute.InterfaceIndex;
2923
2924 /* on-link is signalled by receiving an empty (::) NextHop */
2925 if (IN6_IS_ADDR_UNSPECIFIED(&BestRoute.NextHop.Ipv6.sin6_addr) )
2926 {
2927 rgi6->flags |= RGI_ON_LINK;
2928 }
2929
2930done:
2931 gc_free(&gc);
2932}
2933
2934/* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
2935static int
2936add_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt, DWORD adapter_index)
2937{
2938 struct gc_arena gc = gc_new();
2939 int ret = RTA_ERROR;
2940 DWORD status;
2941 const DWORD if_index = (adapter_index == TUN_ADAPTER_INDEX_INVALID) ? windows_route_find_if_index(r, tt) : adapter_index;
2942
2943 if (if_index != TUN_ADAPTER_INDEX_INVALID)
2944 {
2945 MIB_IPFORWARDROW fr;
2946 CLEAR(fr);
2947 fr.dwForwardDest = htonl(r->network);
2948 fr.dwForwardMask = htonl(r->netmask);
2949 fr.dwForwardPolicy = 0;
2950 fr.dwForwardNextHop = htonl(r->gateway);
2951 fr.dwForwardIfIndex = if_index;
2952 fr.dwForwardType = 4; /* the next hop is not the final dest */
2953 fr.dwForwardProto = 3; /* PROTO_IP_NETMGMT */
2954 fr.dwForwardAge = 0;
2955 fr.dwForwardNextHopAS = 0;
2956 fr.dwForwardMetric1 = (r->flags & RT_METRIC_DEFINED) ? r->metric : 1;
2957 fr.dwForwardMetric2 = METRIC_NOT_USED;
2958 fr.dwForwardMetric3 = METRIC_NOT_USED;
2959 fr.dwForwardMetric4 = METRIC_NOT_USED;
2960 fr.dwForwardMetric5 = METRIC_NOT_USED;
2961
2962 if ((r->network & r->netmask) != r->network)
2963 {
2964 msg(M_WARN, "Warning: address %s is not a network address in relation to netmask %s",
2965 print_in_addr_t(r->network, 0, &gc),
2966 print_in_addr_t(r->netmask, 0, &gc));
2967 }
2968
2969 status = CreateIpForwardEntry(&fr);
2970
2971 if (status == NO_ERROR)
2972 {
2973 ret = RTA_SUCCESS;
2974 }
2975 else if (status == ERROR_OBJECT_ALREADY_EXISTS)
2976 {
2977 ret = RTA_EEXIST;
2978 }
2979 else
2980 {
2981 /* failed, try increasing the metric to work around Vista issue */
2982 const unsigned int forward_metric_limit = 2048; /* iteratively retry higher metrics up to this limit */
2983
2984 for (; fr.dwForwardMetric1 <= forward_metric_limit; ++fr.dwForwardMetric1)
2985 {
2986 /* try a different forward type=3 ("the next hop is the final dest") in addition to 4.
2987 * --redirect-gateway over RRAS seems to need this. */
2988 for (fr.dwForwardType = 4; fr.dwForwardType >= 3; --fr.dwForwardType)
2989 {
2990 status = CreateIpForwardEntry(&fr);
2991 if (status == NO_ERROR)
2992 {
2993 msg(D_ROUTE, "ROUTE: CreateIpForwardEntry succeeded with dwForwardMetric1=%u and dwForwardType=%u",
2994 (unsigned int)fr.dwForwardMetric1,
2995 (unsigned int)fr.dwForwardType);
2996 ret = RTA_SUCCESS;
2997 goto doublebreak;
2998 }
2999 else if (status != ERROR_BAD_ARGUMENTS)
3000 {
3001 goto doublebreak;
3002 }
3003 }
3004 }
3005
3006doublebreak:
3007 if (status != NO_ERROR)
3008 {
3009 if (status == ERROR_OBJECT_ALREADY_EXISTS)
3010 {
3011 ret = RTA_EEXIST;
3012 }
3013 else
3014 {
3015 msg(M_WARN, "ERROR: route addition failed using CreateIpForwardEntry: "
3016 "%s [status=%u if_index=%u]", strerror_win32(status, &gc),
3017 (unsigned int)status, (unsigned int)if_index);
3018 }
3019 }
3020 }
3021 }
3022
3023 gc_free(&gc);
3024 return ret;
3025}
3026
3027static bool
3028del_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt)
3029{
3030 struct gc_arena gc = gc_new();
3031 bool ret = false;
3032 DWORD status;
3033 const DWORD if_index = windows_route_find_if_index(r, tt);
3034
3035 if (if_index != TUN_ADAPTER_INDEX_INVALID)
3036 {
3037 MIB_IPFORWARDROW fr;
3038 CLEAR(fr);
3039
3040 fr.dwForwardDest = htonl(r->network);
3041 fr.dwForwardMask = htonl(r->netmask);
3042 fr.dwForwardPolicy = 0;
3043 fr.dwForwardNextHop = htonl(r->gateway);
3044 fr.dwForwardIfIndex = if_index;
3045
3046 status = DeleteIpForwardEntry(&fr);
3047
3048 if (status == NO_ERROR)
3049 {
3050 ret = true;
3051 }
3052 else
3053 {
3054 msg(M_WARN, "ERROR: route deletion failed using DeleteIpForwardEntry: %s",
3056 }
3057 }
3058
3059 gc_free(&gc);
3060 return ret;
3061}
3062
3063/* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
3064static int
3065do_route_service(const bool add, const route_message_t *rt, const size_t size, HANDLE pipe)
3066{
3067 int ret = RTA_ERROR;
3068 ack_message_t ack;
3069 struct gc_arena gc = gc_new();
3070
3071 if (!send_msg_iservice(pipe, rt, size, &ack, "ROUTE"))
3072 {
3073 goto out;
3074 }
3075
3076 if (ack.error_number != NO_ERROR)
3077 {
3078 ret = (ack.error_number == ERROR_OBJECT_ALREADY_EXISTS) ? RTA_EEXIST : RTA_ERROR;
3079 if (ret == RTA_ERROR)
3080 {
3081 msg(M_WARN, "ERROR: route %s failed using service: %s [status=%u if_index=%d]",
3082 (add ? "addition" : "deletion"), strerror_win32(ack.error_number, &gc),
3083 ack.error_number, rt->iface.index);
3084 }
3085 goto out;
3086 }
3087
3088 ret = RTA_SUCCESS;
3089
3090out:
3091 gc_free(&gc);
3092 return ret;
3093}
3094
3095/* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
3096static int
3097do_route_ipv4_service(const bool add, const struct route_ipv4 *r, const struct tuntap *tt)
3098{
3099 DWORD if_index = windows_route_find_if_index(r, tt);
3100 if (if_index == ~0)
3101 {
3102 return RTA_ERROR;
3103 }
3104
3106 .header = {
3107 (add ? msg_add_route : msg_del_route),
3108 sizeof(route_message_t),
3109 0
3110 },
3111 .family = AF_INET,
3112 .prefix.ipv4.s_addr = htonl(r->network),
3113 .gateway.ipv4.s_addr = htonl(r->gateway),
3114 .iface = { .index = if_index, .name = "" },
3115 .metric = (r->flags & RT_METRIC_DEFINED ? r->metric : -1)
3116 };
3117
3118 netmask_to_netbits(r->network, r->netmask, &msg.prefix_len);
3119 if (msg.prefix_len == -1)
3120 {
3121 msg.prefix_len = 32;
3122 }
3123
3124 return do_route_service(add, &msg, sizeof(msg), tt->options.msg_channel);
3125}
3126
3127/* Add or delete an ipv6 route
3128 * Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error
3129 */
3130static int
3131route_ipv6_ipapi(const bool add, const struct route_ipv6 *r, const struct tuntap *tt)
3132{
3133 DWORD err;
3134 int ret = RTA_ERROR;
3135 PMIB_IPFORWARD_ROW2 fwd_row;
3136 struct gc_arena gc = gc_new();
3137
3138 fwd_row = gc_malloc(sizeof(*fwd_row), true, &gc);
3139
3140 fwd_row->ValidLifetime = 0xffffffff;
3141 fwd_row->PreferredLifetime = 0xffffffff;
3142 fwd_row->Protocol = MIB_IPPROTO_NETMGMT;
3143 fwd_row->Metric = ((r->flags & RT_METRIC_DEFINED) ? r->metric : -1);
3144 fwd_row->DestinationPrefix.Prefix.si_family = AF_INET6;
3145 fwd_row->DestinationPrefix.Prefix.Ipv6.sin6_addr = r->network;
3146 fwd_row->DestinationPrefix.PrefixLength = (UINT8) r->netbits;
3147 fwd_row->NextHop.si_family = AF_INET6;
3148 fwd_row->NextHop.Ipv6.sin6_addr = r->gateway;
3149 fwd_row->InterfaceIndex = r->adapter_index ? r->adapter_index : tt->adapter_index;
3150
3151 /* In TUN mode we use a special link-local address as the next hop.
3152 * The tapdrvr knows about it and will answer neighbor discovery packets.
3153 * (only do this for routes actually using the tun/tap device)
3154 */
3155 if (tt->type == DEV_TYPE_TUN && !r->adapter_index)
3156 {
3157 inet_pton(AF_INET6, "fe80::8", &fwd_row->NextHop.Ipv6.sin6_addr);
3158 }
3159
3160 /* Use LUID if interface index not available */
3161 if (fwd_row->InterfaceIndex == TUN_ADAPTER_INDEX_INVALID && strlen(tt->actual_name))
3162 {
3163 NET_LUID luid;
3164 err = ConvertInterfaceAliasToLuid(wide_string(tt->actual_name, &gc), &luid);
3165 if (err != NO_ERROR)
3166 {
3167 goto out;
3168 }
3169 fwd_row->InterfaceLuid = luid;
3170 fwd_row->InterfaceIndex = 0;
3171 }
3172
3173 if (add)
3174 {
3175 err = CreateIpForwardEntry2(fwd_row);
3176 }
3177 else
3178 {
3179 err = DeleteIpForwardEntry2(fwd_row);
3180 }
3181
3182out:
3183 if (err != NO_ERROR)
3184 {
3185 ret = (err == ERROR_OBJECT_ALREADY_EXISTS) ? RTA_EEXIST : RTA_ERROR;
3186 if (ret == RTA_ERROR)
3187 {
3188 msg(M_WARN, "ERROR: route %s failed using ipapi: %s [status=%lu if_index=%lu]",
3189 (add ? "addition" : "deletion"), strerror_win32(err, &gc), err,
3190 fwd_row->InterfaceIndex);
3191 }
3192 else if (add)
3193 {
3194 msg(D_ROUTE, "IPv6 route addition using ipapi failed because route exists");
3195 }
3196 }
3197 else
3198 {
3199 msg(D_ROUTE, "IPv6 route %s using ipapi", add ? "added" : "deleted");
3200 ret = RTA_SUCCESS;
3201 }
3202 gc_free(&gc);
3203 return ret;
3204}
3205
3206/* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
3207static int
3208do_route_ipv6_service(const bool add, const struct route_ipv6 *r, const struct tuntap *tt)
3209{
3210 int status;
3212 .header = {
3213 (add ? msg_add_route : msg_del_route),
3214 sizeof(route_message_t),
3215 0
3216 },
3217 .family = AF_INET6,
3218 .prefix.ipv6 = r->network,
3219 .prefix_len = r->netbits,
3220 .gateway.ipv6 = r->gateway,
3221 .iface = { .index = tt->adapter_index, .name = "" },
3222 .metric = ( (r->flags & RT_METRIC_DEFINED) ? r->metric : -1)
3223 };
3224
3225 if (r->adapter_index) /* vpn server special route */
3226 {
3227 msg.iface.index = r->adapter_index;
3228 }
3229
3230 /* In TUN mode we use a special link-local address as the next hop.
3231 * The tapdrvr knows about it and will answer neighbor discovery packets.
3232 * (only do this for routes actually using the tun/tap device)
3233 */
3234 if (tt->type == DEV_TYPE_TUN
3235 && msg.iface.index == tt->adapter_index)
3236 {
3237 inet_pton(AF_INET6, "fe80::8", &msg.gateway.ipv6);
3238 }
3239
3240 if (msg.iface.index == TUN_ADAPTER_INDEX_INVALID)
3241 {
3242 strncpy(msg.iface.name, tt->actual_name, sizeof(msg.iface.name));
3243 msg.iface.name[sizeof(msg.iface.name) - 1] = '\0';
3244 }
3245
3246 status = do_route_service(add, &msg, sizeof(msg), tt->options.msg_channel);
3247 if (status != RTA_ERROR)
3248 {
3249 msg(D_ROUTE, "IPv6 route %s via service %s",
3250 add ? "addition" : "deletion",
3251 (status == RTA_SUCCESS) ? "succeeded" : "failed because route exists");
3252 }
3253 return status;
3254}
3255
3256/* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
3257static int
3258add_route_service(const struct route_ipv4 *r, const struct tuntap *tt)
3259{
3260 return do_route_ipv4_service(true, r, tt);
3261}
3262
3263static bool
3264del_route_service(const struct route_ipv4 *r, const struct tuntap *tt)
3265{
3266 return do_route_ipv4_service(false, r, tt);
3267}
3268
3269/* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
3270static int
3271add_route_ipv6_service(const struct route_ipv6 *r, const struct tuntap *tt)
3272{
3273 return do_route_ipv6_service(true, r, tt);
3274}
3275
3276static bool
3277del_route_ipv6_service(const struct route_ipv6 *r, const struct tuntap *tt)
3278{
3279 return do_route_ipv6_service(false, r, tt);
3280}
3281
3282static const char *
3283format_route_entry(const MIB_IPFORWARDROW *r, struct gc_arena *gc)
3284{
3285 struct buffer out = alloc_buf_gc(256, gc);
3286 buf_printf(&out, "%s %s %s p=%d i=%d t=%d pr=%d a=%d h=%d m=%d/%d/%d/%d/%d",
3287 print_in_addr_t(r->dwForwardDest, IA_NET_ORDER, gc),
3288 print_in_addr_t(r->dwForwardMask, IA_NET_ORDER, gc),
3289 print_in_addr_t(r->dwForwardNextHop, IA_NET_ORDER, gc),
3290 (int)r->dwForwardPolicy,
3291 (int)r->dwForwardIfIndex,
3292 (int)r->dwForwardType,
3293 (int)r->dwForwardProto,
3294 (int)r->dwForwardAge,
3295 (int)r->dwForwardNextHopAS,
3296 (int)r->dwForwardMetric1,
3297 (int)r->dwForwardMetric2,
3298 (int)r->dwForwardMetric3,
3299 (int)r->dwForwardMetric4,
3300 (int)r->dwForwardMetric5);
3301 return BSTR(&out);
3302}
3303
3304/*
3305 * Show current routing table
3306 */
3307void
3309{
3310 struct gc_arena gc = gc_new();
3311
3312 const MIB_IPFORWARDTABLE *rt = get_windows_routing_table(&gc);
3313
3314 msg(msglev, "SYSTEM ROUTING TABLE");
3315 if (rt)
3316 {
3317 for (DWORD i = 0; i < rt->dwNumEntries; ++i)
3318 {
3319 msg(msglev, "%s", format_route_entry(&rt->table[i], &gc));
3320 }
3321 }
3322 gc_free(&gc);
3323}
3324
3325#elif defined(TARGET_ANDROID)
3326
3327void
3328get_default_gateway(struct route_gateway_info *rgi, in_addr_t dest, openvpn_net_ctx_t *ctx)
3329{
3330 /* Android, set some pseudo GW, addr is in host byte order,
3331 * Determining the default GW on Android 5.0+ is non trivial
3332 * and serves almost no purpose since OpenVPN only uses the
3333 * default GW address to add routes for networks that should
3334 * NOT be routed over the VPN. Using a well known address
3335 * (127.'d'.'g'.'w') for the default GW make detecting
3336 * these routes easier from the controlling app.
3337 */
3338 CLEAR(*rgi);
3339
3340 rgi->gateway.addr = 127 << 24 | 'd' << 16 | 'g' << 8 | 'w';
3342 strcpy(rgi->iface, "android-gw");
3343
3344 /* Skip scanning/fetching interface from loopback interface we do
3345 * normally on Linux.
3346 * It always fails and "ioctl(SIOCGIFCONF) failed" confuses users
3347 */
3348
3349}
3350
3351void
3353 const struct in6_addr *dest, openvpn_net_ctx_t *ctx)
3354{
3355 /* Same for ipv6 */
3356
3357 CLEAR(*rgi6);
3358
3359 /* Use a fake link-local address */
3360 ASSERT(inet_pton(AF_INET6, "fe80::ad", &rgi6->addrs->addr_ipv6) == 1);
3361 rgi6->addrs->netbits_ipv6 = 64;
3363 strcpy(rgi6->iface, "android-gw");
3364}
3365
3366#elif defined(TARGET_LINUX)
3367
3368void
3369get_default_gateway(struct route_gateway_info *rgi, in_addr_t dest, openvpn_net_ctx_t *ctx)
3370{
3371 struct gc_arena gc = gc_new();
3372 int sd = -1;
3373 char best_name[IFNAMSIZ];
3374
3375 CLEAR(*rgi);
3376 CLEAR(best_name);
3377
3378 /* find best route to 'dest', get gateway IP addr + interface */
3379 if (net_route_v4_best_gw(ctx, &dest, &rgi->gateway.addr, best_name) == 0)
3380 {
3381 rgi->flags |= RGI_ADDR_DEFINED;
3382 if (!rgi->gateway.addr && best_name[0])
3383 {
3384 rgi->flags |= RGI_ON_LINK;
3385 }
3386 }
3387
3388 /* scan adapter list */
3389 if (rgi->flags & RGI_ADDR_DEFINED)
3390 {
3391 struct ifreq *ifr, *ifend;
3392 in_addr_t addr, netmask;
3393 struct ifreq ifreq;
3394 struct ifconf ifc;
3395 struct ifreq ifs[20]; /* Maximum number of interfaces to scan */
3396
3397 if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
3398 {
3399 msg(M_WARN, "GDG: socket() failed");
3400 goto done;
3401 }
3402 ifc.ifc_len = sizeof(ifs);
3403 ifc.ifc_req = ifs;
3404 if (ioctl(sd, SIOCGIFCONF, &ifc) < 0)
3405 {
3406 msg(M_WARN, "GDG: ioctl(SIOCGIFCONF) failed");
3407 goto done;
3408 }
3409
3410 /* scan through interface list */
3411 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
3412 for (ifr = ifc.ifc_req; ifr < ifend; ifr++)
3413 {
3414 if (ifr->ifr_addr.sa_family == AF_INET)
3415 {
3416 /* get interface addr */
3417 addr = ntohl(((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr);
3418
3419 /* get interface name */
3420 strncpynt(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
3421
3422 /* check that the interface is up */
3423 if (ioctl(sd, SIOCGIFFLAGS, &ifreq) < 0)
3424 {
3425 continue;
3426 }
3427 if (!(ifreq.ifr_flags & IFF_UP))
3428 {
3429 continue;
3430 }
3431
3432 if (rgi->flags & RGI_ON_LINK)
3433 {
3434 /* check that interface name of current interface
3435 * matches interface name of best default route */
3436 if (strcmp(ifreq.ifr_name, best_name))
3437 {
3438 continue;
3439 }
3440#if 0
3441 /* if point-to-point link, use remote addr as route gateway */
3442 if ((ifreq.ifr_flags & IFF_POINTOPOINT) && ioctl(sd, SIOCGIFDSTADDR, &ifreq) >= 0)
3443 {
3444 rgi->gateway.addr = ntohl(((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr);
3445 if (rgi->gateway.addr)
3446 {
3447 rgi->flags &= ~RGI_ON_LINK;
3448 }
3449 }
3450#endif
3451 }
3452 else
3453 {
3454 /* get interface netmask */
3455 if (ioctl(sd, SIOCGIFNETMASK, &ifreq) < 0)
3456 {
3457 continue;
3458 }
3459 netmask = ntohl(((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr);
3460
3461 /* check that interface matches default route */
3462 if (((rgi->gateway.addr ^ addr) & netmask) != 0)
3463 {
3464 continue;
3465 }
3466
3467 /* save netmask */
3468 rgi->gateway.netmask = netmask;
3469 rgi->flags |= RGI_NETMASK_DEFINED;
3470 }
3471
3472 /* save iface name */
3473 strncpynt(rgi->iface, ifreq.ifr_name, sizeof(rgi->iface));
3474 rgi->flags |= RGI_IFACE_DEFINED;
3475
3476 /* now get the hardware address. */
3477 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
3478 if (ioctl(sd, SIOCGIFHWADDR, &ifreq) < 0)
3479 {
3480 msg(M_WARN, "GDG: SIOCGIFHWADDR(%s) failed", ifreq.ifr_name);
3481 goto done;
3482 }
3483 memcpy(rgi->hwaddr, &ifreq.ifr_hwaddr.sa_data, 6);
3484 rgi->flags |= RGI_HWADDR_DEFINED;
3485
3486 break;
3487 }
3488 }
3489 }
3490
3491done:
3492 if (sd >= 0)
3493 {
3494 close(sd);
3495 }
3496 gc_free(&gc);
3497}
3498
3499/* IPv6 implementation using netlink
3500 * http://www.linuxjournal.com/article/7356
3501 * netlink(3), netlink(7), rtnetlink(7)
3502 * http://www.virtualbox.org/svn/vbox/trunk/src/VBox/NetworkServices/NAT/rtmon_linux.c
3503 */
3504struct rtreq {
3505 struct nlmsghdr nh;
3506 struct rtmsg rtm;
3507 char attrbuf[512];
3508};
3509
3510void
3512 const struct in6_addr *dest, openvpn_net_ctx_t *ctx)
3513{
3514 int flags;
3515
3516 CLEAR(*rgi6);
3517
3518 if (net_route_v6_best_gw(ctx, dest, &rgi6->gateway.addr_ipv6,
3519 rgi6->iface) == 0)
3520 {
3521 if (!IN6_IS_ADDR_UNSPECIFIED(&rgi6->gateway.addr_ipv6))
3522 {
3523 rgi6->flags |= RGI_ADDR_DEFINED;
3524 }
3525
3526 if (strlen(rgi6->iface) > 0)
3527 {
3528 rgi6->flags |= RGI_IFACE_DEFINED;
3529 }
3530 }
3531
3532 /* if we have an interface but no gateway, the destination is on-link */
3533 flags = rgi6->flags & (RGI_IFACE_DEFINED | RGI_ADDR_DEFINED);
3534 if (flags == RGI_IFACE_DEFINED)
3535 {
3536 rgi6->flags |= (RGI_ADDR_DEFINED | RGI_ON_LINK);
3537 if (dest)
3538 {
3539 rgi6->gateway.addr_ipv6 = *dest;
3540 }
3541 }
3542}
3543
3544#elif defined(TARGET_DARWIN) || defined(TARGET_SOLARIS) \
3545 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
3546 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
3547
3548#include <sys/types.h>
3549#include <sys/socket.h>
3550#include <netinet/in.h>
3551#include <net/route.h>
3552#include <net/if_dl.h>
3553#if !defined(TARGET_SOLARIS)
3554#include <ifaddrs.h>
3555#endif
3556
3557struct rtmsg {
3558 struct rt_msghdr m_rtm;
3559 char m_space[512];
3560};
3561
3562/* the route socket code is identical for all 4 supported BSDs and for
3563 * MacOS X (Darwin), with one crucial difference: when going from
3564 * 32 bit to 64 bit, FreeBSD/OpenBSD increased the structure size but kept
3565 * source code compatibility by keeping the use of "long", while
3566 * MacOS X decided to keep binary compatibility by *changing* the API
3567 * to use "uint32_t", thus 32 bit on all OS X variants
3568 *
3569 * NetBSD does the MacOS way of "fixed number of bits, no matter if
3570 * 32 or 64 bit OS", but chose uint64_t. For maximum portability, we
3571 * just use the OS RT_ROUNDUP() macro, which is guaranteed to be correct.
3572 *
3573 * We used to have a large amount of duplicate code here which really
3574 * differed only in this (long) vs. (uint32_t) - IMHO, worse than
3575 * having a combined block for all BSDs with this single #ifdef inside
3576 */
3577
3578#if defined(TARGET_DARWIN)
3579#define ROUNDUP(a) \
3580 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
3581#elif defined(TARGET_NETBSD)
3582#define ROUNDUP(a) RT_ROUNDUP(a)
3583#else
3584#define ROUNDUP(a) \
3585 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
3586#endif
3587
3588#if defined(TARGET_SOLARIS)
3589#define NEXTADDR(w, u) \
3590 if (rtm_addrs & (w)) { \
3591 l = sizeof(u); memmove(cp, &(u), l); cp += ROUNDUP(l); \
3592 }
3593
3594#define ADVANCE(x, n) (x += ROUNDUP(sizeof(struct sockaddr_in)))
3595#else /* if defined(TARGET_SOLARIS) */
3596#define NEXTADDR(w, u) \
3597 if (rtm_addrs & (w)) { \
3598 l = ((struct sockaddr *)&(u))->sa_len; memmove(cp, &(u), l); cp += ROUNDUP(l); \
3599 }
3600
3601#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
3602#endif
3603
3604#define max(a, b) ((a) > (b) ? (a) : (b))
3605
3606void
3607get_default_gateway(struct route_gateway_info *rgi, in_addr_t dest, openvpn_net_ctx_t *ctx)
3608{
3609 struct gc_arena gc = gc_new();
3610 struct rtmsg m_rtmsg;
3611 int sockfd = -1;
3612 int seq, l, pid, rtm_addrs;
3613 unsigned int i;
3614 struct sockaddr so_dst, so_mask;
3615 char *cp = m_rtmsg.m_space;
3616 struct sockaddr *gate = NULL, *ifp = NULL, *sa;
3617 struct rt_msghdr *rtm_aux;
3618
3619#define rtm m_rtmsg.m_rtm
3620
3621 CLEAR(*rgi);
3622
3623 /* setup data to send to routing socket */
3624 pid = getpid();
3625 seq = 0;
3626#ifdef TARGET_OPENBSD
3627 rtm_addrs = RTA_DST | RTA_NETMASK; /* Kernel refuses RTA_IFP */
3628#else
3629 rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP;
3630#endif
3631
3632 bzero(&m_rtmsg, sizeof(m_rtmsg));
3633 bzero(&so_dst, sizeof(so_dst));
3634 bzero(&so_mask, sizeof(so_mask));
3635 bzero(&rtm, sizeof(struct rt_msghdr));
3636
3637 rtm.rtm_type = RTM_GET;
3638 rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
3639 rtm.rtm_version = RTM_VERSION;
3640 rtm.rtm_seq = ++seq;
3641#ifdef TARGET_OPENBSD
3642 rtm.rtm_tableid = getrtable();
3643#endif
3644 rtm.rtm_addrs = rtm_addrs;
3645
3646 so_dst.sa_family = AF_INET;
3647 so_mask.sa_family = AF_INET;
3648
3649#ifndef TARGET_SOLARIS
3650 so_dst.sa_len = sizeof(struct sockaddr_in);
3651 so_mask.sa_len = sizeof(struct sockaddr_in);
3652#endif
3653
3654 NEXTADDR(RTA_DST, so_dst);
3655 NEXTADDR(RTA_NETMASK, so_mask);
3656
3657 rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
3658
3659 /* transact with routing socket */
3660 sockfd = socket(PF_ROUTE, SOCK_RAW, 0);
3661 if (sockfd < 0)
3662 {
3663 msg(M_WARN, "GDG: socket #1 failed");
3664 goto done;
3665 }
3666 if (write(sockfd, (char *)&m_rtmsg, l) < 0)
3667 {
3668 msg(M_WARN|M_ERRNO, "GDG: problem writing to routing socket");
3669 goto done;
3670 }
3671 do
3672 {
3673 l = read(sockfd, (char *)&m_rtmsg, sizeof(m_rtmsg));
3674 } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
3675 close(sockfd);
3676 sockfd = -1;
3677
3678 /* extract return data from routing socket */
3679 rtm_aux = &rtm;
3680 cp = ((char *)(rtm_aux + 1));
3681 if (rtm_aux->rtm_addrs)
3682 {
3683 for (i = 1; i; i <<= 1)
3684 {
3685 if (i & rtm_aux->rtm_addrs)
3686 {
3687 sa = (struct sockaddr *)cp;
3688 if (i == RTA_GATEWAY)
3689 {
3690 gate = sa;
3691 }
3692 else if (i == RTA_IFP)
3693 {
3694 ifp = sa;
3695 }
3696 ADVANCE(cp, sa);
3697 }
3698 }
3699 }
3700 else
3701 {
3702 goto done;
3703 }
3704
3705 /* get gateway addr and interface name */
3706 if (gate != NULL)
3707 {
3708 /* get default gateway addr */
3709 rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
3710 if (rgi->gateway.addr)
3711 {
3712 rgi->flags |= RGI_ADDR_DEFINED;
3713 }
3714
3715 if (ifp)
3716 {
3717 /* get interface name */
3718 const struct sockaddr_dl *adl = (struct sockaddr_dl *) ifp;
3719 if (adl->sdl_nlen && adl->sdl_nlen < sizeof(rgi->iface))
3720 {
3721 memcpy(rgi->iface, adl->sdl_data, adl->sdl_nlen);
3722 rgi->iface[adl->sdl_nlen] = '\0';
3723 rgi->flags |= RGI_IFACE_DEFINED;
3724 }
3725 }
3726 }
3727
3728 /* get netmask of interface that owns default gateway */
3729 if (rgi->flags & RGI_IFACE_DEFINED)
3730 {
3731 struct ifreq ifr;
3732
3733 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
3734 if (sockfd < 0)
3735 {
3736 msg(M_WARN, "GDG: socket #2 failed");
3737 goto done;
3738 }
3739
3740 CLEAR(ifr);
3741 ifr.ifr_addr.sa_family = AF_INET;
3742 strncpynt(ifr.ifr_name, rgi->iface, IFNAMSIZ);
3743
3744 if (ioctl(sockfd, SIOCGIFNETMASK, (char *)&ifr) < 0)
3745 {
3746 msg(M_WARN, "GDG: ioctl #1 failed");
3747 goto done;
3748 }
3749 close(sockfd);
3750 sockfd = -1;
3751
3752 rgi->gateway.netmask = ntohl(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr);
3753 rgi->flags |= RGI_NETMASK_DEFINED;
3754 }
3755
3756 /* try to read MAC addr associated with interface that owns default gateway */
3757 if (rgi->flags & RGI_IFACE_DEFINED)
3758 {
3759#if defined(TARGET_SOLARIS)
3760 /* OpenSolaris has getifaddrs(3), but it does not return AF_LINK */
3761 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
3762 if (sockfd < 0)
3763 {
3764 msg(M_WARN, "GDG: socket #3 failed");
3765 goto done;
3766 }
3767
3768 struct ifreq ifreq = { 0 };
3769
3770 /* now get the hardware address. */
3771 strncpynt(ifreq.ifr_name, rgi->iface, sizeof(ifreq.ifr_name));
3772 if (ioctl(sockfd, SIOCGIFHWADDR, &ifreq) < 0)
3773 {
3774 msg(M_WARN, "GDG: SIOCGIFHWADDR(%s) failed", ifreq.ifr_name);
3775 }
3776 else
3777 {
3778 memcpy(rgi->hwaddr, &ifreq.ifr_addr.sa_data, 6);
3779 rgi->flags |= RGI_HWADDR_DEFINED;
3780 }
3781#else /* if defined(TARGET_SOLARIS) */
3782 struct ifaddrs *ifap, *ifa;
3783
3784 if (getifaddrs(&ifap) != 0)
3785 {
3786 msg(M_WARN|M_ERRNO, "GDG: getifaddrs() failed");
3787 goto done;
3788 }
3789
3790 for (ifa = ifap; ifa; ifa = ifa->ifa_next)
3791 {
3792 if (ifa->ifa_addr != NULL
3793 && ifa->ifa_addr->sa_family == AF_LINK
3794 && !strncmp(ifa->ifa_name, rgi->iface, IFNAMSIZ) )
3795 {
3796 struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr;
3797 memcpy(rgi->hwaddr, LLADDR(sdl), 6);
3798 rgi->flags |= RGI_HWADDR_DEFINED;
3799 }
3800 }
3801
3802 freeifaddrs(ifap);
3803#endif /* if defined(TARGET_SOLARIS) */
3804 }
3805
3806done:
3807 if (sockfd >= 0)
3808 {
3809 close(sockfd);
3810 }
3811 gc_free(&gc);
3812}
3813
3814/* BSD implementation using routing socket (as does IPv4)
3815 * (the code duplication is somewhat unavoidable if we want this to
3816 * work on OpenSolaris as well. *sigh*)
3817 */
3818
3819/* Solaris has no length field - this is ugly, but less #ifdef in total
3820 */
3821#if defined(TARGET_SOLARIS)
3822#undef ADVANCE
3823#define ADVANCE(x, n) (x += ROUNDUP(sizeof(struct sockaddr_in6)))
3824#endif
3825
3826void
3828 const struct in6_addr *dest, openvpn_net_ctx_t *ctx)
3829{
3830
3831 struct rtmsg m_rtmsg;
3832 int sockfd = -1;
3833 int seq, l, pid, rtm_addrs;
3834 unsigned int i;
3835 struct sockaddr_in6 so_dst, so_mask;
3836 char *cp = m_rtmsg.m_space;
3837 struct sockaddr *gate = NULL, *ifp = NULL, *sa;
3838 struct rt_msghdr *rtm_aux;
3839
3840 CLEAR(*rgi6);
3841
3842 /* setup data to send to routing socket */
3843 pid = getpid();
3844 seq = 0;
3845#ifdef TARGET_OPENBSD
3846 rtm_addrs = RTA_DST | RTA_NETMASK; /* Kernel refuses RTA_IFP */
3847#else
3848 rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP;
3849#endif
3850
3851 bzero(&m_rtmsg, sizeof(m_rtmsg));
3852 bzero(&so_dst, sizeof(so_dst));
3853 bzero(&so_mask, sizeof(so_mask));
3854 bzero(&rtm, sizeof(struct rt_msghdr));
3855
3856 rtm.rtm_type = RTM_GET;
3857 rtm.rtm_flags = RTF_UP;
3858 rtm.rtm_version = RTM_VERSION;
3859 rtm.rtm_seq = ++seq;
3860#ifdef TARGET_OPENBSD
3861 rtm.rtm_tableid = getrtable();
3862#endif
3863
3864 so_dst.sin6_family = AF_INET6;
3865 so_mask.sin6_family = AF_INET6;
3866
3867 if (dest != NULL /* specific host? */
3868 && !IN6_IS_ADDR_UNSPECIFIED(dest) )
3869 {
3870 so_dst.sin6_addr = *dest;
3871 /* :: needs /0 "netmask", host route wants "no netmask */
3872 rtm_addrs &= ~RTA_NETMASK;
3873 }
3874
3875 rtm.rtm_addrs = rtm_addrs;
3876
3877#ifndef TARGET_SOLARIS
3878 so_dst.sin6_len = sizeof(struct sockaddr_in6);
3879 so_mask.sin6_len = sizeof(struct sockaddr_in6);
3880#endif
3881
3882 NEXTADDR(RTA_DST, so_dst);
3883 NEXTADDR(RTA_NETMASK, so_mask);
3884
3885 rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
3886
3887 /* transact with routing socket */
3888 sockfd = socket(PF_ROUTE, SOCK_RAW, 0);
3889 if (sockfd < 0)
3890 {
3891 msg(M_WARN, "GDG6: socket #1 failed");
3892 goto done;
3893 }
3894 if (write(sockfd, (char *)&m_rtmsg, l) < 0)
3895 {
3896 msg(M_WARN|M_ERRNO, "GDG6: problem writing to routing socket");
3897 goto done;
3898 }
3899
3900 do
3901 {
3902 l = read(sockfd, (char *)&m_rtmsg, sizeof(m_rtmsg));
3903 }
3904 while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
3905
3906 close(sockfd);
3907 sockfd = -1;
3908
3909 /* extract return data from routing socket */
3910 rtm_aux = &rtm;
3911 cp = ((char *)(rtm_aux + 1));
3912 if (rtm_aux->rtm_addrs)
3913 {
3914 for (i = 1; i; i <<= 1)
3915 {
3916 if (i & rtm_aux->rtm_addrs)
3917 {
3918 sa = (struct sockaddr *)cp;
3919 if (i == RTA_GATEWAY)
3920 {
3921 gate = sa;
3922 }
3923 else if (i == RTA_IFP)
3924 {
3925 ifp = sa;
3926 }
3927 ADVANCE(cp, sa);
3928 }
3929 }
3930 }
3931 else
3932 {
3933 goto done;
3934 }
3935
3936 /* get gateway addr and interface name */
3937 if (gate != NULL)
3938 {
3939 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)gate;
3940 struct in6_addr gw = s6->sin6_addr;
3941
3942#ifndef TARGET_SOLARIS
3943 /* You do not really want to know... from FreeBSD's route.c
3944 * (KAME encodes the 16 bit scope_id in s6_addr[2] + [3],
3945 * but for a correct link-local address these must be :0000: )
3946 */
3947 if (gate->sa_len == sizeof(struct sockaddr_in6)
3948 && IN6_IS_ADDR_LINKLOCAL(&gw) )
3949 {
3950 gw.s6_addr[2] = gw.s6_addr[3] = 0;
3951 }
3952
3953 if (gate->sa_len != sizeof(struct sockaddr_in6)
3954 || IN6_IS_ADDR_UNSPECIFIED(&gw) )
3955 {
3956 rgi6->flags |= RGI_ON_LINK;
3957 }
3958 else
3959#endif
3960 {
3961 rgi6->gateway.addr_ipv6 = gw;
3962 }
3963 rgi6->flags |= RGI_ADDR_DEFINED;
3964
3965 if (ifp)
3966 {
3967 /* get interface name */
3968 const struct sockaddr_dl *adl = (struct sockaddr_dl *) ifp;
3969 if (adl->sdl_nlen && adl->sdl_nlen < sizeof(rgi6->iface))
3970 {
3971 memcpy(rgi6->iface, adl->sdl_data, adl->sdl_nlen);
3972 rgi6->flags |= RGI_IFACE_DEFINED;
3973 }
3974 }
3975 }
3976
3977done:
3978 if (sockfd >= 0)
3979 {
3980 close(sockfd);
3981 }
3982}
3983
3984#undef max
3985
3986#elif defined(TARGET_HAIKU)
3987
3988void
3989get_default_gateway(struct route_gateway_info *rgi, in_addr_t dest, openvpn_net_ctx_t *ctx)
3990{
3991 CLEAR(*rgi);
3992
3993 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
3994 if (sockfd < 0)
3995 {
3996 msg(M_ERRNO, "%s: Error opening socket for AF_INET", __func__);
3997 return;
3998 }
3999
4000 struct ifconf config;
4001 config.ifc_len = sizeof(config.ifc_value);
4002 if (ioctl(sockfd, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 0)
4003 {
4004 msg(M_ERRNO, "%s: Error getting routing table size", __func__);
4005 return;
4006 }
4007
4008 uint32 size = (uint32)config.ifc_value;
4009 if (size == 0)
4010 {
4011 return;
4012 }
4013
4014 void *buffer = malloc(size);
4016
4017 config.ifc_len = size;
4018 config.ifc_buf = buffer;
4019 if (ioctl(sockfd, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0)
4020 {
4021 free(buffer);
4022 return;
4023 }
4024
4025 struct ifreq *interface = (struct ifreq *)buffer;
4026 struct ifreq *end = (struct ifreq *)((uint8 *)buffer + size);
4027
4028 while (interface < end)
4029 {
4030 struct route_entry route = interface->ifr_route;
4031 if ((route.flags & RTF_GATEWAY) != 0 && (route.flags & RTF_DEFAULT) != 0)
4032 {
4033 rgi->gateway.addr = ntohl(((struct sockaddr_in *)route.gateway)->sin_addr.s_addr);
4035 strncpy(rgi->iface, interface->ifr_name, sizeof(rgi->iface));
4036 }
4037
4038 int32 address_size = 0;
4039 if (route.destination != NULL)
4040 {
4041 address_size += route.destination->sa_len;
4042 }
4043 if (route.mask != NULL)
4044 {
4045 address_size += route.mask->sa_len;
4046 }
4047 if (route.gateway != NULL)
4048 {
4049 address_size += route.gateway->sa_len;
4050 }
4051
4052 interface = (struct ifreq *)((addr_t)interface + IF_NAMESIZE
4053 + sizeof(struct route_entry) + address_size);
4054 }
4055 free(buffer);
4056}
4057
4058void
4060 const struct in6_addr *dest, openvpn_net_ctx_t *ctx)
4061{
4062 /* TODO: Same for ipv6 with AF_INET6 */
4063 CLEAR(*rgi6);
4064}
4065
4066#else /* if defined(_WIN32) */
4067
4068/*
4069 * This is a platform-specific method that returns data about
4070 * the current default gateway. Return data is placed into
4071 * a struct route_gateway_info object provided by caller. The
4072 * implementation should CLEAR the structure before adding
4073 * data to it.
4074 *
4075 * Data returned includes:
4076 * 1. default gateway address (rgi->gateway.addr)
4077 * 2. netmask of interface that owns default gateway
4078 * (rgi->gateway.netmask)
4079 * 3. hardware address (i.e. MAC address) of interface that owns
4080 * default gateway (rgi->hwaddr)
4081 * 4. interface name (or adapter index on Windows) that owns default
4082 * gateway (rgi->iface or rgi->adapter_index)
4083 * 5. an array of additional address/netmask pairs defined by
4084 * interface that owns default gateway (rgi->addrs with length
4085 * given in rgi->n_addrs)
4086 *
4087 * The flags RGI_x_DEFINED may be used to indicate which of the data
4088 * members were successfully returned (set in rgi->flags). All of
4089 * the data members are optional, however certain OpenVPN functionality
4090 * may be disabled by missing items.
4091 */
4092void
4093get_default_gateway(struct route_gateway_info *rgi, in_addr_t dest, openvpn_net_ctx_t *ctx)
4094{
4095 CLEAR(*rgi);
4096}
4097void
4099 const struct in6_addr *dest, openvpn_net_ctx_t *ctx)
4100{
4101 msg(D_ROUTE, "no support for get_default_gateway_ipv6() on this system");
4102 CLEAR(*rgi6);
4103}
4104
4105#endif /* if defined(_WIN32) */
4106
4107bool
4108netmask_to_netbits(const in_addr_t network, const in_addr_t netmask, int *netbits)
4109{
4110 int i;
4111 const int addrlen = sizeof(in_addr_t) * 8;
4112
4113 if ((network & netmask) == network)
4114 {
4115 for (i = 0; i <= addrlen; ++i)
4116 {
4117 in_addr_t mask = netbits_to_netmask(i);
4118 if (mask == netmask)
4119 {
4120 if (i == addrlen)
4121 {
4122 *netbits = -1;
4123 }
4124 else
4125 {
4126 *netbits = i;
4127 }
4128 return true;
4129 }
4130 }
4131 }
4132 return false;
4133}
4134
4135/* similar to netmask_to_netbits(), but don't mess with base address
4136 * etc., just convert to netbits - non-mappable masks are returned as "-1"
4137 */
4138int
4139netmask_to_netbits2(in_addr_t netmask)
4140{
4141 int i;
4142 const int addrlen = sizeof(in_addr_t) * 8;
4143
4144 for (i = 0; i <= addrlen; ++i)
4145 {
4146 in_addr_t mask = netbits_to_netmask(i);
4147 if (mask == netmask)
4148 {
4149 return i;
4150 }
4151 }
4152 return -1;
4153}
4154
4155
4156/*
4157 * get_bypass_addresses() is used by the redirect-gateway bypass-x
4158 * functions to build a route bypass to selected DHCP/DNS servers,
4159 * so that outgoing packets to these servers don't end up in the tunnel.
4160 */
4161
4162#if defined(_WIN32)
4163
4164static void
4165add_host_route_if_nonlocal(struct route_bypass *rb, const in_addr_t addr)
4166{
4167 if (test_local_addr(addr, NULL) == TLA_NONLOCAL && addr != 0 && addr != IPV4_NETMASK_HOST)
4168 {
4169 add_bypass_address(rb, addr);
4170 }
4171}
4172
4173static void
4174add_host_route_array(struct route_bypass *rb, const IP_ADDR_STRING *iplist)
4175{
4176 while (iplist)
4177 {
4178 bool succeed = false;
4179 const in_addr_t ip = getaddr(GETADDR_HOST_ORDER, iplist->IpAddress.String, 0, &succeed, NULL);
4180 if (succeed)
4181 {
4183 }
4184 iplist = iplist->Next;
4185 }
4186}
4187
4188static void
4189get_bypass_addresses(struct route_bypass *rb, const unsigned int flags)
4190{
4191 struct gc_arena gc = gc_new();
4192 /*bool ret_bool = false;*/
4193
4194 /* get full routing table */
4195 const MIB_IPFORWARDTABLE *routes = get_windows_routing_table(&gc);
4196
4197 /* get the route which represents the default gateway */
4198 const MIB_IPFORWARDROW *row = get_default_gateway_row(routes);
4199
4200 if (row)
4201 {
4202 /* get the adapter which the default gateway is associated with */
4203 const IP_ADAPTER_INFO *dgi = get_adapter_info(row->dwForwardIfIndex, &gc);
4204
4205 /* get extra adapter info, such as DNS addresses */
4206 const IP_PER_ADAPTER_INFO *pai = get_per_adapter_info(row->dwForwardIfIndex, &gc);
4207
4208 /* Bypass DHCP server address */
4209 if ((flags & RG_BYPASS_DHCP) && dgi && dgi->DhcpEnabled)
4210 {
4211 add_host_route_array(rb, &dgi->DhcpServer);
4212 }
4213
4214 /* Bypass DNS server addresses */
4215 if ((flags & RG_BYPASS_DNS) && pai)
4216 {
4217 add_host_route_array(rb, &pai->DnsServerList);
4218 }
4219 }
4220
4221 gc_free(&gc);
4222}
4223
4224#else /* if defined(_WIN32) */
4225
4226static void
4227get_bypass_addresses(struct route_bypass *rb, const unsigned int flags) /* PLATFORM-SPECIFIC */
4228{
4229}
4230
4231#endif /* if defined(_WIN32) */
4232
4233/*
4234 * Test if addr is reachable via a local interface (return ILA_LOCAL),
4235 * or if it needs to be routed via the default gateway (return
4236 * ILA_NONLOCAL). If the target platform doesn't implement this
4237 * function, return ILA_NOT_IMPLEMENTED.
4238 *
4239 * Used by redirect-gateway autolocal feature
4240 */
4241
4242#if defined(_WIN32)
4243
4244int
4245test_local_addr(const in_addr_t addr, const struct route_gateway_info *rgi)
4246{
4247 struct gc_arena gc = gc_new();
4248 const in_addr_t nonlocal_netmask = 0x80000000L; /* routes with netmask <= to this are considered non-local */
4249 int ret = TLA_NONLOCAL;
4250
4251 /* get full routing table */
4252 const MIB_IPFORWARDTABLE *rt = get_windows_routing_table(&gc);
4253 if (rt)
4254 {
4255 for (DWORD i = 0; i < rt->dwNumEntries; ++i)
4256 {
4257 const MIB_IPFORWARDROW *row = &rt->table[i];
4258 const in_addr_t net = ntohl(row->dwForwardDest);
4259 const in_addr_t mask = ntohl(row->dwForwardMask);
4260 if (mask > nonlocal_netmask && (addr & mask) == net)
4261 {
4262 ret = TLA_LOCAL;
4263 break;
4264 }
4265 }
4266 }
4267
4268 gc_free(&gc);
4269 return ret;
4270}
4271
4272#else /* if defined(_WIN32) */
4273
4274int
4275test_local_addr(const in_addr_t addr, const struct route_gateway_info *rgi) /* PLATFORM-SPECIFIC */
4276{
4277 if (rgi)
4278 {
4279 if (local_route(addr, 0xFFFFFFFF, rgi->gateway.addr, rgi))
4280 {
4281 return TLA_LOCAL;
4282 }
4283 else
4284 {
4285 return TLA_NONLOCAL;
4286 }
4287 }
4288 return TLA_NOT_IMPLEMENTED;
4289}
4290
4291#endif /* if defined(_WIN32) */
void argv_msg(const int msglev, const struct argv *a)
Write the arguments stored in a struct argv via the msg() command.
Definition argv.c:243
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
Definition argv.c:102
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
Definition argv.c:440
bool argv_printf_cat(struct argv *argres, const char *format,...)
printf() inspired argv concatenation.
Definition argv.c:464
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
Definition argv.c:88
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:240
char * format_hex_ex(const uint8_t *data, int size, int maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
Definition buffer.c:483
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition buffer.c:336
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:88
void gc_addspecial(void *addr, void(*free_function)(void *), struct gc_arena *a)
Definition buffer.c:438
#define BSTR(buf)
Definition buffer.h:129
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Definition buffer.h:1097
#define ALLOC_OBJ_GC(dptr, type, gc)
Definition buffer.h:1092
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition buffer.h:361
static void check_malloc_return(void *p)
Definition buffer.h:1103
static void gc_free(struct gc_arena *a)
Definition buffer.h:1033
static void gc_freeaddrinfo_callback(void *addr)
Definition buffer.h:215
static struct gc_arena gc_new(void)
Definition buffer.h:1025
void setenv_int(struct env_set *es, const char *name, int value)
Definition env_set.c:267
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition env_set.c:283
#define D_ROUTE_DEBUG
Definition errlevel.h:133
#define M_INFO
Definition errlevel.h:55
#define D_ROUTE
Definition errlevel.h:80
static SERVICE_STATUS status
Definition interactive.c:53
@ route
Definition interactive.c:87
@ write
@ read
void management_set_state(struct management *man, const int state, const char *detail, const in_addr_t *tun_local_ip, const struct in6_addr *tun_local_ip6, const struct openvpn_sockaddr *local, const struct openvpn_sockaddr *remote)
Definition manage.c:2749
#define OPENVPN_STATE_ADD_ROUTES
Definition manage.h:472
static void net_ctx_reset(openvpn_net_ctx_t *ctx)
Definition networking.h:57
void * openvpn_net_ctx_t
Definition networking.h:39
@ msg_add_route
Definition openvpn-msg.h:34
@ msg_del_route
Definition openvpn-msg.h:35
#define IPV4_NETMASK_HOST
Definition basic.h:35
#define CLEAR(x)
Definition basic.h:33
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
Definition error.c:812
#define M_FATAL
Definition error.h:89
#define dmsg(flags,...)
Definition error.h:148
#define msg(flags,...)
Definition error.h:144
#define ASSERT(x)
Definition error.h:195
#define M_WARN
Definition error.h:91
#define M_ERRNO
Definition error.h:94
#define DEV_TYPE_TAP
Definition proto.h:37
#define DEV_TYPE_TUN
Definition proto.h:36
static void undo_redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:1115
static bool route_ipv6_match_host(const struct route_ipv6 *r6, const struct in6_addr *host)
Definition route.c:754
static void add_host_route_if_nonlocal(struct route_bypass *rb, const in_addr_t addr)
Definition route.c:4165
bool add_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:1189
bool is_special_addr(const char *addr_str)
Definition route.c:306
struct route_option_list * clone_route_option_list(const struct route_option_list *src, struct gc_arena *a)
Definition route.c:155
void setenv_routes_ipv6(struct env_set *es, const struct route_ipv6_list *rl6)
Definition route.c:1489
static void clear_route_list(struct route_list *rl)
Definition route.c:543
static void test_route_helper(bool *ret, int *count, int *good, int *ambig, const IP_ADAPTER_INFO *adapters, const in_addr_t gateway)
Definition route.c:2618
static void del_bypass_routes(struct route_bypass *rb, in_addr_t gateway, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:982
static bool del_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt)
Definition route.c:3028
static bool redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:1008
static bool add_route3(in_addr_t network, in_addr_t netmask, in_addr_t gateway, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:923
static void add_host_route_array(struct route_bypass *rb, const IP_ADDR_STRING *iplist)
Definition route.c:4174
int netmask_to_netbits2(in_addr_t netmask)
Definition route.c:4139
struct route_ipv6_option_list * new_route_ipv6_option_list(struct gc_arena *a)
Definition route.c:139
static bool init_route(struct route_ipv4 *r, struct addrinfo **network_list, const struct route_option *ro, const struct route_list *rl)
Definition route.c:319
static const char * route_string(const struct route_ipv4 *r, struct gc_arena *gc)
Definition route.c:189
static bool get_special_addr(const struct route_list *rl, const char *string, in_addr_t *out, bool *status)
Definition route.c:236
#define RTA_EEXIST
Definition route.c:105
#define LR_NOMATCH
Definition route.c:1518
bool test_routes(const struct route_list *rl, const struct tuntap *tt)
Definition route.c:2647
static void add_block_local_routes(struct route_list *rl)
Definition route.c:597
void add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, const char *metric)
Definition route.c:528
bool block_local_needed(const struct route_list *rl)
Get the decision whether to block traffic to local networks while the VPN is connected.
Definition route.c:621
void get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6, const struct in6_addr *dest, openvpn_net_ctx_t *ctx)
Definition route.c:2886
static const MIB_IPFORWARDTABLE * get_windows_routing_table(struct gc_arena *gc)
Definition route.c:2581
static DWORD get_best_route(struct gc_arena *gc, SOCKADDR_INET *dest, MIB_IPFORWARD_ROW2 *best_route)
Determines the best route to a destination for both IPv4 and IPv6.
Definition route.c:2746
void show_routes(int msglev)
Definition route.c:3308
static const char * format_route_entry(const MIB_IPFORWARDROW *r, struct gc_arena *gc)
Definition route.c:3283
static void print_route_option(const struct route_option *ro, int level)
Definition route.c:1309
static int add_route_service(const struct route_ipv4 *, const struct tuntap *)
Definition route.c:3258
bool init_route_ipv6_list(struct route_ipv6_list *rl6, const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, const struct in6_addr *remote_host_ipv6, struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:790
void print_route_options(const struct route_option_list *rol, int level)
Definition route.c:1319
static void delete_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:2178
void add_route_to_option_list(struct route_option_list *l, const char *network, const char *netmask, const char *gateway, const char *metric)
Definition route.c:510
static bool del_route_ipv6_service(const struct route_ipv6 *, const struct tuntap *)
Definition route.c:3277
void route_list_add_vpn_gateway(struct route_list *rl, struct env_set *es, const in_addr_t addr)
Definition route.c:557
void print_default_gateway(const int msglevel, const struct route_gateway_info *rgi, const struct route_ipv6_gateway_info *rgi6)
Definition route.c:1335
void copy_route_option_list(struct route_option_list *dest, const struct route_option_list *src, struct gc_arena *a)
Definition route.c:173
void copy_route_ipv6_option_list(struct route_ipv6_option_list *dest, const struct route_ipv6_option_list *src, struct gc_arena *a)
Definition route.c:180
bool add_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:1567
static int test_route(const IP_ADAPTER_INFO *adapters, const in_addr_t gateway, DWORD *index)
Definition route.c:2604
bool add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:1915
static void print_route(const struct route_ipv4 *r, int level)
Definition route.c:1410
#define RTA_ERROR
Definition route.c:103
static bool del_route_service(const struct route_ipv4 *, const struct tuntap *)
Definition route.c:3264
static int local_route(in_addr_t network, in_addr_t netmask, in_addr_t gateway, const struct route_gateway_info *rgi)
Definition route.c:1523
static int add_route_ipv6_service(const struct route_ipv6 *, const struct tuntap *)
Definition route.c:3271
static bool is_on_link(const int is_local_route, const unsigned int flags, const struct route_gateway_info *rgi)
Definition route.c:1560
static const MIB_IPFORWARDROW * get_default_gateway_row(const MIB_IPFORWARDTABLE *routes)
Definition route.c:2695
void get_default_gateway(struct route_gateway_info *rgi, in_addr_t dest, openvpn_net_ctx_t *ctx)
Retrieves the best gateway for a given destination based on the routing table.
Definition route.c:2785
static int route_ipv6_ipapi(bool add, const struct route_ipv6 *, const struct tuntap *)
Definition route.c:3131
static void add_block_local_item(struct route_list *rl, const struct route_gateway_address *gateway, in_addr_t target)
Definition route.c:568
struct route_ipv6_option_list * clone_route_ipv6_option_list(const struct route_ipv6_option_list *src, struct gc_arena *a)
Definition route.c:164
static const char * show_opt(const char *option)
Definition route.c:1296
static bool init_route_ipv6(struct route_ipv6 *r6, const struct route_ipv6_option *r6o, const struct route_ipv6_list *rl6)
Definition route.c:454
struct route_option_list * new_route_option_list(struct gc_arena *a)
Definition route.c:130
int test_local_addr(const in_addr_t addr, const struct route_gateway_info *rgi)
Definition route.c:4245
#define METRIC_NOT_USED
Definition route.c:60
bool init_route_list(struct route_list *rl, const struct route_option_list *opt, const char *remote_endpoint, int default_metric, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:631
static int add_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt, DWORD adapter_index)
Definition route.c:2936
#define RTA_SUCCESS
Definition route.c:104
void delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:2384
#define LR_MATCH
Definition route.c:1519
static int do_route_ipv6_service(const bool add, const struct route_ipv6 *r, const struct tuntap *tt)
Definition route.c:3208
static int do_route_service(const bool add, const route_message_t *rt, const size_t size, HANDLE pipe)
Definition route.c:3065
void route_ipv6_clear_host_bits(struct route_ipv6 *r6)
Definition route.c:1892
static void clear_route_ipv6_list(struct route_ipv6_list *rl6)
Definition route.c:550
void delete_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:1256
#define LR_ERROR
Definition route.c:1520
void print_routes(const struct route_list *rl, int level)
Definition route.c:1421
bool netmask_to_netbits(const in_addr_t network, const in_addr_t netmask, int *netbits)
Definition route.c:4108
static void setenv_route_addr(struct env_set *es, const char *key, const in_addr_t addr, int i)
Definition route.c:219
static DWORD windows_route_find_if_index(const struct route_ipv4 *r, const struct tuntap *tt)
Definition route.c:2837
static int do_route_ipv4_service(const bool add, const struct route_ipv4 *r, const struct tuntap *tt)
Definition route.c:3097
void setenv_routes(struct env_set *es, const struct route_list *rl)
Definition route.c:1451
static bool add_bypass_routes(struct route_bypass *rb, in_addr_t gateway, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:961
static void get_bypass_addresses(struct route_bypass *rb, const unsigned int flags)
Definition route.c:4189
static bool is_route_parm_defined(const char *parm)
Definition route.c:205
static void setenv_route_ipv6(struct env_set *es, const struct route_ipv6 *r6, int i)
Definition route.c:1462
static bool add_bypass_address(struct route_bypass *rb, const in_addr_t a)
Definition route.c:108
static void setenv_route(struct env_set *es, const struct route_ipv4 *r, int i)
Definition route.c:1431
static void del_route3(in_addr_t network, in_addr_t netmask, in_addr_t gateway, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:942
#define RG_LOCAL
Definition route.h:85
#define TLA_LOCAL
Definition route.h:364
#define RGI_ON_LINK
Definition route.h:152
#define RL_DID_LOCAL
Definition route.h:215
#define RL_DID_REDIRECT_DEFAULT_GATEWAY
Definition route.h:214
#define ROUTE_REF_GW
Definition route.h:51
#define RG_BYPASS_DHCP
Definition route.h:87
#define RTSA_REMOTE_ENDPOINT
Definition route.h:63
#define RGI_ADDR_DEFINED
Definition route.h:147
#define RL_ROUTES_ADDED
Definition route.h:216
#define RGI_HWADDR_DEFINED
Definition route.h:149
static in_addr_t netbits_to_netmask(const int netbits)
Definition route.h:394
#define RTSA_REMOTE_HOST
Definition route.h:64
#define ROUTE_METHOD_SERVICE
Definition route.h:43
#define RGI_IFACE_DEFINED
Definition route.h:150
#define ROUTE_METHOD_IPAPI
Definition route.h:41
#define RT_ADDED
Definition route.h:114
#define ROUTE_METHOD_EXE
Definition route.h:42
#define RT_METRIC_DEFINED
Definition route.h:115
#define ROUTE_DELETE_FIRST
Definition route.h:50
#define RG_DEF1
Definition route.h:86
#define RG_BYPASS_DNS
Definition route.h:88
#define RG_ENABLE
Definition route.h:84
#define RG_REROUTE_GW
Definition route.h:89
#define TLA_NOT_IMPLEMENTED
Definition route.h:362
#define ROUTE_METHOD_ADAPTIVE
Definition route.h:40
#define RG_AUTO_LOCAL
Definition route.h:90
#define RG_BLOCK_LOCAL
Definition route.h:91
#define TLA_NONLOCAL
Definition route.h:363
#define N_ROUTE_BYPASS
Definition route.h:55
#define RT_DEFINED
Definition route.h:113
#define ROUTE_METHOD_MASK
Definition route.h:44
#define RTSA_DEFAULT_METRIC
Definition route.h:65
#define RGI_NETMASK_DEFINED
Definition route.h:148
int openvpn_execve_check(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message)
bool get_ipv6_addr(const char *hostname, struct in6_addr *network, unsigned int *netbits, int msglevel)
Translate an IPv6 addr or hostname from string form to in6_addr.
Definition socket.c:226
int openvpn_getaddrinfo(unsigned int flags, const char *hostname, const char *servname, int resolve_retry_seconds, struct signal_info *sig_info, int ai_family, struct addrinfo **res)
Definition socket.c:453
const char * print_in6_addr(struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
Definition socket.c:2994
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
Definition socket.c:2974
in_addr_t getaddr(unsigned int flags, const char *hostname, int resolve_retry_seconds, bool *succeeded, struct signal_info *sig_info)
Translate an IPv4 addr or hostname from string form to in_addr_t.
Definition socket.c:195
#define IF_NAMESIZE
Definition socket.c:2899
#define IPV4_INVALID_ADDR
Definition socket.h:438
#define GETADDR_HOST_ORDER
Definition socket.h:519
#define GETADDR_RESOLVE
Definition socket.h:517
#define IA_NET_ORDER
Definition socket.h:402
#define GETADDR_WARN_ON_SIGNAL
Definition socket.h:522
Definition argv.h:35
Wrapper structure for dynamically allocated memory.
Definition buffer.h:61
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:66
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
Container for unidirectional cipher and HMAC key material.
Definition crypto.h:152
int n_bypass
Definition route.h:56
in_addr_t bypass[N_ROUTE_BYPASS]
Definition route.h:57
in_addr_t netmask
Definition route.h:143
uint8_t hwaddr[6]
Definition route.h:165
unsigned int flags
Definition route.h:153
struct route_gateway_address addrs[RGI_N_ADDRESSES]
Definition route.h:173
DWORD adapter_index
Definition route.h:157
struct route_gateway_address gateway
Definition route.h:168
const struct route_option * option
Definition route.h:118
int metric
Definition route.h:122
struct route_ipv4 * next
Definition route.h:116
in_addr_t network
Definition route.h:119
in_addr_t netmask
Definition route.h:120
in_addr_t gateway
Definition route.h:121
unsigned int flags
Definition route.h:117
struct in6_addr addr_ipv6
Definition route.h:177
struct route_ipv6_gateway_address gateway
Definition route.h:205
struct route_ipv6_gateway_address addrs[RGI_N_ADDRESSES]
Definition route.h:210
unsigned int flags
Definition route.h:183
uint8_t hwaddr[6]
Definition route.h:202
unsigned int iflags
Definition route.h:227
unsigned int flags
Definition route.h:235
struct route_ipv6_gateway_info rgi6
Definition route.h:234
struct route_ipv6 * routes_ipv6
Definition route.h:236
unsigned int spec_flags
Definition route.h:229
int default_metric
Definition route.h:232
struct in6_addr remote_host_ipv6
Definition route.h:231
struct gc_arena gc
Definition route.h:237
struct in6_addr remote_endpoint_ipv6
Definition route.h:230
unsigned int flags
Definition route.h:107
struct gc_arena * gc
Definition route.h:109
struct route_ipv6_option * routes_ipv6
Definition route.h:108
struct route_ipv6_option * next
Definition route.h:100
const char * gateway
Definition route.h:102
const char * metric
Definition route.h:103
const char * prefix
Definition route.h:101
struct in6_addr gateway
Definition route.h:130
DWORD adapter_index
Definition route.h:134
unsigned int netbits
Definition route.h:129
struct route_ipv6 * next
Definition route.h:126
unsigned int flags
Definition route.h:127
struct in6_addr network
Definition route.h:128
int metric
Definition route.h:131
struct route_gateway_info rgi
Definition route.h:220
struct route_ipv4 * routes
Definition route.h:222
struct route_special_addr spec
Definition route.h:219
unsigned int flags
Definition route.h:221
struct gc_arena gc
Definition route.h:223
unsigned int iflags
Definition route.h:217
message_header_t header
Definition openvpn-msg.h:81
interface_t iface
Definition openvpn-msg.h:86
struct gc_arena * gc
Definition route.h:96
unsigned int flags
Definition route.h:94
struct route_option * routes
Definition route.h:95
const char * network
Definition route.h:77
const char * netmask
Definition route.h:78
struct route_option * next
Definition route.h:76
const char * gateway
Definition route.h:79
const char * metric
Definition route.h:80
in_addr_t remote_host
Definition route.h:69
struct route_bypass bypass
Definition route.h:71
unsigned int flags
Definition route.h:66
in_addr_t remote_endpoint
Definition route.h:68
int remote_host_local
Definition route.h:70
HANDLE msg_channel
Definition tun.h:90
Definition tun.h:181
int type
Definition tun.h:183
DWORD adapter_index
Definition tun.h:230
bool did_ifconfig_ipv6_setup
if the internal variables related to ifconfig-ipv6 of this struct have been set up.
Definition tun.h:199
struct tuntap_options options
Definition tun.h:203
bool did_ifconfig_setup
if the internal variables related to ifconfig of this struct have been set up.
Definition tun.h:195
char * actual_name
Definition tun.h:205
static char * iface
struct env_set * es
struct gc_arena gc
Definition test_ssl.c:155
const IP_ADAPTER_INFO * get_tun_adapter(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
Definition tun.c:4654
bool is_adapter_up(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
Definition tun.c:4667
const IP_ADAPTER_INFO * get_adapter_info(DWORD index, struct gc_arena *gc)
Definition tun.c:4569
const IP_PER_ADAPTER_INFO * get_per_adapter_info(const DWORD index, struct gc_arena *gc)
Definition tun.c:4463
bool is_ip_in_adapter_subnet(const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask)
Definition tun.c:4712
const IP_ADAPTER_INFO * get_adapter_info_list(struct gc_arena *gc)
Definition tun.c:4436
const IP_ADAPTER_INFO * get_adapter(const IP_ADAPTER_INFO *ai, DWORD index)
Definition tun.c:4550
DWORD adapter_index_of_ip(const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count, in_addr_t *netmask)
Definition tun.c:4745
#define TUN_ADAPTER_INDEX_INVALID
Definition tun.h:67
WCHAR * wide_string(const char *utf8, struct gc_arena *gc)
Definition win32-util.c:41
bool send_msg_iservice(HANDLE pipe, const void *data, size_t size, ack_message_t *ack, const char *context)
Definition win32.c:1480
void netcmd_semaphore_release(void)
Definition win32.c:874
char * get_win_sys_path(void)
Definition win32.c:1113
void netcmd_semaphore_lock(void)
Definition win32.c:858
#define WIN_ROUTE_PATH_SUFFIX
Definition win32.h:40