svn cleanup
[anytun.git] / openvpn / tun.c
blobe904a0ccfb4f08acfdf9a472e8b809710b05bacf
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.
8 * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
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.
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.
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
26 * Support routines for configuring and accessing TUN/TAP
27 * virtual network adapters.
29 * This file is based on the TUN/TAP driver interface routines
30 * from VTun by Maxim Krasnyansky <max_mk@yahoo.com>.
33 #ifdef WIN32
34 #include "config-win32.h"
35 #else
36 #include "config.h"
37 #endif
39 #include "syshead.h"
41 #include "tun.h"
42 #include "fdmisc.h"
43 #include "common.h"
44 #include "misc.h"
45 #include "socket.h"
46 #include "manage.h"
48 #include "memdbg.h"
50 #ifdef TARGET_SOLARIS
51 static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual);
52 #endif
54 bool
55 is_dev_type (const char *dev, const char *dev_type, const char *match_type)
57 ASSERT (match_type);
58 if (!dev)
59 return false;
60 if (dev_type)
61 return !strcmp (dev_type, match_type);
62 else
63 return !strncmp (dev, match_type, strlen (match_type));
66 int
67 dev_type_enum (const char *dev, const char *dev_type)
69 if (is_dev_type (dev, dev_type, "tun"))
70 return DEV_TYPE_TUN;
71 else if (is_dev_type (dev, dev_type, "tap"))
72 return DEV_TYPE_TAP;
73 else if (is_dev_type (dev, dev_type, "null"))
74 return DEV_TYPE_NULL;
75 else
76 return DEV_TYPE_UNDEF;
79 const char *
80 dev_type_string (const char *dev, const char *dev_type)
82 switch (dev_type_enum (dev, dev_type))
84 case DEV_TYPE_TUN:
85 return "tun";
86 case DEV_TYPE_TAP:
87 return "tap";
88 case DEV_TYPE_NULL:
89 return "null";
90 default:
91 return "[unknown-dev-type]";
95 const char *
96 dev_component_in_dev_node (const char *dev_node)
98 const char *ret;
99 const int dirsep = OS_SPECIFIC_DIRSEP;
101 if (dev_node)
103 ret = strrchr (dev_node, dirsep);
104 if (ret && *ret)
105 ++ret;
106 else
107 ret = dev_node;
108 if (*ret)
109 return ret;
111 return NULL;
115 * Try to predict the actual TUN/TAP device instance name,
116 * before the device is actually opened.
118 const char *
119 guess_tuntap_dev (const char *dev,
120 const char *dev_type,
121 const char *dev_node,
122 struct gc_arena *gc)
124 #ifdef WIN32
125 const int dt = dev_type_enum (dev, dev_type);
126 if (dt == DEV_TYPE_TUN || dt == DEV_TYPE_TAP)
128 return get_netsh_id (dev_node, gc);
130 #endif
132 /* default case */
133 return dev;
137 * Called by the open_tun function of OSes to check if we
138 * explicitly support IPv6.
140 * In this context, explicit means that the OS expects us to
141 * do something special to the tun socket in order to support
142 * IPv6, i.e. it is not transparent.
144 * ipv6_explicitly_supported should be set to false if we don't
145 * have any explicit IPv6 code in the tun device handler.
147 * If ipv6_explicitly_supported is true, then we have explicit
148 * OS-specific tun dev code for handling IPv6. If so, tt->ipv6
149 * is set according to the --tun-ipv6 command line option.
151 static void
152 ipv6_support (bool ipv6, bool ipv6_explicitly_supported, struct tuntap* tt)
154 tt->ipv6 = false;
155 if (ipv6_explicitly_supported)
156 tt->ipv6 = ipv6;
157 else if (ipv6)
158 msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS");
161 /* --ifconfig-nowarn disables some options sanity checking */
162 static const char ifconfig_warn_how_to_silence[] = "(silence this warning with --ifconfig-nowarn)";
165 * If !tun, make sure ifconfig_remote_netmask looks
166 * like a netmask.
168 * If tun, make sure ifconfig_remote_netmask looks
169 * like an IPv4 address.
171 static void
172 ifconfig_sanity_check (bool tun, in_addr_t addr)
174 struct gc_arena gc = gc_new ();
175 const bool looks_like_netmask = ((addr & 0xFF000000) == 0xFF000000);
176 if (tun)
178 if (looks_like_netmask)
179 msg (M_WARN, "WARNING: Since you are using --dev tun, the second argument to --ifconfig must be an IP address. You are using something (%s) that looks more like a netmask. %s",
180 print_in_addr_t (addr, 0, &gc),
181 ifconfig_warn_how_to_silence);
183 else /* tap */
185 if (!looks_like_netmask)
186 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",
187 ifconfig_warn_how_to_silence);
189 gc_free (&gc);
193 * For TAP-style devices, generate a broadcast address.
195 static in_addr_t
196 generate_ifconfig_broadcast_addr (in_addr_t local,
197 in_addr_t netmask)
199 return local | ~netmask;
203 * Check that --local and --remote addresses do not
204 * clash with ifconfig addresses or subnet.
206 static void
207 check_addr_clash (const char *name,
208 int type,
209 in_addr_t public,
210 in_addr_t local,
211 in_addr_t remote_netmask)
213 struct gc_arena gc = gc_new ();
214 #if 0
215 msg (M_INFO, "CHECK_ADDR_CLASH type=%d public=%s local=%s, remote_netmask=%s",
216 type,
217 print_in_addr_t (public, 0, &gc),
218 print_in_addr_t (local, 0, &gc),
219 print_in_addr_t (remote_netmask, 0, &gc));
220 #endif
222 if (public)
224 if (type == DEV_TYPE_TUN)
226 const in_addr_t test_netmask = 0xFFFFFF00;
227 const in_addr_t public_net = public & test_netmask;
228 const in_addr_t local_net = local & test_netmask;
229 const in_addr_t remote_net = remote_netmask & test_netmask;
231 if (public == local || public == remote_netmask)
232 msg (M_WARN,
233 "WARNING: --%s address [%s] conflicts with --ifconfig address pair [%s, %s]. %s",
234 name,
235 print_in_addr_t (public, 0, &gc),
236 print_in_addr_t (local, 0, &gc),
237 print_in_addr_t (remote_netmask, 0, &gc),
238 ifconfig_warn_how_to_silence);
240 if (public_net == local_net || public_net == remote_net)
241 msg (M_WARN,
242 "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",
243 name,
244 print_in_addr_t (public, 0, &gc),
245 print_in_addr_t (local, 0, &gc),
246 print_in_addr_t (remote_netmask, 0, &gc),
247 ifconfig_warn_how_to_silence);
249 else if (type == DEV_TYPE_TAP)
251 const in_addr_t public_network = public & remote_netmask;
252 const in_addr_t virtual_network = local & remote_netmask;
253 if (public_network == virtual_network)
254 msg (M_WARN,
255 "WARNING: --%s address [%s] conflicts with --ifconfig subnet [%s, %s] -- local and remote addresses cannot be inside of the --ifconfig subnet. %s",
256 name,
257 print_in_addr_t (public, 0, &gc),
258 print_in_addr_t (local, 0, &gc),
259 print_in_addr_t (remote_netmask, 0, &gc),
260 ifconfig_warn_how_to_silence);
263 gc_free (&gc);
267 * Complain if --dev tap and --ifconfig is used on an OS for which
268 * we don't have a custom tap ifconfig template below.
270 static void
271 no_tap_ifconfig ()
273 msg (M_FATAL, "Sorry but you cannot use --dev tap and --ifconfig together on this OS because I have not yet been programmed to understand the appropriate ifconfig syntax to use for TAP-style devices on this OS. Your best alternative is to use an --up script and do the ifconfig command manually.");
277 * Return a string to be used for options compatibility check
278 * between peers.
280 const char *
281 ifconfig_options_string (const struct tuntap* tt, bool remote, bool disable, struct gc_arena *gc)
283 struct buffer out = alloc_buf_gc (256, gc);
284 if (tt->did_ifconfig_setup && !disable)
286 if (tt->type == DEV_TYPE_TUN)
288 const char *l, *r;
289 if (remote)
291 r = print_in_addr_t (tt->local, 0, gc);
292 l = print_in_addr_t (tt->remote_netmask, 0, gc);
294 else
296 l = print_in_addr_t (tt->local, 0, gc);
297 r = print_in_addr_t (tt->remote_netmask, 0, gc);
299 buf_printf (&out, "%s %s", r, l);
301 else if (tt->type == DEV_TYPE_TAP)
303 buf_printf (&out, "%s %s",
304 print_in_addr_t (tt->local & tt->remote_netmask, 0, gc),
305 print_in_addr_t (tt->remote_netmask, 0, gc));
307 else
308 buf_printf (&out, "[undef]");
310 return BSTR (&out);
314 * Return a status string describing wait state.
316 const char *
317 tun_stat (const struct tuntap *tt, unsigned int rwflags, struct gc_arena *gc)
319 struct buffer out = alloc_buf_gc (64, gc);
320 if (tt)
322 if (rwflags & EVENT_READ)
324 buf_printf (&out, "T%s",
325 (tt->rwflags_debug & EVENT_READ) ? "R" : "r");
326 #ifdef WIN32
327 buf_printf (&out, "%s",
328 overlapped_io_state_ascii (&tt->reads));
329 #endif
331 if (rwflags & EVENT_WRITE)
333 buf_printf (&out, "T%s",
334 (tt->rwflags_debug & EVENT_WRITE) ? "W" : "w");
335 #ifdef WIN32
336 buf_printf (&out, "%s",
337 overlapped_io_state_ascii (&tt->writes));
338 #endif
341 else
343 buf_printf (&out, "T?");
345 return BSTR (&out);
349 * Init tun/tap object.
351 * Set up tuntap structure for ifconfig,
352 * but don't execute yet.
354 struct tuntap *
355 init_tun (const char *dev, /* --dev option */
356 const char *dev_type, /* --dev-type option */
357 const char *ifconfig_local_parm, /* --ifconfig parm 1 */
358 const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */
359 in_addr_t local_public,
360 in_addr_t remote_public,
361 const bool strict_warn,
362 struct env_set *es)
364 struct gc_arena gc = gc_new ();
365 struct tuntap *tt;
367 ALLOC_OBJ (tt, struct tuntap);
368 clear_tuntap (tt);
370 tt->type = dev_type_enum (dev, dev_type);
372 if (ifconfig_local_parm && ifconfig_remote_netmask_parm)
374 bool tun = false;
375 const char *ifconfig_local = NULL;
376 const char *ifconfig_remote_netmask = NULL;
377 const char *ifconfig_broadcast = NULL;
380 * We only handle TUN/TAP devices here, not --dev null devices.
382 if (tt->type == DEV_TYPE_TUN)
383 tun = true;
384 else if (tt->type == DEV_TYPE_TAP)
385 tun = false;
386 else
387 msg (M_FATAL, "'%s' is not a TUN/TAP device. The --ifconfig option works only for TUN/TAP devices.", dev);
390 * Convert arguments to binary IPv4 addresses.
393 tt->local = getaddr (
394 GETADDR_RESOLVE
395 | GETADDR_HOST_ORDER
396 | GETADDR_FATAL_ON_SIGNAL
397 | GETADDR_FATAL,
398 ifconfig_local_parm,
400 NULL,
401 NULL);
403 tt->remote_netmask = getaddr (
404 (tun ? GETADDR_RESOLVE : 0)
405 | GETADDR_HOST_ORDER
406 | GETADDR_FATAL_ON_SIGNAL
407 | GETADDR_FATAL,
408 ifconfig_remote_netmask_parm,
410 NULL,
411 NULL);
414 * Look for common errors in --ifconfig parms
416 if (strict_warn)
418 ifconfig_sanity_check (tun, tt->remote_netmask);
421 * If local_public or remote_public addresses are defined,
422 * make sure they do not clash with our virtual subnet.
425 check_addr_clash ("local",
426 tt->type,
427 local_public,
428 tt->local,
429 tt->remote_netmask);
431 check_addr_clash ("remote",
432 tt->type,
433 remote_public,
434 tt->local,
435 tt->remote_netmask);
439 * Set ifconfig parameters
441 ifconfig_local = print_in_addr_t (tt->local, 0, &gc);
442 ifconfig_remote_netmask = print_in_addr_t (tt->remote_netmask, 0, &gc);
445 * If TAP-style interface, generate broadcast address.
447 if (!tun)
449 tt->broadcast = generate_ifconfig_broadcast_addr (tt->local, tt->remote_netmask);
450 ifconfig_broadcast = print_in_addr_t (tt->broadcast, 0, &gc);
454 * Set environmental variables with ifconfig parameters.
456 if (es)
458 setenv_str (es, "ifconfig_local", ifconfig_local);
459 if (tun)
461 setenv_str (es, "ifconfig_remote", ifconfig_remote_netmask);
463 else
465 setenv_str (es, "ifconfig_netmask", ifconfig_remote_netmask);
466 setenv_str (es, "ifconfig_broadcast", ifconfig_broadcast);
470 tt->did_ifconfig_setup = true;
472 gc_free (&gc);
473 return tt;
477 * Platform specific tun initializations
479 void
480 init_tun_post (struct tuntap *tt,
481 const struct frame *frame,
482 const struct tuntap_options *options)
484 tt->options = *options;
485 #ifdef WIN32
486 overlapped_io_init (&tt->reads, frame, FALSE, true);
487 overlapped_io_init (&tt->writes, frame, TRUE, true);
488 tt->rw_handle.read = tt->reads.overlapped.hEvent;
489 tt->rw_handle.write = tt->writes.overlapped.hEvent;
490 tt->adapter_index = ~0;
491 #endif
494 /* execute the ifconfig command through the shell */
495 void
496 do_ifconfig (struct tuntap *tt,
497 const char *actual, /* actual device name */
498 int tun_mtu,
499 const struct env_set *es)
501 struct gc_arena gc = gc_new ();
503 if (tt->did_ifconfig_setup)
505 bool tun = false;
506 const char *ifconfig_local = NULL;
507 const char *ifconfig_remote_netmask = NULL;
508 const char *ifconfig_broadcast = NULL;
509 char command_line[256];
512 * We only handle TUN/TAP devices here, not --dev null devices.
514 if (tt->type == DEV_TYPE_TUN)
515 tun = true;
516 else if (tt->type == DEV_TYPE_TAP)
517 tun = false;
518 else
519 ASSERT (0); /* should have been caught in init_tun */
522 * Set ifconfig parameters
524 ifconfig_local = print_in_addr_t (tt->local, 0, &gc);
525 ifconfig_remote_netmask = print_in_addr_t (tt->remote_netmask, 0, &gc);
528 * If TAP-style device, generate broadcast address.
530 if (!tun)
531 ifconfig_broadcast = print_in_addr_t (tt->broadcast, 0, &gc);
533 #ifdef ENABLE_MANAGEMENT
534 if (management)
536 management_set_state (management,
537 OPENVPN_STATE_ASSIGN_IP,
538 NULL,
539 tt->local);
541 #endif
544 #if defined(TARGET_LINUX)
545 #ifdef CONFIG_FEATURE_IPROUTE
547 * Set the MTU for the device
549 openvpn_snprintf (command_line, sizeof (command_line),
550 IPROUTE_PATH " link set dev %s up mtu %d",
551 actual,
552 tun_mtu
554 msg (M_INFO, "%s", command_line);
555 system_check (command_line, es, S_FATAL, "Linux ip link set failed");
557 if (tun) {
560 * Set the address for the device
562 openvpn_snprintf (command_line, sizeof (command_line),
563 IPROUTE_PATH " addr add dev %s local %s peer %s",
564 actual,
565 ifconfig_local,
566 ifconfig_remote_netmask
568 msg (M_INFO, "%s", command_line);
569 system_check (command_line, es, S_FATAL, "Linux ip addr add failed");
570 } else {
571 openvpn_snprintf (command_line, sizeof (command_line),
572 IPROUTE_PATH " addr add dev %s %s/%d broadcast %s",
573 actual,
574 ifconfig_local,
575 count_netmask_bits(ifconfig_remote_netmask),
576 ifconfig_broadcast
578 msg (M_INFO, "%s", command_line);
579 system_check (command_line, es, S_FATAL, "Linux ip addr add failed");
581 tt->did_ifconfig = true;
582 #else
583 if (tun)
584 openvpn_snprintf (command_line, sizeof (command_line),
585 IFCONFIG_PATH " %s %s pointopoint %s mtu %d",
586 actual,
587 ifconfig_local,
588 ifconfig_remote_netmask,
589 tun_mtu
591 else
592 openvpn_snprintf (command_line, sizeof (command_line),
593 IFCONFIG_PATH " %s %s netmask %s mtu %d broadcast %s",
594 actual,
595 ifconfig_local,
596 ifconfig_remote_netmask,
597 tun_mtu,
598 ifconfig_broadcast
600 msg (M_INFO, "%s", command_line);
601 system_check (command_line, es, S_FATAL, "Linux ifconfig failed");
602 tt->did_ifconfig = true;
604 #endif /*CONFIG_FEATURE_IPROUTE*/
605 #elif defined(TARGET_SOLARIS)
607 /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
608 * example:
609 * ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
610 * ifconfig tun2 netmask 255.255.255.255
612 if (tun)
614 openvpn_snprintf (command_line, sizeof (command_line),
615 IFCONFIG_PATH " %s %s %s mtu %d up",
616 actual,
617 ifconfig_local,
618 ifconfig_remote_netmask,
619 tun_mtu
622 msg (M_INFO, "%s", command_line);
623 if (!system_check (command_line, es, 0, "Solaris ifconfig phase-1 failed"))
624 solaris_error_close (tt, es, actual);
626 openvpn_snprintf (command_line, sizeof (command_line),
627 IFCONFIG_PATH " %s netmask 255.255.255.255",
628 actual
631 else
632 no_tap_ifconfig ();
634 msg (M_INFO, "%s", command_line);
635 if (!system_check (command_line, es, 0, "Solaris ifconfig phase-2 failed"))
636 solaris_error_close (tt, es, actual);
638 tt->did_ifconfig = true;
640 #elif defined(TARGET_OPENBSD)
643 * OpenBSD tun devices appear to be persistent by default. It seems in order
644 * to make this work correctly, we need to delete the previous instance
645 * (if it exists), and re-ifconfig. Let me know if you know a better way.
648 openvpn_snprintf (command_line, sizeof (command_line),
649 IFCONFIG_PATH " %s destroy",
650 actual);
651 msg (M_INFO, "%s", command_line);
652 system_check (command_line, es, 0, NULL);
653 openvpn_snprintf (command_line, sizeof (command_line),
654 IFCONFIG_PATH " %s create",
655 actual);
656 msg (M_INFO, "%s", command_line);
657 system_check (command_line, es, 0, NULL);
658 msg (M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
660 /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
661 if (tun)
662 openvpn_snprintf (command_line, sizeof (command_line),
663 IFCONFIG_PATH " %s %s %s mtu %d netmask 255.255.255.255 up",
664 actual,
665 ifconfig_local,
666 ifconfig_remote_netmask,
667 tun_mtu
669 else
670 openvpn_snprintf (command_line, sizeof (command_line),
671 IFCONFIG_PATH " %s %s netmask %s mtu %d broadcast %s link0",
672 actual,
673 ifconfig_local,
674 ifconfig_remote_netmask,
675 tun_mtu,
676 ifconfig_broadcast
678 msg (M_INFO, "%s", command_line);
679 system_check (command_line, es, S_FATAL, "OpenBSD ifconfig failed");
680 tt->did_ifconfig = true;
682 #elif defined(TARGET_NETBSD)
684 if (tun)
685 openvpn_snprintf (command_line, sizeof (command_line),
686 IFCONFIG_PATH " %s %s %s mtu %d netmask 255.255.255.255 up",
687 actual,
688 ifconfig_local,
689 ifconfig_remote_netmask,
690 tun_mtu
692 else
694 * NetBSD has distinct tun and tap devices
695 * so we don't need the "link0" extra parameter to specify we want to do
696 * tunneling at the ethernet level
698 openvpn_snprintf (command_line, sizeof (command_line),
699 IFCONFIG_PATH " %s %s netmask %s mtu %d broadcast %s",
700 actual,
701 ifconfig_local,
702 ifconfig_remote_netmask,
703 tun_mtu,
704 ifconfig_broadcast
706 msg (M_INFO, "%s", command_line);
707 system_check (command_line, es, S_FATAL, "NetBSD ifconfig failed");
708 tt->did_ifconfig = true;
710 #elif defined(TARGET_DARWIN)
713 * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
716 openvpn_snprintf (command_line, sizeof (command_line),
717 IFCONFIG_PATH " %s delete",
718 actual);
719 msg (M_INFO, "%s", command_line);
720 system_check (command_line, es, 0, NULL);
721 msg (M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
724 /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
725 if (tun)
726 openvpn_snprintf (command_line, sizeof (command_line),
727 IFCONFIG_PATH " %s %s %s mtu %d netmask 255.255.255.255 up",
728 actual,
729 ifconfig_local,
730 ifconfig_remote_netmask,
731 tun_mtu
733 else
734 openvpn_snprintf (command_line, sizeof (command_line),
735 IFCONFIG_PATH " %s %s netmask %s mtu %d up",
736 actual,
737 ifconfig_local,
738 ifconfig_remote_netmask,
739 tun_mtu
742 msg (M_INFO, "%s", command_line);
743 system_check (command_line, es, S_FATAL, "Mac OS X ifconfig failed");
744 tt->did_ifconfig = true;
746 #elif defined(TARGET_FREEBSD)
748 /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
749 if (tun)
750 openvpn_snprintf (command_line, sizeof (command_line),
751 IFCONFIG_PATH " %s %s %s mtu %d netmask 255.255.255.255 up",
752 actual,
753 ifconfig_local,
754 ifconfig_remote_netmask,
755 tun_mtu
757 else
758 openvpn_snprintf (command_line, sizeof (command_line),
759 IFCONFIG_PATH " %s %s netmask %s mtu %d up",
760 actual,
761 ifconfig_local,
762 ifconfig_remote_netmask,
763 tun_mtu
766 msg (M_INFO, "%s", command_line);
767 system_check (command_line, es, S_FATAL, "FreeBSD ifconfig failed");
768 tt->did_ifconfig = true;
770 #elif defined (WIN32)
772 const char *netmask;
775 * Make sure that both ifconfig addresses are part of the
776 * same .252 subnet.
778 if (tun)
780 verify_255_255_255_252 (tt->local, tt->remote_netmask);
781 tt->adapter_netmask = ~3;
782 netmask = print_in_addr_t (tt->adapter_netmask, 0, &gc);
784 else
786 netmask = ifconfig_remote_netmask;
787 tt->adapter_netmask = tt->remote_netmask;
790 /* example: netsh interface ip set address my-tap static 10.3.0.1 255.255.255.0 */
791 openvpn_snprintf (command_line, sizeof (command_line),
792 "netsh interface ip set address \"%s\" static %s %s",
793 actual,
794 ifconfig_local,
795 netmask);
797 switch (tt->options.ip_win32_type)
799 case IPW32_SET_MANUAL:
800 msg (M_INFO, "******** NOTE: Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
801 actual,
802 ifconfig_local,
803 netmask);
804 break;
805 case IPW32_SET_NETSH:
806 if (!strcmp (actual, "NULL"))
807 msg (M_FATAL, "Error: When using --ip-win32 netsh, if you have more than one TAP-Win32 adapter, you must also specify --dev-node");
808 netcmd_semaphore_lock ();
809 msg (M_INFO, "%s", command_line);
810 system_check (command_line, es, S_FATAL, "ERROR: netsh command failed");
811 netcmd_semaphore_release ();
812 break;
814 tt->did_ifconfig = true;
817 #else
818 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.");
819 #endif
821 gc_free (&gc);
824 void
825 clear_tuntap (struct tuntap *tuntap)
827 CLEAR (*tuntap);
828 #ifdef WIN32
829 tuntap->hand = NULL;
830 #else
831 tuntap->fd = -1;
832 #endif
833 #ifdef TARGET_SOLARIS
834 tuntap->ip_fd = -1;
835 #endif
836 tuntap->ipv6 = false;
839 static void
840 open_null (struct tuntap *tt)
842 tt->actual_name = string_alloc ("null", NULL);
845 #ifndef WIN32
846 static void
847 open_tun_generic (const char *dev, const char *dev_type, const char *dev_node,
848 bool ipv6, bool ipv6_explicitly_supported, bool dynamic,
849 struct tuntap *tt)
851 char tunname[256];
852 char dynamic_name[256];
853 bool dynamic_opened = false;
855 ipv6_support (ipv6, ipv6_explicitly_supported, tt);
857 if (tt->type == DEV_TYPE_NULL)
859 open_null (tt);
861 else
864 * --dev-node specified, so open an explicit device node
866 if (dev_node)
868 openvpn_snprintf (tunname, sizeof (tunname), "%s", dev_node);
870 else
873 * dynamic open is indicated by --dev specified without
874 * explicit unit number. Try opening /dev/[dev]n
875 * where n = [0, 255].
877 if (dynamic && !has_digit(dev))
879 int i;
880 for (i = 0; i < 256; ++i)
882 openvpn_snprintf (tunname, sizeof (tunname),
883 "/dev/%s%d", dev, i);
884 openvpn_snprintf (dynamic_name, sizeof (dynamic_name),
885 "%s%d", dev, i);
886 if ((tt->fd = open (tunname, O_RDWR)) > 0)
888 dynamic_opened = true;
889 break;
891 msg (D_READ_WRITE | M_ERRNO, "Tried opening %s (failed)", tunname);
893 if (!dynamic_opened)
894 msg (M_FATAL, "Cannot allocate TUN/TAP dev dynamically");
897 * explicit unit number specified
899 else
901 openvpn_snprintf (tunname, sizeof (tunname), "/dev/%s", dev);
905 if (!dynamic_opened)
907 if ((tt->fd = open (tunname, O_RDWR)) < 0)
908 msg (M_ERR, "Cannot open TUN/TAP dev %s", tunname);
911 set_nonblock (tt->fd);
912 set_cloexec (tt->fd); /* don't pass fd to scripts */
913 msg (M_INFO, "TUN/TAP device %s opened", tunname);
915 /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
916 tt->actual_name = string_alloc (dynamic_opened ? dynamic_name : dev, NULL);
920 static void
921 close_tun_generic (struct tuntap *tt)
923 if (tt->fd >= 0)
924 close (tt->fd);
925 if (tt->actual_name)
926 free (tt->actual_name);
927 clear_tuntap (tt);
930 #endif
932 #if defined(TARGET_LINUX)
934 #ifdef HAVE_LINUX_IF_TUN_H /* New driver support */
936 #ifndef HAVE_LINUX_SOCKIOS_H
937 #error header file linux/sockios.h required
938 #endif
940 #if defined(HAVE_TUN_PI) && defined(HAVE_IPHDR) && defined(HAVE_IOVEC) && defined(ETH_P_IPV6) && defined(ETH_P_IP) && defined(HAVE_READV) && defined(HAVE_WRITEV)
941 #define LINUX_IPV6 1
942 /* #warning IPv6 ON */
943 #else
944 #define LINUX_IPV6 0
945 /* #warning IPv6 OFF */
946 #endif
948 #if !PEDANTIC
950 void
951 open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
953 struct ifreq ifr;
956 * Set tt->ipv6 to true if
957 * (a) we have the capability of supporting --tun-ipv6, and
958 * (b) --tun-ipv6 was specified.
960 ipv6_support (ipv6, LINUX_IPV6, tt);
963 * We handle --dev null specially, we do not open /dev/null for this.
965 if (tt->type == DEV_TYPE_NULL)
967 open_null (tt);
969 else
972 * Process --dev-node
974 const char *node = dev_node;
975 if (!node)
976 node = "/dev/net/tun";
979 * Open the interface
981 if ((tt->fd = open (node, O_RDWR)) < 0)
983 msg (M_WARN | M_ERRNO, "Note: Cannot open TUN/TAP dev %s", node);
984 goto linux_2_2_fallback;
988 * Process --tun-ipv6
990 CLEAR (ifr);
991 if (!tt->ipv6)
992 ifr.ifr_flags = IFF_NO_PI;
994 #if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
995 ifr.ifr_flags |= IFF_ONE_QUEUE;
996 #endif
999 * Figure out if tun or tap device
1001 if (tt->type == DEV_TYPE_TUN)
1003 ifr.ifr_flags |= IFF_TUN;
1005 else if (tt->type == DEV_TYPE_TAP)
1007 ifr.ifr_flags |= IFF_TAP;
1009 else
1011 msg (M_FATAL, "I don't recognize device %s as a tun or tap device",
1012 dev);
1016 * Set an explicit name, if --dev is not tun or tap
1018 if (strcmp(dev, "tun") && strcmp(dev, "tap"))
1019 strncpynt (ifr.ifr_name, dev, IFNAMSIZ);
1022 * Use special ioctl that configures tun/tap device with the parms
1023 * we set in ifr
1025 if (ioctl (tt->fd, TUNSETIFF, (void *) &ifr) < 0)
1027 msg (M_WARN | M_ERRNO, "Note: Cannot ioctl TUNSETIFF %s", dev);
1028 goto linux_2_2_fallback;
1031 msg (M_INFO, "TUN/TAP device %s opened", ifr.ifr_name);
1034 * Try making the TX send queue bigger
1036 #if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
1038 struct ifreq netifr;
1039 int ctl_fd;
1041 if ((ctl_fd = socket (AF_INET, SOCK_DGRAM, 0)) >= 0)
1043 CLEAR (netifr);
1044 strncpynt (netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
1045 netifr.ifr_qlen = tt->options.txqueuelen;
1046 if (ioctl (ctl_fd, SIOCSIFTXQLEN, (void *) &netifr) >= 0)
1047 msg (D_OSBUF, "TUN/TAP TX queue length set to %d", tt->options.txqueuelen);
1048 else
1049 msg (M_WARN | M_ERRNO, "Note: Cannot set tx queue length on %s", ifr.ifr_name);
1050 close (ctl_fd);
1052 else
1054 msg (M_WARN | M_ERRNO, "Note: Cannot open control socket on %s", ifr.ifr_name);
1057 #endif
1059 set_nonblock (tt->fd);
1060 set_cloexec (tt->fd);
1061 tt->actual_name = string_alloc (ifr.ifr_name, NULL);
1063 return;
1065 linux_2_2_fallback:
1066 msg (M_INFO, "Note: Attempting fallback to kernel 2.2 TUN/TAP interface");
1067 if (tt->fd >= 0)
1069 close (tt->fd);
1070 tt->fd = -1;
1072 open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt);
1075 #else
1077 void
1078 open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
1080 ASSERT (0);
1083 #endif
1085 #else
1087 void
1088 open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
1090 open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt);
1093 #endif /* HAVE_LINUX_IF_TUN_H */
1095 #ifdef TUNSETPERSIST
1097 void
1098 tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, int persist_mode)
1100 struct tuntap *tt;
1102 ALLOC_OBJ (tt, struct tuntap);
1103 clear_tuntap (tt);
1104 tt->type = dev_type_enum (dev, dev_type);
1105 open_tun (dev, dev_type, dev_node, ipv6, tt);
1106 if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0)
1107 msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
1108 close_tun (tt);
1109 msg (M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF"));
1112 #endif /* TUNSETPERSIST */
1114 void
1115 close_tun (struct tuntap *tt)
1117 if (tt)
1119 close_tun_generic (tt);
1120 free (tt);
1125 write_tun (struct tuntap* tt, uint8_t *buf, int len)
1127 #if LINUX_IPV6
1128 if (tt->ipv6)
1130 struct tun_pi pi;
1131 struct iphdr *iph;
1132 struct iovec vect[2];
1133 int ret;
1135 iph = (struct iphdr *)buf;
1137 pi.flags = 0;
1139 if(iph->version == 6)
1140 pi.proto = htons(ETH_P_IPV6);
1141 else
1142 pi.proto = htons(ETH_P_IP);
1144 vect[0].iov_len = sizeof(pi);
1145 vect[0].iov_base = &pi;
1146 vect[1].iov_len = len;
1147 vect[1].iov_base = buf;
1149 ret = writev(tt->fd, vect, 2);
1150 return(ret - sizeof(pi));
1152 else
1153 #endif
1154 return write (tt->fd, buf, len);
1158 read_tun (struct tuntap* tt, uint8_t *buf, int len)
1160 #if LINUX_IPV6
1161 if (tt->ipv6)
1163 struct iovec vect[2];
1164 struct tun_pi pi;
1165 int ret;
1167 vect[0].iov_len = sizeof(pi);
1168 vect[0].iov_base = &pi;
1169 vect[1].iov_len = len;
1170 vect[1].iov_base = buf;
1172 ret = readv(tt->fd, vect, 2);
1173 return(ret - sizeof(pi));
1175 else
1176 #endif
1177 return read (tt->fd, buf, len);
1180 #elif defined(TARGET_SOLARIS)
1182 #ifndef TUNNEWPPA
1183 #error I need the symbol TUNNEWPPA from net/if_tun.h
1184 #endif
1186 void
1187 open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
1189 int if_fd, muxid, ppa = -1;
1190 struct ifreq ifr;
1191 const char *ptr;
1192 const char *ip_node;
1193 const char *dev_tuntap_type;
1194 int link_type;
1195 bool is_tun;
1197 ipv6_support (ipv6, false, tt);
1199 if (tt->type == DEV_TYPE_NULL)
1201 open_null (tt);
1202 return;
1205 if (tt->type == DEV_TYPE_TUN)
1207 ip_node = "/dev/udp";
1208 if (!dev_node)
1209 dev_node = "/dev/tun";
1210 dev_tuntap_type = "tun";
1211 link_type = I_PLINK;
1212 is_tun = true;
1214 else if (tt->type == DEV_TYPE_TAP)
1216 ip_node = "/dev/ip";
1217 if (!dev_node)
1218 dev_node = "/dev/tap";
1219 dev_tuntap_type = "tap";
1220 link_type = I_PLINK; /* was: I_LINK */
1221 is_tun = false;
1223 else
1225 msg (M_FATAL, "I don't recognize device %s as a tun or tap device",
1226 dev);
1229 /* get unit number */
1230 if (*dev)
1232 ptr = dev;
1233 while (*ptr && !isdigit ((int) *ptr))
1234 ptr++;
1235 ppa = atoi (ptr);
1238 if ((tt->ip_fd = open (ip_node, O_RDWR, 0)) < 0)
1239 msg (M_ERR, "Can't open %s", ip_node);
1241 if ((tt->fd = open (dev_node, O_RDWR, 0)) < 0)
1242 msg (M_ERR, "Can't open %s", dev_node);
1244 /* Assign a new PPA and get its unit number. */
1245 if ((ppa = ioctl (tt->fd, TUNNEWPPA, ppa)) < 0)
1246 msg (M_ERR, "Can't assign new interface");
1248 if ((if_fd = open (dev_node, O_RDWR, 0)) < 0)
1249 msg (M_ERR, "Can't open %s (2)", dev_node);
1251 if (ioctl (if_fd, I_PUSH, "ip") < 0)
1252 msg (M_ERR, "Can't push IP module");
1254 /* Assign ppa according to the unit number returned by tun device */
1255 if (ioctl (if_fd, IF_UNITSEL, (char *) &ppa) < 0)
1256 msg (M_ERR, "Can't set PPA %d", ppa);
1258 if ((muxid = ioctl (tt->ip_fd, link_type, if_fd)) < 0)
1259 msg (M_ERR, "Can't link %s device to IP", dev_tuntap_type);
1261 close (if_fd);
1263 tt->actual_name = (char *) malloc (32);
1264 check_malloc_return (tt->actual_name);
1266 openvpn_snprintf (tt->actual_name, 32, "%s%d", dev_tuntap_type, ppa);
1268 CLEAR (ifr);
1269 strncpynt (ifr.ifr_name, tt->actual_name, sizeof (ifr.ifr_name));
1270 ifr.ifr_ip_muxid = muxid;
1272 if (ioctl (tt->ip_fd, SIOCSIFMUXID, &ifr) < 0)
1274 ioctl (tt->ip_fd, I_PUNLINK, muxid);
1275 msg (M_ERR, "Can't set multiplexor id");
1278 set_nonblock (tt->fd);
1279 set_cloexec (tt->fd);
1280 set_cloexec (tt->ip_fd);
1282 msg (M_INFO, "TUN/TAP device %s opened", tt->actual_name);
1285 static void
1286 solaris_close_tun (struct tuntap *tt)
1288 if (tt)
1290 if (tt->ip_fd >= 0)
1292 struct ifreq ifr;
1293 CLEAR (ifr);
1294 strncpynt (ifr.ifr_name, tt->actual_name, sizeof (ifr.ifr_name));
1296 if (ioctl (tt->ip_fd, SIOCGIFFLAGS, &ifr) < 0)
1297 msg (M_WARN | M_ERRNO, "Can't get iface flags");
1299 if (ioctl (tt->ip_fd, SIOCGIFMUXID, &ifr) < 0)
1300 msg (M_WARN | M_ERRNO, "Can't get multiplexor id");
1302 if (ioctl (tt->ip_fd, I_PUNLINK, ifr.ifr_ip_muxid) < 0)
1303 msg (M_WARN | M_ERRNO, "Can't unlink interface");
1305 close (tt->ip_fd);
1306 tt->ip_fd = -1;
1309 if (tt->fd >= 0)
1311 close (tt->fd);
1312 tt->fd = -1;
1318 * Close TUN device.
1320 void
1321 close_tun (struct tuntap *tt)
1323 if (tt)
1325 solaris_close_tun (tt);
1327 if (tt->actual_name)
1328 free (tt->actual_name);
1330 clear_tuntap (tt);
1331 free (tt);
1335 static void
1336 solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual)
1338 char command_line[256];
1340 openvpn_snprintf (command_line, sizeof (command_line),
1341 IFCONFIG_PATH " %s unplumb",
1342 actual);
1344 msg (M_INFO, "%s", command_line);
1345 system_check (command_line, es, 0, "Solaris ifconfig unplumb failed");
1346 close_tun (tt);
1347 msg (M_FATAL, "Solaris ifconfig failed");
1351 write_tun (struct tuntap* tt, uint8_t *buf, int len)
1353 struct strbuf sbuf;
1354 sbuf.len = len;
1355 sbuf.buf = (char *)buf;
1356 return putmsg (tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
1360 read_tun (struct tuntap* tt, uint8_t *buf, int len)
1362 struct strbuf sbuf;
1363 int f = 0;
1365 sbuf.maxlen = len;
1366 sbuf.buf = (char *)buf;
1367 return getmsg (tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
1370 #elif defined(TARGET_OPENBSD)
1372 #if !defined(HAVE_READV) || !defined(HAVE_WRITEV)
1373 #error openbsd build requires readv & writev library functions
1374 #endif
1377 * OpenBSD has a slightly incompatible TUN device from
1378 * the rest of the world, in that it prepends a
1379 * uint32 to the beginning of the IP header
1380 * to designate the protocol (why not just
1381 * look at the version field in the IP header to
1382 * determine v4 or v6?).
1384 * We strip off this field on reads and
1385 * put it back on writes.
1387 * I have not tested TAP devices on OpenBSD,
1388 * but I have conditionalized the special
1389 * TUN handling code described above to
1390 * go away for TAP devices.
1393 void
1394 open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
1396 open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt);
1398 /* Enable multicast on the interface */
1399 if (tt->fd >= 0)
1401 struct tuninfo info;
1403 if (ioctl (tt->fd, TUNGIFINFO, &info) < 0) {
1404 msg (M_WARN | M_ERRNO, "Can't get interface info: %s",
1405 strerror(errno));
1408 info.flags |= IFF_MULTICAST;
1410 if (ioctl (tt->fd, TUNSIFINFO, &info) < 0) {
1411 msg (M_WARN | M_ERRNO, "Can't set interface info: %s",
1412 strerror(errno));
1417 void
1418 close_tun (struct tuntap* tt)
1420 if (tt)
1422 close_tun_generic (tt);
1423 free (tt);
1427 static inline int
1428 openbsd_modify_read_write_return (int len)
1430 if (len > 0)
1431 return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
1432 else
1433 return len;
1437 write_tun (struct tuntap* tt, uint8_t *buf, int len)
1439 if (tt->type == DEV_TYPE_TUN)
1441 u_int32_t type;
1442 struct iovec iv[2];
1443 struct ip *iph;
1445 iph = (struct ip *) buf;
1447 if (tt->ipv6 && iph->ip_v == 6)
1448 type = htonl (AF_INET6);
1449 else
1450 type = htonl (AF_INET);
1452 iv[0].iov_base = &type;
1453 iv[0].iov_len = sizeof (type);
1454 iv[1].iov_base = buf;
1455 iv[1].iov_len = len;
1457 return openbsd_modify_read_write_return (writev (tt->fd, iv, 2));
1459 else
1460 return write (tt->fd, buf, len);
1464 read_tun (struct tuntap* tt, uint8_t *buf, int len)
1466 if (tt->type == DEV_TYPE_TUN)
1468 u_int32_t type;
1469 struct iovec iv[2];
1471 iv[0].iov_base = &type;
1472 iv[0].iov_len = sizeof (type);
1473 iv[1].iov_base = buf;
1474 iv[1].iov_len = len;
1476 return openbsd_modify_read_write_return (readv (tt->fd, iv, 2));
1478 else
1479 return read (tt->fd, buf, len);
1482 #elif defined(TARGET_NETBSD)
1485 * NetBSD does not support IPv6 on tun out of the box,
1486 * but there exists a patch. When this patch is applied,
1487 * only two things are left to openvpn:
1488 * 1. Activate multicasting (this has already been done
1489 * before by the kernel, but we make sure that nobody
1490 * has deactivated multicasting inbetween.
1491 * 2. Deactivate "link layer mode" (otherwise NetBSD
1492 * prepends the address family to the packet, and we
1493 * would run into the same trouble as with OpenBSD.
1496 void
1497 open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
1499 open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt);
1500 if (tt->fd >= 0)
1502 int i = IFF_POINTOPOINT|IFF_MULTICAST;
1503 ioctl (tt->fd, TUNSIFMODE, &i); /* multicast on */
1504 i = 0;
1505 ioctl (tt->fd, TUNSLMODE, &i); /* link layer mode off */
1509 void
1510 close_tun (struct tuntap *tt)
1512 if (tt)
1514 close_tun_generic (tt);
1515 free (tt);
1520 write_tun (struct tuntap* tt, uint8_t *buf, int len)
1522 return write (tt->fd, buf, len);
1526 read_tun (struct tuntap* tt, uint8_t *buf, int len)
1528 return read (tt->fd, buf, len);
1531 #elif defined(TARGET_FREEBSD)
1533 static inline int
1534 freebsd_modify_read_write_return (int len)
1536 if (len > 0)
1537 return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
1538 else
1539 return len;
1542 void
1543 open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
1545 open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt);
1547 if (tt->fd >= 0)
1549 int i = 0;
1551 /* Disable extended modes */
1552 ioctl (tt->fd, TUNSLMODE, &i);
1553 i = 1;
1554 ioctl (tt->fd, TUNSIFHEAD, &i);
1558 void
1559 close_tun (struct tuntap *tt)
1561 if (tt)
1563 close_tun_generic (tt);
1564 free (tt);
1569 write_tun (struct tuntap* tt, uint8_t *buf, int len)
1571 if (tt->type == DEV_TYPE_TUN)
1573 u_int32_t type;
1574 struct iovec iv[2];
1575 struct ip *iph;
1577 iph = (struct ip *) buf;
1579 if (tt->ipv6 && iph->ip_v == 6)
1580 type = htonl (AF_INET6);
1581 else
1582 type = htonl (AF_INET);
1584 iv[0].iov_base = (char *)&type;
1585 iv[0].iov_len = sizeof (type);
1586 iv[1].iov_base = buf;
1587 iv[1].iov_len = len;
1589 return freebsd_modify_read_write_return (writev (tt->fd, iv, 2));
1591 else
1592 return write (tt->fd, buf, len);
1596 read_tun (struct tuntap* tt, uint8_t *buf, int len)
1598 if (tt->type == DEV_TYPE_TUN)
1600 u_int32_t type;
1601 struct iovec iv[2];
1603 iv[0].iov_base = (char *)&type;
1604 iv[0].iov_len = sizeof (type);
1605 iv[1].iov_base = buf;
1606 iv[1].iov_len = len;
1608 return freebsd_modify_read_write_return (readv (tt->fd, iv, 2));
1610 else
1611 return read (tt->fd, buf, len);
1614 #elif defined(WIN32)
1617 tun_read_queue (struct tuntap *tt, int maxsize)
1619 if (tt->reads.iostate == IOSTATE_INITIAL)
1621 DWORD len;
1622 BOOL status;
1623 int err;
1625 /* reset buf to its initial state */
1626 tt->reads.buf = tt->reads.buf_init;
1628 len = maxsize ? maxsize : BLEN (&tt->reads.buf);
1629 ASSERT (len <= BLEN (&tt->reads.buf));
1631 /* the overlapped read will signal this event on I/O completion */
1632 ASSERT (ResetEvent (tt->reads.overlapped.hEvent));
1634 status = ReadFile(
1635 tt->hand,
1636 BPTR (&tt->reads.buf),
1637 len,
1638 &tt->reads.size,
1639 &tt->reads.overlapped
1642 if (status) /* operation completed immediately? */
1644 /* since we got an immediate return, we must signal the event object ourselves */
1645 ASSERT (SetEvent (tt->reads.overlapped.hEvent));
1647 tt->reads.iostate = IOSTATE_IMMEDIATE_RETURN;
1648 tt->reads.status = 0;
1650 dmsg (D_WIN32_IO, "WIN32 I/O: TAP Read immediate return [%d,%d]",
1651 (int) len,
1652 (int) tt->reads.size);
1654 else
1656 err = GetLastError ();
1657 if (err == ERROR_IO_PENDING) /* operation queued? */
1659 tt->reads.iostate = IOSTATE_QUEUED;
1660 tt->reads.status = err;
1661 dmsg (D_WIN32_IO, "WIN32 I/O: TAP Read queued [%d]",
1662 (int) len);
1664 else /* error occurred */
1666 struct gc_arena gc = gc_new ();
1667 ASSERT (SetEvent (tt->reads.overlapped.hEvent));
1668 tt->reads.iostate = IOSTATE_IMMEDIATE_RETURN;
1669 tt->reads.status = err;
1670 dmsg (D_WIN32_IO, "WIN32 I/O: TAP Read error [%d] : %s",
1671 (int) len,
1672 strerror_win32 (status, &gc));
1673 gc_free (&gc);
1677 return tt->reads.iostate;
1681 tun_write_queue (struct tuntap *tt, struct buffer *buf)
1683 if (tt->writes.iostate == IOSTATE_INITIAL)
1685 BOOL status;
1686 int err;
1688 /* make a private copy of buf */
1689 tt->writes.buf = tt->writes.buf_init;
1690 tt->writes.buf.len = 0;
1691 ASSERT (buf_copy (&tt->writes.buf, buf));
1693 /* the overlapped write will signal this event on I/O completion */
1694 ASSERT (ResetEvent (tt->writes.overlapped.hEvent));
1696 status = WriteFile(
1697 tt->hand,
1698 BPTR (&tt->writes.buf),
1699 BLEN (&tt->writes.buf),
1700 &tt->writes.size,
1701 &tt->writes.overlapped
1704 if (status) /* operation completed immediately? */
1706 tt->writes.iostate = IOSTATE_IMMEDIATE_RETURN;
1708 /* since we got an immediate return, we must signal the event object ourselves */
1709 ASSERT (SetEvent (tt->writes.overlapped.hEvent));
1711 tt->writes.status = 0;
1713 dmsg (D_WIN32_IO, "WIN32 I/O: TAP Write immediate return [%d,%d]",
1714 BLEN (&tt->writes.buf),
1715 (int) tt->writes.size);
1717 else
1719 err = GetLastError ();
1720 if (err == ERROR_IO_PENDING) /* operation queued? */
1722 tt->writes.iostate = IOSTATE_QUEUED;
1723 tt->writes.status = err;
1724 dmsg (D_WIN32_IO, "WIN32 I/O: TAP Write queued [%d]",
1725 BLEN (&tt->writes.buf));
1727 else /* error occurred */
1729 struct gc_arena gc = gc_new ();
1730 ASSERT (SetEvent (tt->writes.overlapped.hEvent));
1731 tt->writes.iostate = IOSTATE_IMMEDIATE_RETURN;
1732 tt->writes.status = err;
1733 dmsg (D_WIN32_IO, "WIN32 I/O: TAP Write error [%d] : %s",
1734 BLEN (&tt->writes.buf),
1735 strerror_win32 (err, &gc));
1736 gc_free (&gc);
1740 return tt->writes.iostate;
1744 tun_finalize (
1745 HANDLE h,
1746 struct overlapped_io *io,
1747 struct buffer *buf)
1749 int ret = -1;
1750 BOOL status;
1752 switch (io->iostate)
1754 case IOSTATE_QUEUED:
1755 status = GetOverlappedResult(
1757 &io->overlapped,
1758 &io->size,
1759 FALSE
1761 if (status)
1763 /* successful return for a queued operation */
1764 if (buf)
1765 *buf = io->buf;
1766 ret = io->size;
1767 io->iostate = IOSTATE_INITIAL;
1768 ASSERT (ResetEvent (io->overlapped.hEvent));
1769 dmsg (D_WIN32_IO, "WIN32 I/O: TAP Completion success [%d]", ret);
1771 else
1773 /* error during a queued operation */
1774 ret = -1;
1775 if (GetLastError() != ERROR_IO_INCOMPLETE)
1777 /* if no error (i.e. just not finished yet),
1778 then DON'T execute this code */
1779 io->iostate = IOSTATE_INITIAL;
1780 ASSERT (ResetEvent (io->overlapped.hEvent));
1781 msg (D_WIN32_IO | M_ERRNO, "WIN32 I/O: TAP Completion error");
1784 break;
1786 case IOSTATE_IMMEDIATE_RETURN:
1787 io->iostate = IOSTATE_INITIAL;
1788 ASSERT (ResetEvent (io->overlapped.hEvent));
1789 if (io->status)
1791 /* error return for a non-queued operation */
1792 SetLastError (io->status);
1793 ret = -1;
1794 msg (D_WIN32_IO | M_ERRNO, "WIN32 I/O: TAP Completion non-queued error");
1796 else
1798 /* successful return for a non-queued operation */
1799 if (buf)
1800 *buf = io->buf;
1801 ret = io->size;
1802 dmsg (D_WIN32_IO, "WIN32 I/O: TAP Completion non-queued success [%d]", ret);
1804 break;
1806 case IOSTATE_INITIAL: /* were we called without proper queueing? */
1807 SetLastError (ERROR_INVALID_FUNCTION);
1808 ret = -1;
1809 dmsg (D_WIN32_IO, "WIN32 I/O: TAP Completion BAD STATE");
1810 break;
1812 default:
1813 ASSERT (0);
1816 if (buf)
1817 buf->len = ret;
1818 return ret;
1821 const struct tap_reg *
1822 get_tap_reg (struct gc_arena *gc)
1824 HKEY adapter_key;
1825 LONG status;
1826 DWORD len;
1827 struct tap_reg *first = NULL;
1828 struct tap_reg *last = NULL;
1829 int i = 0;
1831 status = RegOpenKeyEx(
1832 HKEY_LOCAL_MACHINE,
1833 ADAPTER_KEY,
1835 KEY_READ,
1836 &adapter_key);
1838 if (status != ERROR_SUCCESS)
1839 msg (M_FATAL, "Error opening registry key: %s", ADAPTER_KEY);
1841 while (true)
1843 char enum_name[256];
1844 char unit_string[256];
1845 HKEY unit_key;
1846 char component_id_string[] = "ComponentId";
1847 char component_id[256];
1848 char net_cfg_instance_id_string[] = "NetCfgInstanceId";
1849 char net_cfg_instance_id[256];
1850 DWORD data_type;
1852 len = sizeof (enum_name);
1853 status = RegEnumKeyEx(
1854 adapter_key,
1856 enum_name,
1857 &len,
1858 NULL,
1859 NULL,
1860 NULL,
1861 NULL);
1862 if (status == ERROR_NO_MORE_ITEMS)
1863 break;
1864 else if (status != ERROR_SUCCESS)
1865 msg (M_FATAL, "Error enumerating registry subkeys of key: %s",
1866 ADAPTER_KEY);
1868 openvpn_snprintf (unit_string, sizeof(unit_string), "%s\\%s",
1869 ADAPTER_KEY, enum_name);
1871 status = RegOpenKeyEx(
1872 HKEY_LOCAL_MACHINE,
1873 unit_string,
1875 KEY_READ,
1876 &unit_key);
1878 if (status != ERROR_SUCCESS)
1879 dmsg (D_REGISTRY, "Error opening registry key: %s", unit_string);
1880 else
1882 len = sizeof (component_id);
1883 status = RegQueryValueEx(
1884 unit_key,
1885 component_id_string,
1886 NULL,
1887 &data_type,
1888 component_id,
1889 &len);
1891 if (status != ERROR_SUCCESS || data_type != REG_SZ)
1892 dmsg (D_REGISTRY, "Error opening registry key: %s\\%s",
1893 unit_string, component_id_string);
1894 else
1896 len = sizeof (net_cfg_instance_id);
1897 status = RegQueryValueEx(
1898 unit_key,
1899 net_cfg_instance_id_string,
1900 NULL,
1901 &data_type,
1902 net_cfg_instance_id,
1903 &len);
1905 if (status == ERROR_SUCCESS && data_type == REG_SZ)
1907 if (!strcmp (component_id, TAP_COMPONENT_ID))
1909 struct tap_reg *reg;
1910 ALLOC_OBJ_CLEAR_GC (reg, struct tap_reg, gc);
1911 reg->guid = string_alloc (net_cfg_instance_id, gc);
1913 /* link into return list */
1914 if (!first)
1915 first = reg;
1916 if (last)
1917 last->next = reg;
1918 last = reg;
1922 RegCloseKey (unit_key);
1924 ++i;
1927 RegCloseKey (adapter_key);
1928 return first;
1931 const struct panel_reg *
1932 get_panel_reg (struct gc_arena *gc)
1934 LONG status;
1935 HKEY network_connections_key;
1936 DWORD len;
1937 struct panel_reg *first = NULL;
1938 struct panel_reg *last = NULL;
1939 int i = 0;
1941 status = RegOpenKeyEx(
1942 HKEY_LOCAL_MACHINE,
1943 NETWORK_CONNECTIONS_KEY,
1945 KEY_READ,
1946 &network_connections_key);
1948 if (status != ERROR_SUCCESS)
1949 msg (M_FATAL, "Error opening registry key: %s", NETWORK_CONNECTIONS_KEY);
1951 while (true)
1953 char enum_name[256];
1954 char connection_string[256];
1955 HKEY connection_key;
1956 char name_data[256];
1957 DWORD name_type;
1958 const char name_string[] = "Name";
1960 len = sizeof (enum_name);
1961 status = RegEnumKeyEx(
1962 network_connections_key,
1964 enum_name,
1965 &len,
1966 NULL,
1967 NULL,
1968 NULL,
1969 NULL);
1970 if (status == ERROR_NO_MORE_ITEMS)
1971 break;
1972 else if (status != ERROR_SUCCESS)
1973 msg (M_FATAL, "Error enumerating registry subkeys of key: %s",
1974 NETWORK_CONNECTIONS_KEY);
1976 openvpn_snprintf (connection_string, sizeof(connection_string),
1977 "%s\\%s\\Connection",
1978 NETWORK_CONNECTIONS_KEY, enum_name);
1980 status = RegOpenKeyEx(
1981 HKEY_LOCAL_MACHINE,
1982 connection_string,
1984 KEY_READ,
1985 &connection_key);
1987 if (status != ERROR_SUCCESS)
1988 dmsg (D_REGISTRY, "Error opening registry key: %s", connection_string);
1989 else
1991 len = sizeof (name_data);
1992 status = RegQueryValueEx(
1993 connection_key,
1994 name_string,
1995 NULL,
1996 &name_type,
1997 name_data,
1998 &len);
2000 if (status != ERROR_SUCCESS || name_type != REG_SZ)
2001 dmsg (D_REGISTRY, "Error opening registry key: %s\\%s\\%s",
2002 NETWORK_CONNECTIONS_KEY, connection_string, name_string);
2003 else
2005 struct panel_reg *reg;
2007 ALLOC_OBJ_CLEAR_GC (reg, struct panel_reg, gc);
2008 reg->name = string_alloc (name_data, gc);
2009 reg->guid = string_alloc (enum_name, gc);
2011 /* link into return list */
2012 if (!first)
2013 first = reg;
2014 if (last)
2015 last->next = reg;
2016 last = reg;
2018 RegCloseKey (connection_key);
2020 ++i;
2023 RegCloseKey (network_connections_key);
2025 return first;
2029 * Check that two addresses are part of the same 255.255.255.252 subnet.
2031 void
2032 verify_255_255_255_252 (in_addr_t local, in_addr_t remote)
2034 struct gc_arena gc = gc_new ();
2035 const unsigned int mask = 3;
2036 const char *err = NULL;
2038 if (local == remote)
2040 err = "must be different";
2041 goto error;
2043 if ((local & (~mask)) != (remote & (~mask)))
2045 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";
2046 goto error;
2048 if ((local & mask) == 0
2049 || (local & mask) == 3
2050 || (remote & mask) == 0
2051 || (remote & mask) == 3)
2053 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";
2054 goto error;
2057 gc_free (&gc);
2058 return;
2060 error:
2061 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.",
2062 print_in_addr_t (local, 0, &gc),
2063 print_in_addr_t (remote, 0, &gc),
2064 err);
2065 gc_free (&gc);
2068 void show_valid_win32_tun_subnets (void)
2070 int i;
2071 int col = 0;
2073 printf ("On Windows, point-to-point IP support (i.e. --dev tun)\n");
2074 printf ("is emulated by the TAP-Win32 driver. The major limitation\n");
2075 printf ("imposed by this approach is that the --ifconfig local and\n");
2076 printf ("remote endpoints must be part of the same 255.255.255.252\n");
2077 printf ("subnet. The following list shows examples of endpoint\n");
2078 printf ("pairs which satisfy this requirement. Only the final\n");
2079 printf ("component of the IP address pairs is at issue.\n\n");
2080 printf ("As an example, the following option would be correct:\n");
2081 printf (" --ifconfig 10.7.0.5 10.7.0.6 (on host A)\n");
2082 printf (" --ifconfig 10.7.0.6 10.7.0.5 (on host B)\n");
2083 printf ("because [5,6] is part of the below list.\n\n");
2085 for (i = 0; i < 256; i += 4)
2087 printf("[%3d,%3d] ", i+1, i+2);
2088 if (++col > 4)
2090 col = 0;
2091 printf ("\n");
2094 if (col)
2095 printf ("\n");
2098 void
2099 show_tap_win32_adapters (int msglev, int warnlev)
2101 struct gc_arena gc = gc_new ();
2103 bool warn_panel_null = false;
2104 bool warn_panel_dup = false;
2105 bool warn_tap_dup = false;
2107 int links;
2109 const struct tap_reg *tr;
2110 const struct tap_reg *tr1;
2111 const struct panel_reg *pr;
2113 const struct tap_reg *tap_reg = get_tap_reg (&gc);
2114 const struct panel_reg *panel_reg = get_panel_reg (&gc);
2116 msg (msglev, "Available TAP-WIN32 adapters [name, GUID]:");
2118 /* loop through each TAP-Win32 adapter registry entry */
2119 for (tr = tap_reg; tr != NULL; tr = tr->next)
2121 links = 0;
2123 /* loop through each network connections entry in the control panel */
2124 for (pr = panel_reg; pr != NULL; pr = pr->next)
2126 if (!strcmp (tr->guid, pr->guid))
2128 msg (msglev, "'%s' %s", pr->name, tr->guid);
2129 ++links;
2133 if (links > 1)
2135 warn_panel_dup = true;
2137 else if (links == 0)
2139 /* a TAP adapter exists without a link from the network
2140 connections control panel */
2141 warn_panel_null = true;
2142 msg (msglev, "[NULL] %s", tr->guid);
2146 /* check for TAP-Win32 adapter duplicated GUIDs */
2147 for (tr = tap_reg; tr != NULL; tr = tr->next)
2149 for (tr1 = tap_reg; tr1 != NULL; tr1 = tr1->next)
2151 if (tr != tr1 && !strcmp (tr->guid, tr1->guid))
2152 warn_tap_dup = true;
2156 /* warn on registry inconsistencies */
2157 if (warn_tap_dup)
2158 msg (warnlev, "WARNING: Some TAP-Win32 adapters have duplicate GUIDs");
2160 if (warn_panel_dup)
2161 msg (warnlev, "WARNING: Some TAP-Win32 adapters have duplicate links from the Network Connections control panel");
2163 if (warn_panel_null)
2164 msg (warnlev, "WARNING: Some TAP-Win32 adapters have no link from the Network Connections control panel");
2166 gc_free (&gc);
2170 * Confirm that GUID is a TAP-Win32 adapter.
2172 static bool
2173 is_tap_win32 (const char *guid, const struct tap_reg *tap_reg)
2175 const struct tap_reg *tr;
2177 for (tr = tap_reg; tr != NULL; tr = tr->next)
2179 if (guid && !strcmp (tr->guid, guid))
2180 return true;
2183 return false;
2186 static const char *
2187 guid_to_name (const char *guid, const struct panel_reg *panel_reg)
2189 const struct panel_reg *pr;
2191 for (pr = panel_reg; pr != NULL; pr = pr->next)
2193 if (guid && !strcmp (pr->guid, guid))
2194 return pr->name;
2197 return NULL;
2200 static const char *
2201 name_to_guid (const char *name, const struct tap_reg *tap_reg, const struct panel_reg *panel_reg)
2203 const struct panel_reg *pr;
2205 for (pr = panel_reg; pr != NULL; pr = pr->next)
2207 if (name && !strcmp (pr->name, name) && is_tap_win32 (pr->guid, tap_reg))
2208 return pr->guid;
2211 return NULL;
2214 static void
2215 at_least_one_tap_win32 (const struct tap_reg *tap_reg)
2217 if (!tap_reg)
2218 msg (M_FATAL, "There are no TAP-Win32 adapters on this system. You should be able to create a TAP-Win32 adapter by going to Start -> All Programs -> " PACKAGE_NAME " -> Add a new TAP-Win32 virtual ethernet adapter.");
2222 * Get an adapter GUID and optional actual_name from the
2223 * registry for the TAP device # = device_number.
2225 static const char *
2226 get_unspecified_device_guid (const int device_number,
2227 char *actual_name,
2228 int actual_name_size,
2229 const struct tap_reg *tap_reg_src,
2230 const struct panel_reg *panel_reg_src,
2231 struct gc_arena *gc)
2233 const struct tap_reg *tap_reg = tap_reg_src;
2234 struct buffer ret = clear_buf ();
2235 struct buffer actual = clear_buf ();
2236 int i;
2238 ASSERT (device_number >= 0);
2240 /* Make sure we have at least one TAP adapter */
2241 if (!tap_reg)
2242 return NULL;
2244 /* The actual_name output buffer may be NULL */
2245 if (actual_name)
2247 ASSERT (actual_name_size > 0);
2248 buf_set_write (&actual, actual_name, actual_name_size);
2251 /* Move on to specified device number */
2252 for (i = 0; i < device_number; i++)
2254 tap_reg = tap_reg->next;
2255 if (!tap_reg)
2256 return NULL;
2259 /* Save Network Panel name (if exists) in actual_name */
2260 if (actual_name)
2262 const char *act = guid_to_name (tap_reg->guid, panel_reg_src);
2263 if (act)
2264 buf_printf (&actual, "%s", act);
2265 else
2266 buf_printf (&actual, "NULL");
2269 /* Save GUID for return value */
2270 ret = alloc_buf_gc (256, gc);
2271 buf_printf (&ret, "%s", tap_reg->guid);
2272 return BSTR (&ret);
2276 * Lookup a --dev-node adapter name in the registry
2277 * returning the GUID and optional actual_name.
2279 static const char *
2280 get_device_guid (const char *name,
2281 char *actual_name,
2282 int actual_name_size,
2283 const struct tap_reg *tap_reg,
2284 const struct panel_reg *panel_reg,
2285 struct gc_arena *gc)
2287 struct buffer ret = alloc_buf_gc (256, gc);
2288 struct buffer actual = clear_buf ();
2290 /* Make sure we have at least one TAP adapter */
2291 if (!tap_reg)
2292 return NULL;
2294 /* The actual_name output buffer may be NULL */
2295 if (actual_name)
2297 ASSERT (actual_name_size > 0);
2298 buf_set_write (&actual, actual_name, actual_name_size);
2301 /* Check if GUID was explicitly specified as --dev-node parameter */
2302 if (is_tap_win32 (name, tap_reg))
2304 const char *act = guid_to_name (name, panel_reg);
2305 buf_printf (&ret, "%s", name);
2306 if (act)
2307 buf_printf (&actual, "%s", act);
2308 else
2309 buf_printf (&actual, "NULL");
2310 return BSTR (&ret);
2313 /* Lookup TAP adapter in network connections list */
2315 const char *guid = name_to_guid (name, tap_reg, panel_reg);
2316 if (guid)
2318 buf_printf (&actual, "%s", name);
2319 buf_printf (&ret, "%s", guid);
2320 return BSTR (&ret);
2324 return NULL;
2328 * Return a TAP name for netsh commands.
2330 const char *
2331 get_netsh_id (const char *dev_node, struct gc_arena *gc)
2333 const struct tap_reg *tap_reg = get_tap_reg (gc);
2334 const struct panel_reg *panel_reg = get_panel_reg (gc);
2335 struct buffer actual = alloc_buf_gc (256, gc);
2336 const char *guid;
2338 at_least_one_tap_win32 (tap_reg);
2340 if (dev_node)
2342 guid = get_device_guid (dev_node, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc);
2344 else
2346 guid = get_unspecified_device_guid (0, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc);
2348 if (get_unspecified_device_guid (1, NULL, 0, tap_reg, panel_reg, gc)) /* ambiguous if more than one TAP-Win32 adapter */
2349 guid = NULL;
2352 if (!guid)
2353 return "NULL"; /* not found */
2354 else if (strcmp (BPTR (&actual), "NULL"))
2355 return BPTR (&actual); /* control panel name */
2356 else
2357 return guid; /* no control panel name, return GUID instead */
2361 * Get adapter info list
2363 const IP_ADAPTER_INFO *
2364 get_adapter_info_list (struct gc_arena *gc)
2366 ULONG size = 0;
2367 IP_ADAPTER_INFO *pi = NULL;
2368 DWORD status;
2370 if ((status = GetAdaptersInfo (NULL, &size)) != ERROR_BUFFER_OVERFLOW)
2372 msg (M_INFO, "GetAdaptersInfo #1 failed (status=%u) : %s",
2373 (unsigned int)status,
2374 strerror_win32 (status, gc));
2376 else
2378 pi = (PIP_ADAPTER_INFO) gc_malloc (size, false, gc);
2379 if ((status = GetAdaptersInfo (pi, &size)) == NO_ERROR)
2380 return pi;
2381 else
2383 msg (M_INFO, "GetAdaptersInfo #2 failed (status=%u) : %s",
2384 (unsigned int)status,
2385 strerror_win32 (status, gc));
2388 return pi;
2391 static const IP_INTERFACE_INFO *
2392 get_interface_info_list (struct gc_arena *gc)
2394 ULONG size = 0;
2395 IP_INTERFACE_INFO *ii = NULL;
2396 DWORD status;
2398 if ((status = GetInterfaceInfo (NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)
2400 msg (M_INFO, "GetInterfaceInfo #1 failed (status=%u) : %s",
2401 (unsigned int)status,
2402 strerror_win32 (status, gc));
2404 else
2406 ii = (PIP_INTERFACE_INFO) gc_malloc (size, false, gc);
2407 if ((status = GetInterfaceInfo (ii, &size)) == NO_ERROR)
2408 return ii;
2409 else
2411 msg (M_INFO, "GetInterfaceInfo #2 failed (status=%u) : %s",
2412 (unsigned int)status,
2413 strerror_win32 (status, gc));
2416 return ii;
2419 static const IP_ADAPTER_INDEX_MAP *
2420 get_interface_info (DWORD index, struct gc_arena *gc)
2422 const IP_INTERFACE_INFO *list = get_interface_info_list (gc);
2423 if (list)
2425 int i;
2426 for (i = 0; i < list->NumAdapters; ++i)
2428 const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[i];
2429 if (index == inter->Index)
2430 return inter;
2433 return NULL;
2437 * Given an adapter index, return a pointer to the
2438 * IP_ADAPTER_INFO structure for that adapter.
2441 static const IP_ADAPTER_INFO *
2442 get_adapter (const IP_ADAPTER_INFO *ai, DWORD index)
2444 if (ai && index != (DWORD)~0)
2446 const IP_ADAPTER_INFO *a;
2448 /* find index in the linked list */
2449 for (a = ai; a != NULL; a = a->Next)
2451 if (a->Index == index)
2452 return a;
2455 return NULL;
2458 static const IP_ADAPTER_INFO *
2459 get_adapter_info (DWORD index, struct gc_arena *gc)
2461 return get_adapter (get_adapter_info_list (gc), index);
2464 static int
2465 get_adapter_n_ip_netmask (const IP_ADAPTER_INFO *ai)
2467 if (ai)
2469 int n = 0;
2470 const IP_ADDR_STRING *ip = &ai->IpAddressList;
2472 while (ip)
2474 ++n;
2475 ip = ip->Next;
2477 return n;
2479 else
2480 return 0;
2483 static bool
2484 get_adapter_ip_netmask (const IP_ADAPTER_INFO *ai, const int n, in_addr_t *ip, in_addr_t *netmask)
2486 bool ret = false;
2487 *ip = 0;
2488 *netmask = 0;
2490 if (ai)
2492 const IP_ADDR_STRING *iplist = &ai->IpAddressList;
2493 int i = 0;
2495 while (iplist)
2497 if (i == n)
2498 break;
2499 ++i;
2500 iplist = iplist->Next;
2503 if (iplist)
2505 const unsigned int getaddr_flags = GETADDR_HOST_ORDER;
2506 const char *ip_str = iplist->IpAddress.String;
2507 const char *netmask_str = iplist->IpMask.String;
2508 bool succeed1 = false;
2509 bool succeed2 = false;
2511 if (ip_str && netmask_str && strlen (ip_str) && strlen (netmask_str))
2513 *ip = getaddr (getaddr_flags, ip_str, 0, &succeed1, NULL);
2514 *netmask = getaddr (getaddr_flags, netmask_str, 0, &succeed2, NULL);
2515 ret = (succeed1 == true && succeed2 == true);
2520 return ret;
2523 const IP_ADAPTER_INFO *
2524 get_tun_adapter (const struct tuntap *tt, const IP_ADAPTER_INFO *list)
2526 if (list && tt)
2527 return get_adapter (list, tt->adapter_index);
2528 else
2529 return NULL;
2532 bool
2533 is_adapter_up (const struct tuntap *tt, const IP_ADAPTER_INFO *list)
2535 int i;
2536 bool ret = false;
2538 const IP_ADAPTER_INFO *ai = get_tun_adapter (tt, list);
2540 if (ai)
2542 const int n = get_adapter_n_ip_netmask (ai);
2544 /* loop once for every IP/netmask assigned to adapter */
2545 for (i = 0; i < n; ++i)
2547 in_addr_t ip, netmask;
2548 if (get_adapter_ip_netmask (ai, i, &ip, &netmask))
2550 if (tt->local && tt->adapter_netmask)
2552 /* wait for our --ifconfig parms to match the actual adapter parms */
2553 if (tt->local == ip && tt->adapter_netmask == netmask)
2554 ret = true;
2556 else
2558 /* --ifconfig was not defined, maybe using a real DHCP server */
2559 if (ip && netmask)
2560 ret = true;
2565 else
2566 ret = true; /* this can occur when TAP adapter is bridged */
2568 return ret;
2571 bool
2572 is_ip_in_adapter_subnet (const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask)
2574 int i;
2575 bool ret = false;
2577 if (highest_netmask)
2578 *highest_netmask = 0;
2580 if (ai)
2582 const int n = get_adapter_n_ip_netmask (ai);
2583 for (i = 0; i < n; ++i)
2585 in_addr_t adapter_ip, adapter_netmask;
2586 if (get_adapter_ip_netmask (ai, i, &adapter_ip, &adapter_netmask))
2588 if (adapter_ip && adapter_netmask && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))
2590 if (highest_netmask && adapter_netmask > *highest_netmask)
2591 *highest_netmask = adapter_netmask;
2592 ret = true;
2597 return ret;
2600 DWORD
2601 adapter_index_of_ip (const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count)
2603 struct gc_arena gc = gc_new ();
2604 DWORD ret = ~0;
2605 in_addr_t highest_netmask = 0;
2606 bool first = true;
2608 if (count)
2609 *count = 0;
2611 while (list)
2613 in_addr_t hn;
2615 if (is_ip_in_adapter_subnet (list, ip, &hn))
2617 if (first || hn > highest_netmask)
2619 highest_netmask = hn;
2620 if (count)
2621 *count = 1;
2622 ret = list->Index;
2623 first = false;
2625 else if (hn == highest_netmask)
2627 if (count)
2628 ++*count;
2631 list = list->Next;
2634 dmsg (D_ROUTE_DEBUG, "DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d",
2635 print_in_addr_t (ip, 0, &gc),
2636 print_in_addr_t (highest_netmask, 0, &gc),
2637 (int)ret,
2638 count ? *count : -1);
2640 if (ret == ~0 && count)
2641 *count = 0;
2643 gc_free (&gc);
2644 return ret;
2648 * Given an adapter index, return true if the adapter
2649 * is DHCP disabled.
2651 static bool
2652 dhcp_disabled (DWORD index)
2654 struct gc_arena gc = gc_new ();
2655 const IP_ADAPTER_INFO *ai = get_adapter_info (index, &gc);
2656 bool ret = false;
2658 if (ai && !ai->DhcpEnabled)
2659 ret = true;
2661 gc_free (&gc);
2662 return ret;
2666 * Delete all temporary address/netmask pairs which were added
2667 * to adapter (given by index) by previous calls to AddIPAddress.
2669 static void
2670 delete_temp_addresses (DWORD index)
2672 struct gc_arena gc = gc_new ();
2673 const IP_ADAPTER_INFO *a = get_adapter_info (index, &gc);
2675 if (a)
2677 const IP_ADDR_STRING *ip = &a->IpAddressList;
2678 while (ip)
2680 DWORD status;
2681 const DWORD context = ip->Context;
2683 if ((status = DeleteIPAddress ((ULONG) context)) == NO_ERROR)
2685 msg (M_INFO, "Successfully deleted previously set dynamic IP/netmask: %s/%s",
2686 ip->IpAddress.String,
2687 ip->IpMask.String);
2689 else
2691 const char *empty = "0.0.0.0";
2692 if (strcmp (ip->IpAddress.String, empty)
2693 || strcmp (ip->IpMask.String, empty))
2694 msg (M_INFO, "NOTE: could not delete previously set dynamic IP/netmask: %s/%s (status=%u)",
2695 ip->IpAddress.String,
2696 ip->IpMask.String,
2697 (unsigned int)status);
2699 ip = ip->Next;
2702 gc_free (&gc);
2706 * Get interface index for use with IP Helper API functions.
2708 static DWORD
2709 get_interface_index (const char *guid)
2711 struct gc_arena gc = gc_new ();
2712 ULONG index;
2713 DWORD status;
2714 wchar_t wbuf[256];
2715 snwprintf (wbuf, SIZE (wbuf), L"\\DEVICE\\TCPIP_%S", guid);
2716 wbuf [SIZE(wbuf) - 1] = 0;
2717 if ((status = GetAdapterIndex (wbuf, &index)) != NO_ERROR)
2719 msg (M_INFO, "NOTE: could not get adapter index for %S, status=%u : %s",
2720 wbuf,
2721 (unsigned int)status,
2722 strerror_win32 (status, &gc));
2723 gc_free (&gc);
2724 return (DWORD)~0;
2726 else
2728 gc_free (&gc);
2729 return index;
2734 * Return a string representing a PIP_ADDR_STRING
2736 static const char *
2737 format_ip_addr_string (const IP_ADDR_STRING *ip, struct gc_arena *gc)
2739 struct buffer out = alloc_buf_gc (256, gc);
2740 while (ip)
2742 buf_printf (&out, "%s", ip->IpAddress.String);
2743 if (strlen (ip->IpMask.String))
2745 buf_printf (&out, "/");
2746 buf_printf (&out, "%s", ip->IpMask.String);
2748 buf_printf (&out, " ");
2749 ip = ip->Next;
2751 return BSTR (&out);
2755 * Show info for a single adapter
2757 static void
2758 show_adapter (int msglev, const IP_ADAPTER_INFO *a, struct gc_arena *gc)
2760 msg (msglev, "%s", a->Description);
2761 msg (msglev, " Index = %d", (int)a->Index);
2762 msg (msglev, " GUID = %s", a->AdapterName);
2763 msg (msglev, " IP = %s", format_ip_addr_string (&a->IpAddressList, gc));
2764 msg (msglev, " MAC = %s", format_hex_ex (a->Address, a->AddressLength, 0, 1, ":", gc));
2765 msg (msglev, " GATEWAY = %s", format_ip_addr_string (&a->GatewayList, gc));
2766 if (a->DhcpEnabled)
2768 msg (msglev, " DHCP SERV = %s", format_ip_addr_string (&a->DhcpServer, gc));
2769 msg (msglev, " DHCP LEASE OBTAINED = %s", time_string (a->LeaseObtained, 0, false, gc));
2770 msg (msglev, " DHCP LEASE EXPIRES = %s", time_string (a->LeaseExpires, 0, false, gc));
2772 if (a->HaveWins)
2774 msg (msglev, " PRI WINS = %s", format_ip_addr_string (&a->PrimaryWinsServer, gc));
2775 msg (msglev, " SEC WINS = %s", format_ip_addr_string (&a->SecondaryWinsServer, gc));
2780 * Show current adapter list
2782 void
2783 show_adapters (int msglev)
2785 struct gc_arena gc = gc_new ();
2786 const IP_ADAPTER_INFO *ai = get_adapter_info_list (&gc);
2788 msg (msglev, "SYSTEM ADAPTER LIST");
2789 if (ai)
2791 const IP_ADAPTER_INFO *a;
2793 /* find index in the linked list */
2794 for (a = ai; a != NULL; a = a->Next)
2796 show_adapter (msglev, a, &gc);
2799 gc_free (&gc);
2803 * DHCP release/renewal
2806 bool
2807 dhcp_release (const struct tuntap *tt)
2809 struct gc_arena gc = gc_new ();
2810 bool ret = false;
2811 if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != ~0)
2813 const IP_ADAPTER_INDEX_MAP *inter = get_interface_info (tt->adapter_index, &gc);
2814 if (inter)
2816 DWORD status = IpReleaseAddress ((IP_ADAPTER_INDEX_MAP *)inter);
2817 if (status == NO_ERROR)
2819 msg (D_TUNTAP_INFO, "TAP: DHCP address released");
2820 ret = true;
2822 else
2823 msg (M_WARN, "NOTE: Release of DHCP-assigned IP address lease on TAP-Win32 adapter failed: %s (code=%u)",
2824 strerror_win32 (status, &gc),
2825 (unsigned int)status);
2828 gc_free (&gc);
2829 return ret;
2832 bool
2833 dhcp_renew (const struct tuntap *tt)
2835 struct gc_arena gc = gc_new ();
2836 bool ret = false;
2837 if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != ~0)
2839 const IP_ADAPTER_INDEX_MAP *inter = get_interface_info (tt->adapter_index, &gc);
2840 if (inter)
2842 DWORD status = IpRenewAddress ((IP_ADAPTER_INDEX_MAP *)inter);
2843 if (status == NO_ERROR)
2845 msg (D_TUNTAP_INFO, "TAP: DHCP address renewal succeeded");
2846 ret = true;
2848 else
2849 msg (M_WARN, "WARNING: Failed to renew DHCP IP address lease on TAP-Win32 adapter: %s (code=%u)",
2850 strerror_win32 (status, &gc),
2851 (unsigned int)status);
2854 gc_free (&gc);
2855 return ret;
2859 * Convert DHCP options from the command line / config file
2860 * into a raw DHCP-format options string.
2863 static void
2864 write_dhcp_u8 (struct buffer *buf, const int type, const int data)
2866 if (!buf_safe (buf, 3))
2867 msg (M_FATAL, "write_dhcp_u8: buffer overflow building DHCP options");
2868 buf_write_u8 (buf, type);
2869 buf_write_u8 (buf, 1);
2870 buf_write_u8 (buf, data);
2873 static void
2874 write_dhcp_u32_array (struct buffer *buf, const int type, const uint32_t *data, const unsigned int len)
2876 if (len > 0)
2878 int i;
2879 const int size = len * sizeof (uint32_t);
2881 if (!buf_safe (buf, 2 + size))
2882 msg (M_FATAL, "write_dhcp_u32_array: buffer overflow building DHCP options");
2883 if (size < 1 || size > 255)
2884 msg (M_FATAL, "write_dhcp_u32_array: size (%d) must be > 0 and <= 255", size);
2885 buf_write_u8 (buf, type);
2886 buf_write_u8 (buf, size);
2887 for (i = 0; i < len; ++i)
2888 buf_write_u32 (buf, data[i]);
2892 static void
2893 write_dhcp_str (struct buffer *buf, const int type, const char *str)
2895 const int len = strlen (str);
2896 if (!buf_safe (buf, 2 + len))
2897 msg (M_FATAL, "write_dhcp_str: buffer overflow building DHCP options");
2898 if (len < 1 || len > 255)
2899 msg (M_FATAL, "write_dhcp_str: string '%s' must be > 0 bytes and <= 255 bytes", str);
2900 buf_write_u8 (buf, type);
2901 buf_write_u8 (buf, len);
2902 buf_write (buf, str, len);
2905 static void
2906 build_dhcp_options_string (struct buffer *buf, const struct tuntap_options *o)
2908 if (o->domain)
2909 write_dhcp_str (buf, 15, o->domain);
2911 if (o->netbios_scope)
2912 write_dhcp_str (buf, 47, o->netbios_scope);
2914 if (o->netbios_node_type)
2915 write_dhcp_u8 (buf, 46, o->netbios_node_type);
2917 write_dhcp_u32_array (buf, 6, (uint32_t*)o->dns, o->dns_len);
2918 write_dhcp_u32_array (buf, 44, (uint32_t*)o->wins, o->wins_len);
2919 write_dhcp_u32_array (buf, 42, (uint32_t*)o->ntp, o->ntp_len);
2920 write_dhcp_u32_array (buf, 45, (uint32_t*)o->nbdd, o->nbdd_len);
2922 /* the MS DHCP server option 'Disable Netbios-over-TCP/IP
2923 is implemented as vendor option 001, value 002.
2924 A value of 001 means 'leave NBT alone' which is the default */
2925 if (o->disable_nbt)
2927 buf_write_u8 (buf, 43);
2928 buf_write_u8 (buf, 6); /* total length field */
2929 buf_write_u8 (buf, 0x001);
2930 buf_write_u8 (buf, 4); /* length of the vendor specified field */
2931 buf_write_u32 (buf, 0x002);
2935 void
2936 open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
2938 struct gc_arena gc = gc_new ();
2939 char device_path[256];
2940 const char *device_guid = NULL;
2941 DWORD len;
2943 /*netcmd_semaphore_lock ();*/
2945 ipv6_support (ipv6, false, tt);
2947 if (tt->type == DEV_TYPE_NULL)
2949 open_null (tt);
2950 gc_free (&gc);
2951 return;
2953 else if (tt->type == DEV_TYPE_TAP || tt->type == DEV_TYPE_TUN)
2957 else
2959 msg (M_FATAL|M_NOPREFIX, "Unknown virtual device type: '%s'", dev);
2963 * Lookup the device name in the registry, using the --dev-node high level name.
2966 const struct tap_reg *tap_reg = get_tap_reg (&gc);
2967 const struct panel_reg *panel_reg = get_panel_reg (&gc);
2968 char guid_buffer[256];
2970 at_least_one_tap_win32 (tap_reg);
2972 if (dev_node)
2974 /* Get the device GUID for the device specified with --dev-node. */
2975 device_guid = get_device_guid (dev_node, guid_buffer, sizeof (guid_buffer), tap_reg, panel_reg, &gc);
2977 if (!device_guid)
2978 msg (M_FATAL, "TAP-Win32 adapter '%s' not found", dev_node);
2980 /* Open Windows TAP-Win32 adapter */
2981 openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s",
2982 USERMODEDEVICEDIR,
2983 device_guid,
2984 TAPSUFFIX);
2986 tt->hand = CreateFile (
2987 device_path,
2988 GENERIC_READ | GENERIC_WRITE,
2989 0, /* was: FILE_SHARE_READ */
2991 OPEN_EXISTING,
2992 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
2996 if (tt->hand == INVALID_HANDLE_VALUE)
2997 msg (M_ERR, "CreateFile failed on TAP device: %s", device_path);
2999 else
3001 int device_number = 0;
3003 /* Try opening all TAP devices until we find one available */
3004 while (true)
3006 device_guid = get_unspecified_device_guid (device_number,
3007 guid_buffer,
3008 sizeof (guid_buffer),
3009 tap_reg,
3010 panel_reg,
3011 &gc);
3013 if (!device_guid)
3014 msg (M_FATAL, "All TAP-Win32 adapters on this system are currently in use.");
3016 /* Open Windows TAP-Win32 adapter */
3017 openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s",
3018 USERMODEDEVICEDIR,
3019 device_guid,
3020 TAPSUFFIX);
3022 tt->hand = CreateFile (
3023 device_path,
3024 GENERIC_READ | GENERIC_WRITE,
3025 0, /* was: FILE_SHARE_READ */
3027 OPEN_EXISTING,
3028 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
3032 if (tt->hand == INVALID_HANDLE_VALUE)
3033 msg (D_TUNTAP_INFO, "CreateFile failed on TAP device: %s", device_path);
3034 else
3035 break;
3037 device_number++;
3041 /* translate high-level device name into a device instance
3042 GUID using the registry */
3043 tt->actual_name = string_alloc (guid_buffer, NULL);
3046 msg (M_INFO, "TAP-WIN32 device [%s] opened: %s", tt->actual_name, device_path);
3048 /* get driver version info */
3050 ULONG info[3];
3051 CLEAR (info);
3052 if (DeviceIoControl (tt->hand, TAP_IOCTL_GET_VERSION,
3053 &info, sizeof (info),
3054 &info, sizeof (info), &len, NULL))
3056 msg (D_TUNTAP_INFO, "TAP-Win32 Driver Version %d.%d %s",
3057 (int) info[0],
3058 (int) info[1],
3059 (info[2] ? "(DEBUG)" : ""));
3062 if ( !(info[0] > TAP_WIN32_MIN_MAJOR
3063 || (info[0] == TAP_WIN32_MIN_MAJOR && info[1] >= TAP_WIN32_MIN_MINOR)) )
3064 msg (M_FATAL, "ERROR: This version of " PACKAGE_NAME " requires a TAP-Win32 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.",
3065 TAP_WIN32_MIN_MAJOR,
3066 TAP_WIN32_MIN_MINOR);
3069 /* get driver MTU */
3071 ULONG mtu;
3072 if (DeviceIoControl (tt->hand, TAP_IOCTL_GET_MTU,
3073 &mtu, sizeof (mtu),
3074 &mtu, sizeof (mtu), &len, NULL))
3076 tt->post_open_mtu = (int) mtu;
3077 msg (D_MTU_INFO, "TAP-Win32 MTU=%d", (int) mtu);
3081 /* set point-to-point mode if TUN device */
3083 if (tt->type == DEV_TYPE_TUN)
3085 in_addr_t ep[2];
3086 ep[0] = htonl (tt->local);
3087 ep[1] = htonl (tt->remote_netmask);
3088 if (!tt->did_ifconfig_setup)
3090 msg (M_FATAL, "ERROR: --dev tun also requires --ifconfig");
3092 if (!DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_POINT_TO_POINT,
3093 ep, sizeof (ep),
3094 ep, sizeof (ep), &len, NULL))
3095 msg (M_FATAL, "ERROR: The TAP-Win32 driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun");
3098 /* should we tell the TAP-Win32 driver to masquerade as a DHCP server as a means
3099 of setting the adapter address? */
3100 if (tt->did_ifconfig_setup && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ)
3102 uint32_t ep[4];
3104 /* We will answer DHCP requests with a reply to set IP/subnet to these values */
3105 ep[0] = htonl (tt->local);
3106 ep[1] = htonl (tt->adapter_netmask);
3108 /* At what IP address should the DHCP server masquerade at? */
3109 if (tt->type == DEV_TYPE_TUN)
3111 ep[2] = htonl (tt->remote_netmask);
3112 if (tt->options.dhcp_masq_custom_offset)
3113 msg (M_WARN, "WARNING: because you are using '--dev tun' mode, the '--ip-win32 dynamic [offset]' option is ignoring the offset parameter");
3115 else
3117 in_addr_t dsa; /* DHCP server addr */
3119 ASSERT (tt->type == DEV_TYPE_TAP);
3121 if (tt->options.dhcp_masq_offset < 0)
3122 dsa = (tt->local | (~tt->adapter_netmask)) + tt->options.dhcp_masq_offset;
3123 else
3124 dsa = (tt->local & tt->adapter_netmask) + tt->options.dhcp_masq_offset;
3126 if (dsa == tt->local)
3127 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));
3129 if ((tt->local & tt->adapter_netmask) != (dsa & tt->adapter_netmask))
3130 msg (M_FATAL, "ERROR: --tap-win32 dynamic [offset] : offset is outside of --ifconfig subnet");
3132 ep[2] = htonl (dsa);
3135 /* lease time in seconds */
3136 ep[3] = (uint32_t) tt->options.dhcp_lease_time;
3138 ASSERT (ep[3] > 0);
3140 if (!DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_DHCP_MASQ,
3141 ep, sizeof (ep),
3142 ep, sizeof (ep), &len, NULL))
3143 msg (M_FATAL, "ERROR: The TAP-Win32 driver rejected a DeviceIoControl call to set TAP_IOCTL_CONFIG_DHCP_MASQ mode");
3145 msg (M_INFO, "Notified TAP-Win32 driver to set a DHCP IP/netmask of %s/%s on interface %s [DHCP-serv: %s, lease-time: %d]",
3146 print_in_addr_t (tt->local, 0, &gc),
3147 print_in_addr_t (tt->adapter_netmask, 0, &gc),
3148 device_guid,
3149 print_in_addr_t (ep[2], IA_NET_ORDER, &gc),
3150 ep[3]
3153 /* user-supplied DHCP options capability */
3154 if (tt->options.dhcp_options)
3156 struct buffer buf = alloc_buf (256);
3157 build_dhcp_options_string (&buf, &tt->options);
3158 msg (D_DHCP_OPT, "DHCP option string: %s", format_hex (BPTR (&buf), BLEN (&buf), 0, &gc));
3159 if (!DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_DHCP_SET_OPT,
3160 BPTR (&buf), BLEN (&buf),
3161 BPTR (&buf), BLEN (&buf), &len, NULL))
3162 msg (M_FATAL, "ERROR: The TAP-Win32 driver rejected a TAP_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call");
3163 free_buf (&buf);
3167 /* set driver media status to 'connected' */
3169 ULONG status = TRUE;
3170 if (!DeviceIoControl (tt->hand, TAP_IOCTL_SET_MEDIA_STATUS,
3171 &status, sizeof (status),
3172 &status, sizeof (status), &len, NULL))
3173 msg (M_WARN, "WARNING: The TAP-Win32 driver rejected a TAP_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
3176 /* possible wait for adapter to come up */
3178 int s = tt->options.tap_sleep;
3179 if (s > 0)
3181 msg (M_INFO, "Sleeping for %d seconds...", s);
3182 openvpn_sleep (s);
3186 /* possibly use IP Helper API to set IP address on adapter */
3188 DWORD index = get_interface_index (device_guid);
3189 tt->adapter_index = index;
3191 /* flush arp cache */
3192 if (index != (DWORD)~0)
3194 DWORD status;
3196 if ((status = FlushIpNetTable (index)) == NO_ERROR)
3197 msg (M_INFO, "Successful ARP Flush on interface [%u] %s",
3198 (unsigned int)index,
3199 device_guid);
3200 else
3201 msg (M_WARN, "NOTE: FlushIpNetTable failed on interface [%u] %s (status=%u) : %s",
3202 (unsigned int)index,
3203 device_guid,
3204 (unsigned int)status,
3205 strerror_win32 (status, &gc));
3209 * If the TAP-Win32 driver is masquerading as a DHCP server
3210 * make sure the TCP/IP properties for the adapter are
3211 * set correctly.
3213 if (tt->did_ifconfig_setup && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ)
3215 /* check dhcp enable status */
3216 if (dhcp_disabled (index))
3217 msg (M_WARN, "WARNING: You have selected '--ip-win32 dynamic', which will not work unless the TAP-Win32 TCP/IP properties are set to 'Obtain an IP address automatically'");
3219 /* force an explicit DHCP lease renewal on TAP adapter? */
3220 if (tt->options.dhcp_pre_release)
3221 dhcp_release (tt);
3222 if (tt->options.dhcp_renew)
3223 dhcp_renew (tt);
3226 if (tt->did_ifconfig_setup && tt->options.ip_win32_type == IPW32_SET_IPAPI)
3228 DWORD status;
3229 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')";
3231 /* couldn't get adapter index */
3232 if (index == (DWORD)~0)
3234 msg (M_FATAL, "ERROR: unable to get adapter index for interface %s -- %s",
3235 device_guid,
3236 error_suffix);
3239 /* check dhcp enable status */
3240 if (dhcp_disabled (index))
3241 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-Win32 TCP/IP properties are set to 'Obtain an IP address automatically'");
3243 /* delete previously added IP addresses which were not
3244 correctly deleted */
3245 delete_temp_addresses (index);
3247 /* add a new IP address */
3248 if ((status = AddIPAddress (htonl(tt->local),
3249 htonl(tt->adapter_netmask),
3250 index,
3251 &tt->ipapi_context,
3252 &tt->ipapi_instance)) == NO_ERROR)
3253 msg (M_INFO, "Succeeded in adding a temporary IP/netmask of %s/%s to interface %s using the Win32 IP Helper API",
3254 print_in_addr_t (tt->local, 0, &gc),
3255 print_in_addr_t (tt->adapter_netmask, 0, &gc),
3256 device_guid
3258 else
3259 msg (M_FATAL, "ERROR: AddIPAddress %s/%s failed on interface %s, index=%d, status=%u (windows error: '%s') -- %s",
3260 print_in_addr_t (tt->local, 0, &gc),
3261 print_in_addr_t (tt->adapter_netmask, 0, &gc),
3262 device_guid,
3263 (int)index,
3264 (unsigned int)status,
3265 strerror_win32 (status, &gc),
3266 error_suffix);
3267 tt->ipapi_context_defined = true;
3270 /*netcmd_semaphore_release ();*/
3271 gc_free (&gc);
3274 const char *
3275 tap_win32_getinfo (const struct tuntap *tt, struct gc_arena *gc)
3277 if (tt && tt->hand != NULL)
3279 struct buffer out = alloc_buf_gc (256, gc);
3280 DWORD len;
3281 if (DeviceIoControl (tt->hand, TAP_IOCTL_GET_INFO,
3282 BSTR (&out), BCAP (&out),
3283 BSTR (&out), BCAP (&out),
3284 &len, NULL))
3286 return BSTR (&out);
3289 return NULL;
3292 void
3293 tun_show_debug (struct tuntap *tt)
3295 if (tt && tt->hand != NULL)
3297 struct buffer out = alloc_buf (1024);
3298 DWORD len;
3299 while (DeviceIoControl (tt->hand, TAP_IOCTL_GET_LOG_LINE,
3300 BSTR (&out), BCAP (&out),
3301 BSTR (&out), BCAP (&out),
3302 &len, NULL))
3304 msg (D_TAP_WIN32_DEBUG, "TAP-Win32: %s", BSTR (&out));
3306 free_buf (&out);
3310 void
3311 close_tun (struct tuntap *tt)
3313 struct gc_arena gc = gc_new ();
3315 if (tt)
3317 #if 1
3318 if (tt->ipapi_context_defined)
3320 DWORD status;
3321 if ((status = DeleteIPAddress (tt->ipapi_context)) != NO_ERROR)
3323 msg (M_WARN, "Warning: DeleteIPAddress[%u] failed on TAP-Win32 adapter, status=%u : %s",
3324 (unsigned int)tt->ipapi_context,
3325 (unsigned int)status,
3326 strerror_win32 (status, &gc));
3329 #endif
3331 if (tt->options.dhcp_release)
3332 dhcp_release (tt);
3334 if (tt->hand != NULL)
3336 dmsg (D_WIN32_IO_LOW, "Attempting CancelIO on TAP-Win32 adapter");
3337 if (!CancelIo (tt->hand))
3338 msg (M_WARN | M_ERRNO, "Warning: CancelIO failed on TAP-Win32 adapter");
3341 dmsg (D_WIN32_IO_LOW, "Attempting close of overlapped read event on TAP-Win32 adapter");
3342 overlapped_io_close (&tt->reads);
3344 dmsg (D_WIN32_IO_LOW, "Attempting close of overlapped write event on TAP-Win32 adapter");
3345 overlapped_io_close (&tt->writes);
3347 if (tt->hand != NULL)
3349 dmsg (D_WIN32_IO_LOW, "Attempting CloseHandle on TAP-Win32 adapter");
3350 if (!CloseHandle (tt->hand))
3351 msg (M_WARN | M_ERRNO, "Warning: CloseHandle failed on TAP-Win32 adapter");
3354 if (tt->actual_name)
3355 free (tt->actual_name);
3357 clear_tuntap (tt);
3358 free (tt);
3360 gc_free (&gc);
3364 * Convert --ip-win32 constants between index and ascii form.
3367 struct ipset_names {
3368 const char *short_form;
3371 /* Indexed by IPW32_SET_x */
3372 static const struct ipset_names ipset_names[] = {
3373 {"manual"},
3374 {"netsh"},
3375 {"ipapi"},
3376 {"dynamic"}
3380 ascii2ipset (const char* name)
3382 int i;
3383 ASSERT (IPW32_SET_N == SIZE (ipset_names));
3384 for (i = 0; i < IPW32_SET_N; ++i)
3385 if (!strcmp (name, ipset_names[i].short_form))
3386 return i;
3387 return -1;
3390 const char *
3391 ipset2ascii (int index)
3393 ASSERT (IPW32_SET_N == SIZE (ipset_names));
3394 if (index < 0 || index >= IPW32_SET_N)
3395 return "[unknown --ip-win32 type]";
3396 else
3397 return ipset_names[index].short_form;
3400 const char *
3401 ipset2ascii_all (struct gc_arena *gc)
3403 struct buffer out = alloc_buf_gc (256, gc);
3404 int i;
3406 ASSERT (IPW32_SET_N == SIZE (ipset_names));
3407 for (i = 0; i < IPW32_SET_N; ++i)
3409 if (i)
3410 buf_printf(&out, " ");
3411 buf_printf(&out, "[%s]", ipset2ascii(i));
3413 return BSTR (&out);
3416 #else /* generic */
3418 void
3419 open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
3421 open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt);
3424 void
3425 close_tun (struct tuntap* tt)
3427 if (tt)
3429 close_tun_generic (tt);
3430 free (tt);
3435 write_tun (struct tuntap* tt, uint8_t *buf, int len)
3437 return write (tt->fd, buf, len);
3441 read_tun (struct tuntap* tt, uint8_t *buf, int len)
3443 return read (tt->fd, buf, len);
3446 #endif