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