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