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