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