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