OpenVPN
tun.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2026 OpenVPN Inc <sales@openvpn.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23/*
24 * Support routines for configuring and accessing TUN/TAP
25 * virtual network adapters.
26 *
27 * This file is based on the TUN/TAP driver interface routines
28 * from VTun by Maxim Krasnyansky <max_mk@yahoo.com>.
29 */
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#include "syshead.h"
36
37#include "openvpn.h"
38#include "tun.h"
39#include "fdmisc.h"
40#include "common.h"
41#include "run_command.h"
42#include "socket_util.h"
43#include "manage.h"
44#include "route.h"
45#include "win32.h"
46#include "wfp_block.h"
47#include "networking.h"
48#include "dhcp.h"
49
50#include "memdbg.h"
51
52#ifdef _WIN32
53#include "openvpn-msg.h"
54#endif
55
56#include <string.h>
57
58const char *
60{
61 switch (driver)
62 {
64 return "tap-windows6";
65
67 return "tun/tap";
68
69 case DRIVER_DCO:
70 return "ovpn-dco";
71
72 case DRIVER_AFUNIX:
73 return "unix";
74
75 case DRIVER_NULL:
76 return "null";
77
78 case DRIVER_UTUN:
79 return "utun";
80
81 default:
82 return "unspecified";
83 }
84}
85
86#ifdef _WIN32
87
88static const GUID GUID_DEVCLASS_NET = {
89 0x4d36e972L, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 }
90};
91static const GUID GUID_DEVINTERFACE_NET = {
92 0xcac88484, 0x7515, 0x4c03, { 0x82, 0xe6, 0x71, 0xa8, 0x7a, 0xba, 0xc3, 0x61 }
93};
94
95/* #define SIMULATE_DHCP_FAILED */ /* simulate bad DHCP negotiation */
96
97#define NI_TEST_FIRST (1 << 0)
98#define NI_IP_NETMASK (1 << 1)
99#define NI_OPTIONS (1 << 2)
100
101static void netsh_ifconfig(const struct tuntap_options *to, DWORD adapter_index, const in_addr_t ip,
102 const in_addr_t netmask, const unsigned int flags);
103
104static void windows_set_mtu(const int iface_index, const short family, const int mtu);
105
106static void netsh_set_dns6_servers(const struct in6_addr *addr_list, const unsigned int addr_len,
107 DWORD adapter_index);
108
109static void netsh_command(const struct argv *a, int n, msglvl_t msglevel);
110
111static void exec_command(const char *prefix, const struct argv *a, int n, msglvl_t msglevel);
112
113static const char *netsh_get_id(const char *dev_node, struct gc_arena *gc);
114
115static bool
116do_address_service(const bool add, const short family, const struct tuntap *tt)
117{
118 bool ret = false;
119 ack_message_t ack;
120 struct gc_arena gc = gc_new();
121 HANDLE pipe = tt->options.msg_channel;
122
124 sizeof(address_message_t), 0 },
125 .family = family,
126 .iface = { .index = tt->adapter_index, .name = "" } };
127
129 {
130 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=%lu]",
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 = %lu) 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 unsigned int len = family == AF_INET6 ? tt->options.dns6_len : tt->options.dns_len;
246 unsigned 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 %u",
272 ip_proto_name, addr_len);
273 }
274
275 for (unsigned 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 = %lu) 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 unsigned 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 %u", addr_len);
337 }
338
339 for (unsigned 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 = %lu) 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),
356 ack.error_number, 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=%lu]",
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 %lu 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
1709#if defined(__GNUC__) || defined(__clang__)
1710#pragma GCC diagnostic push
1711#pragma GCC diagnostic ignored "-Wsign-compare"
1712#endif
1713
1714static inline ssize_t
1715header_modify_read_write_return(ssize_t len)
1716{
1717 if (len > 0)
1718 {
1719 return len > sizeof(u_int32_t) ? len - sizeof(u_int32_t) : 0;
1720 }
1721 else
1722 {
1723 return len;
1724 }
1725}
1726
1727#if defined(__GNUC__) || defined(__clang__)
1728#pragma GCC diagnostic pop
1729#endif
1730
1731static ssize_t
1732write_tun_header(struct tuntap *tt, uint8_t *buf, int len)
1733{
1734 if (tt->type == DEV_TYPE_TUN)
1735 {
1736 u_int32_t type;
1737 struct iovec iv[2];
1738 struct ip *iph = (struct ip *)buf;
1739
1740 if (iph->ip_v == 6)
1741 {
1742 type = htonl(AF_INET6);
1743 }
1744 else
1745 {
1746 type = htonl(AF_INET);
1747 }
1748
1749 iv[0].iov_base = &type;
1750 iv[0].iov_len = sizeof(type);
1751 iv[1].iov_base = buf;
1752 iv[1].iov_len = len;
1753
1754 return header_modify_read_write_return(writev(tt->fd, iv, 2));
1755 }
1756 else
1757 {
1758 return write(tt->fd, buf, len);
1759 }
1760}
1761
1762static ssize_t
1763read_tun_header(struct tuntap *tt, uint8_t *buf, int len)
1764{
1765 if (tt->type == DEV_TYPE_TUN)
1766 {
1767 u_int32_t type;
1768 struct iovec iv[2];
1769
1770 iv[0].iov_base = &type;
1771 iv[0].iov_len = sizeof(type);
1772 iv[1].iov_base = buf;
1773 iv[1].iov_len = len;
1774
1775 return header_modify_read_write_return(readv(tt->fd, iv, 2));
1776 }
1777 else
1778 {
1779 return read(tt->fd, buf, len);
1780 }
1781}
1782
1783/* For MacOS this extra handling is conditional on the UTUN driver.
1784 * So it needs its own read_tun()/write_tun() with the necessary
1785 * checks. They are located in the macOS-specific section below.
1786 */
1787#if !defined(TARGET_DARWIN)
1788ssize_t
1789write_tun(struct tuntap *tt, uint8_t *buf, int len)
1790{
1791 return write_tun_header(tt, buf, len);
1792}
1793
1794ssize_t
1795read_tun(struct tuntap *tt, uint8_t *buf, int len)
1796{
1797 return read_tun_header(tt, buf, len);
1798}
1799#endif
1800
1801#endif /* if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || defined(TARGET_NETBSD) || defined (TARGET_OPENBSD) || defined(TARGET_DARWIN) */
1802
1803bool
1804tun_name_is_fixed(const char *dev)
1805{
1806 return has_digit(dev);
1807}
1808
1809#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1810static bool
1811tun_dco_enabled(struct tuntap *tt)
1812{
1813 return tt->backend_driver == DRIVER_DCO;
1814}
1815#endif
1816
1817
1818#if !(defined(_WIN32) || defined(TARGET_LINUX) || defined(TARGET_SOLARIS) || defined(TARGET_ANDROID))
1819static void
1820open_tun_generic(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1821{
1822 char tunname[256];
1823 char dynamic_name[256];
1824 bool dynamic_opened = false;
1825
1826 /*
1827 * --dev-node specified, so open an explicit device node
1828 */
1829 if (dev_node)
1830 {
1831 snprintf(tunname, sizeof(tunname), "%s", dev_node);
1832 }
1833 else
1834 {
1835 /*
1836 * dynamic open is indicated by --dev specified without
1837 * explicit unit number. Try opening /dev/[dev]n
1838 * where n = [0, 255].
1839 */
1840
1841 if (!tun_name_is_fixed(dev))
1842 {
1843 for (int i = 0; i < 256; ++i)
1844 {
1845 /* some platforms have a dedicated directory per driver */
1846 char *sep = "";
1847#if defined(TARGET_HAIKU)
1848 sep = "/";
1849#endif
1850 snprintf(tunname, sizeof(tunname), "/dev/%s%s%d", dev, sep, i);
1851 snprintf(dynamic_name, sizeof(dynamic_name), "%s%s%d", dev, sep, i);
1852 if ((tt->fd = open(tunname, O_RDWR)) > 0)
1853 {
1854 dynamic_opened = true;
1855 break;
1856 }
1857 msg(D_READ_WRITE | M_ERRNO, "Tried opening %s (failed)", tunname);
1858 }
1859 if (!dynamic_opened)
1860 {
1861 msg(M_FATAL, "Cannot allocate TUN/TAP dev dynamically");
1862 }
1863 }
1864 /*
1865 * explicit unit number specified
1866 */
1867 else
1868 {
1869 snprintf(tunname, sizeof(tunname), "/dev/%s", dev);
1870 }
1871 }
1872
1873 if (!dynamic_opened)
1874 {
1875 /* has named device existed before? if so, don't destroy at end */
1876 if (if_nametoindex(dev) > 0)
1877 {
1878 msg(M_INFO, "TUN/TAP device %s exists previously, keep at program end", dev);
1879 tt->persistent_if = true;
1880 }
1881
1882 if ((tt->fd = open(tunname, O_RDWR)) < 0)
1883 {
1884 msg(M_ERR, "Cannot open TUN/TAP dev %s", tunname);
1885 }
1886 }
1887
1888 set_nonblock(tt->fd);
1889 set_cloexec(tt->fd); /* don't pass fd to scripts */
1890 msg(M_INFO, "TUN/TAP device %s opened", tunname);
1891
1892 /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
1893 tt->actual_name = string_alloc(dynamic_opened ? dynamic_name : dev, NULL);
1894}
1895#endif /* !_WIN32 && !TARGET_LINUX && !TARGET_FREEBSD*/
1896
1897#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1898static void
1899open_tun_dco_generic(const char *dev, const char *dev_type, struct tuntap *tt,
1900 openvpn_net_ctx_t *ctx)
1901{
1902 char dynamic_name[256];
1903 bool dynamic_opened = false;
1904
1905 /*
1906 * unlike "open_tun_generic()", DCO on Linux and FreeBSD follows
1907 * the device naming model of "non-DCO linux", that is:
1908 * --dev tun -> try tun0, tun1, ... tun255, use first free
1909 * --dev <anything> -> (try to) create a tun device named "anything"
1910 * ("--dev tap" and "--dev null" are caught earlier and not handled here)
1911 */
1912
1913 if (strcmp(dev, "tun") == 0)
1914 {
1915 for (int i = 0; i < 256; ++i)
1916 {
1917 snprintf(dynamic_name, sizeof(dynamic_name), "%s%d", dev, i);
1918 int ret = open_tun_dco(tt, ctx, dynamic_name);
1919 if (ret == 0)
1920 {
1921 dynamic_opened = true;
1922 msg(M_INFO, "DCO device %s opened", dynamic_name);
1923 break;
1924 }
1925 /* "permission denied" won't succeed if we try 256 times */
1926 else if (ret == -EPERM)
1927 {
1928 break;
1929 }
1930 }
1931 if (!dynamic_opened)
1932 {
1933 msg(M_FATAL, "Cannot allocate DCO dev dynamically");
1934 }
1935 /* tt->actual_name is passed to up and down scripts and used as
1936 * the ifconfig dev name */
1937 tt->actual_name = string_alloc(dynamic_name, NULL);
1938 }
1939 /*
1940 * explicit unit number specified
1941 */
1942 else
1943 {
1944 int ret = open_tun_dco(tt, ctx, dev);
1945 if (ret == -EEXIST)
1946 {
1947 msg(M_INFO, "DCO device %s already exists, won't be destroyed at shutdown", dev);
1948 tt->persistent_if = true;
1949 }
1950 else if (ret < 0)
1951 {
1952 msg(M_ERR, "Cannot open DCO device %s: %s (%d)", dev, strerror(-ret), ret);
1953 }
1954 else
1955 {
1956 msg(M_INFO, "DCO device %s opened", dev);
1957 }
1958
1959 /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
1960 tt->actual_name = string_alloc(dev, NULL);
1961 }
1962}
1963#endif /* TARGET_LINUX || TARGET_FREEBSD*/
1964
1965#if !(defined(_WIN32) || defined(TARGET_SOLARIS))
1966static void
1967close_tun_generic(struct tuntap *tt)
1968{
1969 if (tt->fd >= 0)
1970 {
1971 close(tt->fd);
1972 }
1973
1974 free(tt->actual_name);
1975 clear_tuntap(tt);
1976}
1977#endif /* !_WIN32 */
1978
1979#if defined(TARGET_ANDROID)
1980void
1981open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
1982 openvpn_net_ctx_t *ctx)
1983{
1984#define ANDROID_TUNNAME "vpnservice-tun"
1985 struct gc_arena gc = gc_new();
1986 bool opentun;
1987
1988 int oldtunfd = tt->fd;
1989
1990 /* Prefer IPv6 DNS servers,
1991 * Android will use the DNS server in the order we specify*/
1992 for (unsigned int i = 0; i < tt->options.dns6_len; i++)
1993 {
1994 management_android_control(management, "DNS6SERVER",
1995 print_in6_addr(tt->options.dns6[i], 0, &gc));
1996 }
1997
1998 for (unsigned int i = 0; i < tt->options.dns_len; i++)
1999 {
2000 management_android_control(management, "DNSSERVER",
2001 print_in_addr_t(tt->options.dns[i], 0, &gc));
2002 }
2003
2004 if (tt->options.domain)
2005 {
2006 management_android_control(management, "DNSDOMAIN", tt->options.domain);
2007 }
2008
2009 if (tt->options.http_proxy)
2010 {
2011 struct buffer buf = alloc_buf_gc(strlen(tt->options.http_proxy) + 20, &gc);
2012 buf_printf(&buf, "%s %d", tt->options.http_proxy, tt->options.http_proxy_port);
2013 management_android_control(management, "HTTPPROXY", BSTR(&buf));
2014 }
2015
2017
2019 {
2020 /* keep the old fd */
2021 opentun = true;
2022 }
2023 else
2024 {
2026 /* Pick up the fd from management interface after calling the
2027 * OPENTUN command */
2028 tt->fd = management->connection.lastfdreceived;
2029 management->connection.lastfdreceived = -1;
2030 }
2031
2033 {
2034 close(oldtunfd);
2035 }
2036
2037 /* Set the actual name to a dummy name */
2038 tt->actual_name = string_alloc(ANDROID_TUNNAME, NULL);
2039
2040 if ((tt->fd < 0) || !opentun)
2041 {
2042 msg(M_ERR, "ERROR: Cannot open TUN");
2043 }
2044
2045 gc_free(&gc);
2046}
2047
2048void
2049close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2050{
2051 ASSERT(tt);
2052
2054 free(tt);
2055}
2056
2057ssize_t
2058write_tun(struct tuntap *tt, uint8_t *buf, int len)
2059{
2060 return write(tt->fd, buf, len);
2061}
2062
2063ssize_t
2064read_tun(struct tuntap *tt, uint8_t *buf, int len)
2065{
2066 return read(tt->fd, buf, len);
2067}
2068
2069#elif defined(TARGET_LINUX)
2070
2071#if !PEDANTIC
2072
2073void
2074open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
2075 openvpn_net_ctx_t *ctx)
2076{
2077 struct ifreq ifr;
2078
2079 if (tun_dco_enabled(tt))
2080 {
2081 open_tun_dco_generic(dev, dev_type, tt, ctx);
2082 }
2083 else
2084 {
2085 /*
2086 * Process --dev-node
2087 */
2088 const char *node = dev_node;
2089 if (!node)
2090 {
2091 node = "/dev/net/tun";
2092 }
2093
2094 /*
2095 * Open the interface
2096 */
2097 if ((tt->fd = open(node, O_RDWR)) < 0)
2098 {
2099 msg(M_ERR, "ERROR: Cannot open TUN/TAP dev %s", node);
2100 }
2101
2102 /*
2103 * Process --tun-ipv6
2104 */
2105 CLEAR(ifr);
2106 ifr.ifr_flags = IFF_NO_PI;
2107
2108#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2109 ifr.ifr_flags |= IFF_ONE_QUEUE;
2110#endif
2111
2112 /*
2113 * Figure out if tun or tap device
2114 */
2115 if (tt->type == DEV_TYPE_TUN)
2116 {
2117 ifr.ifr_flags |= IFF_TUN;
2118 }
2119 else if (tt->type == DEV_TYPE_TAP)
2120 {
2121 ifr.ifr_flags |= IFF_TAP;
2122 }
2123 else
2124 {
2125 msg(M_FATAL, "I don't recognize device %s as a tun or tap device", dev);
2126 }
2127
2128 /*
2129 * Set an explicit name, if --dev is not tun or tap
2130 */
2131 if (strcmp(dev, "tun") && strcmp(dev, "tap"))
2132 {
2133 strncpynt(ifr.ifr_name, dev, IFNAMSIZ);
2134 }
2135
2136 /*
2137 * Use special ioctl that configures tun/tap device with the parms
2138 * we set in ifr
2139 */
2140 if (ioctl(tt->fd, TUNSETIFF, (void *)&ifr) < 0)
2141 {
2142 msg(M_ERR, "ERROR: Cannot ioctl TUNSETIFF %s", dev);
2143 }
2144
2145 msg(M_INFO, "TUN/TAP device %s opened", ifr.ifr_name);
2146
2147 /*
2148 * Try making the TX send queue bigger
2149 */
2150#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2151 if (tt->options.txqueuelen)
2152 {
2153 struct ifreq netifr;
2154 int ctl_fd;
2155
2156 if ((ctl_fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
2157 {
2158 CLEAR(netifr);
2159 strncpynt(netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
2160 netifr.ifr_qlen = tt->options.txqueuelen;
2161 if (ioctl(ctl_fd, SIOCSIFTXQLEN, (void *)&netifr) >= 0)
2162 {
2163 msg(D_OSBUF, "TUN/TAP TX queue length set to %d", tt->options.txqueuelen);
2164 }
2165 else
2166 {
2167 msg(M_WARN | M_ERRNO, "Note: Cannot set tx queue length on %s", ifr.ifr_name);
2168 }
2169 close(ctl_fd);
2170 }
2171 else
2172 {
2173 msg(M_WARN | M_ERRNO, "Note: Cannot open control socket on %s", ifr.ifr_name);
2174 }
2175 }
2176#endif /* if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN) */
2177
2178 set_nonblock(tt->fd);
2179 set_cloexec(tt->fd);
2180 tt->actual_name = string_alloc(ifr.ifr_name, NULL);
2181 }
2182 return;
2183}
2184
2185#else /* if !PEDANTIC */
2186
2187void
2188open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
2189 openvpn_net_ctx_t *ctx)
2190{
2191 ASSERT(0);
2192}
2193
2194#endif /* !PEDANTIC */
2195
2196#ifdef ENABLE_FEATURE_TUN_PERSIST
2197
2198void
2199tuncfg(const char *dev, const char *dev_type, const char *dev_node, int persist_mode,
2200 const char *username, const char *groupname, const struct tuntap_options *options,
2201 openvpn_net_ctx_t *ctx)
2202{
2203 struct tuntap *tt;
2204
2205 ALLOC_OBJ(tt, struct tuntap);
2206 clear_tuntap(tt);
2207 tt->type = dev_type_enum(dev, dev_type);
2208 tt->options = *options;
2209
2210 open_tun(dev, dev_type, dev_node, tt, ctx);
2211 if (ioctl(tt->fd, TUNSETPERSIST, persist_mode) < 0)
2212 {
2213 msg(M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
2214 }
2215 if (username != NULL)
2216 {
2218
2219 if (!platform_user_get(username, &platform_state_user))
2220 {
2221 msg(M_ERR, "Cannot get user entry for %s", username);
2222 }
2223 else if (ioctl(tt->fd, TUNSETOWNER, platform_state_user.uid) < 0)
2224 {
2225 msg(M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", username, dev);
2226 }
2227 }
2228 if (groupname != NULL)
2229 {
2231
2232 if (!platform_group_get(groupname, &platform_state_group))
2233 {
2234 msg(M_ERR, "Cannot get group entry for %s", groupname);
2235 }
2236 else if (ioctl(tt->fd, TUNSETGROUP, platform_state_group.gid) < 0)
2237 {
2238 msg(M_ERR, "Cannot ioctl TUNSETGROUP(%s) %s", groupname, dev);
2239 }
2240 }
2241 close_tun(tt, ctx);
2242 msg(M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF"));
2243}
2244
2245#endif /* ENABLE_FEATURE_TUN_PERSIST */
2246
2247void
2248close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2249{
2250 ASSERT(tt);
2251
2252#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
2253 if (tun_dco_enabled(tt))
2254 {
2255 close_tun_dco(tt, ctx);
2256 }
2257#endif
2258 close_tun_generic(tt);
2259 free(tt);
2260}
2261
2262ssize_t
2263write_tun(struct tuntap *tt, uint8_t *buf, int len)
2264{
2265 return write(tt->fd, buf, len);
2266}
2267
2268ssize_t
2269read_tun(struct tuntap *tt, uint8_t *buf, int len)
2270{
2271 return read(tt->fd, buf, len);
2272}
2273
2274#elif defined(TARGET_SOLARIS)
2275
2276#ifndef TUNNEWPPA
2277#error I need the symbol TUNNEWPPA from net/if_tun.h
2278#endif
2279
2280void
2281open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
2282 openvpn_net_ctx_t *ctx)
2283{
2284 int if_fd = -1, ip_muxid = -1, arp_muxid = -1, arp_fd = -1, ppa = -1;
2285 struct lifreq ifr;
2286 const char *ptr;
2287 const char *ip_node = NULL, *arp_node = NULL;
2288 const char *dev_tuntap_type;
2289 int link_type;
2290 struct strioctl strioc_if, strioc_ppa;
2291
2292 /* improved generic TUN/TAP driver from
2293 * https://web.archive.org/web/20250504214754/http://www.whiteboard.ne.jp/~admin2/tuntap/
2294 * has IPv6 support
2295 */
2296 CLEAR(ifr);
2297
2298 if (tt->type == DEV_TYPE_TUN)
2299 {
2300 ip_node = "/dev/udp";
2301 if (!dev_node)
2302 {
2303 dev_node = "/dev/tun";
2304 }
2305 dev_tuntap_type = "tun";
2306 link_type = I_PLINK;
2307 }
2308 else if (tt->type == DEV_TYPE_TAP)
2309 {
2310 ip_node = "/dev/udp";
2311 if (!dev_node)
2312 {
2313 dev_node = "/dev/tap";
2314 }
2315 arp_node = dev_node;
2316 dev_tuntap_type = "tap";
2317 link_type = I_PLINK; /* was: I_LINK */
2318 }
2319 else
2320 {
2321 msg(M_FATAL, "I don't recognize device %s as a tun or tap device", dev);
2322 }
2323
2324 if ((tt->ip_fd = open(ip_node, O_RDWR, 0)) < 0)
2325 {
2326 msg(M_ERR, "Can't open %s", ip_node);
2327 }
2328
2329 if ((tt->fd = open(dev_node, O_RDWR, 0)) < 0)
2330 {
2331 msg(M_ERR, "Can't open %s", dev_node);
2332 }
2333
2334 ptr = dev;
2335
2336 /* get unit number */
2337 if (*ptr)
2338 {
2339 while (*ptr && !isdigit((int)*ptr))
2340 {
2341 ptr++;
2342 }
2343 ppa = atoi(ptr);
2344 }
2345
2346 /* Assign a new PPA and get its unit number. */
2347 strioc_ppa.ic_cmd = TUNNEWPPA;
2348 strioc_ppa.ic_timout = 0;
2349 strioc_ppa.ic_len = sizeof(ppa);
2350 strioc_ppa.ic_dp = (char *)&ppa;
2351
2352 if (*ptr == '\0') /* no number given, try dynamic */
2353 {
2354 bool found_one = false;
2355 while (!found_one && ppa < 64)
2356 {
2357 int new_ppa = ioctl(tt->fd, I_STR, &strioc_ppa);
2358 if (new_ppa >= 0)
2359 {
2360 msg(M_INFO, "open_tun: got dynamic interface '%s%d'", dev_tuntap_type, new_ppa);
2361 ppa = new_ppa;
2362 found_one = true;
2363 break;
2364 }
2365 if (errno != EEXIST)
2366 {
2367 msg(M_ERR, "open_tun: unexpected error trying to find free %s interface",
2368 dev_tuntap_type);
2369 }
2370 ppa++;
2371 }
2372 if (!found_one)
2373 {
2374 msg(M_ERR, "open_tun: could not find free %s interface, give up.", dev_tuntap_type);
2375 }
2376 }
2377 else /* try this particular one */
2378 {
2379 if ((ppa = ioctl(tt->fd, I_STR, &strioc_ppa)) < 0)
2380 {
2381 msg(M_ERR, "Can't assign PPA for new interface (%s%d)", dev_tuntap_type, ppa);
2382 }
2383 }
2384
2385 if ((if_fd = open(dev_node, O_RDWR, 0)) < 0)
2386 {
2387 msg(M_ERR, "Can't open %s (2)", dev_node);
2388 }
2389
2390 if (ioctl(if_fd, I_PUSH, "ip") < 0)
2391 {
2392 msg(M_ERR, "Can't push IP module");
2393 }
2394
2395 if (tt->type == DEV_TYPE_TUN)
2396 {
2397 /* Assign ppa according to the unit number returned by tun device */
2398 if (ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0)
2399 {
2400 msg(M_ERR, "Can't set PPA %d", ppa);
2401 }
2402 }
2403
2404 tt->actual_name = (char *)malloc(32);
2406
2407 snprintf(tt->actual_name, 32, "%s%d", dev_tuntap_type, ppa);
2408
2409 if (tt->type == DEV_TYPE_TAP)
2410 {
2411 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2412 {
2413 msg(M_ERR, "Can't get flags");
2414 }
2415 strncpynt(ifr.lifr_name, tt->actual_name, sizeof(ifr.lifr_name));
2416 ifr.lifr_ppa = ppa;
2417 /* Assign ppa according to the unit number returned by tun device */
2418 if (ioctl(if_fd, SIOCSLIFNAME, &ifr) < 0)
2419 {
2420 msg(M_ERR, "Can't set PPA %d", ppa);
2421 }
2422 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2423 {
2424 msg(M_ERR, "Can't get flags");
2425 }
2426 /* Push arp module to if_fd */
2427 if (ioctl(if_fd, I_PUSH, "arp") < 0)
2428 {
2429 msg(M_ERR, "Can't push ARP module");
2430 }
2431
2432 /* Pop any modules on the stream */
2433 while (true)
2434 {
2435 if (ioctl(tt->ip_fd, I_POP, NULL) < 0)
2436 {
2437 break;
2438 }
2439 }
2440 /* Push arp module to ip_fd */
2441 if (ioctl(tt->ip_fd, I_PUSH, "arp") < 0)
2442 {
2443 msg(M_ERR, "Can't push ARP module");
2444 }
2445
2446 /* Open arp_fd */
2447 if ((arp_fd = open(arp_node, O_RDWR, 0)) < 0)
2448 {
2449 msg(M_ERR, "Can't open %s", arp_node);
2450 }
2451 /* Push arp module to arp_fd */
2452 if (ioctl(arp_fd, I_PUSH, "arp") < 0)
2453 {
2454 msg(M_ERR, "Can't push ARP module");
2455 }
2456
2457 /* Set ifname to arp */
2458 strioc_if.ic_cmd = SIOCSLIFNAME;
2459 strioc_if.ic_timout = 0;
2460 strioc_if.ic_len = sizeof(ifr);
2461 strioc_if.ic_dp = (char *)&ifr;
2462 if (ioctl(arp_fd, I_STR, &strioc_if) < 0)
2463 {
2464 msg(M_ERR, "Can't set ifname to arp");
2465 }
2466 }
2467
2468 if ((ip_muxid = ioctl(tt->ip_fd, link_type, if_fd)) < 0)
2469 {
2470 msg(M_ERR, "Can't link %s device to IP", dev_tuntap_type);
2471 }
2472
2473 if (tt->type == DEV_TYPE_TAP)
2474 {
2475 if ((arp_muxid = ioctl(tt->ip_fd, link_type, arp_fd)) < 0)
2476 {
2477 msg(M_ERR, "Can't link %s device to ARP", dev_tuntap_type);
2478 }
2479 close(arp_fd);
2480 }
2481
2482 CLEAR(ifr);
2483 strncpynt(ifr.lifr_name, tt->actual_name, sizeof(ifr.lifr_name));
2484 ifr.lifr_ip_muxid = ip_muxid;
2485 if (tt->type == DEV_TYPE_TAP)
2486 {
2487 ifr.lifr_arp_muxid = arp_muxid;
2488 }
2489
2490 if (ioctl(tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0)
2491 {
2492 if (tt->type == DEV_TYPE_TAP)
2493 {
2494 ioctl(tt->ip_fd, I_PUNLINK, arp_muxid);
2495 }
2496 ioctl(tt->ip_fd, I_PUNLINK, ip_muxid);
2497 msg(M_ERR, "Can't set multiplexor id");
2498 }
2499
2500 set_nonblock(tt->fd);
2501 set_cloexec(tt->fd);
2502 set_cloexec(tt->ip_fd);
2503
2504 msg(M_INFO, "TUN/TAP device %s opened", tt->actual_name);
2505}
2506
2507static void
2508solaris_close_tun(struct tuntap *tt)
2509{
2510 /* IPv6 interfaces need to be 'manually' de-configured */
2512 {
2513 struct argv argv = argv_new();
2514 argv_printf(&argv, "%s %s inet6 unplumb", IFCONFIG_PATH, tt->actual_name);
2515 argv_msg(M_INFO, &argv);
2516 openvpn_execve_check(&argv, NULL, 0, "Solaris ifconfig inet6 unplumb failed");
2517 argv_free(&argv);
2518 }
2519
2520 if (tt->ip_fd >= 0)
2521 {
2522 struct lifreq ifr;
2523 CLEAR(ifr);
2524 strncpynt(ifr.lifr_name, tt->actual_name, sizeof(ifr.lifr_name));
2525
2526 if (ioctl(tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0)
2527 {
2528 msg(M_WARN | M_ERRNO, "Can't get iface flags");
2529 }
2530
2531 if (ioctl(tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0)
2532 {
2533 msg(M_WARN | M_ERRNO, "Can't get multiplexor id");
2534 }
2535
2536 if (tt->type == DEV_TYPE_TAP)
2537 {
2538 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0)
2539 {
2540 msg(M_WARN | M_ERRNO, "Can't unlink interface(arp)");
2541 }
2542 }
2543
2544 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0)
2545 {
2546 msg(M_WARN | M_ERRNO, "Can't unlink interface(ip)");
2547 }
2548
2549 close(tt->ip_fd);
2550 tt->ip_fd = -1;
2551 }
2552
2553 if (tt->fd >= 0)
2554 {
2555 close(tt->fd);
2556 tt->fd = -1;
2557 }
2558}
2559
2560/*
2561 * Close TUN device.
2562 */
2563void
2564close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2565{
2566 ASSERT(tt);
2567
2568 solaris_close_tun(tt);
2569
2570 free(tt->actual_name);
2571
2572 clear_tuntap(tt);
2573 free(tt);
2574}
2575
2576static void
2577solaris_error_close(struct tuntap *tt, const struct env_set *es, const char *actual,
2578 bool unplumb_inet6)
2579{
2580 struct argv argv = argv_new();
2581
2582 if (unplumb_inet6)
2583 {
2584 argv_printf(&argv, "%s %s inet6 unplumb", IFCONFIG_PATH, actual);
2585 argv_msg(M_INFO, &argv);
2586 openvpn_execve_check(&argv, es, 0, "Solaris ifconfig inet6 unplumb failed");
2587 }
2588
2589 argv_printf(&argv, "%s %s unplumb", IFCONFIG_PATH, actual);
2590
2591 argv_msg(M_INFO, &argv);
2592 openvpn_execve_check(&argv, es, 0, "Solaris ifconfig unplumb failed");
2593 close_tun(tt, NULL);
2594 msg(M_FATAL, "Solaris ifconfig failed");
2595 argv_free(&argv);
2596}
2597
2598ssize_t
2599write_tun(struct tuntap *tt, uint8_t *buf, int len)
2600{
2601 struct strbuf sbuf;
2602 sbuf.len = len;
2603 sbuf.buf = (char *)buf;
2604 return putmsg(tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
2605}
2606
2607ssize_t
2608read_tun(struct tuntap *tt, uint8_t *buf, int len)
2609{
2610 struct strbuf sbuf;
2611 int f = 0;
2612
2613 sbuf.maxlen = len;
2614 sbuf.buf = (char *)buf;
2615 return getmsg(tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
2616}
2617
2618#elif defined(TARGET_OPENBSD)
2619
2620void
2621open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
2622 openvpn_net_ctx_t *ctx)
2623{
2624 open_tun_generic(dev, dev_type, dev_node, tt);
2625
2626 /* Enable multicast on the interface */
2627 if (tt->fd >= 0)
2628 {
2629 struct tuninfo info;
2630
2631 if (ioctl(tt->fd, TUNGIFINFO, &info) < 0)
2632 {
2633 msg(M_WARN | M_ERRNO, "Can't get interface info");
2634 }
2635
2636#ifdef IFF_MULTICAST /* openbsd 4.x doesn't have this */
2637 info.flags |= IFF_MULTICAST;
2638#endif
2639
2640 if (ioctl(tt->fd, TUNSIFINFO, &info) < 0)
2641 {
2642 msg(M_WARN | M_ERRNO, "Can't set interface info");
2643 }
2644 }
2645}
2646
2647/* tun(4): "If the device was created by opening /dev/tunN, it will be
2648 * automatically destroyed. Devices created via ifconfig(8) are
2649 * only marked as not running and traffic will be dropped
2650 * returning EHOSTDOWN."
2651 * --> no special handling should be needed - *but* OpenBSD is misbehaving
2652 * here: if the interface was put in tap mode ("ifconfig tunN link0"), it
2653 * *will* stay around, and needs to be cleaned up manually
2654 */
2655
2656void
2657close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2658{
2659 ASSERT(tt);
2660
2661 /* only *TAP* devices need destroying, tun devices auto-self-destruct
2662 */
2663 if (tt->type == DEV_TYPE_TUN || tt->persistent_if)
2664 {
2665 close_tun_generic(tt);
2666 free(tt);
2667 return;
2668 }
2669
2670 struct argv argv = argv_new();
2671
2672 /* setup command, close tun dev (clears tt->actual_name!), run command
2673 */
2674
2675 argv_printf(&argv, "%s %s destroy", IFCONFIG_PATH, tt->actual_name);
2676
2677 close_tun_generic(tt);
2678
2679 argv_msg(M_INFO, &argv);
2680 openvpn_execve_check(&argv, NULL, 0, "OpenBSD 'destroy tun interface' failed (non-critical)");
2681
2682 free(tt);
2683 argv_free(&argv);
2684}
2685
2686#elif defined(TARGET_NETBSD)
2687
2688/*
2689 * NetBSD 4.0 and up support IPv6 on tun interfaces, but we need to put
2690 * the tun interface into "multi_af" mode, which will prepend the address
2691 * family to all packets (same as OpenBSD and FreeBSD).
2692 *
2693 * If this is not enabled, the kernel silently drops all IPv6 packets on
2694 * output and gets confused on input.
2695 *
2696 * Note: --dev tap3 works *if* the interface is created externally by
2697 * "ifconfig tap3 create"
2698 * (and for devices beyond tap3, "mknod /dev/tapN c ...")
2699 * but we do not have code to do that inside OpenVPN
2700 */
2701
2702void
2703open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
2704 openvpn_net_ctx_t *ctx)
2705{
2706 /* on NetBSD, tap (but not tun) devices are opened by
2707 * opening /dev/tap and then querying the system about the
2708 * actual device name (tap0, tap1, ...) assigned
2709 */
2710 if (strcmp(dev, "tap") == 0)
2711 {
2712 struct ifreq ifr;
2713 if ((tt->fd = open("/dev/tap", O_RDWR)) < 0)
2714 {
2715 msg(M_FATAL, "Cannot allocate NetBSD TAP dev dynamically");
2716 }
2717 if (ioctl(tt->fd, TAPGIFNAME, (void *)&ifr) < 0)
2718 {
2719 msg(M_FATAL, "Cannot query NetBSD TAP device name");
2720 }
2721 set_nonblock(tt->fd);
2722 set_cloexec(tt->fd); /* don't pass fd to scripts */
2723 msg(M_INFO, "TUN/TAP device %s opened", ifr.ifr_name);
2724
2725 tt->actual_name = string_alloc(ifr.ifr_name, NULL);
2726 }
2727 else
2728 {
2729 /* dynamic / named tun can be handled by the generic function
2730 * named tap ("tap3") is handled there as well, if pre-created
2731 */
2732 open_tun_generic(dev, dev_type, dev_node, tt);
2733 }
2734
2735 if (tt->fd >= 0)
2736 {
2737 int i = IFF_POINTOPOINT | IFF_MULTICAST;
2738 ioctl(tt->fd, TUNSIFMODE, &i); /* multicast on */
2739 i = 0;
2740 ioctl(tt->fd, TUNSLMODE, &i); /* link layer mode off */
2741
2742 if (tt->type == DEV_TYPE_TUN)
2743 {
2744 i = 1;
2745 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0) /* multi-af mode on */
2746 {
2747 msg(M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD)");
2748 }
2749 }
2750 }
2751}
2752
2753/* the current way OpenVPN handles tun devices on NetBSD leads to
2754 * lingering tunX interfaces after close -> for a full cleanup, they
2755 * need to be explicitly destroyed
2756 */
2757void
2758close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2759{
2760 ASSERT(tt);
2761
2762 /* only tun devices need destroying, tap devices auto-self-destruct
2763 */
2764 if (tt->type != DEV_TYPE_TUN || tt->persistent_if)
2765 {
2766 close_tun_generic(tt);
2767 free(tt);
2768 return;
2769 }
2770
2771 struct argv argv = argv_new();
2772
2773 /* setup command, close tun dev (clears tt->actual_name!), run command
2774 */
2775
2776 argv_printf(&argv, "%s %s destroy", IFCONFIG_PATH, tt->actual_name);
2777
2778 close_tun_generic(tt);
2779
2780 argv_msg(M_INFO, &argv);
2781 openvpn_execve_check(&argv, NULL, 0, "NetBSD 'destroy tun interface' failed (non-critical)");
2782
2783 free(tt);
2784 argv_free(&argv);
2785}
2786
2787#elif defined(TARGET_FREEBSD)
2788
2789void
2790open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
2791 openvpn_net_ctx_t *ctx)
2792{
2793 if (tun_dco_enabled(tt))
2794 {
2795 open_tun_dco_generic(dev, dev_type, tt, ctx);
2796 }
2797 else
2798 {
2799 open_tun_generic(dev, dev_type, dev_node, tt);
2800
2801 if (tt->fd >= 0 && tt->type == DEV_TYPE_TUN)
2802 {
2803 /* see "Interface Flags" in ifnet(9) */
2804 int i = IFF_POINTOPOINT | IFF_MULTICAST;
2805 if (tt->topology == TOP_SUBNET)
2806 {
2807 i = IFF_BROADCAST | IFF_MULTICAST;
2808 }
2809
2810 if (ioctl(tt->fd, TUNSIFMODE, &i) < 0)
2811 {
2812 msg(M_WARN | M_ERRNO, "ioctl(TUNSIFMODE)");
2813 }
2814
2815 /* multi_af mode for v4+v6, see "tun(4)" */
2816 i = 1;
2817 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0)
2818 {
2819 msg(M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD)");
2820 }
2821 }
2822 }
2823}
2824
2825/* tun(4): "These network interfaces persist until the if_tun.ko module is
2826 * unloaded, or until removed with the ifconfig(8) command."
2827 * (verified for FreeBSD 6.3, 7.4, 8.2 and 9, same for tap(4))
2828 *
2829 * so, to avoid lingering tun/tap interfaces after OpenVPN quits,
2830 * we need to call "ifconfig ... destroy" for cleanup
2831 */
2832void
2833close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2834{
2835 ASSERT(tt);
2836
2837 if (tt->persistent_if) /* keep pre-existing if around */
2838 {
2839 close_tun_generic(tt);
2840 free(tt);
2841 return;
2842 }
2843
2844 /* close and destroy */
2845 struct argv argv = argv_new();
2846
2847 /* setup command, close tun dev (clears tt->actual_name!), run command
2848 */
2849
2850 argv_printf(&argv, "%s %s destroy", IFCONFIG_PATH, tt->actual_name);
2851
2852 close_tun_generic(tt);
2853
2854 argv_msg(M_INFO, &argv);
2855 openvpn_execve_check(&argv, NULL, 0, "FreeBSD 'destroy tun interface' failed (non-critical)");
2856
2857 free(tt);
2858 argv_free(&argv);
2859}
2860
2861#elif defined(TARGET_DRAGONFLY)
2862
2863void
2864open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
2865 openvpn_net_ctx_t *ctx)
2866{
2867 open_tun_generic(dev, dev_type, dev_node, tt);
2868
2869 if (tt->fd >= 0)
2870 {
2871 int i = 0;
2872
2873 /* Disable extended modes */
2874 ioctl(tt->fd, TUNSLMODE, &i);
2875 i = 1;
2876 ioctl(tt->fd, TUNSIFHEAD, &i);
2877 }
2878}
2879
2880void
2881close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2882{
2883 ASSERT(tt);
2884
2885 close_tun_generic(tt);
2886 free(tt);
2887}
2888
2889#elif defined(TARGET_DARWIN)
2890
2891/* Darwin (MacOS X) is mostly "just use the generic stuff", but there
2892 * is always one caveat...:
2893 *
2894 * If IPv6 is configured, and the tun device is closed, the IPv6 address
2895 * configured to the tun interface changes to a lingering /128 route
2896 * pointing to lo0. Need to unconfigure... (observed on 10.5)
2897 */
2898
2899/*
2900 * utun is the native Darwin tun driver present since at least 10.7
2901 * Thanks goes to Jonathan Levin for providing an example how to utun
2902 * (https://www.cs.dartmouth.edu/~sergey/netreads/utun/utun-demo.c)
2903 */
2904
2905/* Helper functions that tries to open utun device
2906 * return -2 on early initialization failures (utun not supported
2907 * at all) and -1 on initlization failure of utun
2908 * device (utun works but utunX is already used)
2909 */
2910static int
2911utun_open_helper(struct ctl_info ctlInfo, int utunnum)
2912{
2913 struct sockaddr_ctl sc;
2914 int fd;
2915
2916 fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
2917
2918 if (fd < 0)
2919 {
2920 msg(M_INFO | M_ERRNO, "Opening utun%d failed (socket(SYSPROTO_CONTROL))", utunnum);
2921 return -2;
2922 }
2923
2924 if (ioctl(fd, CTLIOCGINFO, &ctlInfo) == -1)
2925 {
2926 close(fd);
2927 msg(M_INFO | M_ERRNO, "Opening utun%d failed (ioctl(CTLIOCGINFO))", utunnum);
2928 return -2;
2929 }
2930
2931
2932 sc.sc_id = ctlInfo.ctl_id;
2933 sc.sc_len = sizeof(sc);
2934 sc.sc_family = AF_SYSTEM;
2935 sc.ss_sysaddr = AF_SYS_CONTROL;
2936
2937 sc.sc_unit = utunnum + 1;
2938
2939
2940 /* If the connect is successful, a utun%d device will be created, where "%d"
2941 * is (sc.sc_unit - 1) */
2942
2943 if (connect(fd, (struct sockaddr *)&sc, sizeof(sc)) < 0)
2944 {
2945 msg(M_INFO | M_ERRNO, "Opening utun%d failed (connect(AF_SYS_CONTROL))", utunnum);
2946 close(fd);
2947 return -1;
2948 }
2949
2950 set_nonblock(fd);
2951 set_cloexec(fd); /* don't pass fd to scripts */
2952
2953 return fd;
2954}
2955
2956void
2957open_darwin_utun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
2958{
2959 struct ctl_info ctlInfo;
2960 int fd;
2961 char utunname[20];
2962 int utunnum = -1;
2963 socklen_t utunname_len = sizeof(utunname);
2964
2965 /* dev_node is simply utun, do the normal dynamic utun
2966 * otherwise try to parse the utun number */
2967 if (dev_node && (strcmp("utun", dev_node) != 0))
2968 {
2969 if (sscanf(dev_node, "utun%d", &utunnum) != 1)
2970 {
2971 msg(M_FATAL,
2972 "Cannot parse 'dev-node %s' please use 'dev-node utunX'"
2973 "to use a utun device number X",
2974 dev_node);
2975 }
2976 }
2977
2978
2979 CLEAR(ctlInfo);
2980 if (strlcpy(ctlInfo.ctl_name, UTUN_CONTROL_NAME, sizeof(ctlInfo.ctl_name))
2981 >= sizeof(ctlInfo.ctl_name))
2982 {
2983 msg(M_ERR, "Opening utun: UTUN_CONTROL_NAME too long");
2984 }
2985
2986 /* try to open first available utun device if no specific utun is requested */
2987 if (utunnum == -1)
2988 {
2989 for (utunnum = 0; utunnum < 255; utunnum++)
2990 {
2991 char ifname[20];
2992 /* if the interface exists silently skip it */
2993 ASSERT(snprintf(ifname, sizeof(ifname), "utun%d", utunnum) > 0);
2994 if (if_nametoindex(ifname))
2995 {
2996 continue;
2997 }
2998 fd = utun_open_helper(ctlInfo, utunnum);
2999 /* Break if the fd is valid,
3000 * or if early initialization failed (-2) */
3001 if (fd != -1)
3002 {
3003 break;
3004 }
3005 }
3006 }
3007 else
3008 {
3009 fd = utun_open_helper(ctlInfo, utunnum);
3010 }
3011
3012 /* opening an utun device failed */
3013 tt->fd = fd;
3014
3015 if (fd < 0)
3016 {
3017 return;
3018 }
3019
3020 /* Retrieve the assigned interface name. */
3021 if (getsockopt(fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, utunname, &utunname_len))
3022 {
3023 msg(M_ERR, "Error retrieving utun interface name");
3024 }
3025
3026 tt->actual_name = string_alloc(utunname, NULL);
3027
3028 msg(M_INFO, "Opened utun device %s", utunname);
3030}
3031
3032void
3033open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
3034 openvpn_net_ctx_t *ctx)
3035{
3036 /* If dev_node does not start start with utun assume regular tun/tap */
3037 if ((!dev_node && tt->type == DEV_TYPE_TUN) || (dev_node && !strncmp(dev_node, "utun", 4)))
3038 {
3039 /* Check if user has specific dev_type tap and forced utun with
3040 * dev-node utun */
3041 if (tt->type != DEV_TYPE_TUN)
3042 {
3043 msg(M_FATAL, "Cannot use utun devices with --dev-type %s",
3044 dev_type_string(dev, dev_type));
3045 }
3046
3047 /* Try utun first and fall back to normal tun if utun fails
3048 * and dev_node is not specified */
3049 open_darwin_utun(dev, dev_type, dev_node, tt);
3050
3051 if (tt->backend_driver != DRIVER_UTUN)
3052 {
3053 if (!dev_node)
3054 {
3055 /* No explicit utun and utun failed, try the generic way) */
3056 msg(M_INFO, "Failed to open utun device. Falling back to /dev/tun device");
3057 open_tun_generic(dev, dev_type, NULL, tt);
3058 }
3059 else
3060 {
3061 /* Specific utun device or generic utun request with no tun
3062 * fall back failed, consider this a fatal failure */
3063 msg(M_FATAL, "Cannot open utun device");
3064 }
3065 }
3066 }
3067 else
3068 {
3069 /* Use plain dev-node tun to select /dev/tun style
3070 * Unset dev_node variable prior to passing to open_tun_generic to
3071 * let open_tun_generic pick the first available tun device */
3072
3073 if (dev_node && strcmp(dev_node, "tun") == 0)
3074 {
3075 dev_node = NULL;
3076 }
3077
3078 open_tun_generic(dev, dev_type, dev_node, tt);
3079 }
3080}
3081
3082void
3083close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
3084{
3085 ASSERT(tt);
3086
3087 struct gc_arena gc = gc_new();
3088 struct argv argv = argv_new();
3089
3091 {
3092 const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
3093
3094 argv_printf(&argv, "%s delete -inet6 %s", ROUTE_PATH, ifconfig_ipv6_local);
3095 argv_msg(M_INFO, &argv);
3096 openvpn_execve_check(&argv, NULL, 0, "MacOS X 'remove inet6 route' failed (non-critical)");
3097 }
3098
3099 close_tun_generic(tt);
3100 free(tt);
3101 argv_free(&argv);
3102 gc_free(&gc);
3103}
3104
3105ssize_t
3106write_tun(struct tuntap *tt, uint8_t *buf, int len)
3107{
3108 if (tt->backend_driver == DRIVER_UTUN)
3109 {
3110 return write_tun_header(tt, buf, len);
3111 }
3112 else
3113 {
3114 return write(tt->fd, buf, len);
3115 }
3116}
3117
3118ssize_t
3119read_tun(struct tuntap *tt, uint8_t *buf, int len)
3120{
3121 if (tt->backend_driver == DRIVER_UTUN)
3122 {
3123 return read_tun_header(tt, buf, len);
3124 }
3125 else
3126 {
3127 return read(tt->fd, buf, len);
3128 }
3129}
3130
3131#elif defined(TARGET_AIX)
3132
3133void
3134open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
3135 openvpn_net_ctx_t *ctx)
3136{
3137 char tunname[256];
3138 char dynamic_name[20];
3139 const char *p;
3140
3141 if (tt->type == DEV_TYPE_TUN)
3142 {
3143 msg(M_FATAL, "no support for 'tun' devices on AIX");
3144 }
3145
3146 if (strncmp(dev, "tap", 3) != 0 || dev_node)
3147 {
3148 msg(M_FATAL,
3149 "'--dev %s' and/or '--dev-node' not supported on AIX, use '--dev tap0', 'tap1', etc.",
3150 dev);
3151 }
3152
3153 if (strcmp(dev, "tap") == 0) /* find first free tap dev */
3154 { /* (= no /dev/tapN node) */
3155 int i;
3156 for (i = 0; i < 99; i++)
3157 {
3158 snprintf(tunname, sizeof(tunname), "/dev/tap%d", i);
3159 if (access(tunname, F_OK) < 0 && errno == ENOENT)
3160 {
3161 break;
3162 }
3163 }
3164 if (i >= 99)
3165 {
3166 msg(M_FATAL, "cannot find unused tap device");
3167 }
3168
3169 snprintf(dynamic_name, sizeof(dynamic_name), "tap%d", i);
3170 dev = dynamic_name;
3171 }
3172 else /* name given, sanity check */
3173 {
3174 /* ensure that dev name is "tap+<digits>" *only* */
3175 p = &dev[3];
3176 while (isdigit(*p))
3177 {
3178 p++;
3179 }
3180 if (*p != '\0')
3181 {
3182 msg(M_FATAL, "TAP device name must be '--dev tapNNNN'");
3183 }
3184
3185 snprintf(tunname, sizeof(tunname), "/dev/%s", dev);
3186 }
3187
3188 /* pre-existing device?
3189 */
3190 if (access(tunname, F_OK) < 0 && errno == ENOENT)
3191 {
3192 /* tunnel device must be created with 'ifconfig tapN create'
3193 */
3194 struct argv argv = argv_new();
3195 struct env_set *es = env_set_create(NULL);
3196 argv_printf(&argv, "%s %s create", IFCONFIG_PATH, dev);
3197 argv_msg(M_INFO, &argv);
3198 env_set_add(es, "ODMDIR=/etc/objrepos");
3199 openvpn_execve_check(&argv, es, S_FATAL, "AIX 'create tun interface' failed");
3201 argv_free(&argv);
3202 }
3203 else
3204 {
3205 /* we didn't make it, we're not going to break it */
3206 tt->persistent_if = TRUE;
3207 }
3208
3209 if ((tt->fd = open(tunname, O_RDWR)) < 0)
3210 {
3211 msg(M_ERR, "Cannot open TAP device '%s'", tunname);
3212 }
3213
3214 set_nonblock(tt->fd);
3215 set_cloexec(tt->fd); /* don't pass fd to scripts */
3216 msg(M_INFO, "TUN/TAP device %s opened", tunname);
3217
3218 /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
3219 tt->actual_name = string_alloc(dev, NULL);
3220}
3221
3222/* tap devices need to be manually destroyed on AIX
3223 */
3224void
3225close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
3226{
3227 ASSERT(tt);
3228
3229 struct argv argv = argv_new();
3230 struct env_set *es = env_set_create(NULL);
3231
3232 /* persistent devices need IP address unconfig, others need destroyal
3233 */
3234 if (tt->persistent_if)
3235 {
3236 argv_printf(&argv, "%s %s 0.0.0.0 down", IFCONFIG_PATH, tt->actual_name);
3237 }
3238 else
3239 {
3240 argv_printf(&argv, "%s %s destroy", IFCONFIG_PATH, tt->actual_name);
3241 }
3242
3243 close_tun_generic(tt);
3244 argv_msg(M_INFO, &argv);
3245 env_set_add(es, "ODMDIR=/etc/objrepos");
3246 openvpn_execve_check(&argv, es, 0, "AIX 'destroy tap interface' failed (non-critical)");
3247
3248 free(tt);
3250 argv_free(&argv);
3251}
3252
3253ssize_t
3254write_tun(struct tuntap *tt, uint8_t *buf, int len)
3255{
3256 return write(tt->fd, buf, len);
3257}
3258
3259ssize_t
3260read_tun(struct tuntap *tt, uint8_t *buf, int len)
3261{
3262 return read(tt->fd, buf, len);
3263}
3264
3265#elif defined(_WIN32)
3266
3267int
3268tun_read_queue(struct tuntap *tt, int maxsize)
3269{
3270 if (tt->reads.iostate == IOSTATE_INITIAL)
3271 {
3272 BOOL status;
3273 int err;
3274
3275 /* reset buf to its initial state */
3276 tt->reads.buf = tt->reads.buf_init;
3277
3278 int len = maxsize ? maxsize : BLEN(&tt->reads.buf);
3279 ASSERT(len <= BLEN(&tt->reads.buf));
3280
3281 /* the overlapped read will signal this event on I/O completion */
3282 ASSERT(ResetEvent(tt->reads.overlapped.hEvent));
3283
3284 status =
3285 ReadFile(tt->hand, BPTR(&tt->reads.buf), len, &tt->reads.size, &tt->reads.overlapped);
3286
3287 if (status) /* operation completed immediately? */
3288 {
3289 /* since we got an immediate return, we must signal the event object ourselves */
3290 ASSERT(SetEvent(tt->reads.overlapped.hEvent));
3291
3293 tt->reads.status = 0;
3294
3295 dmsg(D_WIN32_IO, "WIN32 I/O: TAP Read immediate return [%d,%lu]", len,
3296 tt->reads.size);
3297 }
3298 else
3299 {
3300 err = GetLastError();
3301 if (err == ERROR_IO_PENDING) /* operation queued? */
3302 {
3304 tt->reads.status = err;
3305 dmsg(D_WIN32_IO, "WIN32 I/O: TAP Read queued [%d]", len);
3306 }
3307 else /* error occurred */
3308 {
3309 struct gc_arena gc = gc_new();
3310 ASSERT(SetEvent(tt->reads.overlapped.hEvent));
3312 tt->reads.status = err;
3313 dmsg(D_WIN32_IO, "WIN32 I/O: TAP Read error [%d] : %s", len,
3315 gc_free(&gc);
3316 }
3317 }
3318 }
3319 return tt->reads.iostate;
3320}
3321
3322int
3323tun_write_queue(struct tuntap *tt, struct buffer *buf)
3324{
3325 if (tt->writes.iostate == IOSTATE_INITIAL)
3326 {
3327 BOOL status;
3328 int err;
3329
3330 /* make a private copy of buf */
3331 tt->writes.buf = tt->writes.buf_init;
3332 tt->writes.buf.len = 0;
3333 ASSERT(buf_copy(&tt->writes.buf, buf));
3334
3335 /* the overlapped write will signal this event on I/O completion */
3336 ASSERT(ResetEvent(tt->writes.overlapped.hEvent));
3337
3338 status = WriteFile(tt->hand, BPTR(&tt->writes.buf), BLEN(&tt->writes.buf), &tt->writes.size,
3339 &tt->writes.overlapped);
3340
3341 if (status) /* operation completed immediately? */
3342 {
3344
3345 /* since we got an immediate return, we must signal the event object ourselves */
3346 ASSERT(SetEvent(tt->writes.overlapped.hEvent));
3347
3348 tt->writes.status = 0;
3349
3350 dmsg(D_WIN32_IO, "WIN32 I/O: TAP Write immediate return [%d,%lu]", BLEN(&tt->writes.buf),
3351 tt->writes.size);
3352 }
3353 else
3354 {
3355 err = GetLastError();
3356 if (err == ERROR_IO_PENDING) /* operation queued? */
3357 {
3359 tt->writes.status = err;
3360 dmsg(D_WIN32_IO, "WIN32 I/O: TAP Write queued [%d]", BLEN(&tt->writes.buf));
3361 }
3362 else /* error occurred */
3363 {
3364 struct gc_arena gc = gc_new();
3365 ASSERT(SetEvent(tt->writes.overlapped.hEvent));
3367 tt->writes.status = err;
3368 dmsg(D_WIN32_IO, "WIN32 I/O: TAP Write error [%d] : %s", BLEN(&tt->writes.buf),
3369 strerror_win32(err, &gc));
3370 gc_free(&gc);
3371 }
3372 }
3373 }
3374 return tt->writes.iostate;
3375}
3376
3377int
3378tun_write_win32(struct tuntap *tt, struct buffer *buf)
3379{
3380 int err = 0;
3381 int status = 0;
3382 if (overlapped_io_active(&tt->writes))
3383 {
3384 sockethandle_t sh = { .is_handle = true, .h = tt->hand };
3385 status = sockethandle_finalize(sh, &tt->writes, NULL, NULL);
3386 if (status < 0)
3387 {
3388 err = GetLastError();
3389 }
3390 }
3391 tun_write_queue(tt, buf);
3392 if (status < 0)
3393 {
3394 SetLastError(err);
3395 return status;
3396 }
3397 else
3398 {
3399 return BLEN(buf);
3400 }
3401}
3402
3403static const struct device_instance_id_interface *
3405{
3406 HDEVINFO dev_info_set;
3407 DWORD err;
3408 struct device_instance_id_interface *first = NULL;
3409 struct device_instance_id_interface *last = NULL;
3410
3411 dev_info_set =
3412 SetupDiGetClassDevsEx(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
3413 if (dev_info_set == INVALID_HANDLE_VALUE)
3414 {
3415 err = GetLastError();
3416 msg(M_FATAL, "Error [%lu] opening device information set key: %s", err,
3417 strerror_win32(err, gc));
3418 }
3419
3420 msg(D_TAP_WIN_DEBUG, "Enumerate device interface lists:");
3421 for (DWORD i = 0;; ++i)
3422 {
3423 SP_DEVINFO_DATA device_info_data;
3424 BOOL res;
3425 HKEY dev_key;
3426 char net_cfg_instance_id_string[] = "NetCfgInstanceId";
3427 BYTE net_cfg_instance_id[256];
3428 char device_instance_id[256];
3429 DWORD len;
3430 DWORD data_type;
3431 LONG status;
3432 ULONG dev_interface_list_size;
3433 CONFIGRET cr;
3434
3435 ZeroMemory(&device_info_data, sizeof(SP_DEVINFO_DATA));
3436 device_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
3437 res = SetupDiEnumDeviceInfo(dev_info_set, i, &device_info_data);
3438 if (!res)
3439 {
3440 if (GetLastError() == ERROR_NO_MORE_ITEMS)
3441 {
3442 break;
3443 }
3444 else
3445 {
3446 continue;
3447 }
3448 }
3449
3450 dev_key = SetupDiOpenDevRegKey(dev_info_set, &device_info_data, DICS_FLAG_GLOBAL, 0,
3451 DIREG_DRV, KEY_QUERY_VALUE);
3452 if (dev_key == INVALID_HANDLE_VALUE)
3453 {
3454 continue;
3455 }
3456
3457 len = sizeof(net_cfg_instance_id);
3458 data_type = REG_SZ;
3459 status = RegQueryValueEx(dev_key, net_cfg_instance_id_string, NULL, &data_type,
3460 net_cfg_instance_id, &len);
3461 if (status != ERROR_SUCCESS)
3462 {
3463 goto next;
3464 }
3465
3466 len = sizeof(device_instance_id);
3467 res = SetupDiGetDeviceInstanceId(dev_info_set, &device_info_data, device_instance_id, len,
3468 &len);
3469 if (!res)
3470 {
3471 goto next;
3472 }
3473
3474 cr = CM_Get_Device_Interface_List_Size(&dev_interface_list_size,
3475 (LPGUID)&GUID_DEVINTERFACE_NET, device_instance_id,
3476 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3477
3478 if (cr != CR_SUCCESS)
3479 {
3480 goto next;
3481 }
3482
3483 char *dev_interface_list = gc_malloc(dev_interface_list_size, false, gc);
3484 cr = CM_Get_Device_Interface_List((LPGUID)&GUID_DEVINTERFACE_NET, device_instance_id,
3485 dev_interface_list, dev_interface_list_size,
3486 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3487 if (cr != CR_SUCCESS)
3488 {
3489 goto next;
3490 }
3491
3492 char *dev_if = dev_interface_list;
3493
3494 /* device interface list ends with empty string */
3495 while (strlen(dev_if) > 0)
3496 {
3497 struct device_instance_id_interface *dev_iif;
3499 dev_iif->net_cfg_instance_id =
3500 (unsigned char *)string_alloc((char *)net_cfg_instance_id, gc);
3501 dev_iif->device_interface = string_alloc(dev_if, gc);
3502
3503 msg(D_TAP_WIN_DEBUG, "NetCfgInstanceId: %s, Device Interface: %s",
3504 dev_iif->net_cfg_instance_id, dev_iif->device_interface);
3505
3506 /* link into return list */
3507 if (!first)
3508 {
3509 first = dev_iif;
3510 }
3511 if (last)
3512 {
3513 last->next = dev_iif;
3514 }
3515 last = dev_iif;
3516
3517 dev_if += strlen(dev_if) + 1;
3518 }
3519
3520next:
3521 RegCloseKey(dev_key);
3522 }
3523
3524 SetupDiDestroyDeviceInfoList(dev_info_set);
3525
3526 return first;
3527}
3528
3529static const struct tap_reg *
3531{
3532 HKEY adapter_key;
3533 LONG status;
3534 DWORD len;
3535 struct tap_reg *first = NULL;
3536 struct tap_reg *last = NULL;
3537 int i = 0;
3538
3539 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ADAPTER_KEY, 0, KEY_READ, &adapter_key);
3540
3541 if (status != ERROR_SUCCESS)
3542 {
3543 msg(M_FATAL, "Error opening registry key: %s", ADAPTER_KEY);
3544 }
3545
3546 msg(D_TAP_WIN_DEBUG, "Enumerate drivers in registy: ");
3547 while (true)
3548 {
3549 char enum_name[256];
3550 char unit_string[256];
3551 HKEY unit_key;
3552 char component_id_string[] = "ComponentId";
3553 char component_id[256];
3554 char net_cfg_instance_id_string[] = "NetCfgInstanceId";
3555 BYTE net_cfg_instance_id[256];
3556 DWORD data_type;
3557
3558 len = sizeof(enum_name);
3559 status = RegEnumKeyEx(adapter_key, i, enum_name, &len, NULL, NULL, NULL, NULL);
3560 if (status == ERROR_NO_MORE_ITEMS)
3561 {
3562 break;
3563 }
3564 else if (status != ERROR_SUCCESS)
3565 {
3566 msg(M_FATAL, "Error enumerating registry subkeys of key: %s", ADAPTER_KEY);
3567 }
3568
3569 if (!checked_snprintf(unit_string, sizeof(unit_string), "%s\\%s", ADAPTER_KEY, enum_name))
3570 {
3571 msg(M_WARN, "Error constructing unit string for %s", enum_name);
3572 continue;
3573 }
3574
3575 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, unit_string, 0, KEY_READ, &unit_key);
3576
3577 if (status != ERROR_SUCCESS)
3578 {
3579 dmsg(D_REGISTRY, "Error opening registry key: %s", unit_string);
3580 }
3581 else
3582 {
3583 len = sizeof(component_id);
3584 status = RegQueryValueEx(unit_key, component_id_string, NULL, &data_type,
3585 (LPBYTE)component_id, &len);
3586
3587 if (status != ERROR_SUCCESS || data_type != REG_SZ)
3588 {
3589 dmsg(D_REGISTRY, "Error opening registry key: %s\\%s", unit_string,
3590 component_id_string);
3591 }
3592 else
3593 {
3594 len = sizeof(net_cfg_instance_id);
3595 status = RegQueryValueEx(unit_key, net_cfg_instance_id_string, NULL, &data_type,
3596 net_cfg_instance_id, &len);
3597
3598 if (status == ERROR_SUCCESS && data_type == REG_SZ)
3599 {
3600 /* Is this adapter supported? */
3602 if (strcasecmp(component_id, TAP_WIN_COMPONENT_ID) == 0
3603 || strcasecmp(component_id, "root\\" TAP_WIN_COMPONENT_ID) == 0)
3604 {
3606 }
3607 else if (strcasecmp(component_id, "ovpn-dco") == 0)
3608 {
3610 }
3611
3613 {
3614 struct tap_reg *reg;
3615 ALLOC_OBJ_CLEAR_GC(reg, struct tap_reg, gc);
3616 reg->guid = string_alloc((char *)net_cfg_instance_id, gc);
3618
3619 /* link into return list */
3620 if (!first)
3621 {
3622 first = reg;
3623 }
3624 if (last)
3625 {
3626 last->next = reg;
3627 }
3628 last = reg;
3629
3630 msg(D_TAP_WIN_DEBUG, "NetCfgInstanceId: %s, Driver: %s", reg->guid,
3632 }
3633 }
3634 }
3635 RegCloseKey(unit_key);
3636 }
3637 ++i;
3638 }
3639
3640 RegCloseKey(adapter_key);
3641 return first;
3642}
3643
3644static const struct panel_reg *
3646{
3647 LONG status;
3648 HKEY network_connections_key;
3649 DWORD len;
3650 struct panel_reg *first = NULL;
3651 struct panel_reg *last = NULL;
3652 int i = 0;
3653
3654 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ,
3655 &network_connections_key);
3656
3657 if (status != ERROR_SUCCESS)
3658 {
3659 msg(M_FATAL, "Error opening registry key: %s", NETWORK_CONNECTIONS_KEY);
3660 }
3661
3662 while (true)
3663 {
3664 char enum_name[256];
3665 char connection_string[256];
3666 HKEY connection_key;
3667 WCHAR name_data[256];
3668 DWORD name_type;
3669 const WCHAR name_string[] = L"Name";
3670
3671 len = sizeof(enum_name);
3672 status = RegEnumKeyEx(network_connections_key, i, enum_name, &len, NULL, NULL, NULL, NULL);
3673 if (status == ERROR_NO_MORE_ITEMS)
3674 {
3675 break;
3676 }
3677 else if (status != ERROR_SUCCESS)
3678 {
3679 msg(M_FATAL, "Error enumerating registry subkeys of key: %s", NETWORK_CONNECTIONS_KEY);
3680 }
3681
3682 if (!checked_snprintf(connection_string, sizeof(connection_string),
3683 "%s\\%s\\Connection",
3684 NETWORK_CONNECTIONS_KEY, enum_name))
3685 {
3686 msg(M_WARN, "Error constructing connection string for %s", enum_name);
3687 continue;
3688 }
3689
3690
3691 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, connection_string, 0, KEY_READ, &connection_key);
3692
3693 if (status != ERROR_SUCCESS)
3694 {
3695 dmsg(D_REGISTRY, "Error opening registry key: %s", connection_string);
3696 }
3697 else
3698 {
3699 len = sizeof(name_data);
3700 status = RegQueryValueExW(connection_key, name_string, NULL, &name_type,
3701 (LPBYTE)name_data, &len);
3702
3703 if (status != ERROR_SUCCESS || name_type != REG_SZ)
3704 {
3705 dmsg(D_REGISTRY, "Error opening registry key: %s\\%s\\%ls", NETWORK_CONNECTIONS_KEY,
3706 connection_string, name_string);
3707 }
3708 else
3709 {
3710 int n;
3711 LPSTR name;
3712 struct panel_reg *reg;
3713
3714 ALLOC_OBJ_CLEAR_GC(reg, struct panel_reg, gc);
3715 n = WideCharToMultiByte(CP_UTF8, 0, name_data, -1, NULL, 0, NULL, NULL);
3716 name = gc_malloc(n, false, gc);
3717 WideCharToMultiByte(CP_UTF8, 0, name_data, -1, name, n, NULL, NULL);
3718 reg->name = name;
3719 reg->guid = string_alloc(enum_name, gc);
3720
3721 /* link into return list */
3722 if (!first)
3723 {
3724 first = reg;
3725 }
3726 if (last)
3727 {
3728 last->next = reg;
3729 }
3730 last = reg;
3731 }
3732 RegCloseKey(connection_key);
3733 }
3734 ++i;
3735 }
3736
3737 RegCloseKey(network_connections_key);
3738
3739 return first;
3740}
3741
3742/*
3743 * Check that two addresses are part of the same 255.255.255.252 subnet.
3744 */
3745void
3747{
3748 struct gc_arena gc = gc_new();
3749 const unsigned int mask = 3;
3750 const char *err = NULL;
3751
3752 if (local == remote)
3753 {
3754 err = "must be different";
3755 goto error;
3756 }
3757 if ((local & (~mask)) != (remote & (~mask)))
3758 {
3759 err =
3760 "must exist within the same 255.255.255.252 subnet. This is a limitation of --dev tun when used with the TAP-WIN32 driver";
3761 goto error;
3762 }
3763 if ((local & mask) == 0 || (local & mask) == 3 || (remote & mask) == 0 || (remote & mask) == 3)
3764 {
3765 err =
3766 "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";
3767 goto error;
3768 }
3769
3770 gc_free(&gc);
3771 return;
3772
3773error:
3774 msg(M_FATAL,
3775 "There is a problem in your selection of --ifconfig endpoints [local=%s, remote=%s]. The local and remote VPN endpoints %s. Try '" PACKAGE
3776 " --show-valid-subnets' option for more info.",
3777 print_in_addr_t(local, 0, &gc), print_in_addr_t(remote, 0, &gc), err);
3778 gc_free(&gc);
3779}
3780
3781void
3783{
3784 int i;
3785 int col = 0;
3786
3787 printf("On Windows, point-to-point IP support (i.e. --dev tun)\n");
3788 printf("is emulated by the TAP-Windows driver. The major limitation\n");
3789 printf("imposed by this approach is that the --ifconfig local and\n");
3790 printf("remote endpoints must be part of the same 255.255.255.252\n");
3791 printf("subnet. The following list shows examples of endpoint\n");
3792 printf("pairs which satisfy this requirement. Only the final\n");
3793 printf("component of the IP address pairs is at issue.\n\n");
3794 printf("As an example, the following option would be correct:\n");
3795 printf(" --ifconfig 10.7.0.5 10.7.0.6 (on host A)\n");
3796 printf(" --ifconfig 10.7.0.6 10.7.0.5 (on host B)\n");
3797 printf("because [5,6] is part of the below list.\n\n");
3798
3799 for (i = 0; i < 256; i += 4)
3800 {
3801 printf("[%3d,%3d] ", i + 1, i + 2);
3802 if (++col > 4)
3803 {
3804 col = 0;
3805 printf("\n");
3806 }
3807 }
3808 if (col)
3809 {
3810 printf("\n");
3811 }
3812}
3813
3814void
3816{
3817 struct gc_arena gc = gc_new();
3818
3819 bool warn_panel_null = false;
3820 bool warn_panel_dup = false;
3821 bool warn_tap_dup = false;
3822
3823 int links;
3824
3825 const struct tap_reg *tr;
3826 const struct tap_reg *tr1;
3827 const struct panel_reg *pr;
3828
3829 const struct tap_reg *tap_reg = get_tap_reg(&gc);
3830 const struct panel_reg *panel_reg = get_panel_reg(&gc);
3831
3832 msg(msglevel, "Available adapters [name, GUID, driver]:");
3833
3834 /* loop through each TAP-Windows adapter registry entry */
3835 for (tr = tap_reg; tr != NULL; tr = tr->next)
3836 {
3837 links = 0;
3838
3839 /* loop through each network connections entry in the control panel */
3840 for (pr = panel_reg; pr != NULL; pr = pr->next)
3841 {
3842 if (!strcmp(tr->guid, pr->guid))
3843 {
3844 msg(msglevel, "'%s' %s %s", pr->name, tr->guid,
3846 ++links;
3847 }
3848 }
3849
3850 if (links > 1)
3851 {
3852 warn_panel_dup = true;
3853 }
3854 else if (links == 0)
3855 {
3856 /* a TAP adapter exists without a link from the network
3857 * connections control panel */
3858 warn_panel_null = true;
3859 msg(msglevel, "[NULL] %s", tr->guid);
3860 }
3861 }
3862
3863 /* check for TAP-Windows adapter duplicated GUIDs */
3864 for (tr = tap_reg; tr != NULL; tr = tr->next)
3865 {
3866 for (tr1 = tap_reg; tr1 != NULL; tr1 = tr1->next)
3867 {
3868 if (tr != tr1 && !strcmp(tr->guid, tr1->guid))
3869 {
3870 warn_tap_dup = true;
3871 }
3872 }
3873 }
3874
3875 /* warn on registry inconsistencies */
3876 if (warn_tap_dup)
3877 {
3878 msg(warnlevel, "WARNING: Some TAP-Windows adapters have duplicate GUIDs");
3879 }
3880
3881 if (warn_panel_dup)
3882 {
3883 msg(warnlevel,
3884 "WARNING: Some TAP-Windows adapters have duplicate links from the Network Connections control panel");
3885 }
3886
3887 if (warn_panel_null)
3888 {
3889 msg(warnlevel,
3890 "WARNING: Some TAP-Windows adapters have no link from the Network Connections control panel");
3891 }
3892
3893 gc_free(&gc);
3894}
3895
3896/*
3897 * Lookup an adapter by GUID.
3898 */
3899static const struct tap_reg *
3900get_adapter_by_guid(const char *guid, const struct tap_reg *tap_reg)
3901{
3902 const struct tap_reg *tr;
3903
3904 for (tr = tap_reg; tr != NULL; tr = tr->next)
3905 {
3906 if (guid && !strcmp(tr->guid, guid))
3907 {
3908 return tr;
3909 }
3910 }
3911
3912 return NULL;
3913}
3914
3915static const char *
3916guid_to_name(const char *guid, const struct panel_reg *panel_reg)
3917{
3918 const struct panel_reg *pr;
3919
3920 for (pr = panel_reg; pr != NULL; pr = pr->next)
3921 {
3922 if (guid && !strcmp(pr->guid, guid))
3923 {
3924 return pr->name;
3925 }
3926 }
3927
3928 return NULL;
3929}
3930
3931static const struct tap_reg *
3932get_adapter_by_name(const char *name, const struct tap_reg *tap_reg,
3933 const struct panel_reg *panel_reg)
3934{
3935 const struct panel_reg *pr;
3936
3937 for (pr = panel_reg; pr != NULL; pr = pr->next)
3938 {
3939 if (name && !strcmp(pr->name, name))
3940 {
3941 return get_adapter_by_guid(pr->guid, tap_reg);
3942 }
3943 }
3944
3945 return NULL;
3946}
3947
3948static void
3950{
3951 if (!tap_reg)
3952 {
3953 msg(M_FATAL, "There are no TAP-Windows or ovpn-dco adapters "
3954 "on this system. You should be able to create an adapter "
3955 "by using tapctl.exe utility.");
3956 }
3957}
3958
3959/*
3960 * Get an adapter GUID and optional actual_name from the
3961 * registry for the TAP device # = device_number.
3962 */
3963static const char *
3964get_unspecified_device_guid(const int device_number, uint8_t *actual_name, int actual_name_size,
3965 const struct tap_reg *tap_reg_src,
3966 const struct panel_reg *panel_reg_src,
3967 enum tun_driver_type *windows_driver, struct gc_arena *gc)
3968{
3969 const struct tap_reg *tap_reg = tap_reg_src;
3970 struct buffer actual = clear_buf();
3971 int i;
3972
3973 ASSERT(device_number >= 0);
3974
3975 /* Make sure we have at least one TAP adapter */
3976 if (!tap_reg)
3977 {
3978 return NULL;
3979 }
3980
3981 /* The actual_name output buffer may be NULL */
3982 if (actual_name)
3983 {
3985 buf_set_write(&actual, actual_name, actual_name_size);
3986 }
3987
3988 /* Move on to specified device number */
3989 for (i = 0; i < device_number; i++)
3990 {
3991 tap_reg = tap_reg->next;
3992 if (!tap_reg)
3993 {
3994 return NULL;
3995 }
3996 }
3997
3998 /* Save Network Panel name (if exists) in actual_name */
3999 if (actual_name)
4000 {
4001 const char *act = guid_to_name(tap_reg->guid, panel_reg_src);
4002 if (act)
4003 {
4004 buf_printf(&actual, "%s", act);
4005 }
4006 else
4007 {
4008 buf_printf(&actual, "%s", tap_reg->guid);
4009 }
4010 }
4011
4012 /* Save GUID for return value */
4013 struct buffer ret = alloc_buf_gc(256, gc);
4014 buf_printf(&ret, "%s", tap_reg->guid);
4015 if (windows_driver != NULL)
4016 {
4017 *windows_driver = tap_reg->windows_driver;
4018 }
4019 return BSTR(&ret);
4020}
4021
4022/*
4023 * Lookup a --dev-node adapter name in the registry
4024 * returning the GUID and optional actual_name and device type
4025 */
4026static const char *
4027get_device_guid(const char *name, uint8_t *actual_name, int actual_name_size,
4028 enum tun_driver_type *windows_driver, const struct tap_reg *tap_reg,
4029 const struct panel_reg *panel_reg, struct gc_arena *gc)
4030{
4031 struct buffer ret = alloc_buf_gc(256, gc);
4032 struct buffer actual = clear_buf();
4033 const struct tap_reg *tr;
4034
4035 /* Make sure we have at least one TAP adapter */
4036 if (!tap_reg)
4037 {
4038 return NULL;
4039 }
4040
4041 /* The actual_name output buffer may be NULL */
4042 if (actual_name)
4043 {
4044 ASSERT(actual_name_size > 0);
4045 buf_set_write(&actual, actual_name, actual_name_size);
4046 }
4047
4048 /* Check if GUID was explicitly specified as --dev-node parameter */
4049 tr = get_adapter_by_guid(name, tap_reg);
4050 if (tr)
4051 {
4052 const char *act = guid_to_name(name, panel_reg);
4053 buf_printf(&ret, "%s", name);
4054 if (act)
4055 {
4056 buf_printf(&actual, "%s", act);
4057 }
4058 else
4059 {
4060 buf_printf(&actual, "%s", name);
4061 }
4062 if (windows_driver)
4063 {
4065 }
4066 return BSTR(&ret);
4067 }
4068
4069 /* Lookup TAP adapter in network connections list */
4070 {
4072 if (tr)
4073 {
4074 buf_printf(&actual, "%s", name);
4075 if (windows_driver)
4076 {
4078 }
4079 buf_printf(&ret, "%s", tr->guid);
4080 return BSTR(&ret);
4081 }
4082 }
4083
4084 return NULL;
4085}
4086
4087/*
4088 * Get adapter info list
4089 */
4090const IP_ADAPTER_INFO *
4092{
4093 ULONG size = 0;
4094 IP_ADAPTER_INFO *pi = NULL;
4095 DWORD status;
4096
4097 if ((status = GetAdaptersInfo(NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4098 {
4099 msg(M_INFO, "GetAdaptersInfo #1 failed (status=%lu) : %s", status,
4101 }
4102 else
4103 {
4104 pi = (PIP_ADAPTER_INFO)gc_malloc(size, false, gc);
4105 if ((status = GetAdaptersInfo(pi, &size)) != NO_ERROR)
4106 {
4107 msg(M_INFO, "GetAdaptersInfo #2 failed (status=%lu) : %s", status,
4109 pi = NULL;
4110 }
4111 }
4112 return pi;
4113}
4114
4115const IP_PER_ADAPTER_INFO *
4116get_per_adapter_info(const DWORD index, struct gc_arena *gc)
4117{
4118 ULONG size = 0;
4119 IP_PER_ADAPTER_INFO *pi = NULL;
4120 DWORD status;
4121
4122 if (index != TUN_ADAPTER_INDEX_INVALID)
4123 {
4124 if ((status = GetPerAdapterInfo(index, NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4125 {
4126 msg(M_INFO, "GetPerAdapterInfo #1 failed (status=%lu) : %s", status,
4128 }
4129 else
4130 {
4131 pi = (PIP_PER_ADAPTER_INFO)gc_malloc(size, false, gc);
4132 if ((status = GetPerAdapterInfo(index, pi, &size)) == ERROR_SUCCESS)
4133 {
4134 return pi;
4135 }
4136 else
4137 {
4138 msg(M_INFO, "GetPerAdapterInfo #2 failed (status=%lu) : %s", status,
4140 }
4141 }
4142 }
4143 return pi;
4144}
4145
4146static const IP_INTERFACE_INFO *
4148{
4149 ULONG size = 0;
4150 IP_INTERFACE_INFO *ii = NULL;
4151 DWORD status;
4152
4153 if ((status = GetInterfaceInfo(NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)
4154 {
4155 msg(M_INFO, "GetInterfaceInfo #1 failed (status=%lu) : %s", status,
4157 }
4158 else
4159 {
4160 ii = (PIP_INTERFACE_INFO)gc_malloc(size, false, gc);
4161 if ((status = GetInterfaceInfo(ii, &size)) == NO_ERROR)
4162 {
4163 return ii;
4164 }
4165 else
4166 {
4167 msg(M_INFO, "GetInterfaceInfo #2 failed (status=%lu) : %s", status,
4169 }
4170 }
4171 return ii;
4172}
4173
4174static const IP_ADAPTER_INDEX_MAP *
4175get_interface_info(DWORD index, struct gc_arena *gc)
4176{
4177 const IP_INTERFACE_INFO *list = get_interface_info_list(gc);
4178 if (list)
4179 {
4180 int i;
4181 for (i = 0; i < list->NumAdapters; ++i)
4182 {
4183 const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[i];
4184 if (index == inter->Index)
4185 {
4186 return inter;
4187 }
4188 }
4189 }
4190 return NULL;
4191}
4192
4193/*
4194 * Given an adapter index, return a pointer to the
4195 * IP_ADAPTER_INFO structure for that adapter.
4196 */
4197
4198const IP_ADAPTER_INFO *
4199get_adapter(const IP_ADAPTER_INFO *ai, DWORD index)
4200{
4201 if (ai && index != TUN_ADAPTER_INDEX_INVALID)
4202 {
4203 const IP_ADAPTER_INFO *a;
4204
4205 /* find index in the linked list */
4206 for (a = ai; a != NULL; a = a->Next)
4207 {
4208 if (a->Index == index)
4209 {
4210 return a;
4211 }
4212 }
4213 }
4214 return NULL;
4215}
4216
4217const IP_ADAPTER_INFO *
4218get_adapter_info(DWORD index, struct gc_arena *gc)
4219{
4220 return get_adapter(get_adapter_info_list(gc), index);
4221}
4222
4223static int
4224get_adapter_n_ip_netmask(const IP_ADAPTER_INFO *ai)
4225{
4226 if (ai)
4227 {
4228 int n = 0;
4229 const IP_ADDR_STRING *ip = &ai->IpAddressList;
4230
4231 while (ip)
4232 {
4233 ++n;
4234 ip = ip->Next;
4235 }
4236 return n;
4237 }
4238 else
4239 {
4240 return 0;
4241 }
4242}
4243
4244static bool
4245get_adapter_ip_netmask(const IP_ADAPTER_INFO *ai, const int n, in_addr_t *ip, in_addr_t *netmask)
4246{
4247 bool ret = false;
4248 *ip = 0;
4249 *netmask = 0;
4250
4251 if (ai)
4252 {
4253 const IP_ADDR_STRING *iplist = &ai->IpAddressList;
4254 int i = 0;
4255
4256 while (iplist)
4257 {
4258 if (i == n)
4259 {
4260 break;
4261 }
4262 ++i;
4263 iplist = iplist->Next;
4264 }
4265
4266 if (iplist)
4267 {
4268 const unsigned int getaddr_flags = GETADDR_HOST_ORDER;
4269 const char *ip_str = iplist->IpAddress.String;
4270 const char *netmask_str = iplist->IpMask.String;
4271 bool succeed1 = false;
4272 bool succeed2 = false;
4273
4274 if (ip_str && netmask_str && strlen(ip_str) && strlen(netmask_str))
4275 {
4276 *ip = getaddr(getaddr_flags, ip_str, 0, &succeed1, NULL);
4277 *netmask = getaddr(getaddr_flags, netmask_str, 0, &succeed2, NULL);
4278 ret = (succeed1 == true && succeed2 == true);
4279 }
4280 }
4281 }
4282
4283 return ret;
4284}
4285
4286static bool
4287test_adapter_ip_netmask(const IP_ADAPTER_INFO *ai, const in_addr_t ip, const in_addr_t netmask)
4288{
4289 if (ai)
4290 {
4291 in_addr_t ip_adapter = 0;
4292 in_addr_t netmask_adapter = 0;
4293 const bool status = get_adapter_ip_netmask(ai, 0, &ip_adapter, &netmask_adapter);
4294 return (status && ip_adapter == ip && netmask_adapter == netmask);
4295 }
4296 else
4297 {
4298 return false;
4299 }
4300}
4301
4302const IP_ADAPTER_INFO *
4303get_tun_adapter(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
4304{
4305 if (list && tt)
4306 {
4307 return get_adapter(list, tt->adapter_index);
4308 }
4309 else
4310 {
4311 return NULL;
4312 }
4313}
4314
4315bool
4316is_adapter_up(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
4317{
4318 int i;
4319 bool ret = false;
4320
4321 const IP_ADAPTER_INFO *ai = get_tun_adapter(tt, list);
4322
4323 if (ai)
4324 {
4325 const int n = get_adapter_n_ip_netmask(ai);
4326
4327 /* loop once for every IP/netmask assigned to adapter */
4328 for (i = 0; i < n; ++i)
4329 {
4330 in_addr_t ip, netmask;
4331 if (get_adapter_ip_netmask(ai, i, &ip, &netmask))
4332 {
4333 if (tt->local && tt->adapter_netmask)
4334 {
4335 /* wait for our --ifconfig parms to match the actual adapter parms */
4336 if (tt->local == ip && tt->adapter_netmask == netmask)
4337 {
4338 ret = true;
4339 }
4340 }
4341 else
4342 {
4343 /* --ifconfig was not defined, maybe using a real DHCP server */
4344 if (ip && netmask)
4345 {
4346 ret = true;
4347 }
4348 }
4349 }
4350 }
4351 }
4352 else
4353 {
4354 ret = true; /* this can occur when TAP adapter is bridged */
4355 }
4356 return ret;
4357}
4358
4359bool
4360is_ip_in_adapter_subnet(const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask)
4361{
4362 int i;
4363 bool ret = false;
4364
4365 if (highest_netmask)
4366 {
4367 *highest_netmask = 0;
4368 }
4369
4370 if (ai)
4371 {
4372 const int n = get_adapter_n_ip_netmask(ai);
4373 for (i = 0; i < n; ++i)
4374 {
4375 in_addr_t adapter_ip, adapter_netmask;
4376 if (get_adapter_ip_netmask(ai, i, &adapter_ip, &adapter_netmask))
4377 {
4378 if (adapter_ip && adapter_netmask
4379 && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))
4380 {
4381 if (highest_netmask && adapter_netmask > *highest_netmask)
4382 {
4383 *highest_netmask = adapter_netmask;
4384 }
4385 ret = true;
4386 }
4387 }
4388 }
4389 }
4390 return ret;
4391}
4392
4393DWORD
4394adapter_index_of_ip(const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count, in_addr_t *netmask)
4395{
4396 struct gc_arena gc = gc_new();
4397 DWORD ret = TUN_ADAPTER_INDEX_INVALID;
4398 in_addr_t highest_netmask = 0;
4399 int lowest_metric = INT_MAX;
4400 bool first = true;
4401
4402 if (count)
4403 {
4404 *count = 0;
4405 }
4406
4407 while (list)
4408 {
4409 in_addr_t hn;
4410
4411 if (is_ip_in_adapter_subnet(list, ip, &hn))
4412 {
4413 int metric = get_interface_metric(list->Index, AF_INET, NULL);
4414 if (first || hn > highest_netmask)
4415 {
4416 highest_netmask = hn;
4417 if (metric >= 0)
4418 {
4419 lowest_metric = metric;
4420 }
4421 if (count)
4422 {
4423 *count = 1;
4424 }
4425 ret = list->Index;
4426 first = false;
4427 }
4428 else if (hn == highest_netmask)
4429 {
4430 if (count)
4431 {
4432 ++*count;
4433 }
4434 if (metric >= 0 && metric < lowest_metric)
4435 {
4436 ret = list->Index;
4437 lowest_metric = metric;
4438 }
4439 }
4440 }
4441 list = list->Next;
4442 }
4443
4444 dmsg(D_ROUTE_DEBUG, "DEBUG: IP Locate: ip=%s nm=%s index=%lu count=%d metric=%d",
4445 print_in_addr_t(ip, 0, &gc), print_in_addr_t(highest_netmask, 0, &gc), ret,
4446 count ? *count : -1, lowest_metric);
4447
4448 if (ret == TUN_ADAPTER_INDEX_INVALID && count)
4449 {
4450 *count = 0;
4451 }
4452
4453 if (netmask)
4454 {
4455 *netmask = highest_netmask;
4456 }
4457
4458 gc_free(&gc);
4459 return ret;
4460}
4461
4462/*
4463 * Given an adapter index, return true if the adapter
4464 * is DHCP disabled.
4465 */
4466
4467#define DHCP_STATUS_UNDEF 0
4468#define DHCP_STATUS_ENABLED 1
4469#define DHCP_STATUS_DISABLED 2
4470
4471static int
4472dhcp_status(DWORD index)
4473{
4474 struct gc_arena gc = gc_new();
4475 int ret = DHCP_STATUS_UNDEF;
4476 if (index != TUN_ADAPTER_INDEX_INVALID)
4477 {
4478 const IP_ADAPTER_INFO *ai = get_adapter_info(index, &gc);
4479
4480 if (ai)
4481 {
4482 if (ai->DhcpEnabled)
4483 {
4484 ret = DHCP_STATUS_ENABLED;
4485 }
4486 else
4487 {
4489 }
4490 }
4491 }
4492 gc_free(&gc);
4493 return ret;
4494}
4495
4496/*
4497 * Delete all temporary address/netmask pairs which were added
4498 * to adapter (given by index) by previous calls to AddIPAddress.
4499 */
4500static void
4502{
4503 struct gc_arena gc = gc_new();
4504 const IP_ADAPTER_INFO *a = get_adapter_info(index, &gc);
4505
4506 if (a)
4507 {
4508 const IP_ADDR_STRING *ip = &a->IpAddressList;
4509 while (ip)
4510 {
4511 DWORD status;
4512 const DWORD context = ip->Context;
4513
4514 if ((status = DeleteIPAddress(context)) == NO_ERROR)
4515 {
4516 msg(M_INFO, "Successfully deleted previously set dynamic IP/netmask: %s/%s",
4517 ip->IpAddress.String, ip->IpMask.String);
4518 }
4519 else
4520 {
4521 const char *empty = "0.0.0.0";
4522 if (strcmp(ip->IpAddress.String, empty) || strcmp(ip->IpMask.String, empty))
4523 {
4524 msg(M_INFO,
4525 "NOTE: could not delete previously set dynamic IP/netmask: %s/%s (status=%lu)",
4526 ip->IpAddress.String, ip->IpMask.String, status);
4527 }
4528 }
4529 ip = ip->Next;
4530 }
4531 }
4532 gc_free(&gc);
4533}
4534
4535/*
4536 * Get interface index for use with IP Helper API functions.
4537 */
4538static DWORD
4540{
4541 DWORD index;
4542 ULONG aindex;
4543 wchar_t wbuf[256];
4544 swprintf(wbuf, SIZE(wbuf), L"\\DEVICE\\TCPIP_%hs", guid);
4545 if (GetAdapterIndex(wbuf, &aindex) != NO_ERROR)
4546 {
4548 }
4549 else
4550 {
4551 index = (DWORD)aindex;
4552 }
4553 return index;
4554}
4555
4556static DWORD
4558{
4559 struct gc_arena gc = gc_new();
4560 DWORD index = TUN_ADAPTER_INDEX_INVALID;
4561
4562 const IP_ADAPTER_INFO *list = get_adapter_info_list(&gc);
4563
4564 while (list)
4565 {
4566 if (!strcmp(guid, list->AdapterName))
4567 {
4568 index = list->Index;
4569 break;
4570 }
4571 list = list->Next;
4572 }
4573
4574 gc_free(&gc);
4575 return index;
4576}
4577
4578static DWORD
4579get_adapter_index(const char *guid)
4580{
4581 DWORD index;
4582 index = get_adapter_index_method_1(guid);
4583 if (index == TUN_ADAPTER_INDEX_INVALID)
4584 {
4585 index = get_adapter_index_method_2(guid);
4586 }
4587 if (index == TUN_ADAPTER_INDEX_INVALID)
4588 {
4589 msg(M_INFO, "NOTE: could not get adapter index for %s", guid);
4590 }
4591 return index;
4592}
4593
4594/*
4595 * Return a string representing a PIP_ADDR_STRING
4596 */
4597static const char *
4598format_ip_addr_string(const IP_ADDR_STRING *ip, struct gc_arena *gc)
4599{
4600 struct buffer out = alloc_buf_gc(256, gc);
4601 while (ip)
4602 {
4603 buf_printf(&out, "%s", ip->IpAddress.String);
4604 if (strlen(ip->IpMask.String))
4605 {
4606 buf_printf(&out, "/");
4607 buf_printf(&out, "%s", ip->IpMask.String);
4608 }
4609 buf_printf(&out, " ");
4610 ip = ip->Next;
4611 }
4612 return BSTR(&out);
4613}
4614
4615/*
4616 * Show info for a single adapter
4617 */
4618static void
4620{
4621 msg(msglevel, "%s", a->Description);
4622 msg(msglevel, " Index = %lu", a->Index);
4623 msg(msglevel, " GUID = %s", a->AdapterName);
4624 msg(msglevel, " IP = %s", format_ip_addr_string(&a->IpAddressList, gc));
4625 msg(msglevel, " MAC = %s", format_hex_ex(a->Address, a->AddressLength, 0, 1, ":", gc));
4626 msg(msglevel, " GATEWAY = %s", format_ip_addr_string(&a->GatewayList, gc));
4627 if (a->DhcpEnabled)
4628 {
4629 msg(msglevel, " DHCP SERV = %s", format_ip_addr_string(&a->DhcpServer, gc));
4630 msg(msglevel, " DHCP LEASE OBTAINED = %s", time_string(a->LeaseObtained, 0, false, gc));
4631 msg(msglevel, " DHCP LEASE EXPIRES = %s", time_string(a->LeaseExpires, 0, false, gc));
4632 }
4633 if (a->HaveWins)
4634 {
4635 msg(msglevel, " PRI WINS = %s", format_ip_addr_string(&a->PrimaryWinsServer, gc));
4636 msg(msglevel, " SEC WINS = %s", format_ip_addr_string(&a->SecondaryWinsServer, gc));
4637 }
4638
4639 {
4641 if (pai)
4642 {
4643 msg(msglevel, " DNS SERV = %s", format_ip_addr_string(&pai->DnsServerList, gc));
4644 }
4645 }
4646}
4647
4648/*
4649 * Show current adapter list
4650 */
4651void
4653{
4654 struct gc_arena gc = gc_new();
4655 const IP_ADAPTER_INFO *ai = get_adapter_info_list(&gc);
4656
4657 msg(msglevel, "SYSTEM ADAPTER LIST");
4658 if (ai)
4659 {
4660 const IP_ADAPTER_INFO *a;
4661
4662 /* find index in the linked list */
4663 for (a = ai; a != NULL; a = a->Next)
4664 {
4665 show_adapter(msglevel, a, &gc);
4666 }
4667 }
4668 gc_free(&gc);
4669}
4670
4671/*
4672 * Set a particular TAP-Windows adapter (or all of them if
4673 * adapter_name == NULL) to allow it to be opened from
4674 * a non-admin account. This setting will only persist
4675 * for the lifetime of the device object.
4676 */
4677
4678static void
4679tap_allow_nonadmin_access_handle(const char *device_path, HANDLE hand)
4680{
4681 struct security_attributes sa;
4682 BOOL status;
4683
4685 {
4686 msg(M_ERR, "Error: init SA failed");
4687 }
4688
4689 status = SetKernelObjectSecurity(hand, DACL_SECURITY_INFORMATION, &sa.sd);
4690 if (!status)
4691 {
4692 msg(M_ERRNO, "Error: SetKernelObjectSecurity failed on %s", device_path);
4693 }
4694 else
4695 {
4696 msg(M_INFO | M_NOPREFIX, "TAP-Windows device: %s [Non-admin access allowed]", device_path);
4697 }
4698}
4699
4700void
4701tap_allow_nonadmin_access(const char *dev_node)
4702{
4703 struct gc_arena gc = gc_new();
4704 const struct tap_reg *tap_reg = get_tap_reg(&gc);
4705 const struct panel_reg *panel_reg = get_panel_reg(&gc);
4706 const char *device_guid = NULL;
4707 HANDLE hand;
4708 uint8_t actual_buffer[256];
4709 char device_path[256];
4710
4712
4713 if (dev_node)
4714 {
4715 /* Get the device GUID for the device specified with --dev-node. */
4716 device_guid = get_device_guid(dev_node, actual_buffer, sizeof(actual_buffer), NULL, tap_reg,
4717 panel_reg, &gc);
4718
4719 if (!device_guid)
4720 {
4721 msg(M_FATAL, "TAP-Windows adapter '%s' not found", dev_node);
4722 }
4723
4724 /* Open Windows TAP-Windows adapter */
4725 snprintf(device_path, sizeof(device_path), "%s%s%s", USERMODEDEVICEDIR, device_guid,
4726 TAP_WIN_SUFFIX);
4727
4728 hand = CreateFile(device_path, MAXIMUM_ALLOWED, 0, /* was: FILE_SHARE_READ */
4729 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
4730
4731 if (hand == INVALID_HANDLE_VALUE)
4732 {
4733 msg(M_ERR, "CreateFile failed on TAP device: %s", device_path);
4734 }
4735
4736 tap_allow_nonadmin_access_handle(device_path, hand);
4737 CloseHandle(hand);
4738 }
4739 else
4740 {
4741 int device_number = 0;
4742
4743 /* Try opening all TAP devices */
4744 while (true)
4745 {
4746 device_guid = get_unspecified_device_guid(
4747 device_number, actual_buffer, sizeof(actual_buffer), tap_reg, panel_reg, NULL, &gc);
4748
4749 if (!device_guid)
4750 {
4751 break;
4752 }
4753
4754 /* Open Windows TAP-Windows adapter */
4755 snprintf(device_path, sizeof(device_path), "%s%s%s", USERMODEDEVICEDIR, device_guid,
4756 TAP_WIN_SUFFIX);
4757
4758 hand = CreateFile(device_path, MAXIMUM_ALLOWED, 0, /* was: FILE_SHARE_READ */
4759 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
4760
4761 if (hand == INVALID_HANDLE_VALUE)
4762 {
4763 msg(M_WARN, "CreateFile failed on TAP device: %s", device_path);
4764 }
4765 else
4766 {
4767 tap_allow_nonadmin_access_handle(device_path, hand);
4768 CloseHandle(hand);
4769 }
4770
4771 device_number++;
4772 }
4773 }
4774 gc_free(&gc);
4775}
4776
4777/*
4778 * DHCP release/renewal
4779 */
4780bool
4781dhcp_release_by_adapter_index(const DWORD adapter_index)
4782{
4783 struct gc_arena gc = gc_new();
4784 bool ret = false;
4785 const IP_ADAPTER_INDEX_MAP *inter = get_interface_info(adapter_index, &gc);
4786
4787 if (inter)
4788 {
4789 DWORD status = IpReleaseAddress((IP_ADAPTER_INDEX_MAP *)inter);
4790 if (status == NO_ERROR)
4791 {
4792 msg(D_TUNTAP_INFO, "TAP: DHCP address released");
4793 ret = true;
4794 }
4795 else
4796 {
4797 msg(M_WARN,
4798 "NOTE: Release of DHCP-assigned IP address lease on TAP-Windows adapter failed: %s (code=%lu)",
4800 }
4801 }
4802
4803 gc_free(&gc);
4804 return ret;
4805}
4806
4807static bool
4808dhcp_release(const struct tuntap *tt)
4809{
4812 {
4814 }
4815 else
4816 {
4817 return false;
4818 }
4819}
4820
4821bool
4822dhcp_renew_by_adapter_index(const DWORD adapter_index)
4823{
4824 struct gc_arena gc = gc_new();
4825 bool ret = false;
4826 const IP_ADAPTER_INDEX_MAP *inter = get_interface_info(adapter_index, &gc);
4827
4828 if (inter)
4829 {
4830 DWORD status = IpRenewAddress((IP_ADAPTER_INDEX_MAP *)inter);
4831 if (status == NO_ERROR)
4832 {
4833 msg(D_TUNTAP_INFO, "TAP: DHCP address renewal succeeded");
4834 ret = true;
4835 }
4836 else
4837 {
4838 msg(M_WARN,
4839 "WARNING: Failed to renew DHCP IP address lease on TAP-Windows adapter: %s (code=%lu)",
4841 }
4842 }
4843 gc_free(&gc);
4844 return ret;
4845}
4846
4847static bool
4848dhcp_renew(const struct tuntap *tt)
4849{
4852 {
4854 }
4855 else
4856 {
4857 return false;
4858 }
4859}
4860
4861static void
4862exec_command(const char *prefix, const struct argv *a, int n, msglvl_t msglevel)
4863{
4864 int i;
4865 for (i = 0; i < n; ++i)
4866 {
4867 bool status;
4870 argv_msg_prefix(M_INFO, a, prefix);
4871 status = openvpn_execve_check(a, NULL, 0, "ERROR: command failed");
4873 if (status)
4874 {
4875 return;
4876 }
4878 }
4879 msg(msglevel, "%s: command failed", prefix);
4880}
4881
4882static void
4883netsh_command(const struct argv *a, int n, msglvl_t msglevel)
4884{
4885 exec_command("NETSH", a, n, msglevel);
4886}
4887
4888void
4890{
4891 struct argv argv = argv_new();
4892 const char err[] = "ERROR: Windows ipconfig command failed";
4893
4894 msg(D_TUNTAP_INFO, "Start ipconfig commands for register-dns...");
4896
4899 openvpn_execve_check(&argv, es, 0, err);
4900
4901 argv_printf(&argv, "%s%s /registerdns", get_win_sys_path(), WIN_IPCONFIG_PATH_SUFFIX);
4903 openvpn_execve_check(&argv, es, 0, err);
4904 argv_free(&argv);
4905
4907 msg(D_TUNTAP_INFO, "End ipconfig commands for register-dns...");
4908}
4909
4910static void
4911ip_addr_string_to_array(in_addr_t *dest, unsigned int *dest_len, const IP_ADDR_STRING *src)
4912{
4913 unsigned int i = 0;
4914 while (src)
4915 {
4916 const unsigned int getaddr_flags = GETADDR_HOST_ORDER;
4917 const char *ip_str = src->IpAddress.String;
4918 in_addr_t ip = 0;
4919 bool succeed = false;
4920
4921 if (i >= *dest_len)
4922 {
4923 break;
4924 }
4925 if (!ip_str || !strlen(ip_str))
4926 {
4927 break;
4928 }
4929
4930 ip = getaddr(getaddr_flags, ip_str, 0, &succeed, NULL);
4931 if (!succeed)
4932 {
4933 break;
4934 }
4935 dest[i++] = ip;
4936
4937 src = src->Next;
4938 }
4939 *dest_len = i;
4940
4941#if 0
4942 {
4943 struct gc_arena gc = gc_new();
4944 msg(M_INFO, "ip_addr_string_to_array [%d]", *dest_len);
4945 for (i = 0; i < *dest_len; ++i)
4946 {
4947 msg(M_INFO, "%s", print_in_addr_t(dest[i], 0, &gc));
4948 }
4949 gc_free(&gc);
4950 }
4951#endif
4952}
4953
4954static bool
4955ip_addr_one_to_one(const in_addr_t *a1, const unsigned int a1len, const IP_ADDR_STRING *ias)
4956{
4957#define MAX_ADDRS 8
4958 in_addr_t a2[MAX_ADDRS];
4959 unsigned int a2len = MAX_ADDRS;
4960
4961 ip_addr_string_to_array(a2, &a2len, ias);
4962 /*msg (M_INFO, "a1len=%d a2len=%d", a1len, a2len);*/
4963 if (a1len != a2len)
4964 {
4965 return false;
4966 }
4967
4968 for (unsigned int i = 0; i < a1len; ++i)
4969 {
4970 if (a1[i] != a2[i])
4971 {
4972 return false;
4973 }
4974 }
4975 return true;
4976}
4977
4978static bool
4979ip_addr_member_of(const in_addr_t addr, const IP_ADDR_STRING *ias)
4980{
4981 in_addr_t aa[MAX_ADDRS];
4982 unsigned int len = MAX_ADDRS;
4983
4984 ip_addr_string_to_array(aa, &len, ias);
4985 for (unsigned int i = 0; i < len; ++i)
4986 {
4987 if (addr == aa[i])
4988 {
4989 return true;
4990 }
4991 }
4992 return false;
4993}
4994#undef MAX_ADDRS
4995
5001static void
5002netsh_set_dns6_servers(const struct in6_addr *addr_list, const unsigned int addr_len, DWORD adapter_index)
5003{
5004 struct gc_arena gc = gc_new();
5005 struct argv argv = argv_new();
5006
5007 /* delete existing DNS settings from TAP interface */
5008 argv_printf(&argv, "%s%s interface ipv6 delete dns %lu all", get_win_sys_path(),
5009 NETSH_PATH_SUFFIX, adapter_index);
5011
5012 for (unsigned int i = 0; i < addr_len; ++i)
5013 {
5014 const char *fmt = (i == 0) ? "%s%s interface ipv6 set dns %lu static %s"
5015 : "%s%s interface ipv6 add dns %lu %s";
5016 argv_printf(&argv, fmt, get_win_sys_path(), NETSH_PATH_SUFFIX, adapter_index,
5017 print_in6_addr(addr_list[i], 0, &gc));
5018
5019 /* disable slow address validation */
5020 argv_printf_cat(&argv, "%s", "validate=no");
5021
5022 /* Treat errors while adding as non-fatal as we do not check for duplicates */
5023 netsh_command(&argv, 1, (i == 0) ? M_FATAL : M_NONFATAL);
5024 }
5025
5026 argv_free(&argv);
5027 gc_free(&gc);
5028}
5029
5030static void
5031netsh_ifconfig_options(const char *type, const in_addr_t *addr_list, const unsigned int addr_len,
5032 const IP_ADDR_STRING *current, DWORD adapter_index, const bool test_first)
5033{
5034 struct gc_arena gc = gc_new();
5035 struct argv argv = argv_new();
5036 bool delete_first = false;
5037 bool is_dns = !strcmp(type, "dns");
5038
5039 /* first check if we should delete existing DNS/WINS settings from TAP interface */
5040 if (test_first)
5041 {
5042 if (!ip_addr_one_to_one(addr_list, addr_len, current))
5043 {
5044 delete_first = true;
5045 }
5046 }
5047 else
5048 {
5049 delete_first = true;
5050 }
5051
5052 /* delete existing DNS/WINS settings from TAP interface */
5053 if (delete_first)
5054 {
5055 argv_printf(&argv, "%s%s interface ip delete %s %lu all", get_win_sys_path(),
5056 NETSH_PATH_SUFFIX, type, adapter_index);
5058 }
5059
5060 /* add new DNS/WINS settings to TAP interface */
5061 {
5062 bool first = true;
5063 for (unsigned int i = 0; i < addr_len; ++i)
5064 {
5065 if (delete_first || !test_first || !ip_addr_member_of(addr_list[i], current))
5066 {
5067 const char *fmt = first ? "%s%s interface ip set %s %lu static %s"
5068 : "%s%s interface ip add %s %lu %s";
5069
5070 argv_printf(&argv, fmt, get_win_sys_path(), NETSH_PATH_SUFFIX, type, adapter_index,
5071 print_in_addr_t(addr_list[i], 0, &gc));
5072
5073 /* disable slow address validation for DNS */
5074 if (is_dns)
5075 {
5076 argv_printf_cat(&argv, "%s", "validate=no");
5077 }
5078
5080
5081 first = false;
5082 }
5083 else
5084 {
5085 msg(M_INFO, "NETSH: %lu %s %s [already set]", adapter_index, type,
5086 print_in_addr_t(addr_list[i], 0, &gc));
5087 }
5088 }
5089 }
5090
5091 argv_free(&argv);
5092 gc_free(&gc);
5093}
5094
5095static void
5096init_ip_addr_string2(IP_ADDR_STRING *dest, const IP_ADDR_STRING *src1, const IP_ADDR_STRING *src2)
5097{
5098 CLEAR(dest[0]);
5099 CLEAR(dest[1]);
5100 if (src1)
5101 {
5102 dest[0] = *src1;
5103 dest[0].Next = NULL;
5104 }
5105 if (src2)
5106 {
5107 dest[1] = *src2;
5108 dest[0].Next = &dest[1];
5109 dest[1].Next = NULL;
5110 }
5111}
5112
5113static void
5114netsh_ifconfig(const struct tuntap_options *to, DWORD adapter_index, const in_addr_t ip,
5115 const in_addr_t netmask, const unsigned int flags)
5116{
5117 struct gc_arena gc = gc_new();
5118 struct argv argv = argv_new();
5119 const IP_ADAPTER_INFO *ai = NULL;
5120 const IP_PER_ADAPTER_INFO *pai = NULL;
5121
5122 if (flags & NI_TEST_FIRST)
5123 {
5124 const IP_ADAPTER_INFO *list = get_adapter_info_list(&gc);
5125 ai = get_adapter(list, adapter_index);
5126 pai = get_per_adapter_info(adapter_index, &gc);
5127 }
5128
5129 if (flags & NI_IP_NETMASK)
5130 {
5131 if (test_adapter_ip_netmask(ai, ip, netmask))
5132 {
5133 msg(M_INFO, "NETSH: %lu %s/%s [already set]", adapter_index,
5134 print_in_addr_t(ip, 0, &gc), print_in_addr_t(netmask, 0, &gc));
5135 }
5136 else
5137 {
5138 /* example: netsh interface ip set address 42 static 10.3.0.1 255.255.255.0 store=active */
5139 argv_printf(&argv, "%s%s interface ip set address %lu static %s %s store=active", get_win_sys_path(),
5140 NETSH_PATH_SUFFIX, adapter_index, print_in_addr_t(ip, 0, &gc),
5141 print_in_addr_t(netmask, 0, &gc));
5142
5144 }
5145 }
5146
5147 /* set WINS/DNS options */
5148 if (flags & NI_OPTIONS)
5149 {
5150 IP_ADDR_STRING wins[2];
5151 CLEAR(wins[0]);
5152 CLEAR(wins[1]);
5153
5154 netsh_ifconfig_options("dns", to->dns, to->dns_len, pai ? &pai->DnsServerList : NULL,
5155 adapter_index, BOOL_CAST(flags & NI_TEST_FIRST));
5156 if (ai && ai->HaveWins)
5157 {
5158 init_ip_addr_string2(wins, &ai->PrimaryWinsServer, &ai->SecondaryWinsServer);
5159 }
5160
5161 netsh_ifconfig_options("wins", to->wins, to->wins_len, ai ? wins : NULL, adapter_index,
5162 BOOL_CAST(flags & NI_TEST_FIRST));
5163 }
5164
5165 argv_free(&argv);
5166 gc_free(&gc);
5167}
5168
5169static void
5170netsh_enable_dhcp(DWORD adapter_index)
5171{
5172 struct argv argv = argv_new();
5173
5174 /* example: netsh interface ip set address 42 dhcp */
5175 argv_printf(&argv, "%s%s interface ip set address %lu dhcp", get_win_sys_path(),
5176 NETSH_PATH_SUFFIX, adapter_index);
5177
5179
5180 argv_free(&argv);
5181}
5182
5183/* Enable dhcp on tap adapter using iservice */
5184static bool
5186{
5187 bool ret = false;
5188 ack_message_t ack;
5189 struct gc_arena gc = gc_new();
5190 HANDLE pipe = tt->options.msg_channel;
5191
5193 .iface = { .index = tt->adapter_index, .name = "" } };
5194
5195 if (!send_msg_iservice(pipe, &dhcp, sizeof(dhcp), &ack, "Enable_dhcp"))
5196 {
5197 goto out;
5198 }
5199
5200 if (ack.error_number != NO_ERROR)
5201 {
5202 msg(M_NONFATAL, "TUN: enabling dhcp using service failed: %s [status=%u if_index=%lu]",
5203 strerror_win32(ack.error_number, &gc), ack.error_number, dhcp.iface.index);
5204 }
5205 else
5206 {
5207 msg(M_INFO, "DHCP enabled on interface %lu using service", dhcp.iface.index);
5208 ret = true;
5209 }
5210
5211out:
5212 gc_free(&gc);
5213 return ret;
5214}
5215
5216static void
5217windows_set_mtu(const int iface_index, const short family, const int mtu)
5218{
5219 DWORD err = 0;
5220 struct gc_arena gc = gc_new();
5221 MIB_IPINTERFACE_ROW ipiface;
5222 InitializeIpInterfaceEntry(&ipiface);
5223 const char *family_name = (family == AF_INET6) ? "IPv6" : "IPv4";
5224 ipiface.Family = family;
5225 ipiface.InterfaceIndex = iface_index;
5226 if (family == AF_INET6 && mtu < 1280)
5227 {
5228 msg(M_INFO,
5229 "NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
5230 }
5231
5232 err = GetIpInterfaceEntry(&ipiface);
5233 if (err == NO_ERROR)
5234 {
5235 if (family == AF_INET)
5236 {
5237 ipiface.SitePrefixLength = 0;
5238 }
5239 ipiface.NlMtu = mtu;
5240 err = SetIpInterfaceEntry(&ipiface);
5241 }
5242
5243 if (err != NO_ERROR)
5244 {
5245 msg(M_WARN, "TUN: Setting %s mtu failed: %s [status=%lu if_index=%d]", family_name,
5246 strerror_win32(err, &gc), err, iface_index);
5247 }
5248 else
5249 {
5250 msg(M_INFO, "%s MTU set to %d on interface %d using SetIpInterfaceEntry()", family_name,
5251 mtu, iface_index);
5252 }
5253}
5254
5255
5256/*
5257 * Return a TAP name for netsh commands.
5258 */
5259static const char *
5260netsh_get_id(const char *dev_node, struct gc_arena *gc)
5261{
5262 const struct tap_reg *tap_reg = get_tap_reg(gc);
5263 const struct panel_reg *panel_reg = get_panel_reg(gc);
5264 struct buffer actual = alloc_buf_gc(256, gc);
5265 const char *guid;
5266
5268
5269 if (dev_node)
5270 {
5271 guid =
5272 get_device_guid(dev_node, BPTR(&actual), BCAP(&actual), NULL, tap_reg, panel_reg, gc);
5273 }
5274 else
5275 {
5276 guid = get_unspecified_device_guid(0, BPTR(&actual), BCAP(&actual), tap_reg, panel_reg,
5277 NULL, gc);
5278
5280 gc)) /* ambiguous if more than one TAP-Windows adapter */
5281 {
5282 guid = NULL;
5283 }
5284 }
5285
5286 if (!guid)
5287 {
5288 return "NULL"; /* not found */
5289 }
5290 else if (strcmp(BSTR(&actual), "NULL"))
5291 {
5292 return BSTR(&actual); /* control panel name */
5293 }
5294 else
5295 {
5296 return guid; /* no control panel name, return GUID instead */
5297 }
5298}
5299
5300/*
5301 * Called iteratively on TAP-Windows wait-for-initialization polling loop
5302 */
5303void
5305{
5306 tt->standby_iter = 0;
5307}
5308
5309bool
5311{
5312 bool ret = true;
5313 ++tt->standby_iter;
5314 if (tt->options.ip_win32_type == IPW32_SET_ADAPTIVE)
5315 {
5316 if (tt->standby_iter == IPW32_SET_ADAPTIVE_TRY_NETSH)
5317 {
5318 msg(M_INFO, "NOTE: now trying netsh (this may take some time)");
5319 netsh_ifconfig(&tt->options, tt->adapter_index, tt->local, tt->adapter_netmask,
5321 }
5322 else if (tt->standby_iter >= IPW32_SET_ADAPTIVE_TRY_NETSH * 2)
5323 {
5324 ret = false;
5325 }
5326 }
5327 return ret;
5328}
5329
5330static void
5332{
5333 if (tt->options.dhcp_pre_release || tt->options.dhcp_renew)
5334 {
5335 struct gc_arena gc = gc_new();
5336 struct buffer cmd = alloc_buf_gc(256, &gc);
5337 const int verb = 3;
5338 const int pre_sleep = 1;
5339
5340 buf_printf(&cmd, "openvpn --verb %d --tap-sleep %d", verb, pre_sleep);
5341 if (tt->options.dhcp_pre_release)
5342 {
5343 buf_printf(&cmd, " --dhcp-pre-release");
5344 }
5345 if (tt->options.dhcp_renew)
5346 {
5347 buf_printf(&cmd, " --dhcp-renew");
5348 }
5349 buf_printf(&cmd, " --dhcp-internal %lu", tt->adapter_index);
5350
5352 gc_free(&gc);
5353 }
5354}
5355
5356static void
5358{
5359 HANDLE msg_channel = tt->options.msg_channel;
5361 struct gc_arena gc = gc_new();
5362
5363 message_header_t rdns = { msg_register_dns, sizeof(message_header_t), 0 };
5364
5365 if (!send_msg_iservice(msg_channel, &rdns, sizeof(rdns), &ack, "Register_dns"))
5366 {
5367 gc_free(&gc);
5368 return;
5369 }
5370
5371 else if (ack.error_number != NO_ERROR)
5372 {
5373 msg(M_WARN, "Register_dns failed using service: %s [status=0x%x]",
5375 }
5376
5377 else
5378 {
5379 msg(M_INFO, "Register_dns request sent to the service");
5380 }
5381
5382 gc_free(&gc);
5383}
5384
5385void
5387{
5388 if (tt && tt->options.register_dns && tt->options.msg_channel)
5389 {
5391 }
5392 else if (tt && tt->options.register_dns)
5393 {
5394 struct gc_arena gc = gc_new();
5395 struct buffer cmd = alloc_buf_gc(256, &gc);
5396 const int verb = 3;
5397
5398 buf_printf(&cmd, "openvpn --verb %d --register-dns --rdns-internal", verb);
5400 gc_free(&gc);
5401 }
5402}
5403
5404static uint32_t
5405dhcp_masq_addr(const in_addr_t local, const in_addr_t netmask, const int offset)
5406{
5407 struct gc_arena gc = gc_new();
5408 in_addr_t dsa; /* DHCP server addr */
5409
5410 if (offset < 0)
5411 {
5412 dsa = (local | (~netmask)) + offset;
5413 }
5414 else
5415 {
5416 dsa = (local & netmask) + offset;
5417 }
5418
5419 if (dsa == local)
5420 {
5421 msg(M_FATAL,
5422 "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",
5423 print_in_addr_t(dsa, 0, &gc));
5424 }
5425
5426 if ((local & netmask) != (dsa & netmask))
5427 {
5428 msg(M_FATAL, "ERROR: --ip-win32 dynamic [offset] : offset is outside of --ifconfig subnet");
5429 }
5430
5431 gc_free(&gc);
5432 return htonl(dsa);
5433}
5434
5435static void
5437{
5438 ULONG info[3];
5439 DWORD len;
5440 CLEAR(info);
5441 if (DeviceIoControl(tt->hand, TAP_WIN_IOCTL_GET_VERSION, &info, sizeof(info), &info,
5442 sizeof(info), &len, NULL))
5443 {
5444 msg(D_TUNTAP_INFO, "TAP-Windows Driver Version %lu.%lu %s", info[0], info[1],
5445 (info[2] ? "(DEBUG)" : ""));
5446 }
5447 if (!(info[0] == TAP_WIN_MIN_MAJOR && info[1] >= TAP_WIN_MIN_MINOR))
5448 {
5449 msg(M_FATAL,
5450 "ERROR: This version of " PACKAGE_NAME
5451 " requires a TAP-Windows driver that is at least version %u.%u -- If you recently upgraded your " PACKAGE_NAME
5452 " distribution, a reboot is probably required at this point to get Windows to see the new driver.",
5453 TAP_WIN_MIN_MAJOR, TAP_WIN_MIN_MINOR);
5454 }
5455
5456 /* usage of numeric constants is ugly, but this is really tied to
5457 * *this* version of the driver
5458 */
5459 if (tt->type == DEV_TYPE_TUN && info[0] == 9 && info[1] < 8)
5460 {
5461 msg(M_INFO,
5462 "WARNING: Tap-Win32 driver version %lu.%lu does not support IPv6 in TUN mode. IPv6 will not work. Upgrade your Tap-Win32 driver.",
5463 info[0], info[1]);
5464 }
5465
5466 /* tap driver 9.8 (2.2.0 and 2.2.1 release) is buggy
5467 */
5468 if (tt->type == DEV_TYPE_TUN && info[0] == 9 && info[1] == 8)
5469 {
5470 msg(M_FATAL,
5471 "ERROR: Tap-Win32 driver version 9.8 is buggy regarding small IPv4 packets in TUN mode. Upgrade your Tap-Win32 driver.");
5472 }
5473}
5474
5475static void
5477{
5478 ULONG mtu = 0;
5479 DWORD len;
5480 if (DeviceIoControl(tt->hand, TAP_WIN_IOCTL_GET_MTU, &mtu, sizeof(mtu), &mtu, sizeof(mtu), &len,
5481 NULL))
5482 {
5483 msg(D_MTU_INFO, "TAP-Windows MTU=%lu", mtu);
5484 }
5485}
5486
5487static void
5488tuntap_set_ip_addr(struct tuntap *tt, const char *device_guid, bool dhcp_masq_post)
5489{
5490 struct gc_arena gc = gc_new();
5491 const DWORD index = tt->adapter_index;
5492
5493 /* flush arp cache */
5495 {
5496 DWORD status = (DWORD)-1;
5497
5498 if (tt->options.msg_channel)
5499 {
5500 ack_message_t ack;
5502 sizeof(flush_neighbors_message_t), 0 },
5503 .family = AF_INET,
5504 .iface = { .index = index, .name = "" } };
5505
5506 if (send_msg_iservice(tt->options.msg_channel, &msg, sizeof(msg), &ack, "TUN"))
5507 {
5508 status = ack.error_number;
5509 }
5510 }
5511 else
5512 {
5513 status = FlushIpNetTable(index);
5514 }
5515
5516 if (status == NO_ERROR)
5517 {
5518 msg(M_INFO, "Successful ARP Flush on interface [%lu] %s", index, device_guid);
5519 }
5520 else if (status != (DWORD)-1)
5521 {
5523 "NOTE: FlushIpNetTable failed on interface [%lu] %s (status=%lu) : %s", index,
5524 device_guid, status, strerror_win32(status, &gc));
5525 }
5526
5527 /*
5528 * If the TAP-Windows driver is masquerading as a DHCP server
5529 * make sure the TCP/IP properties for the adapter are
5530 * set correctly.
5531 */
5532 if (dhcp_masq_post)
5533 {
5534 /* check dhcp enable status */
5535 if (dhcp_status(index) == DHCP_STATUS_DISABLED)
5536 {
5537 msg(M_WARN,
5538 "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'");
5539 }
5540
5541 /* force an explicit DHCP lease renewal on TAP adapter? */
5542 if (tt->options.dhcp_pre_release)
5543 {
5544 dhcp_release(tt);
5545 }
5546 if (tt->options.dhcp_renew)
5547 {
5548 dhcp_renew(tt);
5549 }
5550 }
5551 else
5552 {
5553 fork_dhcp_action(tt);
5554 }
5555 }
5556
5558 {
5559 DWORD status;
5560 const char *error_suffix =
5561 "I am having trouble using the Windows 'IP helper API' to automatically set the IP address -- consider using other --ip-win32 methods (not 'ipapi')";
5562
5563 /* couldn't get adapter index */
5564 if (index == TUN_ADAPTER_INDEX_INVALID)
5565 {
5566 msg(M_FATAL, "ERROR: unable to get adapter index for interface %s -- %s", device_guid,
5567 error_suffix);
5568 }
5569
5570 /* check dhcp enable status */
5571 if (dhcp_status(index) == DHCP_STATUS_DISABLED)
5572 {
5573 msg(M_WARN,
5574 "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'");
5575 }
5576
5577 /* delete previously added IP addresses which were not
5578 * correctly deleted */
5579 delete_temp_addresses(index);
5580
5581 /* add a new IP address */
5582 if ((status = AddIPAddress(htonl(tt->local), htonl(tt->adapter_netmask), index,
5583 &tt->ipapi_context, &tt->ipapi_instance))
5584 == NO_ERROR)
5585 {
5586 msg(M_INFO,
5587 "Succeeded in adding a temporary IP/netmask of %s/%s to interface %s using the Win32 IP Helper API",
5589 device_guid);
5590 }
5591 else
5592 {
5593 msg(M_FATAL,
5594 "ERROR: AddIPAddress %s/%s failed on interface %s, index=%lu, status=%lu (windows error: '%s') -- %s",
5596 device_guid, index, status, strerror_win32(status, &gc), error_suffix);
5597 }
5598 tt->ipapi_context_defined = true;
5599 }
5600
5601 gc_free(&gc);
5602}
5603
5604static void
5606{
5607 ULONG status = TRUE;
5608 DWORD len;
5609 if (!DeviceIoControl(tt->hand, TAP_WIN_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status,
5610 sizeof(status), &len, NULL))
5611 {
5612 msg(M_WARN,
5613 "WARNING: The TAP-Windows driver rejected a TAP_WIN_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
5614 }
5615
5616 int s = tt->options.tap_sleep;
5617 if (s > 0)
5618 {
5619 msg(M_INFO, "Sleeping for %d seconds...", s);
5621 }
5622}
5623
5624static void
5625tuntap_set_ptp(const struct tuntap *tt)
5626{
5627 DWORD len;
5628 struct gc_arena gc = gc_new();
5629
5631 {
5632 msg(M_FATAL, "ERROR: --dev tun also requires --ifconfig");
5633 }
5634
5635 /* send 0/0/0 to the TAP driver even if we have no IPv4 configured to
5636 * ensure it is somehow initialized.
5637 */
5638 if (!tt->did_ifconfig_setup || tt->topology == TOP_SUBNET)
5639 {
5640 in_addr_t ep[3];
5641 BOOL status;
5642
5643 ep[0] = htonl(tt->local);
5644 ep[1] = htonl(tt->local & tt->remote_netmask);
5645 ep[2] = htonl(tt->remote_netmask);
5646
5647 status = DeviceIoControl(tt->hand, TAP_WIN_IOCTL_CONFIG_TUN, ep, sizeof(ep), ep, sizeof(ep),
5648 &len, NULL);
5649
5650 if (tt->did_ifconfig_setup)
5651 {
5653 "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
5656 print_in_addr_t(ep[2], IA_NET_ORDER, &gc), status ? "SUCCEEDED" : "FAILED");
5657 }
5658 else
5659 {
5660 msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN with fake IPv4 [%s]",
5661 status ? "SUCCEEDED" : "FAILED");
5662 }
5663 }
5664 else
5665 {
5666 in_addr_t ep[2];
5667 ep[0] = htonl(tt->local);
5668 ep[1] = htonl(tt->remote_netmask);
5669
5670 if (!DeviceIoControl(tt->hand, TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT, ep, sizeof(ep), ep,
5671 sizeof(ep), &len, NULL))
5672 {
5673 msg(M_FATAL,
5674 "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun");
5675 }
5676 }
5677
5678 gc_free(&gc);
5679}
5680
5681static void
5682tuntap_dhcp_mask(const struct tuntap *tt, const char *device_guid)
5683{
5684 struct gc_arena gc = gc_new();
5685 DWORD len;
5686 uint32_t ep[4];
5687
5688 /* We will answer DHCP requests with a reply to set IP/subnet to these values */
5689 ep[0] = htonl(tt->local);
5690 ep[1] = htonl(tt->adapter_netmask);
5691
5692 /* At what IP address should the DHCP server masquerade at? */
5693 if (tt->type == DEV_TYPE_TUN)
5694 {
5695 if (tt->topology == TOP_SUBNET)
5696 {
5697 ep[2] = dhcp_masq_addr(
5698 tt->local, tt->remote_netmask,
5700 }
5701 else
5702 {
5703 ep[2] = htonl(tt->remote_netmask);
5704 }
5705 }
5706 else
5707 {
5708 ASSERT(tt->type == DEV_TYPE_TAP);
5709 ep[2] =
5712 }
5713
5714 /* lease time in seconds */
5715 ep[3] = (uint32_t)tt->options.dhcp_lease_time;
5716
5717 ASSERT(ep[3] > 0);
5718
5719#ifndef SIMULATE_DHCP_FAILED /* this code is disabled to simulate bad DHCP negotiation */
5720 if (!DeviceIoControl(tt->hand, TAP_WIN_IOCTL_CONFIG_DHCP_MASQ, ep, sizeof(ep), ep, sizeof(ep),
5721 &len, NULL))
5722 {
5723 msg(M_FATAL,
5724 "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode");
5725 }
5726
5727 msg(M_INFO,
5728 "Notified TAP-Windows driver to set a DHCP IP/netmask of %s/%s on interface %s [DHCP-serv: %s, lease-time: %d]",
5730 device_guid, print_in_addr_t(ep[2], IA_NET_ORDER, &gc), ep[3]);
5731
5732 /* user-supplied DHCP options capability */
5733 if (tt->options.dhcp_options)
5734 {
5735 struct buffer buf = alloc_buf(256);
5736 if (build_dhcp_options_string(&buf, &tt->options))
5737 {
5738 msg(D_DHCP_OPT, "DHCP option string: %s", format_hex(BPTR(&buf), BLEN(&buf), 0, &gc));
5740 BLEN(&buf), BPTR(&buf), BLEN(&buf), &len, NULL))
5741 {
5742 msg(M_FATAL,
5743 "ERROR: The TAP-Windows driver rejected a TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call");
5744 }
5745 }
5746 else
5747 {
5748 msg(M_WARN, "DHCP option string not set due to error");
5749 }
5750 free_buf(&buf);
5751 }
5752#endif /* ifndef SIMULATE_DHCP_FAILED */
5753
5754 gc_free(&gc);
5755}
5756
5757static bool
5760{
5761 const char *path = NULL;
5762 char tuntap_device_path[256];
5763
5764 if (tt->backend_driver == DRIVER_DCO)
5765 {
5766 const struct device_instance_id_interface *dev_if;
5767
5768 for (dev_if = device_instance_id_interface; dev_if != NULL; dev_if = dev_if->next)
5769 {
5770 if (strcmp((const char *)dev_if->net_cfg_instance_id, device_guid) != 0)
5771 {
5772 continue;
5773 }
5774
5775 if (tt->backend_driver == DRIVER_DCO)
5776 {
5777 char *last_sep = strrchr(dev_if->device_interface, '\\');
5778 if (!last_sep || strcmp(last_sep + 1, DCO_WIN_REFERENCE_STRING) != 0)
5779 {
5780 continue;
5781 }
5782 }
5783
5784 path = dev_if->device_interface;
5785 break;
5786 }
5787 if (path == NULL)
5788 {
5789 return false;
5790 }
5791 }
5792 else
5793 {
5794 /* Open TAP-Windows */
5795 snprintf(tuntap_device_path, sizeof(tuntap_device_path), "%s%s%s", USERMODEDEVICEDIR,
5796 device_guid, TAP_WIN_SUFFIX);
5797 path = tuntap_device_path;
5798 }
5799
5800 msg(D_TAP_WIN_DEBUG, "Using device interface: %s", path);
5801
5802 tt->hand = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, /* was: FILE_SHARE_READ */
5803 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
5804 if (tt->hand == INVALID_HANDLE_VALUE)
5805 {
5806 msg(D_TUNTAP_INFO | M_ERRNO, "CreateFile failed on %s device: %s",
5808 return false;
5809 }
5810
5811 return true;
5812}
5813
5814void
5815tun_open_device(struct tuntap *tt, const char *dev_node, const char **device_guid,
5816 struct gc_arena *gc)
5817{
5818 const struct tap_reg *tap_reg = get_tap_reg(gc);
5819 const struct panel_reg *panel_reg = get_panel_reg(gc);
5822
5823 uint8_t actual_buffer[256];
5824
5825 /*
5826 * Lookup the device name in the registry, using the --dev-node high level name.
5827 */
5828 if (dev_node)
5829 {
5830 enum tun_driver_type windows_driver = WINDOWS_DRIVER_UNSPECIFIED;
5831
5832 /* Get the device GUID for the device specified with --dev-node. */
5833 *device_guid = get_device_guid(dev_node, actual_buffer, sizeof(actual_buffer),
5834 &windows_driver, tap_reg, panel_reg, gc);
5835
5836 if (!*device_guid)
5837 {
5838 msg(M_FATAL, "Adapter '%s' not found", dev_node);
5839 }
5840
5841 if (tt->backend_driver != windows_driver)
5842 {
5843 msg(M_FATAL,
5844 "Adapter '%s' is using %s driver, %s expected.",
5845 dev_node, print_tun_backend_driver(windows_driver),
5847 }
5848
5849 if (!tun_try_open_device(tt, *device_guid, device_instance_id_interface))
5850 {
5851 msg(M_FATAL, "Failed to open %s adapter: %s",
5853 }
5854 }
5855 else
5856 {
5857 int device_number = 0;
5858 int adapters_created = 0;
5859
5860 /* Try opening all TAP devices until we find one available */
5861 while (true)
5862 {
5863 enum tun_driver_type windows_driver = WINDOWS_DRIVER_UNSPECIFIED;
5864 *device_guid =
5865 get_unspecified_device_guid(device_number, actual_buffer, sizeof(actual_buffer),
5866 tap_reg, panel_reg, &windows_driver, gc);
5867
5868 if (!*device_guid)
5869 {
5870 /* try to create an adapter a few times if we have a service pipe handle */
5871 if ((++adapters_created > 10)
5873 {
5874 msg(M_FATAL, "All %s adapters on this system are currently in use or disabled.",
5876 }
5877 else
5878 {
5879 /* we have created a new adapter so we must reinitialize adapters structs */
5883
5884 device_number = 0;
5885
5886 continue;
5887 }
5888 }
5889
5890 if (tt->backend_driver != windows_driver)
5891 {
5892 goto next;
5893 }
5894
5896 {
5897 break;
5898 }
5899
5900next:
5901 device_number++;
5902 }
5903 }
5904
5905 /* translate high-level device name into a device instance
5906 * GUID using the registry */
5907 tt->actual_name = string_alloc((const char *)actual_buffer, NULL);
5908
5909 tt->adapter_index = get_adapter_index(*device_guid);
5910}
5911
5912static void
5913tuntap_set_ip_props(const struct tuntap *tt, bool *dhcp_masq, bool *dhcp_masq_post)
5914{
5916 {
5917 /*
5918 * If adapter is set to non-DHCP, set to DHCP mode.
5919 */
5921 {
5922 /* try using the service if available, else directly execute netsh */
5923 if (tt->options.msg_channel)
5924 {
5926 }
5927 else
5928 {
5930 }
5931 }
5932 *dhcp_masq = true;
5933 *dhcp_masq_post = true;
5934 }
5936 {
5937 /*
5938 * If adapter is set to non-DHCP, use netsh right away.
5939 */
5941 {
5944 }
5945 else
5946 {
5947 *dhcp_masq = true;
5948 }
5949 }
5950}
5951
5952static void
5953tuntap_post_open(struct tuntap *tt, const char *device_guid)
5954{
5955 bool dhcp_masq = false;
5956 bool dhcp_masq_post = false;
5957
5959 {
5960 /* get driver version info */
5962
5963 /* get driver MTU */
5964 tuntap_get_mtu(tt);
5965
5966 /*
5967 * Preliminaries for setting TAP-Windows adapter TCP/IP
5968 * properties via --ip-win32 dynamic or --ip-win32 adaptive.
5969 */
5970 if (tt->did_ifconfig_setup)
5971 {
5972 tuntap_set_ip_props(tt, &dhcp_masq, &dhcp_masq_post);
5973 }
5974
5975 /* set point-to-point mode if TUN device */
5976 if (tt->type == DEV_TYPE_TUN)
5977 {
5978 tuntap_set_ptp(tt);
5979 }
5980
5981 /* should we tell the TAP-Windows driver to masquerade as a DHCP server as a means
5982 * of setting the adapter address? */
5983 if (dhcp_masq)
5984 {
5985 tuntap_dhcp_mask(tt, device_guid);
5986 }
5987
5988 /* set driver media status to 'connected' */
5990 }
5991
5992 /* possibly use IP Helper API to set IP address on adapter */
5993 tuntap_set_ip_addr(tt, device_guid, dhcp_masq_post);
5994}
5995
5996void
5997open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
5998 openvpn_net_ctx_t *ctx)
5999{
6002 {
6003 msg(M_WARN,
6004 "Some --dhcp-option or --dns options require DHCP server,"
6005 " which is not supported by the selected %s driver. They will be"
6006 " ignored.",
6008 }
6009
6010 /* dco-win already opened the device, which handle we treat as socket */
6011 if (tuntap_is_dco_win(tt))
6012 {
6013 return;
6014 }
6015
6016 const char *device_guid = NULL;
6017
6018 /*netcmd_semaphore_lock ();*/
6019
6020 msg(M_INFO, "open_tun");
6021
6022 if (tt->type != DEV_TYPE_TAP && tt->type != DEV_TYPE_TUN)
6023 {
6024 msg(M_FATAL | M_NOPREFIX, "Unknown virtual device type: '%s'", dev);
6025 }
6026
6027 struct gc_arena gc = gc_new(); /* used also for device_guid allocation */
6028 tun_open_device(tt, dev_node, &device_guid, &gc);
6029
6030 tuntap_post_open(tt, device_guid);
6031
6032 gc_free(&gc);
6033
6034 /*netcmd_semaphore_release ();*/
6035}
6036
6037const char *
6038tap_win_getinfo(const struct tuntap *tt, struct gc_arena *gc)
6039{
6041 {
6042 struct buffer out = alloc_buf_gc(256, gc);
6043 DWORD len;
6044 if (DeviceIoControl(tt->hand, TAP_WIN_IOCTL_GET_INFO, BSTR(&out), BCAP(&out), BSTR(&out),
6045 BCAP(&out), &len, NULL))
6046 {
6047 return BSTR(&out);
6048 }
6049 }
6050 return NULL;
6051}
6052
6053void
6055{
6056 if (tt->backend_driver == WINDOWS_DRIVER_TAP_WINDOWS6)
6057 {
6058 struct buffer out = alloc_buf(1024);
6059 DWORD len;
6060 while (DeviceIoControl(tt->hand, TAP_WIN_IOCTL_GET_LOG_LINE, BSTR(&out), BCAP(&out),
6061 BSTR(&out), BCAP(&out), &len, NULL))
6062 {
6063 msg(D_TAP_WIN_DEBUG, "TAP-Windows: %s", BSTR(&out));
6064 }
6065 free_buf(&out);
6066 }
6067}
6068
6069static void
6070netsh_delete_address_dns(const struct tuntap *tt, bool ipv6, struct gc_arena *gc)
6071{
6072 const char *ifconfig_ip_local;
6073 struct argv argv = argv_new();
6074
6075 /* delete ipvX dns servers if any were set */
6076 unsigned int len = ipv6 ? tt->options.dns6_len : tt->options.dns_len;
6077 if (len > 0)
6078 {
6079 argv_printf(&argv, "%s%s interface %s delete dns %lu all", get_win_sys_path(),
6080 NETSH_PATH_SUFFIX, ipv6 ? "ipv6" : "ipv4", tt->adapter_index);
6082 }
6083
6084 if (!ipv6 && tt->options.wins_len > 0)
6085 {
6086 argv_printf(&argv, "%s%s interface ipv4 delete winsservers %lu all", get_win_sys_path(),
6089 }
6090
6091 if (ipv6 && tt->type == DEV_TYPE_TUN)
6092 {
6094 }
6095
6096 /* "store=active" is needed in Windows 8(.1) to delete the
6097 * address we added (pointed out by Cedric Tabary).
6098 */
6099
6100 /* netsh interface ipvX delete address %lu %s */
6101 if (ipv6)
6102 {
6103 ifconfig_ip_local = print_in6_addr(tt->local_ipv6, 0, gc);
6104 }
6105 else
6106 {
6107 ifconfig_ip_local = print_in_addr_t(tt->local, 0, gc);
6108 }
6109 argv_printf(&argv, "%s%s interface %s delete address %lu %s store=active", get_win_sys_path(),
6110 NETSH_PATH_SUFFIX, ipv6 ? "ipv6" : "ipv4", tt->adapter_index, ifconfig_ip_local);
6112
6113 argv_free(&argv);
6114}
6115
6116void
6118{
6119 const char *adaptertype = print_tun_backend_driver(tt->backend_driver);
6120
6121 if (tt->hand)
6122 {
6123 dmsg(D_WIN32_IO_LOW, "Attempting CancelIO on %s adapter", adaptertype);
6124 if (!CancelIo(tt->hand))
6125 {
6126 msg(M_WARN | M_ERRNO, "Warning: CancelIO failed on %s adapter", adaptertype);
6127 }
6128 }
6129
6130 dmsg(D_WIN32_IO_LOW, "Attempting close of overlapped read event on %s adapter", adaptertype);
6132
6133 dmsg(D_WIN32_IO_LOW, "Attempting close of overlapped write event on %s adapter", adaptertype);
6135
6136 if (tt->hand)
6137 {
6138 dmsg(D_WIN32_IO_LOW, "Attempting CloseHandle on %s adapter", adaptertype);
6139 if (!CloseHandle(tt->hand))
6140 {
6141 msg(M_WARN | M_ERRNO, "Warning: CloseHandle failed on %s adapter", adaptertype);
6142 }
6143 tt->hand = NULL;
6144 }
6145}
6146
6147void
6149{
6150 ASSERT(tt);
6151
6152 struct gc_arena gc = gc_new();
6153
6155 {
6157 {
6158 /* We didn't do ifconfig. */
6159 }
6160 else if (tt->options.msg_channel)
6161 {
6162 /* If IPv4 is not enabled, delete DNS domain here */
6163 if (!tt->did_ifconfig_setup)
6164 {
6165 do_dns_domain_service(false, tt);
6166 }
6167 do_dns_service(false, AF_INET6, tt);
6169 do_address_service(false, AF_INET6, tt);
6170 }
6171 else
6172 {
6173 if (!tt->did_ifconfig_setup)
6174 {
6175 do_dns_domain_pwsh(false, tt);
6176 }
6177
6178 netsh_delete_address_dns(tt, true, &gc);
6179 }
6180 }
6181
6182 if (tt->did_ifconfig_setup)
6183 {
6185 {
6186 /* We didn't do ifconfig. */
6187 }
6190 {
6191 /* We don't have to clean the configuration with DHCP. */
6192 }
6193 else if (tt->options.msg_channel)
6194 {
6195 do_wins_service(false, tt);
6196 do_dns_domain_service(false, tt);
6197 do_dns_service(false, AF_INET, tt);
6198 do_address_service(false, AF_INET, tt);
6199 }
6200 else
6201 {
6202 do_dns_domain_pwsh(false, tt);
6203
6205 {
6206 netsh_delete_address_dns(tt, false, &gc);
6207 }
6208 }
6209 }
6210
6211 if (tt->ipapi_context_defined)
6212 {
6213 DWORD status;
6214
6215 if ((status = DeleteIPAddress(tt->ipapi_context)) != NO_ERROR)
6216 {
6217 msg(M_WARN,
6218 "Warning: DeleteIPAddress[%lu] failed on TAP-Windows adapter, status=%lu : %s",
6220 }
6221 }
6222
6223 dhcp_release(tt);
6224
6225 close_tun_handle(tt);
6226
6227 free(tt->actual_name);
6228
6229 clear_tuntap(tt);
6230 free(tt);
6231 gc_free(&gc);
6232}
6233
6234/*
6235 * Convert --ip-win32 constants between index and ascii form.
6236 */
6237
6239{
6240 const char *short_form;
6241};
6242
6243/* Indexed by IPW32_SET_x */
6244static const struct ipset_names ipset_names[] = {
6245 { "manual" }, { "netsh" }, { "ipapi" }, { "dynamic" }, { "adaptive" }
6246};
6247
6248int
6249ascii2ipset(const char *name)
6250{
6251 int i;
6253 for (i = 0; i < IPW32_SET_N; ++i)
6254 {
6255 if (!strcmp(name, ipset_names[i].short_form))
6256 {
6257 return i;
6258 }
6259 }
6260 return -1;
6261}
6262
6263const char *
6264ipset2ascii(int index)
6265{
6267 if (index < 0 || index >= IPW32_SET_N)
6268 {
6269 return "[unknown --ip-win32 type]";
6270 }
6271 else
6272 {
6273 return ipset_names[index].short_form;
6274 }
6275}
6276
6277const char *
6279{
6280 struct buffer out = alloc_buf_gc(256, gc);
6281 int i;
6282
6284 for (i = 0; i < IPW32_SET_N; ++i)
6285 {
6286 if (i)
6287 {
6288 buf_printf(&out, " ");
6289 }
6290 buf_printf(&out, "[%s]", ipset2ascii(i));
6291 }
6292 return BSTR(&out);
6293}
6294
6295#else /* generic */
6296
6297void
6298open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
6299 openvpn_net_ctx_t *ctx)
6300{
6301 open_tun_generic(dev, dev_type, dev_node, tt);
6302}
6303
6304void
6305close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
6306{
6307 ASSERT(tt);
6308
6310 free(tt);
6311}
6312
6313ssize_t
6314write_tun(struct tuntap *tt, uint8_t *buf, int len)
6315{
6316 return write(tt->fd, buf, len);
6317}
6318
6319ssize_t
6320read_tun(struct tuntap *tt, uint8_t *buf, int len)
6321{
6322 return read(tt->fd, buf, len);
6323}
6324
6325#endif /* if defined (TARGET_ANDROID) */
void argv_msg(const msglvl_t msglevel, const struct argv *a)
Write the arguments stored in a struct argv via the msg() command.
Definition argv.c:242
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
Definition argv.c:101
void argv_msg_prefix(const msglvl_t msglevel, const struct argv *a, const char *prefix)
Similar to argv_msg() but prefixes the messages being written with a given string.
Definition argv.c:259
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
Definition argv.c:438
bool argv_printf_cat(struct argv *argres, const char *format,...)
printf() inspired argv concatenation.
Definition argv.c:462
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
Definition argv.c:87
void free_buf(struct buffer *buf)
Definition buffer.c:184
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:241
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition buffer.c:341
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:89
char * format_hex_ex(const uint8_t *data, size_t size, size_t maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
Definition buffer.c:488
struct buffer alloc_buf(size_t size)
Definition buffer.c:63
bool checked_snprintf(char *str, size_t size, const char *format,...)
Like snprintf() but returns an boolean.
Definition buffer.c:1143
char * string_alloc(const char *str, struct gc_arena *gc)
Definition buffer.c:653
static bool has_digit(const char *src)
Definition buffer.h:373
#define ALLOC_OBJ(dptr, type)
Definition buffer.h:1083
#define BSTR(buf)
Definition buffer.h:129
static struct buffer clear_buf(void)
Return an empty struct buffer.
Definition buffer.h:223
static bool buf_copy(struct buffer *dest, const struct buffer *src)
Definition buffer.h:705
#define BPTR(buf)
Definition buffer.h:123
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
Definition buffer.h:332
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Definition buffer.h:1125
#define BLEN(buf)
Definition buffer.h:126
static char * format_hex(const uint8_t *data, size_t size, size_t maxoutput, struct gc_arena *gc)
Definition buffer.h:504
#define BCAP(buf)
Definition buffer.h:130
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition buffer.h:362
static void check_malloc_return(void *p)
Definition buffer.h:1131
static void gc_free(struct gc_arena *a)
Definition buffer.h:1049
static struct gc_arena gc_new(void)
Definition buffer.h:1041
static int open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev)
Definition dco.h:298
static void close_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx)
Definition dco.h:304
bool build_dhcp_options_string(struct buffer *buf, const struct tuntap_options *o)
Definition dhcp.c:330
void env_set_destroy(struct env_set *es)
Definition env_set.c:166
void setenv_int(struct env_set *es, const char *name, int value)
Definition env_set.c:291
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition env_set.c:307
void env_set_add(struct env_set *es, const char *str)
Definition env_set.c:193
struct env_set * env_set_create(struct gc_arena *gc)
Definition env_set.c:156
#define D_TAP_WIN_DEBUG
Definition errlevel.h:114
#define D_REGISTRY
Definition errlevel.h:177
#define D_IFCONFIG
Definition errlevel.h:92
#define D_ROUTE_DEBUG
Definition errlevel.h:132
#define D_WIN32_IO_LOW
Definition errlevel.h:124
#define D_WIN32_IO
Definition errlevel.h:172
#define D_TUNTAP_INFO
Definition errlevel.h:80
#define D_MTU_INFO
Definition errlevel.h:104
#define D_READ_WRITE
Definition errlevel.h:166
#define D_OSBUF
Definition errlevel.h:90
#define D_LOW
Definition errlevel.h:96
#define M_INFO
Definition errlevel.h:54
#define D_DHCP_OPT
Definition errlevel.h:97
#define EVENT_WRITE
Definition event.h:38
#define EVENT_READ
Definition event.h:37
void set_nonblock(socket_descriptor_t fd)
Definition fdmisc.c:68
void set_cloexec(socket_descriptor_t fd)
Definition fdmisc.c:78
static SERVICE_STATUS status
Definition interactive.c:51
@ write
@ read
void management_set_state(struct management *man, const int state, const char *detail, const in_addr_t *tun_local_ip, const struct in6_addr *tun_local_ip6, const struct openvpn_sockaddr *local, const struct openvpn_sockaddr *remote)
Definition manage.c:2795
void management_sleep(const int n)
A sleep function that services the management layer for n seconds rather than doing nothing.
Definition manage.c:4145
#define OPENVPN_STATE_ASSIGN_IP
Definition manage.h:450
static void net_ctx_reset(openvpn_net_ctx_t *ctx)
Definition networking.h:56
static void net_ctx_free(openvpn_net_ctx_t *ctx)
Definition networking.h:62
void * openvpn_net_ctx_t
Definition networking.h:38
#define TUN_ADAPTER_INDEX_INVALID
Definition openvpn-msg.h:69
@ msg_del_address
Definition openvpn-msg.h:33
@ msg_add_wins_cfg
Definition openvpn-msg.h:49
@ msg_add_address
Definition openvpn-msg.h:32
@ msg_enable_dhcp
Definition openvpn-msg.h:46
@ msg_create_adapter
Definition openvpn-msg.h:51
@ msg_del_wins_cfg
Definition openvpn-msg.h:50
@ msg_add_dns_cfg
Definition openvpn-msg.h:36
@ msg_register_dns
Definition openvpn-msg.h:45
@ msg_set_mtu
Definition openvpn-msg.h:48
@ msg_flush_neighbors
Definition openvpn-msg.h:42
@ msg_del_dns_cfg
Definition openvpn-msg.h:37
adapter_type_t
@ ADAPTER_TYPE_DCO
@ ADAPTER_TYPE_TAP
#define BOOL_CAST(x)
Definition basic.h:26
#define CLEAR(x)
Definition basic.h:32
#define SIZE(x)
Definition basic.h:29
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
Definition error.c:775
#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:4739
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:3895
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:1481
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:1790
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:2565
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:2198
void route_ipv6_clear_host_bits(struct route_ipv6 *r6)
Definition route.c:1765
#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:2846
in_addr_t getaddr(unsigned int flags, const char *hostname, int resolve_retry_seconds, bool *succeeded, struct signal_info *sig_info)
Translate an IPv4 addr or hostname from string form to in_addr_t.
Definition socket.c:195
const char * print_in6_addr(struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
#define GETADDR_FATAL
#define GETADDR_HOST_ORDER
#define GETADDR_FATAL_ON_SIGNAL
#define GETADDR_RESOLVE
#define IA_NET_ORDER
Definition socket_util.h:90
inet_address_t address
Definition openvpn-msg.h:84
message_header_t header
Definition openvpn-msg.h:82
interface_t iface
Definition openvpn-msg.h:86
Definition argv.h:35
Wrapper structure for dynamically allocated memory.
Definition buffer.h: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:417
struct device_instance_id_interface * next
Definition tun.h:418
Definition dhcp.h:62
message_header_t header
inet_address_t addr[4]
interface_t iface
unsigned int addr_len
message_header_t header
Packet geometry parameters.
Definition mtu.h:108
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
struct gc_entry * list
First element of the linked list of gc_entry structures.
Definition buffer.h:117
char name[256]
Definition openvpn-msg.h:71
const char * short_form
Definition tun.c:6240
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:411
const char * name
Definition tun.h:409
const char * guid
Definition tun.h:410
in_addr_t netmask
Definition route.h:154
unsigned int flags
Definition route.h:165
struct route_gateway_address gateway
Definition route.h:180
int metric
Definition route.h:130
in_addr_t network
Definition route.h:126
in_addr_t netmask
Definition route.h:127
in_addr_t gateway
Definition route.h:128
unsigned int flags
Definition route.h:124
HANDLE write
Definition win32.h:82
HANDLE read
Definition win32.h:81
SECURITY_ATTRIBUTES sa
Definition win32.h:64
message_header_t header
interface_t iface
bool is_handle
Definition socket.h:280
Definition tun.h:401
struct tap_reg * next
Definition tun.h:404
enum tun_driver_type windows_driver
Definition tun.h:403
const char * guid
Definition tun.h:402
struct in6_addr dns6[N_DHCP_ADDR]
Definition tun.h:140
unsigned int dns6_len
Definition tun.h:141
in_addr_t wins[N_DHCP_ADDR]
Definition tun.h:115
int tap_sleep
Definition tun.h:95
unsigned int dns_len
Definition tun.h:112
int dhcp_lease_time
Definition tun.h:92
in_addr_t dns[N_DHCP_ADDR]
Definition tun.h:111
bool dhcp_masq_custom_offset
Definition tun.h:90
const char * domain
Definition tun.h:101
bool dhcp_renew
Definition tun.h:135
const char * domain_search_list[N_SEARCH_LIST_LEN]
Definition tun.h:129
HANDLE msg_channel
Definition tun.h:86
int dhcp_masq_offset
Definition tun.h:91
int ip_win32_type
Definition tun.h:83
bool dhcp_pre_release
Definition tun.h:136
bool register_dns
Definition tun.h:138
unsigned int wins_len
Definition tun.h:116
int dhcp_options
Definition tun.h:99
Definition tun.h:181
in_addr_t local
Definition tun.h:208
int type
Definition tun.h:183
ULONG ipapi_instance
Definition tun.h:227
int netbits_ipv6
Definition tun.h:213
DWORD adapter_index
Definition tun.h:232
struct rw_handle rw_handle
Definition tun.h:221
enum tun_driver_type backend_driver
The backend driver that used for this tun/tap device.
Definition tun.h:191
bool did_ifconfig_ipv6_setup
if the internal variables related to ifconfig-ipv6 of this struct have been set up.
Definition tun.h:199
struct tuntap_options options
Definition tun.h:203
struct in6_addr remote_ipv6
Definition tun.h:212
bool did_ifconfig_setup
if the internal variables related to ifconfig of this struct have been set up.
Definition tun.h:195
int topology
Definition tun.h:186
struct overlapped_io writes
Definition tun.h:220
in_addr_t adapter_netmask
Definition tun.h:228
HANDLE hand
Definition tun.h:216
struct overlapped_io reads
Definition tun.h:219
struct in6_addr local_ipv6
Definition tun.h:211
ULONG ipapi_context
Definition tun.h:226
dco_context_t dco
Definition tun.h:247
char * actual_name
Definition tun.h:205
in_addr_t remote_netmask
Definition tun.h:209
bool ipapi_context_defined
Definition tun.h:225
bool persistent_if
Definition tun.h:201
interface_t iface
unsigned int addr_len
inet_address_t addr[4]
message_header_t header
#define sleep(x)
Definition syshead.h:42
uint32_t in_addr_t
Definition syshead.h:52
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:3964
void ipconfig_register_dns(const struct env_set *es)
Definition tun.c:4889
void tun_show_debug(struct tuntap *tt)
Definition tun.c:6054
static const struct tap_reg * get_tap_reg(struct gc_arena *gc)
Definition tun.c:3530
static DWORD get_adapter_index_method_1(const char *guid)
Definition tun.c:4539
static void tuntap_post_open(struct tuntap *tt, const char *device_guid)
Definition tun.c:5953
static void netsh_set_dns6_servers(const struct in6_addr *addr_list, const unsigned int addr_len, DWORD adapter_index)
Set the ipv6 dns servers on the specified interface.
Definition tun.c:5002
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:5260
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:5997
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:3645
void close_tun_handle(struct tuntap *tt)
Definition tun.c:6117
void fork_register_dns_action(struct tuntap *tt)
Definition tun.c:5386
static bool test_adapter_ip_netmask(const IP_ADAPTER_INFO *ai, const in_addr_t ip, const in_addr_t netmask)
Definition tun.c:4287
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:5170
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:3815
bool dhcp_renew_by_adapter_index(const DWORD adapter_index)
Definition tun.c:4822
static void tuntap_get_version_info(const struct tuntap *tt)
Definition tun.c:5436
static bool service_enable_dhcp(const struct tuntap *tt)
Definition tun.c:5185
static void netsh_delete_address_dns(const struct tuntap *tt, bool ipv6, struct gc_arena *gc)
Definition tun.c:6070
static void exec_command(const char *prefix, const struct argv *a, int n, msglvl_t msglevel)
Definition tun.c:4862
int ascii2ipset(const char *name)
Definition tun.c:6249
const IP_ADAPTER_INFO * get_tun_adapter(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
Definition tun.c:4303
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:4316
static void tuntap_set_ptp(const struct tuntap *tt)
Definition tun.c:5625
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:5758
static DWORD get_adapter_index(const char *guid)
Definition tun.c:4579
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:5114
const IP_ADAPTER_INFO * get_adapter_info(DWORD index, struct gc_arena *gc)
Definition tun.c:4218
static bool dhcp_release(const struct tuntap *tt)
Definition tun.c:4808
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:5331
static void show_adapter(msglvl_t msglevel, const IP_ADAPTER_INFO *a, struct gc_arena *gc)
Definition tun.c:4619
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:4245
const IP_PER_ADAPTER_INFO * get_per_adapter_info(const DWORD index, struct gc_arena *gc)
Definition tun.c:4116
static bool ip_addr_one_to_one(const in_addr_t *a1, const unsigned int a1len, const IP_ADDR_STRING *ias)
Definition tun.c:4955
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:3378
static void ip_addr_string_to_array(in_addr_t *dest, unsigned int *dest_len, const IP_ADDR_STRING *src)
Definition tun.c:4911
#define DHCP_STATUS_DISABLED
Definition tun.c:4469
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:4027
bool is_ip_in_adapter_subnet(const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask)
Definition tun.c:4360
static void delete_temp_addresses(DWORD index)
Definition tun.c:4501
static void tuntap_set_ip_addr(struct tuntap *tt, const char *device_guid, bool dhcp_masq_post)
Definition tun.c:5488
const char * tap_win_getinfo(const struct tuntap *tt, struct gc_arena *gc)
Definition tun.c:6038
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:3932
static const IP_ADAPTER_INDEX_MAP * get_interface_info(DWORD index, struct gc_arena *gc)
Definition tun.c:4175
static const IP_INTERFACE_INFO * get_interface_info_list(struct gc_arena *gc)
Definition tun.c:4147
#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:5405
#define DHCP_STATUS_UNDEF
Definition tun.c:4467
#define DHCP_STATUS_ENABLED
Definition tun.c:4468
static void tuntap_set_ip_props(const struct tuntap *tt, bool *dhcp_masq, bool *dhcp_masq_post)
Definition tun.c:5913
static void register_dns_service(const struct tuntap *tt)
Definition tun.c:5357
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:3323
bool dhcp_release_by_adapter_index(const DWORD adapter_index)
Definition tun.c:4781
void delete_route_connected_v6_net(const struct tuntap *tt)
Definition tun.c:995
bool tun_standby(struct tuntap *tt)
Definition tun.c:5310
static void tuntap_dhcp_mask(const struct tuntap *tt, const char *device_guid)
Definition tun.c:5682
static void init_ip_addr_string2(IP_ADDR_STRING *dest, const IP_ADDR_STRING *src1, const IP_ADDR_STRING *src2)
Definition tun.c:5096
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
#define MAX_ADDRS
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:3404
void close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
Definition tun.c:6148
static const char * guid_to_name(const char *guid, const struct panel_reg *panel_reg)
Definition tun.c:3916
static DWORD get_adapter_index_method_2(const char *guid)
Definition tun.c:4557
static int dhcp_status(DWORD index)
Definition tun.c:4472
const IP_ADAPTER_INFO * get_adapter_info_list(struct gc_arena *gc)
Definition tun.c:4091
void tap_allow_nonadmin_access(const char *dev_node)
Definition tun.c:4701
bool tun_name_is_fixed(const char *dev)
Definition tun.c:1804
static bool ip_addr_member_of(const in_addr_t addr, const IP_ADDR_STRING *ias)
Definition tun.c:4979
static const char * format_ip_addr_string(const IP_ADDR_STRING *ip, struct gc_arena *gc)
Definition tun.c:4598
const IP_ADAPTER_INFO * get_adapter(const IP_ADAPTER_INFO *ai, DWORD index)
Definition tun.c:4199
static void at_least_one_tap_win(const struct tap_reg *tap_reg)
Definition tun.c:3949
void show_adapters(msglvl_t msglevel)
Definition tun.c:4652
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:4848
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:3268
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:5605
static const struct tap_reg * get_adapter_by_guid(const char *guid, const struct tap_reg *tap_reg)
Definition tun.c:3900
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:5476
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:6264
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:5217
const char * ipset2ascii_all(struct gc_arena *gc)
Definition tun.c:6278
static int get_adapter_n_ip_netmask(const IP_ADAPTER_INFO *ai)
Definition tun.c:4224
void tun_standby_init(struct tuntap *tt)
Definition tun.c:5304
#define NI_IP_NETMASK
Definition tun.c:98
void show_valid_win32_tun_subnets(void)
Definition tun.c:3782
static void tap_allow_nonadmin_access_handle(const char *device_path, HANDLE hand)
Definition tun.c:4679
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:4883
DWORD adapter_index_of_ip(const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count, in_addr_t *netmask)
Definition tun.c:4394
static void do_dns_service(bool add, const short family, const struct tuntap *tt)
Definition tun.c:240
static void netsh_ifconfig_options(const char *type, const in_addr_t *addr_list, const unsigned int addr_len, const IP_ADDR_STRING *current, DWORD adapter_index, const bool test_first)
Definition tun.c:5031
void tun_open_device(struct tuntap *tt, const char *dev_node, const char **device_guid, struct gc_arena *gc)
Definition tun.c:5815
void verify_255_255_255_252(in_addr_t local, in_addr_t remote)
Definition tun.c:3746
ssize_t write_tun(struct tuntap *tt, uint8_t *buf, int len)
#define IPW32_SET_NETSH
Definition tun.h:78
#define IPW32_SET_ADAPTIVE
Definition tun.h:81
#define DHCP_OPTIONS_DHCP_REQUIRED
Definition tun.h:70
#define N_SEARCH_LIST_LEN
Definition tun.h:126
#define IPW32_SET_IPAPI
Definition tun.h:79
ssize_t read_tun(struct tuntap *tt, uint8_t *buf, int len)
#define IPW32_SET_DHCP_MASQ
Definition tun.h:80
static bool tuntap_is_dco_win(struct tuntap *tt)
Definition tun.h:532
#define DCO_WIN_REFERENCE_STRING
Definition tun.h:59
#define IPW32_SET_ADAPTIVE_TRY_NETSH
Definition tun.h:66
#define IPW32_SET_N
Definition tun.h:82
#define IPW32_SET_MANUAL
Definition tun.h:77
tun_driver_type
Definition tun.h:44
@ DRIVER_NULL
Definition tun.h:52
@ WINDOWS_DRIVER_UNSPECIFIED
Definition tun.h:45
@ DRIVER_UTUN
macOS internal tun driver
Definition tun.h:55
@ DRIVER_GENERIC_TUNTAP
Definition tun.h:47
@ DRIVER_AFUNIX
using an AF_UNIX socket to pass packets from/to an external program.
Definition tun.h:51
@ WINDOWS_DRIVER_TAP_WINDOWS6
Definition tun.h:46
@ DRIVER_DCO
Definition tun.h:53
struct in6_addr ipv6
Definition openvpn-msg.h:64
struct in_addr ipv4
Definition openvpn-msg.h:63
int get_interface_metric(const NET_IFINDEX index, const ADDRESS_FAMILY family, int *is_auto)
Return interface metric value for the specified interface index.
Definition wfp_block.c:378
void overlapped_io_init(struct overlapped_io *o, const struct frame *frame, BOOL event_state)
Definition win32.c:169
void fork_to_self(const char *cmdline)
Definition win32.c:1067
char * overlapped_io_state_ascii(const struct overlapped_io *o)
Definition win32.c:198
void overlapped_io_close(struct overlapped_io *o)
Definition win32.c:185
void netcmd_semaphore_release(void)
Definition win32.c:867
char * get_win_sys_path(void)
Definition win32.c:1108
void netcmd_semaphore_lock(void)
Definition win32.c:851
bool send_msg_iservice(HANDLE pipe, const void *data, DWORD size, ack_message_t *ack, const char *context)
Send the size bytes in buffer data to the interactive service pipe and read the result in ack.
Definition win32.c:1422
bool init_security_attributes_allow_all(struct security_attributes *obj)
Definition win32.c:150
#define IOSTATE_IMMEDIATE_RETURN
Definition win32.h:207
#define POWERSHELL_PATH_SUFFIX
Definition win32.h:43
#define WIN_IPCONFIG_PATH_SUFFIX
Definition win32.h:41
static bool overlapped_io_active(struct overlapped_io *o)
Definition win32.h:229
#define IOSTATE_INITIAL
Definition win32.h:205
#define IOSTATE_QUEUED
Definition win32.h:206
#define NETSH_PATH_SUFFIX
Definition win32.h:39