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