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