OpenVPN
tun.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2024 OpenVPN Inc <sales@openvpn.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24/*
25 * Support routines for configuring and accessing TUN/TAP
26 * virtual network adapters.
27 *
28 * This file is based on the TUN/TAP driver interface routines
29 * from VTun by Maxim Krasnyansky <max_mk@yahoo.com>.
30 */
31
32#ifdef HAVE_CONFIG_H
33#include "config.h"
34#endif
35
36#include "syshead.h"
37
38#include "openvpn.h"
39#include "tun.h"
40#include "fdmisc.h"
41#include "common.h"
42#include "run_command.h"
43#include "socket.h"
44#include "manage.h"
45#include "route.h"
46#include "win32.h"
47#include "wfp_block.h"
48#include "networking.h"
49
50#include "memdbg.h"
51
52#ifdef _WIN32
53#include "openvpn-msg.h"
54#endif
55
56#include <string.h>
57
58const char *
60{
61 switch (driver)
62 {
64 return "tap-windows6";
65
67 return "wintun";
68
70 return "tun/tap";
71
72 case DRIVER_DCO:
73 return "ovpn-dco";
74
75 case DRIVER_AFUNIX:
76 return "unix";
77
78 case DRIVER_NULL:
79 return "null";
80
81 case DRIVER_UTUN:
82 return "utun";
83
84 default:
85 return "unspecified";
86 }
87}
88
89#ifdef _WIN32
90
91const static GUID GUID_DEVCLASS_NET = { 0x4d36e972L, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 } };
92const static GUID GUID_DEVINTERFACE_NET = { 0xcac88484, 0x7515, 0x4c03, { 0x82, 0xe6, 0x71, 0xa8, 0x7a, 0xba, 0xc3, 0x61 } };
93
94/* #define SIMULATE_DHCP_FAILED */ /* simulate bad DHCP negotiation */
95
96#define NI_TEST_FIRST (1<<0)
97#define NI_IP_NETMASK (1<<1)
98#define NI_OPTIONS (1<<2)
99
100static void netsh_ifconfig(const struct tuntap_options *to,
101 DWORD adapter_index,
102 const in_addr_t ip,
103 const in_addr_t netmask,
104 const unsigned int flags);
105
106static void windows_set_mtu(const int iface_index,
107 const short family,
108 const int mtu);
109
110static void netsh_set_dns6_servers(const struct in6_addr *addr_list,
111 const int addr_len,
112 DWORD adapter_index);
113
114static void netsh_command(const struct argv *a, int n, int msglevel);
115
116static void exec_command(const char *prefix, const struct argv *a, int n, int msglevel);
117
118static const char *netsh_get_id(const char *dev_node, struct gc_arena *gc);
119
120static bool
121do_address_service(const bool add, const short family, const struct tuntap *tt)
122{
123 bool ret = false;
124 ack_message_t ack;
125 struct gc_arena gc = gc_new();
126 HANDLE pipe = tt->options.msg_channel;
127
128 address_message_t addr = {
129 .header = {
131 sizeof(address_message_t),
132 0
133 },
134 .family = family,
135 .iface = { .index = tt->adapter_index, .name = "" }
136 };
137
139 {
140 strncpy(addr.iface.name, tt->actual_name, sizeof(addr.iface.name));
141 addr.iface.name[sizeof(addr.iface.name) - 1] = '\0';
142 }
143
144 if (addr.family == AF_INET)
145 {
146 addr.address.ipv4.s_addr = htonl(tt->local);
148 msg(D_IFCONFIG, "INET address service: %s %s/%d",
149 add ? "add" : "remove",
150 print_in_addr_t(tt->local, 0, &gc), addr.prefix_len);
151 }
152 else
153 {
154 addr.address.ipv6 = tt->local_ipv6;
155 addr.prefix_len = (tt->type == DEV_TYPE_TUN) ? 128 : tt->netbits_ipv6;
156 msg(D_IFCONFIG, "INET6 address service: %s %s/%d",
157 add ? "add" : "remove",
158 print_in6_addr(tt->local_ipv6, 0, &gc), addr.prefix_len);
159 }
160
161 if (!send_msg_iservice(pipe, &addr, sizeof(addr), &ack, "TUN"))
162 {
163 goto out;
164 }
165
166 if (ack.error_number != NO_ERROR)
167 {
168 msg(M_WARN, "TUN: %s address failed using service: %s [status=%u if_index=%d]",
169 (add ? "adding" : "deleting"), strerror_win32(ack.error_number, &gc),
170 ack.error_number, addr.iface.index);
171 goto out;
172 }
173
174 ret = true;
175
176out:
177 gc_free(&gc);
178 return ret;
179}
180
181static void
182do_dns_domain_service(bool add, const struct tuntap *tt)
183{
184 ack_message_t ack;
185 struct gc_arena gc = gc_new();
186 HANDLE pipe = tt->options.msg_channel;
187
188 if (!tt->options.domain) /* no domain to add or delete */
189 {
190 goto out;
191 }
192
193 /* Use dns_cfg_msg with addr_len = 0 for setting only the DOMAIN */
194 dns_cfg_message_t dns = {
195 .header = {
197 sizeof(dns_cfg_message_t),
198 0
199 },
200 .iface = { .index = tt->adapter_index, .name = "" },
201 .domains = "", /* set below */
202 .family = AF_INET, /* unused */
203 .addr_len = 0 /* add/delete only the domain, not DNS servers */
204 };
205
206 strncpynt(dns.iface.name, tt->actual_name, sizeof(dns.iface.name));
207 strncpynt(dns.domains, tt->options.domain, sizeof(dns.domains));
208 /* truncation of domain name is not checked as it can't happen
209 * with 512 bytes room in dns.domains.
210 */
211
212 msg(D_LOW, "%s dns domain on '%s' (if_index = %d) using service",
213 (add ? "Setting" : "Deleting"), dns.iface.name, dns.iface.index);
214 if (!send_msg_iservice(pipe, &dns, sizeof(dns), &ack, "TUN"))
215 {
216 goto out;
217 }
218
219 if (ack.error_number != NO_ERROR)
220 {
221 msg(M_WARN, "TUN: %s dns domain failed using service: %s [status=%u if_name=%s]",
222 (add ? "adding" : "deleting"), strerror_win32(ack.error_number, &gc),
223 ack.error_number, dns.iface.name);
224 goto out;
225 }
226
227 msg(M_INFO, "DNS domain %s using service", (add ? "set" : "deleted"));
228
229out:
230 gc_free(&gc);
231}
232
233static void
234do_dns_service(bool add, const short family, const struct tuntap *tt)
235{
236 ack_message_t ack;
237 struct gc_arena gc = gc_new();
238 HANDLE pipe = tt->options.msg_channel;
239 int len = family == AF_INET6 ? tt->options.dns6_len : tt->options.dns_len;
240 int addr_len = add ? len : 0;
241 const char *ip_proto_name = family == AF_INET6 ? "IPv6" : "IPv4";
242
243 if (len == 0)
244 {
245 /* nothing to do */
246 goto out;
247 }
248
249 /* Use dns_cfg_msg with domain = "" for setting only the DNS servers */
250 dns_cfg_message_t dns = {
251 .header = {
253 sizeof(dns_cfg_message_t),
254 0
255 },
256 .iface = { .index = tt->adapter_index, .name = "" },
257 .domains = "",
258 .family = family,
259 .addr_len = addr_len
260 };
261
262 /* interface name is required */
263 strncpy(dns.iface.name, tt->actual_name, sizeof(dns.iface.name));
264 dns.iface.name[sizeof(dns.iface.name) - 1] = '\0';
265
266 if (addr_len > _countof(dns.addr))
267 {
268 addr_len = _countof(dns.addr);
269 dns.addr_len = addr_len;
270 msg(M_WARN, "Number of %s DNS addresses sent to service truncated to %d",
271 ip_proto_name, addr_len);
272 }
273
274 for (int i = 0; i < addr_len; ++i)
275 {
276 if (family == AF_INET6)
277 {
278 dns.addr[i].ipv6 = tt->options.dns6[i];
279 }
280 else
281 {
282 dns.addr[i].ipv4.s_addr = htonl(tt->options.dns[i]);
283 }
284 }
285
286 msg(D_LOW, "%s %s dns servers on '%s' (if_index = %d) using service",
287 (add ? "Setting" : "Deleting"), ip_proto_name, dns.iface.name, dns.iface.index);
288
289 if (!send_msg_iservice(pipe, &dns, sizeof(dns), &ack, "TUN"))
290 {
291 goto out;
292 }
293
294 if (ack.error_number != NO_ERROR)
295 {
296 msg(M_WARN, "TUN: %s %s dns failed using service: %s [status=%u if_name=%s]",
297 (add ? "adding" : "deleting"), ip_proto_name, strerror_win32(ack.error_number, &gc),
298 ack.error_number, dns.iface.name);
299 goto out;
300 }
301
302 msg(M_INFO, "%s dns servers %s using service", ip_proto_name, (add ? "set" : "deleted"));
303
304out:
305 gc_free(&gc);
306}
307
308static void
309do_wins_service(bool add, const struct tuntap *tt)
310{
311 ack_message_t ack;
312 struct gc_arena gc = gc_new();
313 HANDLE pipe = tt->options.msg_channel;
314 int addr_len = add ? tt->options.wins_len : 0;
315
316 if (tt->options.wins_len == 0)
317 {
318 /* nothing to do */
319 goto out;
320 }
321
322 wins_cfg_message_t wins = {
323 .header = {
325 sizeof(wins_cfg_message_t),
326 0
327 },
328 .iface = {.index = tt->adapter_index, .name = "" },
329 .addr_len = addr_len
330 };
331
332 /* interface name is required */
333 strncpy(wins.iface.name, tt->actual_name, sizeof(wins.iface.name));
334 wins.iface.name[sizeof(wins.iface.name) - 1] = '\0';
335
336 if (addr_len > _countof(wins.addr))
337 {
338 addr_len = _countof(wins.addr);
339 wins.addr_len = addr_len;
340 msg(M_WARN, "Number of WINS addresses sent to service truncated to %d",
341 addr_len);
342 }
343
344 for (int i = 0; i < addr_len; ++i)
345 {
346 wins.addr[i].ipv4.s_addr = htonl(tt->options.wins[i]);
347 }
348
349 msg(D_LOW, "%s WINS servers on '%s' (if_index = %d) using service",
350 (add ? "Setting" : "Deleting"), wins.iface.name, wins.iface.index);
351
352 if (!send_msg_iservice(pipe, &wins, sizeof(wins), &ack, "TUN"))
353 {
354 goto out;
355 }
356
357 if (ack.error_number != NO_ERROR)
358 {
359 msg(M_WARN, "TUN: %s WINS failed using service: %s [status=%u if_name=%s]",
360 (add ? "adding" : "deleting"), strerror_win32(ack.error_number, &gc),
361 ack.error_number, wins.iface.name);
362 goto out;
363 }
364
365 msg(M_INFO, "WINS servers %s using service", (add ? "set" : "deleted"));
366
367out:
368 gc_free(&gc);
369}
370
371static bool
372do_set_mtu_service(const struct tuntap *tt, const short family, const int mtu)
373{
374 bool ret = false;
375 ack_message_t ack;
376 struct gc_arena gc = gc_new();
377 HANDLE pipe = tt->options.msg_channel;
378 const char *family_name = (family == AF_INET6) ? "IPv6" : "IPv4";
379 set_mtu_message_t mtu_msg = {
380 .header = {
382 sizeof(set_mtu_message_t),
383 0
384 },
385 .iface = {.index = tt->adapter_index},
386 .mtu = mtu,
387 .family = family
388 };
389 strncpynt(mtu_msg.iface.name, tt->actual_name, sizeof(mtu_msg.iface.name));
390 if (family == AF_INET6 && mtu < 1280)
391 {
392 msg(M_INFO, "NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
393 }
394
395 if (!send_msg_iservice(pipe, &mtu_msg, sizeof(mtu_msg), &ack, "Set_mtu"))
396 {
397 goto out;
398 }
399
400 if (ack.error_number != NO_ERROR)
401 {
402 msg(M_NONFATAL, "TUN: setting %s mtu using service failed: %s [status=%u if_index=%d]",
403 family_name, strerror_win32(ack.error_number, &gc), ack.error_number, mtu_msg.iface.index);
404 }
405 else
406 {
407 msg(M_INFO, "%s MTU set to %d on interface %d using service", family_name, mtu, mtu_msg.iface.index);
408 ret = true;
409 }
410
411out:
412 gc_free(&gc);
413 return ret;
414}
415
416static void
417do_dns_domain_wmic(bool add, const struct tuntap *tt)
418{
419 if (!tt->options.domain)
420 {
421 return;
422 }
423
424 struct argv argv = argv_new();
425 argv_printf(&argv, "%s%s nicconfig where (InterfaceIndex=%ld) call SetDNSDomain '%s'",
427 exec_command("WMIC", &argv, 1, M_WARN);
428
429 argv_free(&argv);
430}
431
432#endif /* ifdef _WIN32 */
433
434#ifdef TARGET_SOLARIS
435static void solaris_error_close(struct tuntap *tt, const struct env_set *es, const char *actual, bool unplumb_inet6);
436
437#include <stropts.h>
438#endif
439
440#if defined(TARGET_DARWIN)
441#include <sys/kern_control.h>
442#include <net/if_utun.h>
443#include <sys/sys_domain.h>
444#endif
445
446static void clear_tuntap(struct tuntap *tuntap);
447
448bool
449is_dev_type(const char *dev, const char *dev_type, const char *match_type)
450{
451 ASSERT(match_type);
452 if (!dev)
453 {
454 return false;
455 }
456 if (dev_type)
457 {
458 return !strcmp(dev_type, match_type);
459 }
460 else
461 {
462 return !strncmp(dev, match_type, strlen(match_type));
463 }
464}
465
466int
467dev_type_enum(const char *dev, const char *dev_type)
468{
469 /* We pretend that the null device is also a tun device but it does not
470 * really matter as it will discard everything anyway */
471 if (is_dev_type(dev, dev_type, "tun") || is_dev_type(dev, dev_type, "null"))
472 {
473 return DEV_TYPE_TUN;
474 }
475 else if (is_dev_type(dev, dev_type, "tap"))
476 {
477 return DEV_TYPE_TAP;
478 }
479 else
480 {
481 return DEV_TYPE_UNDEF;
482 }
483}
484
485const char *
486dev_type_string(const char *dev, const char *dev_type)
487{
488 switch (dev_type_enum(dev, dev_type))
489 {
490 case DEV_TYPE_TUN:
491 return "tun";
492
493 case DEV_TYPE_TAP:
494 return "tap";
495
496 default:
497 return "[unknown-dev-type]";
498 }
499}
500
501/*
502 * Try to predict the actual TUN/TAP device instance name,
503 * before the device is actually opened.
504 */
505const char *
506guess_tuntap_dev(const char *dev,
507 const char *dev_type,
508 const char *dev_node,
509 struct gc_arena *gc)
510{
511#ifdef _WIN32
512 const int dt = dev_type_enum(dev, dev_type);
513 if (dt == DEV_TYPE_TUN || dt == DEV_TYPE_TAP)
514 {
515 return netsh_get_id(dev_node, gc);
516 }
517#endif
518
519 /* default case */
520 return dev;
521}
522
523
524/* --ifconfig-nowarn disables some options sanity checking */
525static const char ifconfig_warn_how_to_silence[] = "(silence this warning with --ifconfig-nowarn)";
526
527/*
528 * If !tun_p2p, make sure ifconfig_remote_netmask looks
529 * like a netmask.
530 *
531 * If tun_p2p, make sure ifconfig_remote_netmask looks
532 * like an IPv4 address.
533 */
534static void
535ifconfig_sanity_check(bool tun_p2p, in_addr_t addr)
536{
537 struct gc_arena gc = gc_new();
538 const bool looks_like_netmask = ((addr & 0xFF000000) == 0xFF000000);
539 if (tun_p2p)
540 {
541 if (looks_like_netmask)
542 {
543 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",
544 print_in_addr_t(addr, 0, &gc),
546 }
547 }
548 else
549 {
550 if (!looks_like_netmask)
551 {
552 msg(M_WARN, "WARNING: Since you are using subnet topology, the second argument to --ifconfig must be a netmask, for example something like 255.255.255.0. %s",
554 }
555 }
556 gc_free(&gc);
557}
558
559/*
560 * Check that --local and --remote addresses do not
561 * clash with ifconfig addresses or subnet.
562 */
563static void
564check_addr_clash(const char *name,
565 int type,
566 in_addr_t public,
567 in_addr_t local,
568 in_addr_t remote_netmask)
569{
570 struct gc_arena gc = gc_new();
571#if 0
572 msg(M_INFO, "CHECK_ADDR_CLASH type=%d public=%s local=%s, remote_netmask=%s",
573 type,
574 print_in_addr_t(public, 0, &gc),
575 print_in_addr_t(local, 0, &gc),
576 print_in_addr_t(remote_netmask, 0, &gc));
577#endif
578
579 if (public)
580 {
581 if (type == DEV_TYPE_TUN)
582 {
583 const in_addr_t test_netmask = 0xFFFFFF00;
584 const in_addr_t public_net = public &test_netmask;
585 const in_addr_t local_net = local & test_netmask;
586 const in_addr_t remote_net = remote_netmask & test_netmask;
587
588 if (public == local || public == remote_netmask)
589 {
590 msg(M_WARN,
591 "WARNING: --%s address [%s] conflicts with --ifconfig address pair [%s, %s]. %s",
592 name,
593 print_in_addr_t(public, 0, &gc),
594 print_in_addr_t(local, 0, &gc),
595 print_in_addr_t(remote_netmask, 0, &gc),
597 }
598
599 if (public_net == local_net || public_net == remote_net)
600 {
601 msg(M_WARN,
602 "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",
603 name,
604 print_in_addr_t(public, 0, &gc),
605 print_in_addr_t(local, 0, &gc),
606 print_in_addr_t(remote_netmask, 0, &gc),
608 }
609 }
610 else if (type == DEV_TYPE_TAP)
611 {
612 const in_addr_t public_network = public &remote_netmask;
613 const in_addr_t virtual_network = local & remote_netmask;
614 if (public_network == virtual_network)
615 {
616 msg(M_WARN,
617 "WARNING: --%s address [%s] conflicts with --ifconfig subnet [%s, %s] -- local and remote addresses cannot be inside of the --ifconfig subnet. %s",
618 name,
619 print_in_addr_t(public, 0, &gc),
620 print_in_addr_t(local, 0, &gc),
621 print_in_addr_t(remote_netmask, 0, &gc),
623 }
624 }
625 }
626 gc_free(&gc);
627}
628
629void
631{
632 struct gc_arena gc = gc_new();
633 struct route_gateway_info rgi;
634 const unsigned int needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED);
635
636 get_default_gateway(&rgi, 0, ctx);
637 if ((rgi.flags & needed) == needed)
638 {
639 const in_addr_t lan_network = rgi.gateway.addr & rgi.gateway.netmask;
640 if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100)
641 {
642 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.");
643 }
644 }
645 gc_free(&gc);
646}
647
648/*
649 * Return a string to be used for options compatibility check
650 * between peers.
651 */
652const char *
653ifconfig_options_string(const struct tuntap *tt, bool remote, bool disable, struct gc_arena *gc)
654{
655 struct buffer out = alloc_buf_gc(256, gc);
656 if (tt->did_ifconfig_setup && !disable)
657 {
658 if (!is_tun_p2p(tt))
659 {
660 buf_printf(&out, "%s %s",
661 print_in_addr_t(tt->local & tt->remote_netmask, 0, gc),
662 print_in_addr_t(tt->remote_netmask, 0, gc));
663 }
664 else if (tt->type == DEV_TYPE_TUN) /* tun p2p topology */
665 {
666 const char *l, *r;
667 if (remote)
668 {
669 r = print_in_addr_t(tt->local, 0, gc);
670 l = print_in_addr_t(tt->remote_netmask, 0, gc);
671 }
672 else
673 {
674 l = print_in_addr_t(tt->local, 0, gc);
675 r = print_in_addr_t(tt->remote_netmask, 0, gc);
676 }
677 buf_printf(&out, "%s %s", r, l);
678 }
679 else
680 {
681 buf_printf(&out, "[undef]");
682 }
683 }
684 return BSTR(&out);
685}
686
687/*
688 * Return a status string describing wait state.
689 */
690const char *
691tun_stat(const struct tuntap *tt, unsigned int rwflags, struct gc_arena *gc)
692{
693 struct buffer out = alloc_buf_gc(64, gc);
694 if (tt)
695 {
696 if (rwflags & EVENT_READ)
697 {
698 buf_printf(&out, "T%s",
699 (tt->rwflags_debug & EVENT_READ) ? "R" : "r");
700#ifdef _WIN32
701 buf_printf(&out, "%s",
703#endif
704 }
705 if (rwflags & EVENT_WRITE)
706 {
707 buf_printf(&out, "T%s",
708 (tt->rwflags_debug & EVENT_WRITE) ? "W" : "w");
709#ifdef _WIN32
710 buf_printf(&out, "%s",
711 overlapped_io_state_ascii(&tt->writes));
712#endif
713 }
714 }
715 else
716 {
717 buf_printf(&out, "T?");
718 }
719 return BSTR(&out);
720}
721
722/*
723 * Return true for point-to-point topology, false for subnet topology
724 */
725bool
726is_tun_p2p(const struct tuntap *tt)
727{
728 bool tun_p2p = false;
729
730 if (tt->type == DEV_TYPE_TAP
731 || (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET))
732 {
733 tun_p2p = false;
734 }
735 else if (tt->type == DEV_TYPE_TUN)
736 {
737 tun_p2p = true;
738 }
739 else
740 {
741 msg(M_FATAL, "Error: problem with tun vs. tap setting"); /* JYFIXME -- needs to be caught earlier, in init_tun? */
742 }
743 return tun_p2p;
744}
745
746/*
747 * Set the ifconfig_* environment variables, both for IPv4 and IPv6
748 */
749void
750do_ifconfig_setenv(const struct tuntap *tt, struct env_set *es)
751{
752 struct gc_arena gc = gc_new();
753 const char *ifconfig_local = print_in_addr_t(tt->local, 0, &gc);
754 const char *ifconfig_remote_netmask = print_in_addr_t(tt->remote_netmask, 0, &gc);
755
756 /*
757 * Set environmental variables with ifconfig parameters.
758 */
759 if (tt->did_ifconfig_setup)
760 {
761 bool tun = is_tun_p2p(tt);
762
763 setenv_str(es, "ifconfig_local", ifconfig_local);
764 if (tun)
765 {
766 setenv_str(es, "ifconfig_remote", ifconfig_remote_netmask);
767 }
768 else
769 {
770 setenv_str(es, "ifconfig_netmask", ifconfig_remote_netmask);
771 }
772 }
773
775 {
776 const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
777 const char *ifconfig_ipv6_remote = print_in6_addr(tt->remote_ipv6, 0, &gc);
778
779 setenv_str(es, "ifconfig_ipv6_local", ifconfig_ipv6_local);
780 setenv_int(es, "ifconfig_ipv6_netbits", tt->netbits_ipv6);
781 setenv_str(es, "ifconfig_ipv6_remote", ifconfig_ipv6_remote);
782 }
783
784 gc_free(&gc);
785}
786
787/*
788 * Init tun/tap object.
789 *
790 * Set up tuntap structure for ifconfig,
791 * but don't execute yet.
792 */
793struct tuntap *
794init_tun(const char *dev, /* --dev option */
795 const char *dev_type, /* --dev-type option */
796 int topology, /* one of the TOP_x values */
797 const char *ifconfig_local_parm, /* --ifconfig parm 1 */
798 const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */
799 const char *ifconfig_ipv6_local_parm, /* --ifconfig parm 1 IPv6 */
800 int ifconfig_ipv6_netbits_parm,
801 const char *ifconfig_ipv6_remote_parm, /* --ifconfig parm 2 IPv6 */
802 struct addrinfo *local_public,
803 struct addrinfo *remote_public,
804 const bool strict_warn,
805 struct env_set *es,
807 struct tuntap *tt)
808{
809 if (!tt)
810 {
811 ALLOC_OBJ(tt, struct tuntap);
812 clear_tuntap(tt);
813 }
814
815 tt->type = dev_type_enum(dev, dev_type);
816 tt->topology = topology;
817
818 if (ifconfig_local_parm && ifconfig_remote_netmask_parm)
819 {
820 /*
821 * We only handle TUN/TAP devices here, not --dev null devices.
822 */
823 bool tun_p2p = is_tun_p2p(tt);
824
825 /*
826 * Convert arguments to binary IPv4 addresses.
827 */
828
829 tt->local = getaddr(
834 ifconfig_local_parm,
835 0,
836 NULL,
837 NULL);
838
840 (tun_p2p ? GETADDR_RESOLVE : 0)
844 ifconfig_remote_netmask_parm,
845 0,
846 NULL,
847 NULL);
848
849 /*
850 * Look for common errors in --ifconfig parms
851 */
852 if (strict_warn)
853 {
854 struct addrinfo *curele;
856
857 /*
858 * If local_public or remote_public addresses are defined,
859 * make sure they do not clash with our virtual subnet.
860 */
861
862 for (curele = local_public; curele; curele = curele->ai_next)
863 {
864 if (curele->ai_family == AF_INET)
865 {
866 const in_addr_t local = ntohl(((struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
867 check_addr_clash("local",
868 tt->type,
869 local,
870 tt->local,
871 tt->remote_netmask);
872 }
873 }
874
875 for (curele = remote_public; curele; curele = curele->ai_next)
876 {
877 if (curele->ai_family == AF_INET)
878 {
879 const in_addr_t remote = ntohl(((struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
880 check_addr_clash("remote",
881 tt->type,
882 remote,
883 tt->local,
884 tt->remote_netmask);
885 }
886 }
887 }
888
889#ifdef _WIN32
890 /*
891 * Make sure that both ifconfig addresses are part of the
892 * same .252 subnet.
893 */
894 if (tun_p2p)
895 {
897 tt->adapter_netmask = ~3;
898 }
899 else
900 {
902 }
903#endif
904
905 tt->did_ifconfig_setup = true;
906 }
907
908 if (ifconfig_ipv6_local_parm && ifconfig_ipv6_remote_parm)
909 {
910
911 /*
912 * Convert arguments to binary IPv6 addresses.
913 */
914
915 if (inet_pton( AF_INET6, ifconfig_ipv6_local_parm, &tt->local_ipv6 ) != 1
916 || inet_pton( AF_INET6, ifconfig_ipv6_remote_parm, &tt->remote_ipv6 ) != 1)
917 {
918 msg( M_FATAL, "init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary", ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm );
919 }
920 tt->netbits_ipv6 = ifconfig_ipv6_netbits_parm;
921
922 tt->did_ifconfig_ipv6_setup = true;
923 }
924
925 /*
926 * Set environmental variables with ifconfig parameters.
927 */
928 if (es)
929 {
931 }
932
933 return tt;
934}
935
936/*
937 * Platform specific tun initializations
938 */
939void
941 const struct frame *frame,
942 const struct tuntap_options *options)
943{
944 tt->options = *options;
945#ifdef _WIN32
946 if (tt->backend_driver == DRIVER_DCO)
947 {
948 tt->dco.tt = tt;
949 return;
950 }
951
952 overlapped_io_init(&tt->reads, frame, FALSE);
953 overlapped_io_init(&tt->writes, frame, TRUE);
955
957 {
958 tt->wintun_send_ring_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
959 PAGE_READWRITE,
960 0,
961 sizeof(struct tun_ring),
962 NULL);
963 tt->wintun_receive_ring_handle = CreateFileMapping(INVALID_HANDLE_VALUE,
964 NULL,
965 PAGE_READWRITE,
966 0,
967 sizeof(struct tun_ring),
968 NULL);
969 if ((tt->wintun_send_ring_handle == NULL) || (tt->wintun_receive_ring_handle == NULL))
970 {
971 msg(M_FATAL, "Cannot allocate memory for ring buffer");
972 }
973
974 tt->rw_handle.read = CreateEvent(NULL, FALSE, FALSE, NULL);
975 tt->rw_handle.write = CreateEvent(NULL, FALSE, FALSE, NULL);
976
977 if ((tt->rw_handle.read == NULL) || (tt->rw_handle.write == NULL))
978 {
979 msg(M_FATAL, "Cannot create events for ring buffer");
980 }
981 }
982 else
983 {
984 tt->rw_handle.read = tt->reads.overlapped.hEvent;
985 tt->rw_handle.write = tt->writes.overlapped.hEvent;
986 }
987#endif /* ifdef _WIN32 */
988}
989
990#if defined(_WIN32)
991
992/* some of the platforms will auto-add a "network route" pointing
993 * to the interface on "ifconfig tunX 2001:db8::1/64", others need
994 * an extra call to "route add..."
995 * -> helper function to simplify code below
996 */
997static void
999 const struct env_set *es)
1000{
1001 struct route_ipv6 r6;
1002
1003 CLEAR(r6);
1004 r6.network = tt->local_ipv6;
1005 r6.netbits = tt->netbits_ipv6;
1006 r6.gateway = tt->local_ipv6;
1007 r6.metric = 0; /* connected route */
1009 add_route_ipv6(&r6, tt, 0, es, NULL);
1010}
1011
1012void
1014{
1015 struct route_ipv6 r6;
1016
1017 CLEAR(r6);
1018 r6.network = tt->local_ipv6;
1019 r6.netbits = tt->netbits_ipv6;
1020 r6.gateway = tt->local_ipv6;
1021 r6.metric = 0; /* connected route */
1024 delete_route_ipv6(&r6, tt, NULL, NULL);
1025}
1026#endif /* if defined(_WIN32) || defined(TARGET_DARWIN) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) */
1027
1028#if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
1029 || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD)
1030/* we can't use true subnet mode on tun on all platforms, as that
1031 * conflicts with IPv6 (wants to use ND then, which we don't do),
1032 * but the OSes want "a remote address that is different from ours"
1033 * - so we construct one, normally the first in the subnet, but if
1034 * this is the same as ours, use the second one.
1035 * The actual address does not matter at all, as the tun interface
1036 * is still point to point and no layer 2 resolution is done...
1037 */
1038
1039in_addr_t
1040create_arbitrary_remote( struct tuntap *tt )
1041{
1042 in_addr_t remote;
1043
1044 remote = (tt->local & tt->remote_netmask) +1;
1045
1046 if (remote == tt->local)
1047 {
1048 remote++;
1049 }
1050
1051 return remote;
1052}
1053#endif
1054
1064static void
1065do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
1066 const struct env_set *es, openvpn_net_ctx_t *ctx)
1067{
1068#if !defined(TARGET_LINUX)
1069 struct argv argv = argv_new();
1070 struct gc_arena gc = gc_new();
1071 const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
1072#endif
1073
1074#if defined(TARGET_LINUX)
1075 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1076 {
1077 msg(M_FATAL, "Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1078 }
1079
1080 if (net_iface_up(ctx, ifname, true) < 0)
1081 {
1082 msg(M_FATAL, "Linux can't bring %s up", ifname);
1083 }
1084
1085 if (net_addr_v6_add(ctx, ifname, &tt->local_ipv6,
1086 tt->netbits_ipv6) < 0)
1087 {
1088 msg(M_FATAL, "Linux can't add IPv6 to interface %s", ifname);
1089 }
1090#elif defined(TARGET_ANDROID)
1091 char out6[64];
1092
1093 snprintf(out6, sizeof(out6), "%s/%d %d",
1094 ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
1095 management_android_control(management, "IFCONFIG6", out6);
1096#elif defined(TARGET_SOLARIS)
1097 argv_printf(&argv, "%s %s inet6 unplumb", IFCONFIG_PATH, ifname);
1098 argv_msg(M_INFO, &argv);
1099 openvpn_execve_check(&argv, es, 0, NULL);
1100
1101 if (tt->type == DEV_TYPE_TUN)
1102 {
1103 const char *ifconfig_ipv6_remote = print_in6_addr(tt->remote_ipv6, 0, &gc);
1104
1105 argv_printf(&argv, "%s %s inet6 plumb %s/%d %s mtu %d up",
1106 IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
1107 tt->netbits_ipv6, ifconfig_ipv6_remote, tun_mtu);
1108 }
1109 else /* tap mode */
1110 {
1111 /* base IPv6 tap interface needs to be brought up first */
1112 argv_printf(&argv, "%s %s inet6 plumb up", IFCONFIG_PATH, ifname);
1113 argv_msg(M_INFO, &argv);
1114
1115 if (!openvpn_execve_check(&argv, es, 0,
1116 "Solaris ifconfig IPv6 (prepare) failed"))
1117 {
1118 solaris_error_close(tt, es, ifname, true);
1119 }
1120
1121 /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
1122 * after the system has noticed the interface and fired up
1123 * the DHCPv6 client - but this takes quite a while, and the
1124 * server will ignore the DHCPv6 packets anyway. So we don't.
1125 */
1126
1127 /* static IPv6 addresses need to go to a subinterface (tap0:1)
1128 * and we cannot set an mtu here (must go to the "parent")
1129 */
1130 argv_printf(&argv, "%s %s inet6 addif %s/%d up", IFCONFIG_PATH,
1131 ifname, ifconfig_ipv6_local, tt->netbits_ipv6 );
1132 }
1133 argv_msg(M_INFO, &argv);
1134
1135 if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 failed"))
1136 {
1137 solaris_error_close(tt, es, ifname, true);
1138 }
1139
1140 if (tt->type != DEV_TYPE_TUN)
1141 {
1142 argv_printf(&argv, "%s %s inet6 mtu %d", IFCONFIG_PATH,
1143 ifname, tun_mtu);
1144 argv_msg(M_INFO, &argv);
1145 openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 mtu failed");
1146 }
1147#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
1148 || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
1149 || defined(TARGET_DRAGONFLY)
1150 argv_printf(&argv, "%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
1151 ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
1152 argv_msg(M_INFO, &argv);
1153
1155 "generic BSD ifconfig inet6 failed");
1156
1157#if defined(TARGET_FREEBSD) && __FreeBSD_version >= 1200000 \
1158 && __FreeBSD_version < 1300000
1159 /* On FreeBSD 12.0-12.4, there is ipv6_activate_all_interfaces="YES"
1160 * in rc.conf, which is not set by default. If it is *not* set,
1161 * "all new interfaces that are not already up" are configured by
1162 * devd -> /etc/pccard_ether -> /etc/network.subr as "inet6 ifdisabled".
1163 *
1164 * The "is this interface already up?" test is a non-zero time window
1165 * which we manage to hit with our ifconfig often enough to cause
1166 * frequent fails in the openvpn test environment.
1167 *
1168 * Thus: assume that the system might interfere, wait for things to
1169 * settle (it's a very short time window), and remove -ifdisable again.
1170 *
1171 * See: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=248172
1172 */
1173 sleep(1);
1174 argv_printf(&argv, "%s %s inet6 -ifdisabled", IFCONFIG_PATH, ifname);
1175 argv_msg(M_INFO, &argv);
1176
1178 "FreeBSD BSD 'ifconfig inet6 -ifdisabled' failed");
1179#endif
1180
1181#elif defined(TARGET_AIX)
1182 argv_printf(&argv, "%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
1183 ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
1184 argv_msg(M_INFO, &argv);
1185
1186 /* AIX ifconfig will complain if it can't find ODM path in env */
1187 es = env_set_create(NULL);
1188 env_set_add(es, "ODMDIR=/etc/objrepos");
1189
1191 "generic BSD ifconfig inet6 failed");
1192
1194#elif defined (_WIN32)
1196 {
1197 msg(M_INFO, "******** NOTE: Please manually set the v6 IP of '%s' to %s (if it is not already set)",
1198 ifname, ifconfig_ipv6_local);
1199 }
1200 else if (tt->options.msg_channel)
1201 {
1202 do_address_service(true, AF_INET6, tt);
1203 if (tt->type == DEV_TYPE_TUN)
1204 {
1206 }
1207 do_dns_service(true, AF_INET6, tt);
1208 do_set_mtu_service(tt, AF_INET6, tun_mtu);
1209 /* If IPv4 is not enabled, set DNS domain here */
1210 if (!tt->did_ifconfig_setup)
1211 {
1212 do_dns_domain_service(true, tt);
1213 }
1214 }
1215 else
1216 {
1217 /* example: netsh interface ipv6 set address 42
1218 * 2001:608:8003::d/bits store=active
1219 */
1220
1221 /* in TUN mode, we only simulate a subnet, so the interface
1222 * is configured with /128 + a route to fe80::8. In TAP mode,
1223 * the correct netbits must be set, and no on-link route
1224 */
1225 int netbits = (tt->type == DEV_TYPE_TUN) ? 128 : tt->netbits_ipv6;
1226
1227 argv_printf(&argv, "%s%s interface ipv6 set address %lu %s/%d store=active",
1229 ifconfig_ipv6_local, netbits);
1231 if (tt->type == DEV_TYPE_TUN)
1232 {
1234 }
1235 /* set ipv6 dns servers if any are specified */
1237 windows_set_mtu(tt->adapter_index, AF_INET6, tun_mtu);
1238
1239 if (!tt->did_ifconfig_setup)
1240 {
1241 do_dns_domain_wmic(true, tt);
1242 }
1243 }
1244#else /* platforms we have no IPv6 code for */
1245 msg(M_FATAL, "Sorry, but I don't know how to do IPv6 'ifconfig' commands on this operating system. You should ifconfig your TUN/TAP device manually or use an --up script.");
1246#endif /* outer "if defined(TARGET_xxx)" conditional */
1247
1248#if !defined(TARGET_LINUX)
1249 gc_free(&gc);
1250 argv_free(&argv);
1251#endif
1252}
1253
1263static void
1264do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
1265 const struct env_set *es, openvpn_net_ctx_t *ctx)
1266{
1267#if !defined(_WIN32) && !defined(TARGET_ANDROID)
1268 /*
1269 * We only handle TUN/TAP devices here, not --dev null devices.
1270 */
1271 bool tun_p2p = is_tun_p2p(tt);
1272#endif
1273
1274#if !defined(TARGET_LINUX)
1275 const char *ifconfig_local = NULL;
1276 const char *ifconfig_remote_netmask = NULL;
1277 struct argv argv = argv_new();
1278 struct gc_arena gc = gc_new();
1279
1280 /*
1281 * Set ifconfig parameters
1282 */
1283 ifconfig_local = print_in_addr_t(tt->local, 0, &gc);
1284 ifconfig_remote_netmask = print_in_addr_t(tt->remote_netmask, 0, &gc);
1285#endif
1286
1287#if defined(TARGET_LINUX)
1288 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1289 {
1290 msg(M_FATAL, "Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1291 }
1292
1293 if (net_iface_up(ctx, ifname, true) < 0)
1294 {
1295 msg(M_FATAL, "Linux can't bring %s up", ifname);
1296 }
1297
1298 if (tun_p2p)
1299 {
1300 if (net_addr_ptp_v4_add(ctx, ifname, &tt->local,
1301 &tt->remote_netmask) < 0)
1302 {
1303 msg(M_FATAL, "Linux can't add IP to interface %s", ifname);
1304 }
1305 }
1306 else
1307 {
1308 if (net_addr_v4_add(ctx, ifname, &tt->local,
1310 {
1311 msg(M_FATAL, "Linux can't add IP to interface %s", ifname);
1312 }
1313 }
1314#elif defined(TARGET_ANDROID)
1315 char out[64];
1316
1317 snprintf(out, sizeof(out), "%s %s %d %s", ifconfig_local,
1318 ifconfig_remote_netmask, tun_mtu, print_topology(tt->topology));
1319 management_android_control(management, "IFCONFIG", out);
1320
1321#elif defined(TARGET_SOLARIS)
1322 /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
1323 * example:
1324 * ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
1325 * ifconfig tun2 netmask 255.255.255.255
1326 */
1327 if (tun_p2p)
1328 {
1329 argv_printf(&argv, "%s %s %s %s mtu %d up", IFCONFIG_PATH, ifname,
1330 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1331
1332 argv_msg(M_INFO, &argv);
1333 if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-1 failed"))
1334 {
1335 solaris_error_close(tt, es, ifname, false);
1336 }
1337
1338 argv_printf(&argv, "%s %s netmask 255.255.255.255", IFCONFIG_PATH,
1339 ifname);
1340 }
1341 else if (tt->type == DEV_TYPE_TUN)
1342 {
1343 argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
1344 ifname, ifconfig_local, ifconfig_local,
1345 ifconfig_remote_netmask, tun_mtu);
1346 }
1347 else /* tap */
1348 {
1349 argv_printf(&argv, "%s %s %s netmask %s up",
1350 IFCONFIG_PATH, ifname, ifconfig_local,
1351 ifconfig_remote_netmask);
1352 }
1353
1354 argv_msg(M_INFO, &argv);
1355 if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-2 failed"))
1356 {
1357 solaris_error_close(tt, es, ifname, false);
1358 }
1359
1360 if (!tun_p2p && tt->type == DEV_TYPE_TUN)
1361 {
1362 /* Add a network route for the local tun interface */
1363 struct route_ipv4 r;
1364 CLEAR(r);
1366 r.network = tt->local & tt->remote_netmask;
1367 r.netmask = tt->remote_netmask;
1368 r.gateway = tt->local;
1369 r.metric = 0;
1370 add_route(&r, tt, 0, NULL, es, NULL);
1371 }
1372
1373#elif defined(TARGET_OPENBSD)
1374
1375 in_addr_t remote_end; /* for "virtual" subnet topology */
1376
1377 /*
1378 * On OpenBSD, tun interfaces are persistent if created with
1379 * "ifconfig tunX create", and auto-destroyed if created by
1380 * opening "/dev/tunX" (so we just use the /dev/tunX)
1381 */
1382
1383 /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1384 if (tun_p2p)
1385 {
1387 "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
1388 IFCONFIG_PATH, ifname, ifconfig_local,
1389 ifconfig_remote_netmask, tun_mtu);
1390 }
1391 else if (tt->type == DEV_TYPE_TUN)
1392 {
1393 remote_end = create_arbitrary_remote( tt );
1394 argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up -link0",
1395 IFCONFIG_PATH, ifname, ifconfig_local,
1396 print_in_addr_t(remote_end, 0, &gc), tun_mtu,
1397 ifconfig_remote_netmask);
1398 }
1399 else /* tap */
1400 {
1401 argv_printf(&argv, "%s %s %s netmask %s mtu %d link0",
1402 IFCONFIG_PATH, ifname, ifconfig_local,
1403 ifconfig_remote_netmask, tun_mtu);
1404 }
1405 argv_msg(M_INFO, &argv);
1406 openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig failed");
1407
1408 /* Add a network route for the local tun interface */
1409 if (!tun_p2p && tt->type == DEV_TYPE_TUN)
1410 {
1411 struct route_ipv4 r;
1412 CLEAR(r);
1413 r.flags = RT_DEFINED;
1414 r.network = tt->local & tt->remote_netmask;
1415 r.netmask = tt->remote_netmask;
1416 r.gateway = remote_end;
1417 add_route(&r, tt, 0, NULL, es, NULL);
1418 }
1419
1420#elif defined(TARGET_NETBSD)
1421 in_addr_t remote_end = INADDR_ANY; /* for "virtual" subnet topology */
1422
1423 if (tun_p2p)
1424 {
1425 argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
1426 IFCONFIG_PATH, ifname, ifconfig_local,
1427 ifconfig_remote_netmask, tun_mtu);
1428 }
1429 else if (tt->type == DEV_TYPE_TUN)
1430 {
1431 remote_end = create_arbitrary_remote(tt);
1432 argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH,
1433 ifname, ifconfig_local, print_in_addr_t(remote_end, 0, &gc),
1434 tun_mtu, ifconfig_remote_netmask);
1435 }
1436 else /* tap */
1437 {
1438 /*
1439 * NetBSD has distinct tun and tap devices
1440 * so we don't need the "link0" extra parameter to specify we want to do
1441 * tunneling at the ethernet level
1442 */
1443 argv_printf(&argv, "%s %s %s netmask %s mtu %d",
1444 IFCONFIG_PATH, ifname, ifconfig_local,
1445 ifconfig_remote_netmask, tun_mtu);
1446 }
1447 argv_msg(M_INFO, &argv);
1448 openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig failed");
1449
1450 /* Add a network route for the local tun interface */
1451 if (!tun_p2p && tt->type == DEV_TYPE_TUN)
1452 {
1453 struct route_ipv4 r;
1454 CLEAR(r);
1455 r.flags = RT_DEFINED;
1456 r.network = tt->local & tt->remote_netmask;
1457 r.netmask = tt->remote_netmask;
1458 r.gateway = remote_end;
1459 add_route(&r, tt, 0, NULL, es, NULL);
1460 }
1461
1462#elif defined(TARGET_DARWIN)
1463 /*
1464 * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
1465 */
1466
1467 argv_printf(&argv, "%s %s delete", IFCONFIG_PATH, ifname);
1468 argv_msg(M_INFO, &argv);
1469 openvpn_execve_check(&argv, es, 0, NULL);
1470 msg(M_INFO,
1471 "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
1472
1473
1474 /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1475 if (tun_p2p)
1476 {
1477 argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
1478 IFCONFIG_PATH, ifname, ifconfig_local,
1479 ifconfig_remote_netmask, tun_mtu);
1480 }
1481 else if (tt->type == DEV_TYPE_TUN)
1482 {
1483 argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up",
1484 IFCONFIG_PATH, ifname, ifconfig_local, ifconfig_local,
1485 ifconfig_remote_netmask, tun_mtu);
1486 }
1487 else /* tap */
1488 {
1489 argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
1490 ifname, ifconfig_local, ifconfig_remote_netmask,
1491 tun_mtu);
1492 }
1493
1494 argv_msg(M_INFO, &argv);
1495 openvpn_execve_check(&argv, es, S_FATAL, "Mac OS X ifconfig failed");
1496
1497 /* Add a network route for the local tun interface */
1498 if (!tun_p2p && tt->type == DEV_TYPE_TUN)
1499 {
1500 struct route_ipv4 r;
1501 CLEAR(r);
1502 r.flags = RT_DEFINED;
1503 r.network = tt->local & tt->remote_netmask;
1504 r.netmask = tt->remote_netmask;
1505 r.gateway = tt->local;
1506 add_route(&r, tt, 0, NULL, es, NULL);
1507 }
1508
1509#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1510
1511 /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1512 if (tun_p2p) /* point-to-point tun */
1513 {
1514 argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
1515 IFCONFIG_PATH, ifname, ifconfig_local,
1516 ifconfig_remote_netmask, tun_mtu);
1517 }
1518 else /* tun with topology subnet and tap mode (always subnet) */
1519 {
1520 int netbits = netmask_to_netbits2(tt->remote_netmask);
1521 argv_printf(&argv, "%s %s %s/%d mtu %d up", IFCONFIG_PATH,
1522 ifname, ifconfig_local, netbits, tun_mtu );
1523 }
1524
1525 argv_msg(M_INFO, &argv);
1526 openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig failed");
1527
1528#elif defined(TARGET_AIX)
1529 {
1530 /* AIX ifconfig will complain if it can't find ODM path in env */
1531 struct env_set *aix_es = env_set_create(NULL);
1532 env_set_add( aix_es, "ODMDIR=/etc/objrepos" );
1533
1534 if (tt->type == DEV_TYPE_TUN)
1535 {
1536 msg(M_FATAL, "no tun support on AIX (canthappen)");
1537 }
1538
1539 /* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */
1540 argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
1541 ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1542
1543 argv_msg(M_INFO, &argv);
1544 openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig failed");
1545
1546 env_set_destroy(aix_es);
1547 }
1548#elif defined (_WIN32)
1550 {
1551 msg(M_INFO,
1552 "******** NOTE: Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
1553 ifname, ifconfig_local,
1554 ifconfig_remote_netmask);
1555 }
1557 {
1558 /* Let the DHCP configure the interface. */
1559 }
1560 else if (tt->options.msg_channel)
1561 {
1562 do_address_service(true, AF_INET, tt);
1563 do_dns_service(true, AF_INET, tt);
1564 do_dns_domain_service(true, tt);
1565 do_wins_service(true, tt);
1566 }
1567 else
1568 {
1570 {
1573 }
1574
1575 do_dns_domain_wmic(true, tt);
1576 }
1577
1578
1579 if (tt->options.msg_channel)
1580 {
1581 do_set_mtu_service(tt, AF_INET, tun_mtu);
1582 }
1583 else
1584 {
1585 windows_set_mtu(tt->adapter_index, AF_INET, tun_mtu);
1586 }
1587#elif defined(TARGET_HAIKU)
1588 /* example: ifconfig tun/0 inet 1.1.1.1 255.255.255.0 mtu 1450 up */
1589 argv_printf(&argv, "%s %s inet %s %s mtu %d up", IFCONFIG_PATH,
1590 ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1591
1592 argv_msg(M_INFO, &argv);
1593 openvpn_execve_check(&argv, es, S_FATAL, "Haiku ifconfig failed");
1594#else /* if defined(TARGET_LINUX) */
1595 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.");
1596#endif /* if defined(TARGET_LINUX) */
1597
1598#if !defined(TARGET_LINUX)
1599 gc_free(&gc);
1600 argv_free(&argv);
1601#endif
1602}
1603
1604/* execute the ifconfig command through the shell */
1605void
1606do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
1607 const struct env_set *es, openvpn_net_ctx_t *ctx)
1608{
1609 msg(D_LOW, "do_ifconfig, ipv4=%d, ipv6=%d", tt->did_ifconfig_setup,
1611
1612#ifdef ENABLE_MANAGEMENT
1613 if (management)
1614 {
1617 NULL,
1618 &tt->local,
1619 &tt->local_ipv6,
1620 NULL,
1621 NULL);
1622 }
1623#endif
1624
1625 if (tt->did_ifconfig_setup)
1626 {
1627 do_ifconfig_ipv4(tt, ifname, tun_mtu, es, ctx);
1628 }
1629
1631 {
1632 do_ifconfig_ipv6(tt, ifname, tun_mtu, es, ctx);
1633 }
1634
1635 /* release resources potentially allocated during interface setup */
1636 net_ctx_free(ctx);
1637}
1638
1639static void
1641{
1642#if defined(TARGET_LINUX)
1643 int netbits = netmask_to_netbits2(tt->remote_netmask);
1644
1645 if (is_tun_p2p(tt))
1646 {
1647 if (net_addr_ptp_v4_del(ctx, tt->actual_name, &tt->local,
1648 &tt->remote_netmask) < 0)
1649 {
1650 msg(M_WARN, "Linux can't del IP from iface %s",
1651 tt->actual_name);
1652 }
1653 }
1654 else
1655 {
1656 if (net_addr_v4_del(ctx, tt->actual_name, &tt->local, netbits) < 0)
1657 {
1658 msg(M_WARN, "Linux can't del IP from iface %s",
1659 tt->actual_name);
1660 }
1661 }
1662#elif defined(TARGET_FREEBSD)
1663 struct gc_arena gc = gc_new();
1664 const char *ifconfig_local = print_in_addr_t(tt->local, 0, &gc);
1665 struct argv argv = argv_new();
1666
1667 argv_printf(&argv, "%s %s %s -alias", IFCONFIG_PATH,
1668 tt->actual_name, ifconfig_local);
1669 argv_msg(M_INFO, &argv);
1670 openvpn_execve_check(&argv, NULL, 0, "FreeBSD ip addr del failed");
1671
1672 argv_free(&argv);
1673 gc_free(&gc);
1674#endif /* if defined(TARGET_LINUX) */
1675 /* Empty for _WIN32 and all other unixoid platforms */
1676}
1677
1678static void
1680{
1681#if defined(TARGET_LINUX)
1682 if (net_addr_v6_del(ctx, tt->actual_name, &tt->local_ipv6,
1683 tt->netbits_ipv6) < 0)
1684 {
1685 msg(M_WARN, "Linux can't del IPv6 from iface %s", tt->actual_name);
1686 }
1687#elif defined(TARGET_FREEBSD)
1688 struct gc_arena gc = gc_new();
1689 const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
1690 struct argv argv = argv_new();
1691
1692 argv_printf(&argv, "%s %s inet6 %s/%d -alias", IFCONFIG_PATH,
1693 tt->actual_name, ifconfig_ipv6_local, tt->netbits_ipv6);
1694
1695 argv_msg(M_INFO, &argv);
1696 openvpn_execve_check(&argv, NULL, 0, "FreeBSD ip -6 addr del failed");
1697
1698 argv_free(&argv);
1699 gc_free(&gc);
1700#endif /* if defined(TARGET_LINUX) */
1701 /* Empty for _WIN32 and all other unixoid platforms */
1702}
1703
1704void
1706{
1708 {
1709 if (tt->did_ifconfig_setup)
1710 {
1711 undo_ifconfig_ipv4(tt, ctx);
1712 }
1713
1715 {
1716 undo_ifconfig_ipv6(tt, ctx);
1717 }
1718
1719 /* release resources potentially allocated during undo */
1720 net_ctx_reset(ctx);
1721 }
1722}
1723
1724static void
1726{
1727 CLEAR(*tuntap);
1728#ifdef _WIN32
1729 tuntap->hand = NULL;
1730#else
1731 tuntap->fd = -1;
1732#endif
1733#ifdef TARGET_SOLARIS
1734 tuntap->ip_fd = -1;
1735#endif
1736}
1737
1738#if defined(TARGET_OPENBSD) || defined(TARGET_DARWIN)
1739
1740/*
1741 * OpenBSD and Mac OS X when using utun
1742 * have a slightly incompatible TUN device from
1743 * the rest of the world, in that it prepends a
1744 * uint32 to the beginning of the IP header
1745 * to designate the protocol (why not just
1746 * look at the version field in the IP header to
1747 * determine v4 or v6?).
1748 *
1749 * We strip off this field on reads and
1750 * put it back on writes.
1751 *
1752 * I have not tested TAP devices on OpenBSD,
1753 * but I have conditionalized the special
1754 * TUN handling code described above to
1755 * go away for TAP devices.
1756 */
1757
1758#include <netinet/ip.h>
1759#include <sys/uio.h>
1760
1761static inline int
1762header_modify_read_write_return(int len)
1763{
1764 if (len > 0)
1765 {
1766 return len > sizeof(u_int32_t) ? len - sizeof(u_int32_t) : 0;
1767 }
1768 else
1769 {
1770 return len;
1771 }
1772}
1773
1774static int
1775write_tun_header(struct tuntap *tt, uint8_t *buf, int len)
1776{
1777 if (tt->type == DEV_TYPE_TUN)
1778 {
1779 u_int32_t type;
1780 struct iovec iv[2];
1781 struct openvpn_iphdr *iph;
1782
1783 iph = (struct openvpn_iphdr *) buf;
1784
1785 if (OPENVPN_IPH_GET_VER(iph->version_len) == 6)
1786 {
1787 type = htonl(AF_INET6);
1788 }
1789 else
1790 {
1791 type = htonl(AF_INET);
1792 }
1793
1794 iv[0].iov_base = &type;
1795 iv[0].iov_len = sizeof(type);
1796 iv[1].iov_base = buf;
1797 iv[1].iov_len = len;
1798
1799 return header_modify_read_write_return(writev(tt->fd, iv, 2));
1800 }
1801 else
1802 {
1803 return write(tt->fd, buf, len);
1804 }
1805}
1806
1807static int
1808read_tun_header(struct tuntap *tt, uint8_t *buf, int len)
1809{
1810 if (tt->type == DEV_TYPE_TUN)
1811 {
1812 u_int32_t type;
1813 struct iovec iv[2];
1814
1815 iv[0].iov_base = &type;
1816 iv[0].iov_len = sizeof(type);
1817 iv[1].iov_base = buf;
1818 iv[1].iov_len = len;
1819
1820 return header_modify_read_write_return(readv(tt->fd, iv, 2));
1821 }
1822 else
1823 {
1824 return read(tt->fd, buf, len);
1825 }
1826}
1827#endif /* if defined (TARGET_OPENBSD) || defined(TARGET_DARWIN) */
1828
1829bool
1830tun_name_is_fixed(const char *dev)
1831{
1832 return has_digit(dev);
1833}
1834
1835#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1836static bool
1837tun_dco_enabled(struct tuntap *tt)
1838{
1839 return tt->backend_driver == DRIVER_DCO;
1840}
1841#endif
1842
1843
1844#if !(defined(_WIN32) || defined(TARGET_LINUX) || defined(TARGET_SOLARIS))
1845static void
1846open_tun_generic(const char *dev, const char *dev_type, const char *dev_node,
1847 struct tuntap *tt)
1848{
1849 char tunname[256];
1850 char dynamic_name[256];
1851 bool dynamic_opened = false;
1852
1853 /*
1854 * --dev-node specified, so open an explicit device node
1855 */
1856 if (dev_node)
1857 {
1858 snprintf(tunname, sizeof(tunname), "%s", dev_node);
1859 }
1860 else
1861 {
1862 /*
1863 * dynamic open is indicated by --dev specified without
1864 * explicit unit number. Try opening /dev/[dev]n
1865 * where n = [0, 255].
1866 */
1867
1868 if (!tun_name_is_fixed(dev))
1869 {
1870 for (int i = 0; i < 256; ++i)
1871 {
1872 /* some platforms have a dedicated directory per driver */
1873 char *sep = "";
1874#if defined(TARGET_HAIKU)
1875 sep = "/";
1876#endif
1877 snprintf(tunname, sizeof(tunname),
1878 "/dev/%s%s%d", dev, sep, i);
1879 snprintf(dynamic_name, sizeof(dynamic_name),
1880 "%s%s%d", dev, sep, i);
1881 if ((tt->fd = open(tunname, O_RDWR)) > 0)
1882 {
1883 dynamic_opened = true;
1884 break;
1885 }
1886 msg(D_READ_WRITE | M_ERRNO, "Tried opening %s (failed)", tunname);
1887 }
1888 if (!dynamic_opened)
1889 {
1890 msg(M_FATAL, "Cannot allocate TUN/TAP dev dynamically");
1891 }
1892 }
1893 /*
1894 * explicit unit number specified
1895 */
1896 else
1897 {
1898 snprintf(tunname, sizeof(tunname), "/dev/%s", dev);
1899 }
1900 }
1901
1902 if (!dynamic_opened)
1903 {
1904 /* has named device existed before? if so, don't destroy at end */
1905 if (if_nametoindex( dev ) > 0)
1906 {
1907 msg(M_INFO, "TUN/TAP device %s exists previously, keep at program end", dev );
1908 tt->persistent_if = true;
1909 }
1910
1911 if ((tt->fd = open(tunname, O_RDWR)) < 0)
1912 {
1913 msg(M_ERR, "Cannot open TUN/TAP dev %s", tunname);
1914 }
1915 }
1916
1917 set_nonblock(tt->fd);
1918 set_cloexec(tt->fd); /* don't pass fd to scripts */
1919 msg(M_INFO, "TUN/TAP device %s opened", tunname);
1920
1921 /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
1922 tt->actual_name = string_alloc(dynamic_opened ? dynamic_name : dev, NULL);
1923
1924}
1925#endif /* !_WIN32 && !TARGET_LINUX && !TARGET_FREEBSD*/
1926
1927#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1928static void
1929open_tun_dco_generic(const char *dev, const char *dev_type,
1930 struct tuntap *tt, openvpn_net_ctx_t *ctx)
1931{
1932 char dynamic_name[256];
1933 bool dynamic_opened = false;
1934
1935 /*
1936 * unlike "open_tun_generic()", DCO on Linux and FreeBSD follows
1937 * the device naming model of "non-DCO linux", that is:
1938 * --dev tun -> try tun0, tun1, ... tun255, use first free
1939 * --dev <anything> -> (try to) create a tun device named "anything"
1940 * ("--dev tap" and "--dev null" are caught earlier and not handled here)
1941 */
1942
1943 if (strcmp(dev, "tun") == 0)
1944 {
1945 for (int i = 0; i < 256; ++i)
1946 {
1947 snprintf(dynamic_name, sizeof(dynamic_name),
1948 "%s%d", dev, i);
1949 int ret = open_tun_dco(tt, ctx, dynamic_name);
1950 if (ret == 0)
1951 {
1952 dynamic_opened = true;
1953 msg(M_INFO, "DCO device %s opened", dynamic_name);
1954 break;
1955 }
1956 /* "permission denied" won't succeed if we try 256 times */
1957 else if (ret == -EPERM)
1958 {
1959 break;
1960 }
1961 }
1962 if (!dynamic_opened)
1963 {
1964 msg(M_FATAL, "Cannot allocate DCO dev dynamically");
1965 }
1966 /* tt->actual_name is passed to up and down scripts and used as
1967 * the ifconfig dev name */
1968 tt->actual_name = string_alloc(dynamic_name, NULL);
1969 }
1970 /*
1971 * explicit unit number specified
1972 */
1973 else
1974 {
1975 int ret = open_tun_dco(tt, ctx, dev);
1976 if (ret == -EEXIST)
1977 {
1978 msg(M_INFO, "DCO device %s already exists, won't be destroyed at shutdown",
1979 dev);
1980 tt->persistent_if = true;
1981 }
1982 else if (ret < 0)
1983 {
1984 msg(M_ERR, "Cannot open DCO device %s: %s (%d)", dev,
1985 strerror(-ret), ret);
1986 }
1987 else
1988 {
1989 msg(M_INFO, "DCO device %s opened", dev);
1990 }
1991
1992 /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
1993 tt->actual_name = string_alloc(dev, NULL);
1994 }
1995}
1996#endif /* TARGET_LINUX || TARGET_FREEBSD*/
1997
1998#if !(defined(_WIN32) || defined(TARGET_SOLARIS))
1999static void
2000close_tun_generic(struct tuntap *tt)
2001{
2002 if (tt->fd >= 0)
2003 {
2004 close(tt->fd);
2005 }
2006
2007 free(tt->actual_name);
2008 clear_tuntap(tt);
2009}
2010#endif /* !_WIN32 */
2011
2012#if defined (TARGET_ANDROID)
2013void
2014open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
2015 openvpn_net_ctx_t *ctx)
2016{
2017#define ANDROID_TUNNAME "vpnservice-tun"
2018 struct user_pass up;
2019 struct gc_arena gc = gc_new();
2020 bool opentun;
2021
2022 int oldtunfd = tt->fd;
2023
2024 /* Prefer IPv6 DNS servers,
2025 * Android will use the DNS server in the order we specify*/
2026 for (int i = 0; i < tt->options.dns6_len; i++)
2027 {
2028 management_android_control(management, "DNS6SERVER",
2029 print_in6_addr(tt->options.dns6[i], 0, &gc));
2030 }
2031
2032 for (int i = 0; i < tt->options.dns_len; i++)
2033 {
2034 management_android_control(management, "DNSSERVER",
2035 print_in_addr_t(tt->options.dns[i], 0, &gc));
2036 }
2037
2038 if (tt->options.domain)
2039 {
2040 management_android_control(management, "DNSDOMAIN", tt->options.domain);
2041 }
2042
2043 if (tt->options.http_proxy)
2044 {
2045 struct buffer buf = alloc_buf_gc(strlen(tt->options.http_proxy) + 20, &gc);
2046 buf_printf(&buf, "%s %d", tt->options.http_proxy, tt->options.http_proxy_port);
2047 management_android_control(management, "HTTPPROXY", BSTR(&buf));
2048 }
2049
2051
2053 {
2054 /* keep the old fd */
2055 opentun = true;
2056 }
2057 else
2058 {
2060 /* Pick up the fd from management interface after calling the
2061 * OPENTUN command */
2062 tt->fd = management->connection.lastfdreceived;
2063 management->connection.lastfdreceived = -1;
2064 }
2065
2067 {
2068 close(oldtunfd);
2069 }
2070
2071 /* Set the actual name to a dummy name */
2072 tt->actual_name = string_alloc(ANDROID_TUNNAME, NULL);
2073
2074 if ((tt->fd < 0) || !opentun)
2075 {
2076 msg(M_ERR, "ERROR: Cannot open TUN");
2077 }
2078
2079 gc_free(&gc);
2080}
2081
2082void
2083close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2084{
2085 ASSERT(tt);
2086
2088 free(tt);
2089}
2090
2091int
2092write_tun(struct tuntap *tt, uint8_t *buf, int len)
2093{
2094 return write(tt->fd, buf, len);
2095}
2096
2097int
2098read_tun(struct tuntap *tt, uint8_t *buf, int len)
2099{
2100 return read(tt->fd, buf, len);
2101}
2102
2103#elif defined(TARGET_LINUX)
2104
2105#ifndef HAVE_LINUX_SOCKIOS_H
2106#error header file linux/sockios.h required
2107#endif
2108
2109#if !PEDANTIC
2110
2111void
2112open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
2113 openvpn_net_ctx_t *ctx)
2114{
2115 struct ifreq ifr;
2116
2117 if (tun_dco_enabled(tt))
2118 {
2119 open_tun_dco_generic(dev, dev_type, tt, ctx);
2120 }
2121 else
2122 {
2123 /*
2124 * Process --dev-node
2125 */
2126 const char *node = dev_node;
2127 if (!node)
2128 {
2129 node = "/dev/net/tun";
2130 }
2131
2132 /*
2133 * Open the interface
2134 */
2135 if ((tt->fd = open(node, O_RDWR)) < 0)
2136 {
2137 msg(M_ERR, "ERROR: Cannot open TUN/TAP dev %s", node);
2138 }
2139
2140 /*
2141 * Process --tun-ipv6
2142 */
2143 CLEAR(ifr);
2144 ifr.ifr_flags = IFF_NO_PI;
2145
2146#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2147 ifr.ifr_flags |= IFF_ONE_QUEUE;
2148#endif
2149
2150 /*
2151 * Figure out if tun or tap device
2152 */
2153 if (tt->type == DEV_TYPE_TUN)
2154 {
2155 ifr.ifr_flags |= IFF_TUN;
2156 }
2157 else if (tt->type == DEV_TYPE_TAP)
2158 {
2159 ifr.ifr_flags |= IFF_TAP;
2160 }
2161 else
2162 {
2163 msg(M_FATAL, "I don't recognize device %s as a tun or tap device",
2164 dev);
2165 }
2166
2167 /*
2168 * Set an explicit name, if --dev is not tun or tap
2169 */
2170 if (strcmp(dev, "tun") && strcmp(dev, "tap"))
2171 {
2172 strncpynt(ifr.ifr_name, dev, IFNAMSIZ);
2173 }
2174
2175 /*
2176 * Use special ioctl that configures tun/tap device with the parms
2177 * we set in ifr
2178 */
2179 if (ioctl(tt->fd, TUNSETIFF, (void *) &ifr) < 0)
2180 {
2181 msg(M_ERR, "ERROR: Cannot ioctl TUNSETIFF %s", dev);
2182 }
2183
2184 msg(M_INFO, "TUN/TAP device %s opened", ifr.ifr_name);
2185
2186 /*
2187 * Try making the TX send queue bigger
2188 */
2189#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2190 if (tt->options.txqueuelen)
2191 {
2192 struct ifreq netifr;
2193 int ctl_fd;
2194
2195 if ((ctl_fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
2196 {
2197 CLEAR(netifr);
2198 strncpynt(netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
2199 netifr.ifr_qlen = tt->options.txqueuelen;
2200 if (ioctl(ctl_fd, SIOCSIFTXQLEN, (void *) &netifr) >= 0)
2201 {
2202 msg(D_OSBUF, "TUN/TAP TX queue length set to %d", tt->options.txqueuelen);
2203 }
2204 else
2205 {
2206 msg(M_WARN | M_ERRNO, "Note: Cannot set tx queue length on %s", ifr.ifr_name);
2207 }
2208 close(ctl_fd);
2209 }
2210 else
2211 {
2212 msg(M_WARN | M_ERRNO, "Note: Cannot open control socket on %s", ifr.ifr_name);
2213 }
2214 }
2215#endif /* if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN) */
2216
2217 set_nonblock(tt->fd);
2218 set_cloexec(tt->fd);
2219 tt->actual_name = string_alloc(ifr.ifr_name, NULL);
2220 }
2221 return;
2222}
2223
2224#else /* if !PEDANTIC */
2225
2226void
2227open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
2228 openvpn_net_ctx_t *ctx)
2229{
2230 ASSERT(0);
2231}
2232
2233#endif /* !PEDANTIC */
2234
2235#ifdef ENABLE_FEATURE_TUN_PERSIST
2236
2237/* TUNSETGROUP appeared in 2.6.23 */
2238#ifndef TUNSETGROUP
2239#define TUNSETGROUP _IOW('T', 206, int)
2240#endif
2241
2242void
2243tuncfg(const char *dev, const char *dev_type, const char *dev_node,
2244 int persist_mode, const char *username, const char *groupname,
2245 const struct tuntap_options *options, openvpn_net_ctx_t *ctx)
2246{
2247 struct tuntap *tt;
2248
2249 ALLOC_OBJ(tt, struct tuntap);
2250 clear_tuntap(tt);
2251 tt->type = dev_type_enum(dev, dev_type);
2252 tt->options = *options;
2253
2254 open_tun(dev, dev_type, dev_node, tt, ctx);
2255 if (ioctl(tt->fd, TUNSETPERSIST, persist_mode) < 0)
2256 {
2257 msg(M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
2258 }
2259 if (username != NULL)
2260 {
2262
2263 if (!platform_user_get(username, &platform_state_user))
2264 {
2265 msg(M_ERR, "Cannot get user entry for %s", username);
2266 }
2267 else if (ioctl(tt->fd, TUNSETOWNER, platform_state_user.uid) < 0)
2268 {
2269 msg(M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", username, dev);
2270 }
2271 }
2272 if (groupname != NULL)
2273 {
2275
2276 if (!platform_group_get(groupname, &platform_state_group))
2277 {
2278 msg(M_ERR, "Cannot get group entry for %s", groupname);
2279 }
2280 else if (ioctl(tt->fd, TUNSETGROUP, platform_state_group.gid) < 0)
2281 {
2282 msg(M_ERR, "Cannot ioctl TUNSETGROUP(%s) %s", groupname, dev);
2283 }
2284 }
2285 close_tun(tt, ctx);
2286 msg(M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF"));
2287}
2288
2289#endif /* ENABLE_FEATURE_TUN_PERSIST */
2290
2291void
2292close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2293{
2294 ASSERT(tt);
2295
2296#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
2297 if (tun_dco_enabled(tt))
2298 {
2299 close_tun_dco(tt, ctx);
2300 }
2301#endif
2302 close_tun_generic(tt);
2303 free(tt);
2304}
2305
2306int
2307write_tun(struct tuntap *tt, uint8_t *buf, int len)
2308{
2309 return write(tt->fd, buf, len);
2310}
2311
2312int
2313read_tun(struct tuntap *tt, uint8_t *buf, int len)
2314{
2315 return read(tt->fd, buf, len);
2316}
2317
2318#elif defined(TARGET_SOLARIS)
2319
2320#ifndef TUNNEWPPA
2321#error I need the symbol TUNNEWPPA from net/if_tun.h
2322#endif
2323
2324void
2325open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
2326 openvpn_net_ctx_t *ctx)
2327{
2328 int if_fd = -1, ip_muxid = -1, arp_muxid = -1, arp_fd = -1, ppa = -1;
2329 struct lifreq ifr;
2330 const char *ptr;
2331 const char *ip_node = NULL, *arp_node = NULL;
2332 const char *dev_tuntap_type;
2333 int link_type;
2334 struct strioctl strioc_if, strioc_ppa;
2335
2336 /* improved generic TUN/TAP driver from
2337 * http://www.whiteboard.ne.jp/~admin2/tuntap/
2338 * has IPv6 support
2339 */
2340 CLEAR(ifr);
2341
2342 if (tt->type == DEV_TYPE_TUN)
2343 {
2344 ip_node = "/dev/udp";
2345 if (!dev_node)
2346 {
2347 dev_node = "/dev/tun";
2348 }
2349 dev_tuntap_type = "tun";
2350 link_type = I_PLINK;
2351 }
2352 else if (tt->type == DEV_TYPE_TAP)
2353 {
2354 ip_node = "/dev/udp";
2355 if (!dev_node)
2356 {
2357 dev_node = "/dev/tap";
2358 }
2359 arp_node = dev_node;
2360 dev_tuntap_type = "tap";
2361 link_type = I_PLINK; /* was: I_LINK */
2362 }
2363 else
2364 {
2365 msg(M_FATAL, "I don't recognize device %s as a tun or tap device",
2366 dev);
2367 }
2368
2369 if ((tt->ip_fd = open(ip_node, O_RDWR, 0)) < 0)
2370 {
2371 msg(M_ERR, "Can't open %s", ip_node);
2372 }
2373
2374 if ((tt->fd = open(dev_node, O_RDWR, 0)) < 0)
2375 {
2376 msg(M_ERR, "Can't open %s", dev_node);
2377 }
2378
2379 ptr = dev;
2380
2381 /* get unit number */
2382 if (*ptr)
2383 {
2384 while (*ptr && !isdigit((int) *ptr))
2385 {
2386 ptr++;
2387 }
2388 ppa = atoi(ptr);
2389 }
2390
2391 /* Assign a new PPA and get its unit number. */
2392 strioc_ppa.ic_cmd = TUNNEWPPA;
2393 strioc_ppa.ic_timout = 0;
2394 strioc_ppa.ic_len = sizeof(ppa);
2395 strioc_ppa.ic_dp = (char *)&ppa;
2396
2397 if (*ptr == '\0') /* no number given, try dynamic */
2398 {
2399 bool found_one = false;
2400 while (!found_one && ppa < 64)
2401 {
2402 int new_ppa = ioctl(tt->fd, I_STR, &strioc_ppa);
2403 if (new_ppa >= 0)
2404 {
2405 msg( M_INFO, "open_tun: got dynamic interface '%s%d'", dev_tuntap_type, new_ppa );
2406 ppa = new_ppa;
2407 found_one = true;
2408 break;
2409 }
2410 if (errno != EEXIST)
2411 {
2412 msg(M_ERR, "open_tun: unexpected error trying to find free %s interface", dev_tuntap_type );
2413 }
2414 ppa++;
2415 }
2416 if (!found_one)
2417 {
2418 msg(M_ERR, "open_tun: could not find free %s interface, give up.", dev_tuntap_type );
2419 }
2420 }
2421 else /* try this particular one */
2422 {
2423 if ((ppa = ioctl(tt->fd, I_STR, &strioc_ppa)) < 0)
2424 {
2425 msg(M_ERR, "Can't assign PPA for new interface (%s%d)", dev_tuntap_type, ppa );
2426 }
2427 }
2428
2429 if ((if_fd = open(dev_node, O_RDWR, 0)) < 0)
2430 {
2431 msg(M_ERR, "Can't open %s (2)", dev_node);
2432 }
2433
2434 if (ioctl(if_fd, I_PUSH, "ip") < 0)
2435 {
2436 msg(M_ERR, "Can't push IP module");
2437 }
2438
2439 if (tt->type == DEV_TYPE_TUN)
2440 {
2441 /* Assign ppa according to the unit number returned by tun device */
2442 if (ioctl(if_fd, IF_UNITSEL, (char *) &ppa) < 0)
2443 {
2444 msg(M_ERR, "Can't set PPA %d", ppa);
2445 }
2446 }
2447
2448 tt->actual_name = (char *) malloc(32);
2450
2451 snprintf(tt->actual_name, 32, "%s%d", dev_tuntap_type, ppa);
2452
2453 if (tt->type == DEV_TYPE_TAP)
2454 {
2455 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2456 {
2457 msg(M_ERR, "Can't get flags\n");
2458 }
2459 strncpynt(ifr.lifr_name, tt->actual_name, sizeof(ifr.lifr_name));
2460 ifr.lifr_ppa = ppa;
2461 /* Assign ppa according to the unit number returned by tun device */
2462 if (ioctl(if_fd, SIOCSLIFNAME, &ifr) < 0)
2463 {
2464 msg(M_ERR, "Can't set PPA %d", ppa);
2465 }
2466 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
2467 {
2468 msg(M_ERR, "Can't get flags\n");
2469 }
2470 /* Push arp module to if_fd */
2471 if (ioctl(if_fd, I_PUSH, "arp") < 0)
2472 {
2473 msg(M_ERR, "Can't push ARP module");
2474 }
2475
2476 /* Pop any modules on the stream */
2477 while (true)
2478 {
2479 if (ioctl(tt->ip_fd, I_POP, NULL) < 0)
2480 {
2481 break;
2482 }
2483 }
2484 /* Push arp module to ip_fd */
2485 if (ioctl(tt->ip_fd, I_PUSH, "arp") < 0)
2486 {
2487 msg(M_ERR, "Can't push ARP module\n");
2488 }
2489
2490 /* Open arp_fd */
2491 if ((arp_fd = open(arp_node, O_RDWR, 0)) < 0)
2492 {
2493 msg(M_ERR, "Can't open %s\n", arp_node);
2494 }
2495 /* Push arp module to arp_fd */
2496 if (ioctl(arp_fd, I_PUSH, "arp") < 0)
2497 {
2498 msg(M_ERR, "Can't push ARP module\n");
2499 }
2500
2501 /* Set ifname to arp */
2502 strioc_if.ic_cmd = SIOCSLIFNAME;
2503 strioc_if.ic_timout = 0;
2504 strioc_if.ic_len = sizeof(ifr);
2505 strioc_if.ic_dp = (char *)&ifr;
2506 if (ioctl(arp_fd, I_STR, &strioc_if) < 0)
2507 {
2508 msg(M_ERR, "Can't set ifname to arp\n");
2509 }
2510 }
2511
2512 if ((ip_muxid = ioctl(tt->ip_fd, link_type, if_fd)) < 0)
2513 {
2514 msg(M_ERR, "Can't link %s device to IP", dev_tuntap_type);
2515 }
2516
2517 if (tt->type == DEV_TYPE_TAP)
2518 {
2519 if ((arp_muxid = ioctl(tt->ip_fd, link_type, arp_fd)) < 0)
2520 {
2521 msg(M_ERR, "Can't link %s device to ARP", dev_tuntap_type);
2522 }
2523 close(arp_fd);
2524 }
2525
2526 CLEAR(ifr);
2527 strncpynt(ifr.lifr_name, tt->actual_name, sizeof(ifr.lifr_name));
2528 ifr.lifr_ip_muxid = ip_muxid;
2529 if (tt->type == DEV_TYPE_TAP)
2530 {
2531 ifr.lifr_arp_muxid = arp_muxid;
2532 }
2533
2534 if (ioctl(tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0)
2535 {
2536 if (tt->type == DEV_TYPE_TAP)
2537 {
2538 ioctl(tt->ip_fd, I_PUNLINK, arp_muxid);
2539 }
2540 ioctl(tt->ip_fd, I_PUNLINK, ip_muxid);
2541 msg(M_ERR, "Can't set multiplexor id");
2542 }
2543
2544 set_nonblock(tt->fd);
2545 set_cloexec(tt->fd);
2546 set_cloexec(tt->ip_fd);
2547
2548 msg(M_INFO, "TUN/TAP device %s opened", tt->actual_name);
2549}
2550
2551static void
2552solaris_close_tun(struct tuntap *tt)
2553{
2554 /* IPv6 interfaces need to be 'manually' de-configured */
2556 {
2557 struct argv argv = argv_new();
2558 argv_printf( &argv, "%s %s inet6 unplumb",
2559 IFCONFIG_PATH, tt->actual_name );
2560 argv_msg(M_INFO, &argv);
2561 openvpn_execve_check(&argv, NULL, 0, "Solaris ifconfig inet6 unplumb failed");
2562 argv_free(&argv);
2563 }
2564
2565 if (tt->ip_fd >= 0)
2566 {
2567 struct lifreq ifr;
2568 CLEAR(ifr);
2569 strncpynt(ifr.lifr_name, tt->actual_name, sizeof(ifr.lifr_name));
2570
2571 if (ioctl(tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0)
2572 {
2573 msg(M_WARN | M_ERRNO, "Can't get iface flags");
2574 }
2575
2576 if (ioctl(tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0)
2577 {
2578 msg(M_WARN | M_ERRNO, "Can't get multiplexor id");
2579 }
2580
2581 if (tt->type == DEV_TYPE_TAP)
2582 {
2583 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0)
2584 {
2585 msg(M_WARN | M_ERRNO, "Can't unlink interface(arp)");
2586 }
2587 }
2588
2589 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0)
2590 {
2591 msg(M_WARN | M_ERRNO, "Can't unlink interface(ip)");
2592 }
2593
2594 close(tt->ip_fd);
2595 tt->ip_fd = -1;
2596 }
2597
2598 if (tt->fd >= 0)
2599 {
2600 close(tt->fd);
2601 tt->fd = -1;
2602 }
2603}
2604
2605/*
2606 * Close TUN device.
2607 */
2608void
2609close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2610{
2611 ASSERT(tt);
2612
2613 solaris_close_tun(tt);
2614
2615 free(tt->actual_name);
2616
2617 clear_tuntap(tt);
2618 free(tt);
2619}
2620
2621static void
2622solaris_error_close(struct tuntap *tt, const struct env_set *es,
2623 const char *actual, bool unplumb_inet6 )
2624{
2625 struct argv argv = argv_new();
2626
2627 if (unplumb_inet6)
2628 {
2629 argv_printf( &argv, "%s %s inet6 unplumb",
2630 IFCONFIG_PATH, actual );
2631 argv_msg(M_INFO, &argv);
2632 openvpn_execve_check(&argv, es, 0, "Solaris ifconfig inet6 unplumb failed");
2633 }
2634
2636 "%s %s unplumb",
2637 IFCONFIG_PATH,
2638 actual);
2639
2640 argv_msg(M_INFO, &argv);
2641 openvpn_execve_check(&argv, es, 0, "Solaris ifconfig unplumb failed");
2642 close_tun(tt, NULL);
2643 msg(M_FATAL, "Solaris ifconfig failed");
2644 argv_free(&argv);
2645}
2646
2647int
2648write_tun(struct tuntap *tt, uint8_t *buf, int len)
2649{
2650 struct strbuf sbuf;
2651 sbuf.len = len;
2652 sbuf.buf = (char *)buf;
2653 return putmsg(tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
2654}
2655
2656int
2657read_tun(struct tuntap *tt, uint8_t *buf, int len)
2658{
2659 struct strbuf sbuf;
2660 int f = 0;
2661
2662 sbuf.maxlen = len;
2663 sbuf.buf = (char *)buf;
2664 return getmsg(tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
2665}
2666
2667#elif defined(TARGET_OPENBSD)
2668
2669void
2670open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
2671 openvpn_net_ctx_t *ctx)
2672{
2673 open_tun_generic(dev, dev_type, dev_node, tt);
2674
2675 /* Enable multicast on the interface */
2676 if (tt->fd >= 0)
2677 {
2678 struct tuninfo info;
2679
2680 if (ioctl(tt->fd, TUNGIFINFO, &info) < 0)
2681 {
2682 msg(M_WARN | M_ERRNO, "Can't get interface info");
2683 }
2684
2685#ifdef IFF_MULTICAST /* openbsd 4.x doesn't have this */
2686 info.flags |= IFF_MULTICAST;
2687#endif
2688
2689 if (ioctl(tt->fd, TUNSIFINFO, &info) < 0)
2690 {
2691 msg(M_WARN | M_ERRNO, "Can't set interface info");
2692 }
2693 }
2694}
2695
2696/* tun(4): "If the device was created by opening /dev/tunN, it will be
2697 * automatically destroyed. Devices created via ifconfig(8) are
2698 * only marked as not running and traffic will be dropped
2699 * returning EHOSTDOWN."
2700 * --> no special handling should be needed - *but* OpenBSD is misbehaving
2701 * here: if the interface was put in tap mode ("ifconfig tunN link0"), it
2702 * *will* stay around, and needs to be cleaned up manually
2703 */
2704
2705void
2706close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2707{
2708 ASSERT(tt);
2709
2710 /* only *TAP* devices need destroying, tun devices auto-self-destruct
2711 */
2712 if (tt->type == DEV_TYPE_TUN || tt->persistent_if)
2713 {
2714 close_tun_generic(tt);
2715 free(tt);
2716 return;
2717 }
2718
2719 struct argv argv = argv_new();
2720
2721 /* setup command, close tun dev (clears tt->actual_name!), run command
2722 */
2723
2724 argv_printf(&argv, "%s %s destroy",
2725 IFCONFIG_PATH, tt->actual_name);
2726
2727 close_tun_generic(tt);
2728
2729 argv_msg(M_INFO, &argv);
2730 openvpn_execve_check(&argv, NULL, 0, "OpenBSD 'destroy tun interface' failed (non-critical)");
2731
2732 free(tt);
2733 argv_free(&argv);
2734}
2735
2736int
2737write_tun(struct tuntap *tt, uint8_t *buf, int len)
2738{
2739 return write_tun_header(tt, buf, len);
2740}
2741
2742int
2743read_tun(struct tuntap *tt, uint8_t *buf, int len)
2744{
2745 return read_tun_header(tt, buf, len);
2746}
2747
2748#elif defined(TARGET_NETBSD)
2749
2750/*
2751 * NetBSD 4.0 and up support IPv6 on tun interfaces, but we need to put
2752 * the tun interface into "multi_af" mode, which will prepend the address
2753 * family to all packets (same as OpenBSD and FreeBSD).
2754 *
2755 * If this is not enabled, the kernel silently drops all IPv6 packets on
2756 * output and gets confused on input.
2757 *
2758 * Note: --dev tap3 works *if* the interface is created externally by
2759 * "ifconfig tap3 create"
2760 * (and for devices beyond tap3, "mknod /dev/tapN c ...")
2761 * but we do not have code to do that inside OpenVPN
2762 */
2763
2764void
2765open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
2766 openvpn_net_ctx_t *ctx)
2767{
2768 /* on NetBSD, tap (but not tun) devices are opened by
2769 * opening /dev/tap and then querying the system about the
2770 * actual device name (tap0, tap1, ...) assigned
2771 */
2772 if (strcmp(dev, "tap") == 0)
2773 {
2774 struct ifreq ifr;
2775 if ((tt->fd = open( "/dev/tap", O_RDWR)) < 0)
2776 {
2777 msg(M_FATAL, "Cannot allocate NetBSD TAP dev dynamically");
2778 }
2779 if (ioctl( tt->fd, TAPGIFNAME, (void *)&ifr ) < 0)
2780 {
2781 msg(M_FATAL, "Cannot query NetBSD TAP device name");
2782 }
2783 set_nonblock(tt->fd);
2784 set_cloexec(tt->fd); /* don't pass fd to scripts */
2785 msg(M_INFO, "TUN/TAP device %s opened", ifr.ifr_name);
2786
2787 tt->actual_name = string_alloc(ifr.ifr_name, NULL);
2788 }
2789 else
2790 {
2791 /* dynamic / named tun can be handled by the generic function
2792 * named tap ("tap3") is handled there as well, if pre-created
2793 */
2794 open_tun_generic(dev, dev_type, dev_node, tt);
2795 }
2796
2797 if (tt->fd >= 0)
2798 {
2799 int i = IFF_POINTOPOINT|IFF_MULTICAST;
2800 ioctl(tt->fd, TUNSIFMODE, &i); /* multicast on */
2801 i = 0;
2802 ioctl(tt->fd, TUNSLMODE, &i); /* link layer mode off */
2803
2804 if (tt->type == DEV_TYPE_TUN)
2805 {
2806 i = 1;
2807 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0) /* multi-af mode on */
2808 {
2809 msg(M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD)");
2810 }
2811 }
2812 }
2813}
2814
2815/* the current way OpenVPN handles tun devices on NetBSD leads to
2816 * lingering tunX interfaces after close -> for a full cleanup, they
2817 * need to be explicitly destroyed
2818 */
2819void
2820close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2821{
2822 ASSERT(tt);
2823
2824 /* only tun devices need destroying, tap devices auto-self-destruct
2825 */
2826 if (tt->type != DEV_TYPE_TUN || tt->persistent_if)
2827 {
2828 close_tun_generic(tt);
2829 free(tt);
2830 return;
2831 }
2832
2833 struct argv argv = argv_new();
2834
2835 /* setup command, close tun dev (clears tt->actual_name!), run command
2836 */
2837
2838 argv_printf(&argv, "%s %s destroy",
2839 IFCONFIG_PATH, tt->actual_name);
2840
2841 close_tun_generic(tt);
2842
2843 argv_msg(M_INFO, &argv);
2844 openvpn_execve_check(&argv, NULL, 0, "NetBSD 'destroy tun interface' failed (non-critical)");
2845
2846 free(tt);
2847 argv_free(&argv);
2848}
2849
2850static inline int
2851netbsd_modify_read_write_return(int len)
2852{
2853 if (len > 0)
2854 {
2855 return len > sizeof(u_int32_t) ? len - sizeof(u_int32_t) : 0;
2856 }
2857 else
2858 {
2859 return len;
2860 }
2861}
2862
2863int
2864write_tun(struct tuntap *tt, uint8_t *buf, int len)
2865{
2866 if (tt->type == DEV_TYPE_TUN)
2867 {
2868 u_int32_t type;
2869 struct iovec iv[2];
2870 struct openvpn_iphdr *iph;
2871
2872 iph = (struct openvpn_iphdr *) buf;
2873
2874 if (OPENVPN_IPH_GET_VER(iph->version_len) == 6)
2875 {
2876 type = htonl(AF_INET6);
2877 }
2878 else
2879 {
2880 type = htonl(AF_INET);
2881 }
2882
2883 iv[0].iov_base = (char *)&type;
2884 iv[0].iov_len = sizeof(type);
2885 iv[1].iov_base = buf;
2886 iv[1].iov_len = len;
2887
2888 return netbsd_modify_read_write_return(writev(tt->fd, iv, 2));
2889 }
2890 else
2891 {
2892 return write(tt->fd, buf, len);
2893 }
2894}
2895
2896int
2897read_tun(struct tuntap *tt, uint8_t *buf, int len)
2898{
2899 if (tt->type == DEV_TYPE_TUN)
2900 {
2901 u_int32_t type;
2902 struct iovec iv[2];
2903
2904 iv[0].iov_base = (char *)&type;
2905 iv[0].iov_len = sizeof(type);
2906 iv[1].iov_base = buf;
2907 iv[1].iov_len = len;
2908
2909 return netbsd_modify_read_write_return(readv(tt->fd, iv, 2));
2910 }
2911 else
2912 {
2913 return read(tt->fd, buf, len);
2914 }
2915}
2916
2917#elif defined(TARGET_FREEBSD)
2918
2919static inline int
2920freebsd_modify_read_write_return(int len)
2921{
2922 if (len > 0)
2923 {
2924 return len > sizeof(u_int32_t) ? len - sizeof(u_int32_t) : 0;
2925 }
2926 else
2927 {
2928 return len;
2929 }
2930}
2931
2932void
2933open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
2934 openvpn_net_ctx_t *ctx)
2935{
2936 if (tun_dco_enabled(tt))
2937 {
2938 open_tun_dco_generic(dev, dev_type, tt, ctx);
2939 }
2940 else
2941 {
2942 open_tun_generic(dev, dev_type, dev_node, tt);
2943
2944 if (tt->fd >= 0 && tt->type == DEV_TYPE_TUN)
2945 {
2946 /* see "Interface Flags" in ifnet(9) */
2947 int i = IFF_POINTOPOINT | IFF_MULTICAST;
2948 if (tt->topology == TOP_SUBNET)
2949 {
2950 i = IFF_BROADCAST | IFF_MULTICAST;
2951 }
2952
2953 if (ioctl(tt->fd, TUNSIFMODE, &i) < 0)
2954 {
2955 msg(M_WARN | M_ERRNO, "ioctl(TUNSIFMODE)");
2956 }
2957
2958 /* multi_af mode for v4+v6, see "tun(4)" */
2959 i = 1;
2960 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0)
2961 {
2962 msg(M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD)");
2963 }
2964 }
2965 }
2966}
2967
2968/* tun(4): "These network interfaces persist until the if_tun.ko module is
2969 * unloaded, or until removed with the ifconfig(8) command."
2970 * (verified for FreeBSD 6.3, 7.4, 8.2 and 9, same for tap(4))
2971 *
2972 * so, to avoid lingering tun/tap interfaces after OpenVPN quits,
2973 * we need to call "ifconfig ... destroy" for cleanup
2974 */
2975void
2976close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2977{
2978 ASSERT(tt);
2979
2980 if (tt->persistent_if) /* keep pre-existing if around */
2981 {
2982 close_tun_generic(tt);
2983 free(tt);
2984 return;
2985 }
2986
2987 /* close and destroy */
2988 struct argv argv = argv_new();
2989
2990 /* setup command, close tun dev (clears tt->actual_name!), run command
2991 */
2992
2993 argv_printf(&argv, "%s %s destroy",
2994 IFCONFIG_PATH, tt->actual_name);
2995
2996 close_tun_generic(tt);
2997
2998 argv_msg(M_INFO, &argv);
2999 openvpn_execve_check(&argv, NULL, 0,
3000 "FreeBSD 'destroy tun interface' failed (non-critical)");
3001
3002 free(tt);
3003 argv_free(&argv);
3004}
3005
3006int
3007write_tun(struct tuntap *tt, uint8_t *buf, int len)
3008{
3009 if (tt->type == DEV_TYPE_TUN)
3010 {
3011 u_int32_t type;
3012 struct iovec iv[2];
3013 struct ip *iph;
3014
3015 iph = (struct ip *) buf;
3016
3017 if (iph->ip_v == 6)
3018 {
3019 type = htonl(AF_INET6);
3020 }
3021 else
3022 {
3023 type = htonl(AF_INET);
3024 }
3025
3026 iv[0].iov_base = (char *)&type;
3027 iv[0].iov_len = sizeof(type);
3028 iv[1].iov_base = buf;
3029 iv[1].iov_len = len;
3030
3031 return freebsd_modify_read_write_return(writev(tt->fd, iv, 2));
3032 }
3033 else
3034 {
3035 return write(tt->fd, buf, len);
3036 }
3037}
3038
3039int
3040read_tun(struct tuntap *tt, uint8_t *buf, int len)
3041{
3042 if (tt->type == DEV_TYPE_TUN)
3043 {
3044 u_int32_t type;
3045 struct iovec iv[2];
3046
3047 iv[0].iov_base = (char *)&type;
3048 iv[0].iov_len = sizeof(type);
3049 iv[1].iov_base = buf;
3050 iv[1].iov_len = len;
3051
3052 return freebsd_modify_read_write_return(readv(tt->fd, iv, 2));
3053 }
3054 else
3055 {
3056 return read(tt->fd, buf, len);
3057 }
3058}
3059
3060#elif defined(TARGET_DRAGONFLY)
3061
3062static inline int
3063dragonfly_modify_read_write_return(int len)
3064{
3065 if (len > 0)
3066 {
3067 return len > sizeof(u_int32_t) ? len - sizeof(u_int32_t) : 0;
3068 }
3069 else
3070 {
3071 return len;
3072 }
3073}
3074
3075void
3076open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
3077 openvpn_net_ctx_t *ctx)
3078{
3079 open_tun_generic(dev, dev_type, dev_node, tt);
3080
3081 if (tt->fd >= 0)
3082 {
3083 int i = 0;
3084
3085 /* Disable extended modes */
3086 ioctl(tt->fd, TUNSLMODE, &i);
3087 i = 1;
3088 ioctl(tt->fd, TUNSIFHEAD, &i);
3089 }
3090}
3091
3092void
3093close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
3094{
3095 ASSERT(tt);
3096
3097 close_tun_generic(tt);
3098 free(tt);
3099}
3100
3101int
3102write_tun(struct tuntap *tt, uint8_t *buf, int len)
3103{
3104 if (tt->type == DEV_TYPE_TUN)
3105 {
3106 u_int32_t type;
3107 struct iovec iv[2];
3108 struct ip *iph;
3109
3110 iph = (struct ip *) buf;
3111
3112 if (iph->ip_v == 6)
3113 {
3114 type = htonl(AF_INET6);
3115 }
3116 else
3117 {
3118 type = htonl(AF_INET);
3119 }
3120
3121 iv[0].iov_base = (char *)&type;
3122 iv[0].iov_len = sizeof(type);
3123 iv[1].iov_base = buf;
3124 iv[1].iov_len = len;
3125
3126 return dragonfly_modify_read_write_return(writev(tt->fd, iv, 2));
3127 }
3128 else
3129 {
3130 return write(tt->fd, buf, len);
3131 }
3132}
3133
3134int
3135read_tun(struct tuntap *tt, uint8_t *buf, int len)
3136{
3137 if (tt->type == DEV_TYPE_TUN)
3138 {
3139 u_int32_t type;
3140 struct iovec iv[2];
3141
3142 iv[0].iov_base = (char *)&type;
3143 iv[0].iov_len = sizeof(type);
3144 iv[1].iov_base = buf;
3145 iv[1].iov_len = len;
3146
3147 return dragonfly_modify_read_write_return(readv(tt->fd, iv, 2));
3148 }
3149 else
3150 {
3151 return read(tt->fd, buf, len);
3152 }
3153}
3154
3155#elif defined(TARGET_DARWIN)
3156
3157/* Darwin (MacOS X) is mostly "just use the generic stuff", but there
3158 * is always one caveat...:
3159 *
3160 * If IPv6 is configured, and the tun device is closed, the IPv6 address
3161 * configured to the tun interface changes to a lingering /128 route
3162 * pointing to lo0. Need to unconfigure... (observed on 10.5)
3163 */
3164
3165/*
3166 * utun is the native Darwin tun driver present since at least 10.7
3167 * Thanks goes to Jonathan Levin for providing an example how to utun
3168 * (http://newosxbook.com/src.jl?tree=listings&file=17-15-utun.c)
3169 */
3170
3171/* Helper functions that tries to open utun device
3172 * return -2 on early initialization failures (utun not supported
3173 * at all) and -1 on initlization failure of utun
3174 * device (utun works but utunX is already used)
3175 */
3176static int
3177utun_open_helper(struct ctl_info ctlInfo, int utunnum)
3178{
3179 struct sockaddr_ctl sc;
3180 int fd;
3181
3182 fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
3183
3184 if (fd < 0)
3185 {
3186 msg(M_INFO | M_ERRNO, "Opening utun%d failed (socket(SYSPROTO_CONTROL))",
3187 utunnum);
3188 return -2;
3189 }
3190
3191 if (ioctl(fd, CTLIOCGINFO, &ctlInfo) == -1)
3192 {
3193 close(fd);
3194 msg(M_INFO | M_ERRNO, "Opening utun%d failed (ioctl(CTLIOCGINFO))",
3195 utunnum);
3196 return -2;
3197 }
3198
3199
3200 sc.sc_id = ctlInfo.ctl_id;
3201 sc.sc_len = sizeof(sc);
3202 sc.sc_family = AF_SYSTEM;
3203 sc.ss_sysaddr = AF_SYS_CONTROL;
3204
3205 sc.sc_unit = utunnum+1;
3206
3207
3208 /* If the connect is successful, a utun%d device will be created, where "%d"
3209 * is (sc.sc_unit - 1) */
3210
3211 if (connect(fd, (struct sockaddr *)&sc, sizeof(sc)) < 0)
3212 {
3213 msg(M_INFO | M_ERRNO, "Opening utun%d failed (connect(AF_SYS_CONTROL))",
3214 utunnum);
3215 close(fd);
3216 return -1;
3217 }
3218
3219 set_nonblock(fd);
3220 set_cloexec(fd); /* don't pass fd to scripts */
3221
3222 return fd;
3223}
3224
3225void
3226open_darwin_utun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
3227{
3228 struct ctl_info ctlInfo;
3229 int fd;
3230 char utunname[20];
3231 int utunnum = -1;
3232 socklen_t utunname_len = sizeof(utunname);
3233
3234 /* dev_node is simply utun, do the normal dynamic utun
3235 * otherwise try to parse the utun number */
3236 if (dev_node && (strcmp("utun", dev_node) != 0 ))
3237 {
3238 if (sscanf(dev_node, "utun%d", &utunnum) != 1)
3239 {
3240 msg(M_FATAL, "Cannot parse 'dev-node %s' please use 'dev-node utunX'"
3241 "to use a utun device number X", dev_node);
3242 }
3243 }
3244
3245
3246
3247 CLEAR(ctlInfo);
3248 if (strlcpy(ctlInfo.ctl_name, UTUN_CONTROL_NAME, sizeof(ctlInfo.ctl_name)) >=
3249 sizeof(ctlInfo.ctl_name))
3250 {
3251 msg(M_ERR, "Opening utun: UTUN_CONTROL_NAME too long");
3252 }
3253
3254 /* try to open first available utun device if no specific utun is requested */
3255 if (utunnum == -1)
3256 {
3257 for (utunnum = 0; utunnum < 255; utunnum++)
3258 {
3259 char ifname[20];
3260 /* if the interface exists silently skip it */
3261 ASSERT(snprintf(ifname, sizeof(ifname), "utun%d", utunnum) > 0);
3262 if (if_nametoindex(ifname))
3263 {
3264 continue;
3265 }
3266 fd = utun_open_helper(ctlInfo, utunnum);
3267 /* Break if the fd is valid,
3268 * or if early initialization failed (-2) */
3269 if (fd !=-1)
3270 {
3271 break;
3272 }
3273 }
3274 }
3275 else
3276 {
3277 fd = utun_open_helper(ctlInfo, utunnum);
3278 }
3279
3280 /* opening an utun device failed */
3281 tt->fd = fd;
3282
3283 if (fd < 0)
3284 {
3285 return;
3286 }
3287
3288 /* Retrieve the assigned interface name. */
3289 if (getsockopt(fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, utunname, &utunname_len))
3290 {
3291 msg(M_ERR | M_ERRNO, "Error retrieving utun interface name");
3292 }
3293
3294 tt->actual_name = string_alloc(utunname, NULL);
3295
3296 msg(M_INFO, "Opened utun device %s", utunname);
3298}
3299
3300void
3301open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
3302 openvpn_net_ctx_t *ctx)
3303{
3304 /* If dev_node does not start start with utun assume regular tun/tap */
3305 if ((!dev_node && tt->type==DEV_TYPE_TUN)
3306 || (dev_node && !strncmp(dev_node, "utun", 4)))
3307 {
3308
3309 /* Check if user has specific dev_type tap and forced utun with
3310 * dev-node utun */
3311 if (tt->type!=DEV_TYPE_TUN)
3312 {
3313 msg(M_FATAL, "Cannot use utun devices with --dev-type %s",
3314 dev_type_string(dev, dev_type));
3315 }
3316
3317 /* Try utun first and fall back to normal tun if utun fails
3318 * and dev_node is not specified */
3319 open_darwin_utun(dev, dev_type, dev_node, tt);
3320
3321 if (tt->backend_driver != DRIVER_UTUN)
3322 {
3323 if (!dev_node)
3324 {
3325 /* No explicit utun and utun failed, try the generic way) */
3326 msg(M_INFO, "Failed to open utun device. Falling back to /dev/tun device");
3327 open_tun_generic(dev, dev_type, NULL, tt);
3328 }
3329 else
3330 {
3331 /* Specific utun device or generic utun request with no tun
3332 * fall back failed, consider this a fatal failure */
3333 msg(M_FATAL, "Cannot open utun device");
3334 }
3335 }
3336 }
3337 else
3338 {
3339
3340 /* Use plain dev-node tun to select /dev/tun style
3341 * Unset dev_node variable prior to passing to open_tun_generic to
3342 * let open_tun_generic pick the first available tun device */
3343
3344 if (dev_node && strcmp(dev_node, "tun")==0)
3345 {
3346 dev_node = NULL;
3347 }
3348
3349 open_tun_generic(dev, dev_type, dev_node, tt);
3350 }
3351}
3352
3353void
3354close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
3355{
3356 ASSERT(tt);
3357
3358 struct gc_arena gc = gc_new();
3359 struct argv argv = argv_new();
3360
3362 {
3363 const char *ifconfig_ipv6_local =
3364 print_in6_addr(tt->local_ipv6, 0, &gc);
3365
3366 argv_printf(&argv, "%s delete -inet6 %s",
3367 ROUTE_PATH, ifconfig_ipv6_local );
3368 argv_msg(M_INFO, &argv);
3369 openvpn_execve_check(&argv, NULL, 0, "MacOS X 'remove inet6 route' failed (non-critical)");
3370 }
3371
3372 close_tun_generic(tt);
3373 free(tt);
3374 argv_free(&argv);
3375 gc_free(&gc);
3376}
3377
3378int
3379write_tun(struct tuntap *tt, uint8_t *buf, int len)
3380{
3381 if (tt->backend_driver == DRIVER_UTUN)
3382 {
3383 return write_tun_header(tt, buf, len);
3384 }
3385 else
3386 {
3387 return write(tt->fd, buf, len);
3388 }
3389}
3390
3391int
3392read_tun(struct tuntap *tt, uint8_t *buf, int len)
3393{
3394 if (tt->backend_driver == DRIVER_UTUN)
3395 {
3396 return read_tun_header(tt, buf, len);
3397 }
3398 else
3399 {
3400 return read(tt->fd, buf, len);
3401 }
3402}
3403
3404#elif defined(TARGET_AIX)
3405
3406void
3407open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
3408 openvpn_net_ctx_t *ctx)
3409{
3410 char tunname[256];
3411 char dynamic_name[20];
3412 const char *p;
3413
3414 if (tt->type == DEV_TYPE_TUN)
3415 {
3416 msg(M_FATAL, "no support for 'tun' devices on AIX" );
3417 }
3418
3419 if (strncmp( dev, "tap", 3 ) != 0 || dev_node)
3420 {
3421 msg(M_FATAL, "'--dev %s' and/or '--dev-node' not supported on AIX, use '--dev tap0', 'tap1', etc.", dev );
3422 }
3423
3424 if (strcmp( dev, "tap" ) == 0) /* find first free tap dev */
3425 { /* (= no /dev/tapN node) */
3426 int i;
3427 for (i = 0; i<99; i++)
3428 {
3429 snprintf(tunname, sizeof(tunname), "/dev/tap%d", i);
3430 if (access( tunname, F_OK ) < 0 && errno == ENOENT)
3431 {
3432 break;
3433 }
3434 }
3435 if (i >= 99)
3436 {
3437 msg( M_FATAL, "cannot find unused tap device" );
3438 }
3439
3440 snprintf( dynamic_name, sizeof(dynamic_name), "tap%d", i );
3441 dev = dynamic_name;
3442 }
3443 else /* name given, sanity check */
3444 {
3445 /* ensure that dev name is "tap+<digits>" *only* */
3446 p = &dev[3];
3447 while (isdigit(*p) )
3448 {
3449 p++;
3450 }
3451 if (*p != '\0')
3452 {
3453 msg( M_FATAL, "TAP device name must be '--dev tapNNNN'" );
3454 }
3455
3456 snprintf(tunname, sizeof(tunname), "/dev/%s", dev);
3457 }
3458
3459 /* pre-existing device?
3460 */
3461 if (access( tunname, F_OK ) < 0 && errno == ENOENT)
3462 {
3463
3464 /* tunnel device must be created with 'ifconfig tapN create'
3465 */
3466 struct argv argv = argv_new();
3467 struct env_set *es = env_set_create(NULL);
3468 argv_printf(&argv, "%s %s create", IFCONFIG_PATH, dev);
3469 argv_msg(M_INFO, &argv);
3470 env_set_add( es, "ODMDIR=/etc/objrepos" );
3471 openvpn_execve_check(&argv, es, S_FATAL, "AIX 'create tun interface' failed");
3473 argv_free(&argv);
3474 }
3475 else
3476 {
3477 /* we didn't make it, we're not going to break it */
3478 tt->persistent_if = TRUE;
3479 }
3480
3481 if ((tt->fd = open(tunname, O_RDWR)) < 0)
3482 {
3483 msg(M_ERR, "Cannot open TAP device '%s'", tunname);
3484 }
3485
3486 set_nonblock(tt->fd);
3487 set_cloexec(tt->fd); /* don't pass fd to scripts */
3488 msg(M_INFO, "TUN/TAP device %s opened", tunname);
3489
3490 /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
3491 tt->actual_name = string_alloc(dev, NULL);
3492}
3493
3494/* tap devices need to be manually destroyed on AIX
3495 */
3496void
3497close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
3498{
3499 ASSERT(tt);
3500
3501 struct argv argv = argv_new();
3502 struct env_set *es = env_set_create(NULL);
3503
3504 /* persistent devices need IP address unconfig, others need destroyal
3505 */
3506 if (tt->persistent_if)
3507 {
3508 argv_printf(&argv, "%s %s 0.0.0.0 down",
3509 IFCONFIG_PATH, tt->actual_name);
3510 }
3511 else
3512 {
3513 argv_printf(&argv, "%s %s destroy",
3514 IFCONFIG_PATH, tt->actual_name);
3515 }
3516
3517 close_tun_generic(tt);
3518 argv_msg(M_INFO, &argv);
3519 env_set_add( es, "ODMDIR=/etc/objrepos" );
3520 openvpn_execve_check(&argv, es, 0, "AIX 'destroy tap interface' failed (non-critical)");
3521
3522 free(tt);
3524 argv_free(&argv);
3525}
3526
3527int
3528write_tun(struct tuntap *tt, uint8_t *buf, int len)
3529{
3530 return write(tt->fd, buf, len);
3531}
3532
3533int
3534read_tun(struct tuntap *tt, uint8_t *buf, int len)
3535{
3536 return read(tt->fd, buf, len);
3537}
3538
3539#elif defined(_WIN32)
3540
3541int
3542tun_read_queue(struct tuntap *tt, int maxsize)
3543{
3544 if (tt->reads.iostate == IOSTATE_INITIAL)
3545 {
3546 DWORD len;
3547 BOOL status;
3548 int err;
3549
3550 /* reset buf to its initial state */
3551 tt->reads.buf = tt->reads.buf_init;
3552
3553 len = maxsize ? maxsize : BLEN(&tt->reads.buf);
3554 ASSERT(len <= BLEN(&tt->reads.buf));
3555
3556 /* the overlapped read will signal this event on I/O completion */
3557 ASSERT(ResetEvent(tt->reads.overlapped.hEvent));
3558
3559 status = ReadFile(
3560 tt->hand,
3561 BPTR(&tt->reads.buf),
3562 len,
3563 &tt->reads.size,
3564 &tt->reads.overlapped
3565 );
3566
3567 if (status) /* operation completed immediately? */
3568 {
3569 /* since we got an immediate return, we must signal the event object ourselves */
3570 ASSERT(SetEvent(tt->reads.overlapped.hEvent));
3571
3573 tt->reads.status = 0;
3574
3575 dmsg(D_WIN32_IO, "WIN32 I/O: TAP Read immediate return [%d,%d]",
3576 (int) len,
3577 (int) tt->reads.size);
3578 }
3579 else
3580 {
3581 err = GetLastError();
3582 if (err == ERROR_IO_PENDING) /* operation queued? */
3583 {
3585 tt->reads.status = err;
3586 dmsg(D_WIN32_IO, "WIN32 I/O: TAP Read queued [%d]",
3587 (int) len);
3588 }
3589 else /* error occurred */
3590 {
3591 struct gc_arena gc = gc_new();
3592 ASSERT(SetEvent(tt->reads.overlapped.hEvent));
3594 tt->reads.status = err;
3595 dmsg(D_WIN32_IO, "WIN32 I/O: TAP Read error [%d] : %s",
3596 (int) len,
3598 gc_free(&gc);
3599 }
3600 }
3601 }
3602 return tt->reads.iostate;
3603}
3604
3605int
3606tun_write_queue(struct tuntap *tt, struct buffer *buf)
3607{
3608 if (tt->writes.iostate == IOSTATE_INITIAL)
3609 {
3610 BOOL status;
3611 int err;
3612
3613 /* make a private copy of buf */
3614 tt->writes.buf = tt->writes.buf_init;
3615 tt->writes.buf.len = 0;
3616 ASSERT(buf_copy(&tt->writes.buf, buf));
3617
3618 /* the overlapped write will signal this event on I/O completion */
3619 ASSERT(ResetEvent(tt->writes.overlapped.hEvent));
3620
3621 status = WriteFile(
3622 tt->hand,
3623 BPTR(&tt->writes.buf),
3624 BLEN(&tt->writes.buf),
3625 &tt->writes.size,
3626 &tt->writes.overlapped
3627 );
3628
3629 if (status) /* operation completed immediately? */
3630 {
3632
3633 /* since we got an immediate return, we must signal the event object ourselves */
3634 ASSERT(SetEvent(tt->writes.overlapped.hEvent));
3635
3636 tt->writes.status = 0;
3637
3638 dmsg(D_WIN32_IO, "WIN32 I/O: TAP Write immediate return [%d,%d]",
3639 BLEN(&tt->writes.buf),
3640 (int) tt->writes.size);
3641 }
3642 else
3643 {
3644 err = GetLastError();
3645 if (err == ERROR_IO_PENDING) /* operation queued? */
3646 {
3648 tt->writes.status = err;
3649 dmsg(D_WIN32_IO, "WIN32 I/O: TAP Write queued [%d]",
3650 BLEN(&tt->writes.buf));
3651 }
3652 else /* error occurred */
3653 {
3654 struct gc_arena gc = gc_new();
3655 ASSERT(SetEvent(tt->writes.overlapped.hEvent));
3657 tt->writes.status = err;
3658 dmsg(D_WIN32_IO, "WIN32 I/O: TAP Write error [%d] : %s",
3659 BLEN(&tt->writes.buf),
3660 strerror_win32(err, &gc));
3661 gc_free(&gc);
3662 }
3663 }
3664 }
3665 return tt->writes.iostate;
3666}
3667
3668int
3669tun_write_win32(struct tuntap *tt, struct buffer *buf)
3670{
3671 int err = 0;
3672 int status = 0;
3673 if (overlapped_io_active(&tt->writes))
3674 {
3675 sockethandle_t sh = { .is_handle = true, .h = tt->hand };
3676 status = sockethandle_finalize(sh, &tt->writes, NULL, NULL);
3677 if (status < 0)
3678 {
3679 err = GetLastError();
3680 }
3681 }
3682 tun_write_queue(tt, buf);
3683 if (status < 0)
3684 {
3685 SetLastError(err);
3686 return status;
3687 }
3688 else
3689 {
3690 return BLEN(buf);
3691 }
3692}
3693
3694static const struct device_instance_id_interface *
3696{
3697 HDEVINFO dev_info_set;
3698 DWORD err;
3699 struct device_instance_id_interface *first = NULL;
3700 struct device_instance_id_interface *last = NULL;
3701
3702 dev_info_set = SetupDiGetClassDevsEx(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
3703 if (dev_info_set == INVALID_HANDLE_VALUE)
3704 {
3705 err = GetLastError();
3706 msg(M_FATAL, "Error [%u] opening device information set key: %s", (unsigned int)err, strerror_win32(err, gc));
3707 }
3708
3709 msg(D_TAP_WIN_DEBUG, "Enumerate device interface lists:");
3710 for (DWORD i = 0;; ++i)
3711 {
3712 SP_DEVINFO_DATA device_info_data;
3713 BOOL res;
3714 HKEY dev_key;
3715 char net_cfg_instance_id_string[] = "NetCfgInstanceId";
3716 BYTE net_cfg_instance_id[256];
3717 char device_instance_id[256];
3718 DWORD len;
3719 DWORD data_type;
3720 LONG status;
3721 ULONG dev_interface_list_size;
3722 CONFIGRET cr;
3723
3724 ZeroMemory(&device_info_data, sizeof(SP_DEVINFO_DATA));
3725 device_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
3726 res = SetupDiEnumDeviceInfo(dev_info_set, i, &device_info_data);
3727 if (!res)
3728 {
3729 if (GetLastError() == ERROR_NO_MORE_ITEMS)
3730 {
3731 break;
3732 }
3733 else
3734 {
3735 continue;
3736 }
3737 }
3738
3739 dev_key = SetupDiOpenDevRegKey(dev_info_set, &device_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE);
3740 if (dev_key == INVALID_HANDLE_VALUE)
3741 {
3742 continue;
3743 }
3744
3745 len = sizeof(net_cfg_instance_id);
3746 data_type = REG_SZ;
3747 status = RegQueryValueEx(dev_key,
3748 net_cfg_instance_id_string,
3749 NULL,
3750 &data_type,
3752 &len);
3753 if (status != ERROR_SUCCESS)
3754 {
3755 goto next;
3756 }
3757
3758 len = sizeof(device_instance_id);
3759 res = SetupDiGetDeviceInstanceId(dev_info_set, &device_info_data, device_instance_id, len, &len);
3760 if (!res)
3761 {
3762 goto next;
3763 }
3764
3765 cr = CM_Get_Device_Interface_List_Size(&dev_interface_list_size,
3766 (LPGUID)&GUID_DEVINTERFACE_NET,
3767 device_instance_id,
3768 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3769
3770 if (cr != CR_SUCCESS)
3771 {
3772 goto next;
3773 }
3774
3775 char *dev_interface_list = gc_malloc(dev_interface_list_size, false, gc);
3776 cr = CM_Get_Device_Interface_List((LPGUID)&GUID_DEVINTERFACE_NET, device_instance_id,
3777 dev_interface_list,
3778 dev_interface_list_size,
3779 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3780 if (cr != CR_SUCCESS)
3781 {
3782 goto next;
3783 }
3784
3785 char *dev_if = dev_interface_list;
3786
3787 /* device interface list ends with empty string */
3788 while (strlen(dev_if) > 0)
3789 {
3790 struct device_instance_id_interface *dev_iif;
3792 dev_iif->net_cfg_instance_id = (unsigned char *)string_alloc((char *)net_cfg_instance_id, gc);
3793 dev_iif->device_interface = string_alloc(dev_if, gc);
3794
3795 msg(D_TAP_WIN_DEBUG, "NetCfgInstanceId: %s, Device Interface: %s",
3796 dev_iif->net_cfg_instance_id,
3797 dev_iif->device_interface);
3798
3799 /* link into return list */
3800 if (!first)
3801 {
3802 first = dev_iif;
3803 }
3804 if (last)
3805 {
3806 last->next = dev_iif;
3807 }
3808 last = dev_iif;
3809
3810 dev_if += strlen(dev_if) + 1;
3811 }
3812
3813next:
3814 RegCloseKey(dev_key);
3815 }
3816
3817 SetupDiDestroyDeviceInfoList(dev_info_set);
3818
3819 return first;
3820}
3821
3822static const struct tap_reg *
3824{
3825 HKEY adapter_key;
3826 LONG status;
3827 DWORD len;
3828 struct tap_reg *first = NULL;
3829 struct tap_reg *last = NULL;
3830 int i = 0;
3831
3832 status = RegOpenKeyEx(
3833 HKEY_LOCAL_MACHINE,
3834 ADAPTER_KEY,
3835 0,
3836 KEY_READ,
3837 &adapter_key);
3838
3839 if (status != ERROR_SUCCESS)
3840 {
3841 msg(M_FATAL, "Error opening registry key: %s", ADAPTER_KEY);
3842 }
3843
3844 msg(D_TAP_WIN_DEBUG, "Enumerate drivers in registy: ");
3845 while (true)
3846 {
3847 char enum_name[256];
3848 char unit_string[256];
3849 HKEY unit_key;
3850 char component_id_string[] = "ComponentId";
3851 char component_id[256];
3852 char net_cfg_instance_id_string[] = "NetCfgInstanceId";
3853 BYTE net_cfg_instance_id[256];
3854 DWORD data_type;
3855
3856 len = sizeof(enum_name);
3857 status = RegEnumKeyEx(
3858 adapter_key,
3859 i,
3860 enum_name,
3861 &len,
3862 NULL,
3863 NULL,
3864 NULL,
3865 NULL);
3866 if (status == ERROR_NO_MORE_ITEMS)
3867 {
3868 break;
3869 }
3870 else if (status != ERROR_SUCCESS)
3871 {
3872 msg(M_FATAL, "Error enumerating registry subkeys of key: %s",
3873 ADAPTER_KEY);
3874 }
3875
3876 snprintf(unit_string, sizeof(unit_string), "%s\\%s",
3877 ADAPTER_KEY, enum_name);
3878
3879 status = RegOpenKeyEx(
3880 HKEY_LOCAL_MACHINE,
3881 unit_string,
3882 0,
3883 KEY_READ,
3884 &unit_key);
3885
3886 if (status != ERROR_SUCCESS)
3887 {
3888 dmsg(D_REGISTRY, "Error opening registry key: %s", unit_string);
3889 }
3890 else
3891 {
3892 len = sizeof(component_id);
3893 status = RegQueryValueEx(
3894 unit_key,
3895 component_id_string,
3896 NULL,
3897 &data_type,
3898 (LPBYTE)component_id,
3899 &len);
3900
3901 if (status != ERROR_SUCCESS || data_type != REG_SZ)
3902 {
3903 dmsg(D_REGISTRY, "Error opening registry key: %s\\%s",
3904 unit_string, component_id_string);
3905 }
3906 else
3907 {
3908 len = sizeof(net_cfg_instance_id);
3909 status = RegQueryValueEx(
3910 unit_key,
3911 net_cfg_instance_id_string,
3912 NULL,
3913 &data_type,
3914 net_cfg_instance_id,
3915 &len);
3916
3917 if (status == ERROR_SUCCESS && data_type == REG_SZ)
3918 {
3919 /* Is this adapter supported? */
3921 if (strcasecmp(component_id, TAP_WIN_COMPONENT_ID) == 0
3922 || strcasecmp(component_id, "root\\" TAP_WIN_COMPONENT_ID) == 0)
3923 {
3925 }
3926 else if (strcasecmp(component_id, WINTUN_COMPONENT_ID) == 0)
3927 {
3929 }
3930 else if (strcasecmp(component_id, "ovpn-dco") == 0)
3931 {
3933 }
3934
3936 {
3937 struct tap_reg *reg;
3938 ALLOC_OBJ_CLEAR_GC(reg, struct tap_reg, gc);
3939 reg->guid = string_alloc((char *)net_cfg_instance_id, gc);
3941
3942 /* link into return list */
3943 if (!first)
3944 {
3945 first = reg;
3946 }
3947 if (last)
3948 {
3949 last->next = reg;
3950 }
3951 last = reg;
3952
3953 msg(D_TAP_WIN_DEBUG, "NetCfgInstanceId: %s, Driver: %s",
3955 }
3956 }
3957 }
3958 RegCloseKey(unit_key);
3959 }
3960 ++i;
3961 }
3962
3963 RegCloseKey(adapter_key);
3964 return first;
3965}
3966
3967static const struct panel_reg *
3969{
3970 LONG status;
3971 HKEY network_connections_key;
3972 DWORD len;
3973 struct panel_reg *first = NULL;
3974 struct panel_reg *last = NULL;
3975 int i = 0;
3976
3977 status = RegOpenKeyEx(
3978 HKEY_LOCAL_MACHINE,
3979 NETWORK_CONNECTIONS_KEY,
3980 0,
3981 KEY_READ,
3982 &network_connections_key);
3983
3984 if (status != ERROR_SUCCESS)
3985 {
3986 msg(M_FATAL, "Error opening registry key: %s", NETWORK_CONNECTIONS_KEY);
3987 }
3988
3989 while (true)
3990 {
3991 char enum_name[256];
3992 char connection_string[256];
3993 HKEY connection_key;
3994 WCHAR name_data[256];
3995 DWORD name_type;
3996 const WCHAR name_string[] = L"Name";
3997
3998 len = sizeof(enum_name);
3999 status = RegEnumKeyEx(
4000 network_connections_key,
4001 i,
4002 enum_name,
4003 &len,
4004 NULL,
4005 NULL,
4006 NULL,
4007 NULL);
4008 if (status == ERROR_NO_MORE_ITEMS)
4009 {
4010 break;
4011 }
4012 else if (status != ERROR_SUCCESS)
4013 {
4014 msg(M_FATAL, "Error enumerating registry subkeys of key: %s",
4015 NETWORK_CONNECTIONS_KEY);
4016 }
4017
4018 snprintf(connection_string, sizeof(connection_string),
4019 "%s\\%s\\Connection",
4020 NETWORK_CONNECTIONS_KEY, enum_name);
4021
4022 status = RegOpenKeyEx(
4023 HKEY_LOCAL_MACHINE,
4024 connection_string,
4025 0,
4026 KEY_READ,
4027 &connection_key);
4028
4029 if (status != ERROR_SUCCESS)
4030 {
4031 dmsg(D_REGISTRY, "Error opening registry key: %s", connection_string);
4032 }
4033 else
4034 {
4035 len = sizeof(name_data);
4036 status = RegQueryValueExW(
4037 connection_key,
4038 name_string,
4039 NULL,
4040 &name_type,
4041 (LPBYTE) name_data,
4042 &len);
4043
4044 if (status != ERROR_SUCCESS || name_type != REG_SZ)
4045 {
4046 dmsg(D_REGISTRY, "Error opening registry key: %s\\%s\\%ls",
4047 NETWORK_CONNECTIONS_KEY, connection_string, name_string);
4048 }
4049 else
4050 {
4051 int n;
4052 LPSTR name;
4053 struct panel_reg *reg;
4054
4055 ALLOC_OBJ_CLEAR_GC(reg, struct panel_reg, gc);
4056 n = WideCharToMultiByte(CP_UTF8, 0, name_data, -1, NULL, 0, NULL, NULL);
4057 name = gc_malloc(n, false, gc);
4058 WideCharToMultiByte(CP_UTF8, 0, name_data, -1, name, n, NULL, NULL);
4059 reg->name = name;
4060 reg->guid = string_alloc(enum_name, gc);
4061
4062 /* link into return list */
4063 if (!first)
4064 {
4065 first = reg;
4066 }
4067 if (last)
4068 {
4069 last->next = reg;
4070 }
4071 last = reg;
4072 }
4073 RegCloseKey(connection_key);
4074 }
4075 ++i;
4076 }
4077
4078 RegCloseKey(network_connections_key);
4079
4080 return first;
4081}
4082
4083/*
4084 * Check that two addresses are part of the same 255.255.255.252 subnet.
4085 */
4086void
4087verify_255_255_255_252(in_addr_t local, in_addr_t remote)
4088{
4089 struct gc_arena gc = gc_new();
4090 const unsigned int mask = 3;
4091 const char *err = NULL;
4092
4093 if (local == remote)
4094 {
4095 err = "must be different";
4096 goto error;
4097 }
4098 if ((local & (~mask)) != (remote & (~mask)))
4099 {
4100 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";
4101 goto error;
4102 }
4103 if ((local & mask) == 0
4104 || (local & mask) == 3
4105 || (remote & mask) == 0
4106 || (remote & mask) == 3)
4107 {
4108 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";
4109 goto error;
4110 }
4111
4112 gc_free(&gc);
4113 return;
4114
4115error:
4116 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.",
4117 print_in_addr_t(local, 0, &gc),
4118 print_in_addr_t(remote, 0, &gc),
4119 err);
4120 gc_free(&gc);
4121}
4122
4123void
4125{
4126 int i;
4127 int col = 0;
4128
4129 printf("On Windows, point-to-point IP support (i.e. --dev tun)\n");
4130 printf("is emulated by the TAP-Windows driver. The major limitation\n");
4131 printf("imposed by this approach is that the --ifconfig local and\n");
4132 printf("remote endpoints must be part of the same 255.255.255.252\n");
4133 printf("subnet. The following list shows examples of endpoint\n");
4134 printf("pairs which satisfy this requirement. Only the final\n");
4135 printf("component of the IP address pairs is at issue.\n\n");
4136 printf("As an example, the following option would be correct:\n");
4137 printf(" --ifconfig 10.7.0.5 10.7.0.6 (on host A)\n");
4138 printf(" --ifconfig 10.7.0.6 10.7.0.5 (on host B)\n");
4139 printf("because [5,6] is part of the below list.\n\n");
4140
4141 for (i = 0; i < 256; i += 4)
4142 {
4143 printf("[%3d,%3d] ", i+1, i+2);
4144 if (++col > 4)
4145 {
4146 col = 0;
4147 printf("\n");
4148 }
4149 }
4150 if (col)
4151 {
4152 printf("\n");
4153 }
4154}
4155
4156void
4157show_tap_win_adapters(int msglev, int warnlev)
4158{
4159 struct gc_arena gc = gc_new();
4160
4161 bool warn_panel_null = false;
4162 bool warn_panel_dup = false;
4163 bool warn_tap_dup = false;
4164
4165 int links;
4166
4167 const struct tap_reg *tr;
4168 const struct tap_reg *tr1;
4169 const struct panel_reg *pr;
4170
4171 const struct tap_reg *tap_reg = get_tap_reg(&gc);
4172 const struct panel_reg *panel_reg = get_panel_reg(&gc);
4173
4174 msg(msglev, "Available adapters [name, GUID, driver]:");
4175
4176 /* loop through each TAP-Windows adapter registry entry */
4177 for (tr = tap_reg; tr != NULL; tr = tr->next)
4178 {
4179 links = 0;
4180
4181 /* loop through each network connections entry in the control panel */
4182 for (pr = panel_reg; pr != NULL; pr = pr->next)
4183 {
4184 if (!strcmp(tr->guid, pr->guid))
4185 {
4186 msg(msglev, "'%s' %s %s", pr->name, tr->guid, print_tun_backend_driver(tr->windows_driver));
4187 ++links;
4188 }
4189 }
4190
4191 if (links > 1)
4192 {
4193 warn_panel_dup = true;
4194 }
4195 else if (links == 0)
4196 {
4197 /* a TAP adapter exists without a link from the network
4198 * connections control panel */
4199 warn_panel_null = true;
4200 msg(msglev, "[NULL] %s", tr->guid);
4201 }
4202 }
4203
4204 /* check for TAP-Windows adapter duplicated GUIDs */
4205 for (tr = tap_reg; tr != NULL; tr = tr->next)
4206 {
4207 for (tr1 = tap_reg; tr1 != NULL; tr1 = tr1->next)
4208 {
4209 if (tr != tr1 && !strcmp(tr->guid, tr1->guid))
4210 {
4211 warn_tap_dup = true;
4212 }
4213 }
4214 }
4215
4216 /* warn on registry inconsistencies */
4217 if (warn_tap_dup)
4218 {
4219 msg(warnlev, "WARNING: Some TAP-Windows adapters have duplicate GUIDs");
4220 }
4221
4222 if (warn_panel_dup)
4223 {
4224 msg(warnlev, "WARNING: Some TAP-Windows adapters have duplicate links from the Network Connections control panel");
4225 }
4226
4227 if (warn_panel_null)
4228 {
4229 msg(warnlev, "WARNING: Some TAP-Windows adapters have no link from the Network Connections control panel");
4230 }
4231
4232 gc_free(&gc);
4233}
4234
4235/*
4236 * Lookup a TAP-Windows or Wintun adapter by GUID.
4237 */
4238static const struct tap_reg *
4239get_adapter_by_guid(const char *guid, const struct tap_reg *tap_reg)
4240{
4241 const struct tap_reg *tr;
4242
4243 for (tr = tap_reg; tr != NULL; tr = tr->next)
4244 {
4245 if (guid && !strcmp(tr->guid, guid))
4246 {
4247 return tr;
4248 }
4249 }
4250
4251 return NULL;
4252}
4253
4254static const char *
4255guid_to_name(const char *guid, const struct panel_reg *panel_reg)
4256{
4257 const struct panel_reg *pr;
4258
4259 for (pr = panel_reg; pr != NULL; pr = pr->next)
4260 {
4261 if (guid && !strcmp(pr->guid, guid))
4262 {
4263 return pr->name;
4264 }
4265 }
4266
4267 return NULL;
4268}
4269
4270static const struct tap_reg *
4271get_adapter_by_name(const char *name, const struct tap_reg *tap_reg, const struct panel_reg *panel_reg)
4272{
4273 const struct panel_reg *pr;
4274
4275 for (pr = panel_reg; pr != NULL; pr = pr->next)
4276 {
4277 if (name && !strcmp(pr->name, name))
4278 {
4279 return get_adapter_by_guid(pr->guid, tap_reg);
4280 }
4281 }
4282
4283 return NULL;
4284}
4285
4286static void
4288{
4289 if (!tap_reg)
4290 {
4291 msg(M_FATAL, "There are no TAP-Windows, Wintun or ovpn-dco adapters "
4292 "on this system. You should be able to create an adapter "
4293 "by using tapctl.exe utility.");
4294 }
4295}
4296
4297/*
4298 * Get an adapter GUID and optional actual_name from the
4299 * registry for the TAP device # = device_number.
4300 */
4301static const char *
4302get_unspecified_device_guid(const int device_number,
4303 uint8_t *actual_name,
4304 int actual_name_size,
4305 const struct tap_reg *tap_reg_src,
4306 const struct panel_reg *panel_reg_src,
4307 enum tun_driver_type *windows_driver,
4308 struct gc_arena *gc)
4309{
4310 const struct tap_reg *tap_reg = tap_reg_src;
4311 struct buffer actual = clear_buf();
4312 int i;
4313
4314 ASSERT(device_number >= 0);
4315
4316 /* Make sure we have at least one TAP adapter */
4317 if (!tap_reg)
4318 {
4319 return NULL;
4320 }
4321
4322 /* The actual_name output buffer may be NULL */
4323 if (actual_name)
4324 {
4326 buf_set_write(&actual, actual_name, actual_name_size);
4327 }
4328
4329 /* Move on to specified device number */
4330 for (i = 0; i < device_number; i++)
4331 {
4332 tap_reg = tap_reg->next;
4333 if (!tap_reg)
4334 {
4335 return NULL;
4336 }
4337 }
4338
4339 /* Save Network Panel name (if exists) in actual_name */
4340 if (actual_name)
4341 {
4342 const char *act = guid_to_name(tap_reg->guid, panel_reg_src);
4343 if (act)
4344 {
4345 buf_printf(&actual, "%s", act);
4346 }
4347 else
4348 {
4349 buf_printf(&actual, "%s", tap_reg->guid);
4350 }
4351 }
4352
4353 /* Save GUID for return value */
4354 struct buffer ret = alloc_buf_gc(256, gc);
4355 buf_printf(&ret, "%s", tap_reg->guid);
4356 if (windows_driver != NULL)
4357 {
4358 *windows_driver = tap_reg->windows_driver;
4359 }
4360 return BSTR(&ret);
4361}
4362
4363/*
4364 * Lookup a --dev-node adapter name in the registry
4365 * returning the GUID and optional actual_name and device type
4366 */
4367static const char *
4368get_device_guid(const char *name,
4369 uint8_t *actual_name,
4370 int actual_name_size,
4371 enum tun_driver_type *windows_driver,
4372 const struct tap_reg *tap_reg,
4373 const struct panel_reg *panel_reg,
4374 struct gc_arena *gc)
4375{
4376 struct buffer ret = alloc_buf_gc(256, gc);
4377 struct buffer actual = clear_buf();
4378 const struct tap_reg *tr;
4379
4380 /* Make sure we have at least one TAP adapter */
4381 if (!tap_reg)
4382 {
4383 return NULL;
4384 }
4385
4386 /* The actual_name output buffer may be NULL */
4387 if (actual_name)
4388 {
4389 ASSERT(actual_name_size > 0);
4390 buf_set_write(&actual, actual_name, actual_name_size);
4391 }
4392
4393 /* Check if GUID was explicitly specified as --dev-node parameter */
4394 tr = get_adapter_by_guid(name, tap_reg);
4395 if (tr)
4396 {
4397 const char *act = guid_to_name(name, panel_reg);
4398 buf_printf(&ret, "%s", name);
4399 if (act)
4400 {
4401 buf_printf(&actual, "%s", act);
4402 }
4403 else
4404 {
4405 buf_printf(&actual, "%s", name);
4406 }
4407 if (windows_driver)
4408 {
4410 }
4411 return BSTR(&ret);
4412 }
4413
4414 /* Lookup TAP adapter in network connections list */
4415 {
4417 if (tr)
4418 {
4419 buf_printf(&actual, "%s", name);
4420 if (windows_driver)
4421 {
4423 }
4424 buf_printf(&ret, "%s", tr->guid);
4425 return BSTR(&ret);
4426 }
4427 }
4428
4429 return NULL;
4430}
4431
4432/*
4433 * Get adapter info list
4434 */
4435const IP_ADAPTER_INFO *
4437{
4438 ULONG size = 0;
4439 IP_ADAPTER_INFO *pi = NULL;
4440 DWORD status;
4441
4442 if ((status = GetAdaptersInfo(NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4443 {
4444 msg(M_INFO, "GetAdaptersInfo #1 failed (status=%u) : %s",
4445 (unsigned int)status,
4447 }
4448 else
4449 {
4450 pi = (PIP_ADAPTER_INFO) gc_malloc(size, false, gc);
4451 if ((status = GetAdaptersInfo(pi, &size)) != NO_ERROR)
4452 {
4453 msg(M_INFO, "GetAdaptersInfo #2 failed (status=%u) : %s",
4454 (unsigned int)status,
4456 pi = NULL;
4457 }
4458 }
4459 return pi;
4460}
4461
4462const IP_PER_ADAPTER_INFO *
4463get_per_adapter_info(const DWORD index, struct gc_arena *gc)
4464{
4465 ULONG size = 0;
4466 IP_PER_ADAPTER_INFO *pi = NULL;
4467 DWORD status;
4468
4469 if (index != TUN_ADAPTER_INDEX_INVALID)
4470 {
4471 if ((status = GetPerAdapterInfo(index, NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4472 {
4473 msg(M_INFO, "GetPerAdapterInfo #1 failed (status=%u) : %s",
4474 (unsigned int)status,
4476 }
4477 else
4478 {
4479 pi = (PIP_PER_ADAPTER_INFO) gc_malloc(size, false, gc);
4480 if ((status = GetPerAdapterInfo((ULONG)index, pi, &size)) == ERROR_SUCCESS)
4481 {
4482 return pi;
4483 }
4484 else
4485 {
4486 msg(M_INFO, "GetPerAdapterInfo #2 failed (status=%u) : %s",
4487 (unsigned int)status,
4489 }
4490 }
4491 }
4492 return pi;
4493}
4494
4495static const IP_INTERFACE_INFO *
4497{
4498 ULONG size = 0;
4499 IP_INTERFACE_INFO *ii = NULL;
4500 DWORD status;
4501
4502 if ((status = GetInterfaceInfo(NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)
4503 {
4504 msg(M_INFO, "GetInterfaceInfo #1 failed (status=%u) : %s",
4505 (unsigned int)status,
4507 }
4508 else
4509 {
4510 ii = (PIP_INTERFACE_INFO) gc_malloc(size, false, gc);
4511 if ((status = GetInterfaceInfo(ii, &size)) == NO_ERROR)
4512 {
4513 return ii;
4514 }
4515 else
4516 {
4517 msg(M_INFO, "GetInterfaceInfo #2 failed (status=%u) : %s",
4518 (unsigned int)status,
4520 }
4521 }
4522 return ii;
4523}
4524
4525static const IP_ADAPTER_INDEX_MAP *
4526get_interface_info(DWORD index, struct gc_arena *gc)
4527{
4528 const IP_INTERFACE_INFO *list = get_interface_info_list(gc);
4529 if (list)
4530 {
4531 int i;
4532 for (i = 0; i < list->NumAdapters; ++i)
4533 {
4534 const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[i];
4535 if (index == inter->Index)
4536 {
4537 return inter;
4538 }
4539 }
4540 }
4541 return NULL;
4542}
4543
4544/*
4545 * Given an adapter index, return a pointer to the
4546 * IP_ADAPTER_INFO structure for that adapter.
4547 */
4548
4549const IP_ADAPTER_INFO *
4550get_adapter(const IP_ADAPTER_INFO *ai, DWORD index)
4551{
4552 if (ai && index != TUN_ADAPTER_INDEX_INVALID)
4553 {
4554 const IP_ADAPTER_INFO *a;
4555
4556 /* find index in the linked list */
4557 for (a = ai; a != NULL; a = a->Next)
4558 {
4559 if (a->Index == index)
4560 {
4561 return a;
4562 }
4563 }
4564 }
4565 return NULL;
4566}
4567
4568const IP_ADAPTER_INFO *
4569get_adapter_info(DWORD index, struct gc_arena *gc)
4570{
4571 return get_adapter(get_adapter_info_list(gc), index);
4572}
4573
4574static int
4575get_adapter_n_ip_netmask(const IP_ADAPTER_INFO *ai)
4576{
4577 if (ai)
4578 {
4579 int n = 0;
4580 const IP_ADDR_STRING *ip = &ai->IpAddressList;
4581
4582 while (ip)
4583 {
4584 ++n;
4585 ip = ip->Next;
4586 }
4587 return n;
4588 }
4589 else
4590 {
4591 return 0;
4592 }
4593}
4594
4595static bool
4596get_adapter_ip_netmask(const IP_ADAPTER_INFO *ai, const int n, in_addr_t *ip, in_addr_t *netmask)
4597{
4598 bool ret = false;
4599 *ip = 0;
4600 *netmask = 0;
4601
4602 if (ai)
4603 {
4604 const IP_ADDR_STRING *iplist = &ai->IpAddressList;
4605 int i = 0;
4606
4607 while (iplist)
4608 {
4609 if (i == n)
4610 {
4611 break;
4612 }
4613 ++i;
4614 iplist = iplist->Next;
4615 }
4616
4617 if (iplist)
4618 {
4619 const unsigned int getaddr_flags = GETADDR_HOST_ORDER;
4620 const char *ip_str = iplist->IpAddress.String;
4621 const char *netmask_str = iplist->IpMask.String;
4622 bool succeed1 = false;
4623 bool succeed2 = false;
4624
4625 if (ip_str && netmask_str && strlen(ip_str) && strlen(netmask_str))
4626 {
4627 *ip = getaddr(getaddr_flags, ip_str, 0, &succeed1, NULL);
4628 *netmask = getaddr(getaddr_flags, netmask_str, 0, &succeed2, NULL);
4629 ret = (succeed1 == true && succeed2 == true);
4630 }
4631 }
4632 }
4633
4634 return ret;
4635}
4636
4637static bool
4638test_adapter_ip_netmask(const IP_ADAPTER_INFO *ai, const in_addr_t ip, const in_addr_t netmask)
4639{
4640 if (ai)
4641 {
4642 in_addr_t ip_adapter = 0;
4643 in_addr_t netmask_adapter = 0;
4644 const bool status = get_adapter_ip_netmask(ai, 0, &ip_adapter, &netmask_adapter);
4645 return (status && ip_adapter == ip && netmask_adapter == netmask);
4646 }
4647 else
4648 {
4649 return false;
4650 }
4651}
4652
4653const IP_ADAPTER_INFO *
4654get_tun_adapter(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
4655{
4656 if (list && tt)
4657 {
4658 return get_adapter(list, tt->adapter_index);
4659 }
4660 else
4661 {
4662 return NULL;
4663 }
4664}
4665
4666bool
4667is_adapter_up(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
4668{
4669 int i;
4670 bool ret = false;
4671
4672 const IP_ADAPTER_INFO *ai = get_tun_adapter(tt, list);
4673
4674 if (ai)
4675 {
4676 const int n = get_adapter_n_ip_netmask(ai);
4677
4678 /* loop once for every IP/netmask assigned to adapter */
4679 for (i = 0; i < n; ++i)
4680 {
4681 in_addr_t ip, netmask;
4682 if (get_adapter_ip_netmask(ai, i, &ip, &netmask))
4683 {
4684 if (tt->local && tt->adapter_netmask)
4685 {
4686 /* wait for our --ifconfig parms to match the actual adapter parms */
4687 if (tt->local == ip && tt->adapter_netmask == netmask)
4688 {
4689 ret = true;
4690 }
4691 }
4692 else
4693 {
4694 /* --ifconfig was not defined, maybe using a real DHCP server */
4695 if (ip && netmask)
4696 {
4697 ret = true;
4698 }
4699 }
4700 }
4701 }
4702 }
4703 else
4704 {
4705 ret = true; /* this can occur when TAP adapter is bridged */
4706
4707 }
4708 return ret;
4709}
4710
4711bool
4712is_ip_in_adapter_subnet(const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask)
4713{
4714 int i;
4715 bool ret = false;
4716
4717 if (highest_netmask)
4718 {
4719 *highest_netmask = 0;
4720 }
4721
4722 if (ai)
4723 {
4724 const int n = get_adapter_n_ip_netmask(ai);
4725 for (i = 0; i < n; ++i)
4726 {
4727 in_addr_t adapter_ip, adapter_netmask;
4728 if (get_adapter_ip_netmask(ai, i, &adapter_ip, &adapter_netmask))
4729 {
4730 if (adapter_ip && adapter_netmask && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))
4731 {
4732 if (highest_netmask && adapter_netmask > *highest_netmask)
4733 {
4734 *highest_netmask = adapter_netmask;
4735 }
4736 ret = true;
4737 }
4738 }
4739 }
4740 }
4741 return ret;
4742}
4743
4744DWORD
4745adapter_index_of_ip(const IP_ADAPTER_INFO *list,
4746 const in_addr_t ip,
4747 int *count,
4748 in_addr_t *netmask)
4749{
4750 struct gc_arena gc = gc_new();
4751 DWORD ret = TUN_ADAPTER_INDEX_INVALID;
4752 in_addr_t highest_netmask = 0;
4753 int lowest_metric = INT_MAX;
4754 bool first = true;
4755
4756 if (count)
4757 {
4758 *count = 0;
4759 }
4760
4761 while (list)
4762 {
4763 in_addr_t hn;
4764
4765 if (is_ip_in_adapter_subnet(list, ip, &hn))
4766 {
4767 int metric = get_interface_metric(list->Index, AF_INET, NULL);
4768 if (first || hn > highest_netmask)
4769 {
4770 highest_netmask = hn;
4771 if (metric >= 0)
4772 {
4773 lowest_metric = metric;
4774 }
4775 if (count)
4776 {
4777 *count = 1;
4778 }
4779 ret = list->Index;
4780 first = false;
4781 }
4782 else if (hn == highest_netmask)
4783 {
4784 if (count)
4785 {
4786 ++*count;
4787 }
4788 if (metric >= 0 && metric < lowest_metric)
4789 {
4790 ret = list->Index;
4791 lowest_metric = metric;
4792 }
4793 }
4794 }
4795 list = list->Next;
4796 }
4797
4798 dmsg(D_ROUTE_DEBUG, "DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d metric=%d",
4799 print_in_addr_t(ip, 0, &gc),
4800 print_in_addr_t(highest_netmask, 0, &gc),
4801 (int)ret,
4802 count ? *count : -1,
4803 lowest_metric);
4804
4805 if (ret == TUN_ADAPTER_INDEX_INVALID && count)
4806 {
4807 *count = 0;
4808 }
4809
4810 if (netmask)
4811 {
4812 *netmask = highest_netmask;
4813 }
4814
4815 gc_free(&gc);
4816 return ret;
4817}
4818
4819/*
4820 * Given an adapter index, return true if the adapter
4821 * is DHCP disabled.
4822 */
4823
4824#define DHCP_STATUS_UNDEF 0
4825#define DHCP_STATUS_ENABLED 1
4826#define DHCP_STATUS_DISABLED 2
4827
4828static int
4829dhcp_status(DWORD index)
4830{
4831 struct gc_arena gc = gc_new();
4832 int ret = DHCP_STATUS_UNDEF;
4833 if (index != TUN_ADAPTER_INDEX_INVALID)
4834 {
4835 const IP_ADAPTER_INFO *ai = get_adapter_info(index, &gc);
4836
4837 if (ai)
4838 {
4839 if (ai->DhcpEnabled)
4840 {
4841 ret = DHCP_STATUS_ENABLED;
4842 }
4843 else
4844 {
4846 }
4847 }
4848 }
4849 gc_free(&gc);
4850 return ret;
4851}
4852
4853/*
4854 * Delete all temporary address/netmask pairs which were added
4855 * to adapter (given by index) by previous calls to AddIPAddress.
4856 */
4857static void
4859{
4860 struct gc_arena gc = gc_new();
4861 const IP_ADAPTER_INFO *a = get_adapter_info(index, &gc);
4862
4863 if (a)
4864 {
4865 const IP_ADDR_STRING *ip = &a->IpAddressList;
4866 while (ip)
4867 {
4868 DWORD status;
4869 const DWORD context = ip->Context;
4870
4871 if ((status = DeleteIPAddress((ULONG) context)) == NO_ERROR)
4872 {
4873 msg(M_INFO, "Successfully deleted previously set dynamic IP/netmask: %s/%s",
4874 ip->IpAddress.String,
4875 ip->IpMask.String);
4876 }
4877 else
4878 {
4879 const char *empty = "0.0.0.0";
4880 if (strcmp(ip->IpAddress.String, empty)
4881 || strcmp(ip->IpMask.String, empty))
4882 {
4883 msg(M_INFO, "NOTE: could not delete previously set dynamic IP/netmask: %s/%s (status=%u)",
4884 ip->IpAddress.String,
4885 ip->IpMask.String,
4886 (unsigned int)status);
4887 }
4888 }
4889 ip = ip->Next;
4890 }
4891 }
4892 gc_free(&gc);
4893}
4894
4895/*
4896 * Get interface index for use with IP Helper API functions.
4897 */
4898static DWORD
4900{
4901 DWORD index;
4902 ULONG aindex;
4903 wchar_t wbuf[256];
4904 swprintf(wbuf, SIZE(wbuf), L"\\DEVICE\\TCPIP_%hs", guid);
4905 if (GetAdapterIndex(wbuf, &aindex) != NO_ERROR)
4906 {
4908 }
4909 else
4910 {
4911 index = (DWORD)aindex;
4912 }
4913 return index;
4914}
4915
4916static DWORD
4918{
4919 struct gc_arena gc = gc_new();
4920 DWORD index = TUN_ADAPTER_INDEX_INVALID;
4921
4922 const IP_ADAPTER_INFO *list = get_adapter_info_list(&gc);
4923
4924 while (list)
4925 {
4926 if (!strcmp(guid, list->AdapterName))
4927 {
4928 index = list->Index;
4929 break;
4930 }
4931 list = list->Next;
4932 }
4933
4934 gc_free(&gc);
4935 return index;
4936}
4937
4938static DWORD
4939get_adapter_index(const char *guid)
4940{
4941 DWORD index;
4942 index = get_adapter_index_method_1(guid);
4943 if (index == TUN_ADAPTER_INDEX_INVALID)
4944 {
4945 index = get_adapter_index_method_2(guid);
4946 }
4947 if (index == TUN_ADAPTER_INDEX_INVALID)
4948 {
4949 msg(M_INFO, "NOTE: could not get adapter index for %s", guid);
4950 }
4951 return index;
4952}
4953
4954/*
4955 * Return a string representing a PIP_ADDR_STRING
4956 */
4957static const char *
4958format_ip_addr_string(const IP_ADDR_STRING *ip, struct gc_arena *gc)
4959{
4960 struct buffer out = alloc_buf_gc(256, gc);
4961 while (ip)
4962 {
4963 buf_printf(&out, "%s", ip->IpAddress.String);
4964 if (strlen(ip->IpMask.String))
4965 {
4966 buf_printf(&out, "/");
4967 buf_printf(&out, "%s", ip->IpMask.String);
4968 }
4969 buf_printf(&out, " ");
4970 ip = ip->Next;
4971 }
4972 return BSTR(&out);
4973}
4974
4975/*
4976 * Show info for a single adapter
4977 */
4978static void
4980{
4981 msg(msglev, "%s", a->Description);
4982 msg(msglev, " Index = %d", (int)a->Index);
4983 msg(msglev, " GUID = %s", a->AdapterName);
4984 msg(msglev, " IP = %s", format_ip_addr_string(&a->IpAddressList, gc));
4985 msg(msglev, " MAC = %s", format_hex_ex(a->Address, a->AddressLength, 0, 1, ":", gc));
4986 msg(msglev, " GATEWAY = %s", format_ip_addr_string(&a->GatewayList, gc));
4987 if (a->DhcpEnabled)
4988 {
4989 msg(msglev, " DHCP SERV = %s", format_ip_addr_string(&a->DhcpServer, gc));
4990 msg(msglev, " DHCP LEASE OBTAINED = %s", time_string(a->LeaseObtained, 0, false, gc));
4991 msg(msglev, " DHCP LEASE EXPIRES = %s", time_string(a->LeaseExpires, 0, false, gc));
4992 }
4993 if (a->HaveWins)
4994 {
4995 msg(msglev, " PRI WINS = %s", format_ip_addr_string(&a->PrimaryWinsServer, gc));
4996 msg(msglev, " SEC WINS = %s", format_ip_addr_string(&a->SecondaryWinsServer, gc));
4997 }
4998
4999 {
5001 if (pai)
5002 {
5003 msg(msglev, " DNS SERV = %s", format_ip_addr_string(&pai->DnsServerList, gc));
5004 }
5005 }
5006}
5007
5008/*
5009 * Show current adapter list
5010 */
5011void
5013{
5014 struct gc_arena gc = gc_new();
5015 const IP_ADAPTER_INFO *ai = get_adapter_info_list(&gc);
5016
5017 msg(msglev, "SYSTEM ADAPTER LIST");
5018 if (ai)
5019 {
5020 const IP_ADAPTER_INFO *a;
5021
5022 /* find index in the linked list */
5023 for (a = ai; a != NULL; a = a->Next)
5024 {
5025 show_adapter(msglev, a, &gc);
5026 }
5027 }
5028 gc_free(&gc);
5029}
5030
5031/*
5032 * Set a particular TAP-Windows adapter (or all of them if
5033 * adapter_name == NULL) to allow it to be opened from
5034 * a non-admin account. This setting will only persist
5035 * for the lifetime of the device object.
5036 */
5037
5038static void
5039tap_allow_nonadmin_access_handle(const char *device_path, HANDLE hand)
5040{
5041 struct security_attributes sa;
5042 BOOL status;
5043
5045 {
5046 msg(M_ERR, "Error: init SA failed");
5047 }
5048
5049 status = SetKernelObjectSecurity(hand, DACL_SECURITY_INFORMATION, &sa.sd);
5050 if (!status)
5051 {
5052 msg(M_ERRNO, "Error: SetKernelObjectSecurity failed on %s", device_path);
5053 }
5054 else
5055 {
5056 msg(M_INFO|M_NOPREFIX, "TAP-Windows device: %s [Non-admin access allowed]", device_path);
5057 }
5058}
5059
5060void
5061tap_allow_nonadmin_access(const char *dev_node)
5062{
5063 struct gc_arena gc = gc_new();
5064 const struct tap_reg *tap_reg = get_tap_reg(&gc);
5065 const struct panel_reg *panel_reg = get_panel_reg(&gc);
5066 const char *device_guid = NULL;
5067 HANDLE hand;
5068 uint8_t actual_buffer[256];
5069 char device_path[256];
5070
5072
5073 if (dev_node)
5074 {
5075 /* Get the device GUID for the device specified with --dev-node. */
5076 device_guid = get_device_guid(dev_node, actual_buffer, sizeof(actual_buffer), NULL, tap_reg, panel_reg, &gc);
5077
5078 if (!device_guid)
5079 {
5080 msg(M_FATAL, "TAP-Windows adapter '%s' not found", dev_node);
5081 }
5082
5083 /* Open Windows TAP-Windows adapter */
5084 snprintf(device_path, sizeof(device_path), "%s%s%s",
5085 USERMODEDEVICEDIR,
5086 device_guid,
5087 TAP_WIN_SUFFIX);
5088
5089 hand = CreateFile(
5090 device_path,
5091 MAXIMUM_ALLOWED,
5092 0, /* was: FILE_SHARE_READ */
5093 0,
5094 OPEN_EXISTING,
5095 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
5096 0
5097 );
5098
5099 if (hand == INVALID_HANDLE_VALUE)
5100 {
5101 msg(M_ERR, "CreateFile failed on TAP device: %s", device_path);
5102 }
5103
5104 tap_allow_nonadmin_access_handle(device_path, hand);
5105 CloseHandle(hand);
5106 }
5107 else
5108 {
5109 int device_number = 0;
5110
5111 /* Try opening all TAP devices */
5112 while (true)
5113 {
5114 device_guid = get_unspecified_device_guid(device_number,
5115 actual_buffer,
5116 sizeof(actual_buffer),
5117 tap_reg,
5118 panel_reg,
5119 NULL,
5120 &gc);
5121
5122 if (!device_guid)
5123 {
5124 break;
5125 }
5126
5127 /* Open Windows TAP-Windows adapter */
5128 snprintf(device_path, sizeof(device_path), "%s%s%s",
5129 USERMODEDEVICEDIR,
5130 device_guid,
5131 TAP_WIN_SUFFIX);
5132
5133 hand = CreateFile(
5134 device_path,
5135 MAXIMUM_ALLOWED,
5136 0, /* was: FILE_SHARE_READ */
5137 0,
5138 OPEN_EXISTING,
5139 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
5140 0
5141 );
5142
5143 if (hand == INVALID_HANDLE_VALUE)
5144 {
5145 msg(M_WARN, "CreateFile failed on TAP device: %s", device_path);
5146 }
5147 else
5148 {
5149 tap_allow_nonadmin_access_handle(device_path, hand);
5150 CloseHandle(hand);
5151 }
5152
5153 device_number++;
5154 }
5155 }
5156 gc_free(&gc);
5157}
5158
5159/*
5160 * DHCP release/renewal
5161 */
5162bool
5163dhcp_release_by_adapter_index(const DWORD adapter_index)
5164{
5165 struct gc_arena gc = gc_new();
5166 bool ret = false;
5167 const IP_ADAPTER_INDEX_MAP *inter = get_interface_info(adapter_index, &gc);
5168
5169 if (inter)
5170 {
5171 DWORD status = IpReleaseAddress((IP_ADAPTER_INDEX_MAP *)inter);
5172 if (status == NO_ERROR)
5173 {
5174 msg(D_TUNTAP_INFO, "TAP: DHCP address released");
5175 ret = true;
5176 }
5177 else
5178 {
5179 msg(M_WARN, "NOTE: Release of DHCP-assigned IP address lease on TAP-Windows adapter failed: %s (code=%u)",
5181 (unsigned int)status);
5182 }
5183 }
5184
5185 gc_free(&gc);
5186 return ret;
5187}
5188
5189static bool
5190dhcp_release(const struct tuntap *tt)
5191{
5193 {
5195 }
5196 else
5197 {
5198 return false;
5199 }
5200}
5201
5202bool
5203dhcp_renew_by_adapter_index(const DWORD adapter_index)
5204{
5205 struct gc_arena gc = gc_new();
5206 bool ret = false;
5207 const IP_ADAPTER_INDEX_MAP *inter = get_interface_info(adapter_index, &gc);
5208
5209 if (inter)
5210 {
5211 DWORD status = IpRenewAddress((IP_ADAPTER_INDEX_MAP *)inter);
5212 if (status == NO_ERROR)
5213 {
5214 msg(D_TUNTAP_INFO, "TAP: DHCP address renewal succeeded");
5215 ret = true;
5216 }
5217 else
5218 {
5219 msg(M_WARN, "WARNING: Failed to renew DHCP IP address lease on TAP-Windows adapter: %s (code=%u)",
5221 (unsigned int)status);
5222 }
5223 }
5224 gc_free(&gc);
5225 return ret;
5226}
5227
5228static bool
5229dhcp_renew(const struct tuntap *tt)
5230{
5232 {
5234 }
5235 else
5236 {
5237 return false;
5238 }
5239}
5240
5241static void
5242exec_command(const char *prefix, const struct argv *a, int n, int msglevel)
5243{
5244 int i;
5245 for (i = 0; i < n; ++i)
5246 {
5247 bool status;
5250 argv_msg_prefix(M_INFO, a, prefix);
5251 status = openvpn_execve_check(a, NULL, 0, "ERROR: command failed");
5253 if (status)
5254 {
5255 return;
5256 }
5258 }
5259 msg(msglevel, "%s: command failed", prefix);
5260}
5261
5262static void
5263netsh_command(const struct argv *a, int n, int msglevel)
5264{
5265 exec_command("NETSH", a, n, msglevel);
5266}
5267
5268void
5270{
5271 struct argv argv = argv_new();
5272 const char err[] = "ERROR: Windows ipconfig command failed";
5273
5274 msg(D_TUNTAP_INFO, "Start ipconfig commands for register-dns...");
5276
5277 argv_printf(&argv, "%s%s /flushdns",
5281 openvpn_execve_check(&argv, es, 0, err);
5282
5283 argv_printf(&argv, "%s%s /registerdns",
5287 openvpn_execve_check(&argv, es, 0, err);
5288 argv_free(&argv);
5289
5291 msg(D_TUNTAP_INFO, "End ipconfig commands for register-dns...");
5292}
5293
5294void
5295ip_addr_string_to_array(in_addr_t *dest, int *dest_len, const IP_ADDR_STRING *src)
5296{
5297 int i = 0;
5298 while (src)
5299 {
5300 const unsigned int getaddr_flags = GETADDR_HOST_ORDER;
5301 const char *ip_str = src->IpAddress.String;
5302 in_addr_t ip = 0;
5303 bool succeed = false;
5304
5305 if (i >= *dest_len)
5306 {
5307 break;
5308 }
5309 if (!ip_str || !strlen(ip_str))
5310 {
5311 break;
5312 }
5313
5314 ip = getaddr(getaddr_flags, ip_str, 0, &succeed, NULL);
5315 if (!succeed)
5316 {
5317 break;
5318 }
5319 dest[i++] = ip;
5320
5321 src = src->Next;
5322 }
5323 *dest_len = i;
5324
5325#if 0
5326 {
5327 struct gc_arena gc = gc_new();
5328 msg(M_INFO, "ip_addr_string_to_array [%d]", *dest_len);
5329 for (i = 0; i < *dest_len; ++i)
5330 {
5331 msg(M_INFO, "%s", print_in_addr_t(dest[i], 0, &gc));
5332 }
5333 gc_free(&gc);
5334 }
5335#endif
5336}
5337
5338static bool
5339ip_addr_one_to_one(const in_addr_t *a1, const int a1len, const IP_ADDR_STRING *ias)
5340{
5341 in_addr_t a2[8];
5342 int a2len = SIZE(a2);
5343 int i;
5344
5345 ip_addr_string_to_array(a2, &a2len, ias);
5346 /*msg (M_INFO, "a1len=%d a2len=%d", a1len, a2len);*/
5347 if (a1len != a2len)
5348 {
5349 return false;
5350 }
5351
5352 for (i = 0; i < a1len; ++i)
5353 {
5354 if (a1[i] != a2[i])
5355 {
5356 return false;
5357 }
5358 }
5359 return true;
5360}
5361
5362static bool
5363ip_addr_member_of(const in_addr_t addr, const IP_ADDR_STRING *ias)
5364{
5365 in_addr_t aa[8];
5366 int len = SIZE(aa);
5367 int i;
5368
5369 ip_addr_string_to_array(aa, &len, ias);
5370 for (i = 0; i < len; ++i)
5371 {
5372 if (addr == aa[i])
5373 {
5374 return true;
5375 }
5376 }
5377 return false;
5378}
5379
5385static void
5386netsh_set_dns6_servers(const struct in6_addr *addr_list,
5387 const int addr_len,
5388 DWORD adapter_index)
5389{
5390 struct gc_arena gc = gc_new();
5391 struct argv argv = argv_new();
5392
5393 /* delete existing DNS settings from TAP interface */
5394 argv_printf(&argv, "%s%s interface ipv6 delete dns %lu all",
5397 adapter_index);
5399
5400 for (int i = 0; i < addr_len; ++i)
5401 {
5402 const char *fmt = (i == 0) ?
5403 "%s%s interface ipv6 set dns %lu static %s"
5404 : "%s%s interface ipv6 add dns %lu %s";
5406 NETSH_PATH_SUFFIX, adapter_index,
5407 print_in6_addr(addr_list[i], 0, &gc));
5408
5409 /* disable slow address validation on Windows 7 and higher */
5410 if (win32_version_info() >= WIN_7)
5411 {
5412 argv_printf_cat(&argv, "%s", "validate=no");
5413 }
5414
5415 /* Treat errors while adding as non-fatal as we do not check for duplicates */
5416 netsh_command(&argv, 1, (i==0) ? M_FATAL : M_NONFATAL);
5417 }
5418
5419 argv_free(&argv);
5420 gc_free(&gc);
5421}
5422
5423static void
5424netsh_ifconfig_options(const char *type,
5425 const in_addr_t *addr_list,
5426 const int addr_len,
5427 const IP_ADDR_STRING *current,
5428 DWORD adapter_index,
5429 const bool test_first)
5430{
5431 struct gc_arena gc = gc_new();
5432 struct argv argv = argv_new();
5433 bool delete_first = false;
5434 bool is_dns = !strcmp(type, "dns");
5435
5436 /* first check if we should delete existing DNS/WINS settings from TAP interface */
5437 if (test_first)
5438 {
5439 if (!ip_addr_one_to_one(addr_list, addr_len, current))
5440 {
5441 delete_first = true;
5442 }
5443 }
5444 else
5445 {
5446 delete_first = true;
5447 }
5448
5449 /* delete existing DNS/WINS settings from TAP interface */
5450 if (delete_first)
5451 {
5452 argv_printf(&argv, "%s%s interface ip delete %s %lu all",
5455 type,
5456 adapter_index);
5458 }
5459
5460 /* add new DNS/WINS settings to TAP interface */
5461 {
5462 int count = 0;
5463 int i;
5464 for (i = 0; i < addr_len; ++i)
5465 {
5466 if (delete_first || !test_first || !ip_addr_member_of(addr_list[i], current))
5467 {
5468 const char *fmt = count ?
5469 "%s%s interface ip add %s %lu %s"
5470 : "%s%s interface ip set %s %lu static %s";
5471
5472 argv_printf(&argv, fmt,
5475 type,
5476 adapter_index,
5477 print_in_addr_t(addr_list[i], 0, &gc));
5478
5479 /* disable slow address validation on Windows 7 and higher */
5480 /* only for DNS */
5481 if (is_dns && win32_version_info() >= WIN_7)
5482 {
5483 argv_printf_cat(&argv, "%s", "validate=no");
5484 }
5485
5487
5488 ++count;
5489 }
5490 else
5491 {
5492 msg(M_INFO, "NETSH: %lu %s %s [already set]",
5493 adapter_index,
5494 type,
5495 print_in_addr_t(addr_list[i], 0, &gc));
5496 }
5497 }
5498 }
5499
5500 argv_free(&argv);
5501 gc_free(&gc);
5502}
5503
5504static void
5505init_ip_addr_string2(IP_ADDR_STRING *dest, const IP_ADDR_STRING *src1, const IP_ADDR_STRING *src2)
5506{
5507 CLEAR(dest[0]);
5508 CLEAR(dest[1]);
5509 if (src1)
5510 {
5511 dest[0] = *src1;
5512 dest[0].Next = NULL;
5513 }
5514 if (src2)
5515 {
5516 dest[1] = *src2;
5517 dest[0].Next = &dest[1];
5518 dest[1].Next = NULL;
5519 }
5520}
5521
5522static void
5524 DWORD adapter_index,
5525 const in_addr_t ip,
5526 const in_addr_t netmask,
5527 const unsigned int flags)
5528{
5529 struct gc_arena gc = gc_new();
5530 struct argv argv = argv_new();
5531 const IP_ADAPTER_INFO *ai = NULL;
5532 const IP_PER_ADAPTER_INFO *pai = NULL;
5533
5534 if (flags & NI_TEST_FIRST)
5535 {
5536 const IP_ADAPTER_INFO *list = get_adapter_info_list(&gc);
5537 ai = get_adapter(list, adapter_index);
5538 pai = get_per_adapter_info(adapter_index, &gc);
5539 }
5540
5541 if (flags & NI_IP_NETMASK)
5542 {
5543 if (test_adapter_ip_netmask(ai, ip, netmask))
5544 {
5545 msg(M_INFO, "NETSH: %lu %s/%s [already set]",
5546 adapter_index,
5547 print_in_addr_t(ip, 0, &gc),
5548 print_in_addr_t(netmask, 0, &gc));
5549 }
5550 else
5551 {
5552 /* example: netsh interface ip set address 42 static 10.3.0.1 255.255.255.0 */
5553 argv_printf(&argv, "%s%s interface ip set address %lu static %s %s",
5556 adapter_index,
5557 print_in_addr_t(ip, 0, &gc),
5558 print_in_addr_t(netmask, 0, &gc));
5559
5561 }
5562 }
5563
5564 /* set WINS/DNS options */
5565 if (flags & NI_OPTIONS)
5566 {
5567 IP_ADDR_STRING wins[2];
5568 CLEAR(wins[0]);
5569 CLEAR(wins[1]);
5570
5572 to->dns,
5573 to->dns_len,
5574 pai ? &pai->DnsServerList : NULL,
5575 adapter_index,
5576 BOOL_CAST(flags & NI_TEST_FIRST));
5577 if (ai && ai->HaveWins)
5578 {
5579 init_ip_addr_string2(wins, &ai->PrimaryWinsServer, &ai->SecondaryWinsServer);
5580 }
5581
5583 to->wins,
5584 to->wins_len,
5585 ai ? wins : NULL,
5586 adapter_index,
5587 BOOL_CAST(flags & NI_TEST_FIRST));
5588 }
5589
5590 argv_free(&argv);
5591 gc_free(&gc);
5592}
5593
5594static void
5595netsh_enable_dhcp(DWORD adapter_index)
5596{
5597 struct argv argv = argv_new();
5598
5599 /* example: netsh interface ip set address 42 dhcp */
5601 "%s%s interface ip set address %lu dhcp",
5604 adapter_index);
5605
5607
5608 argv_free(&argv);
5609}
5610
5611/* Enable dhcp on tap adapter using iservice */
5612static bool
5614{
5615 bool ret = false;
5616 ack_message_t ack;
5617 struct gc_arena gc = gc_new();
5618 HANDLE pipe = tt->options.msg_channel;
5619
5621 .header = {
5623 sizeof(enable_dhcp_message_t),
5624 0
5625 },
5626 .iface = { .index = tt->adapter_index, .name = "" }
5627 };
5628
5629 if (!send_msg_iservice(pipe, &dhcp, sizeof(dhcp), &ack, "Enable_dhcp"))
5630 {
5631 goto out;
5632 }
5633
5634 if (ack.error_number != NO_ERROR)
5635 {
5636 msg(M_NONFATAL, "TUN: enabling dhcp using service failed: %s [status=%u if_index=%d]",
5637 strerror_win32(ack.error_number, &gc), ack.error_number, dhcp.iface.index);
5638 }
5639 else
5640 {
5641 msg(M_INFO, "DHCP enabled on interface %d using service", dhcp.iface.index);
5642 ret = true;
5643 }
5644
5645out:
5646 gc_free(&gc);
5647 return ret;
5648}
5649
5650static void
5651windows_set_mtu(const int iface_index, const short family,
5652 const int mtu)
5653{
5654 DWORD err = 0;
5655 struct gc_arena gc = gc_new();
5656 MIB_IPINTERFACE_ROW ipiface;
5657 InitializeIpInterfaceEntry(&ipiface);
5658 const char *family_name = (family == AF_INET6) ? "IPv6" : "IPv4";
5659 ipiface.Family = family;
5660 ipiface.InterfaceIndex = iface_index;
5661 if (family == AF_INET6 && mtu < 1280)
5662 {
5663 msg(M_INFO, "NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
5664 }
5665
5666 err = GetIpInterfaceEntry(&ipiface);
5667 if (err == NO_ERROR)
5668 {
5669 if (family == AF_INET)
5670 {
5671 ipiface.SitePrefixLength = 0;
5672 }
5673 ipiface.NlMtu = mtu;
5674 err = SetIpInterfaceEntry(&ipiface);
5675 }
5676
5677 if (err != NO_ERROR)
5678 {
5679 msg(M_WARN, "TUN: Setting %s mtu failed: %s [status=%lu if_index=%d]",
5680 family_name, strerror_win32(err, &gc), err, iface_index);
5681 }
5682 else
5683 {
5684 msg(M_INFO, "%s MTU set to %d on interface %d using SetIpInterfaceEntry()", family_name, mtu, iface_index);
5685 }
5686}
5687
5688
5689/*
5690 * Return a TAP name for netsh commands.
5691 */
5692static const char *
5693netsh_get_id(const char *dev_node, struct gc_arena *gc)
5694{
5695 const struct tap_reg *tap_reg = get_tap_reg(gc);
5696 const struct panel_reg *panel_reg = get_panel_reg(gc);
5697 struct buffer actual = alloc_buf_gc(256, gc);
5698 const char *guid;
5699
5701
5702 if (dev_node)
5703 {
5704 guid = get_device_guid(dev_node, BPTR(&actual), BCAP(&actual), NULL, tap_reg, panel_reg, gc);
5705 }
5706 else
5707 {
5708 guid = get_unspecified_device_guid(0, BPTR(&actual), BCAP(&actual), tap_reg, panel_reg, NULL, gc);
5709
5710 if (get_unspecified_device_guid(1, NULL, 0, tap_reg, panel_reg, NULL, gc)) /* ambiguous if more than one TAP-Windows adapter */
5711 {
5712 guid = NULL;
5713 }
5714 }
5715
5716 if (!guid)
5717 {
5718 return "NULL"; /* not found */
5719 }
5720 else if (strcmp(BSTR(&actual), "NULL"))
5721 {
5722 return BSTR(&actual); /* control panel name */
5723 }
5724 else
5725 {
5726 return guid; /* no control panel name, return GUID instead */
5727 }
5728}
5729
5730/*
5731 * Called iteratively on TAP-Windows wait-for-initialization polling loop
5732 */
5733void
5735{
5736 tt->standby_iter = 0;
5737}
5738
5739bool
5741{
5742 bool ret = true;
5743 ++tt->standby_iter;
5744 if (tt->options.ip_win32_type == IPW32_SET_ADAPTIVE)
5745 {
5746 if (tt->standby_iter == IPW32_SET_ADAPTIVE_TRY_NETSH)
5747 {
5748 msg(M_INFO, "NOTE: now trying netsh (this may take some time)");
5749 netsh_ifconfig(&tt->options,
5750 tt->adapter_index,
5751 tt->local,
5752 tt->adapter_netmask,
5754 }
5755 else if (tt->standby_iter >= IPW32_SET_ADAPTIVE_TRY_NETSH*2)
5756 {
5757 ret = false;
5758 }
5759 }
5760 return ret;
5761}
5762
5763/*
5764 * Convert DHCP options from the command line / config file
5765 * into a raw DHCP-format options string.
5766 */
5767
5768static void
5769write_dhcp_u8(struct buffer *buf, const int type, const int data, bool *error)
5770{
5771 if (!buf_safe(buf, 3))
5772 {
5773 *error = true;
5774 msg(M_WARN, "write_dhcp_u8: buffer overflow building DHCP options");
5775 return;
5776 }
5777 buf_write_u8(buf, type);
5778 buf_write_u8(buf, 1);
5779 buf_write_u8(buf, data);
5780}
5781
5782static void
5783write_dhcp_u32_array(struct buffer *buf, const int type, const uint32_t *data, const unsigned int len, bool *error)
5784{
5785 if (len > 0)
5786 {
5787 int i;
5788 const int size = len * sizeof(uint32_t);
5789
5790 if (!buf_safe(buf, 2 + size))
5791 {
5792 *error = true;
5793 msg(M_WARN, "write_dhcp_u32_array: buffer overflow building DHCP options");
5794 return;
5795 }
5796 if (size < 1 || size > 255)
5797 {
5798 *error = true;
5799 msg(M_WARN, "write_dhcp_u32_array: size (%d) must be > 0 and <= 255", size);
5800 return;
5801 }
5802 buf_write_u8(buf, type);
5803 buf_write_u8(buf, size);
5804 for (i = 0; i < len; ++i)
5805 {
5806 buf_write_u32(buf, data[i]);
5807 }
5808 }
5809}
5810
5811static void
5812write_dhcp_str(struct buffer *buf, const int type, const char *str, bool *error)
5813{
5814 const int len = strlen(str);
5815 if (!buf_safe(buf, 2 + len))
5816 {
5817 *error = true;
5818 msg(M_WARN, "write_dhcp_str: buffer overflow building DHCP options");
5819 return;
5820 }
5821 if (len < 1 || len > 255)
5822 {
5823 *error = true;
5824 msg(M_WARN, "write_dhcp_str: string '%s' must be > 0 bytes and <= 255 bytes", str);
5825 return;
5826 }
5827 buf_write_u8(buf, type);
5828 buf_write_u8(buf, len);
5829 buf_write(buf, str, len);
5830}
5831
5832/*
5833 * RFC3397 states that multiple searchdomains are encoded as follows:
5834 * - at start the length of the entire option is given
5835 * - each subdomain is preceded by its length
5836 * - each searchdomain is separated by a NUL character
5837 * e.g. if you want "openvpn.net" and "duckduckgo.com" then you end up with
5838 * 0x1D 0x7 openvpn 0x3 net 0x00 0x0A duckduckgo 0x3 com 0x00
5839 */
5840static void
5841write_dhcp_search_str(struct buffer *buf, const int type, const char *const *str_array,
5842 int array_len, bool *error)
5843{
5844 char tmp_buf[256];
5845 int i;
5846 int len = 0;
5847 int label_length_pos;
5848
5849 for (i = 0; i < array_len; i++)
5850 {
5851 const char *ptr = str_array[i];
5852
5853 if (strlen(ptr) + len + 1 > sizeof(tmp_buf))
5854 {
5855 *error = true;
5856 msg(M_WARN, "write_dhcp_search_str: temp buffer overflow building DHCP options");
5857 return;
5858 }
5859 /* Loop over all subdomains separated by a dot and replace the dot
5860 * with the length of the subdomain */
5861
5862 /* label_length_pos points to the byte to be replaced by the length
5863 * of the following domain label */
5865
5866 while (true)
5867 {
5868 if (*ptr == '.' || *ptr == '\0')
5869 {
5872 if (*ptr == '\0')
5873 {
5874 break;
5875 }
5876 }
5877 tmp_buf[len++] = *ptr++;
5878 }
5879 /* And close off with an extra NUL char */
5880 tmp_buf[len++] = 0;
5881 }
5882
5883 if (!buf_safe(buf, 2 + len))
5884 {
5885 *error = true;
5886 msg(M_WARN, "write_search_dhcp_str: buffer overflow building DHCP options");
5887 return;
5888 }
5889 if (len > 255)
5890 {
5891 *error = true;
5892 msg(M_WARN, "write_dhcp_search_str: search domain string must be <= 255 bytes");
5893 return;
5894 }
5895
5896 buf_write_u8(buf, type);
5897 buf_write_u8(buf, len);
5898 buf_write(buf, tmp_buf, len);
5899}
5900
5901static bool
5903{
5904 bool error = false;
5905 if (o->domain)
5906 {
5907 write_dhcp_str(buf, 15, o->domain, &error);
5908 }
5909
5910 if (o->netbios_scope)
5911 {
5912 write_dhcp_str(buf, 47, o->netbios_scope, &error);
5913 }
5914
5915 if (o->netbios_node_type)
5916 {
5917 write_dhcp_u8(buf, 46, o->netbios_node_type, &error);
5918 }
5919
5920 write_dhcp_u32_array(buf, 6, (uint32_t *)o->dns, o->dns_len, &error);
5921 write_dhcp_u32_array(buf, 44, (uint32_t *)o->wins, o->wins_len, &error);
5922 write_dhcp_u32_array(buf, 42, (uint32_t *)o->ntp, o->ntp_len, &error);
5923 write_dhcp_u32_array(buf, 45, (uint32_t *)o->nbdd, o->nbdd_len, &error);
5924
5925 if (o->domain_search_list_len > 0)
5926 {
5927 write_dhcp_search_str(buf, 119, o->domain_search_list,
5928 o->domain_search_list_len,
5929 &error);
5930 }
5931
5932 /* the MS DHCP server option 'Disable Netbios-over-TCP/IP
5933 * is implemented as vendor option 001, value 002.
5934 * A value of 001 means 'leave NBT alone' which is the default */
5935 if (o->disable_nbt)
5936 {
5937 if (!buf_safe(buf, 8))
5938 {
5939 msg(M_WARN, "build_dhcp_options_string: buffer overflow building DHCP options");
5940 return false;
5941 }
5942 buf_write_u8(buf, 43);
5943 buf_write_u8(buf, 6);/* total length field */
5944 buf_write_u8(buf, 0x001);
5945 buf_write_u8(buf, 4);/* length of the vendor specified field */
5946 buf_write_u32(buf, 0x002);
5947 }
5948 return !error;
5949}
5950
5951static void
5953{
5954 if (tt->options.dhcp_pre_release || tt->options.dhcp_renew)
5955 {
5956 struct gc_arena gc = gc_new();
5957 struct buffer cmd = alloc_buf_gc(256, &gc);
5958 const int verb = 3;
5959 const int pre_sleep = 1;
5960
5961 buf_printf(&cmd, "openvpn --verb %d --tap-sleep %d", verb, pre_sleep);
5962 if (tt->options.dhcp_pre_release)
5963 {
5964 buf_printf(&cmd, " --dhcp-pre-release");
5965 }
5966 if (tt->options.dhcp_renew)
5967 {
5968 buf_printf(&cmd, " --dhcp-renew");
5969 }
5970 buf_printf(&cmd, " --dhcp-internal %lu", tt->adapter_index);
5971
5973 gc_free(&gc);
5974 }
5975}
5976
5977static void
5979{
5980 HANDLE msg_channel = tt->options.msg_channel;
5982 struct gc_arena gc = gc_new();
5983
5984 message_header_t rdns = { msg_register_dns, sizeof(message_header_t), 0 };
5985
5986 if (!send_msg_iservice(msg_channel, &rdns, sizeof(rdns), &ack, "Register_dns"))
5987 {
5988 gc_free(&gc);
5989 return;
5990 }
5991
5992 else if (ack.error_number != NO_ERROR)
5993 {
5994 msg(M_WARN, "Register_dns failed using service: %s [status=0x%x]",
5996 }
5997
5998 else
5999 {
6000 msg(M_INFO, "Register_dns request sent to the service");
6001 }
6002
6003 gc_free(&gc);
6004}
6005
6006static bool
6008{
6009 HANDLE msg_channel = tt->options.msg_channel;
6010 ack_message_t ack;
6011 bool ret = true;
6012 struct gc_arena gc = gc_new();
6013
6015 .header = {
6018 0
6019 },
6020 .device = tt->hand,
6021 .send_ring_handle = tt->wintun_send_ring_handle,
6022 .receive_ring_handle = tt->wintun_receive_ring_handle,
6023 .send_tail_moved = tt->rw_handle.read,
6024 .receive_tail_moved = tt->rw_handle.write
6025 };
6026
6027 if (!send_msg_iservice(msg_channel, &msg, sizeof(msg), &ack, "Register ring buffers"))
6028 {
6029 ret = false;
6030 }
6031 else if (ack.error_number != NO_ERROR)
6032 {
6033 msg(M_NONFATAL, "Register ring buffers failed using service: %s [status=0x%x]",
6035 ret = false;
6036 }
6037 else
6038 {
6039 msg(M_INFO, "Ring buffers registered via service");
6040 }
6041
6042 gc_free(&gc);
6043 return ret;
6044}
6045
6046void
6048{
6049 if (tt && tt->options.register_dns && tt->options.msg_channel)
6050 {
6052 }
6053 else if (tt && tt->options.register_dns)
6054 {
6055 struct gc_arena gc = gc_new();
6056 struct buffer cmd = alloc_buf_gc(256, &gc);
6057 const int verb = 3;
6058
6059 buf_printf(&cmd, "openvpn --verb %d --register-dns --rdns-internal", verb);
6061 gc_free(&gc);
6062 }
6063}
6064
6065static uint32_t
6066dhcp_masq_addr(const in_addr_t local, const in_addr_t netmask, const int offset)
6067{
6068 struct gc_arena gc = gc_new();
6069 in_addr_t dsa; /* DHCP server addr */
6070
6071 if (offset < 0)
6072 {
6073 dsa = (local | (~netmask)) + offset;
6074 }
6075 else
6076 {
6077 dsa = (local & netmask) + offset;
6078 }
6079
6080 if (dsa == local)
6081 {
6082 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));
6083 }
6084
6085 if ((local & netmask) != (dsa & netmask))
6086 {
6087 msg(M_FATAL, "ERROR: --ip-win32 dynamic [offset] : offset is outside of --ifconfig subnet");
6088 }
6089
6090 gc_free(&gc);
6091 return htonl(dsa);
6092}
6093
6094static void
6096{
6097 ULONG info[3];
6098 DWORD len;
6099 CLEAR(info);
6100 if (DeviceIoControl(tt->hand, TAP_WIN_IOCTL_GET_VERSION,
6101 &info, sizeof(info),
6102 &info, sizeof(info), &len, NULL))
6103 {
6104 msg(D_TUNTAP_INFO, "TAP-Windows Driver Version %d.%d %s",
6105 (int)info[0],
6106 (int)info[1],
6107 (info[2] ? "(DEBUG)" : ""));
6108
6109 }
6110 if (!(info[0] == TAP_WIN_MIN_MAJOR && info[1] >= TAP_WIN_MIN_MINOR))
6111 {
6112 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.",
6113 TAP_WIN_MIN_MAJOR,
6114 TAP_WIN_MIN_MINOR);
6115 }
6116
6117 /* usage of numeric constants is ugly, but this is really tied to
6118 * *this* version of the driver
6119 */
6120 if (tt->type == DEV_TYPE_TUN
6121 && info[0] == 9 && info[1] < 8)
6122 {
6123 msg(M_INFO, "WARNING: Tap-Win32 driver version %d.%d does not support IPv6 in TUN mode. IPv6 will not work. Upgrade your Tap-Win32 driver.", (int)info[0], (int)info[1]);
6124 }
6125
6126 /* tap driver 9.8 (2.2.0 and 2.2.1 release) is buggy
6127 */
6128 if (tt->type == DEV_TYPE_TUN
6129 && info[0] == 9 && info[1] == 8)
6130 {
6131 msg(M_FATAL, "ERROR: Tap-Win32 driver version %d.%d is buggy regarding small IPv4 packets in TUN mode. Upgrade your Tap-Win32 driver.", (int)info[0], (int)info[1]);
6132 }
6133}
6134
6135static void
6137{
6138 ULONG mtu = 0;
6139 DWORD len;
6140 if (DeviceIoControl(tt->hand, TAP_WIN_IOCTL_GET_MTU,
6141 &mtu, sizeof(mtu),
6142 &mtu, sizeof(mtu), &len, NULL))
6143 {
6144 msg(D_MTU_INFO, "TAP-Windows MTU=%d", (int)mtu);
6145 }
6146}
6147
6148static void
6150 const char *device_guid,
6151 bool dhcp_masq_post)
6152{
6153 struct gc_arena gc = gc_new();
6154 const DWORD index = tt->adapter_index;
6155
6156 /* flush arp cache */
6158 && index != TUN_ADAPTER_INDEX_INVALID)
6159 {
6160 DWORD status = -1;
6161
6162 if (tt->options.msg_channel)
6163 {
6164 ack_message_t ack;
6166 .header = {
6169 0
6170 },
6171 .family = AF_INET,
6172 .iface = {.index = index, .name = "" }
6173 };
6174
6175 if (send_msg_iservice(tt->options.msg_channel, &msg, sizeof(msg),
6176 &ack, "TUN"))
6177 {
6178 status = ack.error_number;
6179 }
6180 }
6181 else
6182 {
6183 status = FlushIpNetTable(index);
6184 }
6185
6186 if (status == NO_ERROR)
6187 {
6188 msg(M_INFO, "Successful ARP Flush on interface [%lu] %s",
6189 index,
6190 device_guid);
6191 }
6192 else if (status != -1)
6193 {
6194 msg(D_TUNTAP_INFO, "NOTE: FlushIpNetTable failed on interface [%lu] %s (status=%lu) : %s",
6195 index,
6196 device_guid,
6197 status,
6199 }
6200
6201 /*
6202 * If the TAP-Windows driver is masquerading as a DHCP server
6203 * make sure the TCP/IP properties for the adapter are
6204 * set correctly.
6205 */
6206 if (dhcp_masq_post)
6207 {
6208 /* check dhcp enable status */
6209 if (dhcp_status(index) == DHCP_STATUS_DISABLED)
6210 {
6211 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'");
6212 }
6213
6214 /* force an explicit DHCP lease renewal on TAP adapter? */
6215 if (tt->options.dhcp_pre_release)
6216 {
6217 dhcp_release(tt);
6218 }
6219 if (tt->options.dhcp_renew)
6220 {
6221 dhcp_renew(tt);
6222 }
6223 }
6224 else
6225 {
6226 fork_dhcp_action(tt);
6227 }
6228 }
6229
6231 {
6232 DWORD status;
6233 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')";
6234
6235 /* couldn't get adapter index */
6236 if (index == TUN_ADAPTER_INDEX_INVALID)
6237 {
6238 msg(M_FATAL, "ERROR: unable to get adapter index for interface %s -- %s",
6239 device_guid,
6240 error_suffix);
6241 }
6242
6243 /* check dhcp enable status */
6244 if (dhcp_status(index) == DHCP_STATUS_DISABLED)
6245 {
6246 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'");
6247 }
6248
6249 /* delete previously added IP addresses which were not
6250 * correctly deleted */
6251 delete_temp_addresses(index);
6252
6253 /* add a new IP address */
6254 if ((status = AddIPAddress(htonl(tt->local),
6255 htonl(tt->adapter_netmask),
6256 index,
6257 &tt->ipapi_context,
6258 &tt->ipapi_instance)) == NO_ERROR)
6259 {
6260 msg(M_INFO, "Succeeded in adding a temporary IP/netmask of %s/%s to interface %s using the Win32 IP Helper API",
6261 print_in_addr_t(tt->local, 0, &gc),
6263 device_guid
6264 );
6265 }
6266 else
6267 {
6268 msg(M_FATAL, "ERROR: AddIPAddress %s/%s failed on interface %s, index=%lu, status=%lu (windows error: '%s') -- %s",
6269 print_in_addr_t(tt->local, 0, &gc),
6271 device_guid,
6272 index,
6273 status,
6275 error_suffix);
6276 }
6277 tt->ipapi_context_defined = true;
6278 }
6279
6280 gc_free(&gc);
6281}
6282
6283static bool
6284wintun_register_ring_buffer(struct tuntap *tt, const char *device_guid)
6285{
6286 bool ret = true;
6287
6288 tt->wintun_send_ring = (struct tun_ring *)MapViewOfFile(tt->wintun_send_ring_handle,
6289 FILE_MAP_ALL_ACCESS,
6290 0,
6291 0,
6292 sizeof(struct tun_ring));
6293
6294 tt->wintun_receive_ring = (struct tun_ring *)MapViewOfFile(tt->wintun_receive_ring_handle,
6295 FILE_MAP_ALL_ACCESS,
6296 0,
6297 0,
6298 sizeof(struct tun_ring));
6299
6300 if (tt->options.msg_channel)
6301 {
6303 }
6304 else
6305 {
6306 if (!register_ring_buffers(tt->hand,
6307 tt->wintun_send_ring,
6309 tt->rw_handle.read,
6310 tt->rw_handle.write))
6311 {
6312 switch (GetLastError())
6313 {
6314 case ERROR_ACCESS_DENIED:
6315 msg(M_FATAL, "ERROR: Wintun requires SYSTEM privileges and therefore "
6316 "should be used with interactive service. If you want to "
6317 "use openvpn from command line, you need to do SYSTEM "
6318 "elevation yourself (for example with psexec).");
6319 break;
6320
6321 case ERROR_ALREADY_INITIALIZED:
6322 msg(M_NONFATAL, "Adapter %s is already in use", device_guid);
6323 break;
6324
6325 default:
6326 msg(M_NONFATAL | M_ERRNO, "Failed to register ring buffers");
6327 }
6328 ret = false;
6329 }
6330
6331 }
6332 return ret;
6333}
6334
6335static void
6337{
6338 ULONG status = TRUE;
6339 DWORD len;
6340 if (!DeviceIoControl(tt->hand, TAP_WIN_IOCTL_SET_MEDIA_STATUS,
6341 &status, sizeof(status),
6342 &status, sizeof(status), &len, NULL))
6343 {
6344 msg(M_WARN, "WARNING: The TAP-Windows driver rejected a TAP_WIN_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
6345 }
6346
6347 int s = tt->options.tap_sleep;
6348 if (s > 0)
6349 {
6350 msg(M_INFO, "Sleeping for %d seconds...", s);
6352 }
6353}
6354
6355static void
6356tuntap_set_ptp(const struct tuntap *tt)
6357{
6358 DWORD len;
6359 struct gc_arena gc = gc_new();
6360
6362 {
6363 msg(M_FATAL, "ERROR: --dev tun also requires --ifconfig");
6364 }
6365
6366 /* send 0/0/0 to the TAP driver even if we have no IPv4 configured to
6367 * ensure it is somehow initialized.
6368 */
6369 if (!tt->did_ifconfig_setup || tt->topology == TOP_SUBNET)
6370 {
6371 in_addr_t ep[3];
6372 BOOL status;
6373
6374 ep[0] = htonl(tt->local);
6375 ep[1] = htonl(tt->local & tt->remote_netmask);
6376 ep[2] = htonl(tt->remote_netmask);
6377
6378 status = DeviceIoControl(tt->hand, TAP_WIN_IOCTL_CONFIG_TUN,
6379 ep, sizeof(ep),
6380 ep, sizeof(ep), &len, NULL);
6381
6382 if (tt->did_ifconfig_setup)
6383 {
6384 msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
6388 status ? "SUCCEEDED" : "FAILED");
6389 }
6390 else
6391 {
6392 msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN with fake IPv4 [%s]",
6393 status ? "SUCCEEDED" : "FAILED");
6394 }
6395 }
6396 else
6397 {
6398 in_addr_t ep[2];
6399 ep[0] = htonl(tt->local);
6400 ep[1] = htonl(tt->remote_netmask);
6401
6402 if (!DeviceIoControl(tt->hand, TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT,
6403 ep, sizeof(ep),
6404 ep, sizeof(ep), &len, NULL))
6405 {
6406 msg(M_FATAL, "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun");
6407 }
6408 }
6409
6410 gc_free(&gc);
6411}
6412
6413static void
6414tuntap_dhcp_mask(const struct tuntap *tt, const char *device_guid)
6415{
6416 struct gc_arena gc = gc_new();
6417 DWORD len;
6418 uint32_t ep[4];
6419
6420 /* We will answer DHCP requests with a reply to set IP/subnet to these values */
6421 ep[0] = htonl(tt->local);
6422 ep[1] = htonl(tt->adapter_netmask);
6423
6424 /* At what IP address should the DHCP server masquerade at? */
6425 if (tt->type == DEV_TYPE_TUN)
6426 {
6427 if (tt->topology == TOP_SUBNET)
6428 {
6430 }
6431 else
6432 {
6433 ep[2] = htonl(tt->remote_netmask);
6434 }
6435 }
6436 else
6437 {
6438 ASSERT(tt->type == DEV_TYPE_TAP);
6440 }
6441
6442 /* lease time in seconds */
6443 ep[3] = (uint32_t)tt->options.dhcp_lease_time;
6444
6445 ASSERT(ep[3] > 0);
6446
6447#ifndef SIMULATE_DHCP_FAILED /* this code is disabled to simulate bad DHCP negotiation */
6448 if (!DeviceIoControl(tt->hand, TAP_WIN_IOCTL_CONFIG_DHCP_MASQ,
6449 ep, sizeof(ep),
6450 ep, sizeof(ep), &len, NULL))
6451 {
6452 msg(M_FATAL, "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode");
6453 }
6454
6455 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]",
6456 print_in_addr_t(tt->local, 0, &gc),
6458 device_guid,
6460 ep[3]
6461 );
6462
6463 /* user-supplied DHCP options capability */
6464 if (tt->options.dhcp_options)
6465 {
6466 struct buffer buf = alloc_buf(256);
6467 if (build_dhcp_options_string(&buf, &tt->options))
6468 {
6469 msg(D_DHCP_OPT, "DHCP option string: %s", format_hex(BPTR(&buf), BLEN(&buf), 0, &gc));
6471 BPTR(&buf), BLEN(&buf),
6472 BPTR(&buf), BLEN(&buf), &len, NULL))
6473 {
6474 msg(M_FATAL, "ERROR: The TAP-Windows driver rejected a TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call");
6475 }
6476 }
6477 else
6478 {
6479 msg(M_WARN, "DHCP option string not set due to error");
6480 }
6481 free_buf(&buf);
6482 }
6483#endif /* ifndef SIMULATE_DHCP_FAILED */
6484
6485 gc_free(&gc);
6486}
6487
6488static bool
6490{
6491 const char *path = NULL;
6492 char tuntap_device_path[256];
6493
6494 if (tt->backend_driver == WINDOWS_DRIVER_WINTUN
6495 || tt->backend_driver == DRIVER_DCO)
6496 {
6497 const struct device_instance_id_interface *dev_if;
6498
6499 for (dev_if = device_instance_id_interface; dev_if != NULL; dev_if = dev_if->next)
6500 {
6501 if (strcmp((const char *)dev_if->net_cfg_instance_id, device_guid) != 0)
6502 {
6503 continue;
6504 }
6505
6506 if (tt->backend_driver == DRIVER_DCO)
6507 {
6508 char *last_sep = strrchr(dev_if->device_interface, '\\');
6509 if (!last_sep
6510 || strcmp(last_sep + 1, DCO_WIN_REFERENCE_STRING) != 0)
6511 {
6512 continue;
6513 }
6514 }
6515
6516 path = dev_if->device_interface;
6517 break;
6518 }
6519 if (path == NULL)
6520 {
6521 return false;
6522 }
6523 }
6524 else
6525 {
6526 /* Open TAP-Windows */
6527 snprintf(tuntap_device_path, sizeof(tuntap_device_path), "%s%s%s",
6528 USERMODEDEVICEDIR,
6529 device_guid,
6530 TAP_WIN_SUFFIX);
6531 path = tuntap_device_path;
6532 }
6533
6534 msg(D_TAP_WIN_DEBUG, "Using device interface: %s", path);
6535
6536 tt->hand = CreateFile(path,
6537 GENERIC_READ | GENERIC_WRITE,
6538 0, /* was: FILE_SHARE_READ */
6539 0,
6540 OPEN_EXISTING,
6541 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
6542 0);
6543 if (tt->hand == INVALID_HANDLE_VALUE)
6544 {
6545 msg(D_TUNTAP_INFO | M_ERRNO, "CreateFile failed on %s device: %s", print_tun_backend_driver(tt->backend_driver), path);
6546 return false;
6547 }
6548
6550 {
6551 /* Wintun adapter may be considered "open" after ring buffers are successfuly registered. */
6552 if (!wintun_register_ring_buffer(tt, device_guid))
6553 {
6554 msg(D_TUNTAP_INFO, "Failed to register %s adapter ring buffers", device_guid);
6555 CloseHandle(tt->hand);
6556 tt->hand = NULL;
6557 return false;
6558 }
6559 }
6560
6561 return true;
6562}
6563
6564void
6565tun_open_device(struct tuntap *tt, const char *dev_node, const char **device_guid, struct gc_arena *gc)
6566{
6567 const struct tap_reg *tap_reg = get_tap_reg(gc);
6568 const struct panel_reg *panel_reg = get_panel_reg(gc);
6570 uint8_t actual_buffer[256];
6571
6573
6574 /*
6575 * Lookup the device name in the registry, using the --dev-node high level name.
6576 */
6577 if (dev_node)
6578 {
6579 enum tun_driver_type windows_driver = WINDOWS_DRIVER_UNSPECIFIED;
6580
6581 /* Get the device GUID for the device specified with --dev-node. */
6582 *device_guid = get_device_guid(dev_node, actual_buffer, sizeof(actual_buffer), &windows_driver, tap_reg, panel_reg, gc);
6583
6584 if (!*device_guid)
6585 {
6586 msg(M_FATAL, "Adapter '%s' not found", dev_node);
6587 }
6588
6589 if (tt->backend_driver != windows_driver)
6590 {
6591 msg(M_FATAL, "Adapter '%s' is using %s driver, %s expected. If you want to use this device, adjust --windows-driver.",
6592 dev_node, print_tun_backend_driver(windows_driver), print_tun_backend_driver(tt->backend_driver));
6593 }
6594
6595 if (!tun_try_open_device(tt, *device_guid, device_instance_id_interface))
6596 {
6597 msg(M_FATAL, "Failed to open %s adapter: %s", print_tun_backend_driver(tt->backend_driver), dev_node);
6598 }
6599 }
6600 else
6601 {
6602 int device_number = 0;
6603
6604 /* Try opening all TAP devices until we find one available */
6605 while (true)
6606 {
6607 enum tun_driver_type windows_driver = WINDOWS_DRIVER_UNSPECIFIED;
6608 *device_guid = get_unspecified_device_guid(device_number,
6609 actual_buffer,
6610 sizeof(actual_buffer),
6611 tap_reg,
6612 panel_reg,
6613 &windows_driver,
6614 gc);
6615
6616 if (!*device_guid)
6617 {
6618 msg(M_FATAL, "All %s adapters on this system are currently in use or disabled.", print_tun_backend_driver(tt->backend_driver));
6619 }
6620
6621 if (tt->backend_driver != windows_driver)
6622 {
6623 goto next;
6624 }
6625
6627 {
6628 break;
6629 }
6630
6631next:
6632 device_number++;
6633 }
6634 }
6635
6636 /* translate high-level device name into a device instance
6637 * GUID using the registry */
6638 tt->actual_name = string_alloc((const char *)actual_buffer, NULL);
6639
6640 tt->adapter_index = get_adapter_index(*device_guid);
6641}
6642
6643static void
6644tuntap_set_ip_props(const struct tuntap *tt, bool *dhcp_masq, bool *dhcp_masq_post)
6645{
6647 {
6648 /*
6649 * If adapter is set to non-DHCP, set to DHCP mode.
6650 */
6652 {
6653 /* try using the service if available, else directly execute netsh */
6654 if (tt->options.msg_channel)
6655 {
6657 }
6658 else
6659 {
6661 }
6662 }
6663 *dhcp_masq = true;
6664 *dhcp_masq_post = true;
6665 }
6667 {
6668 /*
6669 * If adapter is set to non-DHCP, use netsh right away.
6670 */
6672 {
6674 tt->adapter_index,
6675 tt->local,
6676 tt->adapter_netmask,
6678 }
6679 else
6680 {
6681 *dhcp_masq = true;
6682 }
6683 }
6684}
6685
6686static void
6687tuntap_post_open(struct tuntap *tt, const char *device_guid)
6688{
6689 bool dhcp_masq = false;
6690 bool dhcp_masq_post = false;
6691
6693 {
6694 /* get driver version info */
6696
6697 /* get driver MTU */
6698 tuntap_get_mtu(tt);
6699
6700 /*
6701 * Preliminaries for setting TAP-Windows adapter TCP/IP
6702 * properties via --ip-win32 dynamic or --ip-win32 adaptive.
6703 */
6704 if (tt->did_ifconfig_setup)
6705 {
6706 tuntap_set_ip_props(tt, &dhcp_masq, &dhcp_masq_post);
6707 }
6708
6709 /* set point-to-point mode if TUN device */
6710 if (tt->type == DEV_TYPE_TUN)
6711 {
6712 tuntap_set_ptp(tt);
6713 }
6714
6715 /* should we tell the TAP-Windows driver to masquerade as a DHCP server as a means
6716 * of setting the adapter address? */
6717 if (dhcp_masq)
6718 {
6719 tuntap_dhcp_mask(tt, device_guid);
6720 }
6721
6722 /* set driver media status to 'connected' */
6724 }
6725
6726 /* possibly use IP Helper API to set IP address on adapter */
6727 tuntap_set_ip_addr(tt, device_guid, dhcp_masq_post);
6728}
6729
6730void
6731open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
6732 openvpn_net_ctx_t *ctx)
6733{
6736 {
6737 msg(M_WARN, "Some --dhcp-option or --dns options require DHCP server,"
6738 " which is not supported by the selected %s driver. They will be"
6739 " ignored.", print_tun_backend_driver(tt->backend_driver));
6740 }
6741
6742 /* dco-win already opened the device, which handle we treat as socket */
6743 if (tuntap_is_dco_win(tt))
6744 {
6745 return;
6746 }
6747
6748 const char *device_guid = NULL;
6749
6750 /*netcmd_semaphore_lock ();*/
6751
6752 msg( M_INFO, "open_tun");
6753
6754 if (tt->type != DEV_TYPE_TAP && tt->type != DEV_TYPE_TUN)
6755 {
6756 msg(M_FATAL|M_NOPREFIX, "Unknown virtual device type: '%s'", dev);
6757 }
6758
6759 struct gc_arena gc = gc_new(); /* used also for device_guid allocation */
6760 tun_open_device(tt, dev_node, &device_guid, &gc);
6761
6762 tuntap_post_open(tt, device_guid);
6763
6764 gc_free(&gc);
6765
6766 /*netcmd_semaphore_release ();*/
6767}
6768
6769const char *
6770tap_win_getinfo(const struct tuntap *tt, struct gc_arena *gc)
6771{
6773 {
6774 struct buffer out = alloc_buf_gc(256, gc);
6775 DWORD len;
6777 BSTR(&out), BCAP(&out),
6778 BSTR(&out), BCAP(&out),
6779 &len, NULL))
6780 {
6781 return BSTR(&out);
6782 }
6783 }
6784 return NULL;
6785}
6786
6787void
6789{
6790 if (tt->backend_driver == WINDOWS_DRIVER_TAP_WINDOWS6)
6791 {
6792 struct buffer out = alloc_buf(1024);
6793 DWORD len;
6795 BSTR(&out), BCAP(&out),
6796 BSTR(&out), BCAP(&out),
6797 &len, NULL))
6798 {
6799 msg(D_TAP_WIN_DEBUG, "TAP-Windows: %s", BSTR(&out));
6800 }
6801 free_buf(&out);
6802 }
6803}
6804
6805static void
6806netsh_delete_address_dns(const struct tuntap *tt, bool ipv6, struct gc_arena *gc)
6807{
6808 const char *ifconfig_ip_local;
6809 struct argv argv = argv_new();
6810
6811 /* delete ipvX dns servers if any were set */
6812 int len = ipv6 ? tt->options.dns6_len : tt->options.dns_len;
6813 if (len > 0)
6814 {
6816 "%s%s interface %s delete dns %lu all",
6819 ipv6 ? "ipv6" : "ipv4",
6820 tt->adapter_index);
6822 }
6823
6824 if (!ipv6 && tt->options.wins_len > 0)
6825 {
6827 "%s%s interface ipv4 delete winsservers %lu all",
6830 tt->adapter_index);
6832 }
6833
6834 if (ipv6 && tt->type == DEV_TYPE_TUN)
6835 {
6837 }
6838
6839 /* "store=active" is needed in Windows 8(.1) to delete the
6840 * address we added (pointed out by Cedric Tabary).
6841 */
6842
6843 /* netsh interface ipvX delete address %lu %s */
6844 if (ipv6)
6845 {
6846 ifconfig_ip_local = print_in6_addr(tt->local_ipv6, 0, gc);
6847 }
6848 else
6849 {
6850 ifconfig_ip_local = print_in_addr_t(tt->local, 0, gc);
6851 }
6853 "%s%s interface %s delete address %lu %s store=active",
6856 ipv6 ? "ipv6" : "ipv4",
6857 tt->adapter_index,
6858 ifconfig_ip_local);
6860
6861 argv_free(&argv);
6862}
6863
6864void
6866{
6867 const char *adaptertype = print_tun_backend_driver(tt->backend_driver);
6868
6869 if (tt->hand)
6870 {
6871 dmsg(D_WIN32_IO_LOW, "Attempting CancelIO on %s adapter", adaptertype);
6872 if (!CancelIo(tt->hand))
6873 {
6874 msg(M_WARN | M_ERRNO, "Warning: CancelIO failed on %s adapter", adaptertype);
6875 }
6876 }
6877
6878 dmsg(D_WIN32_IO_LOW, "Attempting close of overlapped read event on %s adapter", adaptertype);
6880
6881 dmsg(D_WIN32_IO_LOW, "Attempting close of overlapped write event on %s adapter", adaptertype);
6883
6884 if (tt->hand)
6885 {
6886 dmsg(D_WIN32_IO_LOW, "Attempting CloseHandle on %s adapter", adaptertype);
6887 if (!CloseHandle(tt->hand))
6888 {
6889 msg(M_WARN | M_ERRNO, "Warning: CloseHandle failed on %s adapter", adaptertype);
6890 }
6891 tt->hand = NULL;
6892 }
6893
6895 {
6896 CloseHandle(tt->rw_handle.read);
6897 CloseHandle(tt->rw_handle.write);
6898 UnmapViewOfFile(tt->wintun_send_ring);
6899 UnmapViewOfFile(tt->wintun_receive_ring);
6900 CloseHandle(tt->wintun_send_ring_handle);
6901 CloseHandle(tt->wintun_receive_ring_handle);
6902 }
6903}
6904
6905void
6907{
6908 ASSERT(tt);
6909
6910 struct gc_arena gc = gc_new();
6911
6913 {
6915 {
6916 /* We didn't do ifconfig. */
6917 }
6918 else if (tt->options.msg_channel)
6919 {
6920 /* If IPv4 is not enabled, delete DNS domain here */
6921 if (!tt->did_ifconfig_setup)
6922 {
6923 do_dns_domain_service(false, tt);
6924 }
6925 do_dns_service(false, AF_INET6, tt);
6927 do_address_service(false, AF_INET6, tt);
6928 }
6929 else
6930 {
6931 if (!tt->did_ifconfig_setup)
6932 {
6933 do_dns_domain_wmic(false, tt);
6934 }
6935
6936 netsh_delete_address_dns(tt, true, &gc);
6937 }
6938 }
6939
6940 if (tt->did_ifconfig_setup)
6941 {
6943 {
6944 /* We didn't do ifconfig. */
6945 }
6947 {
6948 /* We don't have to clean the configuration with DHCP. */
6949 }
6950 else if (tt->options.msg_channel)
6951 {
6952 do_wins_service(false, tt);
6953 do_dns_domain_service(false, tt);
6954 do_dns_service(false, AF_INET, tt);
6955 do_address_service(false, AF_INET, tt);
6956 }
6957 else
6958 {
6959 do_dns_domain_wmic(false, tt);
6960
6962 {
6963 netsh_delete_address_dns(tt, false, &gc);
6964 }
6965 }
6966 }
6967
6968 if (tt->ipapi_context_defined)
6969 {
6970 DWORD status;
6971 if ((status = DeleteIPAddress(tt->ipapi_context)) != NO_ERROR)
6972 {
6973 msg(M_WARN, "Warning: DeleteIPAddress[%u] failed on TAP-Windows adapter, status=%u : %s",
6974 (unsigned int)tt->ipapi_context,
6975 (unsigned int)status,
6977 }
6978 }
6979
6980 dhcp_release(tt);
6981
6982 close_tun_handle(tt);
6983
6984 free(tt->actual_name);
6985
6986 clear_tuntap(tt);
6987 free(tt);
6988 gc_free(&gc);
6989}
6990
6991/*
6992 * Convert --ip-win32 constants between index and ascii form.
6993 */
6994
6996 const char *short_form;
6997};
6998
6999/* Indexed by IPW32_SET_x */
7000static const struct ipset_names ipset_names[] = {
7001 {"manual"},
7002 {"netsh"},
7003 {"ipapi"},
7004 {"dynamic"},
7005 {"adaptive"}
7006};
7007
7008int
7009ascii2ipset(const char *name)
7010{
7011 int i;
7013 for (i = 0; i < IPW32_SET_N; ++i)
7014 {
7015 if (!strcmp(name, ipset_names[i].short_form))
7016 {
7017 return i;
7018 }
7019 }
7020 return -1;
7021}
7022
7023const char *
7024ipset2ascii(int index)
7025{
7027 if (index < 0 || index >= IPW32_SET_N)
7028 {
7029 return "[unknown --ip-win32 type]";
7030 }
7031 else
7032 {
7033 return ipset_names[index].short_form;
7034 }
7035}
7036
7037const char *
7039{
7040 struct buffer out = alloc_buf_gc(256, gc);
7041 int i;
7042
7044 for (i = 0; i < IPW32_SET_N; ++i)
7045 {
7046 if (i)
7047 {
7048 buf_printf(&out, " ");
7049 }
7050 buf_printf(&out, "[%s]", ipset2ascii(i));
7051 }
7052 return BSTR(&out);
7053}
7054
7055#else /* generic */
7056
7057void
7058open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
7059 openvpn_net_ctx_t *ctx)
7060{
7061 open_tun_generic(dev, dev_type, dev_node, tt);
7062}
7063
7064void
7065close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
7066{
7067 ASSERT(tt);
7068
7070 free(tt);
7071}
7072
7073int
7074write_tun(struct tuntap *tt, uint8_t *buf, int len)
7075{
7076 return write(tt->fd, buf, len);
7077}
7078
7079int
7080read_tun(struct tuntap *tt, uint8_t *buf, int len)
7081{
7082 return read(tt->fd, buf, len);
7083}
7084
7085#endif /* if defined (TARGET_ANDROID) */
void argv_msg(const int msglev, const struct argv *a)
Write the arguments stored in a struct argv via the msg() command.
Definition argv.c:243
void argv_msg_prefix(const int msglev, const struct argv *a, const char *prefix)
Similar to argv_msg() but prefixes the messages being written with a given string.
Definition argv.c:260
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
Definition argv.c:102
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
Definition argv.c:440
bool argv_printf_cat(struct argv *argres, const char *format,...)
printf() inspired argv concatenation.
Definition argv.c:464
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
Definition argv.c:88
void free_buf(struct buffer *buf)
Definition buffer.c:183
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:240
char * format_hex_ex(const uint8_t *data, int size, int maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
Definition buffer.c:483
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition buffer.c:336
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:88
struct buffer alloc_buf(size_t size)
Definition buffer.c:62
char * string_alloc(const char *str, struct gc_arena *gc)
Definition buffer.c:649
static bool has_digit(const char *src)
Definition buffer.h:372
#define ALLOC_OBJ(dptr, type)
Definition buffer.h:1055
static char * format_hex(const uint8_t *data, int size, int maxoutput, struct gc_arena *gc)
Definition buffer.h:505
#define BSTR(buf)
Definition buffer.h:129
static struct buffer clear_buf(void)
Return an empty struct buffer.
Definition buffer.h:222
static bool buf_copy(struct buffer *dest, const struct buffer *src)
Definition buffer.h:712
#define BPTR(buf)
Definition buffer.h:124
static bool buf_write_u32(struct buffer *dest, uint32_t data)
Definition buffer.h:705
static bool buf_safe(const struct buffer *buf, size_t len)
Definition buffer.h:520
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
Definition buffer.h:331
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition buffer.h:668
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Definition buffer.h:692
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Definition buffer.h:1097
#define BLEN(buf)
Definition buffer.h:127
#define BCAP(buf)
Definition buffer.h:130
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition buffer.h:361
static void check_malloc_return(void *p)
Definition buffer.h:1103
static void gc_free(struct gc_arena *a)
Definition buffer.h:1033
static struct gc_arena gc_new(void)
Definition buffer.h:1025
static int open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev)
Definition dco.h:306
static void close_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx)
Definition dco.h:312
void env_set_destroy(struct env_set *es)
Definition env_set.c:166
void setenv_int(struct env_set *es, const char *name, int value)
Definition env_set.c:267
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition env_set.c:283
void env_set_add(struct env_set *es, const char *str)
Definition env_set.c:193
struct env_set * env_set_create(struct gc_arena *gc)
Definition env_set.c:156
#define D_TAP_WIN_DEBUG
Definition errlevel.h:115
#define D_REGISTRY
Definition errlevel.h:178
#define D_IFCONFIG
Definition errlevel.h:93
#define D_ROUTE_DEBUG
Definition errlevel.h:133
#define D_WIN32_IO_LOW
Definition errlevel.h:125
#define D_WIN32_IO
Definition errlevel.h:173
#define D_TUNTAP_INFO
Definition errlevel.h:81
#define D_MTU_INFO
Definition errlevel.h:105
#define D_READ_WRITE
Definition errlevel.h:167
#define D_OSBUF
Definition errlevel.h:91
#define D_LOW
Definition errlevel.h:97
#define M_INFO
Definition errlevel.h:55
#define D_DHCP_OPT
Definition errlevel.h:98
#define EVENT_WRITE
Definition event.h:40
#define EVENT_READ
Definition event.h:39
void set_nonblock(socket_descriptor_t fd)
Definition fdmisc.c:69
void set_cloexec(socket_descriptor_t fd)
Definition fdmisc.c:79
static SERVICE_STATUS status
Definition interactive.c:53
@ write
@ read
void management_set_state(struct management *man, const int state, const char *detail, const in_addr_t *tun_local_ip, const struct in6_addr *tun_local_ip6, const struct openvpn_sockaddr *local, const struct openvpn_sockaddr *remote)
Definition manage.c:2749
void management_sleep(const int n)
A sleep function that services the management layer for n seconds rather than doing nothing.
Definition manage.c:4117
#define OPENVPN_STATE_ASSIGN_IP
Definition manage.h:471
static void net_ctx_reset(openvpn_net_ctx_t *ctx)
Definition networking.h:57
static void net_ctx_free(openvpn_net_ctx_t *ctx)
Definition networking.h:63
void * openvpn_net_ctx_t
Definition networking.h:39
@ msg_del_address
Definition openvpn-msg.h:33
@ msg_add_wins_cfg
Definition openvpn-msg.h:47
@ msg_add_address
Definition openvpn-msg.h:32
@ msg_enable_dhcp
Definition openvpn-msg.h:44
@ msg_register_ring_buffers
Definition openvpn-msg.h:45
@ msg_del_wins_cfg
Definition openvpn-msg.h:48
@ msg_add_dns_cfg
Definition openvpn-msg.h:36
@ msg_register_dns
Definition openvpn-msg.h:43
@ msg_set_mtu
Definition openvpn-msg.h:46
@ msg_flush_neighbors
Definition openvpn-msg.h:40
@ msg_del_dns_cfg
Definition openvpn-msg.h:37
#define BOOL_CAST(x)
Definition basic.h:27
#define CLEAR(x)
Definition basic.h:33
#define SIZE(x)
Definition basic.h:30
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
Definition error.c:812
#define M_NOPREFIX
Definition error.h:97
#define M_FATAL
Definition error.h:89
#define M_NONFATAL
Definition error.h:90
#define dmsg(flags,...)
Definition error.h:148
#define M_ERR
Definition error.h:105
#define msg(flags,...)
Definition error.h:144
#define ASSERT(x)
Definition error.h:195
#define M_WARN
Definition error.h:91
#define M_ERRNO
Definition error.h:94
const char * print_topology(const int topology)
Definition options.c:4855
const char * time_string(time_t t, long usec, bool show_usec, struct gc_arena *gc)
Definition otime.c:108
bool platform_user_get(const char *username, struct platform_state_user *state)
Definition platform.c:79
bool platform_group_get(const char *groupname, struct platform_state_group *state)
Definition platform.c:123
#define DEV_TYPE_TAP
Definition proto.h:37
#define DEV_TYPE_UNDEF
Definition proto.h:35
#define DEV_TYPE_TUN
Definition proto.h:36
#define OPENVPN_IPH_GET_VER(v)
Definition proto.h:93
#define TOP_SUBNET
Definition proto.h:44
static bool register_ring_buffers(HANDLE device, struct tun_ring *send_ring, struct tun_ring *receive_ring, HANDLE send_tail_moved, HANDLE receive_tail_moved)
Registers ring buffers used to exchange data between userspace openvpn process and wintun kernel driv...
Definition ring_buffer.h:98
int netmask_to_netbits2(in_addr_t netmask)
Definition route.c:4139
bool add_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:1567
bool add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:1915
void get_default_gateway(struct route_gateway_info *rgi, in_addr_t dest, openvpn_net_ctx_t *ctx)
Retrieves the best gateway for a given destination based on the routing table.
Definition route.c:2785
void delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:2384
void route_ipv6_clear_host_bits(struct route_ipv6 *r6)
Definition route.c:1892
#define RGI_ADDR_DEFINED
Definition route.h:147
#define RT_ADDED
Definition route.h:114
#define RT_METRIC_DEFINED
Definition route.h:115
#define RT_DEFINED
Definition route.h:113
#define RGI_NETMASK_DEFINED
Definition route.h:148
int openvpn_execve_check(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message)
#define S_FATAL
Definition run_command.h:46
int sockethandle_finalize(sockethandle_t sh, struct overlapped_io *io, struct buffer *buf, struct link_socket_actual *from)
Definition socket.c:3905
const char * print_in6_addr(struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
Definition socket.c:2994
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
Definition socket.c:2974
in_addr_t getaddr(unsigned int flags, const char *hostname, int resolve_retry_seconds, bool *succeeded, struct signal_info *sig_info)
Translate an IPv4 addr or hostname from string form to in_addr_t.
Definition socket.c:195
#define GETADDR_FATAL
Definition socket.h:518
#define GETADDR_HOST_ORDER
Definition socket.h:519
#define GETADDR_FATAL_ON_SIGNAL
Definition socket.h:521
#define GETADDR_RESOLVE
Definition socket.h:517
#define IA_NET_ORDER
Definition socket.h:402
inet_address_t address
Definition openvpn-msg.h:75
message_header_t header
Definition openvpn-msg.h:73
interface_t iface
Definition openvpn-msg.h:77
Definition argv.h:35
Wrapper structure for dynamically allocated memory.
Definition buffer.h:61
uint8_t * data
Pointer to the allocated memory.
Definition buffer.h:68
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:66
int offset
Offset in bytes of the actual content within the allocated memory.
Definition buffer.h:64
Contains all state information for one tunnel.
Definition openvpn.h:474
const char * device_interface
Definition tun.h:439
struct device_instance_id_interface * next
Definition tun.h:440
Definition dhcp.h:53
char domains[512]
Definition openvpn-msg.h:93
message_header_t header
Definition openvpn-msg.h:91
inet_address_t addr[4]
Definition openvpn-msg.h:96
interface_t iface
Definition openvpn-msg.h:92
message_header_t header
Packet geometry parameters.
Definition mtu.h:98
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
struct gc_entry * list
First element of the linked list of gc_entry structures.
Definition buffer.h:118
char name[256]
Definition openvpn-msg.h:64
const char * short_form
Definition tun.c:6996
struct man_connection connection
Definition manage.h:339
uint8_t version_len
Definition proto.h:95
struct buffer buf
Definition win32.h:218
DWORD size
Definition win32.h:208
OVERLAPPED overlapped
Definition win32.h:207
struct buffer buf_init
Definition win32.h:217
int iostate
Definition win32.h:206
struct panel_reg * next
Definition tun.h:433
const char * name
Definition tun.h:431
const char * guid
Definition tun.h:432
in_addr_t netmask
Definition route.h:143
unsigned int flags
Definition route.h:153
struct route_gateway_address gateway
Definition route.h:168
int metric
Definition route.h:122
in_addr_t network
Definition route.h:119
in_addr_t netmask
Definition route.h:120
in_addr_t gateway
Definition route.h:121
unsigned int flags
Definition route.h:117
struct in6_addr gateway
Definition route.h:130
unsigned int netbits
Definition route.h:129
unsigned int flags
Definition route.h:127
struct in6_addr network
Definition route.h:128
int metric
Definition route.h:131
HANDLE write
Definition win32.h:81
HANDLE read
Definition win32.h:80
SECURITY_ATTRIBUTES sa
Definition win32.h:64
message_header_t header
interface_t iface
bool is_handle
Definition socket.h:290
Definition tun.h:423
struct tap_reg * next
Definition tun.h:426
enum tun_driver_type windows_driver
Definition tun.h:425
const char * guid
Definition tun.h:424
Wintun ring buffer See https://github.com/WireGuard/wintun#ring-layout.
Definition ring_buffer.h:51
int wins_len
Definition tun.h:119
struct in6_addr dns6[N_DHCP_ADDR]
Definition tun.h:143
int dns_len
Definition tun.h:115
int dns6_len
Definition tun.h:144
in_addr_t wins[N_DHCP_ADDR]
Definition tun.h:118
int tap_sleep
Definition tun.h:99
int dhcp_lease_time
Definition tun.h:96
in_addr_t dns[N_DHCP_ADDR]
Definition tun.h:114
bool dhcp_masq_custom_offset
Definition tun.h:94
const char * domain
Definition tun.h:105
bool dhcp_renew
Definition tun.h:138
HANDLE msg_channel
Definition tun.h:90
int dhcp_masq_offset
Definition tun.h:95
int ip_win32_type
Definition tun.h:87
bool dhcp_pre_release
Definition tun.h:139
bool register_dns
Definition tun.h:141
int dhcp_options
Definition tun.h:103
Definition tun.h:181
in_addr_t local
Definition tun.h:208
int type
Definition tun.h:183
ULONG ipapi_instance
Definition tun.h:225
int netbits_ipv6
Definition tun.h:213
DWORD adapter_index
Definition tun.h:230
struct rw_handle rw_handle
Definition tun.h:219
enum tun_driver_type backend_driver
The backend driver that used for this tun/tap device.
Definition tun.h:191
HANDLE wintun_receive_ring_handle
Definition tun.h:235
bool did_ifconfig_ipv6_setup
if the internal variables related to ifconfig-ipv6 of this struct have been set up.
Definition tun.h:199
struct tuntap_options options
Definition tun.h:203
struct in6_addr remote_ipv6
Definition tun.h:212
bool did_ifconfig_setup
if the internal variables related to ifconfig of this struct have been set up.
Definition tun.h:195
int topology
Definition tun.h:186
struct overlapped_io writes
Definition tun.h:218
in_addr_t adapter_netmask
Definition tun.h:226
HANDLE hand
Definition tun.h:216
struct tun_ring * wintun_receive_ring
Definition tun.h:237
struct overlapped_io reads
Definition tun.h:217
struct in6_addr local_ipv6
Definition tun.h:211
HANDLE wintun_send_ring_handle
Definition tun.h:234
ULONG ipapi_context
Definition tun.h:224
dco_context_t dco
Definition tun.h:249
char * actual_name
Definition tun.h:205
struct tun_ring * wintun_send_ring
Definition tun.h:236
in_addr_t remote_netmask
Definition tun.h:209
bool ipapi_context_defined
Definition tun.h:223
bool persistent_if
Definition tun.h:201
interface_t iface
inet_address_t addr[4]
message_header_t header
#define sleep(x)
Definition syshead.h:43
struct env_set * es
struct gc_arena gc
Definition test_ssl.c:155
static const char * get_unspecified_device_guid(const int device_number, uint8_t *actual_name, int actual_name_size, const struct tap_reg *tap_reg_src, const struct panel_reg *panel_reg_src, enum tun_driver_type *windows_driver, struct gc_arena *gc)
Definition tun.c:4302
void ipconfig_register_dns(const struct env_set *es)
Definition tun.c:5269
void tun_show_debug(struct tuntap *tt)
Definition tun.c:6788
static const struct tap_reg * get_tap_reg(struct gc_arena *gc)
Definition tun.c:3823
static DWORD get_adapter_index_method_1(const char *guid)
Definition tun.c:4899
static void tuntap_post_open(struct tuntap *tt, const char *device_guid)
Definition tun.c:6687
static bool do_address_service(const bool add, const short family, const struct tuntap *tt)
Definition tun.c:121
static void clear_tuntap(struct tuntap *tuntap)
Definition tun.c:1725
static const char * netsh_get_id(const char *dev_node, struct gc_arena *gc)
Definition tun.c:5693
void open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt, openvpn_net_ctx_t *ctx)
Definition tun.c:6731
int dev_type_enum(const char *dev, const char *dev_type)
Definition tun.c:467
static const struct panel_reg * get_panel_reg(struct gc_arena *gc)
Definition tun.c:3968
void close_tun_handle(struct tuntap *tt)
Definition tun.c:6865
void fork_register_dns_action(struct tuntap *tt)
Definition tun.c:6047
static bool test_adapter_ip_netmask(const IP_ADAPTER_INFO *ai, const in_addr_t ip, const in_addr_t netmask)
Definition tun.c:4638
static void do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu, const struct env_set *es, openvpn_net_ctx_t *ctx)
do_ifconfig_ipv6 - perform platform specific ifconfig6 commands
Definition tun.c:1065
static void netsh_enable_dhcp(DWORD adapter_index)
Definition tun.c:5595
static const GUID GUID_DEVINTERFACE_NET
Definition tun.c:92
#define NI_TEST_FIRST
Definition tun.c:96
bool dhcp_renew_by_adapter_index(const DWORD adapter_index)
Definition tun.c:5203
static void tuntap_get_version_info(const struct tuntap *tt)
Definition tun.c:6095
static bool service_enable_dhcp(const struct tuntap *tt)
Definition tun.c:5613
static void netsh_delete_address_dns(const struct tuntap *tt, bool ipv6, struct gc_arena *gc)
Definition tun.c:6806
int ascii2ipset(const char *name)
Definition tun.c:7009
const IP_ADAPTER_INFO * get_tun_adapter(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
Definition tun.c:4654
static void check_addr_clash(const char *name, int type, in_addr_t public, in_addr_t local, in_addr_t remote_netmask)
Definition tun.c:564
bool is_adapter_up(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
Definition tun.c:4667
static void tuntap_set_ptp(const struct tuntap *tt)
Definition tun.c:6356
static void undo_ifconfig_ipv4(struct tuntap *tt, openvpn_net_ctx_t *ctx)
Definition tun.c:1640
static void do_dns_domain_wmic(bool add, const struct tuntap *tt)
Definition tun.c:417
static bool tun_try_open_device(struct tuntap *tt, const char *device_guid, const struct device_instance_id_interface *device_instance_id_interface)
Definition tun.c:6489
static void write_dhcp_u8(struct buffer *buf, const int type, const int data, bool *error)
Definition tun.c:5769
static DWORD get_adapter_index(const char *guid)
Definition tun.c:4939
static void netsh_ifconfig(const struct tuntap_options *to, DWORD adapter_index, const in_addr_t ip, const in_addr_t netmask, const unsigned int flags)
Definition tun.c:5523
const IP_ADAPTER_INFO * get_adapter_info(DWORD index, struct gc_arena *gc)
Definition tun.c:4569
static bool dhcp_release(const struct tuntap *tt)
Definition tun.c:5190
struct tuntap * init_tun(const char *dev, const char *dev_type, int topology, const char *ifconfig_local_parm, const char *ifconfig_remote_netmask_parm, const char *ifconfig_ipv6_local_parm, int ifconfig_ipv6_netbits_parm, const char *ifconfig_ipv6_remote_parm, struct addrinfo *local_public, struct addrinfo *remote_public, const bool strict_warn, struct env_set *es, openvpn_net_ctx_t *ctx, struct tuntap *tt)
Definition tun.c:794
static void fork_dhcp_action(struct tuntap *tt)
Definition tun.c:5952
const char * tun_stat(const struct tuntap *tt, unsigned int rwflags, struct gc_arena *gc)
Definition tun.c:691
static bool get_adapter_ip_netmask(const IP_ADAPTER_INFO *ai, const int n, in_addr_t *ip, in_addr_t *netmask)
Definition tun.c:4596
const IP_PER_ADAPTER_INFO * get_per_adapter_info(const DWORD index, struct gc_arena *gc)
Definition tun.c:4463
static void show_adapter(int msglev, const IP_ADAPTER_INFO *a, struct gc_arena *gc)
Definition tun.c:4979
static bool build_dhcp_options_string(struct buffer *buf, const struct tuntap_options *o)
Definition tun.c:5902
void show_tap_win_adapters(int msglev, int warnlev)
Definition tun.c:4157
static void ifconfig_sanity_check(bool tun_p2p, in_addr_t addr)
Definition tun.c:535
int tun_write_win32(struct tuntap *tt, struct buffer *buf)
Definition tun.c:3669
#define DHCP_STATUS_DISABLED
Definition tun.c:4826
static const char * get_device_guid(const char *name, uint8_t *actual_name, int actual_name_size, enum tun_driver_type *windows_driver, const struct tap_reg *tap_reg, const struct panel_reg *panel_reg, struct gc_arena *gc)
Definition tun.c:4368
bool is_ip_in_adapter_subnet(const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask)
Definition tun.c:4712
static void delete_temp_addresses(DWORD index)
Definition tun.c:4858
static void tuntap_set_ip_addr(struct tuntap *tt, const char *device_guid, bool dhcp_masq_post)
Definition tun.c:6149
const char * tap_win_getinfo(const struct tuntap *tt, struct gc_arena *gc)
Definition tun.c:6770
static const struct tap_reg * get_adapter_by_name(const char *name, const struct tap_reg *tap_reg, const struct panel_reg *panel_reg)
Definition tun.c:4271
void show_adapters(int msglev)
Definition tun.c:5012
static const IP_ADAPTER_INDEX_MAP * get_interface_info(DWORD index, struct gc_arena *gc)
Definition tun.c:4526
static const IP_INTERFACE_INFO * get_interface_info_list(struct gc_arena *gc)
Definition tun.c:4496
#define NI_OPTIONS
Definition tun.c:98
bool is_dev_type(const char *dev, const char *dev_type, const char *match_type)
Definition tun.c:449
static uint32_t dhcp_masq_addr(const in_addr_t local, const in_addr_t netmask, const int offset)
Definition tun.c:6066
#define DHCP_STATUS_UNDEF
Definition tun.c:4824
#define DHCP_STATUS_ENABLED
Definition tun.c:4825
static void netsh_ifconfig_options(const char *type, const in_addr_t *addr_list, const int addr_len, const IP_ADDR_STRING *current, DWORD adapter_index, const bool test_first)
Definition tun.c:5424
static void tuntap_set_ip_props(const struct tuntap *tt, bool *dhcp_masq, bool *dhcp_masq_post)
Definition tun.c:6644
static void register_dns_service(const struct tuntap *tt)
Definition tun.c:5978
static void do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu, const struct env_set *es, openvpn_net_ctx_t *ctx)
do_ifconfig_ipv4 - perform platform specific ifconfig commands
Definition tun.c:1264
int tun_write_queue(struct tuntap *tt, struct buffer *buf)
Definition tun.c:3606
bool dhcp_release_by_adapter_index(const DWORD adapter_index)
Definition tun.c:5163
void delete_route_connected_v6_net(const struct tuntap *tt)
Definition tun.c:1013
bool tun_standby(struct tuntap *tt)
Definition tun.c:5740
static void tuntap_dhcp_mask(const struct tuntap *tt, const char *device_guid)
Definition tun.c:6414
static void write_dhcp_search_str(struct buffer *buf, const int type, const char *const *str_array, int array_len, bool *error)
Definition tun.c:5841
static void init_ip_addr_string2(IP_ADDR_STRING *dest, const IP_ADDR_STRING *src1, const IP_ADDR_STRING *src2)
Definition tun.c:5505
void do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu, const struct env_set *es, openvpn_net_ctx_t *ctx)
do_ifconfig - configure the tunnel interface
Definition tun.c:1606
const char * dev_type_string(const char *dev, const char *dev_type)
Definition tun.c:486
static const char ifconfig_warn_how_to_silence[]
Definition tun.c:525
static const struct device_instance_id_interface * get_device_instance_id_interface(struct gc_arena *gc)
Definition tun.c:3695
static void write_dhcp_str(struct buffer *buf, const int type, const char *str, bool *error)
Definition tun.c:5812
void close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
Definition tun.c:6906
static const char * guid_to_name(const char *guid, const struct panel_reg *panel_reg)
Definition tun.c:4255
static DWORD get_adapter_index_method_2(const char *guid)
Definition tun.c:4917
static int dhcp_status(DWORD index)
Definition tun.c:4829
const IP_ADAPTER_INFO * get_adapter_info_list(struct gc_arena *gc)
Definition tun.c:4436
void tap_allow_nonadmin_access(const char *dev_node)
Definition tun.c:5061
bool tun_name_is_fixed(const char *dev)
Definition tun.c:1830
static bool ip_addr_member_of(const in_addr_t addr, const IP_ADDR_STRING *ias)
Definition tun.c:5363
static const char * format_ip_addr_string(const IP_ADDR_STRING *ip, struct gc_arena *gc)
Definition tun.c:4958
const IP_ADAPTER_INFO * get_adapter(const IP_ADAPTER_INFO *ai, DWORD index)
Definition tun.c:4550
static void at_least_one_tap_win(const struct tap_reg *tap_reg)
Definition tun.c:4287
static void add_route_connected_v6_net(struct tuntap *tt, const struct env_set *es)
Definition tun.c:998
void warn_on_use_of_common_subnets(openvpn_net_ctx_t *ctx)
Definition tun.c:630
static bool dhcp_renew(const struct tuntap *tt)
Definition tun.c:5229
static void exec_command(const char *prefix, const struct argv *a, int n, int msglevel)
Definition tun.c:5242
static void undo_ifconfig_ipv6(struct tuntap *tt, openvpn_net_ctx_t *ctx)
Definition tun.c:1679
static void write_dhcp_u32_array(struct buffer *buf, const int type, const uint32_t *data, const unsigned int len, bool *error)
Definition tun.c:5783
static void netsh_command(const struct argv *a, int n, int msglevel)
Definition tun.c:5263
int tun_read_queue(struct tuntap *tt, int maxsize)
Definition tun.c:3542
void init_tun_post(struct tuntap *tt, const struct frame *frame, const struct tuntap_options *options)
Definition tun.c:940
static void tuntap_set_connected(const struct tuntap *tt)
Definition tun.c:6336
static const struct tap_reg * get_adapter_by_guid(const char *guid, const struct tap_reg *tap_reg)
Definition tun.c:4239
static void do_dns_domain_service(bool add, const struct tuntap *tt)
Definition tun.c:182
static void tuntap_get_mtu(struct tuntap *tt)
Definition tun.c:6136
const char * ifconfig_options_string(const struct tuntap *tt, bool remote, bool disable, struct gc_arena *gc)
Definition tun.c:653
const char * guess_tuntap_dev(const char *dev, const char *dev_type, const char *dev_node, struct gc_arena *gc)
Definition tun.c:506
const char * ipset2ascii(int index)
Definition tun.c:7024
void do_ifconfig_setenv(const struct tuntap *tt, struct env_set *es)
Definition tun.c:750
static bool do_set_mtu_service(const struct tuntap *tt, const short family, const int mtu)
Definition tun.c:372
void undo_ifconfig(struct tuntap *tt, openvpn_net_ctx_t *ctx)
undo_ifconfig - undo configuration of the tunnel interface
Definition tun.c:1705
bool is_tun_p2p(const struct tuntap *tt)
Definition tun.c:726
static void windows_set_mtu(const int iface_index, const short family, const int mtu)
Definition tun.c:5651
const char * ipset2ascii_all(struct gc_arena *gc)
Definition tun.c:7038
static int get_adapter_n_ip_netmask(const IP_ADAPTER_INFO *ai)
Definition tun.c:4575
void tun_standby_init(struct tuntap *tt)
Definition tun.c:5734
#define NI_IP_NETMASK
Definition tun.c:97
void show_valid_win32_tun_subnets(void)
Definition tun.c:4124
static void tap_allow_nonadmin_access_handle(const char *device_path, HANDLE hand)
Definition tun.c:5039
void ip_addr_string_to_array(in_addr_t *dest, int *dest_len, const IP_ADDR_STRING *src)
Definition tun.c:5295
static bool service_register_ring_buffers(const struct tuntap *tt)
Definition tun.c:6007
static void netsh_set_dns6_servers(const struct in6_addr *addr_list, const int addr_len, DWORD adapter_index)
Set the ipv6 dns servers on the specified interface.
Definition tun.c:5386
static const GUID GUID_DEVCLASS_NET
Definition tun.c:91
const char * print_tun_backend_driver(enum tun_driver_type driver)
Return a string representation of the tun backed driver type.
Definition tun.c:59
static void do_wins_service(bool add, const struct tuntap *tt)
Definition tun.c:309
DWORD adapter_index_of_ip(const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count, in_addr_t *netmask)
Definition tun.c:4745
static void do_dns_service(bool add, const short family, const struct tuntap *tt)
Definition tun.c:234
static bool wintun_register_ring_buffer(struct tuntap *tt, const char *device_guid)
Definition tun.c:6284
void tun_open_device(struct tuntap *tt, const char *dev_node, const char **device_guid, struct gc_arena *gc)
Definition tun.c:6565
void verify_255_255_255_252(in_addr_t local, in_addr_t remote)
Definition tun.c:4087
static bool ip_addr_one_to_one(const in_addr_t *a1, const int a1len, const IP_ADDR_STRING *ias)
Definition tun.c:5339
#define IPW32_SET_NETSH
Definition tun.h:82
#define IPW32_SET_ADAPTIVE
Definition tun.h:85
#define DHCP_OPTIONS_DHCP_REQUIRED
Definition tun.h:75
#define IPW32_SET_IPAPI
Definition tun.h:83
#define TUN_ADAPTER_INDEX_INVALID
Definition tun.h:67
#define IPW32_SET_DHCP_MASQ
Definition tun.h:84
static bool tuntap_is_dco_win(struct tuntap *tt)
Definition tun.h:682
#define DCO_WIN_REFERENCE_STRING
Definition tun.h:62
#define IPW32_SET_ADAPTIVE_TRY_NETSH
Definition tun.h:71
#define WINTUN_COMPONENT_ID
Definition tun.h:61
#define IPW32_SET_N
Definition tun.h:86
#define IPW32_SET_MANUAL
Definition tun.h:81
tun_driver_type
Definition tun.h:45
@ WINDOWS_DRIVER_WINTUN
Definition tun.h:48
@ DRIVER_NULL
Definition tun.h:54
@ WINDOWS_DRIVER_UNSPECIFIED
Definition tun.h:46
@ DRIVER_UTUN
macOS internal tun driver
Definition tun.h:57
@ DRIVER_GENERIC_TUNTAP
Definition tun.h:49
@ DRIVER_AFUNIX
using an AF_UNIX socket to pass packets from/to an external program.
Definition tun.h:53
@ WINDOWS_DRIVER_TAP_WINDOWS6
Definition tun.h:47
@ DRIVER_DCO
Definition tun.h:55
int read_tun(struct tuntap *tt, uint8_t *buf, int len)
int write_tun(struct tuntap *tt, uint8_t *buf, int len)
void tuncfg(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, openvpn_net_ctx_t *ctx)
struct in6_addr ipv6
Definition openvpn-msg.h:59
struct in_addr ipv4
Definition openvpn-msg.h:58
int get_interface_metric(const NET_IFINDEX index, const ADDRESS_FAMILY family, int *is_auto)
Return interface metric value for the specified interface index.
Definition wfp_block.c:404
void overlapped_io_init(struct overlapped_io *o, const struct frame *frame, BOOL event_state)
Definition win32.c:171
int win32_version_info(void)
Definition win32.c:1287
void fork_to_self(const char *cmdline)
Definition win32.c:1073
char * overlapped_io_state_ascii(const struct overlapped_io *o)
Definition win32.c:202
bool send_msg_iservice(HANDLE pipe, const void *data, size_t size, ack_message_t *ack, const char *context)
Definition win32.c:1480
void overlapped_io_close(struct overlapped_io *o)
Definition win32.c:189
void netcmd_semaphore_release(void)
Definition win32.c:874
char * get_win_sys_path(void)
Definition win32.c:1113
void netcmd_semaphore_lock(void)
Definition win32.c:858
bool init_security_attributes_allow_all(struct security_attributes *obj)
Definition win32.c:152
#define IOSTATE_IMMEDIATE_RETURN
Definition win32.h:205
#define WIN_IPCONFIG_PATH_SUFFIX
Definition win32.h:41
static bool overlapped_io_active(struct overlapped_io *o)
Definition win32.h:228
#define IOSTATE_INITIAL
Definition win32.h:203
#define IOSTATE_QUEUED
Definition win32.h:204
#define WIN_7
Definition win32.h:297
#define NETSH_PATH_SUFFIX
Definition win32.h:39
#define WMIC_PATH_SUFFIX
Definition win32.h:43