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