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