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