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