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