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 configuring and accessing TUN/TAP
27 * virtual network adapters.
28 *
29 * This file is based on the TUN/TAP driver interface routines
30 * from VTun by Maxim Krasnyansky <max_mk@yahoo.com>.
31 */
32
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#elif defined(_MSC_VER)
36#include "config-msvc.h"
37#endif
38
39#include "syshead.h"
40
41#include "tun.h"
42#include "fdmisc.h"
43#include "common.h"
44#include "misc.h"
45#include "socket.h"
46#include "manage.h"
47#include "route.h"
48#include "win32.h"
49
50#include "memdbg.h"
51
52#ifdef WIN32
53
54/* #define SIMULATE_DHCP_FAILED */       /* simulate bad DHCP negotiation */
55
56#define NI_TEST_FIRST  (1<<0)
57#define NI_IP_NETMASK  (1<<1)
58#define NI_OPTIONS     (1<<2)
59
60static void netsh_ifconfig (const struct tuntap_options *to,
61			    const char *flex_name,
62			    const in_addr_t ip,
63			    const in_addr_t netmask,
64			    const unsigned int flags);
65static void netsh_command (const struct argv *a, int n);
66
67static const char *netsh_get_id (const char *dev_node, struct gc_arena *gc);
68
69#endif
70
71#ifdef TARGET_SOLARIS
72static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual, bool unplumb_inet6);
73#include <stropts.h>
74#endif
75
76static void clear_tuntap (struct tuntap *tuntap);
77
78bool
79is_dev_type (const char *dev, const char *dev_type, const char *match_type)
80{
81  ASSERT (match_type);
82  if (!dev)
83    return false;
84  if (dev_type)
85    return !strcmp (dev_type, match_type);
86  else
87    return !strncmp (dev, match_type, strlen (match_type));
88}
89
90int
91dev_type_enum (const char *dev, const char *dev_type)
92{
93  if (is_dev_type (dev, dev_type, "tun"))
94    return DEV_TYPE_TUN;
95  else if (is_dev_type (dev, dev_type, "tap"))
96    return DEV_TYPE_TAP;
97  else if (is_dev_type (dev, dev_type, "null"))
98    return DEV_TYPE_NULL;
99  else
100    return DEV_TYPE_UNDEF;
101}
102
103const char *
104dev_type_string (const char *dev, const char *dev_type)
105{
106  switch (dev_type_enum (dev, dev_type))
107    {
108    case DEV_TYPE_TUN:
109      return "tun";
110    case DEV_TYPE_TAP:
111      return "tap";
112    case DEV_TYPE_NULL:
113      return "null";
114    default:
115      return "[unknown-dev-type]";
116    }
117}
118
119/*
120 * Try to predict the actual TUN/TAP device instance name,
121 * before the device is actually opened.
122 */
123const char *
124guess_tuntap_dev (const char *dev,
125		  const char *dev_type,
126		  const char *dev_node,
127		  struct gc_arena *gc)
128{
129#ifdef WIN32
130  const int dt = dev_type_enum (dev, dev_type);
131  if (dt == DEV_TYPE_TUN || dt == DEV_TYPE_TAP)
132    {
133      return netsh_get_id (dev_node, gc);
134    }
135#endif
136
137  /* default case */
138  return dev;
139}
140
141
142/* --ifconfig-nowarn disables some options sanity checking */
143static const char ifconfig_warn_how_to_silence[] = "(silence this warning with --ifconfig-nowarn)";
144
145/*
146 * If !tun, make sure ifconfig_remote_netmask looks
147 *  like a netmask.
148 *
149 * If tun, make sure ifconfig_remote_netmask looks
150 *  like an IPv4 address.
151 */
152static void
153ifconfig_sanity_check (bool tun, in_addr_t addr, int topology)
154{
155  struct gc_arena gc = gc_new ();
156  const bool looks_like_netmask = ((addr & 0xFF000000) == 0xFF000000);
157  if (tun)
158    {
159      if (looks_like_netmask && (topology == TOP_NET30 || topology == TOP_P2P))
160	msg (M_WARN, "WARNING: Since you are using --dev tun with a point-to-point topology, the second argument to --ifconfig must be an IP address.  You are using something (%s) that looks more like a netmask. %s",
161	     print_in_addr_t (addr, 0, &gc),
162	     ifconfig_warn_how_to_silence);
163    }
164  else /* tap */
165    {
166      if (!looks_like_netmask)
167	msg (M_WARN, "WARNING: Since you are using --dev tap, the second argument to --ifconfig must be a netmask, for example something like 255.255.255.0. %s",
168	     ifconfig_warn_how_to_silence);
169    }
170  gc_free (&gc);
171}
172
173/*
174 * For TAP-style devices, generate a broadcast address.
175 */
176static in_addr_t
177generate_ifconfig_broadcast_addr (in_addr_t local,
178				  in_addr_t netmask)
179{
180  return local | ~netmask;
181}
182
183/*
184 * Check that --local and --remote addresses do not
185 * clash with ifconfig addresses or subnet.
186 */
187static void
188check_addr_clash (const char *name,
189		  int type,
190		  in_addr_t public,
191		  in_addr_t local,
192		  in_addr_t remote_netmask)
193{
194  struct gc_arena gc = gc_new ();
195#if 0
196  msg (M_INFO, "CHECK_ADDR_CLASH type=%d public=%s local=%s, remote_netmask=%s",
197       type,
198       print_in_addr_t (public, 0, &gc),
199       print_in_addr_t (local, 0, &gc),
200       print_in_addr_t (remote_netmask, 0, &gc));
201#endif
202
203  if (public)
204    {
205      if (type == DEV_TYPE_TUN)
206	{
207	  const in_addr_t test_netmask = 0xFFFFFF00;
208	  const in_addr_t public_net = public & test_netmask;
209	  const in_addr_t local_net = local & test_netmask;
210	  const in_addr_t remote_net = remote_netmask & test_netmask;
211
212	  if (public == local || public == remote_netmask)
213	    msg (M_WARN,
214		 "WARNING: --%s address [%s] conflicts with --ifconfig address pair [%s, %s]. %s",
215		 name,
216		 print_in_addr_t (public, 0, &gc),
217		 print_in_addr_t (local, 0, &gc),
218		 print_in_addr_t (remote_netmask, 0, &gc),
219		 ifconfig_warn_how_to_silence);
220
221	  if (public_net == local_net || public_net == remote_net)
222	    msg (M_WARN,
223		 "WARNING: potential conflict between --%s address [%s] and --ifconfig address pair [%s, %s] -- this is a warning only that is triggered when local/remote addresses exist within the same /24 subnet as --ifconfig endpoints. %s",
224		 name,
225		 print_in_addr_t (public, 0, &gc),
226		 print_in_addr_t (local, 0, &gc),
227		 print_in_addr_t (remote_netmask, 0, &gc),
228		 ifconfig_warn_how_to_silence);
229	}
230      else if (type == DEV_TYPE_TAP)
231	{
232	  const in_addr_t public_network = public & remote_netmask;
233	  const in_addr_t virtual_network = local & remote_netmask;
234	  if (public_network == virtual_network)
235	    msg (M_WARN,
236		 "WARNING: --%s address [%s] conflicts with --ifconfig subnet [%s, %s] -- local and remote addresses cannot be inside of the --ifconfig subnet. %s",
237		 name,
238		 print_in_addr_t (public, 0, &gc),
239		 print_in_addr_t (local, 0, &gc),
240		 print_in_addr_t (remote_netmask, 0, &gc),
241		 ifconfig_warn_how_to_silence);
242	}
243    }
244  gc_free (&gc);
245}
246
247/*
248 * Issue a warning if ip/netmask (on the virtual IP network) conflicts with
249 * the settings on the local LAN.  This is designed to flag issues where
250 * (for example) the OpenVPN server LAN is running on 192.168.1.x, but then
251 * an OpenVPN client tries to connect from a public location that is also running
252 * off of a router set to 192.168.1.x.
253 */
254void
255check_subnet_conflict (const in_addr_t ip,
256		       const in_addr_t netmask,
257		       const char *prefix)
258{
259#if 0 /* too many false positives */
260  struct gc_arena gc = gc_new ();
261  in_addr_t lan_gw = 0;
262  in_addr_t lan_netmask = 0;
263
264  if (get_default_gateway (&lan_gw, &lan_netmask) && lan_netmask)
265    {
266      const in_addr_t lan_network = lan_gw & lan_netmask;
267      const in_addr_t network = ip & netmask;
268
269      /* do the two subnets defined by network/netmask and lan_network/lan_netmask intersect? */
270      if ((network & lan_netmask) == lan_network
271	  || (lan_network & netmask) == network)
272	{
273	  msg (M_WARN, "WARNING: potential %s subnet conflict between local LAN [%s/%s] and remote VPN [%s/%s]",
274	       prefix,
275	       print_in_addr_t (lan_network, 0, &gc),
276	       print_in_addr_t (lan_netmask, 0, &gc),
277	       print_in_addr_t (network, 0, &gc),
278	       print_in_addr_t (netmask, 0, &gc));
279	}
280    }
281  gc_free (&gc);
282#endif
283}
284
285void
286warn_on_use_of_common_subnets (void)
287{
288  struct gc_arena gc = gc_new ();
289  struct route_gateway_info rgi;
290  const int needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED);
291
292  get_default_gateway (&rgi);
293  if ((rgi.flags & needed) == needed)
294    {
295      const in_addr_t lan_network = rgi.gateway.addr & rgi.gateway.netmask;
296      if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100)
297	msg (M_WARN, "NOTE: your local LAN uses the extremely common subnet address 192.168.0.x or 192.168.1.x.  Be aware that this might create routing conflicts if you connect to the VPN server from public locations such as internet cafes that use the same subnet.");
298    }
299  gc_free (&gc);
300}
301
302/*
303 * Return a string to be used for options compatibility check
304 * between peers.
305 */
306const char *
307ifconfig_options_string (const struct tuntap* tt, bool remote, bool disable, struct gc_arena *gc)
308{
309  struct buffer out = alloc_buf_gc (256, gc);
310  if (tt->did_ifconfig_setup && !disable)
311    {
312      if (tt->type == DEV_TYPE_TAP || (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET))
313	{
314	  buf_printf (&out, "%s %s",
315		      print_in_addr_t (tt->local & tt->remote_netmask, 0, gc),
316		      print_in_addr_t (tt->remote_netmask, 0, gc));
317	}
318      else if (tt->type == DEV_TYPE_TUN)
319	{
320	  const char *l, *r;
321	  if (remote)
322	    {
323	      r = print_in_addr_t (tt->local, 0, gc);
324	      l = print_in_addr_t (tt->remote_netmask, 0, gc);
325	    }
326	  else
327	    {
328	      l = print_in_addr_t (tt->local, 0, gc);
329	      r = print_in_addr_t (tt->remote_netmask, 0, gc);
330	    }
331	  buf_printf (&out, "%s %s", r, l);
332	}
333      else
334	buf_printf (&out, "[undef]");
335    }
336  return BSTR (&out);
337}
338
339/*
340 * Return a status string describing wait state.
341 */
342const char *
343tun_stat (const struct tuntap *tt, unsigned int rwflags, struct gc_arena *gc)
344{
345  struct buffer out = alloc_buf_gc (64, gc);
346  if (tt)
347    {
348      if (rwflags & EVENT_READ)
349	{
350	  buf_printf (&out, "T%s",
351		      (tt->rwflags_debug & EVENT_READ) ? "R" : "r");
352#ifdef WIN32
353	  buf_printf (&out, "%s",
354		      overlapped_io_state_ascii (&tt->reads));
355#endif
356	}
357      if (rwflags & EVENT_WRITE)
358	{
359	  buf_printf (&out, "T%s",
360		      (tt->rwflags_debug & EVENT_WRITE) ? "W" : "w");
361#ifdef WIN32
362	  buf_printf (&out, "%s",
363		      overlapped_io_state_ascii (&tt->writes));
364#endif
365	}
366    }
367  else
368    {
369      buf_printf (&out, "T?");
370    }
371  return BSTR (&out);
372}
373
374/*
375 * Return true for point-to-point topology, false for subnet topology
376 */
377bool
378is_tun_p2p (const struct tuntap *tt)
379{
380  bool tun = false;
381
382  if (tt->type == DEV_TYPE_TAP || (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET))
383    tun = false;
384  else if (tt->type == DEV_TYPE_TUN)
385    tun = true;
386  else
387    msg (M_FATAL, "Error: problem with tun vs. tap setting"); /* JYFIXME -- needs to be caught earlier, in init_tun? */
388
389  return tun;
390}
391
392/*
393 * Init tun/tap object.
394 *
395 * Set up tuntap structure for ifconfig,
396 * but don't execute yet.
397 */
398struct tuntap *
399init_tun (const char *dev,       /* --dev option */
400	  const char *dev_type,  /* --dev-type option */
401	  int topology,          /* one of the TOP_x values */
402	  const char *ifconfig_local_parm,          /* --ifconfig parm 1 */
403	  const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */
404	  const char *ifconfig_ipv6_local_parm,     /* --ifconfig parm 1 IPv6 */
405	  int         ifconfig_ipv6_netbits_parm,
406	  const char *ifconfig_ipv6_remote_parm,    /* --ifconfig parm 2 IPv6 */
407	  in_addr_t local_public,
408	  in_addr_t remote_public,
409	  const bool strict_warn,
410	  struct env_set *es)
411{
412  struct gc_arena gc = gc_new ();
413  struct tuntap *tt;
414
415  ALLOC_OBJ (tt, struct tuntap);
416  clear_tuntap (tt);
417
418  tt->type = dev_type_enum (dev, dev_type);
419  tt->topology = topology;
420
421  if (ifconfig_local_parm && ifconfig_remote_netmask_parm)
422    {
423      bool tun = false;
424      const char *ifconfig_local = NULL;
425      const char *ifconfig_remote_netmask = NULL;
426      const char *ifconfig_broadcast = NULL;
427
428      /*
429       * We only handle TUN/TAP devices here, not --dev null devices.
430       */
431      tun = is_tun_p2p (tt);
432
433      /*
434       * Convert arguments to binary IPv4 addresses.
435       */
436
437      tt->local = getaddr (
438			   GETADDR_RESOLVE
439			   | GETADDR_HOST_ORDER
440			   | GETADDR_FATAL_ON_SIGNAL
441			   | GETADDR_FATAL,
442			   ifconfig_local_parm,
443			   0,
444			   NULL,
445			   NULL);
446
447      tt->remote_netmask = getaddr (
448				    (tun ? GETADDR_RESOLVE : 0)
449				    | GETADDR_HOST_ORDER
450				    | GETADDR_FATAL_ON_SIGNAL
451				    | GETADDR_FATAL,
452				    ifconfig_remote_netmask_parm,
453				    0,
454				    NULL,
455				    NULL);
456
457      /*
458       * Look for common errors in --ifconfig parms
459       */
460      if (strict_warn)
461	{
462	  ifconfig_sanity_check (tt->type == DEV_TYPE_TUN, tt->remote_netmask, tt->topology);
463
464	  /*
465	   * If local_public or remote_public addresses are defined,
466	   * make sure they do not clash with our virtual subnet.
467	   */
468
469	  check_addr_clash ("local",
470			    tt->type,
471			    local_public,
472			    tt->local,
473			    tt->remote_netmask);
474
475	  check_addr_clash ("remote",
476			    tt->type,
477			    remote_public,
478			    tt->local,
479			    tt->remote_netmask);
480
481	  if (tt->type == DEV_TYPE_TAP || (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET))
482	    check_subnet_conflict (tt->local, tt->remote_netmask, "TUN/TAP adapter");
483	  else if (tt->type == DEV_TYPE_TUN)
484	    check_subnet_conflict (tt->local, IPV4_NETMASK_HOST, "TUN/TAP adapter");
485	}
486
487      /*
488       * Set ifconfig parameters
489       */
490      ifconfig_local = print_in_addr_t (tt->local, 0, &gc);
491      ifconfig_remote_netmask = print_in_addr_t (tt->remote_netmask, 0, &gc);
492
493      /*
494       * If TAP-style interface, generate broadcast address.
495       */
496      if (!tun)
497	{
498	  tt->broadcast = generate_ifconfig_broadcast_addr (tt->local, tt->remote_netmask);
499	  ifconfig_broadcast = print_in_addr_t (tt->broadcast, 0, &gc);
500	}
501
502      /*
503       * Set environmental variables with ifconfig parameters.
504       */
505      if (es)
506	{
507	  setenv_str (es, "ifconfig_local", ifconfig_local);
508	  if (tun)
509	    {
510	      setenv_str (es, "ifconfig_remote", ifconfig_remote_netmask);
511	    }
512	  else
513	    {
514	      setenv_str (es, "ifconfig_netmask", ifconfig_remote_netmask);
515	      setenv_str (es, "ifconfig_broadcast", ifconfig_broadcast);
516	    }
517	}
518
519      tt->did_ifconfig_setup = true;
520    }
521
522  if (ifconfig_ipv6_local_parm && ifconfig_ipv6_remote_parm)
523    {
524      const char *ifconfig_ipv6_local = NULL;
525      const char *ifconfig_ipv6_remote = NULL;
526
527      /*
528       * Convert arguments to binary IPv6 addresses.
529       */
530
531      if ( inet_pton( AF_INET6, ifconfig_ipv6_local_parm, &tt->local_ipv6 ) != 1 ||
532           inet_pton( AF_INET6, ifconfig_ipv6_remote_parm, &tt->remote_ipv6 ) != 1 )
533	{
534	  msg( M_FATAL, "init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary", ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm );
535	}
536      tt->netbits_ipv6 = ifconfig_ipv6_netbits_parm;
537
538      /*
539       * Set ifconfig parameters
540       */
541      ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
542      ifconfig_ipv6_remote = print_in6_addr (tt->remote_ipv6, 0, &gc);
543
544      /*
545       * Set environmental variables with ifconfig parameters.
546       */
547      if (es)
548	{
549	  setenv_str (es, "ifconfig_ipv6_local", ifconfig_ipv6_local);
550	  setenv_int (es, "ifconfig_ipv6_netbits", tt->netbits_ipv6);
551	  setenv_str (es, "ifconfig_ipv6_remote", ifconfig_ipv6_remote);
552	}
553      tt->did_ifconfig_ipv6_setup = true;
554    }
555
556  gc_free (&gc);
557  return tt;
558}
559
560/*
561 * Platform specific tun initializations
562 */
563void
564init_tun_post (struct tuntap *tt,
565	       const struct frame *frame,
566	       const struct tuntap_options *options)
567{
568  tt->options = *options;
569#ifdef WIN32
570  overlapped_io_init (&tt->reads, frame, FALSE, true);
571  overlapped_io_init (&tt->writes, frame, TRUE, true);
572  tt->rw_handle.read = tt->reads.overlapped.hEvent;
573  tt->rw_handle.write = tt->writes.overlapped.hEvent;
574  tt->adapter_index = TUN_ADAPTER_INDEX_INVALID;
575#endif
576}
577
578#if defined(WIN32) || \
579    defined(TARGET_DARWIN) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD)
580
581/* some of the platforms will auto-add a "network route" pointing
582 * to the interface on "ifconfig tunX 2001:db8::1/64", others need
583 * an extra call to "route add..."
584 * -> helper function to simplify code below
585 */
586void add_route_connected_v6_net(struct tuntap * tt,
587	                        const struct env_set *es)
588{
589    struct route_ipv6 r6;
590
591    r6.defined = true;
592    r6.network = tt->local_ipv6;
593    r6.netbits = tt->netbits_ipv6;
594    r6.gateway = tt->local_ipv6;
595    r6.metric  = 0;			/* connected route */
596    r6.metric_defined = true;
597    add_route_ipv6 (&r6, tt, 0, es);
598}
599
600void delete_route_connected_v6_net(struct tuntap * tt,
601	                           const struct env_set *es)
602{
603    struct route_ipv6 r6;
604
605    r6.defined = true;
606    r6.network = tt->local_ipv6;
607    r6.netbits = tt->netbits_ipv6;
608    r6.gateway = tt->local_ipv6;
609    r6.metric  = 0;			/* connected route */
610    r6.metric_defined = true;
611    delete_route_ipv6 (&r6, tt, 0, es);
612}
613#endif
614
615
616/* execute the ifconfig command through the shell */
617void
618do_ifconfig (struct tuntap *tt,
619	     const char *actual,    /* actual device name */
620	     int tun_mtu,
621	     const struct env_set *es)
622{
623  struct gc_arena gc = gc_new ();
624
625  if (tt->did_ifconfig_setup)
626    {
627      bool tun = false;
628      const char *ifconfig_local = NULL;
629      const char *ifconfig_remote_netmask = NULL;
630      const char *ifconfig_broadcast = NULL;
631      const char *ifconfig_ipv6_local = NULL;
632      const char *ifconfig_ipv6_remote = NULL;
633      bool do_ipv6 = false;
634      struct argv argv;
635
636      argv_init (&argv);
637
638      msg( M_INFO, "do_ifconfig, tt->ipv6=%d, tt->did_ifconfig_ipv6_setup=%d",
639	           tt->ipv6, tt->did_ifconfig_ipv6_setup );
640
641      /*
642       * We only handle TUN/TAP devices here, not --dev null devices.
643       */
644      tun = is_tun_p2p (tt);
645
646      /*
647       * Set ifconfig parameters
648       */
649      ifconfig_local = print_in_addr_t (tt->local, 0, &gc);
650      ifconfig_remote_netmask = print_in_addr_t (tt->remote_netmask, 0, &gc);
651
652      if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
653        {
654	  ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
655	  ifconfig_ipv6_remote = print_in6_addr (tt->remote_ipv6, 0, &gc);
656	  do_ipv6 = true;
657	}
658
659      /*
660       * If TAP-style device, generate broadcast address.
661       */
662      if (!tun)
663	ifconfig_broadcast = print_in_addr_t (tt->broadcast, 0, &gc);
664
665#ifdef ENABLE_MANAGEMENT
666  if (management)
667    {
668      management_set_state (management,
669			    OPENVPN_STATE_ASSIGN_IP,
670			    NULL,
671			    tt->local,
672			    0);
673    }
674#endif
675
676
677#if defined(TARGET_LINUX)
678#ifdef ENABLE_IPROUTE
679	/*
680	 * Set the MTU for the device
681	 */
682	argv_printf (&argv,
683			  "%s link set dev %s up mtu %d",
684			  iproute_path,
685			  actual,
686			  tun_mtu
687			  );
688	  argv_msg (M_INFO, &argv);
689	  openvpn_execve_check (&argv, es, S_FATAL, "Linux ip link set failed");
690
691	if (tun) {
692
693		/*
694		 * Set the address for the device
695		 */
696		argv_printf (&argv,
697				  "%s addr add dev %s local %s peer %s",
698				  iproute_path,
699				  actual,
700				  ifconfig_local,
701				  ifconfig_remote_netmask
702				  );
703		  argv_msg (M_INFO, &argv);
704		  openvpn_execve_check (&argv, es, S_FATAL, "Linux ip addr add failed");
705	} else {
706		argv_printf (&argv,
707				  "%s addr add dev %s %s/%d broadcast %s",
708				  iproute_path,
709				  actual,
710				  ifconfig_local,
711				  count_netmask_bits(ifconfig_remote_netmask),
712				  ifconfig_broadcast
713				  );
714		  argv_msg (M_INFO, &argv);
715		  openvpn_execve_check (&argv, es, S_FATAL, "Linux ip addr add failed");
716	}
717      if ( do_ipv6 )
718	{
719	  argv_printf( &argv,
720		      "%s -6 addr add %s/%d dev %s",
721		      iproute_path,
722		      ifconfig_ipv6_local,
723		      tt->netbits_ipv6,
724		      actual
725		      );
726	  argv_msg (M_INFO, &argv);
727	  openvpn_execve_check (&argv, es, S_FATAL, "Linux ip -6 addr add failed");
728	}
729      tt->did_ifconfig = true;
730#else
731      if (tun)
732	argv_printf (&argv,
733			  "%s %s %s pointopoint %s mtu %d",
734			  IFCONFIG_PATH,
735			  actual,
736			  ifconfig_local,
737			  ifconfig_remote_netmask,
738			  tun_mtu
739			  );
740      else
741	argv_printf (&argv,
742			  "%s %s %s netmask %s mtu %d broadcast %s",
743			  IFCONFIG_PATH,
744			  actual,
745			  ifconfig_local,
746			  ifconfig_remote_netmask,
747			  tun_mtu,
748			  ifconfig_broadcast
749			  );
750      argv_msg (M_INFO, &argv);
751      openvpn_execve_check (&argv, es, S_FATAL, "Linux ifconfig failed");
752      if ( do_ipv6 )
753	{
754	  argv_printf (&argv,
755			  "%s %s add %s/%d",
756			  IFCONFIG_PATH,
757			  actual,
758			  ifconfig_ipv6_local,
759			  tt->netbits_ipv6
760			  );
761	  argv_msg (M_INFO, &argv);
762	  openvpn_execve_check (&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
763	}
764      tt->did_ifconfig = true;
765
766#endif /*ENABLE_IPROUTE*/
767#elif defined(TARGET_SOLARIS)
768
769      /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
770       * example:
771       *    ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
772       *    ifconfig tun2 netmask 255.255.255.255
773       */
774      if (tun)
775	{
776	  argv_printf (&argv,
777			    "%s %s %s %s mtu %d up",
778			    IFCONFIG_PATH,
779			    actual,
780			    ifconfig_local,
781			    ifconfig_remote_netmask,
782			    tun_mtu
783			    );
784
785	  argv_msg (M_INFO, &argv);
786	  if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-1 failed"))
787	    solaris_error_close (tt, es, actual, false);
788
789	  argv_printf (&argv,
790			    "%s %s netmask 255.255.255.255",
791			    IFCONFIG_PATH,
792			    actual
793			    );
794	}
795      else
796        if (tt->topology == TOP_SUBNET)
797	{
798          argv_printf (&argv,
799                              "%s %s %s %s netmask %s mtu %d up",
800                              IFCONFIG_PATH,
801                              actual,
802                              ifconfig_local,
803                              ifconfig_local,
804                              ifconfig_remote_netmask,
805                              tun_mtu
806                              );
807	}
808        else
809          argv_printf (&argv,
810                            " %s %s %s netmask %s broadcast + up",
811                            IFCONFIG_PATH,
812                            actual,
813                            ifconfig_local,
814                            ifconfig_remote_netmask
815                            );
816
817      argv_msg (M_INFO, &argv);
818      if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-2 failed"))
819	solaris_error_close (tt, es, actual, false);
820
821      if ( do_ipv6 )
822        {
823 	  argv_printf (&argv, "%s %s inet6 unplumb",
824			    IFCONFIG_PATH, actual );
825	  argv_msg (M_INFO, &argv);
826	  openvpn_execve_check (&argv, es, 0, NULL);
827
828	  if ( tt->type == DEV_TYPE_TUN )
829	   {
830	      argv_printf (&argv,
831			    "%s %s inet6 plumb %s/%d %s up",
832			    IFCONFIG_PATH,
833			    actual,
834			    ifconfig_ipv6_local,
835			    tt->netbits_ipv6,
836			    ifconfig_ipv6_remote
837			    );
838	    }
839	  else						/* tap mode */
840	    {
841	      /* base IPv6 tap interface needs to be brought up first
842	       */
843	      argv_printf (&argv, "%s %s inet6 plumb up",
844			    IFCONFIG_PATH, actual );
845	      argv_msg (M_INFO, &argv);
846	      if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig IPv6 (prepare) failed"))
847		solaris_error_close (tt, es, actual, true);
848
849	      /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
850	       * after the system has noticed the interface and fired up
851	       * the DHCPv6 client - but this takes quite a while, and the
852	       * server will ignore the DHCPv6 packets anyway.  So we don't.
853	       */
854
855	      /* static IPv6 addresses need to go to a subinterface (tap0:1)
856	       */
857	      argv_printf (&argv,
858			    "%s %s inet6 addif %s/%d up",
859			    IFCONFIG_PATH, actual,
860			    ifconfig_ipv6_local, tt->netbits_ipv6 );
861	    }
862	  argv_msg (M_INFO, &argv);
863	  if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig IPv6 failed"))
864	    solaris_error_close (tt, es, actual, true);
865        }
866
867      if (!tun && tt->topology == TOP_SUBNET)
868	{
869	  /* Add a network route for the local tun interface */
870	  struct route r;
871	  CLEAR (r);
872	  r.flags = RT_DEFINED | RT_METRIC_DEFINED;
873	  r.network = tt->local & tt->remote_netmask;
874	  r.netmask = tt->remote_netmask;
875	  r.gateway = tt->local;
876	  r.metric = 0;
877	  add_route (&r, tt, 0, NULL, es);
878	}
879
880      tt->did_ifconfig = true;
881
882#elif defined(TARGET_OPENBSD)
883
884      /*
885       * On OpenBSD, tun interfaces are persistent if created with
886       * "ifconfig tunX create", and auto-destroyed if created by
887       * opening "/dev/tunX" (so we just use the /dev/tunX)
888       */
889
890      /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
891      if (tun)
892	argv_printf (&argv,
893			  "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
894			  IFCONFIG_PATH,
895			  actual,
896			  ifconfig_local,
897			  ifconfig_remote_netmask,
898			  tun_mtu
899			  );
900      else
901	if ( tt->topology == TOP_SUBNET )
902	{
903	    argv_printf (&argv,
904			  "%s %s %s %s mtu %d netmask %s up -link0",
905			  IFCONFIG_PATH,
906			  actual,
907			  ifconfig_local,
908			  ifconfig_local,
909			  tun_mtu,
910			  ifconfig_remote_netmask
911			  );
912	}
913      else
914	argv_printf (&argv,
915			  "%s %s %s netmask %s mtu %d broadcast %s link0",
916			  IFCONFIG_PATH,
917			  actual,
918			  ifconfig_local,
919			  ifconfig_remote_netmask,
920			  tun_mtu,
921			  ifconfig_broadcast
922			  );
923      argv_msg (M_INFO, &argv);
924      openvpn_execve_check (&argv, es, S_FATAL, "OpenBSD ifconfig failed");
925      if ( do_ipv6 )
926	{
927	  argv_printf (&argv,
928			  "%s %s inet6 %s/%d",
929			  IFCONFIG_PATH,
930			  actual,
931			  ifconfig_ipv6_local,
932			  tt->netbits_ipv6
933			  );
934	  argv_msg (M_INFO, &argv);
935	  openvpn_execve_check (&argv, es, S_FATAL, "OpenBSD ifconfig inet6 failed");
936
937	  /* and, hooray, we explicitely need to add a route... */
938	  add_route_connected_v6_net(tt, es);
939	}
940      tt->did_ifconfig = true;
941
942#elif defined(TARGET_NETBSD)
943
944/* whether or not NetBSD can do IPv6 can be seen by the availability of
945 * the TUNSIFHEAD ioctl() - see next TARGET_NETBSD block for more details
946 */
947#ifdef TUNSIFHEAD
948# define NETBSD_MULTI_AF
949#endif
950
951      if (tun)
952	argv_printf (&argv,
953			  "%s %s %s %s mtu %d netmask 255.255.255.255 up",
954			  IFCONFIG_PATH,
955			  actual,
956			  ifconfig_local,
957			  ifconfig_remote_netmask,
958			  tun_mtu
959			  );
960      else
961	if ( tt->topology == TOP_SUBNET )
962	{
963	    argv_printf (&argv,
964			  "%s %s %s %s mtu %d netmask %s up",
965			  IFCONFIG_PATH,
966			  actual,
967			  ifconfig_local,
968			  ifconfig_local,
969			  tun_mtu,
970			  ifconfig_remote_netmask
971			  );
972	}
973      else
974      /*
975       * NetBSD has distinct tun and tap devices
976       * so we don't need the "link0" extra parameter to specify we want to do
977       * tunneling at the ethernet level
978       */
979		argv_printf (&argv,
980			  "%s %s %s netmask %s mtu %d broadcast %s",
981			  IFCONFIG_PATH,
982			  actual,
983			  ifconfig_local,
984			  ifconfig_remote_netmask,
985			  tun_mtu,
986			  ifconfig_broadcast
987			  );
988      argv_msg (M_INFO, &argv);
989      openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig failed");
990
991      if ( do_ipv6 )
992	{
993#ifdef NETBSD_MULTI_AF
994	  argv_printf (&argv,
995			  "%s %s inet6 %s/%d",
996			  IFCONFIG_PATH,
997			  actual,
998			  ifconfig_ipv6_local,
999			  tt->netbits_ipv6
1000			  );
1001	  argv_msg (M_INFO, &argv);
1002	  openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig inet6 failed");
1003
1004	  /* and, hooray, we explicitely need to add a route... */
1005	  add_route_connected_v6_net(tt, es);
1006#else
1007	  msg( M_INFO, "no IPv6 support for tun interfaces on NetBSD before 4.0 (if your system is newer, recompile openvpn)" );
1008	  tt->ipv6 = false;
1009#endif
1010	}
1011      tt->did_ifconfig = true;
1012
1013#elif defined(TARGET_DARWIN)
1014      /*
1015       * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
1016       */
1017
1018      argv_printf (&argv,
1019			"%s %s delete",
1020			IFCONFIG_PATH,
1021			actual);
1022      argv_msg (M_INFO, &argv);
1023      openvpn_execve_check (&argv, es, 0, NULL);
1024      msg (M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
1025
1026
1027      /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1028      if (tun)
1029	argv_printf (&argv,
1030			  "%s %s %s %s mtu %d netmask 255.255.255.255 up",
1031			  IFCONFIG_PATH,
1032			  actual,
1033			  ifconfig_local,
1034			  ifconfig_remote_netmask,
1035			  tun_mtu
1036			  );
1037      else
1038        {
1039          if (tt->topology == TOP_SUBNET)
1040    	    argv_printf (&argv,
1041			      "%s %s %s %s netmask %s mtu %d up",
1042			      IFCONFIG_PATH,
1043			      actual,
1044			      ifconfig_local,
1045			      ifconfig_local,
1046			      ifconfig_remote_netmask,
1047			      tun_mtu
1048			      );
1049	  else
1050    	    argv_printf (&argv,
1051			      "%s %s %s netmask %s mtu %d up",
1052			      IFCONFIG_PATH,
1053			      actual,
1054			      ifconfig_local,
1055			      ifconfig_remote_netmask,
1056			      tun_mtu
1057			      );
1058	}
1059
1060      argv_msg (M_INFO, &argv);
1061      openvpn_execve_check (&argv, es, S_FATAL, "Mac OS X ifconfig failed");
1062      tt->did_ifconfig = true;
1063
1064      /* Add a network route for the local tun interface */
1065      if (!tun && tt->topology == TOP_SUBNET)
1066	{
1067	  struct route r;
1068	  CLEAR (r);
1069	  r.flags = RT_DEFINED;
1070	  r.network = tt->local & tt->remote_netmask;
1071	  r.netmask = tt->remote_netmask;
1072	  r.gateway = tt->local;
1073	  add_route (&r, tt, 0, NULL, es);
1074	}
1075
1076      if ( do_ipv6 )
1077	{
1078          argv_printf (&argv,
1079                              "%s %s inet6 %s/%d",
1080                              IFCONFIG_PATH,
1081                              actual,
1082                              ifconfig_ipv6_local,
1083                              tt->netbits_ipv6
1084                              );
1085	  argv_msg (M_INFO, &argv);
1086	  openvpn_execve_check (&argv, es, S_FATAL, "MacOS X ifconfig inet6 failed");
1087
1088	  /* and, hooray, we explicitely need to add a route... */
1089	  add_route_connected_v6_net(tt, es);
1090	}
1091
1092#elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)
1093
1094      /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1095      if (tun)
1096	argv_printf (&argv,
1097			  "%s %s %s %s mtu %d netmask 255.255.255.255 up",
1098			  IFCONFIG_PATH,
1099			  actual,
1100			  ifconfig_local,
1101			  ifconfig_remote_netmask,
1102			  tun_mtu
1103			  );
1104      else if ( tt->topology == TOP_SUBNET )
1105	{
1106	    argv_printf (&argv,
1107			  "%s %s %s %s mtu %d netmask %s up",
1108			  IFCONFIG_PATH,
1109			  actual,
1110			  ifconfig_local,
1111			  ifconfig_local,
1112			  tun_mtu,
1113			  ifconfig_remote_netmask
1114			  );
1115	}
1116      else
1117	argv_printf (&argv,
1118		      "%s %s %s netmask %s mtu %d up",
1119                              IFCONFIG_PATH,
1120                              actual,
1121                              ifconfig_local,
1122                              ifconfig_remote_netmask,
1123                              tun_mtu
1124                              );
1125
1126      argv_msg (M_INFO, &argv);
1127      openvpn_execve_check (&argv, es, S_FATAL, "FreeBSD ifconfig failed");
1128      tt->did_ifconfig = true;
1129
1130	/* Add a network route for the local tun interface */
1131      if (!tun && tt->topology == TOP_SUBNET)
1132        {
1133          struct route r;
1134          CLEAR (r);
1135          r.flags = RT_DEFINED;
1136          r.network = tt->local & tt->remote_netmask;
1137          r.netmask = tt->remote_netmask;
1138          r.gateway = tt->local;
1139          add_route (&r, tt, 0, NULL, es);
1140        }
1141
1142      if ( do_ipv6 )
1143	{
1144          argv_printf (&argv,
1145                              "%s %s inet6 %s/%d",
1146                              IFCONFIG_PATH,
1147                              actual,
1148                              ifconfig_ipv6_local,
1149                              tt->netbits_ipv6
1150                              );
1151	  argv_msg (M_INFO, &argv);
1152	  openvpn_execve_check (&argv, es, S_FATAL, "FreeBSD ifconfig inet6 failed");
1153	}
1154
1155#elif defined (WIN32)
1156      {
1157	/*
1158	 * Make sure that both ifconfig addresses are part of the
1159	 * same .252 subnet.
1160	 */
1161	if (tun)
1162	  {
1163	    verify_255_255_255_252 (tt->local, tt->remote_netmask);
1164	    tt->adapter_netmask = ~3;
1165	  }
1166	else
1167	  {
1168	    tt->adapter_netmask = tt->remote_netmask;
1169	  }
1170
1171	switch (tt->options.ip_win32_type)
1172	  {
1173	  case IPW32_SET_MANUAL:
1174	    msg (M_INFO, "******** NOTE:  Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
1175		 actual,
1176		 ifconfig_local,
1177		 print_in_addr_t (tt->adapter_netmask, 0, &gc));
1178	    break;
1179	  case IPW32_SET_NETSH:
1180	    if (!strcmp (actual, "NULL"))
1181	      msg (M_FATAL, "Error: When using --ip-win32 netsh, if you have more than one TAP-Windows adapter, you must also specify --dev-node");
1182
1183	    netsh_ifconfig (&tt->options,
1184			    actual,
1185			    tt->local,
1186			    tt->adapter_netmask,
1187			    NI_IP_NETMASK|NI_OPTIONS);
1188
1189	    break;
1190	  }
1191	tt->did_ifconfig = true;
1192      }
1193
1194    /* IPv6 always uses "netsh" interface */
1195    if ( do_ipv6 )
1196      {
1197	char * saved_actual;
1198
1199	if (!strcmp (actual, "NULL"))
1200	  msg (M_FATAL, "Error: When using --tun-ipv6, if you have more than one TAP-Windows adapter, you must also specify --dev-node");
1201
1202	/* example: netsh interface ipv6 set address MyTap 2001:608:8003::d store=active */
1203	argv_printf (&argv,
1204		    "%s%sc interface ipv6 set address %s %s store=active",
1205		     get_win_sys_path(),
1206		     NETSH_PATH_SUFFIX,
1207		     actual,
1208		     ifconfig_ipv6_local );
1209
1210	netsh_command (&argv, 4);
1211
1212	/* explicit route needed */
1213	/* on windows, OpenVPN does ifconfig first, open_tun later, so
1214	 * tt->actual_name might not yet be initialized, but routing code
1215	 * needs to know interface name - point to "actual", restore later
1216	 */
1217	saved_actual = tt->actual_name;
1218	tt->actual_name = (char*) actual;
1219	add_route_connected_v6_net(tt, es);
1220	tt->actual_name = saved_actual;
1221      }
1222#else
1223      msg (M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
1224#endif
1225      argv_reset (&argv);
1226    }
1227  gc_free (&gc);
1228}
1229
1230static void
1231clear_tuntap (struct tuntap *tuntap)
1232{
1233  CLEAR (*tuntap);
1234#ifdef WIN32
1235  tuntap->hand = NULL;
1236#else
1237  tuntap->fd = -1;
1238#endif
1239#ifdef TARGET_SOLARIS
1240  tuntap->ip_fd = -1;
1241#endif
1242  tuntap->ipv6 = false;
1243}
1244
1245static void
1246open_null (struct tuntap *tt)
1247{
1248  tt->actual_name = string_alloc ("null", NULL);
1249}
1250
1251#ifndef WIN32
1252static void
1253open_tun_generic (const char *dev, const char *dev_type, const char *dev_node,
1254		  bool ipv6_explicitly_supported, bool dynamic,
1255		  struct tuntap *tt)
1256{
1257  char tunname[256];
1258  char dynamic_name[256];
1259  bool dynamic_opened = false;
1260
1261
1262  if ( tt->ipv6 && ! ipv6_explicitly_supported )
1263    msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS");
1264
1265  if (tt->type == DEV_TYPE_NULL)
1266    {
1267      open_null (tt);
1268    }
1269  else
1270    {
1271      /*
1272       * --dev-node specified, so open an explicit device node
1273       */
1274      if (dev_node)
1275	{
1276	  openvpn_snprintf (tunname, sizeof (tunname), "%s", dev_node);
1277	}
1278      else
1279	{
1280	  /*
1281	   * dynamic open is indicated by --dev specified without
1282	   * explicit unit number.  Try opening /dev/[dev]n
1283	   * where n = [0, 255].
1284	   */
1285#ifdef TARGET_NETBSD
1286	  /* on NetBSD, tap (but not tun) devices are opened by
1287           * opening /dev/tap and then querying the system about the
1288	   * actual device name (tap0, tap1, ...) assigned
1289           */
1290	  if ( dynamic && strcmp( dev, "tap" ) == 0 )
1291	    {
1292	      struct ifreq ifr;
1293	      if ((tt->fd = open ( "/dev/tap", O_RDWR)) < 0)
1294		{
1295		  msg (M_FATAL, "Cannot allocate NetBSD TAP dev dynamically");
1296		}
1297	      if ( ioctl( tt->fd, TAPGIFNAME, (void*)&ifr ) < 0 )
1298		{
1299		  msg (M_FATAL, "Cannot query NetBSD TAP device name");
1300		}
1301	      CLEAR(dynamic_name);
1302	      strncpy( dynamic_name, ifr.ifr_name, sizeof(dynamic_name)-1 );
1303	      dynamic_opened = true;
1304	      openvpn_snprintf (tunname, sizeof (tunname), "/dev/%s", dynamic_name );
1305	    }
1306	  else
1307#endif
1308
1309	  if (dynamic && !has_digit((unsigned char *)dev))
1310	    {
1311	      int i;
1312	      for (i = 0; i < 256; ++i)
1313		{
1314		  openvpn_snprintf (tunname, sizeof (tunname),
1315				    "/dev/%s%d", dev, i);
1316		  openvpn_snprintf (dynamic_name, sizeof (dynamic_name),
1317				    "%s%d", dev, i);
1318		  if ((tt->fd = open (tunname, O_RDWR)) > 0)
1319		    {
1320		      dynamic_opened = true;
1321		      break;
1322		    }
1323		  msg (D_READ_WRITE | M_ERRNO, "Tried opening %s (failed)", tunname);
1324		}
1325	      if (!dynamic_opened)
1326		msg (M_FATAL, "Cannot allocate TUN/TAP dev dynamically");
1327	    }
1328	  /*
1329	   * explicit unit number specified
1330	   */
1331	  else
1332	    {
1333	      openvpn_snprintf (tunname, sizeof (tunname), "/dev/%s", dev);
1334	    }
1335	}
1336
1337      if (!dynamic_opened)
1338	{
1339	  /* has named device existed before? if so, don't destroy at end */
1340	  if ( if_nametoindex( dev ) > 0 )
1341	    {
1342	      msg (M_INFO, "TUN/TAP device %s exists previously, keep at program end", dev );
1343	      tt->persistent_if = true;
1344	    }
1345
1346	  if ((tt->fd = open (tunname, O_RDWR)) < 0)
1347	    msg (M_ERR, "Cannot open TUN/TAP dev %s", tunname);
1348	}
1349
1350      set_nonblock (tt->fd);
1351      set_cloexec (tt->fd); /* don't pass fd to scripts */
1352      msg (M_INFO, "TUN/TAP device %s opened", tunname);
1353
1354      /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
1355      tt->actual_name = string_alloc (dynamic_opened ? dynamic_name : dev, NULL);
1356    }
1357}
1358
1359static void
1360close_tun_generic (struct tuntap *tt)
1361{
1362  if (tt->fd >= 0)
1363    close (tt->fd);
1364  if (tt->actual_name)
1365    free (tt->actual_name);
1366  clear_tuntap (tt);
1367}
1368
1369#endif
1370
1371#if defined(TARGET_LINUX)
1372
1373#ifdef HAVE_LINUX_IF_TUN_H	/* New driver support */
1374
1375#ifndef HAVE_LINUX_SOCKIOS_H
1376#error header file linux/sockios.h required
1377#endif
1378
1379#if !PEDANTIC
1380
1381void
1382open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1383{
1384  struct ifreq ifr;
1385
1386  /*
1387   * We handle --dev null specially, we do not open /dev/null for this.
1388   */
1389  if (tt->type == DEV_TYPE_NULL)
1390    {
1391      open_null (tt);
1392    }
1393  else
1394    {
1395      /*
1396       * Process --dev-node
1397       */
1398      const char *node = dev_node;
1399      if (!node)
1400	node = "/dev/net/tun";
1401
1402      /*
1403       * Open the interface
1404       */
1405      if ((tt->fd = open (node, O_RDWR)) < 0)
1406	{
1407	  msg (M_ERR, "ERROR: Cannot open TUN/TAP dev %s", node);
1408	}
1409
1410      /*
1411       * Process --tun-ipv6
1412       */
1413      CLEAR (ifr);
1414      if (!tt->ipv6)
1415	ifr.ifr_flags = IFF_NO_PI;
1416
1417#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
1418      ifr.ifr_flags |= IFF_ONE_QUEUE;
1419#endif
1420
1421      /*
1422       * Figure out if tun or tap device
1423       */
1424      if (tt->type == DEV_TYPE_TUN)
1425	{
1426	  ifr.ifr_flags |= IFF_TUN;
1427	}
1428      else if (tt->type == DEV_TYPE_TAP)
1429	{
1430	  ifr.ifr_flags |= IFF_TAP;
1431	}
1432      else
1433	{
1434	  msg (M_FATAL, "I don't recognize device %s as a tun or tap device",
1435	       dev);
1436	}
1437
1438      /*
1439       * Set an explicit name, if --dev is not tun or tap
1440       */
1441      if (strcmp(dev, "tun") && strcmp(dev, "tap"))
1442	strncpynt (ifr.ifr_name, dev, IFNAMSIZ);
1443
1444      /*
1445       * Use special ioctl that configures tun/tap device with the parms
1446       * we set in ifr
1447       */
1448      if (ioctl (tt->fd, TUNSETIFF, (void *) &ifr) < 0)
1449	{
1450	  msg (M_ERR, "ERROR: Cannot ioctl TUNSETIFF %s", dev);
1451	}
1452
1453      msg (M_INFO, "TUN/TAP device %s opened", ifr.ifr_name);
1454
1455      /*
1456       * Try making the TX send queue bigger
1457       */
1458#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
1459      if (tt->options.txqueuelen) {
1460	struct ifreq netifr;
1461	int ctl_fd;
1462
1463	if ((ctl_fd = socket (AF_INET, SOCK_DGRAM, 0)) >= 0)
1464	  {
1465	    CLEAR (netifr);
1466	    strncpynt (netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
1467	    netifr.ifr_qlen = tt->options.txqueuelen;
1468	    if (ioctl (ctl_fd, SIOCSIFTXQLEN, (void *) &netifr) >= 0)
1469	      msg (D_OSBUF, "TUN/TAP TX queue length set to %d", tt->options.txqueuelen);
1470	    else
1471	      msg (M_WARN | M_ERRNO, "Note: Cannot set tx queue length on %s", ifr.ifr_name);
1472	    close (ctl_fd);
1473	  }
1474	else
1475	  {
1476	    msg (M_WARN | M_ERRNO, "Note: Cannot open control socket on %s", ifr.ifr_name);
1477	  }
1478      }
1479#endif
1480
1481      set_nonblock (tt->fd);
1482      set_cloexec (tt->fd);
1483      tt->actual_name = string_alloc (ifr.ifr_name, NULL);
1484    }
1485  return;
1486}
1487
1488#else
1489
1490void
1491open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1492{
1493  ASSERT (0);
1494}
1495
1496#endif
1497
1498#else
1499
1500void
1501open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1502{
1503  open_tun_generic (dev, dev_type, dev_node, false, true, tt);
1504}
1505
1506#endif /* HAVE_LINUX_IF_TUN_H */
1507
1508#ifdef ENABLE_FEATURE_TUN_PERSIST
1509
1510/*
1511 * This can be removed in future
1512 * when all systems will use newer
1513 * linux-headers
1514 */
1515#ifndef TUNSETOWNER
1516#define TUNSETOWNER	_IOW('T', 204, int)
1517#endif
1518#ifndef TUNSETGROUP
1519#define TUNSETGROUP	_IOW('T', 206, int)
1520#endif
1521
1522void
1523tuncfg (const char *dev, const char *dev_type, const char *dev_node, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options)
1524{
1525  struct tuntap *tt;
1526
1527  ALLOC_OBJ (tt, struct tuntap);
1528  clear_tuntap (tt);
1529  tt->type = dev_type_enum (dev, dev_type);
1530  tt->options = *options;
1531  open_tun (dev, dev_type, dev_node, tt);
1532  if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0)
1533    msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
1534  if (username != NULL)
1535    {
1536      struct platform_state_user platform_state_user;
1537
1538      if (!platform_user_get (username, &platform_state_user))
1539        msg (M_ERR, "Cannot get user entry for %s", username);
1540      else
1541        if (ioctl (tt->fd, TUNSETOWNER, platform_state_user.pw->pw_uid) < 0)
1542          msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", username, dev);
1543    }
1544  if (groupname != NULL)
1545    {
1546      struct platform_state_group platform_state_group;
1547
1548      if (!platform_group_get (groupname, &platform_state_group))
1549        msg (M_ERR, "Cannot get group entry for %s", groupname);
1550      else
1551        if (ioctl (tt->fd, TUNSETGROUP, platform_state_group.gr->gr_gid) < 0)
1552          msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", groupname, dev);
1553    }
1554  close_tun (tt);
1555  msg (M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF"));
1556}
1557
1558#endif /* ENABLE_FEATURE_TUN_PERSIST */
1559
1560void
1561close_tun (struct tuntap *tt)
1562{
1563  if (tt)
1564    {
1565	if (tt->type != DEV_TYPE_NULL && tt->did_ifconfig)
1566	  {
1567	    struct argv argv;
1568	    struct gc_arena gc = gc_new ();
1569	    argv_init (&argv);
1570
1571#ifdef ENABLE_IPROUTE
1572	    if (is_tun_p2p (tt))
1573	      {
1574		argv_printf (&argv,
1575			"%s addr del dev %s local %s peer %s",
1576			iproute_path,
1577			tt->actual_name,
1578			print_in_addr_t (tt->local, 0, &gc),
1579			print_in_addr_t (tt->remote_netmask, 0, &gc)
1580			);
1581	      }
1582	    else
1583	      {
1584		argv_printf (&argv,
1585			"%s addr del dev %s %s/%d",
1586			iproute_path,
1587			tt->actual_name,
1588			print_in_addr_t (tt->local, 0, &gc),
1589			count_netmask_bits(print_in_addr_t (tt->remote_netmask, 0, &gc))
1590			);
1591	      }
1592#else
1593	    argv_printf (&argv,
1594			"%s %s 0.0.0.0",
1595			IFCONFIG_PATH,
1596			tt->actual_name
1597			);
1598#endif
1599
1600	    argv_msg (M_INFO, &argv);
1601	    openvpn_execve_check (&argv, NULL, 0, "Linux ip addr del failed");
1602
1603	    argv_reset (&argv);
1604	    gc_free (&gc);
1605	  }
1606      close_tun_generic (tt);
1607      free (tt);
1608    }
1609}
1610
1611int
1612write_tun (struct tuntap* tt, uint8_t *buf, int len)
1613{
1614  if (tt->ipv6)
1615    {
1616      struct tun_pi pi;
1617      struct iphdr *iph;
1618      struct iovec vect[2];
1619      int ret;
1620
1621      iph = (struct iphdr *)buf;
1622
1623      pi.flags = 0;
1624
1625      if(iph->version == 6)
1626	pi.proto = htons(ETH_P_IPV6);
1627      else
1628	pi.proto = htons(ETH_P_IP);
1629
1630      vect[0].iov_len = sizeof(pi);
1631      vect[0].iov_base = &pi;
1632      vect[1].iov_len = len;
1633      vect[1].iov_base = buf;
1634
1635      ret = writev(tt->fd, vect, 2);
1636      return(ret - sizeof(pi));
1637    }
1638  else
1639    return write (tt->fd, buf, len);
1640}
1641
1642int
1643read_tun (struct tuntap* tt, uint8_t *buf, int len)
1644{
1645  if (tt->ipv6)
1646    {
1647      struct iovec vect[2];
1648      struct tun_pi pi;
1649      int ret;
1650
1651      vect[0].iov_len = sizeof(pi);
1652      vect[0].iov_base = &pi;
1653      vect[1].iov_len = len;
1654      vect[1].iov_base = buf;
1655
1656      ret = readv(tt->fd, vect, 2);
1657      return(ret - sizeof(pi));
1658    }
1659  else
1660    return read (tt->fd, buf, len);
1661}
1662
1663#elif defined(TARGET_SOLARIS)
1664
1665#ifndef TUNNEWPPA
1666#error I need the symbol TUNNEWPPA from net/if_tun.h
1667#endif
1668
1669void
1670open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1671{
1672  int if_fd, ip_muxid, arp_muxid, arp_fd, ppa = -1;
1673  struct lifreq ifr;
1674  const char *ptr;
1675  const char *ip_node, *arp_node;
1676  const char *dev_tuntap_type;
1677  int link_type;
1678  bool is_tun;
1679  struct strioctl  strioc_if, strioc_ppa;
1680
1681  /* improved generic TUN/TAP driver from
1682   * http://www.whiteboard.ne.jp/~admin2/tuntap/
1683   * has IPv6 support
1684   */
1685  CLEAR(ifr);
1686
1687  if (tt->type == DEV_TYPE_NULL)
1688    {
1689      open_null (tt);
1690      return;
1691    }
1692
1693  if (tt->type == DEV_TYPE_TUN)
1694    {
1695      ip_node = "/dev/udp";
1696      if (!dev_node)
1697	dev_node = "/dev/tun";
1698      dev_tuntap_type = "tun";
1699      link_type = I_PLINK;
1700      is_tun = true;
1701    }
1702  else if (tt->type == DEV_TYPE_TAP)
1703    {
1704      ip_node = "/dev/udp";
1705      if (!dev_node)
1706	dev_node = "/dev/tap";
1707      arp_node = dev_node;
1708      dev_tuntap_type = "tap";
1709      link_type = I_PLINK; /* was: I_LINK */
1710      is_tun = false;
1711    }
1712  else
1713    {
1714      msg (M_FATAL, "I don't recognize device %s as a tun or tap device",
1715	   dev);
1716    }
1717
1718  if ((tt->ip_fd = open (ip_node, O_RDWR, 0)) < 0)
1719    msg (M_ERR, "Can't open %s", ip_node);
1720
1721  if ((tt->fd = open (dev_node, O_RDWR, 0)) < 0)
1722    msg (M_ERR, "Can't open %s", dev_node);
1723
1724  /* get unit number */
1725  if (*dev)
1726    {
1727      ptr = dev;
1728      while (*ptr && !isdigit ((int) *ptr))
1729	ptr++;
1730      ppa = atoi (ptr);
1731    }
1732
1733  /* Assign a new PPA and get its unit number. */
1734  strioc_ppa.ic_cmd = TUNNEWPPA;
1735  strioc_ppa.ic_timout = 0;
1736  strioc_ppa.ic_len = sizeof(ppa);
1737  strioc_ppa.ic_dp = (char *)&ppa;
1738
1739  if ( *ptr == '\0' )		/* no number given, try dynamic */
1740    {
1741      bool found_one = false;
1742      while( ! found_one && ppa < 64 )
1743	{
1744	  int new_ppa = ioctl (tt->fd, I_STR, &strioc_ppa);
1745	  if ( new_ppa >= 0 )
1746	    {
1747	      msg( M_INFO, "open_tun: got dynamic interface '%s%d'", dev_tuntap_type, new_ppa );
1748	      ppa = new_ppa;
1749	      found_one = true;
1750	      break;
1751	    }
1752	  if ( errno != EEXIST )
1753	    msg (M_ERR, "open_tun: unexpected error trying to find free %s interface", dev_tuntap_type );
1754	  ppa++;
1755	}
1756      if ( !found_one )
1757	msg (M_ERR, "open_tun: could not find free %s interface, give up.", dev_tuntap_type );
1758    }
1759  else				/* try this particular one */
1760    {
1761      if ((ppa = ioctl (tt->fd, I_STR, &strioc_ppa)) < 0)
1762        msg (M_ERR, "Can't assign PPA for new interface (%s%d)", dev_tuntap_type, ppa );
1763    }
1764
1765  if ((if_fd = open (dev_node, O_RDWR, 0)) < 0)
1766    msg (M_ERR, "Can't open %s (2)", dev_node);
1767
1768  if (ioctl (if_fd, I_PUSH, "ip") < 0)
1769    msg (M_ERR, "Can't push IP module");
1770
1771  if (tt->type == DEV_TYPE_TUN)
1772    {
1773  /* Assign ppa according to the unit number returned by tun device */
1774  if (ioctl (if_fd, IF_UNITSEL, (char *) &ppa) < 0)
1775    msg (M_ERR, "Can't set PPA %d", ppa);
1776    }
1777
1778  tt->actual_name = (char *) malloc (32);
1779  check_malloc_return (tt->actual_name);
1780
1781  openvpn_snprintf (tt->actual_name, 32, "%s%d", dev_tuntap_type, ppa);
1782
1783  if (tt->type == DEV_TYPE_TAP)
1784    {
1785          if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
1786            msg (M_ERR, "Can't get flags\n");
1787          strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name));
1788          ifr.lifr_ppa = ppa;
1789          /* Assign ppa according to the unit number returned by tun device */
1790          if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
1791            msg (M_ERR, "Can't set PPA %d", ppa);
1792          if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
1793            msg (M_ERR, "Can't get flags\n");
1794          /* Push arp module to if_fd */
1795          if (ioctl (if_fd, I_PUSH, "arp") < 0)
1796            msg (M_ERR, "Can't push ARP module");
1797
1798          /* Pop any modules on the stream */
1799          while (true)
1800            {
1801                 if (ioctl (tt->ip_fd, I_POP, NULL) < 0)
1802                     break;
1803            }
1804          /* Push arp module to ip_fd */
1805          if (ioctl (tt->ip_fd, I_PUSH, "arp") < 0)
1806            msg (M_ERR, "Can't push ARP module\n");
1807
1808          /* Open arp_fd */
1809          if ((arp_fd = open (arp_node, O_RDWR, 0)) < 0)
1810            msg (M_ERR, "Can't open %s\n", arp_node);
1811          /* Push arp module to arp_fd */
1812          if (ioctl (arp_fd, I_PUSH, "arp") < 0)
1813            msg (M_ERR, "Can't push ARP module\n");
1814
1815          /* Set ifname to arp */
1816          strioc_if.ic_cmd = SIOCSLIFNAME;
1817          strioc_if.ic_timout = 0;
1818          strioc_if.ic_len = sizeof(ifr);
1819          strioc_if.ic_dp = (char *)&ifr;
1820          if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
1821              msg (M_ERR, "Can't set ifname to arp\n");
1822          }
1823   }
1824
1825  if ((ip_muxid = ioctl (tt->ip_fd, link_type, if_fd)) < 0)
1826    msg (M_ERR, "Can't link %s device to IP", dev_tuntap_type);
1827
1828  if (tt->type == DEV_TYPE_TAP) {
1829          if ((arp_muxid = ioctl (tt->ip_fd, link_type, arp_fd)) < 0)
1830            msg (M_ERR, "Can't link %s device to ARP", dev_tuntap_type);
1831          close (arp_fd);
1832  }
1833
1834  CLEAR (ifr);
1835  strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name));
1836  ifr.lifr_ip_muxid  = ip_muxid;
1837  if (tt->type == DEV_TYPE_TAP) {
1838          ifr.lifr_arp_muxid = arp_muxid;
1839  }
1840
1841  if (ioctl (tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0)
1842    {
1843      if (tt->type == DEV_TYPE_TAP)
1844        {
1845              ioctl (tt->ip_fd, I_PUNLINK , arp_muxid);
1846        }
1847      ioctl (tt->ip_fd, I_PUNLINK, ip_muxid);
1848      msg (M_ERR, "Can't set multiplexor id");
1849    }
1850
1851  set_nonblock (tt->fd);
1852  set_cloexec (tt->fd);
1853  set_cloexec (tt->ip_fd);
1854
1855  msg (M_INFO, "TUN/TAP device %s opened", tt->actual_name);
1856}
1857
1858static void
1859solaris_close_tun (struct tuntap *tt)
1860{
1861  if (tt)
1862    {
1863      /* IPv6 interfaces need to be 'manually' de-configured */
1864      if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
1865	{
1866	  struct argv argv;
1867	  argv_init (&argv);
1868	  argv_printf( &argv, "%s %s inet6 unplumb",
1869		       IFCONFIG_PATH, tt->actual_name );
1870	  argv_msg (M_INFO, &argv);
1871	  openvpn_execve_check (&argv, NULL, 0, "Solaris ifconfig inet6 unplumb failed");
1872	  argv_reset (&argv);
1873	}
1874
1875      if (tt->ip_fd >= 0)
1876	{
1877          struct lifreq ifr;
1878	  CLEAR (ifr);
1879          strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name));
1880
1881          if (ioctl (tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0)
1882	    msg (M_WARN | M_ERRNO, "Can't get iface flags");
1883
1884          if (ioctl (tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0)
1885	    msg (M_WARN | M_ERRNO, "Can't get multiplexor id");
1886
1887          if (tt->type == DEV_TYPE_TAP)
1888            {
1889                  if (ioctl (tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0)
1890                    msg (M_WARN | M_ERRNO, "Can't unlink interface(arp)");
1891            }
1892
1893          if (ioctl (tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0)
1894            msg (M_WARN | M_ERRNO, "Can't unlink interface(ip)");
1895
1896	  close (tt->ip_fd);
1897	  tt->ip_fd = -1;
1898	}
1899
1900      if (tt->fd >= 0)
1901	{
1902	  close (tt->fd);
1903	  tt->fd = -1;
1904	}
1905    }
1906}
1907
1908/*
1909 * Close TUN device.
1910 */
1911void
1912close_tun (struct tuntap *tt)
1913{
1914  if (tt)
1915    {
1916      solaris_close_tun (tt);
1917
1918      if (tt->actual_name)
1919	free (tt->actual_name);
1920
1921      clear_tuntap (tt);
1922      free (tt);
1923    }
1924}
1925
1926static void
1927solaris_error_close (struct tuntap *tt, const struct env_set *es,
1928                     const char *actual, bool unplumb_inet6 )
1929{
1930  struct argv argv;
1931  argv_init (&argv);
1932
1933  if (unplumb_inet6)
1934    {
1935      argv_printf( &argv, "%s %s inet6 unplumb",
1936		   IFCONFIG_PATH, actual );
1937      argv_msg (M_INFO, &argv);
1938      openvpn_execve_check (&argv, es, 0, "Solaris ifconfig inet6 unplumb failed");
1939    }
1940
1941  argv_printf (&argv,
1942		    "%s %s unplumb",
1943		    IFCONFIG_PATH,
1944		    actual);
1945
1946  argv_msg (M_INFO, &argv);
1947  openvpn_execve_check (&argv, es, 0, "Solaris ifconfig unplumb failed");
1948  close_tun (tt);
1949  msg (M_FATAL, "Solaris ifconfig failed");
1950  argv_reset (&argv);
1951}
1952
1953int
1954write_tun (struct tuntap* tt, uint8_t *buf, int len)
1955{
1956  struct strbuf sbuf;
1957  sbuf.len = len;
1958  sbuf.buf = (char *)buf;
1959  return putmsg (tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
1960}
1961
1962int
1963read_tun (struct tuntap* tt, uint8_t *buf, int len)
1964{
1965  struct strbuf sbuf;
1966  int f = 0;
1967
1968  sbuf.maxlen = len;
1969  sbuf.buf = (char *)buf;
1970  return getmsg (tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
1971}
1972
1973#elif defined(TARGET_OPENBSD)
1974
1975/*
1976 * OpenBSD has a slightly incompatible TUN device from
1977 * the rest of the world, in that it prepends a
1978 * uint32 to the beginning of the IP header
1979 * to designate the protocol (why not just
1980 * look at the version field in the IP header to
1981 * determine v4 or v6?).
1982 *
1983 * We strip off this field on reads and
1984 * put it back on writes.
1985 *
1986 * I have not tested TAP devices on OpenBSD,
1987 * but I have conditionalized the special
1988 * TUN handling code described above to
1989 * go away for TAP devices.
1990 */
1991
1992void
1993open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1994{
1995  open_tun_generic (dev, dev_type, dev_node, true, true, tt);
1996
1997  /* Enable multicast on the interface */
1998  if (tt->fd >= 0)
1999    {
2000      struct tuninfo info;
2001
2002      if (ioctl (tt->fd, TUNGIFINFO, &info) < 0) {
2003	msg (M_WARN | M_ERRNO, "Can't get interface info: %s",
2004	  strerror(errno));
2005      }
2006
2007#ifdef IFF_MULTICAST /* openbsd 4.x doesn't have this */
2008      info.flags |= IFF_MULTICAST;
2009#endif
2010
2011      if (ioctl (tt->fd, TUNSIFINFO, &info) < 0) {
2012	msg (M_WARN | M_ERRNO, "Can't set interface info: %s",
2013	  strerror(errno));
2014      }
2015    }
2016}
2017
2018/* tun(4): "If the device was created by opening /dev/tunN, it will be
2019 *          automatically destroyed.  Devices created via ifconfig(8) are
2020 *          only marked as not running and traffic will be dropped
2021 *          returning EHOSTDOWN."
2022 * --> no special handling should be needed - *but* OpenBSD is misbehaving
2023 * here: if the interface was put in tap mode ("ifconfig tunN link0"), it
2024 * *will* stay around, and needs to be cleaned up manually
2025 */
2026
2027void
2028close_tun (struct tuntap* tt)
2029{
2030  /* only *TAP* devices need destroying, tun devices auto-self-destruct
2031   */
2032  if (tt && (tt->type == DEV_TYPE_TUN || tt->persistent_if ) )
2033    {
2034      close_tun_generic (tt);
2035      free(tt);
2036    }
2037  else if (tt)
2038    {
2039      struct gc_arena gc = gc_new ();
2040      struct argv argv;
2041
2042      /* setup command, close tun dev (clears tt->actual_name!), run command
2043       */
2044
2045      argv_init (&argv);
2046      argv_printf (&argv, "%s %s destroy",
2047                          IFCONFIG_PATH, tt->actual_name);
2048
2049      close_tun_generic (tt);
2050
2051      argv_msg (M_INFO, &argv);
2052      openvpn_execve_check (&argv, NULL, 0, "OpenBSD 'destroy tun interface' failed (non-critical)");
2053
2054      free (tt);
2055    }
2056}
2057
2058static inline int
2059openbsd_modify_read_write_return (int len)
2060{
2061 if (len > 0)
2062    return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
2063  else
2064    return len;
2065}
2066
2067int
2068write_tun (struct tuntap* tt, uint8_t *buf, int len)
2069{
2070  if (tt->type == DEV_TYPE_TUN)
2071    {
2072      u_int32_t type;
2073      struct iovec iv[2];
2074      struct ip *iph;
2075
2076      iph = (struct ip *) buf;
2077
2078      if (tt->ipv6 && iph->ip_v == 6)
2079	type = htonl (AF_INET6);
2080      else
2081	type = htonl (AF_INET);
2082
2083      iv[0].iov_base = &type;
2084      iv[0].iov_len = sizeof (type);
2085      iv[1].iov_base = buf;
2086      iv[1].iov_len = len;
2087
2088      return openbsd_modify_read_write_return (writev (tt->fd, iv, 2));
2089    }
2090  else
2091    return write (tt->fd, buf, len);
2092}
2093
2094int
2095read_tun (struct tuntap* tt, uint8_t *buf, int len)
2096{
2097  if (tt->type == DEV_TYPE_TUN)
2098    {
2099      u_int32_t type;
2100      struct iovec iv[2];
2101
2102      iv[0].iov_base = &type;
2103      iv[0].iov_len = sizeof (type);
2104      iv[1].iov_base = buf;
2105      iv[1].iov_len = len;
2106
2107      return openbsd_modify_read_write_return (readv (tt->fd, iv, 2));
2108    }
2109  else
2110    return read (tt->fd, buf, len);
2111}
2112
2113#elif defined(TARGET_NETBSD)
2114
2115/*
2116 * NetBSD before 4.0 does not support IPv6 on tun out of the box,
2117 * but there exists a patch (sys/net/if_tun.c, 1.79->1.80, see PR 32944).
2118 *
2119 * NetBSD 4.0 and up do, but we need to put the tun interface into
2120 * "multi_af" mode, which will prepend the address family to all packets
2121 * (same as OpenBSD and FreeBSD).  If this is not enabled, the kernel
2122 * silently drops all IPv6 packets on output and gets confused on input.
2123 *
2124 * On earlier versions, multi_af is not available at all, so we have
2125 * two different NetBSD code variants here :-(
2126 *
2127 */
2128
2129void
2130open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
2131{
2132#ifdef NETBSD_MULTI_AF
2133    open_tun_generic (dev, dev_type, dev_node, true, true, tt);
2134#else
2135    open_tun_generic (dev, dev_type, dev_node, false, true, tt);
2136#endif
2137
2138    if (tt->fd >= 0)
2139      {
2140        int i = IFF_POINTOPOINT|IFF_MULTICAST;
2141        ioctl (tt->fd, TUNSIFMODE, &i);  /* multicast on */
2142        i = 0;
2143        ioctl (tt->fd, TUNSLMODE, &i);   /* link layer mode off */
2144
2145#ifdef NETBSD_MULTI_AF
2146	if ( tt->type == DEV_TYPE_TUN )
2147	  {
2148	    i = 1;
2149	    if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0) 	/* multi-af mode on */
2150	      {
2151		msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno));
2152	      }
2153	  }
2154#endif
2155      }
2156}
2157
2158/* the current way OpenVPN handles tun devices on NetBSD leads to
2159 * lingering tunX interfaces after close -> for a full cleanup, they
2160 * need to be explicitely destroyed
2161 */
2162void
2163close_tun (struct tuntap *tt)
2164{
2165  /* only tun devices need destroying, tap devices auto-self-destruct
2166   */
2167  if (tt && ( tt->type != DEV_TYPE_TUN || tt->persistent_if ) )
2168    {
2169      close_tun_generic (tt);
2170      free(tt);
2171    }
2172  else if (tt)
2173    {
2174      struct gc_arena gc = gc_new ();
2175      struct argv argv;
2176
2177      /* setup command, close tun dev (clears tt->actual_name!), run command
2178       */
2179
2180      argv_init (&argv);
2181      argv_printf (&argv, "%s %s destroy",
2182                          IFCONFIG_PATH, tt->actual_name);
2183
2184      close_tun_generic (tt);
2185
2186      argv_msg (M_INFO, &argv);
2187      openvpn_execve_check (&argv, NULL, 0, "NetBSD 'destroy tun interface' failed (non-critical)");
2188
2189      free (tt);
2190    }
2191}
2192
2193#ifdef NETBSD_MULTI_AF
2194
2195static inline int
2196netbsd_modify_read_write_return (int len)
2197{
2198  if (len > 0)
2199    return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
2200  else
2201    return len;
2202}
2203
2204int
2205write_tun (struct tuntap* tt, uint8_t *buf, int len)
2206{
2207  if (tt->type == DEV_TYPE_TUN)
2208    {
2209      u_int32_t type;
2210      struct iovec iv[2];
2211      struct openvpn_iphdr *iph;
2212
2213      iph = (struct openvpn_iphdr *) buf;
2214
2215      if (tt->ipv6 && OPENVPN_IPH_GET_VER(iph->version_len) == 6)
2216        type = htonl (AF_INET6);
2217      else
2218        type = htonl (AF_INET);
2219
2220      iv[0].iov_base = (char *)&type;
2221      iv[0].iov_len = sizeof (type);
2222      iv[1].iov_base = buf;
2223      iv[1].iov_len = len;
2224
2225      return netbsd_modify_read_write_return (writev (tt->fd, iv, 2));
2226    }
2227  else
2228    return write (tt->fd, buf, len);
2229}
2230
2231int
2232read_tun (struct tuntap* tt, uint8_t *buf, int len)
2233{
2234  if (tt->type == DEV_TYPE_TUN)
2235    {
2236      u_int32_t type;
2237      struct iovec iv[2];
2238
2239      iv[0].iov_base = (char *)&type;
2240      iv[0].iov_len = sizeof (type);
2241      iv[1].iov_base = buf;
2242      iv[1].iov_len = len;
2243
2244      return netbsd_modify_read_write_return (readv (tt->fd, iv, 2));
2245    }
2246  else
2247    return read (tt->fd, buf, len);
2248}
2249
2250#else	/* not NETBSD_MULTI_AF -> older code, IPv4 only */
2251
2252int
2253write_tun (struct tuntap* tt, uint8_t *buf, int len)
2254{
2255    return write (tt->fd, buf, len);
2256}
2257
2258int
2259read_tun (struct tuntap* tt, uint8_t *buf, int len)
2260{
2261    return read (tt->fd, buf, len);
2262}
2263#endif	/* NETBSD_MULTI_AF */
2264
2265#elif defined(TARGET_FREEBSD)
2266
2267static inline int
2268freebsd_modify_read_write_return (int len)
2269{
2270  if (len > 0)
2271    return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
2272  else
2273    return len;
2274}
2275
2276void
2277open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
2278{
2279  open_tun_generic (dev, dev_type, dev_node, true, true, tt);
2280
2281  if (tt->fd >= 0 && tt->type == DEV_TYPE_TUN)
2282    {
2283      int i = IFF_POINTOPOINT | IFF_MULTICAST;
2284
2285      if (ioctl (tt->fd, TUNSIFMODE, &i) < 0) {
2286	msg (M_WARN | M_ERRNO, "ioctl(TUNSIFMODE): %s", strerror(errno));
2287      }
2288      i = 1;
2289      if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0) {
2290	msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno));
2291      }
2292    }
2293}
2294
2295/* tun(4): "These network interfaces persist until the if_tun.ko module is
2296 *          unloaded, or until removed with the ifconfig(8) command."
2297 *          (verified for FreeBSD 6.3, 7.4, 8.2 and 9, same for tap(4))
2298 *
2299 * so, to avoid lingering tun/tap interfaces after OpenVPN quits,
2300 * we need to call "ifconfig ... destroy" for cleanup
2301 */
2302void
2303close_tun (struct tuntap *tt)
2304{
2305  if (tt && tt->persistent_if )		/* keep pre-existing if around */
2306    {
2307      close_tun_generic (tt);
2308      free (tt);
2309    }
2310  else if (tt)				/* close and destroy */
2311    {
2312      struct gc_arena gc = gc_new ();
2313      struct argv argv;
2314
2315      /* setup command, close tun dev (clears tt->actual_name!), run command
2316       */
2317
2318      argv_init (&argv);
2319      argv_printf (&argv, "%s %s destroy",
2320                          IFCONFIG_PATH, tt->actual_name);
2321
2322      close_tun_generic (tt);
2323
2324      argv_msg (M_INFO, &argv);
2325      openvpn_execve_check (&argv, NULL, 0, "FreeBSD 'destroy tun interface' failed (non-critical)");
2326
2327      free (tt);
2328    }
2329}
2330
2331int
2332write_tun (struct tuntap* tt, uint8_t *buf, int len)
2333{
2334  if (tt->type == DEV_TYPE_TUN)
2335    {
2336      u_int32_t type;
2337      struct iovec iv[2];
2338      struct ip *iph;
2339
2340      iph = (struct ip *) buf;
2341
2342      if (tt->ipv6 && iph->ip_v == 6)
2343        type = htonl (AF_INET6);
2344      else
2345        type = htonl (AF_INET);
2346
2347      iv[0].iov_base = (char *)&type;
2348      iv[0].iov_len = sizeof (type);
2349      iv[1].iov_base = buf;
2350      iv[1].iov_len = len;
2351
2352      return freebsd_modify_read_write_return (writev (tt->fd, iv, 2));
2353    }
2354  else
2355    return write (tt->fd, buf, len);
2356}
2357
2358int
2359read_tun (struct tuntap* tt, uint8_t *buf, int len)
2360{
2361  if (tt->type == DEV_TYPE_TUN)
2362    {
2363      u_int32_t type;
2364      struct iovec iv[2];
2365
2366      iv[0].iov_base = (char *)&type;
2367      iv[0].iov_len = sizeof (type);
2368      iv[1].iov_base = buf;
2369      iv[1].iov_len = len;
2370
2371      return freebsd_modify_read_write_return (readv (tt->fd, iv, 2));
2372    }
2373  else
2374    return read (tt->fd, buf, len);
2375}
2376
2377#elif defined(TARGET_DRAGONFLY)
2378
2379static inline int
2380dragonfly_modify_read_write_return (int len)
2381{
2382  if (len > 0)
2383    return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
2384  else
2385    return len;
2386}
2387
2388void
2389open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
2390{
2391  open_tun_generic (dev, dev_type, dev_node, true, true, tt);
2392
2393  if (tt->fd >= 0)
2394    {
2395      int i = 0;
2396
2397      /* Disable extended modes */
2398      ioctl (tt->fd, TUNSLMODE, &i);
2399      i = 1;
2400      ioctl (tt->fd, TUNSIFHEAD, &i);
2401    }
2402}
2403
2404void
2405close_tun (struct tuntap *tt)
2406{
2407  if (tt)
2408    {
2409      close_tun_generic (tt);
2410      free (tt);
2411    }
2412}
2413
2414int
2415write_tun (struct tuntap* tt, uint8_t *buf, int len)
2416{
2417  if (tt->type == DEV_TYPE_TUN)
2418    {
2419      u_int32_t type;
2420      struct iovec iv[2];
2421      struct ip *iph;
2422
2423      iph = (struct ip *) buf;
2424
2425      if (tt->ipv6 && iph->ip_v == 6)
2426        type = htonl (AF_INET6);
2427      else
2428        type = htonl (AF_INET);
2429
2430      iv[0].iov_base = (char *)&type;
2431      iv[0].iov_len = sizeof (type);
2432      iv[1].iov_base = buf;
2433      iv[1].iov_len = len;
2434
2435      return dragonfly_modify_read_write_return (writev (tt->fd, iv, 2));
2436    }
2437  else
2438    return write (tt->fd, buf, len);
2439}
2440
2441int
2442read_tun (struct tuntap* tt, uint8_t *buf, int len)
2443{
2444  if (tt->type == DEV_TYPE_TUN)
2445    {
2446      u_int32_t type;
2447      struct iovec iv[2];
2448
2449      iv[0].iov_base = (char *)&type;
2450      iv[0].iov_len = sizeof (type);
2451      iv[1].iov_base = buf;
2452      iv[1].iov_len = len;
2453
2454      return dragonfly_modify_read_write_return (readv (tt->fd, iv, 2));
2455    }
2456  else
2457    return read (tt->fd, buf, len);
2458}
2459
2460#elif defined(TARGET_DARWIN)
2461
2462/* Darwin (MacOS X) is mostly "just use the generic stuff", but there
2463 * is always one caveat...:
2464 *
2465 * If IPv6 is configured, and the tun device is closed, the IPv6 address
2466 * configured to the tun interface changes to a lingering /128 route
2467 * pointing to lo0.  Need to unconfigure...  (observed on 10.5)
2468 */
2469
2470void
2471open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
2472{
2473  open_tun_generic (dev, dev_type, dev_node, true, true, tt);
2474}
2475
2476void
2477close_tun (struct tuntap* tt)
2478{
2479  if (tt)
2480    {
2481      struct gc_arena gc = gc_new ();
2482      struct argv argv;
2483      argv_init (&argv);
2484
2485      if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
2486	{
2487	  const char * ifconfig_ipv6_local =
2488				print_in6_addr (tt->local_ipv6, 0, &gc);
2489
2490          argv_printf (&argv, "%s delete -inet6 %s",
2491                              ROUTE_PATH, ifconfig_ipv6_local );
2492	  argv_msg (M_INFO, &argv);
2493	  openvpn_execve_check (&argv, NULL, 0, "MacOS X 'remove inet6 route' failed (non-critical)");
2494	}
2495
2496      close_tun_generic (tt);
2497      free (tt);
2498      argv_reset (&argv);
2499      gc_free (&gc);
2500    }
2501}
2502
2503int
2504write_tun (struct tuntap* tt, uint8_t *buf, int len)
2505{
2506  return write (tt->fd, buf, len);
2507}
2508
2509int
2510read_tun (struct tuntap* tt, uint8_t *buf, int len)
2511{
2512  return read (tt->fd, buf, len);
2513}
2514
2515#elif defined(WIN32)
2516
2517int
2518tun_read_queue (struct tuntap *tt, int maxsize)
2519{
2520  if (tt->reads.iostate == IOSTATE_INITIAL)
2521    {
2522      DWORD len;
2523      BOOL status;
2524      int err;
2525
2526      /* reset buf to its initial state */
2527      tt->reads.buf = tt->reads.buf_init;
2528
2529      len = maxsize ? maxsize : BLEN (&tt->reads.buf);
2530      ASSERT (len <= BLEN (&tt->reads.buf));
2531
2532      /* the overlapped read will signal this event on I/O completion */
2533      ASSERT (ResetEvent (tt->reads.overlapped.hEvent));
2534
2535      status = ReadFile(
2536		      tt->hand,
2537		      BPTR (&tt->reads.buf),
2538		      len,
2539		      &tt->reads.size,
2540		      &tt->reads.overlapped
2541		      );
2542
2543      if (status) /* operation completed immediately? */
2544	{
2545	  /* since we got an immediate return, we must signal the event object ourselves */
2546	  ASSERT (SetEvent (tt->reads.overlapped.hEvent));
2547
2548	  tt->reads.iostate = IOSTATE_IMMEDIATE_RETURN;
2549	  tt->reads.status = 0;
2550
2551	  dmsg (D_WIN32_IO, "WIN32 I/O: TAP Read immediate return [%d,%d]",
2552	       (int) len,
2553	       (int) tt->reads.size);
2554	}
2555      else
2556	{
2557	  err = GetLastError ();
2558	  if (err == ERROR_IO_PENDING) /* operation queued? */
2559	    {
2560	      tt->reads.iostate = IOSTATE_QUEUED;
2561	      tt->reads.status = err;
2562	      dmsg (D_WIN32_IO, "WIN32 I/O: TAP Read queued [%d]",
2563		   (int) len);
2564	    }
2565	  else /* error occurred */
2566	    {
2567	      struct gc_arena gc = gc_new ();
2568	      ASSERT (SetEvent (tt->reads.overlapped.hEvent));
2569	      tt->reads.iostate = IOSTATE_IMMEDIATE_RETURN;
2570	      tt->reads.status = err;
2571	      dmsg (D_WIN32_IO, "WIN32 I/O: TAP Read error [%d] : %s",
2572		   (int) len,
2573		   strerror_win32 (status, &gc));
2574	      gc_free (&gc);
2575	    }
2576	}
2577    }
2578  return tt->reads.iostate;
2579}
2580
2581int
2582tun_write_queue (struct tuntap *tt, struct buffer *buf)
2583{
2584  if (tt->writes.iostate == IOSTATE_INITIAL)
2585    {
2586      BOOL status;
2587      int err;
2588
2589      /* make a private copy of buf */
2590      tt->writes.buf = tt->writes.buf_init;
2591      tt->writes.buf.len = 0;
2592      ASSERT (buf_copy (&tt->writes.buf, buf));
2593
2594      /* the overlapped write will signal this event on I/O completion */
2595      ASSERT (ResetEvent (tt->writes.overlapped.hEvent));
2596
2597      status = WriteFile(
2598			tt->hand,
2599			BPTR (&tt->writes.buf),
2600			BLEN (&tt->writes.buf),
2601			&tt->writes.size,
2602			&tt->writes.overlapped
2603			);
2604
2605      if (status) /* operation completed immediately? */
2606	{
2607	  tt->writes.iostate = IOSTATE_IMMEDIATE_RETURN;
2608
2609	  /* since we got an immediate return, we must signal the event object ourselves */
2610	  ASSERT (SetEvent (tt->writes.overlapped.hEvent));
2611
2612	  tt->writes.status = 0;
2613
2614	  dmsg (D_WIN32_IO, "WIN32 I/O: TAP Write immediate return [%d,%d]",
2615	       BLEN (&tt->writes.buf),
2616	       (int) tt->writes.size);
2617	}
2618      else
2619	{
2620	  err = GetLastError ();
2621	  if (err == ERROR_IO_PENDING) /* operation queued? */
2622	    {
2623	      tt->writes.iostate = IOSTATE_QUEUED;
2624	      tt->writes.status = err;
2625	      dmsg (D_WIN32_IO, "WIN32 I/O: TAP Write queued [%d]",
2626		   BLEN (&tt->writes.buf));
2627	    }
2628	  else /* error occurred */
2629	    {
2630	      struct gc_arena gc = gc_new ();
2631	      ASSERT (SetEvent (tt->writes.overlapped.hEvent));
2632	      tt->writes.iostate = IOSTATE_IMMEDIATE_RETURN;
2633	      tt->writes.status = err;
2634	      dmsg (D_WIN32_IO, "WIN32 I/O: TAP Write error [%d] : %s",
2635		   BLEN (&tt->writes.buf),
2636		   strerror_win32 (err, &gc));
2637	      gc_free (&gc);
2638	    }
2639	}
2640    }
2641  return tt->writes.iostate;
2642}
2643
2644int
2645tun_finalize (
2646	      HANDLE h,
2647	      struct overlapped_io *io,
2648	      struct buffer *buf)
2649{
2650  int ret = -1;
2651  BOOL status;
2652
2653  switch (io->iostate)
2654    {
2655    case IOSTATE_QUEUED:
2656      status = GetOverlappedResult(
2657				   h,
2658				   &io->overlapped,
2659				   &io->size,
2660				   FALSE
2661				   );
2662      if (status)
2663	{
2664	  /* successful return for a queued operation */
2665	  if (buf)
2666	    *buf = io->buf;
2667	  ret = io->size;
2668	  io->iostate = IOSTATE_INITIAL;
2669	  ASSERT (ResetEvent (io->overlapped.hEvent));
2670	  dmsg (D_WIN32_IO, "WIN32 I/O: TAP Completion success [%d]", ret);
2671	}
2672      else
2673	{
2674	  /* error during a queued operation */
2675	  ret = -1;
2676	  if (GetLastError() != ERROR_IO_INCOMPLETE)
2677	    {
2678	      /* if no error (i.e. just not finished yet),
2679		 then DON'T execute this code */
2680	      io->iostate = IOSTATE_INITIAL;
2681	      ASSERT (ResetEvent (io->overlapped.hEvent));
2682	      msg (D_WIN32_IO | M_ERRNO, "WIN32 I/O: TAP Completion error");
2683	    }
2684	}
2685      break;
2686
2687    case IOSTATE_IMMEDIATE_RETURN:
2688      io->iostate = IOSTATE_INITIAL;
2689      ASSERT (ResetEvent (io->overlapped.hEvent));
2690      if (io->status)
2691	{
2692	  /* error return for a non-queued operation */
2693	  SetLastError (io->status);
2694	  ret = -1;
2695	  msg (D_WIN32_IO | M_ERRNO, "WIN32 I/O: TAP Completion non-queued error");
2696	}
2697      else
2698	{
2699	  /* successful return for a non-queued operation */
2700	  if (buf)
2701	    *buf = io->buf;
2702	  ret = io->size;
2703	  dmsg (D_WIN32_IO, "WIN32 I/O: TAP Completion non-queued success [%d]", ret);
2704	}
2705      break;
2706
2707    case IOSTATE_INITIAL: /* were we called without proper queueing? */
2708      SetLastError (ERROR_INVALID_FUNCTION);
2709      ret = -1;
2710      dmsg (D_WIN32_IO, "WIN32 I/O: TAP Completion BAD STATE");
2711      break;
2712
2713    default:
2714      ASSERT (0);
2715    }
2716
2717  if (buf)
2718    buf->len = ret;
2719  return ret;
2720}
2721
2722const struct tap_reg *
2723get_tap_reg (struct gc_arena *gc)
2724{
2725  HKEY adapter_key;
2726  LONG status;
2727  DWORD len;
2728  struct tap_reg *first = NULL;
2729  struct tap_reg *last = NULL;
2730  int i = 0;
2731
2732  status = RegOpenKeyEx(
2733			HKEY_LOCAL_MACHINE,
2734			ADAPTER_KEY,
2735			0,
2736			KEY_READ,
2737			&adapter_key);
2738
2739  if (status != ERROR_SUCCESS)
2740    msg (M_FATAL, "Error opening registry key: %s", ADAPTER_KEY);
2741
2742  while (true)
2743    {
2744      char enum_name[256];
2745      char unit_string[256];
2746      HKEY unit_key;
2747      char component_id_string[] = "ComponentId";
2748      char component_id[256];
2749      char net_cfg_instance_id_string[] = "NetCfgInstanceId";
2750      char net_cfg_instance_id[256];
2751      DWORD data_type;
2752
2753      len = sizeof (enum_name);
2754      status = RegEnumKeyEx(
2755			    adapter_key,
2756			    i,
2757			    enum_name,
2758			    &len,
2759			    NULL,
2760			    NULL,
2761			    NULL,
2762			    NULL);
2763      if (status == ERROR_NO_MORE_ITEMS)
2764	break;
2765      else if (status != ERROR_SUCCESS)
2766	msg (M_FATAL, "Error enumerating registry subkeys of key: %s",
2767	     ADAPTER_KEY);
2768
2769      openvpn_snprintf (unit_string, sizeof(unit_string), "%s\\%s",
2770			ADAPTER_KEY, enum_name);
2771
2772      status = RegOpenKeyEx(
2773			    HKEY_LOCAL_MACHINE,
2774			    unit_string,
2775			    0,
2776			    KEY_READ,
2777			    &unit_key);
2778
2779      if (status != ERROR_SUCCESS)
2780	dmsg (D_REGISTRY, "Error opening registry key: %s", unit_string);
2781      else
2782	{
2783	  len = sizeof (component_id);
2784	  status = RegQueryValueEx(
2785				   unit_key,
2786				   component_id_string,
2787				   NULL,
2788				   &data_type,
2789				   component_id,
2790				   &len);
2791
2792	  if (status != ERROR_SUCCESS || data_type != REG_SZ)
2793	    dmsg (D_REGISTRY, "Error opening registry key: %s\\%s",
2794		 unit_string, component_id_string);
2795	  else
2796	    {
2797	      len = sizeof (net_cfg_instance_id);
2798	      status = RegQueryValueEx(
2799				       unit_key,
2800				       net_cfg_instance_id_string,
2801				       NULL,
2802				       &data_type,
2803				       net_cfg_instance_id,
2804				       &len);
2805
2806	      if (status == ERROR_SUCCESS && data_type == REG_SZ)
2807		{
2808		  if (!strcmp (component_id, TAP_WIN_COMPONENT_ID))
2809		    {
2810		      struct tap_reg *reg;
2811		      ALLOC_OBJ_CLEAR_GC (reg, struct tap_reg, gc);
2812		      reg->guid = string_alloc (net_cfg_instance_id, gc);
2813
2814		      /* link into return list */
2815		      if (!first)
2816			first = reg;
2817		      if (last)
2818			last->next = reg;
2819		      last = reg;
2820		    }
2821		}
2822	    }
2823	  RegCloseKey (unit_key);
2824	}
2825      ++i;
2826    }
2827
2828  RegCloseKey (adapter_key);
2829  return first;
2830}
2831
2832const struct panel_reg *
2833get_panel_reg (struct gc_arena *gc)
2834{
2835  LONG status;
2836  HKEY network_connections_key;
2837  DWORD len;
2838  struct panel_reg *first = NULL;
2839  struct panel_reg *last = NULL;
2840  int i = 0;
2841
2842  status = RegOpenKeyEx(
2843			HKEY_LOCAL_MACHINE,
2844			NETWORK_CONNECTIONS_KEY,
2845			0,
2846			KEY_READ,
2847			&network_connections_key);
2848
2849  if (status != ERROR_SUCCESS)
2850    msg (M_FATAL, "Error opening registry key: %s", NETWORK_CONNECTIONS_KEY);
2851
2852  while (true)
2853    {
2854      char enum_name[256];
2855      char connection_string[256];
2856      HKEY connection_key;
2857      char name_data[256];
2858      DWORD name_type;
2859      const char name_string[] = "Name";
2860
2861      len = sizeof (enum_name);
2862      status = RegEnumKeyEx(
2863			    network_connections_key,
2864			    i,
2865			    enum_name,
2866			    &len,
2867			    NULL,
2868			    NULL,
2869			    NULL,
2870			    NULL);
2871      if (status == ERROR_NO_MORE_ITEMS)
2872	break;
2873      else if (status != ERROR_SUCCESS)
2874	msg (M_FATAL, "Error enumerating registry subkeys of key: %s",
2875	     NETWORK_CONNECTIONS_KEY);
2876
2877      openvpn_snprintf (connection_string, sizeof(connection_string),
2878			"%s\\%s\\Connection",
2879			NETWORK_CONNECTIONS_KEY, enum_name);
2880
2881      status = RegOpenKeyEx(
2882			    HKEY_LOCAL_MACHINE,
2883			    connection_string,
2884			    0,
2885			    KEY_READ,
2886			    &connection_key);
2887
2888      if (status != ERROR_SUCCESS)
2889	dmsg (D_REGISTRY, "Error opening registry key: %s", connection_string);
2890      else
2891	{
2892	  len = sizeof (name_data);
2893	  status = RegQueryValueEx(
2894				   connection_key,
2895				   name_string,
2896				   NULL,
2897				   &name_type,
2898				   name_data,
2899				   &len);
2900
2901	  if (status != ERROR_SUCCESS || name_type != REG_SZ)
2902	    dmsg (D_REGISTRY, "Error opening registry key: %s\\%s\\%s",
2903		 NETWORK_CONNECTIONS_KEY, connection_string, name_string);
2904	  else
2905	    {
2906	      struct panel_reg *reg;
2907
2908	      ALLOC_OBJ_CLEAR_GC (reg, struct panel_reg, gc);
2909	      reg->name = string_alloc (name_data, gc);
2910	      reg->guid = string_alloc (enum_name, gc);
2911
2912	      /* link into return list */
2913	      if (!first)
2914		first = reg;
2915	      if (last)
2916		last->next = reg;
2917	      last = reg;
2918	    }
2919	  RegCloseKey (connection_key);
2920	}
2921      ++i;
2922    }
2923
2924  RegCloseKey (network_connections_key);
2925
2926  return first;
2927}
2928
2929/*
2930 * Check that two addresses are part of the same 255.255.255.252 subnet.
2931 */
2932void
2933verify_255_255_255_252 (in_addr_t local, in_addr_t remote)
2934{
2935  struct gc_arena gc = gc_new ();
2936  const unsigned int mask = 3;
2937  const char *err = NULL;
2938
2939  if (local == remote)
2940    {
2941      err = "must be different";
2942      goto error;
2943    }
2944  if ((local & (~mask)) != (remote & (~mask)))
2945    {
2946      err = "must exist within the same 255.255.255.252 subnet.  This is a limitation of --dev tun when used with the TAP-WIN32 driver";
2947      goto error;
2948    }
2949  if ((local & mask) == 0
2950      || (local & mask) == 3
2951      || (remote & mask) == 0
2952      || (remote & mask) == 3)
2953    {
2954      err = "cannot use the first or last address within a given 255.255.255.252 subnet.  This is a limitation of --dev tun when used with the TAP-WIN32 driver";
2955      goto error;
2956    }
2957
2958  gc_free (&gc);
2959  return;
2960
2961 error:
2962  msg (M_FATAL, "There is a problem in your selection of --ifconfig endpoints [local=%s, remote=%s].  The local and remote VPN endpoints %s.  Try '" PACKAGE " --show-valid-subnets' option for more info.",
2963       print_in_addr_t (local, 0, &gc),
2964       print_in_addr_t (remote, 0, &gc),
2965       err);
2966  gc_free (&gc);
2967}
2968
2969void show_valid_win32_tun_subnets (void)
2970{
2971  int i;
2972  int col = 0;
2973
2974  printf ("On Windows, point-to-point IP support (i.e. --dev tun)\n");
2975  printf ("is emulated by the TAP-Windows driver.  The major limitation\n");
2976  printf ("imposed by this approach is that the --ifconfig local and\n");
2977  printf ("remote endpoints must be part of the same 255.255.255.252\n");
2978  printf ("subnet.  The following list shows examples of endpoint\n");
2979  printf ("pairs which satisfy this requirement.  Only the final\n");
2980  printf ("component of the IP address pairs is at issue.\n\n");
2981  printf ("As an example, the following option would be correct:\n");
2982  printf ("    --ifconfig 10.7.0.5 10.7.0.6 (on host A)\n");
2983  printf ("    --ifconfig 10.7.0.6 10.7.0.5 (on host B)\n");
2984  printf ("because [5,6] is part of the below list.\n\n");
2985
2986  for (i = 0; i < 256; i += 4)
2987    {
2988      printf("[%3d,%3d] ", i+1, i+2);
2989      if (++col > 4)
2990	{
2991	  col = 0;
2992	  printf ("\n");
2993	}
2994    }
2995  if (col)
2996    printf ("\n");
2997}
2998
2999void
3000show_tap_win_adapters (int msglev, int warnlev)
3001{
3002  struct gc_arena gc = gc_new ();
3003
3004  bool warn_panel_null = false;
3005  bool warn_panel_dup = false;
3006  bool warn_tap_dup = false;
3007
3008  int links;
3009
3010  const struct tap_reg *tr;
3011  const struct tap_reg *tr1;
3012  const struct panel_reg *pr;
3013
3014  const struct tap_reg *tap_reg = get_tap_reg (&gc);
3015  const struct panel_reg *panel_reg = get_panel_reg (&gc);
3016
3017  msg (msglev, "Available TAP-WIN32 adapters [name, GUID]:");
3018
3019  /* loop through each TAP-Windows adapter registry entry */
3020  for (tr = tap_reg; tr != NULL; tr = tr->next)
3021    {
3022      links = 0;
3023
3024      /* loop through each network connections entry in the control panel */
3025      for (pr = panel_reg; pr != NULL; pr = pr->next)
3026	{
3027	  if (!strcmp (tr->guid, pr->guid))
3028	    {
3029	      msg (msglev, "'%s' %s", pr->name, tr->guid);
3030	      ++links;
3031	    }
3032	}
3033
3034      if (links > 1)
3035	{
3036	  warn_panel_dup = true;
3037	}
3038      else if (links == 0)
3039	{
3040	  /* a TAP adapter exists without a link from the network
3041	     connections control panel */
3042	  warn_panel_null = true;
3043	  msg (msglev, "[NULL] %s", tr->guid);
3044	}
3045    }
3046
3047  /* check for TAP-Windows adapter duplicated GUIDs */
3048  for (tr = tap_reg; tr != NULL; tr = tr->next)
3049    {
3050      for (tr1 = tap_reg; tr1 != NULL; tr1 = tr1->next)
3051	{
3052	  if (tr != tr1 && !strcmp (tr->guid, tr1->guid))
3053	    warn_tap_dup = true;
3054	}
3055    }
3056
3057  /* warn on registry inconsistencies */
3058  if (warn_tap_dup)
3059    msg (warnlev, "WARNING: Some TAP-Windows adapters have duplicate GUIDs");
3060
3061  if (warn_panel_dup)
3062    msg (warnlev, "WARNING: Some TAP-Windows adapters have duplicate links from the Network Connections control panel");
3063
3064  if (warn_panel_null)
3065    msg (warnlev, "WARNING: Some TAP-Windows adapters have no link from the Network Connections control panel");
3066
3067  gc_free (&gc);
3068}
3069
3070/*
3071 * Confirm that GUID is a TAP-Windows adapter.
3072 */
3073static bool
3074is_tap_win (const char *guid, const struct tap_reg *tap_reg)
3075{
3076  const struct tap_reg *tr;
3077
3078  for (tr = tap_reg; tr != NULL; tr = tr->next)
3079    {
3080      if (guid && !strcmp (tr->guid, guid))
3081	return true;
3082    }
3083
3084  return false;
3085}
3086
3087static const char *
3088guid_to_name (const char *guid, const struct panel_reg *panel_reg)
3089{
3090  const struct panel_reg *pr;
3091
3092  for (pr = panel_reg; pr != NULL; pr = pr->next)
3093    {
3094      if (guid && !strcmp (pr->guid, guid))
3095	return pr->name;
3096    }
3097
3098  return NULL;
3099}
3100
3101static const char *
3102name_to_guid (const char *name, const struct tap_reg *tap_reg, const struct panel_reg *panel_reg)
3103{
3104  const struct panel_reg *pr;
3105
3106  for (pr = panel_reg; pr != NULL; pr = pr->next)
3107    {
3108      if (name && !strcmp (pr->name, name) && is_tap_win (pr->guid, tap_reg))
3109	return pr->guid;
3110    }
3111
3112  return NULL;
3113}
3114
3115static void
3116at_least_one_tap_win (const struct tap_reg *tap_reg)
3117{
3118  if (!tap_reg)
3119    msg (M_FATAL, "There are no TAP-Windows adapters on this system.  You should be able to create a TAP-Windows adapter by going to Start -> All Programs -> " PACKAGE_NAME " -> Add a new TAP-Windows virtual ethernet adapter.");
3120}
3121
3122/*
3123 * Get an adapter GUID and optional actual_name from the
3124 * registry for the TAP device # = device_number.
3125 */
3126static const char *
3127get_unspecified_device_guid (const int device_number,
3128		             char *actual_name,
3129		             int actual_name_size,
3130			     const struct tap_reg *tap_reg_src,
3131			     const struct panel_reg *panel_reg_src,
3132		             struct gc_arena *gc)
3133{
3134  const struct tap_reg *tap_reg = tap_reg_src;
3135  struct buffer ret = clear_buf ();
3136  struct buffer actual = clear_buf ();
3137  int i;
3138
3139  ASSERT (device_number >= 0);
3140
3141  /* Make sure we have at least one TAP adapter */
3142  if (!tap_reg)
3143    return NULL;
3144
3145  /* The actual_name output buffer may be NULL */
3146  if (actual_name)
3147    {
3148      ASSERT (actual_name_size > 0);
3149      buf_set_write (&actual, actual_name, actual_name_size);
3150    }
3151
3152  /* Move on to specified device number */
3153  for (i = 0; i < device_number; i++)
3154    {
3155      tap_reg = tap_reg->next;
3156      if (!tap_reg)
3157	return NULL;
3158    }
3159
3160  /* Save Network Panel name (if exists) in actual_name */
3161  if (actual_name)
3162    {
3163      const char *act = guid_to_name (tap_reg->guid, panel_reg_src);
3164      if (act)
3165	buf_printf (&actual, "%s", act);
3166      else
3167	buf_printf (&actual, "%s", tap_reg->guid);
3168    }
3169
3170  /* Save GUID for return value */
3171  ret = alloc_buf_gc (256, gc);
3172  buf_printf (&ret, "%s", tap_reg->guid);
3173  return BSTR (&ret);
3174}
3175
3176/*
3177 * Lookup a --dev-node adapter name in the registry
3178 * returning the GUID and optional actual_name.
3179 */
3180static const char *
3181get_device_guid (const char *name,
3182		 char *actual_name,
3183		 int actual_name_size,
3184		 const struct tap_reg *tap_reg,
3185		 const struct panel_reg *panel_reg,
3186		 struct gc_arena *gc)
3187{
3188  struct buffer ret = alloc_buf_gc (256, gc);
3189  struct buffer actual = clear_buf ();
3190
3191  /* Make sure we have at least one TAP adapter */
3192  if (!tap_reg)
3193    return NULL;
3194
3195  /* The actual_name output buffer may be NULL */
3196  if (actual_name)
3197    {
3198      ASSERT (actual_name_size > 0);
3199      buf_set_write (&actual, actual_name, actual_name_size);
3200    }
3201
3202  /* Check if GUID was explicitly specified as --dev-node parameter */
3203  if (is_tap_win (name, tap_reg))
3204    {
3205      const char *act = guid_to_name (name, panel_reg);
3206      buf_printf (&ret, "%s", name);
3207      if (act)
3208	buf_printf (&actual, "%s", act);
3209      else
3210	buf_printf (&actual, "%s", name);
3211      return BSTR (&ret);
3212    }
3213
3214  /* Lookup TAP adapter in network connections list */
3215  {
3216    const char *guid = name_to_guid (name, tap_reg, panel_reg);
3217    if (guid)
3218      {
3219	buf_printf (&actual, "%s", name);
3220	buf_printf (&ret, "%s", guid);
3221	return BSTR (&ret);
3222      }
3223  }
3224
3225  return NULL;
3226}
3227
3228/*
3229 * Get adapter info list
3230 */
3231const IP_ADAPTER_INFO *
3232get_adapter_info_list (struct gc_arena *gc)
3233{
3234  ULONG size = 0;
3235  IP_ADAPTER_INFO *pi = NULL;
3236  DWORD status;
3237
3238  if ((status = GetAdaptersInfo (NULL, &size)) != ERROR_BUFFER_OVERFLOW)
3239    {
3240      msg (M_INFO, "GetAdaptersInfo #1 failed (status=%u) : %s",
3241	   (unsigned int)status,
3242	   strerror_win32 (status, gc));
3243    }
3244  else
3245    {
3246      pi = (PIP_ADAPTER_INFO) gc_malloc (size, false, gc);
3247      if ((status = GetAdaptersInfo (pi, &size)) == NO_ERROR)
3248	return pi;
3249      else
3250	{
3251	  msg (M_INFO, "GetAdaptersInfo #2 failed (status=%u) : %s",
3252	       (unsigned int)status,
3253	       strerror_win32 (status, gc));
3254	}
3255    }
3256  return pi;
3257}
3258
3259const IP_PER_ADAPTER_INFO *
3260get_per_adapter_info (const DWORD index, struct gc_arena *gc)
3261{
3262  ULONG size = 0;
3263  IP_PER_ADAPTER_INFO *pi = NULL;
3264  DWORD status;
3265
3266  if (index != TUN_ADAPTER_INDEX_INVALID)
3267    {
3268      if ((status = GetPerAdapterInfo (index, NULL, &size)) != ERROR_BUFFER_OVERFLOW)
3269	{
3270	  msg (M_INFO, "GetPerAdapterInfo #1 failed (status=%u) : %s",
3271	       (unsigned int)status,
3272	       strerror_win32 (status, gc));
3273	}
3274      else
3275	{
3276	  pi = (PIP_PER_ADAPTER_INFO) gc_malloc (size, false, gc);
3277	  if ((status = GetPerAdapterInfo ((ULONG)index, pi, &size)) == ERROR_SUCCESS)
3278	    return pi;
3279	  else
3280	    {
3281	      msg (M_INFO, "GetPerAdapterInfo #2 failed (status=%u) : %s",
3282		   (unsigned int)status,
3283		   strerror_win32 (status, gc));
3284	    }
3285	}
3286    }
3287  return pi;
3288}
3289
3290static const IP_INTERFACE_INFO *
3291get_interface_info_list (struct gc_arena *gc)
3292{
3293  ULONG size = 0;
3294  IP_INTERFACE_INFO *ii = NULL;
3295  DWORD status;
3296
3297  if ((status = GetInterfaceInfo (NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)
3298    {
3299      msg (M_INFO, "GetInterfaceInfo #1 failed (status=%u) : %s",
3300	   (unsigned int)status,
3301	   strerror_win32 (status, gc));
3302    }
3303  else
3304    {
3305      ii = (PIP_INTERFACE_INFO) gc_malloc (size, false, gc);
3306      if ((status = GetInterfaceInfo (ii, &size)) == NO_ERROR)
3307	return ii;
3308      else
3309	{
3310	  msg (M_INFO, "GetInterfaceInfo #2 failed (status=%u) : %s",
3311	       (unsigned int)status,
3312	       strerror_win32 (status, gc));
3313	}
3314    }
3315  return ii;
3316}
3317
3318static const IP_ADAPTER_INDEX_MAP *
3319get_interface_info (DWORD index, struct gc_arena *gc)
3320{
3321  const IP_INTERFACE_INFO *list = get_interface_info_list (gc);
3322  if (list)
3323    {
3324      int i;
3325      for (i = 0; i < list->NumAdapters; ++i)
3326	{
3327	  const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[i];
3328	  if (index == inter->Index)
3329	    return inter;
3330	}
3331    }
3332  return NULL;
3333}
3334
3335/*
3336 * Given an adapter index, return a pointer to the
3337 * IP_ADAPTER_INFO structure for that adapter.
3338 */
3339
3340const IP_ADAPTER_INFO *
3341get_adapter (const IP_ADAPTER_INFO *ai, DWORD index)
3342{
3343  if (ai && index != TUN_ADAPTER_INDEX_INVALID)
3344    {
3345      const IP_ADAPTER_INFO *a;
3346
3347      /* find index in the linked list */
3348      for (a = ai; a != NULL; a = a->Next)
3349	{
3350	  if (a->Index == index)
3351	    return a;
3352	}
3353    }
3354  return NULL;
3355}
3356
3357const IP_ADAPTER_INFO *
3358get_adapter_info (DWORD index, struct gc_arena *gc)
3359{
3360  return get_adapter (get_adapter_info_list (gc), index);
3361}
3362
3363static int
3364get_adapter_n_ip_netmask (const IP_ADAPTER_INFO *ai)
3365{
3366  if (ai)
3367    {
3368      int n = 0;
3369      const IP_ADDR_STRING *ip = &ai->IpAddressList;
3370
3371      while (ip)
3372	{
3373	  ++n;
3374	  ip = ip->Next;
3375	}
3376      return n;
3377    }
3378  else
3379    return 0;
3380}
3381
3382static bool
3383get_adapter_ip_netmask (const IP_ADAPTER_INFO *ai, const int n, in_addr_t *ip, in_addr_t *netmask)
3384{
3385  bool ret = false;
3386  *ip = 0;
3387  *netmask = 0;
3388
3389  if (ai)
3390    {
3391      const IP_ADDR_STRING *iplist = &ai->IpAddressList;
3392      int i = 0;
3393
3394      while (iplist)
3395	{
3396	  if (i == n)
3397	    break;
3398	  ++i;
3399	  iplist = iplist->Next;
3400	}
3401
3402      if (iplist)
3403	{
3404	  const unsigned int getaddr_flags = GETADDR_HOST_ORDER;
3405	  const char *ip_str = iplist->IpAddress.String;
3406	  const char *netmask_str = iplist->IpMask.String;
3407	  bool succeed1 = false;
3408	  bool succeed2 = false;
3409
3410	  if (ip_str && netmask_str && strlen (ip_str) && strlen (netmask_str))
3411	    {
3412	      *ip = getaddr (getaddr_flags, ip_str, 0, &succeed1, NULL);
3413	      *netmask = getaddr (getaddr_flags, netmask_str, 0, &succeed2, NULL);
3414	      ret = (succeed1 == true && succeed2 == true);
3415	    }
3416	}
3417    }
3418
3419  return ret;
3420}
3421
3422static bool
3423test_adapter_ip_netmask (const IP_ADAPTER_INFO *ai, const in_addr_t ip, const in_addr_t netmask)
3424{
3425  if (ai)
3426    {
3427      in_addr_t ip_adapter = 0;
3428      in_addr_t netmask_adapter = 0;
3429      const bool status = get_adapter_ip_netmask (ai, 0, &ip_adapter, &netmask_adapter);
3430      return (status && ip_adapter == ip && netmask_adapter == netmask);
3431    }
3432  else
3433    return false;
3434}
3435
3436const IP_ADAPTER_INFO *
3437get_tun_adapter (const struct tuntap *tt, const IP_ADAPTER_INFO *list)
3438{
3439  if (list && tt)
3440    return get_adapter (list, tt->adapter_index);
3441  else
3442    return NULL;
3443}
3444
3445bool
3446is_adapter_up (const struct tuntap *tt, const IP_ADAPTER_INFO *list)
3447{
3448  int i;
3449  bool ret = false;
3450
3451  const IP_ADAPTER_INFO *ai = get_tun_adapter (tt, list);
3452
3453  if (ai)
3454    {
3455      const int n = get_adapter_n_ip_netmask (ai);
3456
3457      /* loop once for every IP/netmask assigned to adapter */
3458      for (i = 0; i < n; ++i)
3459	{
3460	  in_addr_t ip, netmask;
3461	  if (get_adapter_ip_netmask (ai, i, &ip, &netmask))
3462	    {
3463	      if (tt->local && tt->adapter_netmask)
3464		{
3465		  /* wait for our --ifconfig parms to match the actual adapter parms */
3466		  if (tt->local == ip && tt->adapter_netmask == netmask)
3467		    ret = true;
3468		}
3469	      else
3470		{
3471		  /* --ifconfig was not defined, maybe using a real DHCP server */
3472		  if (ip && netmask)
3473		    ret = true;
3474		}
3475	    }
3476	}
3477    }
3478  else
3479    ret = true; /* this can occur when TAP adapter is bridged */
3480
3481  return ret;
3482}
3483
3484bool
3485is_ip_in_adapter_subnet (const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask)
3486{
3487  int i;
3488  bool ret = false;
3489
3490  if (highest_netmask)
3491    *highest_netmask = 0;
3492
3493  if (ai)
3494    {
3495      const int n = get_adapter_n_ip_netmask (ai);
3496      for (i = 0; i < n; ++i)
3497	{
3498	  in_addr_t adapter_ip, adapter_netmask;
3499	  if (get_adapter_ip_netmask (ai, i, &adapter_ip, &adapter_netmask))
3500	    {
3501	      if (adapter_ip && adapter_netmask && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))
3502		{
3503		  if (highest_netmask && adapter_netmask > *highest_netmask)
3504		    *highest_netmask = adapter_netmask;
3505		  ret = true;
3506		}
3507	    }
3508	}
3509    }
3510  return ret;
3511}
3512
3513DWORD
3514adapter_index_of_ip (const IP_ADAPTER_INFO *list,
3515		     const in_addr_t ip,
3516		     int *count,
3517		     in_addr_t *netmask)
3518{
3519  struct gc_arena gc = gc_new ();
3520  DWORD ret = TUN_ADAPTER_INDEX_INVALID;
3521  in_addr_t highest_netmask = 0;
3522  bool first = true;
3523
3524  if (count)
3525    *count = 0;
3526
3527  while (list)
3528    {
3529      in_addr_t hn;
3530
3531      if (is_ip_in_adapter_subnet (list, ip, &hn))
3532	{
3533	  if (first || hn > highest_netmask)
3534	    {
3535	      highest_netmask = hn;
3536	      if (count)
3537		*count = 1;
3538	      ret = list->Index;
3539	      first = false;
3540	    }
3541	  else if (hn == highest_netmask)
3542	    {
3543	      if (count)
3544		++*count;
3545	    }
3546	}
3547      list = list->Next;
3548    }
3549
3550  dmsg (D_ROUTE_DEBUG, "DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d",
3551       print_in_addr_t (ip, 0, &gc),
3552       print_in_addr_t (highest_netmask, 0, &gc),
3553       (int)ret,
3554       count ? *count : -1);
3555
3556  if (ret == TUN_ADAPTER_INDEX_INVALID && count)
3557    *count = 0;
3558
3559  if (netmask)
3560    *netmask = highest_netmask;
3561
3562  gc_free (&gc);
3563  return ret;
3564}
3565
3566/*
3567 * Given an adapter index, return true if the adapter
3568 * is DHCP disabled.
3569 */
3570
3571#define DHCP_STATUS_UNDEF     0
3572#define DHCP_STATUS_ENABLED   1
3573#define DHCP_STATUS_DISABLED  2
3574
3575static int
3576dhcp_status (DWORD index)
3577{
3578  struct gc_arena gc = gc_new ();
3579  int ret = DHCP_STATUS_UNDEF;
3580  if (index != TUN_ADAPTER_INDEX_INVALID)
3581    {
3582      const IP_ADAPTER_INFO *ai = get_adapter_info (index, &gc);
3583
3584      if (ai)
3585	{
3586	  if (ai->DhcpEnabled)
3587	    ret = DHCP_STATUS_ENABLED;
3588	  else
3589	    ret = DHCP_STATUS_DISABLED;
3590	}
3591    }
3592  gc_free (&gc);
3593  return ret;
3594}
3595
3596/*
3597 * Delete all temporary address/netmask pairs which were added
3598 * to adapter (given by index) by previous calls to AddIPAddress.
3599 */
3600static void
3601delete_temp_addresses (DWORD index)
3602{
3603  struct gc_arena gc = gc_new ();
3604  const IP_ADAPTER_INFO *a = get_adapter_info (index, &gc);
3605
3606  if (a)
3607    {
3608      const IP_ADDR_STRING *ip = &a->IpAddressList;
3609      while (ip)
3610	{
3611	  DWORD status;
3612	  const DWORD context = ip->Context;
3613
3614	  if ((status = DeleteIPAddress ((ULONG) context)) == NO_ERROR)
3615	    {
3616	      msg (M_INFO, "Successfully deleted previously set dynamic IP/netmask: %s/%s",
3617		   ip->IpAddress.String,
3618		   ip->IpMask.String);
3619	    }
3620	  else
3621	    {
3622	      const char *empty = "0.0.0.0";
3623	      if (strcmp (ip->IpAddress.String, empty)
3624		  || strcmp (ip->IpMask.String, empty))
3625		msg (M_INFO, "NOTE: could not delete previously set dynamic IP/netmask: %s/%s (status=%u)",
3626		     ip->IpAddress.String,
3627		     ip->IpMask.String,
3628		     (unsigned int)status);
3629	    }
3630	  ip = ip->Next;
3631	}
3632    }
3633  gc_free (&gc);
3634}
3635
3636/*
3637 * Get interface index for use with IP Helper API functions.
3638 */
3639static DWORD
3640get_adapter_index_method_1 (const char *guid)
3641{
3642  DWORD index;
3643  ULONG aindex;
3644  wchar_t wbuf[256];
3645  _snwprintf (wbuf, SIZE (wbuf), L"\\DEVICE\\TCPIP_%S", guid);
3646  wbuf [SIZE(wbuf) - 1] = 0;
3647  if (GetAdapterIndex (wbuf, &aindex) != NO_ERROR)
3648    index = TUN_ADAPTER_INDEX_INVALID;
3649  else
3650    index = (DWORD)aindex;
3651  return index;
3652}
3653
3654static DWORD
3655get_adapter_index_method_2 (const char *guid)
3656{
3657  struct gc_arena gc = gc_new ();
3658  DWORD index = TUN_ADAPTER_INDEX_INVALID;
3659
3660  const IP_ADAPTER_INFO *list = get_adapter_info_list (&gc);
3661
3662  while (list)
3663    {
3664      if (!strcmp (guid, list->AdapterName))
3665	{
3666	  index = list->Index;
3667	  break;
3668	}
3669      list = list->Next;
3670    }
3671
3672  gc_free (&gc);
3673  return index;
3674}
3675
3676static DWORD
3677get_adapter_index (const char *guid)
3678{
3679  DWORD index;
3680  index = get_adapter_index_method_1 (guid);
3681  if (index == TUN_ADAPTER_INDEX_INVALID)
3682    index = get_adapter_index_method_2 (guid);
3683  if (index == TUN_ADAPTER_INDEX_INVALID)
3684    msg (M_INFO, "NOTE: could not get adapter index for %s", guid);
3685  return index;
3686}
3687
3688static DWORD
3689get_adapter_index_flexible (const char *name) /* actual name or GUID */
3690{
3691  struct gc_arena gc = gc_new ();
3692  DWORD index;
3693  index = get_adapter_index_method_1 (name);
3694  if (index == TUN_ADAPTER_INDEX_INVALID)
3695    index = get_adapter_index_method_2 (name);
3696  if (index == TUN_ADAPTER_INDEX_INVALID)
3697    {
3698      const struct tap_reg *tap_reg = get_tap_reg (&gc);
3699      const struct panel_reg *panel_reg = get_panel_reg (&gc);
3700      const char *guid = name_to_guid (name, tap_reg, panel_reg);
3701      index = get_adapter_index_method_1 (guid);
3702      if (index == TUN_ADAPTER_INDEX_INVALID)
3703	index = get_adapter_index_method_2 (guid);
3704    }
3705  if (index == TUN_ADAPTER_INDEX_INVALID)
3706    msg (M_INFO, "NOTE: could not get adapter index for name/GUID '%s'", name);
3707  gc_free (&gc);
3708  return index;
3709}
3710
3711/*
3712 * Return a string representing a PIP_ADDR_STRING
3713 */
3714static const char *
3715format_ip_addr_string (const IP_ADDR_STRING *ip, struct gc_arena *gc)
3716{
3717  struct buffer out = alloc_buf_gc (256, gc);
3718  while (ip)
3719    {
3720      buf_printf (&out, "%s", ip->IpAddress.String);
3721      if (strlen (ip->IpMask.String))
3722	{
3723	  buf_printf (&out, "/");
3724	  buf_printf (&out, "%s", ip->IpMask.String);
3725	}
3726      buf_printf (&out, " ");
3727      ip = ip->Next;
3728    }
3729  return BSTR (&out);
3730}
3731
3732/*
3733 * Show info for a single adapter
3734 */
3735static void
3736show_adapter (int msglev, const IP_ADAPTER_INFO *a, struct gc_arena *gc)
3737{
3738  msg (msglev, "%s", a->Description);
3739  msg (msglev, "  Index = %d", (int)a->Index);
3740  msg (msglev, "  GUID = %s", a->AdapterName);
3741  msg (msglev, "  IP = %s", format_ip_addr_string (&a->IpAddressList, gc));
3742  msg (msglev, "  MAC = %s", format_hex_ex (a->Address, a->AddressLength, 0, 1, ":", gc));
3743  msg (msglev, "  GATEWAY = %s", format_ip_addr_string (&a->GatewayList, gc));
3744  if (a->DhcpEnabled)
3745    {
3746      msg (msglev, "  DHCP SERV = %s", format_ip_addr_string (&a->DhcpServer, gc));
3747      msg (msglev, "  DHCP LEASE OBTAINED = %s", time_string (a->LeaseObtained, 0, false, gc));
3748      msg (msglev, "  DHCP LEASE EXPIRES  = %s", time_string (a->LeaseExpires, 0, false, gc));
3749    }
3750  if (a->HaveWins)
3751    {
3752      msg (msglev, "  PRI WINS = %s", format_ip_addr_string (&a->PrimaryWinsServer, gc));
3753      msg (msglev, "  SEC WINS = %s", format_ip_addr_string (&a->SecondaryWinsServer, gc));
3754    }
3755
3756  {
3757    const IP_PER_ADAPTER_INFO *pai = get_per_adapter_info (a->Index, gc);
3758    if (pai)
3759      {
3760	msg (msglev, "  DNS SERV = %s", format_ip_addr_string (&pai->DnsServerList, gc));
3761      }
3762  }
3763}
3764
3765/*
3766 * Show current adapter list
3767 */
3768void
3769show_adapters (int msglev)
3770{
3771  struct gc_arena gc = gc_new ();
3772  const IP_ADAPTER_INFO *ai = get_adapter_info_list (&gc);
3773
3774  msg (msglev, "SYSTEM ADAPTER LIST");
3775  if (ai)
3776    {
3777      const IP_ADAPTER_INFO *a;
3778
3779      /* find index in the linked list */
3780      for (a = ai; a != NULL; a = a->Next)
3781	{
3782	  show_adapter (msglev, a, &gc);
3783	}
3784    }
3785  gc_free (&gc);
3786}
3787
3788/*
3789 * Set a particular TAP-Windows adapter (or all of them if
3790 * adapter_name == NULL) to allow it to be opened from
3791 * a non-admin account.  This setting will only persist
3792 * for the lifetime of the device object.
3793 */
3794
3795static void
3796tap_allow_nonadmin_access_handle (const char *device_path, HANDLE hand)
3797{
3798  struct security_attributes sa;
3799  BOOL status;
3800
3801  if (!init_security_attributes_allow_all (&sa))
3802    msg (M_ERR, "Error: init SA failed");
3803
3804  status = SetKernelObjectSecurity (hand, DACL_SECURITY_INFORMATION, &sa.sd);
3805  if (!status)
3806    {
3807      msg (M_ERRNO, "Error: SetKernelObjectSecurity failed on %s", device_path);
3808    }
3809  else
3810    {
3811      msg (M_INFO|M_NOPREFIX, "TAP-Windows device: %s [Non-admin access allowed]", device_path);
3812    }
3813}
3814
3815void
3816tap_allow_nonadmin_access (const char *dev_node)
3817{
3818  struct gc_arena gc = gc_new ();
3819  const struct tap_reg *tap_reg = get_tap_reg (&gc);
3820  const struct panel_reg *panel_reg = get_panel_reg (&gc);
3821  const char *device_guid = NULL;
3822  HANDLE hand;
3823  char actual_buffer[256];
3824  char device_path[256];
3825
3826  at_least_one_tap_win (tap_reg);
3827
3828  if (dev_node)
3829    {
3830      /* Get the device GUID for the device specified with --dev-node. */
3831      device_guid = get_device_guid (dev_node, actual_buffer, sizeof (actual_buffer), tap_reg, panel_reg, &gc);
3832
3833      if (!device_guid)
3834	msg (M_FATAL, "TAP-Windows adapter '%s' not found", dev_node);
3835
3836      /* Open Windows TAP-Windows adapter */
3837      openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s",
3838			USERMODEDEVICEDIR,
3839			device_guid,
3840			TAP_WIN_SUFFIX);
3841
3842      hand = CreateFile (
3843			 device_path,
3844			 MAXIMUM_ALLOWED,
3845			 0, /* was: FILE_SHARE_READ */
3846			 0,
3847			 OPEN_EXISTING,
3848			 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
3849			 0
3850			 );
3851
3852      if (hand == INVALID_HANDLE_VALUE)
3853	msg (M_ERR, "CreateFile failed on TAP device: %s", device_path);
3854
3855      tap_allow_nonadmin_access_handle (device_path, hand);
3856      CloseHandle (hand);
3857    }
3858  else
3859    {
3860      int device_number = 0;
3861
3862      /* Try opening all TAP devices */
3863      while (true)
3864	{
3865	  device_guid = get_unspecified_device_guid (device_number,
3866						     actual_buffer,
3867						     sizeof (actual_buffer),
3868						     tap_reg,
3869						     panel_reg,
3870						     &gc);
3871
3872	  if (!device_guid)
3873	    break;
3874
3875	  /* Open Windows TAP-Windows adapter */
3876	  openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s",
3877			    USERMODEDEVICEDIR,
3878			    device_guid,
3879			    TAP_WIN_SUFFIX);
3880
3881	  hand = CreateFile (
3882			     device_path,
3883			     MAXIMUM_ALLOWED,
3884			     0, /* was: FILE_SHARE_READ */
3885			     0,
3886			     OPEN_EXISTING,
3887			     FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
3888			     0
3889			     );
3890
3891	  if (hand == INVALID_HANDLE_VALUE)
3892	    msg (M_WARN, "CreateFile failed on TAP device: %s", device_path);
3893	  else
3894	    {
3895	      tap_allow_nonadmin_access_handle (device_path, hand);
3896	      CloseHandle (hand);
3897	    }
3898
3899	  device_number++;
3900	}
3901    }
3902  gc_free (&gc);
3903}
3904
3905/*
3906 * DHCP release/renewal
3907 */
3908bool
3909dhcp_release_by_adapter_index(const DWORD adapter_index)
3910{
3911  struct gc_arena gc = gc_new ();
3912  bool ret = false;
3913  const IP_ADAPTER_INDEX_MAP *inter = get_interface_info (adapter_index, &gc);
3914
3915  if (inter)
3916    {
3917      DWORD status = IpReleaseAddress ((IP_ADAPTER_INDEX_MAP *)inter);
3918      if (status == NO_ERROR)
3919	{
3920	  msg (D_TUNTAP_INFO, "TAP: DHCP address released");
3921	  ret = true;
3922	}
3923      else
3924	msg (M_WARN, "NOTE: Release of DHCP-assigned IP address lease on TAP-Windows adapter failed: %s (code=%u)",
3925	     strerror_win32 (status, &gc),
3926	     (unsigned int)status);
3927    }
3928
3929  gc_free (&gc);
3930  return ret;
3931}
3932
3933static bool
3934dhcp_release (const struct tuntap *tt)
3935{
3936  if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != TUN_ADAPTER_INDEX_INVALID)
3937    return dhcp_release_by_adapter_index (tt->adapter_index);
3938  else
3939    return false;
3940}
3941
3942bool
3943dhcp_renew_by_adapter_index (const DWORD adapter_index)
3944{
3945  struct gc_arena gc = gc_new ();
3946  bool ret = false;
3947  const IP_ADAPTER_INDEX_MAP *inter = get_interface_info (adapter_index, &gc);
3948
3949  if (inter)
3950    {
3951      DWORD status = IpRenewAddress ((IP_ADAPTER_INDEX_MAP *)inter);
3952      if (status == NO_ERROR)
3953	{
3954	  msg (D_TUNTAP_INFO, "TAP: DHCP address renewal succeeded");
3955	  ret = true;
3956	}
3957      else
3958	msg (M_WARN, "WARNING: Failed to renew DHCP IP address lease on TAP-Windows adapter: %s (code=%u)",
3959	     strerror_win32 (status, &gc),
3960	     (unsigned int)status);
3961    }
3962  gc_free (&gc);
3963  return ret;
3964}
3965
3966static bool
3967dhcp_renew (const struct tuntap *tt)
3968{
3969  if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != TUN_ADAPTER_INDEX_INVALID)
3970    return dhcp_renew_by_adapter_index (tt->adapter_index);
3971  else
3972    return false;
3973}
3974
3975/*
3976 * netsh functions
3977 */
3978
3979static void
3980netsh_command (const struct argv *a, int n)
3981{
3982  int i;
3983  for (i = 0; i < n; ++i)
3984    {
3985      bool status;
3986      openvpn_sleep (1);
3987      netcmd_semaphore_lock ();
3988      argv_msg_prefix (M_INFO, a, "NETSH");
3989      status = openvpn_execve_check (a, NULL, 0, "ERROR: netsh command failed");
3990      netcmd_semaphore_release ();
3991      if (status)
3992	return;
3993      openvpn_sleep (4);
3994    }
3995  msg (M_FATAL, "NETSH: command failed");
3996}
3997
3998void
3999ipconfig_register_dns (const struct env_set *es)
4000{
4001  struct argv argv;
4002  bool status;
4003  const char err[] = "ERROR: Windows ipconfig command failed";
4004
4005  msg (D_TUNTAP_INFO, "Start net commands...");
4006  netcmd_semaphore_lock ();
4007
4008  argv_init (&argv);
4009
4010  argv_printf (&argv, "%s%sc stop dnscache",
4011	       get_win_sys_path(),
4012	       WIN_NET_PATH_SUFFIX);
4013  argv_msg (D_TUNTAP_INFO, &argv);
4014  status = openvpn_execve_check (&argv, es, 0, err);
4015  argv_reset(&argv);
4016
4017  argv_printf (&argv, "%s%sc start dnscache",
4018	       get_win_sys_path(),
4019	       WIN_NET_PATH_SUFFIX);
4020  argv_msg (D_TUNTAP_INFO, &argv);
4021  status = openvpn_execve_check (&argv, es, 0, err);
4022  argv_reset(&argv);
4023
4024  argv_printf (&argv, "%s%sc /flushdns",
4025	       get_win_sys_path(),
4026	       WIN_IPCONFIG_PATH_SUFFIX);
4027  argv_msg (D_TUNTAP_INFO, &argv);
4028  status = openvpn_execve_check (&argv, es, 0, err);
4029  argv_reset(&argv);
4030
4031  argv_printf (&argv, "%s%sc /registerdns",
4032	       get_win_sys_path(),
4033	       WIN_IPCONFIG_PATH_SUFFIX);
4034  argv_msg (D_TUNTAP_INFO, &argv);
4035  status = openvpn_execve_check (&argv, es, 0, err);
4036  argv_reset(&argv);
4037
4038  netcmd_semaphore_release ();
4039  msg (D_TUNTAP_INFO, "End net commands...");
4040}
4041
4042void
4043ip_addr_string_to_array (in_addr_t *dest, int *dest_len, const IP_ADDR_STRING *src)
4044{
4045  int i = 0;
4046  while (src)
4047    {
4048      const unsigned int getaddr_flags = GETADDR_HOST_ORDER;
4049      const char *ip_str = src->IpAddress.String;
4050      in_addr_t ip = 0;
4051      bool succeed = false;
4052
4053      if (i >= *dest_len)
4054	break;
4055      if (!ip_str || !strlen (ip_str))
4056	break;
4057
4058      ip = getaddr (getaddr_flags, ip_str, 0, &succeed, NULL);
4059      if (!succeed)
4060	break;
4061      dest[i++] = ip;
4062
4063      src = src->Next;
4064    }
4065  *dest_len = i;
4066
4067#if 0
4068 {
4069   struct gc_arena gc = gc_new ();
4070   msg (M_INFO, "ip_addr_string_to_array [%d]", *dest_len);
4071   for (i = 0; i < *dest_len; ++i)
4072     {
4073       msg (M_INFO, "%s", print_in_addr_t (dest[i], 0, &gc));
4074     }
4075   gc_free (&gc);
4076 }
4077#endif
4078}
4079
4080static bool
4081ip_addr_one_to_one (const in_addr_t *a1, const int a1len, const IP_ADDR_STRING *ias)
4082{
4083  in_addr_t a2[8];
4084  int a2len = SIZE(a2);
4085  int i;
4086
4087  ip_addr_string_to_array (a2, &a2len, ias);
4088  /*msg (M_INFO, "a1len=%d a2len=%d", a1len, a2len);*/
4089  if (a1len != a2len)
4090    return false;
4091
4092  for (i = 0; i < a1len; ++i)
4093    {
4094      if (a1[i] != a2[i])
4095	return false;
4096    }
4097  return true;
4098}
4099
4100static bool
4101ip_addr_member_of (const in_addr_t addr, const IP_ADDR_STRING *ias)
4102{
4103  in_addr_t aa[8];
4104  int len = SIZE(aa);
4105  int i;
4106
4107  ip_addr_string_to_array (aa, &len, ias);
4108  for (i = 0; i < len; ++i)
4109    {
4110      if (addr == aa[i])
4111	return true;
4112    }
4113  return false;
4114}
4115
4116static void
4117netsh_ifconfig_options (const char *type,
4118			const in_addr_t *addr_list,
4119			const int addr_len,
4120			const IP_ADDR_STRING *current,
4121			const char *flex_name,
4122			const bool test_first)
4123{
4124  struct gc_arena gc = gc_new ();
4125  struct argv argv = argv_new ();
4126  bool delete_first = false;
4127
4128  /* first check if we should delete existing DNS/WINS settings from TAP interface */
4129  if (test_first)
4130    {
4131      if (!ip_addr_one_to_one (addr_list, addr_len, current))
4132	delete_first = true;
4133    }
4134  else
4135    delete_first = true;
4136
4137  /* delete existing DNS/WINS settings from TAP interface */
4138  if (delete_first)
4139    {
4140      argv_printf (&argv, "%s%sc interface ip delete %s %s all",
4141		   get_win_sys_path(),
4142		   NETSH_PATH_SUFFIX,
4143		   type,
4144		   flex_name);
4145      netsh_command (&argv, 2);
4146    }
4147
4148  /* add new DNS/WINS settings to TAP interface */
4149  {
4150    int count = 0;
4151    int i;
4152    for (i = 0; i < addr_len; ++i)
4153      {
4154	if (delete_first || !test_first || !ip_addr_member_of (addr_list[i], current))
4155	  {
4156	    const char *fmt = count ?
4157	        "%s%sc interface ip add %s %s %s"
4158	      : "%s%sc interface ip set %s %s static %s";
4159
4160	    argv_printf (&argv, fmt,
4161			 get_win_sys_path(),
4162			 NETSH_PATH_SUFFIX,
4163			 type,
4164			 flex_name,
4165			 print_in_addr_t (addr_list[i], 0, &gc));
4166	    netsh_command (&argv, 2);
4167
4168	    ++count;
4169	  }
4170	else
4171	  {
4172	    msg (M_INFO, "NETSH: \"%s\" %s %s [already set]",
4173		 flex_name,
4174		 type,
4175		 print_in_addr_t (addr_list[i], 0, &gc));
4176	  }
4177      }
4178  }
4179
4180  argv_reset (&argv);
4181  gc_free (&gc);
4182}
4183
4184static void
4185init_ip_addr_string2 (IP_ADDR_STRING *dest, const IP_ADDR_STRING *src1, const IP_ADDR_STRING *src2)
4186{
4187  CLEAR (dest[0]);
4188  CLEAR (dest[1]);
4189  if (src1)
4190    {
4191      dest[0] = *src1;
4192      dest[0].Next = NULL;
4193    }
4194  if (src2)
4195    {
4196      dest[1] = *src2;
4197      dest[0].Next = &dest[1];
4198      dest[1].Next = NULL;
4199    }
4200}
4201
4202static void
4203netsh_ifconfig (const struct tuntap_options *to,
4204		const char *flex_name,
4205		const in_addr_t ip,
4206		const in_addr_t netmask,
4207		const unsigned int flags)
4208{
4209  struct gc_arena gc = gc_new ();
4210  struct argv argv = argv_new ();
4211  const IP_ADAPTER_INFO *ai = NULL;
4212  const IP_PER_ADAPTER_INFO *pai = NULL;
4213
4214  if (flags & NI_TEST_FIRST)
4215    {
4216      const IP_ADAPTER_INFO *list = get_adapter_info_list (&gc);
4217      const int index = get_adapter_index_flexible (flex_name);
4218      ai = get_adapter (list, index);
4219      pai = get_per_adapter_info (index, &gc);
4220    }
4221
4222  if (flags & NI_IP_NETMASK)
4223    {
4224      if (test_adapter_ip_netmask (ai, ip, netmask))
4225	{
4226	  msg (M_INFO, "NETSH: \"%s\" %s/%s [already set]",
4227	       flex_name,
4228	       print_in_addr_t (ip, 0, &gc),
4229	       print_in_addr_t (netmask, 0, &gc));
4230	}
4231      else
4232	{
4233	  /* example: netsh interface ip set address my-tap static 10.3.0.1 255.255.255.0 */
4234	  argv_printf (&argv, "%s%sc interface ip set address %s static %s %s",
4235		       get_win_sys_path(),
4236		       NETSH_PATH_SUFFIX,
4237		       flex_name,
4238		       print_in_addr_t (ip, 0, &gc),
4239		       print_in_addr_t (netmask, 0, &gc));
4240
4241	  netsh_command (&argv, 4);
4242	}
4243    }
4244
4245  /* set WINS/DNS options */
4246  if (flags & NI_OPTIONS)
4247    {
4248      IP_ADDR_STRING wins[2];
4249      CLEAR (wins[0]);
4250      CLEAR (wins[1]);
4251
4252      netsh_ifconfig_options ("dns",
4253			      to->dns,
4254			      to->dns_len,
4255			      pai ? &pai->DnsServerList : NULL,
4256			      flex_name,
4257			      BOOL_CAST (flags & NI_TEST_FIRST));
4258      if (ai && ai->HaveWins)
4259	init_ip_addr_string2 (wins, &ai->PrimaryWinsServer, &ai->SecondaryWinsServer);
4260
4261      netsh_ifconfig_options ("wins",
4262			      to->wins,
4263			      to->wins_len,
4264			      ai ? wins : NULL,
4265			      flex_name,
4266			      BOOL_CAST (flags & NI_TEST_FIRST));
4267    }
4268
4269  argv_reset (&argv);
4270  gc_free (&gc);
4271}
4272
4273static void
4274netsh_enable_dhcp (const struct tuntap_options *to,
4275		   const char *actual_name)
4276{
4277  struct argv argv;
4278  argv_init (&argv);
4279
4280  /* example: netsh interface ip set address my-tap dhcp */
4281  argv_printf (&argv,
4282	      "%s%sc interface ip set address %s dhcp",
4283	       get_win_sys_path(),
4284	       NETSH_PATH_SUFFIX,
4285	       actual_name);
4286
4287  netsh_command (&argv, 4);
4288
4289  argv_reset (&argv);
4290}
4291
4292/*
4293 * Return a TAP name for netsh commands.
4294 */
4295static const char *
4296netsh_get_id (const char *dev_node, struct gc_arena *gc)
4297{
4298  const struct tap_reg *tap_reg = get_tap_reg (gc);
4299  const struct panel_reg *panel_reg = get_panel_reg (gc);
4300  struct buffer actual = alloc_buf_gc (256, gc);
4301  const char *guid;
4302
4303  at_least_one_tap_win (tap_reg);
4304
4305  if (dev_node)
4306    {
4307      guid = get_device_guid (dev_node, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc);
4308    }
4309  else
4310    {
4311      guid = get_unspecified_device_guid (0, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc);
4312
4313      if (get_unspecified_device_guid (1, NULL, 0, tap_reg, panel_reg, gc)) /* ambiguous if more than one TAP-Windows adapter */
4314	guid = NULL;
4315    }
4316
4317  if (!guid)
4318    return "NULL";         /* not found */
4319  else if (strcmp (BPTR (&actual), "NULL"))
4320    return BPTR (&actual); /* control panel name */
4321  else
4322    return guid;           /* no control panel name, return GUID instead */
4323}
4324
4325/*
4326 * Called iteratively on TAP-Windows wait-for-initialization polling loop
4327 */
4328void
4329tun_standby_init (struct tuntap *tt)
4330{
4331  tt->standby_iter = 0;
4332}
4333
4334bool
4335tun_standby (struct tuntap *tt)
4336{
4337  bool ret = true;
4338  ++tt->standby_iter;
4339  if (tt->options.ip_win32_type == IPW32_SET_ADAPTIVE)
4340    {
4341      if (tt->standby_iter == IPW32_SET_ADAPTIVE_TRY_NETSH)
4342	{
4343	  msg (M_INFO, "NOTE: now trying netsh (this may take some time)");
4344	  netsh_ifconfig (&tt->options,
4345			  tt->actual_name,
4346			  tt->local,
4347			  tt->adapter_netmask,
4348			  NI_TEST_FIRST|NI_IP_NETMASK|NI_OPTIONS);
4349	}
4350      else if (tt->standby_iter >= IPW32_SET_ADAPTIVE_TRY_NETSH*2)
4351	{
4352	  ret = false;
4353	}
4354    }
4355  return ret;
4356}
4357
4358/*
4359 * Convert DHCP options from the command line / config file
4360 * into a raw DHCP-format options string.
4361 */
4362
4363static void
4364write_dhcp_u8 (struct buffer *buf, const int type, const int data, bool *error)
4365{
4366  if (!buf_safe (buf, 3))
4367    {
4368      *error = true;
4369      msg (M_WARN, "write_dhcp_u8: buffer overflow building DHCP options");
4370      return;
4371    }
4372  buf_write_u8 (buf, type);
4373  buf_write_u8 (buf, 1);
4374  buf_write_u8 (buf, data);
4375}
4376
4377static void
4378write_dhcp_u32_array (struct buffer *buf, const int type, const uint32_t *data, const unsigned int len, bool *error)
4379{
4380  if (len > 0)
4381    {
4382      int i;
4383      const int size = len * sizeof (uint32_t);
4384
4385      if (!buf_safe (buf, 2 + size))
4386	{
4387	  *error = true;
4388	  msg (M_WARN, "write_dhcp_u32_array: buffer overflow building DHCP options");
4389	  return;
4390	}
4391      if (size < 1 || size > 255)
4392	{
4393	  *error = true;
4394	  msg (M_WARN, "write_dhcp_u32_array: size (%d) must be > 0 and <= 255", size);
4395	  return;
4396	}
4397      buf_write_u8 (buf, type);
4398      buf_write_u8 (buf, size);
4399      for (i = 0; i < len; ++i)
4400	buf_write_u32 (buf, data[i]);
4401    }
4402}
4403
4404static void
4405write_dhcp_str (struct buffer *buf, const int type, const char *str, bool *error)
4406{
4407  const int len = strlen (str);
4408  if (!buf_safe (buf, 2 + len))
4409    {
4410      *error = true;
4411      msg (M_WARN, "write_dhcp_str: buffer overflow building DHCP options");
4412      return;
4413    }
4414  if (len < 1 || len > 255)
4415    {
4416      *error = true;
4417      msg (M_WARN, "write_dhcp_str: string '%s' must be > 0 bytes and <= 255 bytes", str);
4418      return;
4419    }
4420  buf_write_u8 (buf, type);
4421  buf_write_u8 (buf, len);
4422  buf_write (buf, str, len);
4423}
4424
4425static bool
4426build_dhcp_options_string (struct buffer *buf, const struct tuntap_options *o)
4427{
4428  bool error = false;
4429  if (o->domain)
4430    write_dhcp_str (buf, 15, o->domain, &error);
4431
4432  if (o->netbios_scope)
4433    write_dhcp_str (buf, 47, o->netbios_scope, &error);
4434
4435  if (o->netbios_node_type)
4436    write_dhcp_u8 (buf, 46, o->netbios_node_type, &error);
4437
4438  write_dhcp_u32_array (buf, 6, (uint32_t*)o->dns, o->dns_len, &error);
4439  write_dhcp_u32_array (buf, 44, (uint32_t*)o->wins, o->wins_len, &error);
4440  write_dhcp_u32_array (buf, 42, (uint32_t*)o->ntp, o->ntp_len, &error);
4441  write_dhcp_u32_array (buf, 45, (uint32_t*)o->nbdd, o->nbdd_len, &error);
4442
4443  /* the MS DHCP server option 'Disable Netbios-over-TCP/IP
4444     is implemented as vendor option 001, value 002.
4445     A value of 001 means 'leave NBT alone' which is the default */
4446  if (o->disable_nbt)
4447  {
4448    if (!buf_safe (buf, 8))
4449      {
4450	msg (M_WARN, "build_dhcp_options_string: buffer overflow building DHCP options");
4451	return false;
4452      }
4453    buf_write_u8 (buf,  43);
4454    buf_write_u8 (buf,  6);  /* total length field */
4455    buf_write_u8 (buf,  0x001);
4456    buf_write_u8 (buf,  4);  /* length of the vendor specified field */
4457    buf_write_u32 (buf, 0x002);
4458  }
4459  return !error;
4460}
4461
4462static void
4463fork_dhcp_action (struct tuntap *tt)
4464{
4465  if (tt->options.dhcp_pre_release || tt->options.dhcp_renew)
4466    {
4467      struct gc_arena gc = gc_new ();
4468      struct buffer cmd = alloc_buf_gc (256, &gc);
4469      const int verb = 3;
4470      const int pre_sleep = 1;
4471
4472      buf_printf (&cmd, "openvpn --verb %d --tap-sleep %d", verb, pre_sleep);
4473      if (tt->options.dhcp_pre_release)
4474	buf_printf (&cmd, " --dhcp-pre-release");
4475      if (tt->options.dhcp_renew)
4476	buf_printf (&cmd, " --dhcp-renew");
4477      buf_printf (&cmd, " --dhcp-internal %u", (unsigned int)tt->adapter_index);
4478
4479      fork_to_self (BSTR (&cmd));
4480      gc_free (&gc);
4481    }
4482}
4483
4484void
4485fork_register_dns_action (struct tuntap *tt)
4486{
4487  if (tt && tt->options.register_dns)
4488    {
4489      struct gc_arena gc = gc_new ();
4490      struct buffer cmd = alloc_buf_gc (256, &gc);
4491      const int verb = 3;
4492
4493      buf_printf (&cmd, "openvpn --verb %d --register-dns --rdns-internal", verb);
4494      fork_to_self (BSTR (&cmd));
4495      gc_free (&gc);
4496    }
4497}
4498
4499static uint32_t
4500dhcp_masq_addr (const in_addr_t local, const in_addr_t netmask, const int offset)
4501{
4502  struct gc_arena gc = gc_new ();
4503  in_addr_t dsa; /* DHCP server addr */
4504
4505  if (offset < 0)
4506    dsa = (local | (~netmask)) + offset;
4507  else
4508    dsa = (local & netmask) + offset;
4509
4510  if (dsa == local)
4511    msg (M_FATAL, "ERROR: There is a clash between the --ifconfig local address and the internal DHCP server address -- both are set to %s -- please use the --ip-win32 dynamic option to choose a different free address from the --ifconfig subnet for the internal DHCP server", print_in_addr_t (dsa, 0, &gc));
4512
4513  if ((local & netmask) != (dsa & netmask))
4514    msg (M_FATAL, "ERROR: --ip-win32 dynamic [offset] : offset is outside of --ifconfig subnet");
4515
4516  gc_free (&gc);
4517  return htonl(dsa);
4518}
4519
4520void
4521open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
4522{
4523  struct gc_arena gc = gc_new ();
4524  char device_path[256];
4525  const char *device_guid = NULL;
4526  DWORD len;
4527  bool dhcp_masq = false;
4528  bool dhcp_masq_post = false;
4529
4530  /*netcmd_semaphore_lock ();*/
4531
4532  msg( M_INFO, "open_tun, tt->ipv6=%d", tt->ipv6 );
4533
4534  if (tt->type == DEV_TYPE_NULL)
4535    {
4536      open_null (tt);
4537      gc_free (&gc);
4538      return;
4539    }
4540  else if (tt->type == DEV_TYPE_TAP || tt->type == DEV_TYPE_TUN)
4541    {
4542      ;
4543    }
4544  else
4545    {
4546      msg (M_FATAL|M_NOPREFIX, "Unknown virtual device type: '%s'", dev);
4547    }
4548
4549  /*
4550   * Lookup the device name in the registry, using the --dev-node high level name.
4551   */
4552  {
4553    const struct tap_reg *tap_reg = get_tap_reg (&gc);
4554    const struct panel_reg *panel_reg = get_panel_reg (&gc);
4555    char actual_buffer[256];
4556
4557    at_least_one_tap_win (tap_reg);
4558
4559    if (dev_node)
4560      {
4561        /* Get the device GUID for the device specified with --dev-node. */
4562        device_guid = get_device_guid (dev_node, actual_buffer, sizeof (actual_buffer), tap_reg, panel_reg, &gc);
4563
4564	if (!device_guid)
4565	  msg (M_FATAL, "TAP-Windows adapter '%s' not found", dev_node);
4566
4567        /* Open Windows TAP-Windows adapter */
4568        openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s",
4569   		          USERMODEDEVICEDIR,
4570		          device_guid,
4571		          TAP_WIN_SUFFIX);
4572
4573        tt->hand = CreateFile (
4574			       device_path,
4575			       GENERIC_READ | GENERIC_WRITE,
4576			       0, /* was: FILE_SHARE_READ */
4577			       0,
4578			       OPEN_EXISTING,
4579			       FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
4580			       0
4581			       );
4582
4583        if (tt->hand == INVALID_HANDLE_VALUE)
4584          msg (M_ERR, "CreateFile failed on TAP device: %s", device_path);
4585      }
4586    else
4587      {
4588        int device_number = 0;
4589
4590        /* Try opening all TAP devices until we find one available */
4591        while (true)
4592          {
4593            device_guid = get_unspecified_device_guid (device_number,
4594						       actual_buffer,
4595						       sizeof (actual_buffer),
4596						       tap_reg,
4597						       panel_reg,
4598						       &gc);
4599
4600	    if (!device_guid)
4601	      msg (M_FATAL, "All TAP-Windows adapters on this system are currently in use.");
4602
4603            /* Open Windows TAP-Windows adapter */
4604            openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s",
4605       		  	      USERMODEDEVICEDIR,
4606			      device_guid,
4607			      TAP_WIN_SUFFIX);
4608
4609            tt->hand = CreateFile (
4610			 	   device_path,
4611				   GENERIC_READ | GENERIC_WRITE,
4612				   0, /* was: FILE_SHARE_READ */
4613				   0,
4614				   OPEN_EXISTING,
4615				   FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
4616				   0
4617				   );
4618
4619            if (tt->hand == INVALID_HANDLE_VALUE)
4620              msg (D_TUNTAP_INFO, "CreateFile failed on TAP device: %s", device_path);
4621            else
4622              break;
4623
4624            device_number++;
4625          }
4626      }
4627
4628    /* translate high-level device name into a device instance
4629       GUID using the registry */
4630    tt->actual_name = string_alloc (actual_buffer, NULL);
4631  }
4632
4633  msg (M_INFO, "TAP-WIN32 device [%s] opened: %s", tt->actual_name, device_path);
4634  tt->adapter_index = get_adapter_index (device_guid);
4635
4636  /* get driver version info */
4637  {
4638    ULONG info[3];
4639    CLEAR (info);
4640    if (DeviceIoControl (tt->hand, TAP_WIN_IOCTL_GET_VERSION,
4641			 &info, sizeof (info),
4642			 &info, sizeof (info), &len, NULL))
4643      {
4644	msg (D_TUNTAP_INFO, "TAP-Windows Driver Version %d.%d %s",
4645	     (int) info[0],
4646	     (int) info[1],
4647	     (info[2] ? "(DEBUG)" : ""));
4648
4649      }
4650    if (!(info[0] == TAP_WIN_MIN_MAJOR && info[1] >= TAP_WIN_MIN_MINOR))
4651      msg (M_FATAL, "ERROR:  This version of " PACKAGE_NAME " requires a TAP-Windows driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME " distribution, a reboot is probably required at this point to get Windows to see the new driver.",
4652	   TAP_WIN_MIN_MAJOR,
4653	   TAP_WIN_MIN_MINOR);
4654
4655    /* usage of numeric constants is ugly, but this is really tied to
4656     * *this* version of the driver
4657     */
4658    if ( tt->ipv6 && tt->type == DEV_TYPE_TUN &&
4659         info[0] == 9 && info[1] < 8)
4660      {
4661	msg( M_INFO, "WARNING:  Tap-Win32 driver version %d.%d does not support IPv6 in TUN mode.  IPv6 will be disabled.  Upgrade to Tap-Win32 9.8 (2.2-beta3 release or later) or use TAP mode to get IPv6", (int) info[0], (int) info[1] );
4662	tt->ipv6 = false;
4663      }
4664
4665    /* tap driver 9.8 (2.2.0 and 2.2.1 release) is buggy
4666     */
4667    if ( tt->type == DEV_TYPE_TUN &&
4668	 info[0] == 9 && info[1] == 8)
4669      {
4670	msg( M_FATAL, "ERROR:  Tap-Win32 driver version %d.%d is buggy regarding small IPv4 packets in TUN mode.  Upgrade to Tap-Win32 9.9 (2.2.2 release or later) or use TAP mode", (int) info[0], (int) info[1] );
4671      }
4672  }
4673
4674  /* get driver MTU */
4675  {
4676    ULONG mtu;
4677    if (DeviceIoControl (tt->hand, TAP_WIN_IOCTL_GET_MTU,
4678			 &mtu, sizeof (mtu),
4679			 &mtu, sizeof (mtu), &len, NULL))
4680      {
4681	tt->post_open_mtu = (int) mtu;
4682	msg (D_MTU_INFO, "TAP-Windows MTU=%d", (int) mtu);
4683      }
4684  }
4685
4686  /*
4687   * Preliminaries for setting TAP-Windows adapter TCP/IP
4688   * properties via --ip-win32 dynamic or --ip-win32 adaptive.
4689   */
4690  if (tt->did_ifconfig_setup)
4691    {
4692      if (tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ)
4693	{
4694	  /*
4695	   * If adapter is set to non-DHCP, set to DHCP mode.
4696	   */
4697	  if (dhcp_status (tt->adapter_index) == DHCP_STATUS_DISABLED)
4698	    netsh_enable_dhcp (&tt->options, tt->actual_name);
4699	  dhcp_masq = true;
4700	  dhcp_masq_post = true;
4701	}
4702      else if (tt->options.ip_win32_type == IPW32_SET_ADAPTIVE)
4703	{
4704	  /*
4705	   * If adapter is set to non-DHCP, use netsh right away.
4706	   */
4707	  if (dhcp_status (tt->adapter_index) != DHCP_STATUS_ENABLED)
4708	    {
4709	      netsh_ifconfig (&tt->options,
4710			      tt->actual_name,
4711			      tt->local,
4712			      tt->adapter_netmask,
4713			      NI_TEST_FIRST|NI_IP_NETMASK|NI_OPTIONS);
4714	    }
4715	  else
4716	    {
4717	      dhcp_masq = true;
4718	    }
4719	}
4720    }
4721
4722  /* set point-to-point mode if TUN device */
4723
4724  if (tt->type == DEV_TYPE_TUN)
4725    {
4726      if (!tt->did_ifconfig_setup)
4727	{
4728	  msg (M_FATAL, "ERROR: --dev tun also requires --ifconfig");
4729	}
4730
4731      if (tt->topology == TOP_SUBNET)
4732	{
4733	  in_addr_t ep[3];
4734	  BOOL status;
4735
4736	  ep[0] = htonl (tt->local);
4737	  ep[1] = htonl (tt->local & tt->remote_netmask);
4738	  ep[2] = htonl (tt->remote_netmask);
4739
4740	  status = DeviceIoControl (tt->hand, TAP_WIN_IOCTL_CONFIG_TUN,
4741				    ep, sizeof (ep),
4742				    ep, sizeof (ep), &len, NULL);
4743
4744          msg (status ? M_INFO : M_FATAL, "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
4745	       print_in_addr_t (ep[1], IA_NET_ORDER, &gc),
4746	       print_in_addr_t (ep[0], IA_NET_ORDER, &gc),
4747	       print_in_addr_t (ep[2], IA_NET_ORDER, &gc),
4748	       status ? "SUCCEEDED" : "FAILED");
4749
4750	} else {
4751
4752	  in_addr_t ep[2];
4753	  ep[0] = htonl (tt->local);
4754	  ep[1] = htonl (tt->remote_netmask);
4755
4756	  if (!DeviceIoControl (tt->hand, TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT,
4757				ep, sizeof (ep),
4758				ep, sizeof (ep), &len, NULL))
4759	    msg (M_FATAL, "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun");
4760	}
4761    }
4762
4763  /* should we tell the TAP-Windows driver to masquerade as a DHCP server as a means
4764     of setting the adapter address? */
4765  if (dhcp_masq)
4766    {
4767      uint32_t ep[4];
4768
4769      /* We will answer DHCP requests with a reply to set IP/subnet to these values */
4770      ep[0] = htonl (tt->local);
4771      ep[1] = htonl (tt->adapter_netmask);
4772
4773      /* At what IP address should the DHCP server masquerade at? */
4774      if (tt->type == DEV_TYPE_TUN)
4775	{
4776	  if (tt->topology == TOP_SUBNET)
4777	    {
4778	      if (tt->options.dhcp_masq_custom_offset)
4779		ep[2] = dhcp_masq_addr (tt->local, tt->remote_netmask, tt->options.dhcp_masq_offset);
4780	      else
4781		ep[2] = dhcp_masq_addr (tt->local, tt->remote_netmask, -1);
4782	    }
4783	  else
4784	    ep[2] = htonl (tt->remote_netmask);
4785	}
4786      else
4787	{
4788	  ASSERT (tt->type == DEV_TYPE_TAP);
4789	  ep[2] = dhcp_masq_addr (tt->local, tt->adapter_netmask, tt->options.dhcp_masq_custom_offset ? tt->options.dhcp_masq_offset : 0);
4790	}
4791
4792      /* lease time in seconds */
4793      ep[3] = (uint32_t) tt->options.dhcp_lease_time;
4794
4795      ASSERT (ep[3] > 0);
4796
4797#ifndef SIMULATE_DHCP_FAILED /* this code is disabled to simulate bad DHCP negotiation */
4798      if (!DeviceIoControl (tt->hand, TAP_WIN_IOCTL_CONFIG_DHCP_MASQ,
4799			    ep, sizeof (ep),
4800			    ep, sizeof (ep), &len, NULL))
4801	msg (M_FATAL, "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode");
4802
4803      msg (M_INFO, "Notified TAP-Windows driver to set a DHCP IP/netmask of %s/%s on interface %s [DHCP-serv: %s, lease-time: %d]",
4804	   print_in_addr_t (tt->local, 0, &gc),
4805	   print_in_addr_t (tt->adapter_netmask, 0, &gc),
4806	   device_guid,
4807	   print_in_addr_t (ep[2], IA_NET_ORDER, &gc),
4808	   ep[3]
4809	   );
4810
4811      /* user-supplied DHCP options capability */
4812      if (tt->options.dhcp_options)
4813	{
4814	  struct buffer buf = alloc_buf (256);
4815	  if (build_dhcp_options_string (&buf, &tt->options))
4816	    {
4817	      msg (D_DHCP_OPT, "DHCP option string: %s", format_hex (BPTR (&buf), BLEN (&buf), 0, &gc));
4818	      if (!DeviceIoControl (tt->hand, TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT,
4819				    BPTR (&buf), BLEN (&buf),
4820				    BPTR (&buf), BLEN (&buf), &len, NULL))
4821		msg (M_FATAL, "ERROR: The TAP-Windows driver rejected a TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call");
4822	    }
4823	  else
4824	    msg (M_WARN, "DHCP option string not set due to error");
4825	  free_buf (&buf);
4826	}
4827#endif
4828    }
4829
4830  /* set driver media status to 'connected' */
4831  {
4832    ULONG status = TRUE;
4833    if (!DeviceIoControl (tt->hand, TAP_WIN_IOCTL_SET_MEDIA_STATUS,
4834			  &status, sizeof (status),
4835			  &status, sizeof (status), &len, NULL))
4836      msg (M_WARN, "WARNING: The TAP-Windows driver rejected a TAP_WIN_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
4837  }
4838
4839  /* possible wait for adapter to come up */
4840  {
4841    int s = tt->options.tap_sleep;
4842    if (s > 0)
4843      {
4844	msg (M_INFO, "Sleeping for %d seconds...", s);
4845	openvpn_sleep (s);
4846      }
4847  }
4848
4849  /* possibly use IP Helper API to set IP address on adapter */
4850  {
4851    const DWORD index = tt->adapter_index;
4852
4853    /* flush arp cache */
4854    if (index != TUN_ADAPTER_INDEX_INVALID)
4855      {
4856	DWORD status;
4857
4858	if ((status = FlushIpNetTable (index)) == NO_ERROR)
4859	  msg (M_INFO, "Successful ARP Flush on interface [%u] %s",
4860	       (unsigned int)index,
4861	       device_guid);
4862	else
4863	  msg (D_TUNTAP_INFO, "NOTE: FlushIpNetTable failed on interface [%u] %s (status=%u) : %s",
4864	       (unsigned int)index,
4865	       device_guid,
4866	       (unsigned int)status,
4867	       strerror_win32 (status, &gc));
4868      }
4869
4870    /*
4871     * If the TAP-Windows driver is masquerading as a DHCP server
4872     * make sure the TCP/IP properties for the adapter are
4873     * set correctly.
4874     */
4875    if (dhcp_masq_post)
4876      {
4877	/* check dhcp enable status */
4878	if (dhcp_status (index) == DHCP_STATUS_DISABLED)
4879	  msg (M_WARN, "WARNING: You have selected '--ip-win32 dynamic', which will not work unless the TAP-Windows TCP/IP properties are set to 'Obtain an IP address automatically'");
4880
4881	/* force an explicit DHCP lease renewal on TAP adapter? */
4882	if (tt->options.dhcp_pre_release)
4883	  dhcp_release (tt);
4884	if (tt->options.dhcp_renew)
4885	  dhcp_renew (tt);
4886      }
4887    else
4888      fork_dhcp_action (tt);
4889
4890    if (tt->did_ifconfig_setup && tt->options.ip_win32_type == IPW32_SET_IPAPI)
4891      {
4892	DWORD status;
4893	const char *error_suffix = "I am having trouble using the Windows 'IP helper API' to automatically set the IP address -- consider using other --ip-win32 methods (not 'ipapi')";
4894
4895	/* couldn't get adapter index */
4896	if (index == TUN_ADAPTER_INDEX_INVALID)
4897	  {
4898	    msg (M_FATAL, "ERROR: unable to get adapter index for interface %s -- %s",
4899		 device_guid,
4900		 error_suffix);
4901	  }
4902
4903	/* check dhcp enable status */
4904	if (dhcp_status (index) == DHCP_STATUS_DISABLED)
4905	  msg (M_WARN, "NOTE: You have selected (explicitly or by default) '--ip-win32 ipapi', which has a better chance of working correctly if the TAP-Windows TCP/IP properties are set to 'Obtain an IP address automatically'");
4906
4907	/* delete previously added IP addresses which were not
4908	   correctly deleted */
4909	delete_temp_addresses (index);
4910
4911	/* add a new IP address */
4912	if ((status = AddIPAddress (htonl(tt->local),
4913				    htonl(tt->adapter_netmask),
4914				    index,
4915				    &tt->ipapi_context,
4916				    &tt->ipapi_instance)) == NO_ERROR)
4917	  msg (M_INFO, "Succeeded in adding a temporary IP/netmask of %s/%s to interface %s using the Win32 IP Helper API",
4918	       print_in_addr_t (tt->local, 0, &gc),
4919	       print_in_addr_t (tt->adapter_netmask, 0, &gc),
4920	       device_guid
4921	       );
4922	else
4923	  msg (M_FATAL, "ERROR: AddIPAddress %s/%s failed on interface %s, index=%d, status=%u (windows error: '%s') -- %s",
4924	       print_in_addr_t (tt->local, 0, &gc),
4925	       print_in_addr_t (tt->adapter_netmask, 0, &gc),
4926	       device_guid,
4927	       (int)index,
4928	       (unsigned int)status,
4929	       strerror_win32 (status, &gc),
4930	       error_suffix);
4931	tt->ipapi_context_defined = true;
4932      }
4933  }
4934  /*netcmd_semaphore_release ();*/
4935  gc_free (&gc);
4936}
4937
4938const char *
4939tap_win_getinfo (const struct tuntap *tt, struct gc_arena *gc)
4940{
4941  if (tt && tt->hand != NULL)
4942    {
4943      struct buffer out = alloc_buf_gc (256, gc);
4944      DWORD len;
4945      if (DeviceIoControl (tt->hand, TAP_WIN_IOCTL_GET_INFO,
4946			   BSTR (&out), BCAP (&out),
4947			   BSTR (&out), BCAP (&out),
4948			   &len, NULL))
4949	{
4950	  return BSTR (&out);
4951	}
4952    }
4953  return NULL;
4954}
4955
4956void
4957tun_show_debug (struct tuntap *tt)
4958{
4959  if (tt && tt->hand != NULL)
4960    {
4961      struct buffer out = alloc_buf (1024);
4962      DWORD len;
4963      while (DeviceIoControl (tt->hand, TAP_WIN_IOCTL_GET_LOG_LINE,
4964			      BSTR (&out), BCAP (&out),
4965			      BSTR (&out), BCAP (&out),
4966			      &len, NULL))
4967	{
4968	  msg (D_TAP_WIN_DEBUG, "TAP-Windows: %s", BSTR (&out));
4969	}
4970      free_buf (&out);
4971    }
4972}
4973
4974void
4975close_tun (struct tuntap *tt)
4976{
4977  struct gc_arena gc = gc_new ();
4978
4979  if (tt)
4980    {
4981      if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
4982        {
4983	  const char *ifconfig_ipv6_local;
4984	  struct argv argv;
4985	  argv_init (&argv);
4986
4987	  /* remove route pointing to interface */
4988	  delete_route_connected_v6_net(tt, NULL);
4989
4990	  /* netsh interface ipv6 delete address \"%s\" %s */
4991	  ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0,  &gc);
4992	  argv_printf (&argv,
4993		    "%s%sc interface ipv6 delete address %s %s",
4994		     get_win_sys_path(),
4995		     NETSH_PATH_SUFFIX,
4996		     tt->actual_name,
4997		     ifconfig_ipv6_local );
4998
4999	  netsh_command (&argv, 1);
5000          argv_reset (&argv);
5001	}
5002#if 1
5003      if (tt->ipapi_context_defined)
5004	{
5005	  DWORD status;
5006	  if ((status = DeleteIPAddress (tt->ipapi_context)) != NO_ERROR)
5007	    {
5008	      msg (M_WARN, "Warning: DeleteIPAddress[%u] failed on TAP-Windows adapter, status=%u : %s",
5009		   (unsigned int)tt->ipapi_context,
5010		   (unsigned int)status,
5011		   strerror_win32 (status, &gc));
5012	    }
5013	}
5014#endif
5015
5016      if (tt->options.dhcp_release)
5017	dhcp_release (tt);
5018
5019      if (tt->hand != NULL)
5020	{
5021	  dmsg (D_WIN32_IO_LOW, "Attempting CancelIO on TAP-Windows adapter");
5022	  if (!CancelIo (tt->hand))
5023	    msg (M_WARN | M_ERRNO, "Warning: CancelIO failed on TAP-Windows adapter");
5024	}
5025
5026      dmsg (D_WIN32_IO_LOW, "Attempting close of overlapped read event on TAP-Windows adapter");
5027      overlapped_io_close (&tt->reads);
5028
5029      dmsg (D_WIN32_IO_LOW, "Attempting close of overlapped write event on TAP-Windows adapter");
5030      overlapped_io_close (&tt->writes);
5031
5032      if (tt->hand != NULL)
5033	{
5034	  dmsg (D_WIN32_IO_LOW, "Attempting CloseHandle on TAP-Windows adapter");
5035	  if (!CloseHandle (tt->hand))
5036	    msg (M_WARN | M_ERRNO, "Warning: CloseHandle failed on TAP-Windows adapter");
5037	}
5038
5039      if (tt->actual_name)
5040	free (tt->actual_name);
5041
5042      clear_tuntap (tt);
5043      free (tt);
5044    }
5045  gc_free (&gc);
5046}
5047
5048/*
5049 * Convert --ip-win32 constants between index and ascii form.
5050 */
5051
5052struct ipset_names {
5053  const char *short_form;
5054};
5055
5056/* Indexed by IPW32_SET_x */
5057static const struct ipset_names ipset_names[] = {
5058  {"manual"},
5059  {"netsh"},
5060  {"ipapi"},
5061  {"dynamic"},
5062  {"adaptive"}
5063};
5064
5065int
5066ascii2ipset (const char* name)
5067{
5068  int i;
5069  ASSERT (IPW32_SET_N == SIZE (ipset_names));
5070  for (i = 0; i < IPW32_SET_N; ++i)
5071    if (!strcmp (name, ipset_names[i].short_form))
5072      return i;
5073  return -1;
5074}
5075
5076const char *
5077ipset2ascii (int index)
5078{
5079  ASSERT (IPW32_SET_N == SIZE (ipset_names));
5080  if (index < 0 || index >= IPW32_SET_N)
5081    return "[unknown --ip-win32 type]";
5082  else
5083    return ipset_names[index].short_form;
5084}
5085
5086const char *
5087ipset2ascii_all (struct gc_arena *gc)
5088{
5089  struct buffer out = alloc_buf_gc (256, gc);
5090  int i;
5091
5092  ASSERT (IPW32_SET_N == SIZE (ipset_names));
5093  for (i = 0; i < IPW32_SET_N; ++i)
5094    {
5095      if (i)
5096	buf_printf(&out, " ");
5097      buf_printf(&out, "[%s]", ipset2ascii(i));
5098    }
5099  return BSTR (&out);
5100}
5101
5102#else /* generic */
5103
5104void
5105open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
5106{
5107  open_tun_generic (dev, dev_type, dev_node, false, true, tt);
5108}
5109
5110void
5111close_tun (struct tuntap* tt)
5112{
5113  if (tt)
5114    {
5115      close_tun_generic (tt);
5116      free (tt);
5117    }
5118}
5119
5120int
5121write_tun (struct tuntap* tt, uint8_t *buf, int len)
5122{
5123  return write (tt->fd, buf, len);
5124}
5125
5126int
5127read_tun (struct tuntap* tt, uint8_t *buf, int len)
5128{
5129  return read (tt->fd, buf, len);
5130}
5131
5132#endif
5133