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-2010 OpenVPN Technologies, 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
20 *  along with this program (see the file COPYING included with this
21 *  distribution); if not, write to the Free Software Foundation, Inc.,
22 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 */
24
25/*
26 * Support routines for adding/deleting network routes.
27 */
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#elif defined(_MSC_VER)
32#include "config-msvc.h"
33#endif
34
35#include "syshead.h"
36
37#include "common.h"
38#include "error.h"
39#include "route.h"
40#include "misc.h"
41#include "socket.h"
42#include "manage.h"
43#include "win32.h"
44#include "options.h"
45
46#include "memdbg.h"
47
48#ifdef WIN32
49#define METRIC_NOT_USED ((DWORD)-1)
50#endif
51
52static void delete_route (struct route *r, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es);
53
54static void get_bypass_addresses (struct route_bypass *rb, const unsigned int flags);
55
56#ifdef ENABLE_DEBUG
57
58static void
59print_bypass_addresses (const struct route_bypass *rb)
60{
61  struct gc_arena gc = gc_new ();
62  int i;
63  for (i = 0; i < rb->n_bypass; ++i)
64    {
65      msg (D_ROUTE, "ROUTE: bypass_host_route[%d]=%s",
66	   i,
67	   print_in_addr_t (rb->bypass[i], 0, &gc));
68    }
69  gc_free (&gc);
70}
71
72#endif
73
74static bool
75add_bypass_address (struct route_bypass *rb, const in_addr_t a)
76{
77  int i;
78  for (i = 0; i < rb->n_bypass; ++i)
79    {
80      if (a == rb->bypass[i]) /* avoid duplicates */
81	return true;
82    }
83  if (rb->n_bypass < N_ROUTE_BYPASS)
84    {
85      rb->bypass[rb->n_bypass++] = a;
86      return true;
87    }
88  else
89    {
90      return false;
91    }
92}
93
94struct route_option_list *
95new_route_option_list (const int max_routes, struct gc_arena *a)
96{
97  struct route_option_list *ret;
98  ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_option_list, struct route_option, max_routes, a);
99  ret->capacity = max_routes;
100  return ret;
101}
102
103struct route_ipv6_option_list *
104new_route_ipv6_option_list (const int max_routes, struct gc_arena *a)
105{
106  struct route_ipv6_option_list *ret;
107  ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_ipv6_option_list, struct route_ipv6_option, max_routes, a);
108  ret->capacity = max_routes;
109  return ret;
110}
111
112struct route_option_list *
113clone_route_option_list (const struct route_option_list *src, struct gc_arena *a)
114{
115  const size_t rl_size = array_mult_safe (sizeof(struct route_option), src->capacity, sizeof(struct route_option_list));
116  struct route_option_list *ret = gc_malloc (rl_size, false, a);
117  memcpy (ret, src, rl_size);
118  return ret;
119}
120
121struct route_ipv6_option_list *
122clone_route_ipv6_option_list (const struct route_ipv6_option_list *src, struct gc_arena *a)
123{
124  const size_t rl_size = array_mult_safe (sizeof(struct route_ipv6_option), src->capacity, sizeof(struct route_ipv6_option_list));
125  struct route_ipv6_option_list *ret = gc_malloc (rl_size, false, a);
126  memcpy (ret, src, rl_size);
127  return ret;
128}
129
130void
131copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src)
132{
133  const size_t src_size = array_mult_safe (sizeof(struct route_option), src->capacity, sizeof(struct route_option_list));
134  if (src->capacity > dest->capacity)
135    msg (M_FATAL, PACKAGE_NAME " ROUTE: (copy) number of route options in src (%d) is greater than route list capacity in dest (%d)", src->capacity, dest->capacity);
136  memcpy (dest, src, src_size);
137}
138
139void
140copy_route_ipv6_option_list (struct route_ipv6_option_list *dest,
141			     const struct route_ipv6_option_list *src)
142{
143  const size_t src_size = array_mult_safe (sizeof(struct route_ipv6_option), src->capacity, sizeof(struct route_ipv6_option_list));
144  if (src->capacity > dest->capacity)
145    msg (M_FATAL, PACKAGE_NAME " ROUTE: (copy) number of route options in src (%d) is greater than route list capacity in dest (%d)", src->capacity, dest->capacity);
146  memcpy (dest, src, src_size);
147}
148
149struct route_list *
150new_route_list (const int max_routes, struct gc_arena *a)
151{
152  struct route_list *ret;
153  ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_list, struct route, max_routes, a);
154  ret->capacity = max_routes;
155  return ret;
156}
157
158struct route_ipv6_list *
159new_route_ipv6_list (const int max_routes, struct gc_arena *a)
160{
161  struct route_ipv6_list *ret;
162  ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_ipv6_list, struct route_ipv6, max_routes, a);
163  ret->capacity = max_routes;
164  return ret;
165}
166
167static const char *
168route_string (const struct route *r, struct gc_arena *gc)
169{
170  struct buffer out = alloc_buf_gc (256, gc);
171  buf_printf (&out, "ROUTE network %s netmask %s gateway %s",
172	      print_in_addr_t (r->network, 0, gc),
173	      print_in_addr_t (r->netmask, 0, gc),
174	      print_in_addr_t (r->gateway, 0, gc)
175	      );
176  if (r->flags & RT_METRIC_DEFINED)
177    buf_printf (&out, " metric %d", r->metric);
178  return BSTR (&out);
179}
180
181static bool
182is_route_parm_defined (const char *parm)
183{
184  if (!parm)
185    return false;
186  if (!strcmp (parm, "default"))
187    return false;
188  return true;
189}
190
191static void
192setenv_route_addr (struct env_set *es, const char *key, const in_addr_t addr, int i)
193{
194  struct gc_arena gc = gc_new ();
195  struct buffer name = alloc_buf_gc (256, &gc);
196  if (i >= 0)
197    buf_printf (&name, "route_%s_%d", key, i);
198  else
199    buf_printf (&name, "route_%s", key);
200  setenv_str (es, BSTR (&name), print_in_addr_t (addr, 0, &gc));
201  gc_free (&gc);
202}
203
204static bool
205get_special_addr (const struct route_list *rl,
206		  const char *string,
207		  in_addr_t *out,
208		  bool *status)
209{
210  if (status)
211    *status = true;
212  if (!strcmp (string, "vpn_gateway"))
213    {
214      if (rl)
215	{
216	  if (rl->spec.flags & RTSA_REMOTE_ENDPOINT)
217	    *out = rl->spec.remote_endpoint;
218	  else
219	    {
220	      msg (M_INFO, PACKAGE_NAME " ROUTE: vpn_gateway undefined");
221	      if (status)
222		*status = false;
223	    }
224	}
225      return true;
226    }
227  else if (!strcmp (string, "net_gateway"))
228    {
229      if (rl)
230	{
231	  if (rl->rgi.flags & RGI_ADDR_DEFINED)
232	    *out = rl->rgi.gateway.addr;
233	  else
234	    {
235	      msg (M_INFO, PACKAGE_NAME " ROUTE: net_gateway undefined -- unable to get default gateway from system");
236	      if (status)
237		*status = false;
238	    }
239	}
240      return true;
241    }
242  else if (!strcmp (string, "remote_host"))
243    {
244      if (rl)
245	{
246	  if (rl->spec.flags & RTSA_REMOTE_HOST)
247	    *out = rl->spec.remote_host;
248	  else
249	    {
250	      msg (M_INFO, PACKAGE_NAME " ROUTE: remote_host undefined");
251	      if (status)
252		*status = false;
253	    }
254	}
255      return true;
256    }
257  return false;
258}
259
260bool
261is_special_addr (const char *addr_str)
262{
263  if (addr_str)
264    return get_special_addr (NULL, addr_str, NULL, NULL);
265  else
266    return false;
267}
268
269static bool
270init_route (struct route *r,
271	    struct addrinfo **network_list,
272	    const struct route_option *ro,
273	    const struct route_list *rl)
274{
275  const in_addr_t default_netmask = IPV4_NETMASK_HOST;
276  bool status;
277  int ret;
278  struct in_addr special;
279
280  CLEAR (*r);
281  r->option = ro;
282
283  /* network */
284
285  if (!is_route_parm_defined (ro->network))
286    {
287      goto fail;
288    }
289
290
291  /* get_special_addr replaces specialaddr with a special ip addr
292     like gw. getaddrinfo is called to convert a a addrinfo struct */
293
294  if(get_special_addr (rl, ro->network, &special.s_addr, &status))
295    {
296      special.s_addr = htonl(special.s_addr);
297      ret = openvpn_getaddrinfo(0, inet_ntoa(special), 0, NULL,
298                                AF_INET, network_list);
299    }
300  else
301    ret = openvpn_getaddrinfo(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL,
302                              ro->network, 0, NULL, AF_INET, network_list);
303
304  status = (ret == 0);
305
306  if (!status)
307    goto fail;
308
309  /* netmask */
310
311  if (is_route_parm_defined (ro->netmask))
312    {
313      r->netmask = getaddr (
314			    GETADDR_HOST_ORDER
315			    | GETADDR_WARN_ON_SIGNAL,
316			    ro->netmask,
317			    0,
318			    &status,
319			    NULL);
320      if (!status)
321	goto fail;
322    }
323  else
324    r->netmask = default_netmask;
325
326  /* gateway */
327
328  if (is_route_parm_defined (ro->gateway))
329    {
330      if (!get_special_addr (rl, ro->gateway, &r->gateway, &status))
331	{
332	  r->gateway = getaddr (
333				GETADDR_RESOLVE
334				| GETADDR_HOST_ORDER
335				| GETADDR_WARN_ON_SIGNAL,
336				ro->gateway,
337				0,
338				&status,
339				NULL);
340	}
341      if (!status)
342	goto fail;
343    }
344  else
345    {
346      if (rl->spec.flags & RTSA_REMOTE_ENDPOINT)
347	r->gateway = rl->spec.remote_endpoint;
348      else
349	{
350	  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");
351	  goto fail;
352	}
353    }
354
355  /* metric */
356
357  r->metric = 0;
358  if (is_route_parm_defined (ro->metric))
359    {
360      r->metric = atoi (ro->metric);
361      if (r->metric < 0)
362	{
363	  msg (M_WARN, PACKAGE_NAME " ROUTE: route metric for network %s (%s) must be >= 0",
364	       ro->network,
365	       ro->metric);
366	  goto fail;
367	}
368      r->flags |= RT_METRIC_DEFINED;
369    }
370  else if (rl->spec.flags & RTSA_DEFAULT_METRIC)
371    {
372      r->metric = rl->spec.default_metric;
373      r->flags |= RT_METRIC_DEFINED;
374    }
375
376  r->flags |= RT_DEFINED;
377
378  return true;
379
380 fail:
381  msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve route for host/network: %s",
382       ro->network);
383  return false;
384}
385
386static bool
387init_route_ipv6 (struct route_ipv6 *r6,
388	         const struct route_ipv6_option *r6o,
389	         const struct route_ipv6_list *rl6 )
390{
391  r6->defined = false;
392
393  if ( !get_ipv6_addr( r6o->prefix, &r6->network, &r6->netbits, NULL, M_WARN ))
394    goto fail;
395
396  /* gateway */
397  if (is_route_parm_defined (r6o->gateway))
398    {
399      if ( inet_pton( AF_INET6, r6o->gateway, &r6->gateway ) != 1 )
400        {
401	  msg( M_WARN, PACKAGE_NAME "ROUTE6: cannot parse gateway spec '%s'", r6o->gateway );
402        }
403    }
404  else if (rl6->remote_endpoint_defined)
405    {
406      r6->gateway = rl6->remote_endpoint_ipv6;
407    }
408  else
409    {
410      msg (M_WARN, PACKAGE_NAME " ROUTE6: " PACKAGE_NAME " needs a gateway parameter for a --route-ipv6 option and no default was specified by either --route-ipv6-gateway or --ifconfig-ipv6 options");
411      goto fail;
412    }
413
414  /* metric */
415
416  r6->metric_defined = false;
417  r6->metric = -1;
418  if (is_route_parm_defined (r6o->metric))
419    {
420      r6->metric = atoi (r6o->metric);
421      if (r6->metric < 0)
422	{
423	  msg (M_WARN, PACKAGE_NAME " ROUTE: route metric for network %s (%s) must be >= 0",
424	       r6o->prefix,
425	       r6o->metric);
426	  goto fail;
427	}
428      r6->metric_defined = true;
429    }
430  else if (rl6->default_metric_defined)
431    {
432      r6->metric = rl6->default_metric;
433      r6->metric_defined = true;
434    }
435
436  r6->defined = true;
437
438  return true;
439
440 fail:
441  msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve route for host/network: %s",
442       r6o->prefix);
443  r6->defined = false;
444  return false;
445}
446
447void
448add_route_to_option_list (struct route_option_list *l,
449			  const char *network,
450			  const char *netmask,
451			  const char *gateway,
452			  const char *metric)
453{
454  struct route_option *ro;
455  if (l->n >= l->capacity)
456    msg (M_FATAL, PACKAGE_NAME " ROUTE: cannot add more than %d routes -- please increase the max-routes option in the client configuration file",
457	 l->capacity);
458  ro = &l->routes[l->n];
459  ro->network = network;
460  ro->netmask = netmask;
461  ro->gateway = gateway;
462  ro->metric = metric;
463  ++l->n;
464}
465
466void
467add_route_ipv6_to_option_list (struct route_ipv6_option_list *l,
468			  const char *prefix,
469			  const char *gateway,
470			  const char *metric)
471{
472  struct route_ipv6_option *ro;
473  if (l->n >= l->capacity)
474    msg (M_FATAL, PACKAGE_NAME " ROUTE: cannot add more than %d IPv6 routes -- please increase the max-routes option in the client configuration file",
475	 l->capacity);
476  ro = &l->routes_ipv6[l->n];
477  ro->prefix = prefix;
478  ro->gateway = gateway;
479  ro->metric = metric;
480  ++l->n;
481}
482
483void
484clear_route_list (struct route_list *rl)
485{
486  const int capacity = rl->capacity;
487  const size_t rl_size = array_mult_safe (sizeof(struct route), capacity, sizeof(struct route_list));
488  memset(rl, 0, rl_size);
489  rl->capacity = capacity;
490}
491
492void
493clear_route_ipv6_list (struct route_ipv6_list *rl6)
494{
495  const int capacity = rl6->capacity;
496  const size_t rl6_size = array_mult_safe (sizeof(struct route_ipv6), capacity, sizeof(struct route_ipv6_list));
497  memset(rl6, 0, rl6_size);
498  rl6->capacity = capacity;
499}
500
501void
502route_list_add_vpn_gateway (struct route_list *rl,
503			    struct env_set *es,
504			    const in_addr_t addr)
505{
506  rl->spec.remote_endpoint = addr;
507  rl->spec.flags |= RTSA_REMOTE_ENDPOINT;
508  setenv_route_addr (es, "vpn_gateway", rl->spec.remote_endpoint, -1);
509}
510
511static void
512add_block_local_item (struct route_list *rl,
513		      const struct route_gateway_address *gateway,
514		      in_addr_t target)
515{
516  const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED);
517  if ((rl->rgi.flags & rgi_needed) == rgi_needed
518      && rl->rgi.gateway.netmask < 0xFFFFFFFF
519      && (rl->n)+2 <= rl->capacity)
520    {
521      struct route r;
522      unsigned int l2;
523
524      /* split a route into two smaller blocking routes, and direct them to target */
525      CLEAR(r);
526      r.flags = RT_DEFINED;
527      r.gateway = target;
528      r.network = gateway->addr & gateway->netmask;
529      l2 = ((~gateway->netmask)+1)>>1;
530      r.netmask = ~(l2-1);
531      rl->routes[rl->n++] = r;
532      r.network += l2;
533      rl->routes[rl->n++] = r;
534    }
535}
536
537static void
538add_block_local (struct route_list *rl)
539{
540  const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED);
541  if ((rl->flags & RG_BLOCK_LOCAL)
542      && (rl->rgi.flags & rgi_needed) == rgi_needed
543      && (rl->spec.flags & RTSA_REMOTE_ENDPOINT)
544      && rl->spec.remote_host_local != TLA_LOCAL)
545    {
546      size_t i;
547
548      /* add bypass for gateway addr */
549      add_bypass_address (&rl->spec.bypass, rl->rgi.gateway.addr);
550
551      /* block access to local subnet */
552      add_block_local_item (rl, &rl->rgi.gateway, rl->spec.remote_endpoint);
553
554      /* process additional subnets on gateway interface */
555      for (i = 0; i < rl->rgi.n_addrs; ++i)
556	{
557	  const struct route_gateway_address *gwa = &rl->rgi.addrs[i];
558	  /* omit the add/subnet in &rl->rgi which we processed above */
559	  if (!((rl->rgi.gateway.addr & rl->rgi.gateway.netmask) == (gwa->addr & gwa->netmask)
560		&& rl->rgi.gateway.netmask == gwa->netmask))
561	    add_block_local_item (rl, gwa, rl->spec.remote_endpoint);
562	}
563    }
564}
565
566bool
567init_route_list (struct route_list *rl,
568		 const struct route_option_list *opt,
569		 const char *remote_endpoint,
570		 int default_metric,
571		 in_addr_t remote_host,
572		 struct env_set *es)
573{
574  struct gc_arena gc = gc_new ();
575  bool ret = true;
576
577  clear_route_list (rl);
578
579  rl->flags = opt->flags;
580
581  if (remote_host)
582    {
583      rl->spec.remote_host = remote_host;
584      rl->spec.flags |= RTSA_REMOTE_HOST;
585    }
586
587  if (default_metric)
588    {
589      rl->spec.default_metric = default_metric;
590      rl->spec.flags |= RTSA_DEFAULT_METRIC;
591    }
592
593  get_default_gateway (&rl->rgi);
594  if (rl->rgi.flags & RGI_ADDR_DEFINED)
595    {
596      setenv_route_addr (es, "net_gateway", rl->rgi.gateway.addr, -1);
597#ifdef ENABLE_DEBUG
598      print_default_gateway (D_ROUTE, &rl->rgi);
599#endif
600    }
601  else
602    {
603      dmsg (D_ROUTE, "ROUTE: default_gateway=UNDEF");
604    }
605
606  if (rl->spec.flags & RTSA_REMOTE_HOST)
607    rl->spec.remote_host_local = test_local_addr (remote_host, &rl->rgi);
608
609  if (is_route_parm_defined (remote_endpoint))
610    {
611      bool defined = false;
612      rl->spec.remote_endpoint = getaddr (
613				     GETADDR_RESOLVE
614				     | GETADDR_HOST_ORDER
615				     | GETADDR_WARN_ON_SIGNAL,
616				     remote_endpoint,
617				     0,
618				     &defined,
619				     NULL);
620
621      if (defined)
622	{
623	  setenv_route_addr (es, "vpn_gateway", rl->spec.remote_endpoint, -1);
624	  rl->spec.flags |= RTSA_REMOTE_ENDPOINT;
625	}
626      else
627	{
628	  msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve default gateway: %s",
629	       remote_endpoint);
630	  ret = false;
631	}
632    }
633
634  if (rl->flags & RG_ENABLE)
635    {
636      add_block_local (rl);
637      get_bypass_addresses (&rl->spec.bypass, rl->flags);
638#ifdef ENABLE_DEBUG
639      print_bypass_addresses (&rl->spec.bypass);
640#endif
641    }
642
643  /* parse the routes from opt to rl */
644  {
645    int i = 0;
646    int j = rl->n;
647    bool warned = false;
648    for (i = 0; i < opt->n; ++i)
649      {
650        struct addrinfo* netlist;
651	struct route r;
652
653	if (!init_route (&r,
654			 &netlist,
655			 &opt->routes[i],
656			 rl))
657	  ret = false;
658	else
659	  {
660            struct addrinfo* curele;
661            for (curele	= netlist; curele; curele = curele->ai_next)
662	      {
663		if (j < rl->capacity)
664		  {
665                    r.network = ntohl(((struct sockaddr_in*)(curele)->ai_addr)->sin_addr.s_addr);
666		    rl->routes[j++] = r;
667		  }
668		else
669		  {
670		    if (!warned)
671		      {
672			msg (M_WARN, PACKAGE_NAME " ROUTE: routes dropped because number of expanded routes is greater than route list capacity (%d)", rl->capacity);
673			warned = true;
674		      }
675		  }
676	      }
677            freeaddrinfo(netlist);
678	  }
679      }
680    rl->n = j;
681  }
682
683  gc_free (&gc);
684  return ret;
685}
686
687bool
688init_route_ipv6_list (struct route_ipv6_list *rl6,
689		 const struct route_ipv6_option_list *opt6,
690		 const char *remote_endpoint,
691		 int default_metric,
692		 struct env_set *es)
693{
694  struct gc_arena gc = gc_new ();
695  bool ret = true;
696
697  clear_route_ipv6_list (rl6);
698
699  rl6->flags = opt6->flags;
700
701  if (default_metric >= 0 )
702    {
703      rl6->default_metric = default_metric;
704      rl6->default_metric_defined = true;
705    }
706
707  /* "default_gateway" is stuff for "redirect-gateway", which we don't
708   * do for IPv6 yet -> TODO
709   */
710    {
711      dmsg (D_ROUTE, "ROUTE6: default_gateway=UNDEF");
712    }
713
714  if ( is_route_parm_defined( remote_endpoint ))
715    {
716      if ( inet_pton( AF_INET6, remote_endpoint,
717			&rl6->remote_endpoint_ipv6) == 1 )
718        {
719	  rl6->remote_endpoint_defined = true;
720        }
721      else
722	{
723	  msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve default gateway: %s", remote_endpoint);
724          ret = false;
725	}
726    }
727  else
728    rl6->remote_endpoint_defined = false;
729
730
731  if (!(opt6->n >= 0 && opt6->n <= rl6->capacity))
732    msg (M_FATAL, PACKAGE_NAME " ROUTE6: (init) number of route options (%d) is greater than route list capacity (%d)", opt6->n, rl6->capacity);
733
734  /* parse the routes from opt to rl6 */
735  {
736    int i, j = 0;
737    for (i = 0; i < opt6->n; ++i)
738      {
739	if (!init_route_ipv6 (&rl6->routes_ipv6[j],
740			      &opt6->routes_ipv6[i],
741			      rl6 ))
742	  ret = false;
743	else
744	  ++j;
745      }
746    rl6->n = j;
747  }
748
749  gc_free (&gc);
750  return ret;
751}
752
753static void
754add_route3 (in_addr_t network,
755	    in_addr_t netmask,
756	    in_addr_t gateway,
757	    const struct tuntap *tt,
758	    unsigned int flags,
759	    const struct route_gateway_info *rgi,
760	    const struct env_set *es)
761{
762  struct route r;
763  CLEAR (r);
764  r.flags = RT_DEFINED;
765  r.network = network;
766  r.netmask = netmask;
767  r.gateway = gateway;
768  add_route (&r, tt, flags, rgi, es);
769}
770
771static void
772del_route3 (in_addr_t network,
773	    in_addr_t netmask,
774	    in_addr_t gateway,
775	    const struct tuntap *tt,
776	    unsigned int flags,
777	    const struct route_gateway_info *rgi,
778	    const struct env_set *es)
779{
780  struct route r;
781  CLEAR (r);
782  r.flags = RT_DEFINED|RT_ADDED;
783  r.network = network;
784  r.netmask = netmask;
785  r.gateway = gateway;
786  delete_route (&r, tt, flags, rgi, es);
787}
788
789static void
790add_bypass_routes (struct route_bypass *rb,
791		   in_addr_t gateway,
792		   const struct tuntap *tt,
793		   unsigned int flags,
794		   const struct route_gateway_info *rgi,
795		   const struct env_set *es)
796{
797  int i;
798  for (i = 0; i < rb->n_bypass; ++i)
799    {
800      if (rb->bypass[i])
801	add_route3 (rb->bypass[i],
802		    IPV4_NETMASK_HOST,
803		    gateway,
804		    tt,
805		    flags | ROUTE_REF_GW,
806		    rgi,
807		    es);
808    }
809}
810
811static void
812del_bypass_routes (struct route_bypass *rb,
813		   in_addr_t gateway,
814		   const struct tuntap *tt,
815		   unsigned int flags,
816		   const struct route_gateway_info *rgi,
817		   const struct env_set *es)
818{
819  int i;
820  for (i = 0; i < rb->n_bypass; ++i)
821    {
822      if (rb->bypass[i])
823	del_route3 (rb->bypass[i],
824		    IPV4_NETMASK_HOST,
825		    gateway,
826		    tt,
827		    flags | ROUTE_REF_GW,
828		    rgi,
829		    es);
830    }
831}
832
833static void
834redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
835{
836  const char err[] = "NOTE: unable to redirect default gateway --";
837
838  if ( rl && rl->flags & RG_ENABLE )
839    {
840      if (!(rl->spec.flags & RTSA_REMOTE_ENDPOINT))
841	{
842	  msg (M_WARN, "%s VPN gateway parameter (--route-gateway or --ifconfig) is missing", err);
843	}
844      else if (!(rl->rgi.flags & RGI_ADDR_DEFINED))
845	{
846	  msg (M_WARN, "%s Cannot read current default gateway from system", err);
847	}
848      else if (!(rl->spec.flags & RTSA_REMOTE_HOST))
849	{
850	  msg (M_WARN, "%s Cannot obtain current remote host address", err);
851	}
852      else
853	{
854	  bool local = BOOL_CAST(rl->flags & RG_LOCAL);
855	  if (rl->flags & RG_AUTO_LOCAL) {
856	    const int tla = rl->spec.remote_host_local;
857	    if (tla == TLA_NONLOCAL)
858	      {
859		dmsg (D_ROUTE, "ROUTE remote_host is NOT LOCAL");
860		local = false;
861	      }
862	    else if (tla == TLA_LOCAL)
863	      {
864		dmsg (D_ROUTE, "ROUTE remote_host is LOCAL");
865		local = true;
866	      }
867	  }
868	  if (!local)
869	    {
870	      /* route remote host to original default gateway */
871	      /* if remote_host is not ipv4 (ie: ipv6), just skip
872	       * adding this special /32 route */
873	      if (rl->spec.remote_host != IPV4_INVALID_ADDR) {
874		add_route3 (rl->spec.remote_host,
875			    IPV4_NETMASK_HOST,
876			    rl->rgi.gateway.addr,
877			    tt,
878			    flags | ROUTE_REF_GW,
879			    &rl->rgi,
880			    es);
881		rl->iflags |= RL_DID_LOCAL;
882	      } else {
883		dmsg (D_ROUTE, "ROUTE remote_host protocol differs from tunneled");
884	      }
885	    }
886
887	  /* route DHCP/DNS server traffic through original default gateway */
888	  add_bypass_routes (&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es);
889
890	  if (rl->flags & RG_REROUTE_GW)
891	    {
892	      if (rl->flags & RG_DEF1)
893		{
894		  /* add new default route (1st component) */
895		  add_route3 (0x00000000,
896			      0x80000000,
897			      rl->spec.remote_endpoint,
898			      tt,
899			      flags,
900			      &rl->rgi,
901			      es);
902
903		  /* add new default route (2nd component) */
904		  add_route3 (0x80000000,
905			      0x80000000,
906			      rl->spec.remote_endpoint,
907			      tt,
908			      flags,
909			      &rl->rgi,
910			      es);
911		}
912	      else
913		{
914		  /* delete default route */
915		  del_route3 (0,
916			      0,
917			      rl->rgi.gateway.addr,
918			      tt,
919			      flags | ROUTE_REF_GW,
920			      &rl->rgi,
921			      es);
922
923		  /* add new default route */
924		  add_route3 (0,
925			      0,
926			      rl->spec.remote_endpoint,
927			      tt,
928			      flags,
929			      &rl->rgi,
930			      es);
931		}
932	    }
933
934	  /* set a flag so we can undo later */
935	  rl->iflags |= RL_DID_REDIRECT_DEFAULT_GATEWAY;
936	}
937    }
938}
939
940static void
941undo_redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
942{
943  if ( rl && rl->iflags & RL_DID_REDIRECT_DEFAULT_GATEWAY )
944    {
945      /* delete remote host route */
946      if (rl->iflags & RL_DID_LOCAL)
947	{
948	  del_route3 (rl->spec.remote_host,
949		      IPV4_NETMASK_HOST,
950		      rl->rgi.gateway.addr,
951		      tt,
952		      flags | ROUTE_REF_GW,
953		      &rl->rgi,
954		      es);
955	  rl->iflags &= ~RL_DID_LOCAL;
956	}
957
958      /* delete special DHCP/DNS bypass route */
959      del_bypass_routes (&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es);
960
961      if (rl->flags & RG_REROUTE_GW)
962	{
963	  if (rl->flags & RG_DEF1)
964	    {
965	      /* delete default route (1st component) */
966	      del_route3 (0x00000000,
967			  0x80000000,
968			  rl->spec.remote_endpoint,
969			  tt,
970			  flags,
971			  &rl->rgi,
972			  es);
973
974	      /* delete default route (2nd component) */
975	      del_route3 (0x80000000,
976			  0x80000000,
977			  rl->spec.remote_endpoint,
978			  tt,
979			  flags,
980			  &rl->rgi,
981			  es);
982	    }
983	  else
984	    {
985	      /* delete default route */
986	      del_route3 (0,
987			  0,
988			  rl->spec.remote_endpoint,
989			  tt,
990			  flags,
991			  &rl->rgi,
992			  es);
993
994	      /* restore original default route */
995	      add_route3 (0,
996			  0,
997			  rl->rgi.gateway.addr,
998			  tt,
999			  flags | ROUTE_REF_GW,
1000			  &rl->rgi,
1001			  es);
1002	    }
1003	}
1004
1005      rl->iflags &= ~RL_DID_REDIRECT_DEFAULT_GATEWAY;
1006    }
1007}
1008
1009void
1010add_routes (struct route_list *rl, struct route_ipv6_list *rl6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
1011{
1012  redirect_default_route_to_vpn (rl, tt, flags, es);
1013  if ( rl && !(rl->iflags & RL_ROUTES_ADDED) )
1014    {
1015      int i;
1016
1017#ifdef ENABLE_MANAGEMENT
1018      if (management && rl->n)
1019	{
1020	  management_set_state (management,
1021				OPENVPN_STATE_ADD_ROUTES,
1022				NULL,
1023				0,
1024				0);
1025	}
1026#endif
1027
1028      for (i = 0; i < rl->n; ++i)
1029	{
1030	  struct route *r = &rl->routes[i];
1031	  check_subnet_conflict (r->network, r->netmask, "route");
1032	  if (flags & ROUTE_DELETE_FIRST)
1033	    delete_route (r, tt, flags, &rl->rgi, es);
1034	  add_route (r, tt, flags, &rl->rgi, es);
1035	}
1036      rl->iflags |= RL_ROUTES_ADDED;
1037    }
1038  if (rl6 && !rl6->routes_added)
1039    {
1040      int i;
1041
1042      for (i = 0; i < rl6->n; ++i)
1043	{
1044	  struct route_ipv6 *r = &rl6->routes_ipv6[i];
1045	  if (flags & ROUTE_DELETE_FIRST)
1046	    delete_route_ipv6 (r, tt, flags, es);
1047	  add_route_ipv6 (r, tt, flags, es);
1048	}
1049      rl6->routes_added = true;
1050    }
1051}
1052
1053void
1054delete_routes (struct route_list *rl, struct route_ipv6_list *rl6,
1055	       const struct tuntap *tt, unsigned int flags, const struct env_set *es)
1056{
1057  if ( rl && rl->iflags & RL_ROUTES_ADDED )
1058    {
1059      int i;
1060      for (i = rl->n - 1; i >= 0; --i)
1061	{
1062	  struct route * r = &rl->routes[i];
1063	  delete_route (r, tt, flags, &rl->rgi, es);
1064	}
1065      rl->iflags &= ~RL_ROUTES_ADDED;
1066    }
1067
1068   undo_redirect_default_route_to_vpn (rl, tt, flags, es);
1069
1070  if ( rl )
1071    {
1072      clear_route_list (rl);
1073    }
1074
1075  if ( rl6 && rl6->routes_added )
1076    {
1077      int i;
1078      for (i = rl6->n - 1; i >= 0; --i)
1079	{
1080	  const struct route_ipv6 *r6 = &rl6->routes_ipv6[i];
1081	  delete_route_ipv6 (r6, tt, flags, es);
1082	}
1083      rl6->routes_added = false;
1084    }
1085
1086  if ( rl6 )
1087    {
1088      clear_route_ipv6_list (rl6);
1089    }
1090}
1091
1092#ifndef ENABLE_SMALL
1093
1094static const char *
1095show_opt (const char *option)
1096{
1097  if (!option)
1098    return "nil";
1099  else
1100    return option;
1101}
1102
1103static void
1104print_route_option (const struct route_option *ro, int level)
1105{
1106  msg (level, "  route %s/%s/%s/%s",
1107       show_opt (ro->network),
1108       show_opt (ro->netmask),
1109       show_opt (ro->gateway),
1110       show_opt (ro->metric));
1111}
1112
1113void
1114print_route_options (const struct route_option_list *rol,
1115		     int level)
1116{
1117  int i;
1118  if (rol->flags & RG_ENABLE)
1119    msg (level, "  [redirect_default_gateway local=%d]",
1120	 (rol->flags & RG_LOCAL) != 0);
1121  for (i = 0; i < rol->n; ++i)
1122    print_route_option (&rol->routes[i], level);
1123}
1124
1125void
1126print_default_gateway(const int msglevel, const struct route_gateway_info *rgi)
1127{
1128  struct gc_arena gc = gc_new ();
1129  if (rgi->flags & RGI_ADDR_DEFINED)
1130    {
1131      struct buffer out = alloc_buf_gc (256, &gc);
1132      buf_printf (&out, "ROUTE_GATEWAY");
1133      if (rgi->flags & RGI_ON_LINK)
1134	buf_printf (&out, " ON_LINK");
1135      else
1136	buf_printf (&out, " %s", print_in_addr_t (rgi->gateway.addr, 0, &gc));
1137      if (rgi->flags & RGI_NETMASK_DEFINED)
1138	buf_printf (&out, "/%s", print_in_addr_t (rgi->gateway.netmask, 0, &gc));
1139#ifdef WIN32
1140      if (rgi->flags & RGI_IFACE_DEFINED)
1141	buf_printf (&out, " I=%u", (unsigned int)rgi->adapter_index);
1142#else
1143      if (rgi->flags & RGI_IFACE_DEFINED)
1144	buf_printf (&out, " IFACE=%s", rgi->iface);
1145#endif
1146      if (rgi->flags & RGI_HWADDR_DEFINED)
1147	buf_printf (&out, " HWADDR=%s", format_hex_ex (rgi->hwaddr, 6, 0, 1, ":", &gc));
1148      msg (msglevel, "%s", BSTR (&out));
1149    }
1150  gc_free (&gc);
1151}
1152
1153#endif
1154
1155static void
1156print_route (const struct route *r, int level)
1157{
1158  struct gc_arena gc = gc_new ();
1159  if (r->flags & RT_DEFINED)
1160    msg (level, "%s", route_string (r, &gc));
1161  gc_free (&gc);
1162}
1163
1164void
1165print_routes (const struct route_list *rl, int level)
1166{
1167  int i;
1168  for (i = 0; i < rl->n; ++i)
1169    print_route (&rl->routes[i], level);
1170}
1171
1172static void
1173setenv_route (struct env_set *es, const struct route *r, int i)
1174{
1175  struct gc_arena gc = gc_new ();
1176  if (r->flags & RT_DEFINED)
1177    {
1178      setenv_route_addr (es, "network", r->network, i);
1179      setenv_route_addr (es, "netmask", r->netmask, i);
1180      setenv_route_addr (es, "gateway", r->gateway, i);
1181
1182      if (r->flags & RT_METRIC_DEFINED)
1183	{
1184	  struct buffer name = alloc_buf_gc (256, &gc);
1185	  buf_printf (&name, "route_metric_%d", i);
1186	  setenv_int (es, BSTR (&name), r->metric);
1187	}
1188    }
1189  gc_free (&gc);
1190}
1191
1192void
1193setenv_routes (struct env_set *es, const struct route_list *rl)
1194{
1195  int i;
1196  for (i = 0; i < rl->n; ++i)
1197    setenv_route (es, &rl->routes[i], i + 1);
1198}
1199
1200static void
1201setenv_route_ipv6 (struct env_set *es, const struct route_ipv6 *r6, int i)
1202{
1203  struct gc_arena gc = gc_new ();
1204  if (r6->defined)
1205    {
1206      struct buffer name1 = alloc_buf_gc( 256, &gc );
1207      struct buffer val = alloc_buf_gc( 256, &gc );
1208      struct buffer name2 = alloc_buf_gc( 256, &gc );
1209
1210      buf_printf( &name1, "route_ipv6_network_%d", i );
1211      buf_printf( &val, "%s/%d", print_in6_addr( r6->network, 0, &gc ),
1212				 r6->netbits );
1213      setenv_str( es, BSTR(&name1), BSTR(&val) );
1214
1215      buf_printf( &name2, "route_ipv6_gateway_%d", i );
1216      setenv_str( es, BSTR(&name2), print_in6_addr( r6->gateway, 0, &gc ));
1217    }
1218  gc_free (&gc);
1219}
1220void
1221setenv_routes_ipv6 (struct env_set *es, const struct route_ipv6_list *rl6)
1222{
1223  int i;
1224  for (i = 0; i < rl6->n; ++i)
1225    setenv_route_ipv6 (es, &rl6->routes_ipv6[i], i + 1);
1226}
1227
1228/*
1229 * local_route() determines whether the gateway of a provided host
1230 * route is on the same interface that owns the default gateway.
1231 * It uses the data structure
1232 * returned by get_default_gateway() (struct route_gateway_info)
1233 * to determine this.  If the route is local, LR_MATCH is returned.
1234 * When adding routes into the kernel, if LR_MATCH is defined for
1235 * a given route, the route should explicitly reference the default
1236 * gateway interface as the route destination.  For example, here
1237 * is an example on Linux that uses LR_MATCH:
1238 *
1239 *   route add -net 10.10.0.1 netmask 255.255.255.255 dev eth0
1240 *
1241 * This capability is needed by the "default-gateway block-local"
1242 * directive, to allow client access to the local subnet to be
1243 * blocked but still allow access to the local default gateway.
1244 */
1245
1246/* local_route() return values */
1247#define LR_NOMATCH 0 /* route is not local */
1248#define LR_MATCH   1 /* route is local */
1249#define LR_ERROR   2 /* caller should abort adding route */
1250
1251static int
1252local_route (in_addr_t network,
1253	     in_addr_t netmask,
1254	     in_addr_t gateway,
1255	     const struct route_gateway_info *rgi)
1256{
1257  /* set LR_MATCH on local host routes */
1258  const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED|RGI_IFACE_DEFINED);
1259  if (rgi
1260      && (rgi->flags & rgi_needed) == rgi_needed
1261      && gateway == rgi->gateway.addr
1262      && netmask == 0xFFFFFFFF)
1263    {
1264      if (((network ^  rgi->gateway.addr) & rgi->gateway.netmask) == 0)
1265	return LR_MATCH;
1266      else
1267	{
1268	  /* examine additional subnets on gateway interface */
1269	  size_t i;
1270	  for (i = 0; i < rgi->n_addrs; ++i)
1271	    {
1272	      const struct route_gateway_address *gwa = &rgi->addrs[i];
1273	      if (((network ^ gwa->addr) & gwa->netmask) == 0)
1274		return LR_MATCH;
1275	    }
1276	}
1277    }
1278    return LR_NOMATCH;
1279}
1280
1281/* Return true if the "on-link" form of the route should be used.  This is when the gateway for a
1282   a route is specified as an interface rather than an address. */
1283static inline bool
1284is_on_link (const int is_local_route, const unsigned int flags, const struct route_gateway_info *rgi)
1285{
1286  return rgi && (is_local_route == LR_MATCH || ((flags & ROUTE_REF_GW) && (rgi->flags & RGI_ON_LINK)));
1287}
1288
1289void
1290add_route (struct route *r,
1291	   const struct tuntap *tt,
1292	   unsigned int flags,
1293	   const struct route_gateway_info *rgi, /* may be NULL */
1294	   const struct env_set *es)
1295{
1296  struct gc_arena gc;
1297  struct argv argv;
1298  const char *network;
1299  const char *netmask;
1300  const char *gateway;
1301  bool status = false;
1302  int is_local_route;
1303
1304  if (!(r->flags & RT_DEFINED))
1305    return;
1306
1307  gc_init (&gc);
1308  argv_init (&argv);
1309
1310  network = print_in_addr_t (r->network, 0, &gc);
1311  netmask = print_in_addr_t (r->netmask, 0, &gc);
1312  gateway = print_in_addr_t (r->gateway, 0, &gc);
1313
1314  is_local_route = local_route(r->network, r->netmask, r->gateway, rgi);
1315  if (is_local_route == LR_ERROR)
1316    goto done;
1317
1318#if defined(TARGET_LINUX)
1319#ifdef ENABLE_IPROUTE
1320  /* FIXME -- add on-link support for ENABLE_IPROUTE */
1321  argv_printf (&argv, "%s route add %s/%d via %s",
1322  	      iproute_path,
1323	      network,
1324	      count_netmask_bits(netmask),
1325	      gateway);
1326  if (r->flags & RT_METRIC_DEFINED)
1327    argv_printf_cat (&argv, "metric %d", r->metric);
1328
1329#else
1330  argv_printf (&argv, "%s add -net %s netmask %s",
1331	       ROUTE_PATH,
1332	       network,
1333	       netmask);
1334  if (r->flags & RT_METRIC_DEFINED)
1335    argv_printf_cat (&argv, "metric %d", r->metric);
1336  if (is_on_link (is_local_route, flags, rgi))
1337    argv_printf_cat (&argv, "dev %s", rgi->iface);
1338  else
1339    argv_printf_cat (&argv, "gw %s", gateway);
1340
1341#endif  /*ENABLE_IPROUTE*/
1342  argv_msg (D_ROUTE, &argv);
1343  status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route add command failed");
1344
1345#elif defined (WIN32)
1346  {
1347    DWORD ai = TUN_ADAPTER_INDEX_INVALID;
1348    argv_printf (&argv, "%s%sc ADD %s MASK %s %s",
1349		 get_win_sys_path(),
1350		 WIN_ROUTE_PATH_SUFFIX,
1351		 network,
1352		 netmask,
1353		 gateway);
1354    if (r->flags & RT_METRIC_DEFINED)
1355      argv_printf_cat (&argv, "METRIC %d", r->metric);
1356    if (is_on_link (is_local_route, flags, rgi))
1357      {
1358	ai = rgi->adapter_index;
1359	argv_printf_cat (&argv, "IF %u", (unsigned int)ai);
1360      }
1361
1362    argv_msg (D_ROUTE, &argv);
1363
1364    if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
1365      {
1366	status = add_route_ipapi (r, tt, ai);
1367	msg (D_ROUTE, "Route addition via IPAPI %s", status ? "succeeded" : "failed");
1368      }
1369    else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_EXE)
1370      {
1371	netcmd_semaphore_lock ();
1372	status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add command failed");
1373	netcmd_semaphore_release ();
1374      }
1375    else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_ADAPTIVE)
1376      {
1377	status = add_route_ipapi (r, tt, ai);
1378	msg (D_ROUTE, "Route addition via IPAPI %s [adaptive]", status ? "succeeded" : "failed");
1379	if (!status)
1380	  {
1381	    msg (D_ROUTE, "Route addition fallback to route.exe");
1382	    netcmd_semaphore_lock ();
1383	    status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add command failed [adaptive]");
1384	    netcmd_semaphore_release ();
1385	  }
1386      }
1387    else
1388      {
1389	ASSERT (0);
1390      }
1391  }
1392
1393#elif defined (TARGET_SOLARIS)
1394
1395  /* example: route add 192.0.2.32 -netmask 255.255.255.224 somegateway */
1396
1397  argv_printf (&argv, "%s add",
1398		ROUTE_PATH);
1399
1400  argv_printf_cat (&argv, "%s -netmask %s %s",
1401	      network,
1402	      netmask,
1403	      gateway);
1404
1405  /* Solaris can only distinguish between "metric 0" == "on-link on the
1406   * interface where the IP address given is configured" and "metric > 0"
1407   * == "use gateway specified" (no finer-grained route metrics available)
1408   *
1409   * More recent versions of Solaris can also do "-interface", but that
1410   * would break backwards compatibility with older versions for no gain.
1411   */
1412  if (r->flags & RT_METRIC_DEFINED )
1413    argv_printf_cat (&argv, "%d", r->metric);
1414
1415  argv_msg (D_ROUTE, &argv);
1416  status = openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route add command failed");
1417
1418#elif defined(TARGET_FREEBSD)
1419
1420  argv_printf (&argv, "%s add",
1421		ROUTE_PATH);
1422
1423#if 0
1424  if (r->flags & RT_METRIC_DEFINED)
1425    argv_printf_cat (&argv, "-rtt %d", r->metric);
1426#endif
1427
1428  argv_printf_cat (&argv, "-net %s %s %s",
1429	      network,
1430	      gateway,
1431	      netmask);
1432
1433  /* FIXME -- add on-link support for FreeBSD */
1434
1435  argv_msg (D_ROUTE, &argv);
1436  status = openvpn_execve_check (&argv, es, 0, "ERROR: FreeBSD route add command failed");
1437
1438#elif defined(TARGET_DRAGONFLY)
1439
1440  argv_printf (&argv, "%s add",
1441		ROUTE_PATH);
1442
1443#if 0
1444  if (r->flags & RT_METRIC_DEFINED)
1445    argv_printf_cat (&argv, "-rtt %d", r->metric);
1446#endif
1447
1448  argv_printf_cat (&argv, "-net %s %s %s",
1449	      network,
1450	      gateway,
1451	      netmask);
1452
1453  /* FIXME -- add on-link support for Dragonfly */
1454
1455  argv_msg (D_ROUTE, &argv);
1456  status = openvpn_execve_check (&argv, es, 0, "ERROR: DragonFly route add command failed");
1457
1458#elif defined(TARGET_DARWIN)
1459
1460  argv_printf (&argv, "%s add",
1461		ROUTE_PATH);
1462
1463#if 0
1464  if (r->flags & RT_METRIC_DEFINED)
1465    argv_printf_cat (&argv, "-rtt %d", r->metric);
1466#endif
1467
1468  if (is_on_link (is_local_route, flags, rgi))
1469    {
1470      /* Mac OS X route syntax for ON_LINK:
1471	 route add -cloning -net 10.10.0.1 -netmask 255.255.255.255 -interface en0 */
1472      argv_printf_cat (&argv, "-cloning -net %s -netmask %s -interface %s",
1473		       network,
1474		       netmask,
1475		       rgi->iface);
1476    }
1477  else
1478    {
1479      argv_printf_cat (&argv, "-net %s %s %s",
1480		       network,
1481		       gateway,
1482		       netmask);
1483    }
1484
1485  argv_msg (D_ROUTE, &argv);
1486  status = openvpn_execve_check (&argv, es, 0, "ERROR: OS X route add command failed");
1487
1488#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1489
1490  argv_printf (&argv, "%s add",
1491		ROUTE_PATH);
1492
1493#if 0
1494  if (r->flags & RT_METRIC_DEFINED)
1495    argv_printf_cat (&argv, "-rtt %d", r->metric);
1496#endif
1497
1498  argv_printf_cat (&argv, "-net %s %s -netmask %s",
1499	      network,
1500	      gateway,
1501	      netmask);
1502
1503  /* FIXME -- add on-link support for OpenBSD/NetBSD */
1504
1505  argv_msg (D_ROUTE, &argv);
1506  status = openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD/NetBSD route add command failed");
1507
1508#else
1509  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");
1510#endif
1511
1512 done:
1513  if (status)
1514    r->flags |= RT_ADDED;
1515  else
1516    r->flags &= ~RT_ADDED;
1517  argv_reset (&argv);
1518  gc_free (&gc);
1519}
1520
1521
1522static const char *
1523print_in6_addr_netbits_only( struct in6_addr network_copy, int netbits,
1524                             struct gc_arena * gc)
1525{
1526  /* clear host bit parts of route
1527   * (needed if routes are specified improperly, or if we need to
1528   * explicitely setup/clear the "connected" network routes on some OSes)
1529   */
1530  int byte = 15;
1531  int bits_to_clear = 128 - netbits;
1532
1533  while( byte >= 0 && bits_to_clear > 0 )
1534    {
1535      if ( bits_to_clear >= 8 )
1536	{ network_copy.s6_addr[byte--] = 0; bits_to_clear -= 8; }
1537      else
1538	{ network_copy.s6_addr[byte--] &= (0xff << bits_to_clear); bits_to_clear = 0; }
1539    }
1540
1541  return print_in6_addr( network_copy, 0, gc);
1542}
1543
1544void
1545add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
1546{
1547  struct gc_arena gc;
1548  struct argv argv;
1549
1550  const char *network;
1551  const char *gateway;
1552  bool status = false;
1553  const char *device = tt->actual_name;
1554
1555  bool gateway_needed = false;
1556
1557  if (!r6->defined)
1558    return;
1559
1560  gc_init (&gc);
1561  argv_init (&argv);
1562
1563  network = print_in6_addr_netbits_only( r6->network, r6->netbits, &gc);
1564  gateway = print_in6_addr( r6->gateway, 0, &gc);
1565
1566  if ( !tt->ipv6 )
1567    {
1568      msg( M_INFO, "add_route_ipv6(): not adding %s/%d, no IPv6 on if %s",
1569		    network, r6->netbits, device );
1570      return;
1571    }
1572
1573  msg( M_INFO, "add_route_ipv6(%s/%d -> %s metric %d) dev %s",
1574		network, r6->netbits, gateway, r6->metric, device );
1575
1576  /*
1577   * Filter out routes which are essentially no-ops
1578   * (not currently done for IPv6)
1579   */
1580
1581  /* On "tun" interface, we never set a gateway if the operating system
1582   * can do "route to interface" - it does not add value, as the target
1583   * dev already fully qualifies the route destination on point-to-point
1584   * interfaces.   OTOH, on "tap" interface, we must always set the
1585   * gateway unless the route is to be an on-link network
1586   */
1587  if ( tt->type == DEV_TYPE_TAP &&
1588                  !(r6->metric_defined && r6->metric == 0 ) )
1589    {
1590      gateway_needed = true;
1591    }
1592
1593#if defined(TARGET_LINUX)
1594#ifdef ENABLE_IPROUTE
1595  argv_printf (&argv, "%s -6 route add %s/%d dev %s",
1596  	      iproute_path,
1597	      network,
1598	      r6->netbits,
1599	      device);
1600  if (gateway_needed)
1601    argv_printf_cat (&argv, "via %s", gateway);
1602  if (r6->metric_defined && r6->metric > 0 )
1603    argv_printf_cat (&argv, " metric %d", r6->metric);
1604
1605#else
1606  argv_printf (&argv, "%s -A inet6 add %s/%d dev %s",
1607		ROUTE_PATH,
1608	      network,
1609	      r6->netbits,
1610	      device);
1611  if (gateway_needed)
1612    argv_printf_cat (&argv, "gw %s", gateway);
1613  if (r6->metric_defined && r6->metric > 0 )
1614    argv_printf_cat (&argv, " metric %d", r6->metric);
1615#endif  /*ENABLE_IPROUTE*/
1616  argv_msg (D_ROUTE, &argv);
1617  status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route -6/-A inet6 add command failed");
1618
1619#elif defined (WIN32)
1620
1621  /* netsh interface ipv6 add route 2001:db8::/32 MyTunDevice */
1622  argv_printf (&argv, "%s%sc interface ipv6 add route %s/%d %s",
1623	       get_win_sys_path(),
1624	       NETSH_PATH_SUFFIX,
1625	       network,
1626	       r6->netbits,
1627	       device);
1628
1629  /* next-hop depends on TUN or TAP mode:
1630   * - in TAP mode, we use the "real" next-hop
1631   * - in TUN mode we use a special-case link-local address that the tapdrvr
1632   *   knows about and will answer ND (neighbor discovery) packets for
1633   */
1634  if ( tt->type == DEV_TYPE_TUN )
1635	argv_printf_cat( &argv, " %s", "fe80::8" );
1636  else
1637	argv_printf_cat( &argv, " %s", gateway );
1638
1639#if 0
1640  if (r->metric_defined)
1641    argv_printf_cat (&argv, " METRIC %d", r->metric);
1642#endif
1643
1644  /* in some versions of Windows, routes are persistent across reboots by
1645   * default, unless "store=active" is set (pointed out by Tony Lim, thanks)
1646   */
1647  argv_printf_cat( &argv, " store=active" );
1648
1649  argv_msg (D_ROUTE, &argv);
1650
1651  netcmd_semaphore_lock ();
1652  status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add ipv6 command failed");
1653  netcmd_semaphore_release ();
1654
1655#elif defined (TARGET_SOLARIS)
1656
1657  /* example: route add -inet6 2001:db8::/32 somegateway 0 */
1658
1659  /* for some weird reason, this does not work for me unless I set
1660   * "metric 0" - otherwise, the routes will be nicely installed, but
1661   * packets will just disappear somewhere.  So we use "0" now...
1662   */
1663
1664  argv_printf (&argv, "%s add -inet6 %s/%d %s 0",
1665		ROUTE_PATH,
1666		network,
1667		r6->netbits,
1668		gateway );
1669
1670  argv_msg (D_ROUTE, &argv);
1671  status = openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route add -inet6 command failed");
1672
1673#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1674
1675  argv_printf (&argv, "%s add -inet6 %s/%d",
1676		ROUTE_PATH,
1677	        network,
1678	        r6->netbits);
1679
1680  if (gateway_needed)
1681    argv_printf_cat (&argv, "%s", gateway);
1682  else
1683    argv_printf_cat (&argv, "-iface %s", device);
1684
1685  argv_msg (D_ROUTE, &argv);
1686  status = openvpn_execve_check (&argv, es, 0, "ERROR: *BSD route add -inet6 command failed");
1687
1688#elif defined(TARGET_DARWIN)
1689
1690  argv_printf (&argv, "%s add -inet6 %s -prefixlen %d",
1691		ROUTE_PATH,
1692	        network, r6->netbits );
1693
1694  if (gateway_needed)
1695    argv_printf_cat (&argv, "%s", gateway);
1696  else
1697    argv_printf_cat (&argv, "-iface %s", device);
1698
1699  argv_msg (D_ROUTE, &argv);
1700  status = openvpn_execve_check (&argv, es, 0, "ERROR: MacOS X route add -inet6 command failed");
1701
1702#elif defined(TARGET_OPENBSD)
1703
1704  argv_printf (&argv, "%s add -inet6 %s -prefixlen %d %s",
1705		ROUTE_PATH,
1706	        network, r6->netbits, gateway );
1707
1708  argv_msg (D_ROUTE, &argv);
1709  status = openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD route add -inet6 command failed");
1710
1711#elif defined(TARGET_NETBSD)
1712
1713  argv_printf (&argv, "%s add -inet6 %s/%d %s",
1714		ROUTE_PATH,
1715	        network, r6->netbits, gateway );
1716
1717  argv_msg (D_ROUTE, &argv);
1718  status = openvpn_execve_check (&argv, es, 0, "ERROR: NetBSD route add -inet6 command failed");
1719
1720#else
1721  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");
1722#endif
1723
1724  r6->defined = status;
1725  argv_reset (&argv);
1726  gc_free (&gc);
1727}
1728
1729static void
1730delete_route (struct route *r,
1731	      const struct tuntap *tt,
1732	      unsigned int flags,
1733	      const struct route_gateway_info *rgi,
1734	      const struct env_set *es)
1735{
1736  struct gc_arena gc;
1737  struct argv argv;
1738  const char *network;
1739  const char *netmask;
1740  const char *gateway;
1741  int is_local_route;
1742
1743  if ((r->flags & (RT_DEFINED|RT_ADDED)) != (RT_DEFINED|RT_ADDED))
1744    return;
1745
1746  gc_init (&gc);
1747  argv_init (&argv);
1748
1749  network = print_in_addr_t (r->network, 0, &gc);
1750  netmask = print_in_addr_t (r->netmask, 0, &gc);
1751  gateway = print_in_addr_t (r->gateway, 0, &gc);
1752
1753  is_local_route = local_route(r->network, r->netmask, r->gateway, rgi);
1754  if (is_local_route == LR_ERROR)
1755    goto done;
1756
1757#if defined(TARGET_LINUX)
1758#ifdef ENABLE_IPROUTE
1759  argv_printf (&argv, "%s route del %s/%d",
1760  	      iproute_path,
1761	      network,
1762	      count_netmask_bits(netmask));
1763#else
1764  argv_printf (&argv, "%s del -net %s netmask %s",
1765	       ROUTE_PATH,
1766	       network,
1767	       netmask);
1768#endif /*ENABLE_IPROUTE*/
1769  if (r->flags & RT_METRIC_DEFINED)
1770    argv_printf_cat (&argv, "metric %d", r->metric);
1771  argv_msg (D_ROUTE, &argv);
1772  openvpn_execve_check (&argv, es, 0, "ERROR: Linux route delete command failed");
1773
1774#elif defined (WIN32)
1775
1776  argv_printf (&argv, "%s%sc DELETE %s MASK %s %s",
1777	       get_win_sys_path(),
1778	       WIN_ROUTE_PATH_SUFFIX,
1779	       network,
1780	       netmask,
1781	       gateway);
1782
1783  argv_msg (D_ROUTE, &argv);
1784
1785  if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
1786    {
1787      const bool status = del_route_ipapi (r, tt);
1788      msg (D_ROUTE, "Route deletion via IPAPI %s", status ? "succeeded" : "failed");
1789    }
1790  else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_EXE)
1791    {
1792      netcmd_semaphore_lock ();
1793      openvpn_execve_check (&argv, es, 0, "ERROR: Windows route delete command failed");
1794      netcmd_semaphore_release ();
1795    }
1796  else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_ADAPTIVE)
1797    {
1798      const bool status = del_route_ipapi (r, tt);
1799      msg (D_ROUTE, "Route deletion via IPAPI %s [adaptive]", status ? "succeeded" : "failed");
1800      if (!status)
1801	{
1802	  msg (D_ROUTE, "Route deletion fallback to route.exe");
1803	  netcmd_semaphore_lock ();
1804	  openvpn_execve_check (&argv, es, 0, "ERROR: Windows route delete command failed [adaptive]");
1805	  netcmd_semaphore_release ();
1806	}
1807    }
1808  else
1809    {
1810      ASSERT (0);
1811    }
1812
1813#elif defined (TARGET_SOLARIS)
1814
1815  argv_printf (&argv, "%s delete %s -netmask %s %s",
1816		ROUTE_PATH,
1817	      network,
1818	      netmask,
1819	      gateway);
1820
1821  argv_msg (D_ROUTE, &argv);
1822  openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route delete command failed");
1823
1824#elif defined(TARGET_FREEBSD)
1825
1826  argv_printf (&argv, "%s delete -net %s %s %s",
1827		ROUTE_PATH,
1828	      network,
1829	      gateway,
1830	      netmask);
1831
1832  argv_msg (D_ROUTE, &argv);
1833  openvpn_execve_check (&argv, es, 0, "ERROR: FreeBSD route delete command failed");
1834
1835#elif defined(TARGET_DRAGONFLY)
1836
1837  argv_printf (&argv, "%s delete -net %s %s %s",
1838		ROUTE_PATH,
1839	      network,
1840	      gateway,
1841	      netmask);
1842
1843  argv_msg (D_ROUTE, &argv);
1844  openvpn_execve_check (&argv, es, 0, "ERROR: DragonFly route delete command failed");
1845
1846#elif defined(TARGET_DARWIN)
1847
1848  if (is_on_link (is_local_route, flags, rgi))
1849    {
1850      argv_printf (&argv, "%s delete -cloning -net %s -netmask %s -interface %s",
1851		   ROUTE_PATH,
1852		   network,
1853		   netmask,
1854		   rgi->iface);
1855    }
1856  else
1857    {
1858      argv_printf (&argv, "%s delete -net %s %s %s",
1859		   ROUTE_PATH,
1860		   network,
1861		   gateway,
1862		   netmask);
1863    }
1864
1865  argv_msg (D_ROUTE, &argv);
1866  openvpn_execve_check (&argv, es, 0, "ERROR: OS X route delete command failed");
1867
1868#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1869
1870  argv_printf (&argv, "%s delete -net %s %s -netmask %s",
1871		ROUTE_PATH,
1872	      network,
1873	      gateway,
1874	      netmask);
1875
1876  argv_msg (D_ROUTE, &argv);
1877  openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD/NetBSD route delete command failed");
1878
1879#else
1880  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");
1881#endif
1882
1883 done:
1884  r->flags &= ~RT_ADDED;
1885  argv_reset (&argv);
1886  gc_free (&gc);
1887}
1888
1889void
1890delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
1891{
1892  struct gc_arena gc;
1893  struct argv argv;
1894  const char *network;
1895  const char *gateway;
1896  const char *device = tt->actual_name;
1897  bool gateway_needed = false;
1898
1899  if (!r6->defined)
1900    return;
1901
1902  gc_init (&gc);
1903  argv_init (&argv);
1904
1905  network = print_in6_addr_netbits_only( r6->network, r6->netbits, &gc);
1906  gateway = print_in6_addr( r6->gateway, 0, &gc);
1907
1908  if ( !tt->ipv6 )
1909    {
1910      msg( M_INFO, "delete_route_ipv6(): not deleting %s/%d, no IPv6 on if %s",
1911		    network, r6->netbits, device );
1912      return;
1913    }
1914
1915  msg( M_INFO, "delete_route_ipv6(%s/%d)", network, r6->netbits );
1916
1917  /* if we used a gateway on "add route", we also need to specify it on
1918   * delete, otherwise some OSes will refuse to delete the route
1919   */
1920  if ( tt->type == DEV_TYPE_TAP &&
1921                  !(r6->metric_defined && r6->metric == 0 ) )
1922    {
1923      gateway_needed = true;
1924    }
1925
1926
1927#if defined(TARGET_LINUX)
1928#ifdef ENABLE_IPROUTE
1929  argv_printf (&argv, "%s -6 route del %s/%d dev %s",
1930  	      iproute_path,
1931	      network,
1932	      r6->netbits,
1933	      device);
1934  if (gateway_needed)
1935    argv_printf_cat (&argv, "via %s", gateway);
1936#else
1937  argv_printf (&argv, "%s -A inet6 del %s/%d dev %s",
1938		ROUTE_PATH,
1939	      network,
1940	      r6->netbits,
1941	      device);
1942  if (gateway_needed)
1943    argv_printf_cat (&argv, "gw %s", gateway);
1944  if (r6->metric_defined && r6->metric > 0 )
1945    argv_printf_cat (&argv, " metric %d", r6->metric);
1946#endif  /*ENABLE_IPROUTE*/
1947  argv_msg (D_ROUTE, &argv);
1948  openvpn_execve_check (&argv, es, 0, "ERROR: Linux route -6/-A inet6 del command failed");
1949
1950#elif defined (WIN32)
1951
1952  /* netsh interface ipv6 delete route 2001:db8::/32 MyTunDevice */
1953  argv_printf (&argv, "%s%sc interface ipv6 delete route %s/%d %s",
1954	       get_win_sys_path(),
1955	       NETSH_PATH_SUFFIX,
1956	       network,
1957	       r6->netbits,
1958	       device);
1959
1960  /* next-hop depends on TUN or TAP mode:
1961   * - in TAP mode, we use the "real" next-hop
1962   * - in TUN mode we use a special-case link-local address that the tapdrvr
1963   *   knows about and will answer ND (neighbor discovery) packets for
1964   * (and "route deletion without specifying next-hop" does not work...)
1965   */
1966  if ( tt->type == DEV_TYPE_TUN )
1967	argv_printf_cat( &argv, " %s", "fe80::8" );
1968  else
1969	argv_printf_cat( &argv, " %s", gateway );
1970
1971#if 0
1972  if (r->metric_defined)
1973    argv_printf_cat (&argv, "METRIC %d", r->metric);
1974#endif
1975
1976  argv_msg (D_ROUTE, &argv);
1977
1978  netcmd_semaphore_lock ();
1979  openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add ipv6 command failed");
1980  netcmd_semaphore_release ();
1981
1982#elif defined (TARGET_SOLARIS)
1983
1984  /* example: route delete -inet6 2001:db8::/32 somegateway */
1985  /* GERT-TODO: this is untested, but should work */
1986
1987  argv_printf (&argv, "%s delete -inet6 %s/%d %s",
1988		ROUTE_PATH,
1989		network,
1990		r6->netbits,
1991		gateway );
1992
1993  argv_msg (D_ROUTE, &argv);
1994  openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route delete -inet6 command failed");
1995
1996#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1997
1998  argv_printf (&argv, "%s delete -inet6 %s/%d",
1999		ROUTE_PATH,
2000	        network,
2001	        r6->netbits );
2002
2003  if (gateway_needed)
2004    argv_printf_cat (&argv, "%s", gateway);
2005  else
2006    argv_printf_cat (&argv, "-iface %s", device);
2007
2008  argv_msg (D_ROUTE, &argv);
2009  openvpn_execve_check (&argv, es, 0, "ERROR: *BSD route delete -inet6 command failed");
2010
2011#elif defined(TARGET_DARWIN)
2012
2013  argv_printf (&argv, "%s delete -inet6 %s -prefixlen %d",
2014		ROUTE_PATH,
2015		network, r6->netbits );
2016
2017  if (gateway_needed)
2018    argv_printf_cat (&argv, "%s", gateway);
2019  else
2020    argv_printf_cat (&argv, "-iface %s", device);
2021
2022  argv_msg (D_ROUTE, &argv);
2023  openvpn_execve_check (&argv, es, 0, "ERROR: MacOS X route delete -inet6 command failed");
2024
2025#elif defined(TARGET_OPENBSD)
2026
2027  argv_printf (&argv, "%s delete -inet6 %s -prefixlen %d %s",
2028		ROUTE_PATH,
2029	        network, r6->netbits, gateway );
2030
2031  argv_msg (D_ROUTE, &argv);
2032  openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD route delete -inet6 command failed");
2033
2034#elif defined(TARGET_NETBSD)
2035
2036  argv_printf (&argv, "%s delete -inet6 %s/%d %s",
2037		ROUTE_PATH,
2038	        network, r6->netbits, gateway );
2039
2040  argv_msg (D_ROUTE, &argv);
2041  openvpn_execve_check (&argv, es, 0, "ERROR: NetBSD route delete -inet6 command failed");
2042
2043#else
2044  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");
2045#endif
2046
2047  argv_reset (&argv);
2048  gc_free (&gc);
2049}
2050
2051/*
2052 * The --redirect-gateway option requires OS-specific code below
2053 * to get the current default gateway.
2054 */
2055
2056#if defined(WIN32)
2057
2058static const MIB_IPFORWARDTABLE *
2059get_windows_routing_table (struct gc_arena *gc)
2060{
2061  ULONG size = 0;
2062  PMIB_IPFORWARDTABLE rt = NULL;
2063  DWORD status;
2064
2065  status = GetIpForwardTable (NULL, &size, TRUE);
2066  if (status == ERROR_INSUFFICIENT_BUFFER)
2067    {
2068      rt = (PMIB_IPFORWARDTABLE) gc_malloc (size, false, gc);
2069      status = GetIpForwardTable (rt, &size, TRUE);
2070      if (status != NO_ERROR)
2071	{
2072	  msg (D_ROUTE, "NOTE: GetIpForwardTable returned error: %s (code=%u)",
2073	       strerror_win32 (status, gc),
2074	       (unsigned int)status);
2075	  rt = NULL;
2076	}
2077    }
2078  return rt;
2079}
2080
2081static int
2082test_route (const IP_ADAPTER_INFO *adapters,
2083	    const in_addr_t gateway,
2084	    DWORD *index)
2085{
2086  int count = 0;
2087  DWORD i = adapter_index_of_ip (adapters, gateway, &count, NULL);
2088  if (index)
2089    *index = i;
2090  return count;
2091}
2092
2093static void
2094test_route_helper (bool *ret,
2095		   int *count,
2096		   int *good,
2097		   int *ambig,
2098		   const IP_ADAPTER_INFO *adapters,
2099		   const in_addr_t gateway)
2100{
2101  int c;
2102
2103  ++*count;
2104  c = test_route (adapters, gateway, NULL);
2105  if (c == 0)
2106    *ret = false;
2107  else
2108    ++*good;
2109  if (c > 1)
2110    ++*ambig;
2111}
2112
2113/*
2114 * If we tried to add routes now, would we succeed?
2115 */
2116bool
2117test_routes (const struct route_list *rl, const struct tuntap *tt)
2118{
2119  struct gc_arena gc = gc_new ();
2120  const IP_ADAPTER_INFO *adapters = get_adapter_info_list (&gc);
2121  bool ret = false;
2122  int count = 0;
2123  int good = 0;
2124  int ambig = 0;
2125  bool adapter_up = false;
2126
2127  if (is_adapter_up (tt, adapters))
2128    {
2129      ret = true;
2130      adapter_up = true;
2131
2132      if (rl)
2133	{
2134	  int i;
2135	  for (i = 0; i < rl->n; ++i)
2136	    test_route_helper (&ret, &count, &good, &ambig, adapters, rl->routes[i].gateway);
2137
2138	  if ((rl->flags & RG_ENABLE) && (rl->spec.flags & RTSA_REMOTE_ENDPOINT))
2139	    test_route_helper (&ret, &count, &good, &ambig, adapters, rl->spec.remote_endpoint);
2140	}
2141    }
2142
2143  msg (D_ROUTE, "TEST ROUTES: %d/%d succeeded len=%d ret=%d a=%d u/d=%s",
2144       good,
2145       count,
2146       rl ? rl->n : -1,
2147       (int)ret,
2148       ambig,
2149       adapter_up ? "up" : "down");
2150
2151  gc_free (&gc);
2152  return ret;
2153}
2154
2155static const MIB_IPFORWARDROW *
2156get_default_gateway_row (const MIB_IPFORWARDTABLE *routes)
2157{
2158  struct gc_arena gc = gc_new ();
2159  DWORD lowest_metric = MAXDWORD;
2160  const MIB_IPFORWARDROW *ret = NULL;
2161  int i;
2162  int best = -1;
2163
2164  if (routes)
2165    {
2166      for (i = 0; i < routes->dwNumEntries; ++i)
2167	{
2168	  const MIB_IPFORWARDROW *row = &routes->table[i];
2169	  const in_addr_t net = ntohl (row->dwForwardDest);
2170	  const in_addr_t mask = ntohl (row->dwForwardMask);
2171	  const DWORD index = row->dwForwardIfIndex;
2172	  const DWORD metric = row->dwForwardMetric1;
2173
2174	  dmsg (D_ROUTE_DEBUG, "GDGR: route[%d] %s/%s i=%d m=%d",
2175		i,
2176		print_in_addr_t ((in_addr_t) net, 0, &gc),
2177		print_in_addr_t ((in_addr_t) mask, 0, &gc),
2178		(int)index,
2179		(int)metric);
2180
2181	  if (!net && !mask && metric < lowest_metric)
2182	    {
2183	      ret = row;
2184	      lowest_metric = metric;
2185	      best = i;
2186	    }
2187	}
2188    }
2189
2190  dmsg (D_ROUTE_DEBUG, "GDGR: best=%d lm=%u", best, (unsigned int)lowest_metric);
2191
2192  gc_free (&gc);
2193  return ret;
2194}
2195
2196void
2197get_default_gateway (struct route_gateway_info *rgi)
2198{
2199  struct gc_arena gc = gc_new ();
2200
2201  const IP_ADAPTER_INFO *adapters = get_adapter_info_list (&gc);
2202  const MIB_IPFORWARDTABLE *routes = get_windows_routing_table (&gc);
2203  const MIB_IPFORWARDROW *row = get_default_gateway_row (routes);
2204  DWORD a_index;
2205  const IP_ADAPTER_INFO *ai;
2206
2207  CLEAR(*rgi);
2208
2209  if (row)
2210    {
2211      rgi->gateway.addr = ntohl (row->dwForwardNextHop);
2212      if (rgi->gateway.addr)
2213	{
2214	  rgi->flags |= RGI_ADDR_DEFINED;
2215	  a_index = adapter_index_of_ip (adapters, rgi->gateway.addr, NULL, &rgi->gateway.netmask);
2216	  if (a_index != TUN_ADAPTER_INDEX_INVALID)
2217	    {
2218	      rgi->adapter_index = a_index;
2219	      rgi->flags |= (RGI_IFACE_DEFINED|RGI_NETMASK_DEFINED);
2220	      ai = get_adapter (adapters, a_index);
2221	      if (ai)
2222		{
2223		  memcpy (rgi->hwaddr, ai->Address, 6);
2224		  rgi->flags |= RGI_HWADDR_DEFINED;
2225		}
2226	    }
2227	}
2228    }
2229
2230  gc_free (&gc);
2231}
2232
2233static DWORD
2234windows_route_find_if_index (const struct route *r, const struct tuntap *tt)
2235{
2236  struct gc_arena gc = gc_new ();
2237  DWORD ret = TUN_ADAPTER_INDEX_INVALID;
2238  int count = 0;
2239  const IP_ADAPTER_INFO *adapters = get_adapter_info_list (&gc);
2240  const IP_ADAPTER_INFO *tun_adapter = get_tun_adapter (tt, adapters);
2241  bool on_tun = false;
2242
2243  /* first test on tun interface */
2244  if (is_ip_in_adapter_subnet (tun_adapter, r->gateway, NULL))
2245    {
2246      ret = tun_adapter->Index;
2247      count = 1;
2248      on_tun = true;
2249    }
2250  else /* test on other interfaces */
2251    {
2252      count = test_route (adapters, r->gateway, &ret);
2253    }
2254
2255  if (count == 0)
2256    {
2257      msg (M_WARN, "Warning: route gateway is not reachable on any active network adapters: %s",
2258	   print_in_addr_t (r->gateway, 0, &gc));
2259      ret = TUN_ADAPTER_INDEX_INVALID;
2260    }
2261  else if (count > 1)
2262    {
2263      msg (M_WARN, "Warning: route gateway is ambiguous: %s (%d matches)",
2264	   print_in_addr_t (r->gateway, 0, &gc),
2265	   count);
2266      ret = TUN_ADAPTER_INDEX_INVALID;
2267    }
2268
2269  dmsg (D_ROUTE_DEBUG, "DEBUG: route find if: on_tun=%d count=%d index=%d",
2270       on_tun,
2271       count,
2272       (int)ret);
2273
2274  gc_free (&gc);
2275  return ret;
2276}
2277
2278bool
2279add_route_ipapi (const struct route *r, const struct tuntap *tt, DWORD adapter_index)
2280{
2281  struct gc_arena gc = gc_new ();
2282  bool ret = false;
2283  DWORD status;
2284  const DWORD if_index = (adapter_index == TUN_ADAPTER_INDEX_INVALID) ? windows_route_find_if_index (r, tt) : adapter_index;
2285
2286  if (if_index != TUN_ADAPTER_INDEX_INVALID)
2287    {
2288      MIB_IPFORWARDROW fr;
2289      CLEAR (fr);
2290      fr.dwForwardDest = htonl (r->network);
2291      fr.dwForwardMask = htonl (r->netmask);
2292      fr.dwForwardPolicy = 0;
2293      fr.dwForwardNextHop = htonl (r->gateway);
2294      fr.dwForwardIfIndex = if_index;
2295      fr.dwForwardType = 4;  /* the next hop is not the final dest */
2296      fr.dwForwardProto = 3; /* PROTO_IP_NETMGMT */
2297      fr.dwForwardAge = 0;
2298      fr.dwForwardNextHopAS = 0;
2299      fr.dwForwardMetric1 = (r->flags & RT_METRIC_DEFINED) ? r->metric : 1;
2300      fr.dwForwardMetric2 = METRIC_NOT_USED;
2301      fr.dwForwardMetric3 = METRIC_NOT_USED;
2302      fr.dwForwardMetric4 = METRIC_NOT_USED;
2303      fr.dwForwardMetric5 = METRIC_NOT_USED;
2304
2305      if ((r->network & r->netmask) != r->network)
2306	msg (M_WARN, "Warning: address %s is not a network address in relation to netmask %s",
2307	     print_in_addr_t (r->network, 0, &gc),
2308	     print_in_addr_t (r->netmask, 0, &gc));
2309
2310      status = CreateIpForwardEntry (&fr);
2311
2312      if (status == NO_ERROR)
2313	ret = true;
2314      else
2315	{
2316	  /* failed, try increasing the metric to work around Vista issue */
2317	  const unsigned int forward_metric_limit = 2048; /* iteratively retry higher metrics up to this limit */
2318
2319	  for ( ; fr.dwForwardMetric1 <= forward_metric_limit; ++fr.dwForwardMetric1)
2320	    {
2321	      /* try a different forward type=3 ("the next hop is the final dest") in addition to 4.
2322		 --redirect-gateway over RRAS seems to need this. */
2323	      for (fr.dwForwardType = 4; fr.dwForwardType >= 3; --fr.dwForwardType)
2324		{
2325		  status = CreateIpForwardEntry (&fr);
2326		  if (status == NO_ERROR)
2327		    {
2328		      msg (D_ROUTE, "ROUTE: CreateIpForwardEntry succeeded with dwForwardMetric1=%u and dwForwardType=%u",
2329			   (unsigned int)fr.dwForwardMetric1,
2330			   (unsigned int)fr.dwForwardType);
2331		      ret = true;
2332		      goto doublebreak;
2333		    }
2334		  else if (status != ERROR_BAD_ARGUMENTS)
2335		    goto doublebreak;
2336		}
2337	    }
2338
2339	doublebreak:
2340	  if (status != NO_ERROR)
2341	    msg (M_WARN, "ROUTE: route addition failed using CreateIpForwardEntry: %s [status=%u if_index=%u]",
2342		 strerror_win32 (status, &gc),
2343		 (unsigned int)status,
2344		 (unsigned int)if_index);
2345	}
2346    }
2347
2348  gc_free (&gc);
2349  return ret;
2350}
2351
2352bool
2353del_route_ipapi (const struct route *r, const struct tuntap *tt)
2354{
2355  struct gc_arena gc = gc_new ();
2356  bool ret = false;
2357  DWORD status;
2358  const DWORD if_index = windows_route_find_if_index (r, tt);
2359
2360  if (if_index != TUN_ADAPTER_INDEX_INVALID)
2361    {
2362      MIB_IPFORWARDROW fr;
2363      CLEAR (fr);
2364
2365      fr.dwForwardDest = htonl (r->network);
2366      fr.dwForwardMask = htonl (r->netmask);
2367      fr.dwForwardPolicy = 0;
2368      fr.dwForwardNextHop = htonl (r->gateway);
2369      fr.dwForwardIfIndex = if_index;
2370
2371      status = DeleteIpForwardEntry (&fr);
2372
2373      if (status == NO_ERROR)
2374	ret = true;
2375      else
2376	msg (M_WARN, "ROUTE: route deletion failed using DeleteIpForwardEntry: %s",
2377	     strerror_win32 (status, &gc));
2378    }
2379
2380  gc_free (&gc);
2381  return ret;
2382}
2383
2384static const char *
2385format_route_entry (const MIB_IPFORWARDROW *r, struct gc_arena *gc)
2386{
2387  struct buffer out = alloc_buf_gc (256, gc);
2388  buf_printf (&out, "%s %s %s p=%d i=%d t=%d pr=%d a=%d h=%d m=%d/%d/%d/%d/%d",
2389	      print_in_addr_t (r->dwForwardDest, IA_NET_ORDER, gc),
2390	      print_in_addr_t (r->dwForwardMask, IA_NET_ORDER, gc),
2391	      print_in_addr_t (r->dwForwardNextHop, IA_NET_ORDER, gc),
2392	      (int)r->dwForwardPolicy,
2393	      (int)r->dwForwardIfIndex,
2394	      (int)r->dwForwardType,
2395	      (int)r->dwForwardProto,
2396	      (int)r->dwForwardAge,
2397	      (int)r->dwForwardNextHopAS,
2398	      (int)r->dwForwardMetric1,
2399	      (int)r->dwForwardMetric2,
2400	      (int)r->dwForwardMetric3,
2401	      (int)r->dwForwardMetric4,
2402	      (int)r->dwForwardMetric5);
2403  return BSTR (&out);
2404}
2405
2406/*
2407 * Show current routing table
2408 */
2409void
2410show_routes (int msglev)
2411{
2412  struct gc_arena gc = gc_new ();
2413  int i;
2414
2415  const MIB_IPFORWARDTABLE *rt = get_windows_routing_table (&gc);
2416
2417  msg (msglev, "SYSTEM ROUTING TABLE");
2418  if (rt)
2419    {
2420      for (i = 0; i < rt->dwNumEntries; ++i)
2421	{
2422	  msg (msglev, "%s", format_route_entry (&rt->table[i], &gc));
2423	}
2424    }
2425  gc_free (&gc);
2426}
2427
2428#elif defined(TARGET_LINUX)
2429
2430void
2431get_default_gateway (struct route_gateway_info *rgi)
2432{
2433  struct gc_arena gc = gc_new ();
2434  int sd = -1;
2435  char best_name[16];
2436  best_name[0] = 0;
2437
2438  CLEAR(*rgi);
2439
2440  /* get default gateway IP addr */
2441  {
2442    FILE *fp = fopen ("/proc/net/route", "r");
2443    if (fp)
2444      {
2445	char line[256];
2446	int count = 0;
2447	unsigned int lowest_metric = UINT_MAX;
2448	in_addr_t best_gw = 0;
2449	bool found = false;
2450	while (fgets (line, sizeof (line), fp) != NULL)
2451	  {
2452	    if (count)
2453	      {
2454		unsigned int net_x = 0;
2455		unsigned int mask_x = 0;
2456		unsigned int gw_x = 0;
2457		unsigned int metric = 0;
2458		unsigned int flags = 0;
2459		char name[16];
2460		name[0] = 0;
2461		const int np = sscanf (line, "%15s\t%x\t%x\t%x\t%*s\t%*s\t%d\t%x",
2462				       name,
2463				       &net_x,
2464				       &gw_x,
2465				       &flags,
2466				       &metric,
2467				       &mask_x);
2468		if (np == 6 && (flags & IFF_UP))
2469		  {
2470		    const in_addr_t net = ntohl (net_x);
2471		    const in_addr_t mask = ntohl (mask_x);
2472		    const in_addr_t gw = ntohl (gw_x);
2473
2474		    if (!net && !mask && metric < lowest_metric)
2475		      {
2476			found = true;
2477			best_gw = gw;
2478			strcpy (best_name, name);
2479			lowest_metric = metric;
2480		      }
2481		  }
2482	      }
2483	    ++count;
2484	  }
2485	fclose (fp);
2486
2487	if (found)
2488	  {
2489	    rgi->gateway.addr = best_gw;
2490	    rgi->flags |= RGI_ADDR_DEFINED;
2491	    if (!rgi->gateway.addr && best_name[0])
2492	      rgi->flags |= RGI_ON_LINK;
2493	  }
2494      }
2495  }
2496
2497  /* scan adapter list */
2498  if (rgi->flags & RGI_ADDR_DEFINED)
2499    {
2500      struct ifreq *ifr, *ifend;
2501      in_addr_t addr, netmask;
2502      struct ifreq ifreq;
2503      struct ifconf ifc;
2504      struct ifreq ifs[20]; /* Maximum number of interfaces to scan */
2505
2506      if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
2507	{
2508	  msg (M_WARN, "GDG: socket() failed");
2509	  goto done;
2510	}
2511      ifc.ifc_len = sizeof (ifs);
2512      ifc.ifc_req = ifs;
2513      if (ioctl (sd, SIOCGIFCONF, &ifc) < 0)
2514	{
2515	  msg (M_WARN, "GDG: ioctl(SIOCGIFCONF) failed");
2516	  goto done;
2517	}
2518
2519      /* scan through interface list */
2520      ifend = ifs + (ifc.ifc_len / sizeof (struct ifreq));
2521      for (ifr = ifc.ifc_req; ifr < ifend; ifr++)
2522	{
2523	  if (ifr->ifr_addr.sa_family == AF_INET)
2524	    {
2525	      /* get interface addr */
2526	      addr = ntohl(((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr);
2527
2528	      /* get interface name */
2529	      strncpynt (ifreq.ifr_name, ifr->ifr_name, sizeof (ifreq.ifr_name));
2530
2531	      /* check that the interface is up */
2532	      if (ioctl (sd, SIOCGIFFLAGS, &ifreq) < 0)
2533		continue;
2534	      if (!(ifreq.ifr_flags & IFF_UP))
2535		continue;
2536
2537	      if (rgi->flags & RGI_ON_LINK)
2538		{
2539		  /* check that interface name of current interface
2540		     matches interface name of best default route */
2541		  if (strcmp(ifreq.ifr_name, best_name))
2542		    continue;
2543#if 0
2544		  /* if point-to-point link, use remote addr as route gateway */
2545		  if ((ifreq.ifr_flags & IFF_POINTOPOINT) && ioctl (sd, SIOCGIFDSTADDR, &ifreq) >= 0)
2546		    {
2547		      rgi->gateway.addr = ntohl(((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr);
2548		      if (rgi->gateway.addr)
2549			rgi->flags &= ~RGI_ON_LINK;
2550		    }
2551#endif
2552		}
2553	      else
2554		{
2555		  /* get interface netmask */
2556		  if (ioctl (sd, SIOCGIFNETMASK, &ifreq) < 0)
2557		    continue;
2558		  netmask = ntohl(((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr);
2559
2560		  /* check that interface matches default route */
2561		  if (((rgi->gateway.addr ^ addr) & netmask) != 0)
2562		    continue;
2563
2564		  /* save netmask */
2565		  rgi->gateway.netmask = netmask;
2566		  rgi->flags |= RGI_NETMASK_DEFINED;
2567		}
2568
2569	      /* save iface name */
2570	      strncpynt (rgi->iface, ifreq.ifr_name, sizeof(rgi->iface));
2571	      rgi->flags |= RGI_IFACE_DEFINED;
2572
2573	      /* now get the hardware address. */
2574	      memset (&ifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
2575	      if (ioctl (sd, SIOCGIFHWADDR, &ifreq) < 0)
2576		{
2577		  msg (M_WARN, "GDG: SIOCGIFHWADDR(%s) failed", ifreq.ifr_name);
2578		  goto done;
2579		}
2580	      memcpy (rgi->hwaddr, &ifreq.ifr_hwaddr.sa_data, 6);
2581	      rgi->flags |= RGI_HWADDR_DEFINED;
2582
2583	      break;
2584	    }
2585	}
2586    }
2587
2588 done:
2589  if (sd >= 0)
2590    close (sd);
2591  gc_free (&gc);
2592}
2593
2594#elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)
2595
2596#include <sys/types.h>
2597#include <sys/socket.h>
2598#include <netinet/in.h>
2599
2600/* all of this is taken from <net/route.h> in FreeBSD */
2601#define RTA_DST     0x1
2602#define RTA_GATEWAY 0x2
2603#define RTA_NETMASK 0x4
2604
2605#define RTM_GET     0x4
2606#define RTM_VERSION 5
2607
2608#define RTF_UP      0x1
2609#define RTF_GATEWAY 0x2
2610
2611/*
2612 * These numbers are used by reliable protocols for determining
2613 * retransmission behavior and are included in the routing structure.
2614 */
2615struct rt_metrics {
2616        u_long  rmx_locks;      /* Kernel must leave these values alone */
2617        u_long  rmx_mtu;        /* MTU for this path */
2618        u_long  rmx_hopcount;   /* max hops expected */
2619        u_long  rmx_expire;     /* lifetime for route, e.g. redirect */
2620        u_long  rmx_recvpipe;   /* inbound delay-bandwidth product */
2621        u_long  rmx_sendpipe;   /* outbound delay-bandwidth product */
2622        u_long  rmx_ssthresh;   /* outbound gateway buffer limit */
2623        u_long  rmx_rtt;        /* estimated round trip time */
2624        u_long  rmx_rttvar;     /* estimated rtt variance */
2625        u_long  rmx_pksent;     /* packets sent using this route */
2626        u_long  rmx_filler[4];  /* will be used for T/TCP later */
2627};
2628
2629/*
2630 * Structures for routing messages.
2631 */
2632struct rt_msghdr {
2633        u_short rtm_msglen;     /* to skip over non-understood messages */
2634        u_char  rtm_version;    /* future binary compatibility */
2635        u_char  rtm_type;       /* message type */
2636        u_short rtm_index;      /* index for associated ifp */
2637        int     rtm_flags;      /* flags, incl. kern & message, e.g. DONE */
2638        int     rtm_addrs;      /* bitmask identifying sockaddrs in msg */
2639        pid_t   rtm_pid;        /* identify sender */
2640        int     rtm_seq;        /* for sender to identify action */
2641        int     rtm_errno;      /* why failed */
2642        int     rtm_use;        /* from rtentry */
2643        u_long  rtm_inits;      /* which metrics we are initializing */
2644        struct  rt_metrics rtm_rmx; /* metrics themselves */
2645};
2646
2647struct {
2648  struct rt_msghdr m_rtm;
2649  char       m_space[512];
2650} m_rtmsg;
2651
2652#define ROUNDUP(a) \
2653        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
2654
2655/*
2656 * FIXME -- add support for netmask, hwaddr, and iface
2657 */
2658void
2659get_default_gateway (struct route_gateway_info *rgi)
2660{
2661  struct gc_arena gc = gc_new ();
2662  int s, seq, l, pid, rtm_addrs, i;
2663  struct sockaddr so_dst, so_mask;
2664  char *cp = m_rtmsg.m_space;
2665  struct sockaddr *gate = NULL, *sa;
2666  struct  rt_msghdr *rtm_aux;
2667
2668#define NEXTADDR(w, u) \
2669        if (rtm_addrs & (w)) {\
2670            l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
2671        }
2672
2673#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
2674
2675#define rtm m_rtmsg.m_rtm
2676
2677  CLEAR(*rgi);
2678
2679  pid = getpid();
2680  seq = 0;
2681  rtm_addrs = RTA_DST | RTA_NETMASK;
2682
2683  bzero(&so_dst, sizeof(so_dst));
2684  bzero(&so_mask, sizeof(so_mask));
2685  bzero(&rtm, sizeof(struct rt_msghdr));
2686
2687  rtm.rtm_type = RTM_GET;
2688  rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
2689  rtm.rtm_version = RTM_VERSION;
2690  rtm.rtm_seq = ++seq;
2691  rtm.rtm_addrs = rtm_addrs;
2692
2693  so_dst.sa_family = AF_INET;
2694  so_dst.sa_len = sizeof(struct sockaddr_in);
2695  so_mask.sa_family = AF_INET;
2696  so_mask.sa_len = sizeof(struct sockaddr_in);
2697
2698  NEXTADDR(RTA_DST, so_dst);
2699  NEXTADDR(RTA_NETMASK, so_mask);
2700
2701  rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
2702
2703  s = socket(PF_ROUTE, SOCK_RAW, 0);
2704
2705  if (write(s, (char *)&m_rtmsg, l) < 0)
2706    {
2707      msg(M_WARN|M_ERRNO, "Could not retrieve default gateway from route socket:");
2708      gc_free (&gc);
2709      close(s);
2710      return;
2711    }
2712
2713  do {
2714    l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
2715  } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
2716
2717  close(s);
2718
2719  rtm_aux = &rtm;
2720
2721  cp = ((char *)(rtm_aux + 1));
2722  if (rtm_aux->rtm_addrs) {
2723    for (i = 1; i; i <<= 1)
2724      if (i & rtm_aux->rtm_addrs) {
2725	sa = (struct sockaddr *)cp;
2726	if (i == RTA_GATEWAY )
2727	  gate = sa;
2728	ADVANCE(cp, sa);
2729      }
2730  }
2731  else
2732    {
2733      gc_free (&gc);
2734      return;
2735    }
2736
2737
2738  if (gate != NULL )
2739    {
2740      rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
2741      rgi->flags |= RGI_ADDR_DEFINED;
2742
2743      gc_free (&gc);
2744    }
2745  else
2746    {
2747      gc_free (&gc);
2748    }
2749}
2750
2751#elif defined(TARGET_DARWIN)
2752
2753#include <sys/types.h>
2754#include <sys/socket.h>
2755#include <netinet/in.h>
2756#include <net/route.h>
2757#include <net/if_dl.h>
2758
2759struct rtmsg {
2760  struct rt_msghdr m_rtm;
2761  char       m_space[512];
2762};
2763
2764#define ROUNDUP(a) \
2765        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
2766
2767#define NEXTADDR(w, u) \
2768        if (rtm_addrs & (w)) {\
2769            l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
2770        }
2771
2772#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
2773
2774#define max(a,b) ((a) > (b) ? (a) : (b))
2775
2776void
2777get_default_gateway (struct route_gateway_info *rgi)
2778{
2779  struct gc_arena gc = gc_new ();
2780  struct rtmsg m_rtmsg;
2781  int sockfd = -1;
2782  int seq, l, pid, rtm_addrs, i;
2783  struct sockaddr so_dst, so_mask;
2784  char *cp = m_rtmsg.m_space;
2785  struct sockaddr *gate = NULL, *ifp = NULL, *sa;
2786  struct  rt_msghdr *rtm_aux;
2787
2788# define rtm m_rtmsg.m_rtm
2789
2790  CLEAR(*rgi);
2791
2792  /* setup data to send to routing socket */
2793  pid = getpid();
2794  seq = 0;
2795  rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP;
2796
2797  bzero(&m_rtmsg, sizeof(m_rtmsg));
2798  bzero(&so_dst, sizeof(so_dst));
2799  bzero(&so_mask, sizeof(so_mask));
2800  bzero(&rtm, sizeof(struct rt_msghdr));
2801
2802  rtm.rtm_type = RTM_GET;
2803  rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
2804  rtm.rtm_version = RTM_VERSION;
2805  rtm.rtm_seq = ++seq;
2806  rtm.rtm_addrs = rtm_addrs;
2807
2808  so_dst.sa_family = AF_INET;
2809  so_dst.sa_len = sizeof(struct sockaddr_in);
2810  so_mask.sa_family = AF_INET;
2811  so_mask.sa_len = sizeof(struct sockaddr_in);
2812
2813  NEXTADDR(RTA_DST, so_dst);
2814  NEXTADDR(RTA_NETMASK, so_mask);
2815
2816  rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
2817
2818  /* transact with routing socket */
2819  sockfd = socket(PF_ROUTE, SOCK_RAW, 0);
2820  if (sockfd < 0)
2821    {
2822      msg (M_WARN, "GDG: socket #1 failed");
2823      goto done;
2824    }
2825  if (write(sockfd, (char *)&m_rtmsg, l) < 0)
2826    {
2827      msg (M_WARN, "GDG: problem writing to routing socket");
2828      goto done;
2829    }
2830  do {
2831    l = read(sockfd, (char *)&m_rtmsg, sizeof(m_rtmsg));
2832  } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
2833  close(sockfd);
2834  sockfd = -1;
2835
2836  /* extract return data from routing socket */
2837  rtm_aux = &rtm;
2838  cp = ((char *)(rtm_aux + 1));
2839  if (rtm_aux->rtm_addrs)
2840    {
2841      for (i = 1; i; i <<= 1)
2842	{
2843	  if (i & rtm_aux->rtm_addrs)
2844	    {
2845	      sa = (struct sockaddr *)cp;
2846	      if (i == RTA_GATEWAY )
2847		gate = sa;
2848	      else if (i == RTA_IFP)
2849		ifp = sa;
2850	      ADVANCE(cp, sa);
2851	    }
2852	}
2853    }
2854  else
2855    goto done;
2856
2857  /* get gateway addr and interface name */
2858  if (gate != NULL )
2859    {
2860      /* get default gateway addr */
2861      rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
2862      if (rgi->gateway.addr)
2863	  rgi->flags |= RGI_ADDR_DEFINED;
2864
2865      if (ifp)
2866	{
2867	  /* get interface name */
2868	  const struct sockaddr_dl *adl = (struct sockaddr_dl *) ifp;
2869	  int len = adl->sdl_nlen;
2870	  if (adl->sdl_nlen && adl->sdl_nlen < sizeof(rgi->iface))
2871	    {
2872	      memcpy (rgi->iface, adl->sdl_data, adl->sdl_nlen);
2873	      rgi->iface[adl->sdl_nlen] = '\0';
2874	      rgi->flags |= RGI_IFACE_DEFINED;
2875	    }
2876	}
2877    }
2878
2879  /* get netmask of interface that owns default gateway */
2880  if (rgi->flags & RGI_IFACE_DEFINED) {
2881    struct ifreq ifr;
2882
2883    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
2884    if (sockfd < 0)
2885      {
2886	msg (M_WARN, "GDG: socket #2 failed");
2887	goto done;
2888      }
2889
2890    CLEAR(ifr);
2891    ifr.ifr_addr.sa_family = AF_INET;
2892    strncpynt(ifr.ifr_name, rgi->iface, IFNAMSIZ);
2893
2894    if (ioctl(sockfd, SIOCGIFNETMASK, (char *)&ifr) < 0)
2895      {
2896	msg (M_WARN, "GDG: ioctl #1 failed");
2897	goto done;
2898      }
2899    close(sockfd);
2900    sockfd = -1;
2901
2902    rgi->gateway.netmask = ntohl(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr);
2903    rgi->flags |= RGI_NETMASK_DEFINED;
2904  }
2905
2906  /* try to read MAC addr associated with interface that owns default gateway */
2907  if (rgi->flags & RGI_IFACE_DEFINED)
2908    {
2909      struct ifconf ifc;
2910      struct ifreq *ifr;
2911      const int bufsize = 4096;
2912      char *buffer;
2913
2914      buffer = (char *) gc_malloc (bufsize, true, &gc);
2915      sockfd = socket(AF_INET, SOCK_DGRAM, 0);
2916      if (sockfd < 0)
2917	{
2918	  msg (M_WARN, "GDG: socket #3 failed");
2919	  goto done;
2920	}
2921
2922      ifc.ifc_len = bufsize;
2923      ifc.ifc_buf = buffer;
2924
2925      if (ioctl(sockfd, SIOCGIFCONF, (char *)&ifc) < 0)
2926	{
2927	  msg (M_WARN, "GDG: ioctl #2 failed");
2928	  goto done;
2929	}
2930      close(sockfd);
2931      sockfd = -1;
2932
2933      for (cp = buffer; cp <= buffer + ifc.ifc_len - sizeof(struct ifreq); )
2934	{
2935	  ifr = (struct ifreq *)cp;
2936	  const size_t len = sizeof(ifr->ifr_name) + max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len);
2937	  if (!ifr->ifr_addr.sa_family)
2938	    break;
2939	  if (!strncmp(ifr->ifr_name, rgi->iface, IFNAMSIZ))
2940	    {
2941	      if (ifr->ifr_addr.sa_family == AF_LINK)
2942		{
2943		  struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
2944		  memcpy(rgi->hwaddr, LLADDR(sdl), 6);
2945		  rgi->flags |= RGI_HWADDR_DEFINED;
2946		}
2947	    }
2948	  cp += len;
2949	}
2950    }
2951
2952 done:
2953  if (sockfd >= 0)
2954    close(sockfd);
2955  gc_free (&gc);
2956}
2957
2958#undef max
2959
2960#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2961
2962#include <sys/types.h>
2963#include <sys/socket.h>
2964#include <netinet/in.h>
2965
2966/* all of this is taken from <net/route.h> in OpenBSD 3.6 */
2967#define RTA_DST		0x1	/* destination sockaddr present */
2968#define RTA_GATEWAY	0x2	/* gateway sockaddr present */
2969#define RTA_NETMASK	0x4	/* netmask sockaddr present */
2970
2971#define RTM_GET		0x4	/* Report Metrics */
2972
2973#define RTM_VERSION	3	/* Up the ante and ignore older versions */
2974
2975#define	RTF_UP		0x1		/* route usable */
2976#define	RTF_GATEWAY	0x2		/* destination is a gateway */
2977
2978/*
2979 * Huge version for userland compatibility.
2980 */
2981struct rt_metrics {
2982	u_long	rmx_locks;	/* Kernel must leave these values alone */
2983	u_long	rmx_mtu;	/* MTU for this path */
2984	u_long	rmx_hopcount;	/* max hops expected */
2985	u_long	rmx_expire;	/* lifetime for route, e.g. redirect */
2986	u_long	rmx_recvpipe;	/* inbound delay-bandwidth product */
2987	u_long	rmx_sendpipe;	/* outbound delay-bandwidth product */
2988	u_long	rmx_ssthresh;	/* outbound gateway buffer limit */
2989	u_long	rmx_rtt;	/* estimated round trip time */
2990	u_long	rmx_rttvar;	/* estimated rtt variance */
2991	u_long	rmx_pksent;	/* packets sent using this route */
2992};
2993
2994/*
2995 * Structures for routing messages.
2996 */
2997struct rt_msghdr {
2998	u_short	rtm_msglen;	/* to skip over non-understood messages */
2999	u_char	rtm_version;	/* future binary compatibility */
3000	u_char	rtm_type;	/* message type */
3001	u_short	rtm_index;	/* index for associated ifp */
3002	int	rtm_flags;	/* flags, incl. kern & message, e.g. DONE */
3003	int	rtm_addrs;	/* bitmask identifying sockaddrs in msg */
3004	pid_t	rtm_pid;	/* identify sender */
3005	int	rtm_seq;	/* for sender to identify action */
3006	int	rtm_errno;	/* why failed */
3007	int	rtm_use;	/* from rtentry */
3008	u_long	rtm_inits;	/* which metrics we are initializing */
3009	struct	rt_metrics rtm_rmx; /* metrics themselves */
3010};
3011
3012struct {
3013  struct rt_msghdr m_rtm;
3014  char       m_space[512];
3015} m_rtmsg;
3016
3017#define ROUNDUP(a) \
3018        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
3019
3020/*
3021 * FIXME -- add support for netmask, hwaddr, and iface
3022 */
3023void
3024get_default_gateway (struct route_gateway_info *rgi)
3025{
3026  struct gc_arena gc = gc_new ();
3027  int s, seq, l, rtm_addrs, i;
3028  pid_t pid;
3029  struct sockaddr so_dst, so_mask;
3030  char *cp = m_rtmsg.m_space;
3031  struct sockaddr *gate = NULL, *sa;
3032  struct  rt_msghdr *rtm_aux;
3033
3034#define NEXTADDR(w, u) \
3035        if (rtm_addrs & (w)) {\
3036            l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\
3037        }
3038
3039#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
3040
3041#define rtm m_rtmsg.m_rtm
3042
3043  CLEAR(*rgi);
3044
3045  pid = getpid();
3046  seq = 0;
3047  rtm_addrs = RTA_DST | RTA_NETMASK;
3048
3049  bzero(&so_dst, sizeof(so_dst));
3050  bzero(&so_mask, sizeof(so_mask));
3051  bzero(&rtm, sizeof(struct rt_msghdr));
3052
3053  rtm.rtm_type = RTM_GET;
3054  rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
3055  rtm.rtm_version = RTM_VERSION;
3056  rtm.rtm_seq = ++seq;
3057  rtm.rtm_addrs = rtm_addrs;
3058
3059  so_dst.sa_family = AF_INET;
3060  so_dst.sa_len = sizeof(struct sockaddr_in);
3061  so_mask.sa_family = AF_INET;
3062  so_mask.sa_len = sizeof(struct sockaddr_in);
3063
3064  NEXTADDR(RTA_DST, so_dst);
3065  NEXTADDR(RTA_NETMASK, so_mask);
3066
3067  rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
3068
3069  s = socket(PF_ROUTE, SOCK_RAW, 0);
3070
3071  if (write(s, (char *)&m_rtmsg, l) < 0)
3072    {
3073      msg(M_WARN|M_ERRNO, "Could not retrieve default gateway from route socket:");
3074      gc_free (&gc);
3075      close(s);
3076      return;
3077    }
3078
3079  do {
3080    l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
3081  } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
3082
3083  close(s);
3084
3085  rtm_aux = &rtm;
3086
3087  cp = ((char *)(rtm_aux + 1));
3088  if (rtm_aux->rtm_addrs) {
3089    for (i = 1; i; i <<= 1)
3090      if (i & rtm_aux->rtm_addrs) {
3091	sa = (struct sockaddr *)cp;
3092	if (i == RTA_GATEWAY )
3093	  gate = sa;
3094	ADVANCE(cp, sa);
3095      }
3096  }
3097  else
3098    {
3099      gc_free (&gc);
3100      return;
3101    }
3102
3103
3104  if (gate != NULL )
3105    {
3106      rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
3107      rgi->flags |= RGI_ADDR_DEFINED;
3108
3109      gc_free (&gc);
3110    }
3111  else
3112    {
3113      gc_free (&gc);
3114    }
3115}
3116
3117#else
3118
3119/*
3120 * This is a platform-specific method that returns data about
3121 * the current default gateway.  Return data is placed into
3122 * a struct route_gateway_info object provided by caller.  The
3123 * implementation should CLEAR the structure before adding
3124 * data to it.
3125 *
3126 * Data returned includes:
3127 * 1. default gateway address (rgi->gateway.addr)
3128 * 2. netmask of interface that owns default gateway
3129 *    (rgi->gateway.netmask)
3130 * 3. hardware address (i.e. MAC address) of interface that owns
3131 *    default gateway (rgi->hwaddr)
3132 * 4. interface name (or adapter index on Windows) that owns default
3133 *    gateway (rgi->iface or rgi->adapter_index)
3134 * 5. an array of additional address/netmask pairs defined by
3135 *    interface that owns default gateway (rgi->addrs with length
3136 *    given in rgi->n_addrs)
3137 *
3138 * The flags RGI_x_DEFINED may be used to indicate which of the data
3139 * members were successfully returned (set in rgi->flags).  All of
3140 * the data members are optional, however certain OpenVPN functionality
3141 * may be disabled by missing items.
3142 */
3143void
3144get_default_gateway (struct route_gateway_info *rgi)
3145{
3146  CLEAR(*rgi);
3147}
3148
3149#endif
3150
3151bool
3152netmask_to_netbits (const in_addr_t network, const in_addr_t netmask, int *netbits)
3153{
3154  int i;
3155  const int addrlen = sizeof (in_addr_t) * 8;
3156
3157  if ((network & netmask) == network)
3158    {
3159      for (i = 0; i <= addrlen; ++i)
3160	{
3161	  in_addr_t mask = netbits_to_netmask (i);
3162	  if (mask == netmask)
3163	    {
3164	      if (i == addrlen)
3165		*netbits = -1;
3166	      else
3167		*netbits = i;
3168	      return true;
3169	    }
3170	}
3171    }
3172  return false;
3173}
3174
3175/*
3176 * get_bypass_addresses() is used by the redirect-gateway bypass-x
3177 * functions to build a route bypass to selected DHCP/DNS servers,
3178 * so that outgoing packets to these servers don't end up in the tunnel.
3179 */
3180
3181#if defined(WIN32)
3182
3183static void
3184add_host_route_if_nonlocal (struct route_bypass *rb, const in_addr_t addr)
3185{
3186  if (test_local_addr(addr, NULL) == TLA_NONLOCAL && addr != 0 && addr != IPV4_NETMASK_HOST)
3187    add_bypass_address (rb, addr);
3188}
3189
3190static void
3191add_host_route_array (struct route_bypass *rb, const IP_ADDR_STRING *iplist)
3192{
3193  while (iplist)
3194    {
3195      bool succeed = false;
3196      const in_addr_t ip = getaddr (GETADDR_HOST_ORDER, iplist->IpAddress.String, 0, &succeed, NULL);
3197      if (succeed)
3198	{
3199	  add_host_route_if_nonlocal (rb, ip);
3200	}
3201      iplist = iplist->Next;
3202    }
3203}
3204
3205static void
3206get_bypass_addresses (struct route_bypass *rb, const unsigned int flags)
3207{
3208  struct gc_arena gc = gc_new ();
3209  /*bool ret_bool = false;*/
3210
3211  /* get full routing table */
3212  const MIB_IPFORWARDTABLE *routes = get_windows_routing_table (&gc);
3213
3214  /* get the route which represents the default gateway */
3215  const MIB_IPFORWARDROW *row = get_default_gateway_row (routes);
3216
3217  if (row)
3218    {
3219      /* get the adapter which the default gateway is associated with */
3220      const IP_ADAPTER_INFO *dgi = get_adapter_info (row->dwForwardIfIndex, &gc);
3221
3222      /* get extra adapter info, such as DNS addresses */
3223      const IP_PER_ADAPTER_INFO *pai = get_per_adapter_info (row->dwForwardIfIndex, &gc);
3224
3225      /* Bypass DHCP server address */
3226      if ((flags & RG_BYPASS_DHCP) && dgi && dgi->DhcpEnabled)
3227	add_host_route_array (rb, &dgi->DhcpServer);
3228
3229      /* Bypass DNS server addresses */
3230      if ((flags & RG_BYPASS_DNS) && pai)
3231	add_host_route_array (rb, &pai->DnsServerList);
3232    }
3233
3234  gc_free (&gc);
3235}
3236
3237#else
3238
3239static void
3240get_bypass_addresses (struct route_bypass *rb, const unsigned int flags)  /* PLATFORM-SPECIFIC */
3241{
3242}
3243
3244#endif
3245
3246/*
3247 * Test if addr is reachable via a local interface (return ILA_LOCAL),
3248 * or if it needs to be routed via the default gateway (return
3249 * ILA_NONLOCAL).  If the target platform doesn't implement this
3250 * function, return ILA_NOT_IMPLEMENTED.
3251 *
3252 * Used by redirect-gateway autolocal feature
3253 */
3254
3255#if defined(WIN32)
3256
3257int
3258test_local_addr (const in_addr_t addr, const struct route_gateway_info *rgi)
3259{
3260  struct gc_arena gc = gc_new ();
3261  const in_addr_t nonlocal_netmask = 0x80000000L; /* routes with netmask <= to this are considered non-local */
3262  bool ret = TLA_NONLOCAL;
3263
3264  /* get full routing table */
3265  const MIB_IPFORWARDTABLE *rt = get_windows_routing_table (&gc);
3266  if (rt)
3267    {
3268      int i;
3269      for (i = 0; i < rt->dwNumEntries; ++i)
3270	{
3271	  const MIB_IPFORWARDROW *row = &rt->table[i];
3272	  const in_addr_t net = ntohl (row->dwForwardDest);
3273	  const in_addr_t mask = ntohl (row->dwForwardMask);
3274	  if (mask > nonlocal_netmask && (addr & mask) == net)
3275	    {
3276	      ret = TLA_LOCAL;
3277	      break;
3278	    }
3279	}
3280    }
3281
3282  gc_free (&gc);
3283  return ret;
3284}
3285
3286#else
3287
3288int
3289test_local_addr (const in_addr_t addr, const struct route_gateway_info *rgi) /* PLATFORM-SPECIFIC */
3290{
3291  if (rgi)
3292    {
3293      if (local_route (addr, 0xFFFFFFFF, rgi->gateway.addr, rgi))
3294	return TLA_LOCAL;
3295      else
3296	return TLA_NONLOCAL;
3297    }
3298  return TLA_NOT_IMPLEMENTED;
3299}
3300
3301#endif
3302