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
46#include "memdbg.h"
47
48#if defined(TARGET_LINUX) || defined(TARGET_ANDROID)
49#include <linux/rtnetlink.h> /* RTM_GETROUTE etc. */
50#endif
51
52#if defined(TARGET_NETBSD)
53#include <net/route.h> /* RT_ROUNDUP(), RT_ADVANCE() */
54#endif
55
56#ifdef _WIN32
57#include "openvpn-msg.h"
58
59#define METRIC_NOT_USED ((DWORD)-1)
60static int add_route_service(const struct route_ipv4 *, const struct tuntap *);
61
62static bool del_route_service(const struct route_ipv4 *, const struct tuntap *);
63
64static int add_route_ipv6_service(const struct route_ipv6 *, const struct tuntap *);
65
66static bool del_route_ipv6_service(const struct route_ipv6 *, const struct tuntap *);
67
68static int route_ipv6_ipapi(bool add, const struct route_ipv6 *, const struct tuntap *);
69
70static int add_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt,
71 DWORD adapter_index);
72
73static bool del_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt);
74
75
76#endif
77
78static void delete_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags,
79 const struct route_gateway_info *rgi, const struct env_set *es,
81
82static void get_bypass_addresses(struct route_bypass *rb, const unsigned int flags);
83
84#ifdef ENABLE_DEBUG
85
86static void
87print_bypass_addresses(const struct route_bypass *rb)
88{
89 struct gc_arena gc = gc_new();
90 int i;
91 for (i = 0; i < rb->n_bypass; ++i)
92 {
93 msg(D_ROUTE, "ROUTE: bypass_host_route[%d]=%s", i, print_in_addr_t(rb->bypass[i], 0, &gc));
94 }
95 gc_free(&gc);
96}
97
98#endif
99
100/* Route addition return status codes */
101#define RTA_ERROR 0 /* route addition failed */
102#define RTA_SUCCESS 1 /* route addition succeeded */
103#define RTA_EEXIST 2 /* route not added as it already exists */
104
105#ifndef TARGET_ANDROID
106static bool
108{
109 int i;
110 for (i = 0; i < rb->n_bypass; ++i)
111 {
112 if (a == rb->bypass[i]) /* avoid duplicates */
113 {
114 return true;
115 }
116 }
117 if (rb->n_bypass < N_ROUTE_BYPASS)
118 {
119 rb->bypass[rb->n_bypass++] = a;
120 return true;
121 }
122 else
123 {
124 return false;
125 }
126}
127#endif
128
129struct route_option_list *
131{
132 struct route_option_list *ret;
134 ret->gc = a;
135 return ret;
136}
137
140{
141 struct route_ipv6_option_list *ret;
143 ret->gc = a;
144 return ret;
145}
146
147/*
148 * NOTE: structs are cloned/copied shallow by design.
149 * The routes list from src will stay intact since it is allocated using
150 * the options->gc. The cloned/copied lists will share this common tail
151 * to avoid copying the data around between pulls. Pulled routes use
152 * the c2->gc so they get freed immediately after a reconnect.
153 */
154struct route_option_list *
156{
157 struct route_option_list *ret;
158 ALLOC_OBJ_GC(ret, struct route_option_list, a);
159 *ret = *src;
160 return ret;
161}
162
165{
166 struct route_ipv6_option_list *ret;
167 ALLOC_OBJ_GC(ret, struct route_ipv6_option_list, a);
168 *ret = *src;
169 return ret;
170}
171
172void
174 struct gc_arena *a)
175{
176 *dest = *src;
177 dest->gc = a;
178}
179
180void
182 const struct route_ipv6_option_list *src, struct gc_arena *a)
183{
184 *dest = *src;
185 dest->gc = a;
186}
187
188static bool
189is_route_parm_defined(const char *parm)
190{
191 if (!parm)
192 {
193 return false;
194 }
195 if (!strcmp(parm, "default"))
196 {
197 return false;
198 }
199 return true;
200}
201
202static void
203setenv_route_addr(struct env_set *es, const char *key, const in_addr_t addr, int i)
204{
205 struct gc_arena gc = gc_new();
206 struct buffer name = alloc_buf_gc(256, &gc);
207 if (i >= 0)
208 {
209 buf_printf(&name, "route_%s_%d", key, i);
210 }
211 else
212 {
213 buf_printf(&name, "route_%s", key);
214 }
215 setenv_str(es, BSTR(&name), print_in_addr_t(addr, 0, &gc));
216 gc_free(&gc);
217}
218
219static bool
220get_special_addr(const struct route_list *rl, const char *string, in_addr_t *out, bool *status)
221{
222 if (status)
223 {
224 *status = true;
225 }
226 if (!strcmp(string, "vpn_gateway"))
227 {
228 if (rl)
229 {
230 if (rl->spec.flags & RTSA_REMOTE_ENDPOINT)
231 {
232 *out = rl->spec.remote_endpoint;
233 }
234 else
235 {
236 msg(M_INFO, PACKAGE_NAME " ROUTE: vpn_gateway undefined");
237 if (status)
238 {
239 *status = false;
240 }
241 }
242 }
243 return true;
244 }
245 else if (!strcmp(string, "net_gateway"))
246 {
247 if (rl)
248 {
249 if (rl->ngi.flags & RGI_ADDR_DEFINED)
250 {
251 *out = rl->ngi.gateway.addr;
252 }
253 else
254 {
256 " ROUTE: net_gateway undefined -- unable to get default gateway from system");
257 if (status)
258 {
259 *status = false;
260 }
261 }
262 }
263 return true;
264 }
265 else if (!strcmp(string, "remote_host"))
266 {
267 if (rl)
268 {
269 if (rl->spec.flags & RTSA_REMOTE_HOST)
270 {
271 *out = rl->spec.remote_host;
272 }
273 else
274 {
275 msg(M_INFO, PACKAGE_NAME " ROUTE: remote_host undefined");
276 if (status)
277 {
278 *status = false;
279 }
280 }
281 }
282 return true;
283 }
284 return false;
285}
286
287bool
289{
290 if (addr_str)
291 {
293 }
294 else
295 {
296 return false;
297 }
298}
299
300static bool
301init_route(struct route_ipv4 *r, struct addrinfo **network_list, const struct route_option *ro,
302 const struct route_list *rl)
303{
305 bool status;
306 int ret;
307 struct in_addr special = { 0 };
308
309 CLEAR(*r);
310 r->option = ro;
311
312 /* network */
314 {
315 goto fail;
316 }
317
318 /* get_special_addr replaces specialaddr with a special ip addr
319 * like gw. getaddrinfo is called to convert a a addrinfo struct */
320
321 if (get_special_addr(rl, ro->network, (in_addr_t *)&special.s_addr, &status))
322 {
323 if (!status)
324 {
325 goto fail;
326 }
327 special.s_addr = htonl(special.s_addr);
328 char buf[INET_ADDRSTRLEN];
329 inet_ntop(AF_INET, &special, buf, sizeof(buf));
330 ret = openvpn_getaddrinfo(0, buf, NULL, 0, NULL, AF_INET, network_list);
331 }
332 else
333 {
335 NULL, AF_INET, network_list);
336 }
337
338 status = (ret == 0);
339
340 if (!status)
341 {
342 goto fail;
343 }
344
345 /* netmask */
346
348 {
349 r->netmask =
351 if (!status)
352 {
353 goto fail;
354 }
355 }
356 else
357 {
358 r->netmask = default_netmask;
359 }
360
361 /* gateway */
362
364 {
365 if (!get_special_addr(rl, ro->gateway, &r->gateway, &status))
366 {
368 ro->gateway, 0, &status, NULL);
369 }
370 if (!status)
371 {
372 goto fail;
373 }
374 }
375 else
376 {
378 {
380 }
381 else
382 {
383 msg(M_WARN, PACKAGE_NAME
384 " ROUTE: " PACKAGE_NAME
385 " needs a gateway parameter for a --route option and no default was specified by either --route-gateway or --ifconfig options");
386 goto fail;
387 }
388 }
389
390 /* metric */
391
392 r->metric = 0;
394 {
395 r->metric = atoi(ro->metric);
396 if (r->metric < 0)
397 {
398 msg(M_WARN, PACKAGE_NAME " ROUTE: route metric for network %s (%s) must be >= 0",
399 ro->network, ro->metric);
400 goto fail;
401 }
403 }
404 else if (rl->spec.flags & RTSA_DEFAULT_METRIC)
405 {
406 r->metric = rl->spec.default_metric;
408 }
409
410 r->flags |= RT_DEFINED;
411
412 /* routing table id */
413 r->table_id = ro->table_id;
414
415 return true;
416
417fail:
418 msg(M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve route for host/network: %s",
419 ro->network);
420 return false;
421}
422
423static bool
425 const struct route_ipv6_list *rl6)
426{
427 CLEAR(*r6);
428
429 if (!get_ipv6_addr(r6o->prefix, &r6->network, &r6->netbits, M_WARN))
430 {
431 goto fail;
432 }
433
434 /* gateway */
436 {
437 if (inet_pton(AF_INET6, r6o->gateway, &r6->gateway) != 1)
438 {
439 msg(M_WARN, PACKAGE_NAME "ROUTE6: cannot parse gateway spec '%s'", r6o->gateway);
440 }
441 }
442 else if (rl6->spec_flags & RTSA_REMOTE_ENDPOINT)
443 {
444 r6->gateway = rl6->remote_endpoint_ipv6;
445 }
446
447 /* metric */
448
449 r6->metric = -1;
451 {
452 r6->metric = atoi(r6o->metric);
453 if (r6->metric < 0)
454 {
455 msg(M_WARN, PACKAGE_NAME " ROUTE: route metric for network %s (%s) must be >= 0",
456 r6o->prefix, r6o->metric);
457 goto fail;
458 }
459 r6->flags |= RT_METRIC_DEFINED;
460 }
461 else if (rl6->spec_flags & RTSA_DEFAULT_METRIC)
462 {
463 r6->metric = rl6->default_metric;
464 r6->flags |= RT_METRIC_DEFINED;
465 }
466
467 r6->flags |= RT_DEFINED;
468
469 /* routing table id */
470 r6->table_id = r6o->table_id;
471
472 return true;
473
474fail:
475 msg(M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve route for host/network: %s",
476 r6o->prefix);
477 return false;
478}
479
480void
481add_route_to_option_list(struct route_option_list *l, const char *network, const char *netmask,
482 const char *gateway, const char *metric, int table_id)
483{
484 struct route_option *ro;
485 ALLOC_OBJ_GC(ro, struct route_option, l->gc);
486 ro->network = network;
487 ro->netmask = netmask;
488 ro->gateway = gateway;
489 ro->metric = metric;
490 ro->table_id = table_id;
491 ro->next = l->routes;
492 l->routes = ro;
493}
494
495void
497 const char *gateway, const char *metric, int table_id)
498{
499 struct route_ipv6_option *ro;
500 ALLOC_OBJ_GC(ro, struct route_ipv6_option, l->gc);
501 ro->prefix = prefix;
502 ro->gateway = gateway;
503 ro->metric = metric;
504 ro->table_id = table_id;
505 ro->next = l->routes_ipv6;
506 l->routes_ipv6 = ro;
507}
508
509static void
511{
512 gc_free(&rl->gc);
513 CLEAR(*rl);
514}
515
516static void
518{
519 gc_free(&rl6->gc);
520 CLEAR(*rl6);
521}
522
523void
525{
526 ASSERT(rl);
527 rl->spec.remote_endpoint = addr;
529 setenv_route_addr(es, "vpn_gateway", rl->spec.remote_endpoint, -1);
530}
531
532static void
534 in_addr_t target)
535{
536 if (rl->rgi.gateway.netmask < 0xFFFFFFFF)
537 {
538 struct route_ipv4 *r1, *r2;
539 unsigned int l2;
540
541 ALLOC_OBJ_GC(r1, struct route_ipv4, &rl->gc);
542 ALLOC_OBJ_GC(r2, struct route_ipv4, &rl->gc);
543
544 /* split a route into two smaller blocking routes, and direct them to target */
545 l2 = ((~gateway->netmask) + 1) >> 1;
546 r1->flags = RT_DEFINED;
547 r1->gateway = target;
548 r1->network = gateway->addr & gateway->netmask;
549 r1->netmask = ~(l2 - 1);
550 r1->next = rl->routes;
551 rl->routes = r1;
552
553 *r2 = *r1;
554 r2->network += l2;
555 r2->next = rl->routes;
556 rl->routes = r2;
557 }
558}
559
560static void
562{
563#ifndef TARGET_ANDROID
564 /* add bypass for gateway addr */
566#endif
567
568 /* block access to local subnet */
570
571 /* process additional subnets on gateway interface */
572 for (int i = 0; i < rl->rgi.n_addrs; ++i)
573 {
574 const struct route_gateway_address *gwa = &rl->rgi.addrs[i];
575 /* omit the add/subnet in &rl->rgi which we processed above */
576 if (!((rl->rgi.gateway.addr & rl->rgi.gateway.netmask) == (gwa->addr & gwa->netmask)
577 && rl->rgi.gateway.netmask == gwa->netmask))
578 {
580 }
581 }
582}
583
584bool
586{
587 const unsigned int rgi_needed = (RGI_ADDR_DEFINED | RGI_NETMASK_DEFINED);
588 return (rl->flags & RG_BLOCK_LOCAL) && (rl->rgi.flags & rgi_needed) == rgi_needed
590}
591
592bool
593init_route_list(struct route_list *rl, const struct route_option_list *opt,
594 const char *remote_endpoint, int default_metric, in_addr_t remote_host,
595 struct env_set *es, openvpn_net_ctx_t *ctx)
596{
597 struct gc_arena gc = gc_new();
598 bool ret = true;
599
601
602 rl->flags = opt->flags;
603
604 if (remote_host != IPV4_INVALID_ADDR)
605 {
606 rl->spec.remote_host = remote_host;
608 }
609
610 if (default_metric)
611 {
612 rl->spec.default_metric = default_metric;
614 }
615
616 get_default_gateway(&rl->ngi, INADDR_ANY, ctx);
617 if (rl->ngi.flags & RGI_ADDR_DEFINED)
618 {
619 setenv_route_addr(es, "net_gateway", rl->ngi.gateway.addr, -1);
620#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
621 print_default_gateway(D_ROUTE, &rl->rgi, NULL);
622#endif
623 }
624 else
625 {
626 dmsg(D_ROUTE, "ROUTE: default_gateway=UNDEF");
627 }
628
629 get_default_gateway(&rl->rgi, remote_host != IPV4_INVALID_ADDR ? remote_host : INADDR_ANY, ctx);
630
631 if (rl->spec.flags & RTSA_REMOTE_HOST)
632 {
633 rl->spec.remote_host_local = test_local_addr(remote_host, &rl->rgi);
634 }
635
636 if (is_route_parm_defined(remote_endpoint))
637 {
638 bool defined = false;
641 0, &defined, NULL);
642
643 if (defined)
644 {
645 setenv_route_addr(es, "vpn_gateway", rl->spec.remote_endpoint, -1);
647 }
648 else
649 {
650 msg(M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve default gateway: %s",
651 remote_endpoint);
652 ret = false;
653 }
654 }
655
656 if (rl->flags & RG_ENABLE)
657 {
658 if (block_local_needed(rl))
659 {
661 }
663#ifdef ENABLE_DEBUG
664 print_bypass_addresses(&rl->spec.bypass);
665#endif
666 }
667
668 /* parse the routes from opt to rl */
669 {
670 const struct route_option *ro;
671 for (ro = opt->routes; ro; ro = ro->next)
672 {
673 struct addrinfo *netlist = NULL;
674 struct route_ipv4 r;
675
676 if (!init_route(&r, &netlist, ro, rl))
677 {
678 ret = false;
679 }
680 else
681 {
682 const struct addrinfo *curele;
683 for (curele = netlist; curele; curele = curele->ai_next)
684 {
685 struct route_ipv4 *new;
686 ALLOC_OBJ_GC(new, struct route_ipv4, &rl->gc);
687 *new = r;
688 new->network = ntohl(((struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
689 new->next = rl->routes;
690 rl->routes = new;
691 }
692 }
693 if (netlist)
694 {
696 }
697 }
698 }
699
700 gc_free(&gc);
701 return ret;
702}
703
704bool
705ipv6_net_contains_host(const struct in6_addr *network, unsigned int bits, const struct in6_addr *host)
706{
707 /* not the most beautiful implementation in the world, but portable and
708 * "good enough" */
709 if (bits > 128)
710 {
711 return false;
712 }
713
714 int i;
715 for (i = 0; bits >= 8; i++, bits -= 8)
716 {
717 if (network->s6_addr[i] != host->s6_addr[i])
718 {
719 return false;
720 }
721 }
722
723 if (bits == 0)
724 {
725 return true;
726 }
727
728 unsigned int mask = 0xff << (8 - bits);
729
730 if ((network->s6_addr[i] & mask) == (host->s6_addr[i] & mask))
731 {
732 return true;
733 }
734
735 return false;
736}
737
738bool
740 const char *remote_endpoint, int default_metric,
741 const struct in6_addr *remote_host_ipv6, struct env_set *es,
743{
744 struct gc_arena gc = gc_new();
745 bool ret = true;
746 bool need_remote_ipv6_route;
747
749
750 rl6->flags = opt6->flags;
751
752 if (remote_host_ipv6)
753 {
754 rl6->remote_host_ipv6 = *remote_host_ipv6;
756 }
757
758 if (default_metric >= 0)
759 {
760 rl6->default_metric = default_metric;
762 }
763
764 msg(D_ROUTE, "GDG6: remote_host_ipv6=%s",
765 remote_host_ipv6 ? print_in6_addr(*remote_host_ipv6, 0, &gc) : "n/a");
766
767 get_default_gateway_ipv6(&rl6->ngi6, NULL, ctx);
768 if (rl6->ngi6.flags & RGI_ADDR_DEFINED)
769 {
770 setenv_str(es, "net_gateway_ipv6", print_in6_addr(rl6->ngi6.gateway.addr_ipv6, 0, &gc));
771#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
772 print_default_gateway(D_ROUTE, NULL, &rl6->rgi6);
773#endif
774 }
775 else
776 {
777 dmsg(D_ROUTE, "ROUTE6: default_gateway=UNDEF");
778 }
779
780 get_default_gateway_ipv6(&rl6->rgi6, remote_host_ipv6, ctx);
781
782 if (is_route_parm_defined(remote_endpoint))
783 {
784 if (inet_pton(AF_INET6, remote_endpoint, &rl6->remote_endpoint_ipv6) == 1)
785 {
787 }
788 else
789 {
790 msg(M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve VPN endpoint: %s",
791 remote_endpoint);
792 ret = false;
793 }
794 }
795
796 /* parse the routes from opt6 to rl6
797 * discovering potential overlaps with remote_host_ipv6 in the process
798 */
799 need_remote_ipv6_route = false;
800
801 {
802 const struct route_ipv6_option *ro6;
803 for (ro6 = opt6->routes_ipv6; ro6; ro6 = ro6->next)
804 {
805 struct route_ipv6 *r6;
806 ALLOC_OBJ_GC(r6, struct route_ipv6, &rl6->gc);
807 if (!init_route_ipv6(r6, ro6, rl6))
808 {
809 ret = false;
810 }
811 else
812 {
813 r6->next = rl6->routes_ipv6;
814 rl6->routes_ipv6 = r6;
815
816#ifndef TARGET_ANDROID
817 /* On Android the VPNService protect function call will take of
818 * avoiding routing loops, so ignore this part and let
819 * need_remote_ipv6_route always evaluate to false
820 */
821 if (remote_host_ipv6
822 && ipv6_net_contains_host(&r6->network, r6->netbits, remote_host_ipv6))
823 {
824 need_remote_ipv6_route = true;
825 msg(D_ROUTE,
826 "ROUTE6: %s/%d overlaps IPv6 remote %s, adding host route to VPN endpoint",
827 print_in6_addr(r6->network, 0, &gc), r6->netbits,
828 print_in6_addr(*remote_host_ipv6, 0, &gc));
829 }
830#endif
831 }
832 }
833 }
834
835 /* add VPN server host route if needed */
836 if (need_remote_ipv6_route)
837 {
840 {
841 struct route_ipv6 *r6;
842 ALLOC_OBJ_CLEAR_GC(r6, struct route_ipv6, &rl6->gc);
843
844 r6->network = *remote_host_ipv6;
845 r6->netbits = 128;
846 if (!(rl6->rgi6.flags & RGI_ON_LINK))
847 {
848 r6->gateway = rl6->rgi6.gateway.addr_ipv6;
849 }
850 r6->metric = 1;
851#ifdef _WIN32
852 r6->adapter_index = rl6->rgi6.adapter_index;
853#else
854 r6->iface = rl6->rgi6.iface;
855#endif
857
858 r6->next = rl6->routes_ipv6;
859 rl6->routes_ipv6 = r6;
860 }
861 else
862 {
863 msg(M_WARN,
864 "ROUTE6: IPv6 route overlaps with IPv6 remote address, but could not determine IPv6 gateway address + interface, expect failure\n");
865 }
866 }
867
868 gc_free(&gc);
869 return ret;
870}
871
872static bool
874 unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es,
876{
877 struct route_ipv4 r;
878 CLEAR(r);
879 r.flags = RT_DEFINED;
880 r.network = network;
881 r.netmask = netmask;
882 r.gateway = gateway;
883 return add_route(&r, tt, flags, rgi, es, ctx);
884}
885
886static void
888 unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es,
890{
891 struct route_ipv4 r;
892 CLEAR(r);
894 r.network = network;
895 r.netmask = netmask;
896 r.gateway = gateway;
897 delete_route(&r, tt, flags, rgi, es, ctx);
898}
899
900static bool
902 unsigned int flags, const struct route_gateway_info *rgi,
903 const struct env_set *es, openvpn_net_ctx_t *ctx)
904{
905 int ret = true;
906 for (int i = 0; i < rb->n_bypass; ++i)
907 {
908 if (rb->bypass[i])
909 {
911 rgi, es, ctx)
912 && ret;
913 }
914 }
915 return ret;
916}
917
918static void
920 unsigned int flags, const struct route_gateway_info *rgi,
921 const struct env_set *es, openvpn_net_ctx_t *ctx)
922{
923 int i;
924 for (i = 0; i < rb->n_bypass; ++i)
925 {
926 if (rb->bypass[i])
927 {
929 ctx);
930 }
931 }
932}
933
934static bool
935redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, unsigned int flags,
936 const struct env_set *es, openvpn_net_ctx_t *ctx)
937{
938 const char err[] = "NOTE: unable to redirect IPv4 default gateway --";
939 bool ret = true;
940
941 if (rl && rl->flags & RG_ENABLE)
942 {
943 bool local = rl->flags & RG_LOCAL;
944
945 if (!(rl->spec.flags & RTSA_REMOTE_ENDPOINT) && (rl->flags & RG_REROUTE_GW))
946 {
947 msg(M_WARN, "%s VPN gateway parameter (--route-gateway or --ifconfig) is missing", err);
948 ret = false;
949 }
950 /*
951 * check if a default route is defined, unless:
952 * - we are connecting to a remote host in our network
953 * - we are connecting to a non-IPv4 remote host (i.e. we use IPv6)
954 */
955 else if (!(rl->rgi.flags & RGI_ADDR_DEFINED) && !local
956 && (rl->spec.flags & RTSA_REMOTE_HOST))
957 {
958 msg(M_WARN, "%s Cannot read current default gateway from system", err);
959 ret = false;
960 }
961 else
962 {
963#ifndef TARGET_ANDROID
964 if (rl->flags & RG_AUTO_LOCAL)
965 {
966 const int tla = rl->spec.remote_host_local;
967 if (tla == TLA_NONLOCAL)
968 {
969 dmsg(D_ROUTE, "ROUTE remote_host is NOT LOCAL");
970 local = false;
971 }
972 else if (tla == TLA_LOCAL)
973 {
974 dmsg(D_ROUTE, "ROUTE remote_host is LOCAL");
975 local = true;
976 }
977 }
978 if (!local)
979 {
980 /* route remote host to original default gateway */
981 /* if remote_host is not ipv4 (ie: ipv6), just skip
982 * adding this special /32 route */
983 if ((rl->spec.flags & RTSA_REMOTE_HOST)
985 {
987 tt, flags | ROUTE_REF_GW, &rl->rgi, es, ctx);
988 if (ret)
989 {
990 rl->iflags |= RL_DID_LOCAL;
991 }
992 }
993 else
994 {
995 dmsg(D_ROUTE, "ROUTE remote_host protocol differs from tunneled");
996 }
997 }
998#endif /* ifndef TARGET_ANDROID */
999
1000 /* route DHCP/DNS server traffic through original default gateway */
1001 ret = add_bypass_routes(&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es,
1002 ctx)
1003 && ret;
1004
1005 if (rl->flags & RG_REROUTE_GW)
1006 {
1007 if (rl->flags & RG_DEF1)
1008 {
1009 /* add new default route (1st component) */
1010 ret = add_route3(0x00000000, 0x80000000, rl->spec.remote_endpoint, tt, flags,
1011 &rl->rgi, es, ctx)
1012 && ret;
1013
1014 /* add new default route (2nd component) */
1015 ret = add_route3(0x80000000, 0x80000000, rl->spec.remote_endpoint, tt, flags,
1016 &rl->rgi, es, ctx)
1017 && ret;
1018 }
1019 else
1020 {
1021 /* don't try to remove the def route if it does not exist */
1022 if (rl->rgi.flags & RGI_ADDR_DEFINED)
1023 {
1024 /* delete default route */
1025 del_route3(0, 0, rl->rgi.gateway.addr, tt, flags | ROUTE_REF_GW, &rl->rgi,
1026 es, ctx);
1027 }
1028
1029 /* add new default route */
1030 ret = add_route3(0, 0, rl->spec.remote_endpoint, tt, flags, &rl->rgi, es, ctx)
1031 && ret;
1032 }
1033 }
1034
1035 /* set a flag so we can undo later */
1037 }
1038 }
1039 return ret;
1040}
1041
1042static void
1044 unsigned int flags, const struct env_set *es,
1045 openvpn_net_ctx_t *ctx)
1046{
1048 {
1049 /* delete remote host route */
1050 if (rl->iflags & RL_DID_LOCAL)
1051 {
1053 flags | ROUTE_REF_GW, &rl->rgi, es, ctx);
1054 rl->iflags &= ~RL_DID_LOCAL;
1055 }
1056
1057 /* delete special DHCP/DNS bypass route */
1058 del_bypass_routes(&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es, ctx);
1059
1060 if (rl->flags & RG_REROUTE_GW)
1061 {
1062 if (rl->flags & RG_DEF1)
1063 {
1064 /* delete default route (1st component) */
1065 del_route3(0x00000000, 0x80000000, rl->spec.remote_endpoint, tt, flags, &rl->rgi,
1066 es, ctx);
1067
1068 /* delete default route (2nd component) */
1069 del_route3(0x80000000, 0x80000000, rl->spec.remote_endpoint, tt, flags, &rl->rgi,
1070 es, ctx);
1071 }
1072 else
1073 {
1074 /* delete default route */
1075 del_route3(0, 0, rl->spec.remote_endpoint, tt, flags, &rl->rgi, es, ctx);
1076 /* restore original default route if there was any */
1077 if (rl->rgi.flags & RGI_ADDR_DEFINED)
1078 {
1079 add_route3(0, 0, rl->rgi.gateway.addr, tt, flags | ROUTE_REF_GW, &rl->rgi, es,
1080 ctx);
1081 }
1082 }
1083 }
1084
1085 rl->iflags &= ~RL_DID_REDIRECT_DEFAULT_GATEWAY;
1086 }
1087}
1088
1089bool
1090add_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tuntap *tt,
1091 unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
1092{
1093 bool ret = redirect_default_route_to_vpn(rl, tt, flags, es, ctx);
1094 if (rl && !(rl->iflags & RL_ROUTES_ADDED))
1095 {
1096 struct route_ipv4 *r;
1097
1098 if (rl->routes && !tt->did_ifconfig_setup)
1099 {
1100 msg(M_INFO,
1101 "WARNING: OpenVPN was configured to add an IPv4 "
1102 "route. However, no IPv4 has been configured for %s, "
1103 "therefore the route installation may fail or may not work "
1104 "as expected.",
1105 tt->actual_name);
1106 }
1107
1108#ifdef ENABLE_MANAGEMENT
1109 if (management && rl->routes)
1110 {
1112 NULL);
1113 }
1114#endif
1115
1116 for (r = rl->routes; r; r = r->next)
1117 {
1119 {
1120 delete_route(r, tt, flags, &rl->rgi, es, ctx);
1121 }
1122 ret = add_route(r, tt, flags, &rl->rgi, es, ctx) && ret;
1123 }
1124 rl->iflags |= RL_ROUTES_ADDED;
1125 }
1126 if (rl6 && !(rl6->iflags & RL_ROUTES_ADDED))
1127 {
1128 struct route_ipv6 *r;
1129
1130 if (!tt->did_ifconfig_ipv6_setup)
1131 {
1132 msg(M_INFO,
1133 "WARNING: OpenVPN was configured to add an IPv6 "
1134 "route. However, no IPv6 has been configured for %s, "
1135 "therefore the route installation may fail or may not work "
1136 "as expected.",
1137 tt->actual_name);
1138 }
1139
1140 for (r = rl6->routes_ipv6; r; r = r->next)
1141 {
1143 {
1144 delete_route_ipv6(r, tt, es, ctx);
1145 }
1146 ret = add_route_ipv6(r, tt, flags, es, ctx) && ret;
1147 }
1148 rl6->iflags |= RL_ROUTES_ADDED;
1149 }
1150
1151 return ret;
1152}
1153
1154void
1155delete_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tuntap *tt,
1156 unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
1157{
1158 delete_routes_v4(rl, tt, flags, es, ctx);
1159 delete_routes_v6(rl6, tt, flags, es, ctx);
1160}
1161
1162void
1163delete_routes_v4(struct route_list *rl, const struct tuntap *tt, unsigned int flags,
1164 const struct env_set *es, openvpn_net_ctx_t *ctx)
1165{
1166 if (rl && (rl->iflags & RL_ROUTES_ADDED))
1167 {
1168 struct route_ipv4 *r;
1169 for (r = rl->routes; r; r = r->next)
1170 {
1171 delete_route(r, tt, flags, &rl->rgi, es, ctx);
1172 }
1173 rl->iflags &= ~RL_ROUTES_ADDED;
1174 }
1175
1177
1178 if (rl)
1179 {
1180 clear_route_list(rl);
1181 }
1182}
1183
1184void
1185delete_routes_v6(struct route_ipv6_list *rl6, const struct tuntap *tt, unsigned int flags,
1186 const struct env_set *es, openvpn_net_ctx_t *ctx)
1187{
1188 if (rl6 && (rl6->iflags & RL_ROUTES_ADDED))
1189 {
1190 const struct route_ipv6 *r6;
1191 for (r6 = rl6->routes_ipv6; r6; r6 = r6->next)
1192 {
1193 delete_route_ipv6(r6, tt, es, ctx);
1194 }
1195 rl6->iflags &= ~RL_ROUTES_ADDED;
1196 }
1197
1198 if (rl6)
1199 {
1201 }
1202}
1203
1204#ifndef ENABLE_SMALL
1205
1206static const char *
1207show_opt(const char *option)
1208{
1209 if (!option)
1210 {
1211 return "default (not set)";
1212 }
1213 else
1214 {
1215 return option;
1216 }
1217}
1218
1219static void
1220print_route_option(const struct route_option *ro, msglvl_t msglevel)
1221{
1222 msg(msglevel, " route %s/%s/%s/%s", show_opt(ro->network), show_opt(ro->netmask),
1223 show_opt(ro->gateway), show_opt(ro->metric));
1224}
1225
1226void
1228{
1229 const struct route_option *ro;
1230 if (rol->flags & RG_ENABLE)
1231 {
1232 msg(msglevel, " [redirect_default_gateway local=%d]", (rol->flags & RG_LOCAL) != 0);
1233 }
1234 for (ro = rol->routes; ro; ro = ro->next)
1235 {
1236 print_route_option(ro, msglevel);
1237 }
1238}
1239
1240void
1241print_default_gateway(const msglvl_t msglevel, const struct route_gateway_info *rgi,
1242 const struct route_ipv6_gateway_info *rgi6)
1243{
1244 struct gc_arena gc = gc_new();
1245 if (rgi && (rgi->flags & RGI_ADDR_DEFINED))
1246 {
1247 struct buffer out = alloc_buf_gc(256, &gc);
1248 buf_printf(&out, "ROUTE_GATEWAY");
1249 if (rgi->flags & RGI_ON_LINK)
1250 {
1251 buf_printf(&out, " ON_LINK");
1252 }
1253 else
1254 {
1255 buf_printf(&out, " %s", print_in_addr_t(rgi->gateway.addr, 0, &gc));
1256 }
1257 if (rgi->flags & RGI_NETMASK_DEFINED)
1258 {
1259 buf_printf(&out, "/%s", print_in_addr_t(rgi->gateway.netmask, 0, &gc));
1260 }
1261#ifdef _WIN32
1262 if (rgi->flags & RGI_IFACE_DEFINED)
1263 {
1264 buf_printf(&out, " I=%lu", rgi->adapter_index);
1265 }
1266#else
1267 if (rgi->flags & RGI_IFACE_DEFINED)
1268 {
1269 buf_printf(&out, " IFACE=%s", rgi->iface);
1270 }
1271#endif
1272 if (rgi->flags & RGI_HWADDR_DEFINED)
1273 {
1274 buf_printf(&out, " HWADDR=%s", format_hex_ex(rgi->hwaddr, 6, 0, 1, ":", &gc));
1275 }
1276 msg(msglevel, "%s", BSTR(&out));
1277 }
1278
1279 if (rgi6 && (rgi6->flags & RGI_ADDR_DEFINED))
1280 {
1281 struct buffer out = alloc_buf_gc(256, &gc);
1282 buf_printf(&out, "ROUTE6_GATEWAY");
1283 buf_printf(&out, " %s", print_in6_addr(rgi6->gateway.addr_ipv6, 0, &gc));
1284 if (rgi6->flags & RGI_ON_LINK)
1285 {
1286 buf_printf(&out, " ON_LINK");
1287 }
1288 if (rgi6->flags & RGI_NETMASK_DEFINED)
1289 {
1290 buf_printf(&out, "/%d", rgi6->gateway.netbits_ipv6);
1291 }
1292#ifdef _WIN32
1293 if (rgi6->flags & RGI_IFACE_DEFINED)
1294 {
1295 buf_printf(&out, " I=%lu", rgi6->adapter_index);
1296 }
1297#else
1298 if (rgi6->flags & RGI_IFACE_DEFINED)
1299 {
1300 buf_printf(&out, " IFACE=%s", rgi6->iface);
1301 }
1302#endif
1303 if (rgi6->flags & RGI_HWADDR_DEFINED)
1304 {
1305 buf_printf(&out, " HWADDR=%s", format_hex_ex(rgi6->hwaddr, 6, 0, 1, ":", &gc));
1306 }
1307 msg(msglevel, "%s", BSTR(&out));
1308 }
1309 gc_free(&gc);
1310}
1311
1312#endif /* ifndef ENABLE_SMALL */
1313
1314static void
1315setenv_route(struct env_set *es, const struct route_ipv4 *r, int i)
1316{
1317 struct gc_arena gc = gc_new();
1318 if (r->flags & RT_DEFINED)
1319 {
1320 setenv_route_addr(es, "network", r->network, i);
1321 setenv_route_addr(es, "netmask", r->netmask, i);
1322 setenv_route_addr(es, "gateway", r->gateway, i);
1323
1324 if (r->flags & RT_METRIC_DEFINED)
1325 {
1326 struct buffer name = alloc_buf_gc(256, &gc);
1327 buf_printf(&name, "route_metric_%d", i);
1328 setenv_int(es, BSTR(&name), r->metric);
1329 }
1330 }
1331 gc_free(&gc);
1332}
1333
1334void
1335setenv_routes(struct env_set *es, const struct route_list *rl)
1336{
1337 int i = 1;
1338 const struct route_ipv4 *r;
1339 for (r = rl->routes; r; r = r->next)
1340 {
1341 setenv_route(es, r, i++);
1342 }
1343}
1344
1345static void
1346setenv_route_ipv6(struct env_set *es, const struct route_ipv6 *r6, int i)
1347{
1348 struct gc_arena gc = gc_new();
1349 if (r6->flags & RT_DEFINED)
1350 {
1351 struct buffer name1 = alloc_buf_gc(256, &gc);
1352 struct buffer val = alloc_buf_gc(256, &gc);
1353 struct buffer name2 = alloc_buf_gc(256, &gc);
1354
1355 buf_printf(&name1, "route_ipv6_network_%d", i);
1356 buf_printf(&val, "%s/%d", print_in6_addr(r6->network, 0, &gc), r6->netbits);
1357 setenv_str(es, BSTR(&name1), BSTR(&val));
1358
1359 buf_printf(&name2, "route_ipv6_gateway_%d", i);
1360 setenv_str(es, BSTR(&name2), print_in6_addr(r6->gateway, 0, &gc));
1361
1362 if (r6->flags & RT_METRIC_DEFINED)
1363 {
1364 struct buffer name3 = alloc_buf_gc(256, &gc);
1365 buf_printf(&name3, "route_ipv6_metric_%d", i);
1366 setenv_int(es, BSTR(&name3), r6->metric);
1367 }
1368 }
1369 gc_free(&gc);
1370}
1371void
1373{
1374 int i = 1;
1375 const struct route_ipv6 *r6;
1376 for (r6 = rl6->routes_ipv6; r6; r6 = r6->next)
1377 {
1378 setenv_route_ipv6(es, r6, i++);
1379 }
1380}
1381
1382/*
1383 * local_route() determines whether the gateway of a provided host
1384 * route is on the same interface that owns the default gateway.
1385 * It uses the data structure
1386 * returned by get_default_gateway() (struct route_gateway_info)
1387 * to determine this. If the route is local, LR_MATCH is returned.
1388 * When adding routes into the kernel, if LR_MATCH is defined for
1389 * a given route, the route should explicitly reference the default
1390 * gateway interface as the route destination. For example, here
1391 * is an example on Linux that uses LR_MATCH:
1392 *
1393 * route add -net 10.10.0.1 netmask 255.255.255.255 dev eth0
1394 *
1395 * This capability is needed by the "default-gateway block-local"
1396 * directive, to allow client access to the local subnet to be
1397 * blocked but still allow access to the local default gateway.
1398 */
1399
1400/* local_route() return values */
1401#define LR_NOMATCH 0 /* route is not local */
1402#define LR_MATCH 1 /* route is local */
1403#define LR_ERROR 2 /* caller should abort adding route */
1404
1405static int
1407 const struct route_gateway_info *rgi)
1408{
1409 /* set LR_MATCH on local host routes */
1410 const unsigned int rgi_needed = (RGI_ADDR_DEFINED | RGI_NETMASK_DEFINED | RGI_IFACE_DEFINED);
1411 if (rgi && (rgi->flags & rgi_needed) == rgi_needed && gateway == rgi->gateway.addr
1412 && netmask == 0xFFFFFFFF)
1413 {
1414 if (((network ^ rgi->gateway.addr) & rgi->gateway.netmask) == 0)
1415 {
1416 return LR_MATCH;
1417 }
1418 else
1419 {
1420 /* examine additional subnets on gateway interface */
1421 for (int i = 0; i < rgi->n_addrs; ++i)
1422 {
1423 const struct route_gateway_address *gwa = &rgi->addrs[i];
1424 if (((network ^ gwa->addr) & gwa->netmask) == 0)
1425 {
1426 return LR_MATCH;
1427 }
1428 }
1429 }
1430 }
1431 return LR_NOMATCH;
1432}
1433
1434/* Return true if the "on-link" form of the route should be used. This is when the gateway for
1435 * a route is specified as an interface rather than an address. */
1436#if defined(TARGET_LINUX) || defined(_WIN32) || defined(TARGET_DARWIN)
1437static inline bool
1438is_on_link(const int is_local_route, const unsigned int flags, const struct route_gateway_info *rgi)
1439{
1440 return rgi
1441 && (is_local_route == LR_MATCH
1442 || ((flags & ROUTE_REF_GW) && (rgi->flags & RGI_ON_LINK)));
1443}
1444#endif
1445
1446bool
1447add_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags,
1448 const struct route_gateway_info *rgi, /* may be NULL */
1449 const struct env_set *es, openvpn_net_ctx_t *ctx)
1450{
1451 int status = 0;
1452 int is_local_route;
1453
1454 if (!(r->flags & RT_DEFINED))
1455 {
1456 return true; /* no error */
1457 }
1458
1459 struct argv argv = argv_new();
1460 struct gc_arena gc = gc_new();
1461
1462#if !defined(TARGET_LINUX)
1463 const char *network = print_in_addr_t(r->network, 0, &gc);
1464#if !defined(TARGET_AIX)
1465 const char *netmask = print_in_addr_t(r->netmask, 0, &gc);
1466#endif
1467 const char *gateway = print_in_addr_t(r->gateway, 0, &gc);
1468#endif
1469
1470 is_local_route = local_route(r->network, r->netmask, r->gateway, rgi);
1471 if (is_local_route == LR_ERROR)
1472 {
1473 goto done;
1474 }
1475
1476#if defined(TARGET_LINUX)
1477 const char *iface = NULL;
1478 int metric = -1;
1479
1480 if (is_on_link(is_local_route, flags, rgi))
1481 {
1482 iface = rgi->iface;
1483 }
1484
1485 if (r->flags & RT_METRIC_DEFINED)
1486 {
1487 metric = r->metric;
1488 }
1489
1490
1492 int ret = net_route_v4_add(ctx, &r->network, netmask_to_netbits2(r->netmask), &r->gateway,
1493 iface, r->table_id, metric);
1494 if (ret == -EEXIST)
1495 {
1496 msg(D_ROUTE, "NOTE: Linux route add command failed because route exists");
1498 }
1499 else if (ret < 0)
1500 {
1501 msg(M_WARN, "ERROR: Linux route add command failed");
1502 status = RTA_ERROR;
1503 }
1504
1505#elif defined(TARGET_ANDROID)
1506 char out[128];
1507
1508 if (rgi)
1509 {
1510 snprintf(out, sizeof(out), "%s %s %s dev %s", network, netmask, gateway, rgi->iface);
1511 }
1512 else
1513 {
1514 snprintf(out, sizeof(out), "%s %s %s", network, netmask, gateway);
1515 }
1516 bool ret = management_android_control(management, "ROUTE", out);
1517 status = ret ? RTA_SUCCESS : RTA_ERROR;
1518
1519#elif defined(_WIN32)
1520 {
1521 DWORD ai = TUN_ADAPTER_INDEX_INVALID;
1522 argv_printf(&argv, "%s%s ADD %s MASK %s %s", get_win_sys_path(), WIN_ROUTE_PATH_SUFFIX,
1523 network, netmask, gateway);
1524 if (r->flags & RT_METRIC_DEFINED)
1525 {
1526 argv_printf_cat(&argv, "METRIC %d", r->metric);
1527 }
1528 if (is_on_link(is_local_route, flags, rgi))
1529 {
1530 ai = rgi->adapter_index;
1531 argv_printf_cat(&argv, "IF %lu", ai);
1532 }
1533
1535
1536 const char *method = "service";
1537 if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_SERVICE)
1538 {
1539 status = add_route_service(r, tt);
1540 }
1541 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
1542 {
1543 status = add_route_ipapi(r, tt, ai);
1544 method = "ipapi";
1545 }
1546 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_EXE)
1547 {
1549 bool ret =
1550 openvpn_execve_check(&argv, es, 0, "ERROR: Windows route add command failed");
1551 status = ret ? RTA_SUCCESS : RTA_ERROR;
1553 method = "route.exe";
1554 }
1555 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_ADAPTIVE)
1556 {
1557 status = add_route_ipapi(r, tt, ai);
1558 method = "ipapi [adaptive]";
1559 if (status == RTA_ERROR)
1560 {
1561 msg(D_ROUTE, "Route addition fallback to route.exe");
1563 bool ret = openvpn_execve_check(
1564 &argv, es, 0, "ERROR: Windows route add command failed [adaptive]");
1565 status = ret ? RTA_SUCCESS : RTA_ERROR;
1567 method = "route.exe";
1568 }
1569 }
1570 else
1571 {
1572 ASSERT(0);
1573 }
1574 if (status != RTA_ERROR) /* error is logged upstream */
1575 {
1576 msg(D_ROUTE, "Route addition via %s %s", method,
1577 (status == RTA_SUCCESS) ? "succeeded" : "failed because route exists");
1578 }
1579 }
1580
1581#elif defined(TARGET_SOLARIS)
1582
1583 /* example: route add 192.0.2.32 -netmask 255.255.255.224 somegateway */
1584
1585 argv_printf(&argv, "%s add", ROUTE_PATH);
1586
1587 argv_printf_cat(&argv, "%s -netmask %s %s", network, netmask, gateway);
1588
1589 /* Solaris can only distinguish between "metric 0" == "on-link on the
1590 * interface where the IP address given is configured" and "metric > 0"
1591 * == "use gateway specified" (no finer-grained route metrics available)
1592 *
1593 * More recent versions of Solaris can also do "-interface", but that
1594 * would break backwards compatibility with older versions for no gain.
1595 */
1596 if (r->flags & RT_METRIC_DEFINED)
1597 {
1598 argv_printf_cat(&argv, "%d", r->metric);
1599 }
1600
1602 bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route add command failed");
1603 status = ret ? RTA_SUCCESS : RTA_ERROR;
1604
1605#elif defined(TARGET_FREEBSD)
1606
1607 argv_printf(&argv, "%s add", ROUTE_PATH);
1608
1609#if 0
1610 if (r->flags & RT_METRIC_DEFINED)
1611 {
1612 argv_printf_cat(&argv, "-rtt %d", r->metric);
1613 }
1614#endif
1615
1616 argv_printf_cat(&argv, "-net %s %s %s", network, gateway, netmask);
1617
1618 /* FIXME -- add on-link support for FreeBSD */
1619
1621 bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: FreeBSD route add command failed");
1622 status = ret ? RTA_SUCCESS : RTA_ERROR;
1623
1624#elif defined(TARGET_DRAGONFLY)
1625
1626 argv_printf(&argv, "%s add", ROUTE_PATH);
1627
1628#if 0
1629 if (r->flags & RT_METRIC_DEFINED)
1630 {
1631 argv_printf_cat(&argv, "-rtt %d", r->metric);
1632 }
1633#endif
1634
1635 argv_printf_cat(&argv, "-net %s %s %s", network, gateway, netmask);
1636
1637 /* FIXME -- add on-link support for Dragonfly */
1638
1640 bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: DragonFly route add command failed");
1641 status = ret ? RTA_SUCCESS : RTA_ERROR;
1642
1643#elif defined(TARGET_DARWIN)
1644
1645 argv_printf(&argv, "%s add", ROUTE_PATH);
1646
1647#if 0
1648 if (r->flags & RT_METRIC_DEFINED)
1649 {
1650 argv_printf_cat(&argv, "-rtt %d", r->metric);
1651 }
1652#endif
1653
1654 if (is_on_link(is_local_route, flags, rgi))
1655 {
1656 /* Mac OS X route syntax for ON_LINK:
1657 * route add -cloning -net 10.10.0.1 -netmask 255.255.255.255 -interface en0 */
1658 argv_printf_cat(&argv, "-cloning -net %s -netmask %s -interface %s", network, netmask,
1659 rgi->iface);
1660 }
1661 else
1662 {
1663 argv_printf_cat(&argv, "-net %s %s %s", network, gateway, netmask);
1664 }
1665
1667 bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: OS X route add command failed");
1668 status = ret ? RTA_SUCCESS : RTA_ERROR;
1669
1670#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1671
1672 argv_printf(&argv, "%s add", ROUTE_PATH);
1673
1674#if 0
1675 if (r->flags & RT_METRIC_DEFINED)
1676 {
1677 argv_printf_cat(&argv, "-rtt %d", r->metric);
1678 }
1679#endif
1680
1681 argv_printf_cat(&argv, "-net %s %s -netmask %s", network, gateway, netmask);
1682
1683 /* FIXME -- add on-link support for OpenBSD/NetBSD */
1684
1686 bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: OpenBSD/NetBSD route add command failed");
1687 status = ret ? RTA_SUCCESS : RTA_ERROR;
1688
1689#elif defined(TARGET_AIX)
1690
1691 {
1692 int netbits = netmask_to_netbits2(r->netmask);
1693 argv_printf(&argv, "%s add -net %s/%d %s", ROUTE_PATH, network, netbits, gateway);
1695 bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: AIX route add command failed");
1696 status = ret ? RTA_SUCCESS : RTA_ERROR;
1697 }
1698
1699#elif defined(TARGET_HAIKU)
1700
1701 /* ex: route add /dev/net/ipro1000/0 0.0.0.0 gw 192.168.1.1 netmask 128.0.0.0 */
1702 argv_printf(&argv, "%s add %s inet %s gw %s netmask %s", ROUTE_PATH, rgi->iface, network,
1703 gateway, netmask);
1705 bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: Haiku inet route add command failed");
1706 status = ret ? RTA_SUCCESS : RTA_ERROR;
1707
1708#else /* if defined(TARGET_LINUX) */
1709 msg(M_FATAL,
1710 "Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script");
1711#endif /* if defined(TARGET_LINUX) */
1712
1713done:
1714 if (status == RTA_SUCCESS)
1715 {
1716 r->flags |= RT_ADDED;
1717 }
1718 else
1719 {
1720 r->flags &= ~RT_ADDED;
1721 }
1722 argv_free(&argv);
1723 gc_free(&gc);
1724 /* release resources potentially allocated during route setup */
1725 net_ctx_reset(ctx);
1726
1727 return (status != RTA_ERROR);
1728}
1729
1730void
1732{
1733 /* clear host bit parts of route
1734 * (needed if routes are specified improperly, or if we need to
1735 * explicitly setup/clear the "connected" network routes on some OSes)
1736 */
1737 int byte = 15;
1738 int bits_to_clear = 128 - r6->netbits;
1739
1740 while (byte >= 0 && bits_to_clear > 0)
1741 {
1742 if (bits_to_clear >= 8)
1743 {
1744 r6->network.s6_addr[byte--] = 0;
1745 bits_to_clear -= 8;
1746 }
1747 else
1748 {
1749 r6->network.s6_addr[byte--] &= (uint8_t)(0xff << bits_to_clear);
1750 bits_to_clear = 0;
1751 }
1752 }
1753}
1754
1755bool
1756add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags,
1757 const struct env_set *es, openvpn_net_ctx_t *ctx)
1758{
1759 int status = 0;
1760 bool gateway_needed = false;
1761
1762 if (!(r6->flags & RT_DEFINED))
1763 {
1764 return true; /* no error */
1765 }
1766
1767 struct argv argv = argv_new();
1768 struct gc_arena gc = gc_new();
1769
1770#ifndef _WIN32
1771 const char *device = tt->actual_name;
1772 if (r6->iface != NULL) /* vpn server special route */
1773 {
1774 device = r6->iface;
1775 if (!IN6_IS_ADDR_UNSPECIFIED(&r6->gateway))
1776 {
1777 gateway_needed = true;
1778 }
1779 }
1780#endif
1781
1783 const char *network = print_in6_addr(r6->network, 0, &gc);
1784 const char *gateway = print_in6_addr(r6->gateway, 0, &gc);
1785
1786#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
1787 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1788
1789 /* the BSD platforms cannot specify gateway and interface independently,
1790 * but for link-local destinations, we MUST specify the interface, so
1791 * we build a combined "$gateway%$interface" gateway string
1792 */
1793 if (r6->iface != NULL && gateway_needed
1794 && IN6_IS_ADDR_LINKLOCAL(&r6->gateway)) /* fe80::...%intf */
1795 {
1796 size_t len = strlen(gateway) + 1 + strlen(r6->iface) + 1;
1797 char *tmp = gc_malloc(len, true, &gc);
1798 snprintf(tmp, len, "%s%%%s", gateway, r6->iface);
1799 gateway = tmp;
1800 }
1801#endif
1802
1803#ifndef _WIN32
1804 msg(D_ROUTE, "add_route_ipv6(%s/%d -> %s metric %d) dev %s", network, r6->netbits, gateway,
1805 r6->metric, device);
1806#else
1807 msg(D_ROUTE, "add_route_ipv6(%s/%d -> %s metric %d) IF %lu", network, r6->netbits, gateway,
1808 r6->metric, r6->adapter_index ? r6->adapter_index : tt->adapter_index);
1809#endif
1810
1811 /*
1812 * Filter out routes which are essentially no-ops
1813 * (not currently done for IPv6)
1814 */
1815
1816 /* On "tun" interface, we never set a gateway if the operating system
1817 * can do "route to interface" - it does not add value, as the target
1818 * dev already fully qualifies the route destination on point-to-point
1819 * interfaces. OTOH, on "tap" interface, we must always set the
1820 * gateway unless the route is to be an on-link network
1821 */
1822 if (tt->type == DEV_TYPE_TAP && !((r6->flags & RT_METRIC_DEFINED) && r6->metric == 0))
1823 {
1824 gateway_needed = true;
1825 }
1826
1827 if (gateway_needed && IN6_IS_ADDR_UNSPECIFIED(&r6->gateway))
1828 {
1829 msg(M_WARN,
1830 "ROUTE6 WARNING: " PACKAGE_NAME " needs a gateway "
1831 "parameter for a --route-ipv6 option and no default was set via "
1832 "--ifconfig-ipv6 or --route-ipv6-gateway option. Not installing "
1833 "IPv6 route to %s/%d.",
1834 network, r6->netbits);
1835 status = 0;
1836 goto done;
1837 }
1838
1839#if defined(TARGET_LINUX)
1840 int metric = -1;
1841 if ((r6->flags & RT_METRIC_DEFINED) && (r6->metric > 0))
1842 {
1843 metric = r6->metric;
1844 }
1845
1847 int ret = net_route_v6_add(ctx, &r6->network, r6->netbits, gateway_needed ? &r6->gateway : NULL,
1848 device, r6->table_id, metric);
1849 if (ret == -EEXIST)
1850 {
1851 msg(D_ROUTE, "NOTE: Linux route add command failed because route exists");
1853 }
1854 else if (ret < 0)
1855 {
1856 msg(M_WARN, "ERROR: Linux route add command failed");
1857 status = RTA_ERROR;
1858 }
1859
1860#elif defined(TARGET_ANDROID)
1861 char out[64];
1862
1863 snprintf(out, sizeof(out), "%s/%d %s", network, r6->netbits, device);
1864
1865 status = management_android_control(management, "ROUTE6", out);
1866
1867#elif defined(_WIN32)
1868
1869 if (tt->options.msg_channel)
1870 {
1872 }
1873 else
1874 {
1875 status = route_ipv6_ipapi(true, r6, tt);
1876 }
1877#elif defined(TARGET_SOLARIS)
1878
1879 /* example: route add -inet6 2001:db8::/32 somegateway 0 */
1880
1881 /* for some reason, routes to tun/tap do not work for me unless I set
1882 * "metric 0" - otherwise, the routes will be nicely installed, but
1883 * packets will just disappear somewhere. So we always use "0" now,
1884 * unless the route points to "gateway on other interface"...
1885 *
1886 * (Note: OpenSolaris can not specify host%interface gateways, so we just
1887 * use the GW addresses - it seems to still work for fe80:: addresses,
1888 * however this is done internally. NUD maybe?)
1889 */
1890 argv_printf(&argv, "%s add -inet6 %s/%d %s", ROUTE_PATH, network, r6->netbits, gateway);
1891
1892 /* on tun (not tap), not "elsewhere"? -> metric 0 */
1893 if (tt->type == DEV_TYPE_TUN && !r6->iface)
1894 {
1895 argv_printf_cat(&argv, "0");
1896 }
1897
1899 bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route add -inet6 command failed");
1900 status = ret ? RTA_SUCCESS : RTA_ERROR;
1901
1902#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1903
1904 argv_printf(&argv, "%s add -inet6 %s/%d", ROUTE_PATH, network, r6->netbits);
1905
1906 if (gateway_needed)
1907 {
1908 argv_printf_cat(&argv, "%s", gateway);
1909 }
1910 else
1911 {
1912 argv_printf_cat(&argv, "-iface %s", device);
1913 }
1914
1916 bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: *BSD route add -inet6 command failed");
1917 status = ret ? RTA_SUCCESS : RTA_ERROR;
1918
1919#elif defined(TARGET_DARWIN)
1920
1921 argv_printf(&argv, "%s add -inet6 %s -prefixlen %d", ROUTE_PATH, network, r6->netbits);
1922
1923 if (gateway_needed)
1924 {
1925 argv_printf_cat(&argv, "%s", gateway);
1926 }
1927 else
1928 {
1929 argv_printf_cat(&argv, "-iface %s", device);
1930 }
1931
1933 bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: MacOS X route add -inet6 command failed");
1934 status = ret ? RTA_SUCCESS : RTA_ERROR;
1935
1936#elif defined(TARGET_OPENBSD)
1937
1938 argv_printf(&argv, "%s add -inet6 %s -prefixlen %d %s", ROUTE_PATH, network, r6->netbits,
1939 gateway);
1940
1942 bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: OpenBSD route add -inet6 command failed");
1943 status = ret ? RTA_SUCCESS : RTA_ERROR;
1944
1945#elif defined(TARGET_NETBSD)
1946
1947 argv_printf(&argv, "%s add -inet6 %s/%d %s", ROUTE_PATH, network, r6->netbits, gateway);
1948
1950 bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: NetBSD route add -inet6 command failed");
1951 status = ret ? RTA_SUCCESS : RTA_ERROR;
1952
1953#elif defined(TARGET_AIX)
1954
1955 argv_printf(&argv, "%s add -inet6 %s/%d %s", ROUTE_PATH, network, r6->netbits, gateway);
1957 bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: AIX route add command failed");
1958 status = ret ? RTA_SUCCESS : RTA_ERROR;
1959
1960#elif defined(TARGET_HAIKU)
1961
1962 /* ex: route add /dev/net/ipro1000/0 inet6 :: gw beef::cafe prefixlen 64 */
1963 argv_printf(&argv, "%s add %s inet6 %s gw %s prefixlen %d", ROUTE_PATH, r6->iface, network,
1964 gateway, r6->netbits);
1966 bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: Haiku inet6 route add command failed");
1967 status = ret ? RTA_SUCCESS : RTA_ERROR;
1968
1969#else /* if defined(TARGET_LINUX) */
1970 msg(M_FATAL,
1971 "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");
1972#endif /* if defined(TARGET_LINUX) */
1973
1974done:
1975 if (status == RTA_SUCCESS)
1976 {
1977 r6->flags |= RT_ADDED;
1978 }
1979 else
1980 {
1981 r6->flags &= ~RT_ADDED;
1982 }
1983 argv_free(&argv);
1984 gc_free(&gc);
1985 /* release resources potentially allocated during route setup */
1986 net_ctx_reset(ctx);
1987
1988 return (status != RTA_ERROR);
1989}
1990
1991static void
1992delete_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags,
1993 const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
1994{
1995#if !defined(TARGET_LINUX)
1996 const char *network;
1997#if !defined(TARGET_AIX)
1998 const char *netmask;
1999#endif
2000 const char *gateway;
2001#else /* if !defined(TARGET_LINUX) */
2002 int metric;
2003#endif
2004 int is_local_route;
2005
2006 if ((r->flags & (RT_DEFINED | RT_ADDED)) != (RT_DEFINED | RT_ADDED))
2007 {
2008 return;
2009 }
2010
2011 struct gc_arena gc = gc_new();
2012 struct argv argv = argv_new();
2013
2014#if !defined(TARGET_LINUX)
2015 network = print_in_addr_t(r->network, 0, &gc);
2016#if !defined(TARGET_AIX)
2017 netmask = print_in_addr_t(r->netmask, 0, &gc);
2018#endif
2019 gateway = print_in_addr_t(r->gateway, 0, &gc);
2020#endif
2021
2022 is_local_route = local_route(r->network, r->netmask, r->gateway, rgi);
2023 if (is_local_route == LR_ERROR)
2024 {
2025 goto done;
2026 }
2027
2028#if defined(TARGET_LINUX)
2029 metric = -1;
2030 if (r->flags & RT_METRIC_DEFINED)
2031 {
2032 metric = r->metric;
2033 }
2034
2035 if (net_route_v4_del(ctx, &r->network, netmask_to_netbits2(r->netmask), &r->gateway, NULL,
2036 r->table_id, metric)
2037 < 0)
2038 {
2039 msg(M_WARN, "ERROR: Linux route delete command failed");
2040 }
2041#elif defined(_WIN32)
2042
2043 argv_printf(&argv, "%s%s DELETE %s MASK %s %s", get_win_sys_path(), WIN_ROUTE_PATH_SUFFIX,
2044 network, netmask, gateway);
2045
2047
2048 if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_SERVICE)
2049 {
2050 const bool status = del_route_service(r, tt);
2051 msg(D_ROUTE, "Route deletion via service %s", status ? "succeeded" : "failed");
2052 }
2053 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
2054 {
2055 const bool status = del_route_ipapi(r, tt);
2056 msg(D_ROUTE, "Route deletion via IPAPI %s", status ? "succeeded" : "failed");
2057 }
2058 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_EXE)
2059 {
2061 openvpn_execve_check(&argv, es, 0, "ERROR: Windows route delete command failed");
2063 }
2064 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_ADAPTIVE)
2065 {
2066 const bool status = del_route_ipapi(r, tt);
2067 msg(D_ROUTE, "Route deletion via IPAPI %s [adaptive]", status ? "succeeded" : "failed");
2068 if (!status)
2069 {
2070 msg(D_ROUTE, "Route deletion fallback to route.exe");
2073 "ERROR: Windows route delete command failed [adaptive]");
2075 }
2076 }
2077 else
2078 {
2079 ASSERT(0);
2080 }
2081
2082#elif defined(TARGET_SOLARIS)
2083
2084 argv_printf(&argv, "%s delete %s -netmask %s %s", ROUTE_PATH, network, netmask, gateway);
2085
2087 openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route delete command failed");
2088
2089#elif defined(TARGET_FREEBSD)
2090
2091 argv_printf(&argv, "%s delete -net %s %s %s", ROUTE_PATH, network, gateway, netmask);
2092
2094 openvpn_execve_check(&argv, es, 0, "ERROR: FreeBSD route delete command failed");
2095
2096#elif defined(TARGET_DRAGONFLY)
2097
2098 argv_printf(&argv, "%s delete -net %s %s %s", ROUTE_PATH, network, gateway, netmask);
2099
2101 openvpn_execve_check(&argv, es, 0, "ERROR: DragonFly route delete command failed");
2102
2103#elif defined(TARGET_DARWIN)
2104
2105 if (is_on_link(is_local_route, flags, rgi))
2106 {
2107 argv_printf(&argv, "%s delete -cloning -net %s -netmask %s -interface %s", ROUTE_PATH,
2108 network, netmask, rgi->iface);
2109 }
2110 else
2111 {
2112 argv_printf(&argv, "%s delete -net %s %s %s", ROUTE_PATH, network, gateway, netmask);
2113 }
2114
2116 openvpn_execve_check(&argv, es, 0, "ERROR: OS X route delete command failed");
2117
2118#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2119
2120 argv_printf(&argv, "%s delete -net %s %s -netmask %s", ROUTE_PATH, network, gateway, netmask);
2121
2123 openvpn_execve_check(&argv, es, 0, "ERROR: OpenBSD/NetBSD route delete command failed");
2124
2125#elif defined(TARGET_ANDROID)
2126 /* Avoids the unused variables warnings that all other platforms use
2127 * by adding them to the error message. */
2128 msg(D_ROUTE_DEBUG, "Deleting routes on Android is not possible/not "
2129 "needed. The VpnService API allows routes to be set "
2130 "on connect only and will clean up automatically. "
2131 "Tried to delete route %s netmask %s gateway %s",
2132 network, netmask, gateway);
2133#elif defined(TARGET_AIX)
2134
2135 {
2136 int netbits = netmask_to_netbits2(r->netmask);
2137 argv_printf(&argv, "%s delete -net %s/%d %s", ROUTE_PATH, network, netbits, gateway);
2139 openvpn_execve_check(&argv, es, 0, "ERROR: AIX route delete command failed");
2140 }
2141
2142#elif defined(TARGET_HAIKU)
2143
2144 /* ex: route delete /dev/net/ipro1000/0 inet 192.168.0.0 gw 192.168.1.1 netmask 255.255.0.0 */
2145 argv_printf(&argv, "%s delete %s inet %s gw %s netmask %s", ROUTE_PATH, rgi->iface, network,
2146 gateway, netmask);
2148 openvpn_execve_check(&argv, es, 0, "ERROR: Haiku inet route delete command failed");
2149
2150#else /* if defined(TARGET_LINUX) */
2151 msg(M_FATAL,
2152 "Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script");
2153#endif /* if defined(TARGET_LINUX) */
2154
2155done:
2156 r->flags &= ~RT_ADDED;
2157 argv_free(&argv);
2158 gc_free(&gc);
2159 /* release resources potentially allocated during route cleanup */
2160 net_ctx_reset(ctx);
2161}
2162
2163void
2164delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt, const struct env_set *es,
2165 openvpn_net_ctx_t *ctx)
2166{
2167 const char *network;
2168
2169 if ((r6->flags & (RT_DEFINED | RT_ADDED)) != (RT_DEFINED | RT_ADDED))
2170 {
2171 return;
2172 }
2173
2174#if !defined(_WIN32)
2175#if !defined(TARGET_LINUX)
2176 const char *gateway;
2177#endif
2178#if !defined(TARGET_SOLARIS)
2179 bool gateway_needed = false;
2180 const char *device = tt->actual_name;
2181 if (r6->iface != NULL) /* vpn server special route */
2182 {
2183 device = r6->iface;
2184 gateway_needed = true;
2185 }
2186 (void)device; /* unused on some platforms */
2187
2188 /* if we used a gateway on "add route", we also need to specify it on
2189 * delete, otherwise some OSes will refuse to delete the route
2190 */
2191 if (tt->type == DEV_TYPE_TAP && !((r6->flags & RT_METRIC_DEFINED) && r6->metric == 0))
2192 {
2193 gateway_needed = true;
2194 }
2195#endif
2196#endif
2197
2198 struct gc_arena gc = gc_new();
2199 struct argv argv = argv_new();
2200
2201 network = print_in6_addr(r6->network, 0, &gc);
2202#if !defined(TARGET_LINUX) && !defined(_WIN32)
2203 gateway = print_in6_addr(r6->gateway, 0, &gc);
2204#endif
2205
2206#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
2207 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2208
2209 /* the BSD platforms cannot specify gateway and interface independently,
2210 * but for link-local destinations, we MUST specify the interface, so
2211 * we build a combined "$gateway%$interface" gateway string
2212 */
2213 if (r6->iface != NULL && gateway_needed
2214 && IN6_IS_ADDR_LINKLOCAL(&r6->gateway)) /* fe80::...%intf */
2215 {
2216 size_t len = strlen(gateway) + 1 + strlen(r6->iface) + 1;
2217 char *tmp = gc_malloc(len, true, &gc);
2218 snprintf(tmp, len, "%s%%%s", gateway, r6->iface);
2219 gateway = tmp;
2220 }
2221#endif
2222
2223 msg(D_ROUTE, "delete_route_ipv6(%s/%d)", network, r6->netbits);
2224
2225#if defined(TARGET_LINUX)
2226 int metric = -1;
2227 if ((r6->flags & RT_METRIC_DEFINED) && (r6->metric > 0))
2228 {
2229 metric = r6->metric;
2230 }
2231
2232 if (net_route_v6_del(ctx, &r6->network, r6->netbits, gateway_needed ? &r6->gateway : NULL,
2233 device, r6->table_id, metric)
2234 < 0)
2235 {
2236 msg(M_WARN, "ERROR: Linux route v6 delete command failed");
2237 }
2238
2239#elif defined(_WIN32)
2240
2241 if (tt->options.msg_channel)
2242 {
2244 }
2245 else
2246 {
2247 route_ipv6_ipapi(false, r6, tt);
2248 }
2249#elif defined(TARGET_SOLARIS)
2250
2251 /* example: route delete -inet6 2001:db8::/32 somegateway */
2252
2253 argv_printf(&argv, "%s delete -inet6 %s/%d %s", ROUTE_PATH, network, r6->netbits, gateway);
2254
2256 openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route delete -inet6 command failed");
2257
2258#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
2259
2260 argv_printf(&argv, "%s delete -inet6 %s/%d", ROUTE_PATH, network, r6->netbits);
2261
2262 if (gateway_needed)
2263 {
2264 argv_printf_cat(&argv, "%s", gateway);
2265 }
2266 else
2267 {
2268 argv_printf_cat(&argv, "-iface %s", device);
2269 }
2270
2272 openvpn_execve_check(&argv, es, 0, "ERROR: *BSD route delete -inet6 command failed");
2273
2274#elif defined(TARGET_DARWIN)
2275
2276 argv_printf(&argv, "%s delete -inet6 %s -prefixlen %d", ROUTE_PATH, network, r6->netbits);
2277
2278 if (gateway_needed)
2279 {
2280 argv_printf_cat(&argv, "%s", gateway);
2281 }
2282 else
2283 {
2284 argv_printf_cat(&argv, "-iface %s", device);
2285 }
2286
2288 openvpn_execve_check(&argv, es, 0, "ERROR: MacOS X route delete -inet6 command failed");
2289
2290#elif defined(TARGET_OPENBSD)
2291
2292 argv_printf(&argv, "%s delete -inet6 %s -prefixlen %d %s", ROUTE_PATH, network, r6->netbits,
2293 gateway);
2294
2296 openvpn_execve_check(&argv, es, 0, "ERROR: OpenBSD route delete -inet6 command failed");
2297
2298#elif defined(TARGET_NETBSD)
2299
2300 argv_printf(&argv, "%s delete -inet6 %s/%d %s", ROUTE_PATH, network, r6->netbits, gateway);
2301
2303 openvpn_execve_check(&argv, es, 0, "ERROR: NetBSD route delete -inet6 command failed");
2304
2305#elif defined(TARGET_AIX)
2306
2307 argv_printf(&argv, "%s delete -inet6 %s/%d %s", ROUTE_PATH, network, r6->netbits, gateway);
2309 openvpn_execve_check(&argv, es, 0, "ERROR: AIX route add command failed");
2310
2311#elif defined(TARGET_ANDROID)
2312 msg(D_ROUTE_DEBUG, "Deleting routes on Android is not possible/not "
2313 "needed. The VpnService API allows routes to be set "
2314 "on connect only and will clean up automatically. "
2315 "Tried to delete %s gateway %s",
2316 network,
2317 gateway_needed ? gateway : "(not needed)");
2318#elif defined(TARGET_HAIKU)
2319
2320 /* ex: route delete /dev/net/ipro1000/0 inet6 :: gw beef::cafe prefixlen 64 */
2321 argv_printf(&argv, "%s delete %s inet6 %s gw %s prefixlen %d", ROUTE_PATH, r6->iface, network,
2322 gateway, r6->netbits);
2324 openvpn_execve_check(&argv, es, 0, "ERROR: Haiku inet6 route delete command failed");
2325
2326#else /* if defined(TARGET_LINUX) */
2327 msg(M_FATAL,
2328 "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");
2329#endif /* if defined(TARGET_LINUX) */
2330
2331 argv_free(&argv);
2332 gc_free(&gc);
2333 /* release resources potentially allocated during route cleanup */
2334 net_ctx_reset(ctx);
2335}
2336
2337/*
2338 * The --redirect-gateway option requires OS-specific code below
2339 * to get the current default gateway.
2340 */
2341
2342#if defined(_WIN32)
2343
2344static const MIB_IPFORWARDTABLE *
2346{
2347 ULONG size = 0;
2348 PMIB_IPFORWARDTABLE rt = NULL;
2349 DWORD status;
2350
2351 status = GetIpForwardTable(NULL, &size, TRUE);
2352 if (status == ERROR_INSUFFICIENT_BUFFER)
2353 {
2354 rt = (PMIB_IPFORWARDTABLE)gc_malloc(size, false, gc);
2355 status = GetIpForwardTable(rt, &size, TRUE);
2356 if (status != NO_ERROR)
2357 {
2358 msg(D_ROUTE, "NOTE: GetIpForwardTable returned error: %s (code=%lu)",
2360 rt = NULL;
2361 }
2362 }
2363 return rt;
2364}
2365
2366static int
2367test_route(const IP_ADAPTER_INFO *adapters, const in_addr_t gateway, DWORD *index)
2368{
2369 int count = 0;
2370 DWORD i = adapter_index_of_ip(adapters, gateway, &count, NULL);
2371 if (index)
2372 {
2373 *index = i;
2374 }
2375 return count;
2376}
2377
2378static void
2379test_route_helper(bool *ret, int *count, int *good, int *ambig, const IP_ADAPTER_INFO *adapters,
2380 const in_addr_t gateway)
2381{
2382 int c;
2383
2384 ++*count;
2385 c = test_route(adapters, gateway, NULL);
2386 if (c == 0)
2387 {
2388 *ret = false;
2389 }
2390 else
2391 {
2392 ++*good;
2393 }
2394 if (c > 1)
2395 {
2396 ++*ambig;
2397 }
2398}
2399
2400/*
2401 * If we tried to add routes now, would we succeed?
2402 */
2403bool
2404test_routes(const struct route_list *rl, const struct tuntap *tt)
2405{
2406 struct gc_arena gc = gc_new();
2407 const IP_ADAPTER_INFO *adapters = get_adapter_info_list(&gc);
2408 bool ret = false;
2409 int count = 0;
2410 int good = 0;
2411 int ambig = 0;
2412 int len = -1;
2413 bool adapter_up = false;
2414
2415 if (is_adapter_up(tt, adapters))
2416 {
2417 ret = true;
2418 adapter_up = true;
2419
2420 /* we do this test only if we have IPv4 routes to install, and if
2421 * the tun/tap interface has seen IPv4 ifconfig - because if we
2422 * have no IPv4, the check will always fail, failing tun init
2423 */
2424 if (rl && tt->did_ifconfig_setup)
2425 {
2426 const struct route_ipv4 *r;
2427 for (r = rl->routes, len = 0; r; r = r->next, ++len)
2428 {
2429 test_route_helper(&ret, &count, &good, &ambig, adapters, r->gateway);
2430 }
2431
2432 if ((rl->flags & RG_ENABLE) && (rl->spec.flags & RTSA_REMOTE_ENDPOINT))
2433 {
2434 test_route_helper(&ret, &count, &good, &ambig, adapters, rl->spec.remote_endpoint);
2435 }
2436 }
2437 }
2438
2439 msg(D_ROUTE, "TEST ROUTES: %d/%d succeeded len=%d ret=%u a=%d u/d=%s",
2440 good, count, len, ret, ambig, adapter_up ? "up" : "down");
2441
2442 gc_free(&gc);
2443 return ret;
2444}
2445
2446static const MIB_IPFORWARDROW *
2447get_default_gateway_row(const MIB_IPFORWARDTABLE *routes)
2448{
2449 struct gc_arena gc = gc_new();
2450 DWORD lowest_metric = MAXDWORD;
2451 const MIB_IPFORWARDROW *ret = NULL;
2452 int best = -1;
2453
2454 if (routes)
2455 {
2456 for (DWORD i = 0; i < routes->dwNumEntries; ++i)
2457 {
2458 const MIB_IPFORWARDROW *row = &routes->table[i];
2459 const in_addr_t net = ntohl(row->dwForwardDest);
2460 const in_addr_t mask = ntohl(row->dwForwardMask);
2461 const DWORD index = row->dwForwardIfIndex;
2462 const DWORD metric = row->dwForwardMetric1;
2463
2464 dmsg(D_ROUTE_DEBUG, "GDGR: route[%lu] %s/%s i=%lu m=%lu", i,
2465 print_in_addr_t((in_addr_t)net, 0, &gc), print_in_addr_t((in_addr_t)mask, 0, &gc),
2466 index, metric);
2467
2468 if (!net && !mask && metric < lowest_metric)
2469 {
2470 ret = row;
2471 lowest_metric = metric;
2472 best = i;
2473 }
2474 }
2475 }
2476
2477 dmsg(D_ROUTE_DEBUG, "GDGR: best=%d lm=%lu", best, lowest_metric);
2478
2479 gc_free(&gc);
2480 return ret;
2481}
2482
2494static DWORD
2495get_best_route(struct gc_arena *gc, SOCKADDR_INET *dest, MIB_IPFORWARD_ROW2 *best_route)
2496{
2497 DWORD best_if_index;
2498 DWORD status;
2499
2500 CLEAR(*best_route);
2501
2502 /* get the best interface index to reach dest */
2503 status = GetBestInterfaceEx((struct sockaddr *)dest, &best_if_index);
2504 if (status != NO_ERROR)
2505 {
2506 msg(D_ROUTE, "NOTE: GetBestInterfaceEx returned error: %s (code=%lu)",
2508 goto done;
2509 }
2510
2511 msg(D_ROUTE_DEBUG, "GetBestInterfaceEx() returned if=%lu", best_if_index);
2512
2513 /* get the routing information (such as NextHop) for the destination and interface */
2514 NET_LUID luid;
2515 CLEAR(luid);
2516 SOCKADDR_INET best_src;
2517 CLEAR(best_src);
2518 status = GetBestRoute2(&luid, best_if_index, NULL, dest, 0, best_route, &best_src);
2519 if (status != NO_ERROR)
2520 {
2521 msg(D_ROUTE, "NOTE: GetIpForwardEntry2 returned error: %s (code=%lu)",
2523 goto done;
2524 }
2525
2526done:
2527 return status;
2528}
2529
2530void
2532{
2533 CLEAR(*rgi);
2534
2535 struct gc_arena gc = gc_new();
2536
2537 /* convert in_addr_t into SOCKADDR_INET */
2538 SOCKADDR_INET sa;
2539 CLEAR(sa);
2540 sa.si_family = AF_INET;
2541 sa.Ipv4.sin_addr.s_addr = htonl(dest);
2542
2543 /* get the best route to the destination */
2544 MIB_IPFORWARD_ROW2 best_route;
2545 CLEAR(best_route);
2546 DWORD status = get_best_route(&gc, &sa, &best_route);
2547 if (status != NO_ERROR)
2548 {
2549 goto done;
2550 }
2551
2553 rgi->gateway.addr = ntohl(best_route.NextHop.Ipv4.sin_addr.S_un.S_addr);
2554 rgi->adapter_index = best_route.InterfaceIndex;
2555
2556 if (rgi->gateway.addr == INADDR_ANY)
2557 {
2558 rgi->flags |= RGI_ON_LINK;
2559 }
2560
2561 /* get netmask and MAC address */
2562 const IP_ADAPTER_INFO *adapters = get_adapter_info_list(&gc);
2563 const IP_ADAPTER_INFO *ai = get_adapter(adapters, rgi->adapter_index);
2564 if (ai)
2565 {
2566 memcpy(rgi->hwaddr, ai->Address, 6);
2567 rgi->flags |= RGI_HWADDR_DEFINED;
2568
2569 /* get netmask for non-onlink routes */
2570 in_addr_t nm = inet_addr(ai->IpAddressList.IpMask.String);
2571 if (!(rgi->flags & RGI_ON_LINK) && (nm != INADDR_NONE))
2572 {
2573 rgi->gateway.netmask = ntohl(nm);
2574 rgi->flags |= RGI_NETMASK_DEFINED;
2575 }
2576 }
2577
2578done:
2579 gc_free(&gc);
2580}
2581
2582static DWORD
2583windows_route_find_if_index(const struct route_ipv4 *r, const struct tuntap *tt)
2584{
2585 struct gc_arena gc = gc_new();
2586 DWORD ret = TUN_ADAPTER_INDEX_INVALID;
2587 int count = 0;
2588 const IP_ADAPTER_INFO *adapters = get_adapter_info_list(&gc);
2589 const IP_ADAPTER_INFO *tun_adapter = get_tun_adapter(tt, adapters);
2590 bool on_tun = false;
2591
2592 /* first test on tun interface */
2593 if (is_ip_in_adapter_subnet(tun_adapter, r->gateway, NULL))
2594 {
2595 ret = tun_adapter->Index;
2596 count = 1;
2597 on_tun = true;
2598 }
2599 else /* test on other interfaces */
2600 {
2601 count = test_route(adapters, r->gateway, &ret);
2602 }
2603
2604 if (count == 0)
2605 {
2606 msg(M_WARN, "Warning: route gateway is not reachable on any active network adapters: %s",
2607 print_in_addr_t(r->gateway, 0, &gc));
2609 }
2610 else if (count > 1)
2611 {
2612 msg(M_WARN, "Warning: route gateway is ambiguous: %s (%d matches)",
2613 print_in_addr_t(r->gateway, 0, &gc), count);
2614 }
2615
2616 dmsg(D_ROUTE_DEBUG, "DEBUG: route find if: on_tun=%d count=%d index=%lu",
2617 on_tun, count, ret);
2618
2619 gc_free(&gc);
2620 return ret;
2621}
2622
2623/* IPv6 implementation using GetBestRoute2()
2624 * https://msdn.microsoft.com/en-us/library/windows/desktop/aa365922(v=vs.85).aspx
2625 * https://msdn.microsoft.com/en-us/library/windows/desktop/aa814411(v=vs.85).aspx
2626 */
2627void
2628get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6, const struct in6_addr *dest,
2629 openvpn_net_ctx_t *ctx)
2630{
2631 struct gc_arena gc = gc_new();
2632 CLEAR(*rgi6);
2633
2634 SOCKADDR_INET DestinationAddress;
2635 CLEAR(DestinationAddress);
2636 DestinationAddress.si_family = AF_INET6;
2637 if (dest)
2638 {
2639 DestinationAddress.Ipv6.sin6_addr = *dest;
2640 }
2641
2642 MIB_IPFORWARD_ROW2 BestRoute;
2643 CLEAR(BestRoute);
2644 DWORD status = get_best_route(&gc, &DestinationAddress, &BestRoute);
2645
2646 if (status != NO_ERROR)
2647 {
2648 goto done;
2649 }
2650
2651 msg(D_ROUTE, "GDG6: II=%lu DP=%s/%d NH=%s", BestRoute.InterfaceIndex,
2652 print_in6_addr(BestRoute.DestinationPrefix.Prefix.Ipv6.sin6_addr, 0, &gc),
2653 BestRoute.DestinationPrefix.PrefixLength,
2654 print_in6_addr(BestRoute.NextHop.Ipv6.sin6_addr, 0, &gc));
2655 msg(D_ROUTE, "GDG6: Metric=%lu, Loopback=%u, AA=%u, I=%u", BestRoute.Metric,
2656 BestRoute.Loopback, BestRoute.AutoconfigureAddress, BestRoute.Immortal);
2657
2658 rgi6->gateway.addr_ipv6 = BestRoute.NextHop.Ipv6.sin6_addr;
2659 rgi6->adapter_index = BestRoute.InterfaceIndex;
2661
2662 /* on-link is signalled by receiving an empty (::) NextHop */
2663 if (IN6_IS_ADDR_UNSPECIFIED(&BestRoute.NextHop.Ipv6.sin6_addr))
2664 {
2665 rgi6->flags |= RGI_ON_LINK;
2666 }
2667
2668done:
2669 gc_free(&gc);
2670}
2671
2672/* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
2673static int
2674add_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt, DWORD adapter_index)
2675{
2676 struct gc_arena gc = gc_new();
2677 int ret = RTA_ERROR;
2678 DWORD status;
2679 const DWORD if_index = (adapter_index == TUN_ADAPTER_INDEX_INVALID)
2681 : adapter_index;
2682
2683 if (if_index != TUN_ADAPTER_INDEX_INVALID)
2684 {
2685 MIB_IPFORWARDROW fr;
2686 CLEAR(fr);
2687 fr.dwForwardDest = htonl(r->network);
2688 fr.dwForwardMask = htonl(r->netmask);
2689 fr.dwForwardPolicy = 0;
2690 fr.dwForwardNextHop = htonl(r->gateway);
2691 fr.dwForwardIfIndex = if_index;
2692 fr.dwForwardType = 4; /* the next hop is not the final dest */
2693 fr.dwForwardProto = 3; /* PROTO_IP_NETMGMT */
2694 fr.dwForwardAge = 0;
2695 fr.dwForwardNextHopAS = 0;
2696 fr.dwForwardMetric1 = (r->flags & RT_METRIC_DEFINED) ? r->metric : 1;
2697 fr.dwForwardMetric2 = METRIC_NOT_USED;
2698 fr.dwForwardMetric3 = METRIC_NOT_USED;
2699 fr.dwForwardMetric4 = METRIC_NOT_USED;
2700 fr.dwForwardMetric5 = METRIC_NOT_USED;
2701
2702 if ((r->network & r->netmask) != r->network)
2703 {
2704 msg(M_WARN, "Warning: address %s is not a network address in relation to netmask %s",
2705 print_in_addr_t(r->network, 0, &gc), print_in_addr_t(r->netmask, 0, &gc));
2706 }
2707
2708 status = CreateIpForwardEntry(&fr);
2709
2710 if (status == NO_ERROR)
2711 {
2712 ret = RTA_SUCCESS;
2713 }
2714 else if (status == ERROR_OBJECT_ALREADY_EXISTS)
2715 {
2716 ret = RTA_EEXIST;
2717 }
2718 else
2719 {
2720 /* failed, try increasing the metric to work around Vista issue */
2721 /* iteratively retry higher metrics up to this limit */
2722 const DWORD forward_metric_limit = 2048;
2723
2724 for (; fr.dwForwardMetric1 <= forward_metric_limit; ++fr.dwForwardMetric1)
2725 {
2726 /* try a different forward type=3 ("the next hop is the final dest") in addition
2727 * to 4.
2728 * --redirect-gateway over RRAS seems to need this. */
2729 for (fr.dwForwardType = 4; fr.dwForwardType >= 3; --fr.dwForwardType)
2730 {
2731 status = CreateIpForwardEntry(&fr);
2732 if (status == NO_ERROR)
2733 {
2734 msg(D_ROUTE,
2735 "ROUTE: CreateIpForwardEntry succeeded with dwForwardMetric1=%lu and dwForwardType=%lu",
2736 fr.dwForwardMetric1, fr.dwForwardType);
2737 ret = RTA_SUCCESS;
2738 goto doublebreak;
2739 }
2740 else if (status != ERROR_BAD_ARGUMENTS)
2741 {
2742 goto doublebreak;
2743 }
2744 }
2745 }
2746
2747doublebreak:
2748 if (status != NO_ERROR)
2749 {
2750 if (status == ERROR_OBJECT_ALREADY_EXISTS)
2751 {
2752 ret = RTA_EEXIST;
2753 }
2754 else
2755 {
2756 msg(M_WARN,
2757 "ERROR: route addition failed using CreateIpForwardEntry: "
2758 "%s [status=%lu if_index=%lu]",
2759 strerror_win32(status, &gc), status, if_index);
2760 }
2761 }
2762 }
2763 }
2764
2765 gc_free(&gc);
2766 return ret;
2767}
2768
2769static bool
2770del_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt)
2771{
2772 struct gc_arena gc = gc_new();
2773 bool ret = false;
2774 DWORD status;
2775 const DWORD if_index = windows_route_find_if_index(r, tt);
2776
2777 if (if_index != TUN_ADAPTER_INDEX_INVALID)
2778 {
2779 MIB_IPFORWARDROW fr;
2780 CLEAR(fr);
2781
2782 fr.dwForwardDest = htonl(r->network);
2783 fr.dwForwardMask = htonl(r->netmask);
2784 fr.dwForwardPolicy = 0;
2785 fr.dwForwardNextHop = htonl(r->gateway);
2786 fr.dwForwardIfIndex = if_index;
2787
2788 status = DeleteIpForwardEntry(&fr);
2789
2790 if (status == NO_ERROR)
2791 {
2792 ret = true;
2793 }
2794 else
2795 {
2796 msg(M_WARN, "ERROR: route deletion failed using DeleteIpForwardEntry: %s",
2798 }
2799 }
2800
2801 gc_free(&gc);
2802 return ret;
2803}
2804
2805/* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
2806static int
2807do_route_service(const bool add, const route_message_t *rt, const DWORD size, HANDLE pipe)
2808{
2809 int ret = RTA_ERROR;
2810 ack_message_t ack;
2811 struct gc_arena gc = gc_new();
2812
2813 if (!send_msg_iservice(pipe, rt, size, &ack, "ROUTE"))
2814 {
2815 goto out;
2816 }
2817
2818 if (ack.error_number != NO_ERROR)
2819 {
2820 ret = (ack.error_number == ERROR_OBJECT_ALREADY_EXISTS) ? RTA_EEXIST : RTA_ERROR;
2821 if (ret == RTA_ERROR)
2822 {
2823 msg(M_WARN, "ERROR: route %s failed using service: %s [status=%u if_index=%lu]",
2824 (add ? "addition" : "deletion"), strerror_win32(ack.error_number, &gc),
2825 ack.error_number, rt->iface.index);
2826 }
2827 goto out;
2828 }
2829
2830 ret = RTA_SUCCESS;
2831
2832out:
2833 gc_free(&gc);
2834 return ret;
2835}
2836
2837/* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
2838static int
2839do_route_ipv4_service(const bool add, const struct route_ipv4 *r, const struct tuntap *tt)
2840{
2841 DWORD if_index = windows_route_find_if_index(r, tt);
2842 if (if_index == TUN_ADAPTER_INDEX_INVALID)
2843 {
2844 return RTA_ERROR;
2845 }
2846
2848 sizeof(route_message_t), 0 },
2849 .family = AF_INET,
2850 .prefix.ipv4.s_addr = htonl(r->network),
2851 .gateway.ipv4.s_addr = htonl(r->gateway),
2852 .iface = { .index = if_index, .name = "" },
2853 .metric = (r->flags & RT_METRIC_DEFINED) ? r->metric : -1 };
2854
2855 netmask_to_netbits(r->network, r->netmask, &msg.prefix_len);
2856 if (msg.prefix_len == -1)
2857 {
2858 msg.prefix_len = 32;
2859 }
2860
2861 return do_route_service(add, &msg, sizeof(msg), tt->options.msg_channel);
2862}
2863
2864/* Add or delete an ipv6 route
2865 * Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error
2866 */
2867static int
2868route_ipv6_ipapi(const bool add, const struct route_ipv6 *r, const struct tuntap *tt)
2869{
2870 DWORD err;
2871 int ret = RTA_ERROR;
2872 PMIB_IPFORWARD_ROW2 fwd_row;
2873 struct gc_arena gc = gc_new();
2874
2875 fwd_row = gc_malloc(sizeof(*fwd_row), true, &gc);
2876
2877 fwd_row->ValidLifetime = 0xffffffff;
2878 fwd_row->PreferredLifetime = 0xffffffff;
2879 fwd_row->Protocol = MIB_IPPROTO_NETMGMT;
2880 fwd_row->Metric = ((r->flags & RT_METRIC_DEFINED) ? r->metric : -1);
2881 fwd_row->DestinationPrefix.Prefix.si_family = AF_INET6;
2882 fwd_row->DestinationPrefix.Prefix.Ipv6.sin6_addr = r->network;
2883 fwd_row->DestinationPrefix.PrefixLength = (UINT8)r->netbits;
2884 fwd_row->NextHop.si_family = AF_INET6;
2885 fwd_row->NextHop.Ipv6.sin6_addr = r->gateway;
2886 fwd_row->InterfaceIndex = r->adapter_index ? r->adapter_index : tt->adapter_index;
2887
2888 /* In TUN mode we use a special link-local address as the next hop.
2889 * The tapdrvr knows about it and will answer neighbor discovery packets.
2890 * (only do this for routes actually using the tun/tap device)
2891 */
2892 if (tt->type == DEV_TYPE_TUN && !r->adapter_index)
2893 {
2894 inet_pton(AF_INET6, "fe80::8", &fwd_row->NextHop.Ipv6.sin6_addr);
2895 }
2896
2897 /* Use LUID if interface index not available */
2898 if (fwd_row->InterfaceIndex == TUN_ADAPTER_INDEX_INVALID && strlen(tt->actual_name))
2899 {
2900 NET_LUID luid;
2901 err = ConvertInterfaceAliasToLuid(wide_string(tt->actual_name, &gc), &luid);
2902 if (err != NO_ERROR)
2903 {
2904 goto out;
2905 }
2906 fwd_row->InterfaceLuid = luid;
2907 fwd_row->InterfaceIndex = 0;
2908 }
2909
2910 if (add)
2911 {
2912 err = CreateIpForwardEntry2(fwd_row);
2913 }
2914 else
2915 {
2916 err = DeleteIpForwardEntry2(fwd_row);
2917 }
2918
2919out:
2920 if (err != NO_ERROR)
2921 {
2922 ret = (err == ERROR_OBJECT_ALREADY_EXISTS) ? RTA_EEXIST : RTA_ERROR;
2923 if (ret == RTA_ERROR)
2924 {
2925 msg(M_WARN, "ERROR: route %s failed using ipapi: %s [status=%lu if_index=%lu]",
2926 (add ? "addition" : "deletion"), strerror_win32(err, &gc), err,
2927 fwd_row->InterfaceIndex);
2928 }
2929 else if (add)
2930 {
2931 msg(D_ROUTE, "IPv6 route addition using ipapi failed because route exists");
2932 }
2933 }
2934 else
2935 {
2936 msg(D_ROUTE, "IPv6 route %s using ipapi", add ? "added" : "deleted");
2937 ret = RTA_SUCCESS;
2938 }
2939 gc_free(&gc);
2940 return ret;
2941}
2942
2943/* Returns RTA_SUCCESS on success, RTA_EEXIST if route exists, RTA_ERROR on error */
2944static int
2945do_route_ipv6_service(const bool add, const struct route_ipv6 *r, const struct tuntap *tt)
2946{
2947 int status;
2949 sizeof(route_message_t), 0 },
2950 .family = AF_INET6,
2951 .prefix.ipv6 = r->network,
2952 .prefix_len = r->netbits,
2953 .gateway.ipv6 = r->gateway,
2954 .iface = { .index = tt->adapter_index, .name = "" },
2955 .metric = (r->flags & RT_METRIC_DEFINED) ? r->metric : -1 };
2956
2957 if (r->adapter_index) /* vpn server special route */
2958 {
2959 msg.iface.index = r->adapter_index;
2960 }
2961
2962 /* In TUN mode we use a special link-local address as the next hop.
2963 * The tapdrvr knows about it and will answer neighbor discovery packets.
2964 * (only do this for routes actually using the tun/tap device)
2965 */
2966 if (tt->type == DEV_TYPE_TUN && msg.iface.index == tt->adapter_index)
2967 {
2968 inet_pton(AF_INET6, "fe80::8", &msg.gateway.ipv6);
2969 }
2970
2971 if (msg.iface.index == TUN_ADAPTER_INDEX_INVALID)
2972 {
2973 strncpy(msg.iface.name, tt->actual_name, sizeof(msg.iface.name));
2974 msg.iface.name[sizeof(msg.iface.name) - 1] = '\0';
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 strncpynt(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 strncpynt(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 bzero(&m_rtmsg, sizeof(m_rtmsg));
3353 bzero(&so_dst, sizeof(so_dst));
3354 bzero(&so_mask, sizeof(so_mask));
3355 bzero(&rtm, sizeof(struct rt_msghdr));
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 strncpynt(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 strncpynt(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 bzero(&m_rtmsg, sizeof(m_rtmsg));
3571 bzero(&so_dst, sizeof(so_dst));
3572 bzero(&so_mask, sizeof(so_mask));
3573 bzero(&rtm, sizeof(struct rt_msghdr));
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 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 return;
3723 }
3724
3725 uint32 size = (uint32)config.ifc_value;
3726 if (size == 0)
3727 {
3728 return;
3729 }
3730
3731 void *buffer = malloc(size);
3733
3734 config.ifc_len = size;
3735 config.ifc_buf = buffer;
3736 if (ioctl(sockfd, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0)
3737 {
3738 free(buffer);
3739 return;
3740 }
3741
3742 struct ifreq *interface = (struct ifreq *)buffer;
3743 struct ifreq *end = (struct ifreq *)((uint8 *)buffer + size);
3744
3745 while (interface < end)
3746 {
3747 struct route_entry route = interface->ifr_route;
3748 if ((route.flags & RTF_GATEWAY) != 0 && (route.flags & RTF_DEFAULT) != 0)
3749 {
3750 rgi->gateway.addr = ntohl(((struct sockaddr_in *)route.gateway)->sin_addr.s_addr);
3752 strncpy(rgi->iface, interface->ifr_name, sizeof(rgi->iface));
3753 }
3754
3755 int32 address_size = 0;
3756 if (route.destination != NULL)
3757 {
3758 address_size += route.destination->sa_len;
3759 }
3760 if (route.mask != NULL)
3761 {
3762 address_size += route.mask->sa_len;
3763 }
3764 if (route.gateway != NULL)
3765 {
3766 address_size += route.gateway->sa_len;
3767 }
3768
3769 interface = (struct ifreq *)((addr_t)interface + IF_NAMESIZE + sizeof(struct route_entry)
3770 + address_size);
3771 }
3772 free(buffer);
3773}
3774
3775void
3776get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6, const struct in6_addr *dest,
3777 openvpn_net_ctx_t *ctx)
3778{
3779 /* TODO: Same for ipv6 with AF_INET6 */
3780 CLEAR(*rgi6);
3781}
3782
3783#else /* if defined(_WIN32) */
3784
3785/*
3786 * This is a platform-specific method that returns data about
3787 * the current default gateway. Return data is placed into
3788 * a struct route_gateway_info object provided by caller. The
3789 * implementation should CLEAR the structure before adding
3790 * data to it.
3791 *
3792 * Data returned includes:
3793 * 1. default gateway address (rgi->gateway.addr)
3794 * 2. netmask of interface that owns default gateway
3795 * (rgi->gateway.netmask)
3796 * 3. hardware address (i.e. MAC address) of interface that owns
3797 * default gateway (rgi->hwaddr)
3798 * 4. interface name (or adapter index on Windows) that owns default
3799 * gateway (rgi->iface or rgi->adapter_index)
3800 * 5. an array of additional address/netmask pairs defined by
3801 * interface that owns default gateway (rgi->addrs with length
3802 * given in rgi->n_addrs)
3803 *
3804 * The flags RGI_x_DEFINED may be used to indicate which of the data
3805 * members were successfully returned (set in rgi->flags). All of
3806 * the data members are optional, however certain OpenVPN functionality
3807 * may be disabled by missing items.
3808 */
3809void
3811{
3812 CLEAR(*rgi);
3813}
3814void
3815get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6, const struct in6_addr *dest,
3816 openvpn_net_ctx_t *ctx)
3817{
3818 msg(D_ROUTE, "no support for get_default_gateway_ipv6() on this system");
3819 CLEAR(*rgi6);
3820}
3821
3822#endif /* if defined(_WIN32) */
3823
3824bool
3825netmask_to_netbits(const in_addr_t network, const in_addr_t netmask, int *netbits)
3826{
3827 int i;
3828 const int addrlen = sizeof(in_addr_t) * 8;
3829
3830 if ((network & netmask) == network)
3831 {
3832 for (i = 0; i <= addrlen; ++i)
3833 {
3834 in_addr_t mask = netbits_to_netmask(i);
3835 if (mask == netmask)
3836 {
3837 if (i == addrlen)
3838 {
3839 *netbits = -1;
3840 }
3841 else
3842 {
3843 *netbits = i;
3844 }
3845 return true;
3846 }
3847 }
3848 }
3849 return false;
3850}
3851
3852/* similar to netmask_to_netbits(), but don't mess with base address
3853 * etc., just convert to netbits - non-mappable masks are returned as "-1"
3854 */
3855int
3857{
3858 int i;
3859 const int addrlen = sizeof(in_addr_t) * 8;
3860
3861 for (i = 0; i <= addrlen; ++i)
3862 {
3863 in_addr_t mask = netbits_to_netmask(i);
3864 if (mask == netmask)
3865 {
3866 return i;
3867 }
3868 }
3869 return -1;
3870}
3871
3872
3873/*
3874 * get_bypass_addresses() is used by the redirect-gateway bypass-x
3875 * functions to build a route bypass to selected DHCP/DNS servers,
3876 * so that outgoing packets to these servers don't end up in the tunnel.
3877 */
3878
3879#if defined(_WIN32)
3880
3881static void
3883{
3884 if (test_local_addr(addr, NULL) == TLA_NONLOCAL && addr != 0 && addr != IPV4_NETMASK_HOST)
3885 {
3886 add_bypass_address(rb, addr);
3887 }
3888}
3889
3890static void
3891add_host_route_array(struct route_bypass *rb, const IP_ADDR_STRING *iplist)
3892{
3893 while (iplist)
3894 {
3895 bool succeed = false;
3896 const in_addr_t ip =
3897 getaddr(GETADDR_HOST_ORDER, iplist->IpAddress.String, 0, &succeed, NULL);
3898 if (succeed)
3899 {
3901 }
3902 iplist = iplist->Next;
3903 }
3904}
3905
3906static void
3907get_bypass_addresses(struct route_bypass *rb, const unsigned int flags)
3908{
3909 struct gc_arena gc = gc_new();
3910 /*bool ret_bool = false;*/
3911
3912 /* get full routing table */
3913 const MIB_IPFORWARDTABLE *routes = get_windows_routing_table(&gc);
3914
3915 /* get the route which represents the default gateway */
3916 const MIB_IPFORWARDROW *row = get_default_gateway_row(routes);
3917
3918 if (row)
3919 {
3920 /* get the adapter which the default gateway is associated with */
3921 const IP_ADAPTER_INFO *dgi = get_adapter_info(row->dwForwardIfIndex, &gc);
3922
3923 /* get extra adapter info, such as DNS addresses */
3924 const IP_PER_ADAPTER_INFO *pai = get_per_adapter_info(row->dwForwardIfIndex, &gc);
3925
3926 /* Bypass DHCP server address */
3927 if ((flags & RG_BYPASS_DHCP) && dgi && dgi->DhcpEnabled)
3928 {
3929 add_host_route_array(rb, &dgi->DhcpServer);
3930 }
3931
3932 /* Bypass DNS server addresses */
3933 if ((flags & RG_BYPASS_DNS) && pai)
3934 {
3935 add_host_route_array(rb, &pai->DnsServerList);
3936 }
3937 }
3938
3939 gc_free(&gc);
3940}
3941
3942#else /* if defined(_WIN32) */
3943
3944static void
3945get_bypass_addresses(struct route_bypass *rb, const unsigned int flags) /* PLATFORM-SPECIFIC */
3946{
3947}
3948
3949#endif /* if defined(_WIN32) */
3950
3951/*
3952 * Test if addr is reachable via a local interface (return ILA_LOCAL),
3953 * or if it needs to be routed via the default gateway (return
3954 * ILA_NONLOCAL). If the target platform doesn't implement this
3955 * function, return ILA_NOT_IMPLEMENTED.
3956 *
3957 * Used by redirect-gateway autolocal feature
3958 */
3959
3960#if defined(_WIN32)
3961
3962int
3963test_local_addr(const in_addr_t addr, const struct route_gateway_info *rgi)
3964{
3965 struct gc_arena gc = gc_new();
3966 const in_addr_t nonlocal_netmask =
3967 0x80000000L; /* routes with netmask <= to this are considered non-local */
3968 int ret = TLA_NONLOCAL;
3969
3970 /* get full routing table */
3971 const MIB_IPFORWARDTABLE *rt = get_windows_routing_table(&gc);
3972 if (rt)
3973 {
3974 for (DWORD i = 0; i < rt->dwNumEntries; ++i)
3975 {
3976 const MIB_IPFORWARDROW *row = &rt->table[i];
3977 const in_addr_t net = ntohl(row->dwForwardDest);
3978 const in_addr_t mask = ntohl(row->dwForwardMask);
3979 if (mask > nonlocal_netmask && (addr & mask) == net)
3980 {
3981 ret = TLA_LOCAL;
3982 break;
3983 }
3984 }
3985 }
3986
3987 gc_free(&gc);
3988 return ret;
3989}
3990
3991#else /* if defined(_WIN32) */
3992
3993int
3994test_local_addr(const in_addr_t addr, const struct route_gateway_info *rgi) /* PLATFORM-SPECIFIC */
3995{
3996 if (rgi)
3997 {
3998 if (local_route(addr, 0xFFFFFFFF, rgi->gateway.addr, rgi))
3999 {
4000 return TLA_LOCAL;
4001 }
4002 else
4003 {
4004 return TLA_NONLOCAL;
4005 }
4006 }
4007 return TLA_NOT_IMPLEMENTED;
4008}
4009
4010#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:318
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:452
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:411
#define BSTR(buf)
Return the buffer content pointer cast to char *.
Definition buffer.h:151
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Allocate and zero-initialise a garbage-collected object of the given type.
Definition buffer.h:2070
#define ALLOC_OBJ_GC(dptr, type, gc)
Allocate a garbage-collected object of the given type (uninitialised).
Definition buffer.h:2058
static void strncpynt(char *dest, const char *src, size_t maxlen)
Like strncpy() but always null-terminates the destination.
Definition buffer.h:646
static void check_malloc_return(void *p)
Abort if a memory allocation returned NULL.
Definition buffer.h:2082
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
Definition buffer.h:1912
static void gc_freeaddrinfo_callback(void *addr)
Callback to free a struct addrinfo, suitable for use with gc_addspecial().
Definition buffer.h:369
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
Definition buffer.h:1896
void setenv_int(struct env_set *es, const char *name, int value)
Definition env_set.c:291
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition env_set.c:307
#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:2882
#define OPENVPN_STATE_ADD_ROUTES
Definition manage.h:453
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:172
#define msg(flags,...)
Definition error.h:152
unsigned int msglvl_t
Definition error.h:77
#define ASSERT(x)
Definition error.h:219
#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
void print_route_options(const struct route_option_list *rol, msglvl_t msglevel)
Definition route.c:1227
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:1043
static void print_route_option(const struct route_option *ro, msglvl_t msglevel)
Definition route.c:1220
static void add_host_route_if_nonlocal(struct route_bypass *rb, const in_addr_t addr)
Definition route.c:3882
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:1090
bool is_special_addr(const char *addr_str)
Definition route.c:288
struct route_option_list * clone_route_option_list(const struct route_option_list *src, struct gc_arena *a)
Definition route.c:155
void setenv_routes_ipv6(struct env_set *es, const struct route_ipv6_list *rl6)
Definition route.c:1372
static void clear_route_list(struct route_list *rl)
Definition route.c:510
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:2379
static void del_bypass_routes(struct route_bypass *rb, in_addr_t gateway, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:919
static bool del_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt)
Definition route.c:2770
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:935
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:873
static void add_host_route_array(struct route_bypass *rb, const IP_ADDR_STRING *iplist)
Definition route.c:3891
int netmask_to_netbits2(in_addr_t netmask)
Definition route.c:3856
struct route_ipv6_option_list * new_route_ipv6_option_list(struct gc_arena *a)
Definition route.c:139
static bool init_route(struct route_ipv4 *r, struct addrinfo **network_list, const struct route_option *ro, const struct route_list *rl)
Definition route.c:301
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:1185
static bool get_special_addr(const struct route_list *rl, const char *string, in_addr_t *out, bool *status)
Definition route.c:220
#define RTA_EEXIST
Definition route.c:103
#define LR_NOMATCH
Definition route.c:1401
bool test_routes(const struct route_list *rl, const struct tuntap *tt)
Definition route.c:2404
static void add_block_local_routes(struct route_list *rl)
Definition route.c:561
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:585
void get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6, const struct in6_addr *dest, openvpn_net_ctx_t *ctx)
Definition route.c:2628
static const MIB_IPFORWARDTABLE * get_windows_routing_table(struct gc_arena *gc)
Definition route.c:2345
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:2495
static int do_route_service(const bool add, const route_message_t *rt, const DWORD size, HANDLE pipe)
Definition route.c:2807
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:739
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:1992
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:524
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:705
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:496
void copy_route_option_list(struct route_option_list *dest, const struct route_option_list *src, struct gc_arena *a)
Definition route.c:173
void copy_route_ipv6_option_list(struct route_ipv6_option_list *dest, const struct route_ipv6_option_list *src, struct gc_arena *a)
Definition route.c:181
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:1447
static int test_route(const IP_ADAPTER_INFO *adapters, const in_addr_t gateway, DWORD *index)
Definition route.c:2367
void print_default_gateway(const msglvl_t msglevel, const struct route_gateway_info *rgi, const struct route_ipv6_gateway_info *rgi6)
Definition route.c:1241
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:1756
#define RTA_ERROR
Definition route.c:101
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:1406
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:1438
static const MIB_IPFORWARDROW * get_default_gateway_row(const MIB_IPFORWARDTABLE *routes)
Definition route.c:2447
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:2531
static int route_ipv6_ipapi(bool add, const struct route_ipv6 *, const struct tuntap *)
Definition route.c:2868
static void add_block_local_item(struct route_list *rl, const struct route_gateway_address *gateway, in_addr_t target)
Definition route.c:533
struct route_ipv6_option_list * clone_route_ipv6_option_list(const struct route_ipv6_option_list *src, struct gc_arena *a)
Definition route.c:164
static const char * show_opt(const char *option)
Definition route.c:1207
static bool init_route_ipv6(struct route_ipv6 *r6, const struct route_ipv6_option *r6o, const struct route_ipv6_list *rl6)
Definition route.c:424
struct route_option_list * new_route_option_list(struct gc_arena *a)
Definition route.c:130
int test_local_addr(const in_addr_t addr, const struct route_gateway_info *rgi)
Definition route.c:3963
#define METRIC_NOT_USED
Definition route.c:59
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:593
static int add_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt, DWORD adapter_index)
Definition route.c:2674
#define RTA_SUCCESS
Definition route.c:102
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:2164
#define LR_MATCH
Definition route.c:1402
static int do_route_ipv6_service(const bool add, const struct route_ipv6 *r, const struct tuntap *tt)
Definition route.c:2945
void route_ipv6_clear_host_bits(struct route_ipv6 *r6)
Definition route.c:1731
static void clear_route_ipv6_list(struct route_ipv6_list *rl6)
Definition route.c:517
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:1155
#define LR_ERROR
Definition route.c:1403
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:3825
static void setenv_route_addr(struct env_set *es, const char *key, const in_addr_t addr, int i)
Definition route.c:203
static DWORD windows_route_find_if_index(const struct route_ipv4 *r, const struct tuntap *tt)
Definition route.c:2583
static int do_route_ipv4_service(const bool add, const struct route_ipv4 *r, const struct tuntap *tt)
Definition route.c:2839
void setenv_routes(struct env_set *es, const struct route_list *rl)
Definition route.c:1335
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:1163
static bool add_bypass_routes(struct route_bypass *rb, in_addr_t gateway, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:901
static void get_bypass_addresses(struct route_bypass *rb, const unsigned int flags)
Definition route.c:3907
static bool is_route_parm_defined(const char *parm)
Definition route.c:189
static void setenv_route_ipv6(struct env_set *es, const struct route_ipv6 *r6, int i)
Definition route.c:1346
static bool add_bypass_address(struct route_bypass *rb, const in_addr_t a)
Definition route.c:107
static void setenv_route(struct env_set *es, const struct route_ipv4 *r, int i)
Definition route.c:1315
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:481
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:887
#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)
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 socket.c:222
in_addr_t getaddr(unsigned int flags, const char *hostname, int resolve_retry_seconds, bool *succeeded, struct signal_info *sig_info)
Translate an IPv4 addr or hostname from string form to in_addr_t.
Definition socket.c:195
#define IPV4_INVALID_ADDR
Definition socket.h:378
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)
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 GETADDR_HOST_ORDER
#define GETADDR_RESOLVE
#define IA_NET_ORDER
Definition socket_util.h:90
#define GETADDR_WARN_ON_SIGNAL
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
struct env_set * es
char * r6[]
char * r1[]
struct gc_arena gc
Definition test_ssl.c:122
const IP_ADAPTER_INFO * get_tun_adapter(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
Definition tun.c:4294
bool is_adapter_up(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
Definition tun.c:4307
const IP_ADAPTER_INFO * get_adapter_info(DWORD index, struct gc_arena *gc)
Definition tun.c:4209
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:4351
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:4190
DWORD adapter_index_of_ip(const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count, in_addr_t *netmask)
Definition tun.c:4385
WCHAR * wide_string(const char *utf8, struct gc_arena *gc)
Definition win32-util.c:40
void netcmd_semaphore_release(void)
Definition win32.c:867
char * get_win_sys_path(void)
Definition win32.c:1108
void netcmd_semaphore_lock(void)
Definition win32.c:851
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:1422
#define WIN_ROUTE_PATH_SUFFIX
Definition win32.h:40