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