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