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