64 return "tap-windows6";
89 0x4d36e972L, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 }
92 0xcac88484, 0x7515, 0x4c03, { 0x82, 0xe6, 0x71, 0xa8, 0x7a, 0xba, 0xc3, 0x61 }
97#define NI_TEST_FIRST (1 << 0)
98#define NI_IP_NETMASK (1 << 1)
99#define NI_OPTIONS (1 << 2)
102 const in_addr_t netmask,
const unsigned int flags);
104static void windows_set_mtu(
const int iface_index,
const short family,
const int mtu);
107 DWORD adapter_index);
115#if defined(__GNUC__) || defined(__clang__)
116#pragma GCC diagnostic push
117#pragma GCC diagnostic ignored "-Wsign-compare"
139 if (addr.
family == AF_INET)
143 msg(
D_IFCONFIG,
"INET address service: %s %s/%d", add ?
"add" :
"remove",
150 msg(
D_IFCONFIG,
"INET6 address service: %s %s/%d", add ?
"add" :
"remove",
161 msg(
M_WARN,
"TUN: %s address failed using service: %s [status=%u if_index=%d]",
208 size_t dstlen = strlen(
dns.domains);
210 size_t extra = dstlen ? 2 : 1;
211 if (dstlen + srclen + extra >
sizeof(
dns.domains))
213 msg(
M_WARN,
"DNS search domains sent to service truncated to %d", i);
218 dns.domains[dstlen++] =
',';
223 msg(
D_LOW,
"%s DNS domains on '%s' (if_index = %d) using service",
224 (add ?
"Setting" :
"Deleting"),
dns.iface.name,
dns.iface.index);
232 msg(
M_WARN,
"TUN: %s DNS domains failed using service: %s [status=%u if_name=%s]",
238 msg(
M_INFO,
"DNS domains %s using service", (add ?
"set" :
"deleted"));
251 int addr_len = add ? len : 0;
252 const char *ip_proto_name = family == AF_INET6 ?
"IPv6" :
"IPv4";
266 .addr_len = addr_len };
272 if (addr_len > _countof(dns.
addr))
274 addr_len = _countof(dns.
addr);
276 msg(
M_WARN,
"Number of %s DNS addresses sent to service truncated to %d", ip_proto_name,
280 for (
int i = 0; i < addr_len; ++i)
282 if (family == AF_INET6)
292 msg(
D_LOW,
"%s %s dns servers on '%s' (if_index = %d) using service",
302 msg(
M_WARN,
"TUN: %s %s dns failed using service: %s [status=%u if_name=%s]",
308 msg(
M_INFO,
"%s dns servers %s using service", ip_proto_name, (add ?
"set" :
"deleted"));
331 .addr_len = addr_len };
337 if (addr_len > _countof(wins.
addr))
339 addr_len = _countof(wins.
addr);
341 msg(
M_WARN,
"Number of WINS addresses sent to service truncated to %d", addr_len);
344 for (
int i = 0; i < addr_len; ++i)
349 msg(
D_LOW,
"%s WINS servers on '%s' (if_index = %d) using service",
359 msg(
M_WARN,
"TUN: %s WINS failed using service: %s [status=%u if_name=%s]",
365 msg(
M_INFO,
"WINS servers %s using service", (add ?
"set" :
"deleted"));
371#if defined(__GNUC__) || defined(__clang__)
372#pragma GCC diagnostic pop
382 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
388 if (family == AF_INET6 && mtu < 1280)
391 "NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
401 msg(
M_NONFATAL,
"TUN: setting %s mtu using service failed: %s [status=%u if_index=%d]",
407 msg(
M_INFO,
"%s MTU set to %d on interface %d using service", family_name, mtu,
427 "%s%s -NoProfile -NonInteractive -Command Set-DnsClient -InterfaceIndex %lu -ConnectionSpecificSuffix '%s'",
479 msg(
M_NONFATAL,
"TUN: creating %s adapter using service failed: %s [status=%u]",
497static void solaris_error_close(
struct tuntap *tt,
const struct env_set *
es,
const char *actual,
503#if defined(TARGET_DARWIN)
504#include <sys/kern_control.h>
505#include <net/if_utun.h>
506#include <sys/sys_domain.h>
512is_dev_type(
const char *dev,
const char *dev_type,
const char *match_type)
521 return !strcmp(dev_type, match_type);
525 return !strncmp(dev, match_type, strlen(match_type));
560 return "[unknown-dev-type]";
598 const bool looks_like_netmask = ((addr & 0xFF000000) == 0xFF000000);
601 if (looks_like_netmask)
604 "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",
610 if (!looks_like_netmask)
613 "WARNING: Since you are using subnet topology, the second argument to --ifconfig must be a netmask, for example something like 255.255.255.0. %s",
630 msg(
M_INFO,
"CHECK_ADDR_CLASH type=%d public=%s local=%s, remote_netmask=%s",
641 const in_addr_t test_netmask = 0xFFFFFF00;
642 const in_addr_t public_net =
public & test_netmask;
643 const in_addr_t local_net = local & test_netmask;
644 const in_addr_t remote_net = remote_netmask & test_netmask;
646 if (
public == local ||
public == remote_netmask)
649 "WARNING: --%s address [%s] conflicts with --ifconfig address pair [%s, %s]. %s",
654 if (public_net == local_net || public_net == remote_net)
657 "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",
664 const in_addr_t public_network =
public & remote_netmask;
665 const in_addr_t virtual_network = local & remote_netmask;
666 if (public_network == virtual_network)
669 "WARNING: --%s address [%s] conflicts with --ifconfig subnet [%s, %s] -- local and remote addresses cannot be inside of the --ifconfig subnet. %s",
686 if ((rgi.
flags & needed) == needed)
689 if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100)
692 "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.");
706 if (
tt->did_ifconfig_setup && !disable)
785 msg(
M_FATAL,
"Error: problem with tun vs. tap setting");
811 setenv_str(
es,
"ifconfig_remote", ifconfig_remote_netmask);
815 setenv_str(
es,
"ifconfig_netmask", ifconfig_remote_netmask);
824 setenv_str(
es,
"ifconfig_ipv6_local", ifconfig_ipv6_local);
826 setenv_str(
es,
"ifconfig_ipv6_remote", ifconfig_ipv6_remote);
840 const char *dev_type,
842 const char *ifconfig_local_parm,
843 const char *ifconfig_remote_netmask_parm,
844 const char *ifconfig_ipv6_local_parm,
845 int ifconfig_ipv6_netbits_parm,
846 const char *ifconfig_ipv6_remote_parm,
847 struct addrinfo *local_public,
struct addrinfo *remote_public,
const bool strict_warn,
859 if (ifconfig_local_parm && ifconfig_remote_netmask_parm)
872 ifconfig_local_parm, 0, NULL, NULL);
876 ifconfig_remote_netmask_parm, 0, NULL, NULL);
883 struct addrinfo *curele;
891 for (curele = local_public; curele; curele = curele->ai_next)
893 if (curele->ai_family == AF_INET)
896 ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
901 for (curele = remote_public; curele; curele = curele->ai_next)
903 if (curele->ai_family == AF_INET)
906 ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
931 if (ifconfig_ipv6_local_parm && ifconfig_ipv6_remote_parm)
937 if (inet_pton(AF_INET6, ifconfig_ipv6_local_parm, &tt->
local_ipv6) != 1
938 || inet_pton(AF_INET6, ifconfig_ipv6_remote_parm, &tt->
remote_ipv6) != 1)
940 msg(
M_FATAL,
"init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary",
941 ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm);
1020#if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || defined(TARGET_NETBSD) \
1021 || defined(TARGET_OPENBSD)
1032create_arbitrary_remote(
struct tuntap *tt)
1038 if (remote == tt->
local)
1060#if !defined(TARGET_LINUX)
1066#if defined(TARGET_LINUX)
1067 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1069 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1072 if (net_iface_up(ctx, ifname,
true) < 0)
1074 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1079 msg(
M_FATAL,
"Linux can't add IPv6 to interface %s", ifname);
1081#elif defined(TARGET_ANDROID)
1084 snprintf(out6,
sizeof(out6),
"%s/%d %d", ifconfig_ipv6_local, tt->
netbits_ipv6, tun_mtu);
1085 management_android_control(
management,
"IFCONFIG6", out6);
1086#elif defined(TARGET_SOLARIS)
1096 ifconfig_ipv6_local, tt->
netbits_ipv6, ifconfig_ipv6_remote, tun_mtu);
1106 solaris_error_close(tt,
es, ifname,
true);
1125 solaris_error_close(tt,
es, ifname,
true);
1134#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) || defined(TARGET_DARWIN) \
1135 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1142#if defined(TARGET_FREEBSD) && __FreeBSD_version >= 1200000 && __FreeBSD_version < 1300000
1164#elif defined(TARGET_AIX)
1176#elif defined(_WIN32)
1180 "******** NOTE: Please manually set the v6 IP of '%s' to %s (if it is not already set)",
1181 ifname, ifconfig_ipv6_local);
1210 argv_printf(&
argv,
"%s%s interface ipv6 set address %lu %s/%d store=active",
1229 "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.");
1232#if !defined(TARGET_LINUX)
1251#if !defined(_WIN32) && !defined(TARGET_ANDROID)
1258#if !defined(TARGET_LINUX)
1259 const char *ifconfig_local = NULL;
1260 const char *ifconfig_remote_netmask = NULL;
1271#if defined(TARGET_LINUX)
1272 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1274 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1277 if (net_iface_up(ctx, ifname,
true) < 0)
1279 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1286 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1293 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1296#elif defined(TARGET_ANDROID)
1299 snprintf(out,
sizeof(out),
"%s %s %d %s", ifconfig_local, ifconfig_remote_netmask, tun_mtu,
1301 management_android_control(
management,
"IFCONFIG", out);
1303#elif defined(TARGET_SOLARIS)
1312 ifconfig_remote_netmask, tun_mtu);
1317 solaris_error_close(tt,
es, ifname,
false);
1325 ifconfig_local, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1330 ifconfig_remote_netmask);
1336 solaris_error_close(tt,
es, ifname,
false);
1352#elif defined(TARGET_OPENBSD)
1366 ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1370 remote_end = create_arbitrary_remote(tt);
1373 ifconfig_remote_netmask);
1378 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1395#elif defined(TARGET_NETBSD)
1401 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1405 remote_end = create_arbitrary_remote(tt);
1408 ifconfig_remote_netmask);
1418 ifconfig_remote_netmask, tun_mtu);
1435#elif defined(TARGET_DARWIN)
1443 msg(
M_INFO,
"NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
1450 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1455 ifconfig_local, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1460 ifconfig_remote_netmask, tun_mtu);
1478#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1484 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1496#elif defined(TARGET_AIX)
1504 msg(
M_FATAL,
"no tun support on AIX (canthappen)");
1509 ifconfig_remote_netmask, tun_mtu);
1516#elif defined(_WIN32)
1520 "******** NOTE: Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
1521 ifname, ifconfig_local, ifconfig_remote_netmask);
1555#elif defined(TARGET_HAIKU)
1558 ifconfig_remote_netmask, tun_mtu);
1564 "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.");
1567#if !defined(TARGET_LINUX)
1581#ifdef ENABLE_MANAGEMENT
1606#if defined(TARGET_LINUX)
1623#elif defined(TARGET_FREEBSD)
1641#if defined(TARGET_LINUX)
1646#elif defined(TARGET_FREEBSD)
1692#ifdef TARGET_SOLARIS
1697#if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) || defined(TARGET_DARWIN)
1715#include <netinet/ip.h>
1718#if defined(__GNUC__) || defined(__clang__)
1719#pragma GCC diagnostic push
1720#pragma GCC diagnostic ignored "-Wsign-compare"
1723static inline ssize_t
1724header_modify_read_write_return(ssize_t len)
1728 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
1736#if defined(__GNUC__) || defined(__clang__)
1737#pragma GCC diagnostic pop
1741write_tun_header(
struct tuntap *tt, uint8_t *buf,
int len)
1747 struct ip *iph = (
struct ip *)buf;
1751 type = htonl(AF_INET6);
1755 type = htonl(AF_INET);
1758 iv[0].iov_base = &type;
1759 iv[0].iov_len =
sizeof(type);
1760 iv[1].iov_base = buf;
1761 iv[1].iov_len = len;
1763 return header_modify_read_write_return(writev(tt->fd, iv, 2));
1767 return write(tt->fd, buf, len);
1772read_tun_header(
struct tuntap *tt, uint8_t *buf,
int len)
1779 iv[0].iov_base = &type;
1780 iv[0].iov_len =
sizeof(type);
1781 iv[1].iov_base = buf;
1782 iv[1].iov_len = len;
1784 return header_modify_read_write_return(readv(tt->fd, iv, 2));
1788 return read(tt->fd, buf, len);
1796#if !defined(TARGET_DARWIN)
1800 return write_tun_header(tt, buf, len);
1806 return read_tun_header(tt, buf, len);
1818#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1820tun_dco_enabled(
struct tuntap *tt)
1827#if !(defined(_WIN32) || defined(TARGET_LINUX) || defined(TARGET_SOLARIS) || defined(TARGET_ANDROID))
1829open_tun_generic(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt)
1832 char dynamic_name[256];
1833 bool dynamic_opened =
false;
1840 snprintf(tunname,
sizeof(tunname),
"%s", dev_node);
1852 for (
int i = 0; i < 256; ++i)
1856#if defined(TARGET_HAIKU)
1859 snprintf(tunname,
sizeof(tunname),
"/dev/%s%s%d", dev, sep, i);
1860 snprintf(dynamic_name,
sizeof(dynamic_name),
"%s%s%d", dev, sep, i);
1861 if ((tt->fd = open(tunname, O_RDWR)) > 0)
1863 dynamic_opened =
true;
1868 if (!dynamic_opened)
1870 msg(
M_FATAL,
"Cannot allocate TUN/TAP dev dynamically");
1878 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
1882 if (!dynamic_opened)
1885 if (if_nametoindex(dev) > 0)
1887 msg(
M_INFO,
"TUN/TAP device %s exists previously, keep at program end", dev);
1891 if ((tt->fd = open(tunname, O_RDWR)) < 0)
1893 msg(
M_ERR,
"Cannot open TUN/TAP dev %s", tunname);
1899 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
1906#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1908open_tun_dco_generic(
const char *dev,
const char *dev_type,
struct tuntap *tt,
1911 char dynamic_name[256];
1912 bool dynamic_opened =
false;
1922 if (strcmp(dev,
"tun") == 0)
1924 for (
int i = 0; i < 256; ++i)
1926 snprintf(dynamic_name,
sizeof(dynamic_name),
"%s%d", dev, i);
1930 dynamic_opened =
true;
1931 msg(
M_INFO,
"DCO device %s opened", dynamic_name);
1935 else if (ret == -EPERM)
1940 if (!dynamic_opened)
1942 msg(
M_FATAL,
"Cannot allocate DCO dev dynamically");
1956 msg(
M_INFO,
"DCO device %s already exists, won't be destroyed at shutdown", dev);
1961 msg(
M_ERR,
"Cannot open DCO device %s: %s (%d)", dev, strerror(-ret), ret);
1965 msg(
M_INFO,
"DCO device %s opened", dev);
1974#if !(defined(_WIN32) || defined(TARGET_SOLARIS))
1976close_tun_generic(
struct tuntap *tt)
1988#if defined(TARGET_ANDROID)
1990open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
1993#define ANDROID_TUNNAME "vpnservice-tun"
1997 int oldtunfd = tt->fd;
2003 management_android_control(
management,
"DNS6SERVER",
2009 management_android_control(
management,
"DNSSERVER",
2021 buf_printf(&buf,
"%s %d",
tt->options.http_proxy,
tt->options.http_proxy_port);
2051 msg(
M_ERR,
"ERROR: Cannot open TUN");
2078#elif defined(TARGET_LINUX)
2083open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *
tt,
2088 if (tun_dco_enabled(tt))
2090 open_tun_dco_generic(dev, dev_type, tt, ctx);
2097 const char *node = dev_node;
2100 node =
"/dev/net/tun";
2106 if ((tt->fd = open(node, O_RDWR)) < 0)
2108 msg(
M_ERR,
"ERROR: Cannot open TUN/TAP dev %s", node);
2115 ifr.ifr_flags = IFF_NO_PI;
2117#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2118 ifr.ifr_flags |= IFF_ONE_QUEUE;
2126 ifr.ifr_flags |= IFF_TUN;
2130 ifr.ifr_flags |= IFF_TAP;
2134 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device", dev);
2140 if (strcmp(dev,
"tun") && strcmp(dev,
"tap"))
2149 if (ioctl(tt->fd, TUNSETIFF, (
void *)&ifr) < 0)
2151 msg(
M_ERR,
"ERROR: Cannot ioctl TUNSETIFF %s", dev);
2154 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2159#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2162 struct ifreq netifr;
2165 if ((ctl_fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
2168 strncpynt(netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
2169 netifr.ifr_qlen = tt->
options.txqueuelen;
2170 if (ioctl(ctl_fd, SIOCSIFTXQLEN, (
void *)&netifr) >= 0)
2176 msg(
M_WARN |
M_ERRNO,
"Note: Cannot set tx queue length on %s", ifr.ifr_name);
2182 msg(
M_WARN |
M_ERRNO,
"Note: Cannot open control socket on %s", ifr.ifr_name);
2197open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2205#ifdef ENABLE_FEATURE_TUN_PERSIST
2208tuncfg(
const char *dev,
const char *dev_type,
const char *dev_node,
int persist_mode,
2219 open_tun(dev, dev_type, dev_node, tt, ctx);
2220 if (ioctl(tt->fd, TUNSETPERSIST, persist_mode) < 0)
2222 msg(
M_ERR,
"Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
2224 if (username != NULL)
2230 msg(
M_ERR,
"Cannot get user entry for %s", username);
2234 msg(
M_ERR,
"Cannot ioctl TUNSETOWNER(%s) %s", username, dev);
2237 if (groupname != NULL)
2243 msg(
M_ERR,
"Cannot get group entry for %s", groupname);
2247 msg(
M_ERR,
"Cannot ioctl TUNSETGROUP(%s) %s", groupname, dev);
2251 msg(
M_INFO,
"Persist state set to: %s", (persist_mode ?
"ON" :
"OFF"));
2261#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
2262 if (tun_dco_enabled(tt))
2267 close_tun_generic(tt);
2274 return write(tt->fd, buf, len);
2280 return read(tt->fd, buf, len);
2283#elif defined(TARGET_SOLARIS)
2286#error I need the symbol TUNNEWPPA from net/if_tun.h
2290open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2293 int if_fd = -1, ip_muxid = -1, arp_muxid = -1, arp_fd = -1, ppa = -1;
2296 const char *ip_node = NULL, *arp_node = NULL;
2297 const char *dev_tuntap_type;
2299 struct strioctl strioc_if, strioc_ppa;
2309 ip_node =
"/dev/udp";
2312 dev_node =
"/dev/tun";
2314 dev_tuntap_type =
"tun";
2315 link_type = I_PLINK;
2319 ip_node =
"/dev/udp";
2322 dev_node =
"/dev/tap";
2324 arp_node = dev_node;
2325 dev_tuntap_type =
"tap";
2326 link_type = I_PLINK;
2330 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device", dev);
2333 if ((tt->ip_fd = open(ip_node, O_RDWR, 0)) < 0)
2335 msg(
M_ERR,
"Can't open %s", ip_node);
2338 if ((tt->fd = open(dev_node, O_RDWR, 0)) < 0)
2340 msg(
M_ERR,
"Can't open %s", dev_node);
2348 while (*ptr && !isdigit((
int)*ptr))
2356 strioc_ppa.ic_cmd = TUNNEWPPA;
2357 strioc_ppa.ic_timout = 0;
2358 strioc_ppa.ic_len =
sizeof(ppa);
2359 strioc_ppa.ic_dp = (
char *)&ppa;
2363 bool found_one =
false;
2364 while (!found_one && ppa < 64)
2366 int new_ppa = ioctl(tt->fd, I_STR, &strioc_ppa);
2369 msg(
M_INFO,
"open_tun: got dynamic interface '%s%d'", dev_tuntap_type, new_ppa);
2374 if (errno != EEXIST)
2376 msg(
M_ERR,
"open_tun: unexpected error trying to find free %s interface",
2383 msg(
M_ERR,
"open_tun: could not find free %s interface, give up.", dev_tuntap_type);
2388 if ((ppa = ioctl(tt->fd, I_STR, &strioc_ppa)) < 0)
2390 msg(
M_ERR,
"Can't assign PPA for new interface (%s%d)", dev_tuntap_type, ppa);
2394 if ((if_fd = open(dev_node, O_RDWR, 0)) < 0)
2396 msg(
M_ERR,
"Can't open %s (2)", dev_node);
2399 if (ioctl(if_fd, I_PUSH,
"ip") < 0)
2401 msg(
M_ERR,
"Can't push IP module");
2407 if (ioctl(if_fd, IF_UNITSEL, (
char *)&ppa) < 0)
2409 msg(
M_ERR,
"Can't set PPA %d", ppa);
2416 snprintf(tt->
actual_name, 32,
"%s%d", dev_tuntap_type, ppa);
2420 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2427 if (ioctl(if_fd, SIOCSLIFNAME, &ifr) < 0)
2429 msg(
M_ERR,
"Can't set PPA %d", ppa);
2431 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2436 if (ioctl(if_fd, I_PUSH,
"arp") < 0)
2438 msg(
M_ERR,
"Can't push ARP module");
2444 if (ioctl(tt->ip_fd, I_POP, NULL) < 0)
2450 if (ioctl(tt->ip_fd, I_PUSH,
"arp") < 0)
2452 msg(
M_ERR,
"Can't push ARP module");
2456 if ((arp_fd = open(arp_node, O_RDWR, 0)) < 0)
2458 msg(
M_ERR,
"Can't open %s", arp_node);
2461 if (ioctl(arp_fd, I_PUSH,
"arp") < 0)
2463 msg(
M_ERR,
"Can't push ARP module");
2467 strioc_if.ic_cmd = SIOCSLIFNAME;
2468 strioc_if.ic_timout = 0;
2469 strioc_if.ic_len =
sizeof(ifr);
2470 strioc_if.ic_dp = (
char *)𝔦
2471 if (ioctl(arp_fd, I_STR, &strioc_if) < 0)
2473 msg(
M_ERR,
"Can't set ifname to arp");
2477 if ((ip_muxid = ioctl(tt->ip_fd, link_type, if_fd)) < 0)
2479 msg(
M_ERR,
"Can't link %s device to IP", dev_tuntap_type);
2484 if ((arp_muxid = ioctl(tt->ip_fd, link_type, arp_fd)) < 0)
2486 msg(
M_ERR,
"Can't link %s device to ARP", dev_tuntap_type);
2493 ifr.lifr_ip_muxid = ip_muxid;
2496 ifr.lifr_arp_muxid = arp_muxid;
2499 if (ioctl(tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0)
2503 ioctl(tt->ip_fd, I_PUNLINK, arp_muxid);
2505 ioctl(tt->ip_fd, I_PUNLINK, ip_muxid);
2506 msg(
M_ERR,
"Can't set multiplexor id");
2517solaris_close_tun(
struct tuntap *tt)
2535 if (ioctl(tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0)
2540 if (ioctl(tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0)
2547 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0)
2553 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0)
2577 solaris_close_tun(tt);
2586solaris_error_close(
struct tuntap *tt,
const struct env_set *
es,
const char *actual,
2612 sbuf.buf = (
char *)buf;
2613 return putmsg(tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
2623 sbuf.buf = (
char *)buf;
2624 return getmsg(tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
2627#elif defined(TARGET_OPENBSD)
2630open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2633 open_tun_generic(dev, dev_type, dev_node, tt);
2638 struct tuninfo info;
2640 if (ioctl(tt->fd, TUNGIFINFO, &info) < 0)
2646 info.flags |= IFF_MULTICAST;
2649 if (ioctl(tt->fd, TUNSIFINFO, &info) < 0)
2674 close_tun_generic(tt);
2686 close_tun_generic(tt);
2695#elif defined(TARGET_NETBSD)
2712open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2719 if (strcmp(dev,
"tap") == 0)
2722 if ((tt->fd = open(
"/dev/tap", O_RDWR)) < 0)
2724 msg(
M_FATAL,
"Cannot allocate NetBSD TAP dev dynamically");
2726 if (ioctl(tt->fd, TAPGIFNAME, (
void *)&ifr) < 0)
2728 msg(
M_FATAL,
"Cannot query NetBSD TAP device name");
2732 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2741 open_tun_generic(dev, dev_type, dev_node, tt);
2746 int i = IFF_POINTOPOINT | IFF_MULTICAST;
2747 ioctl(tt->fd, TUNSIFMODE, &i);
2749 ioctl(tt->fd, TUNSLMODE, &i);
2754 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0)
2775 close_tun_generic(tt);
2787 close_tun_generic(tt);
2796#elif defined(TARGET_FREEBSD)
2799open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2802 if (tun_dco_enabled(tt))
2804 open_tun_dco_generic(dev, dev_type, tt, ctx);
2808 open_tun_generic(dev, dev_type, dev_node, tt);
2813 int i = IFF_POINTOPOINT | IFF_MULTICAST;
2816 i = IFF_BROADCAST | IFF_MULTICAST;
2819 if (ioctl(tt->fd, TUNSIFMODE, &i) < 0)
2826 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0)
2848 close_tun_generic(tt);
2861 close_tun_generic(tt);
2870#elif defined(TARGET_DRAGONFLY)
2873open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2876 open_tun_generic(dev, dev_type, dev_node, tt);
2883 ioctl(tt->fd, TUNSLMODE, &i);
2885 ioctl(tt->fd, TUNSIFHEAD, &i);
2894 close_tun_generic(tt);
2898#elif defined(TARGET_DARWIN)
2920utun_open_helper(
struct ctl_info ctlInfo,
int utunnum)
2922 struct sockaddr_ctl sc;
2925 fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
2929 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (socket(SYSPROTO_CONTROL))", utunnum);
2933 if (ioctl(fd, CTLIOCGINFO, &ctlInfo) == -1)
2936 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (ioctl(CTLIOCGINFO))", utunnum);
2941 sc.sc_id = ctlInfo.ctl_id;
2942 sc.sc_len =
sizeof(sc);
2943 sc.sc_family = AF_SYSTEM;
2944 sc.ss_sysaddr = AF_SYS_CONTROL;
2946 sc.sc_unit = utunnum + 1;
2952 if (connect(fd, (
struct sockaddr *)&sc,
sizeof(sc)) < 0)
2954 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (connect(AF_SYS_CONTROL))", utunnum);
2966open_darwin_utun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt)
2968 struct ctl_info ctlInfo;
2972 socklen_t utunname_len =
sizeof(utunname);
2976 if (dev_node && (strcmp(
"utun", dev_node) != 0))
2978 if (sscanf(dev_node,
"utun%d", &utunnum) != 1)
2981 "Cannot parse 'dev-node %s' please use 'dev-node utunX'"
2982 "to use a utun device number X",
2989 if (strlcpy(ctlInfo.ctl_name, UTUN_CONTROL_NAME,
sizeof(ctlInfo.ctl_name))
2990 >=
sizeof(ctlInfo.ctl_name))
2992 msg(
M_ERR,
"Opening utun: UTUN_CONTROL_NAME too long");
2998 for (utunnum = 0; utunnum < 255; utunnum++)
3002 ASSERT(snprintf(ifname,
sizeof(ifname),
"utun%d", utunnum) > 0);
3003 if (if_nametoindex(ifname))
3007 fd = utun_open_helper(ctlInfo, utunnum);
3018 fd = utun_open_helper(ctlInfo, utunnum);
3030 if (getsockopt(fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, utunname, &utunname_len))
3032 msg(
M_ERR,
"Error retrieving utun interface name");
3037 msg(
M_INFO,
"Opened utun device %s", utunname);
3042open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3046 if ((!dev_node && tt->
type ==
DEV_TYPE_TUN) || (dev_node && !strncmp(dev_node,
"utun", 4)))
3052 msg(
M_FATAL,
"Cannot use utun devices with --dev-type %s",
3058 open_darwin_utun(dev, dev_type, dev_node, tt);
3065 msg(
M_INFO,
"Failed to open utun device. Falling back to /dev/tun device");
3066 open_tun_generic(dev, dev_type, NULL, tt);
3082 if (dev_node && strcmp(dev_node,
"tun") == 0)
3087 open_tun_generic(dev, dev_type, dev_node, tt);
3108 close_tun_generic(tt);
3119 return write_tun_header(tt, buf, len);
3123 return write(tt->fd, buf, len);
3132 return read_tun_header(tt, buf, len);
3136 return read(tt->fd, buf, len);
3140#elif defined(TARGET_AIX)
3143open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3147 char dynamic_name[20];
3152 msg(
M_FATAL,
"no support for 'tun' devices on AIX");
3155 if (strncmp(dev,
"tap", 3) != 0 || dev_node)
3158 "'--dev %s' and/or '--dev-node' not supported on AIX, use '--dev tap0', 'tap1', etc.",
3162 if (strcmp(dev,
"tap") == 0)
3165 for (i = 0; i < 99; i++)
3167 snprintf(tunname,
sizeof(tunname),
"/dev/tap%d", i);
3168 if (access(tunname, F_OK) < 0 && errno == ENOENT)
3175 msg(
M_FATAL,
"cannot find unused tap device");
3178 snprintf(dynamic_name,
sizeof(dynamic_name),
"tap%d", i);
3191 msg(
M_FATAL,
"TAP device name must be '--dev tapNNNN'");
3194 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
3199 if (access(tunname, F_OK) < 0 && errno == ENOENT)
3218 if ((tt->fd = open(tunname, O_RDWR)) < 0)
3220 msg(
M_ERR,
"Cannot open TAP device '%s'", tunname);
3225 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
3252 close_tun_generic(tt);
3265 return write(tt->fd, buf, len);
3271 return read(tt->fd, buf, len);
3274#elif defined(_WIN32)
3276#if defined(__GNUC__) || defined(__clang__)
3277#pragma GCC diagnostic push
3278#pragma GCC diagnostic ignored "-Wsign-compare"
3310 dmsg(
D_WIN32_IO,
"WIN32 I/O: TAP Read immediate return [%d,%d]", (
int)len,
3315 err = GetLastError();
3316 if (err == ERROR_IO_PENDING)
3328 dmsg(
D_WIN32_IO,
"WIN32 I/O: TAP Read error [%d] : %s", (
int)len,
3370 err = GetLastError();
3371 if (err == ERROR_IO_PENDING)
3403 err = GetLastError();
3421 HDEVINFO dev_info_set;
3427 SetupDiGetClassDevsEx(&
GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
3428 if (dev_info_set == INVALID_HANDLE_VALUE)
3430 err = GetLastError();
3431 msg(
M_FATAL,
"Error [%u] opening device information set key: %s", (
unsigned int)err,
3436 for (DWORD i = 0;; ++i)
3438 SP_DEVINFO_DATA device_info_data;
3441 char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3443 char device_instance_id[256];
3447 ULONG dev_interface_list_size;
3450 ZeroMemory(&device_info_data,
sizeof(SP_DEVINFO_DATA));
3451 device_info_data.cbSize =
sizeof(SP_DEVINFO_DATA);
3452 res = SetupDiEnumDeviceInfo(dev_info_set, i, &device_info_data);
3455 if (GetLastError() == ERROR_NO_MORE_ITEMS)
3465 dev_key = SetupDiOpenDevRegKey(dev_info_set, &device_info_data, DICS_FLAG_GLOBAL, 0,
3466 DIREG_DRV, KEY_QUERY_VALUE);
3467 if (dev_key == INVALID_HANDLE_VALUE)
3474 status = RegQueryValueEx(dev_key, net_cfg_instance_id_string, NULL, &data_type,
3476 if (
status != ERROR_SUCCESS)
3481 len =
sizeof(device_instance_id);
3482 res = SetupDiGetDeviceInstanceId(dev_info_set, &device_info_data, device_instance_id, len,
3489 cr = CM_Get_Device_Interface_List_Size(&dev_interface_list_size,
3491 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3493 if (cr != CR_SUCCESS)
3498 char *dev_interface_list =
gc_malloc(dev_interface_list_size,
false,
gc);
3500 dev_interface_list, dev_interface_list_size,
3501 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3502 if (cr != CR_SUCCESS)
3507 char *dev_if = dev_interface_list;
3510 while (strlen(dev_if) > 0)
3528 last->
next = dev_iif;
3532 dev_if += strlen(dev_if) + 1;
3536 RegCloseKey(dev_key);
3539 SetupDiDestroyDeviceInfoList(dev_info_set);
3554 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ADAPTER_KEY, 0, KEY_READ, &adapter_key);
3556 if (
status != ERROR_SUCCESS)
3558 msg(
M_FATAL,
"Error opening registry key: %s", ADAPTER_KEY);
3564 char enum_name[256];
3565 char unit_string[256];
3567 char component_id_string[] =
"ComponentId";
3568 char component_id[256];
3569 char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3570 BYTE net_cfg_instance_id[256];
3573 len =
sizeof(enum_name);
3574 status = RegEnumKeyEx(adapter_key, i, enum_name, &len, NULL, NULL, NULL, NULL);
3575 if (
status == ERROR_NO_MORE_ITEMS)
3579 else if (
status != ERROR_SUCCESS)
3581 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s", ADAPTER_KEY);
3584 if (!
checked_snprintf(unit_string,
sizeof(unit_string),
"%s\\%s", ADAPTER_KEY, enum_name))
3586 msg(
M_WARN,
"Error constructing unit string for %s", enum_name);
3590 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, unit_string, 0, KEY_READ, &unit_key);
3592 if (
status != ERROR_SUCCESS)
3598 len =
sizeof(component_id);
3599 status = RegQueryValueEx(unit_key, component_id_string, NULL, &data_type,
3600 (LPBYTE)component_id, &len);
3602 if (
status != ERROR_SUCCESS || data_type != REG_SZ)
3604 dmsg(
D_REGISTRY,
"Error opening registry key: %s\\%s", unit_string,
3605 component_id_string);
3609 len =
sizeof(net_cfg_instance_id);
3610 status = RegQueryValueEx(unit_key, net_cfg_instance_id_string, NULL, &data_type,
3611 net_cfg_instance_id, &len);
3613 if (
status == ERROR_SUCCESS && data_type == REG_SZ)
3622 else if (strcasecmp(component_id,
"ovpn-dco") == 0)
3650 RegCloseKey(unit_key);
3655 RegCloseKey(adapter_key);
3663 HKEY network_connections_key;
3669 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ,
3670 &network_connections_key);
3672 if (
status != ERROR_SUCCESS)
3674 msg(
M_FATAL,
"Error opening registry key: %s", NETWORK_CONNECTIONS_KEY);
3679 char enum_name[256];
3680 char connection_string[256];
3681 HKEY connection_key;
3682 WCHAR name_data[256];
3684 const WCHAR name_string[] = L
"Name";
3686 len =
sizeof(enum_name);
3687 status = RegEnumKeyEx(network_connections_key, i, enum_name, &len, NULL, NULL, NULL, NULL);
3688 if (
status == ERROR_NO_MORE_ITEMS)
3692 else if (
status != ERROR_SUCCESS)
3694 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s", NETWORK_CONNECTIONS_KEY);
3698 "%s\\%s\\Connection",
3699 NETWORK_CONNECTIONS_KEY, enum_name))
3701 msg(
M_WARN,
"Error constructing connection string for %s", enum_name);
3706 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, connection_string, 0, KEY_READ, &connection_key);
3708 if (
status != ERROR_SUCCESS)
3710 dmsg(
D_REGISTRY,
"Error opening registry key: %s", connection_string);
3714 len =
sizeof(name_data);
3715 status = RegQueryValueExW(connection_key, name_string, NULL, &name_type,
3716 (LPBYTE)name_data, &len);
3718 if (
status != ERROR_SUCCESS || name_type != REG_SZ)
3720 dmsg(
D_REGISTRY,
"Error opening registry key: %s\\%s\\%ls", NETWORK_CONNECTIONS_KEY,
3721 connection_string, name_string);
3730 n = WideCharToMultiByte(CP_UTF8, 0, name_data, -1, NULL, 0, NULL, NULL);
3732 WideCharToMultiByte(CP_UTF8, 0, name_data, -1,
name, n, NULL, NULL);
3747 RegCloseKey(connection_key);
3752 RegCloseKey(network_connections_key);
3764 const unsigned int mask = 3;
3765 const char *err = NULL;
3767 if (local == remote)
3769 err =
"must be different";
3772 if ((local & (~mask)) != (remote & (~mask)))
3775 "must exist within the same 255.255.255.252 subnet. This is a limitation of --dev tun when used with the TAP-WIN32 driver";
3778 if ((local & mask) == 0 || (local & mask) == 3 || (remote & mask) == 0 || (remote & mask) == 3)
3781 "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";
3790 "There is a problem in your selection of --ifconfig endpoints [local=%s, remote=%s]. The local and remote VPN endpoints %s. Try '" PACKAGE
3791 " --show-valid-subnets' option for more info.",
3802 printf(
"On Windows, point-to-point IP support (i.e. --dev tun)\n");
3803 printf(
"is emulated by the TAP-Windows driver. The major limitation\n");
3804 printf(
"imposed by this approach is that the --ifconfig local and\n");
3805 printf(
"remote endpoints must be part of the same 255.255.255.252\n");
3806 printf(
"subnet. The following list shows examples of endpoint\n");
3807 printf(
"pairs which satisfy this requirement. Only the final\n");
3808 printf(
"component of the IP address pairs is at issue.\n\n");
3809 printf(
"As an example, the following option would be correct:\n");
3810 printf(
" --ifconfig 10.7.0.5 10.7.0.6 (on host A)\n");
3811 printf(
" --ifconfig 10.7.0.6 10.7.0.5 (on host B)\n");
3812 printf(
"because [5,6] is part of the below list.\n\n");
3814 for (i = 0; i < 256; i += 4)
3816 printf(
"[%3d,%3d] ", i + 1, i + 2);
3834 bool warn_panel_null =
false;
3835 bool warn_panel_dup =
false;
3836 bool warn_tap_dup =
false;
3847 msg(msglevel,
"Available adapters [name, GUID, driver]:");
3867 warn_panel_dup =
true;
3869 else if (links == 0)
3873 warn_panel_null =
true;
3874 msg(msglevel,
"[NULL] %s", tr->
guid);
3883 if (tr != tr1 && !strcmp(tr->
guid, tr1->
guid))
3885 warn_tap_dup =
true;
3893 msg(warnlevel,
"WARNING: Some TAP-Windows adapters have duplicate GUIDs");
3899 "WARNING: Some TAP-Windows adapters have duplicate links from the Network Connections control panel");
3902 if (warn_panel_null)
3905 "WARNING: Some TAP-Windows adapters have no link from the Network Connections control panel");
3968 msg(
M_FATAL,
"There are no TAP-Windows or ovpn-dco adapters "
3969 "on this system. You should be able to create an adapter "
3970 "by using tapctl.exe utility.");
3980 const struct tap_reg *tap_reg_src,
4030 if (windows_driver !=
NULL)
4059 ASSERT(actual_name_size > 0);
4105const IP_ADAPTER_INFO *
4109 IP_ADAPTER_INFO *pi = NULL;
4112 if ((
status = GetAdaptersInfo(NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4114 msg(
M_INFO,
"GetAdaptersInfo #1 failed (status=%u) : %s", (
unsigned int)
status,
4119 pi = (PIP_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4120 if ((
status = GetAdaptersInfo(pi, &size)) != NO_ERROR)
4122 msg(
M_INFO,
"GetAdaptersInfo #2 failed (status=%u) : %s", (
unsigned int)
status,
4130const IP_PER_ADAPTER_INFO *
4134 IP_PER_ADAPTER_INFO *pi = NULL;
4139 if ((
status = GetPerAdapterInfo(index, NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4141 msg(
M_INFO,
"GetPerAdapterInfo #1 failed (status=%u) : %s", (
unsigned int)
status,
4146 pi = (PIP_PER_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4147 if ((
status = GetPerAdapterInfo((ULONG)index, pi, &size)) == ERROR_SUCCESS)
4153 msg(
M_INFO,
"GetPerAdapterInfo #2 failed (status=%u) : %s", (
unsigned int)
status,
4161static const IP_INTERFACE_INFO *
4165 IP_INTERFACE_INFO *ii = NULL;
4168 if ((
status = GetInterfaceInfo(NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)
4170 msg(
M_INFO,
"GetInterfaceInfo #1 failed (status=%u) : %s", (
unsigned int)
status,
4175 ii = (PIP_INTERFACE_INFO)
gc_malloc(size,
false,
gc);
4176 if ((
status = GetInterfaceInfo(ii, &size)) == NO_ERROR)
4182 msg(
M_INFO,
"GetInterfaceInfo #2 failed (status=%u) : %s", (
unsigned int)
status,
4189static const IP_ADAPTER_INDEX_MAP *
4196 for (i = 0; i < list->NumAdapters; ++i)
4198 const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[i];
4199 if (index == inter->Index)
4213const IP_ADAPTER_INFO *
4218 const IP_ADAPTER_INFO *a;
4221 for (a = ai; a != NULL; a = a->Next)
4223 if (a->Index == index)
4232const IP_ADAPTER_INFO *
4244 const IP_ADDR_STRING *ip = &ai->IpAddressList;
4268 const IP_ADDR_STRING *iplist = &ai->IpAddressList;
4278 iplist = iplist->Next;
4284 const char *ip_str = iplist->IpAddress.String;
4285 const char *netmask_str = iplist->IpMask.String;
4286 bool succeed1 =
false;
4287 bool succeed2 =
false;
4289 if (ip_str && netmask_str && strlen(ip_str) && strlen(netmask_str))
4291 *ip =
getaddr(getaddr_flags, ip_str, 0, &succeed1, NULL);
4292 *netmask =
getaddr(getaddr_flags, netmask_str, 0, &succeed2, NULL);
4293 ret = (succeed1 ==
true && succeed2 ==
true);
4309 return (
status && ip_adapter == ip && netmask_adapter == netmask);
4317const IP_ADAPTER_INFO *
4343 for (i = 0; i < n; ++i)
4380 if (highest_netmask)
4382 *highest_netmask = 0;
4388 for (i = 0; i < n; ++i)
4393 if (adapter_ip && adapter_netmask
4394 && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))
4396 if (highest_netmask && adapter_netmask > *highest_netmask)
4398 *highest_netmask = adapter_netmask;
4414 int lowest_metric = INT_MAX;
4429 if (first || hn > highest_netmask)
4431 highest_netmask = hn;
4434 lowest_metric = metric;
4443 else if (hn == highest_netmask)
4449 if (metric >= 0 && metric < lowest_metric)
4452 lowest_metric = metric;
4459 dmsg(
D_ROUTE_DEBUG,
"DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d metric=%d",
4461 count ? *count : -1, lowest_metric);
4470 *netmask = highest_netmask;
4482#define DHCP_STATUS_UNDEF 0
4483#define DHCP_STATUS_ENABLED 1
4484#define DHCP_STATUS_DISABLED 2
4497 if (ai->DhcpEnabled)
4523 const IP_ADDR_STRING *ip = &a->IpAddressList;
4527 const DWORD
context = ip->Context;
4531 msg(
M_INFO,
"Successfully deleted previously set dynamic IP/netmask: %s/%s",
4532 ip->IpAddress.String, ip->IpMask.String);
4536 const char *empty =
"0.0.0.0";
4537 if (strcmp(ip->IpAddress.String, empty) || strcmp(ip->IpMask.String, empty))
4540 "NOTE: could not delete previously set dynamic IP/netmask: %s/%s (status=%u)",
4541 ip->IpAddress.String, ip->IpMask.String, (
unsigned int)
status);
4559 swprintf(wbuf,
SIZE(wbuf), L
"\\DEVICE\\TCPIP_%hs", guid);
4560 if (GetAdapterIndex(wbuf, &aindex) != NO_ERROR)
4566 index = (DWORD)aindex;
4581 if (!strcmp(guid,
list->AdapterName))
4583 index =
list->Index;
4604 msg(
M_INFO,
"NOTE: could not get adapter index for %s", guid);
4618 buf_printf(&out,
"%s", ip->IpAddress.String);
4619 if (
strlen(ip->IpMask.String))
4636 msg(msglevel,
"%s",
a->Description);
4637 msg(msglevel,
" Index = %d", (
int)
a->Index);
4638 msg(msglevel,
" GUID = %s",
a->AdapterName);
4645 msg(msglevel,
" DHCP LEASE OBTAINED = %s",
time_string(
a->LeaseObtained, 0,
false,
gc));
4646 msg(msglevel,
" DHCP LEASE EXPIRES = %s",
time_string(
a->LeaseExpires, 0,
false,
gc));
4672 msg(msglevel,
"SYSTEM ADAPTER LIST");
4675 const IP_ADAPTER_INFO *a;
4678 for (a = ai; a != NULL; a = a->Next)
4701 msg(
M_ERR,
"Error: init SA failed");
4704 status = SetKernelObjectSecurity(hand, DACL_SECURITY_INFORMATION, &
sa.sd);
4707 msg(
M_ERRNO,
"Error: SetKernelObjectSecurity failed on %s", device_path);
4711 msg(
M_INFO |
M_NOPREFIX,
"TAP-Windows device: %s [Non-admin access allowed]", device_path);
4721 const char *device_guid = NULL;
4723 uint8_t actual_buffer[256];
4724 char device_path[256];
4736 msg(
M_FATAL,
"TAP-Windows adapter '%s' not found", dev_node);
4740 snprintf(device_path,
sizeof(device_path),
"%s%s%s", USERMODEDEVICEDIR, device_guid,
4743 hand = CreateFile(device_path, MAXIMUM_ALLOWED, 0,
4744 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
4746 if (hand == INVALID_HANDLE_VALUE)
4748 msg(
M_ERR,
"CreateFile failed on TAP device: %s", device_path);
4756 int device_number = 0;
4770 snprintf(device_path,
sizeof(device_path),
"%s%s%s", USERMODEDEVICEDIR, device_guid,
4773 hand = CreateFile(device_path, MAXIMUM_ALLOWED, 0,
4774 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
4776 if (hand == INVALID_HANDLE_VALUE)
4778 msg(
M_WARN,
"CreateFile failed on TAP device: %s", device_path);
4804 DWORD
status = IpReleaseAddress((IP_ADAPTER_INDEX_MAP *)inter);
4813 "NOTE: Release of DHCP-assigned IP address lease on TAP-Windows adapter failed: %s (code=%u)",
4845 DWORD
status = IpRenewAddress((IP_ADAPTER_INDEX_MAP *)inter);
4854 "WARNING: Failed to renew DHCP IP address lease on TAP-Windows adapter: %s (code=%u)",
4880 for (i = 0; i < n; ++i)
4894 msg(msglevel,
"%s: command failed", prefix);
4907 const char err[] =
"ERROR: Windows ipconfig command failed";
4932 const char *ip_str = src->IpAddress.String;
4934 bool succeed =
false;
4940 if (!ip_str || !strlen(ip_str))
4945 ip =
getaddr(getaddr_flags, ip_str, 0, &succeed, NULL);
4959 msg(
M_INFO,
"ip_addr_string_to_array [%d]", *dest_len);
4960 for (i = 0; i < *dest_len; ++i)
4973 int a2len =
SIZE(a2);
4983 for (i = 0; i < a1len; ++i)
5001 for (i = 0; i < len; ++i)
5027 for (
int i = 0; i < addr_len; ++i)
5029 const char *fmt = (i == 0) ?
"%s%s interface ipv6 set dns %lu static %s"
5030 :
"%s%s interface ipv6 add dns %lu %s";
5047 const IP_ADDR_STRING *current, DWORD adapter_index,
const bool test_first)
5051 bool delete_first =
false;
5052 bool is_dns = !strcmp(type,
"dns");
5059 delete_first =
true;
5064 delete_first =
true;
5079 for (i = 0; i < addr_len; ++i)
5083 const char *fmt = count ?
"%s%s interface ip add %s %lu %s"
5084 :
"%s%s interface ip set %s %lu static %s";
5101 msg(
M_INFO,
"NETSH: %lu %s %s [already set]", adapter_index, type,
5119 dest[0].Next = NULL;
5124 dest[0].Next = &dest[1];
5125 dest[1].Next = NULL;
5131 const in_addr_t netmask,
const unsigned int flags)
5135 const IP_ADAPTER_INFO *ai = NULL;
5136 const IP_PER_ADAPTER_INFO *pai = NULL;
5149 msg(
M_INFO,
"NETSH: %lu %s/%s [already set]", adapter_index,
5166 IP_ADDR_STRING wins[2];
5172 if (ai && ai->HaveWins)
5218 msg(
M_NONFATAL,
"TUN: enabling dhcp using service failed: %s [status=%u if_index=%d]",
5223 msg(
M_INFO,
"DHCP enabled on interface %d using service",
dhcp.iface.index);
5237 MIB_IPINTERFACE_ROW ipiface;
5238 InitializeIpInterfaceEntry(&ipiface);
5239 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
5240 ipiface.Family = family;
5241 ipiface.InterfaceIndex = iface_index;
5242 if (family == AF_INET6 && mtu < 1280)
5245 "NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
5248 err = GetIpInterfaceEntry(&ipiface);
5249 if (err == NO_ERROR)
5251 if (family == AF_INET)
5253 ipiface.SitePrefixLength = 0;
5255 ipiface.NlMtu = mtu;
5256 err = SetIpInterfaceEntry(&ipiface);
5259 if (err != NO_ERROR)
5261 msg(
M_WARN,
"TUN: Setting %s mtu failed: %s [status=%lu if_index=%d]", family_name,
5266 msg(
M_INFO,
"%s MTU set to %d on interface %d using SetIpInterfaceEntry()", family_name,
5308 return BSTR(&actual);
5322 tt->standby_iter = 0;
5334 msg(
M_INFO,
"NOTE: now trying netsh (this may take some time)");
5349 if (
tt->options.dhcp_pre_release ||
tt->options.dhcp_renew)
5357 if (
tt->options.dhcp_pre_release)
5361 if (
tt->options.dhcp_renew)
5375 HANDLE msg_channel =
tt->options.msg_channel;
5389 msg(
M_WARN,
"Register_dns failed using service: %s [status=0x%x]",
5395 msg(
M_INFO,
"Register_dns request sent to the service");
5414 buf_printf(&
cmd,
"openvpn --verb %d --register-dns --rdns-internal", verb);
5428 dsa = (local | (~netmask)) + offset;
5432 dsa = (local & netmask) + offset;
5438 "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",
5442 if ((local & netmask) != (dsa & netmask))
5444 msg(
M_FATAL,
"ERROR: --ip-win32 dynamic [offset] : offset is outside of --ifconfig subnet");
5457 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_VERSION, &info,
sizeof(info), &info,
5458 sizeof(info), &len, NULL))
5460 msg(
D_TUNTAP_INFO,
"TAP-Windows Driver Version %d.%d %s", (
int)info[0], (
int)info[1],
5461 (info[2] ?
"(DEBUG)" :
""));
5467 " requires a TAP-Windows driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME
5468 " distribution, a reboot is probably required at this point to get Windows to see the new driver.",
5478 "WARNING: Tap-Win32 driver version %d.%d does not support IPv6 in TUN mode. IPv6 will not work. Upgrade your Tap-Win32 driver.",
5479 (
int)info[0], (
int)info[1]);
5487 "ERROR: Tap-Win32 driver version %d.%d is buggy regarding small IPv4 packets in TUN mode. Upgrade your Tap-Win32 driver.",
5488 (
int)info[0], (
int)info[1]);
5497 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_MTU, &mtu,
sizeof(mtu), &mtu,
sizeof(mtu), &len,
5521 .iface = { .index = index, .name =
"" } };
5530 status = FlushIpNetTable(index);
5535 msg(
M_INFO,
"Successful ARP Flush on interface [%lu] %s", index, device_guid);
5540 "NOTE: FlushIpNetTable failed on interface [%lu] %s (status=%lu) : %s", index,
5555 "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'");
5577 const char *error_suffix =
5578 "I am having trouble using the Windows 'IP helper API' to automatically set the IP address -- consider using other --ip-win32 methods (not 'ipapi')";
5583 msg(
M_FATAL,
"ERROR: unable to get adapter index for interface %s -- %s", device_guid,
5591 "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'");
5604 "Succeeded in adding a temporary IP/netmask of %s/%s to interface %s using the Win32 IP Helper API",
5611 "ERROR: AddIPAddress %s/%s failed on interface %s, index=%lu, status=%lu (windows error: '%s') -- %s",
5621#if defined(__GNUC__) || defined(__clang__)
5622#pragma GCC diagnostic pop
5631 sizeof(
status), &len, NULL))
5634 "WARNING: The TAP-Windows driver rejected a TAP_WIN_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
5640 msg(
M_INFO,
"Sleeping for %d seconds...", s);
5653 msg(
M_FATAL,
"ERROR: --dev tun also requires --ifconfig");
5664 ep[0] = htonl(tt->
local);
5668 status = DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_TUN, ep,
sizeof(ep), ep,
sizeof(ep),
5674 "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
5682 status ?
"SUCCEEDED" :
"FAILED");
5688 ep[0] = htonl(tt->
local);
5691 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT, ep,
sizeof(ep), ep,
5692 sizeof(ep), &len, NULL))
5695 "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun");
5710 ep[0] = htonl(tt->
local);
5740#ifndef SIMULATE_DHCP_FAILED
5741 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_DHCP_MASQ, ep,
sizeof(ep), ep,
sizeof(ep),
5745 "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode");
5749 "Notified TAP-Windows driver to set a DHCP IP/netmask of %s/%s on interface %s [DHCP-serv: %s, lease-time: %d]",
5764 "ERROR: The TAP-Windows driver rejected a TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call");
5769 msg(
M_WARN,
"DHCP option string not set due to error");
5816 snprintf(tuntap_device_path,
sizeof(tuntap_device_path),
"%s%s%s", USERMODEDEVICEDIR,
5817 device_guid, TAP_WIN_SUFFIX);
5818 path = tuntap_device_path;
5823 tt->
hand = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
5824 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
5825 if (tt->
hand == INVALID_HANDLE_VALUE)
5844 uint8_t actual_buffer[256];
5854 *device_guid =
get_device_guid(dev_node, actual_buffer,
sizeof(actual_buffer),
5859 msg(
M_FATAL,
"Adapter '%s' not found", dev_node);
5865 "Adapter '%s' is using %s driver, %s expected.",
5872 msg(
M_FATAL,
"Failed to open %s adapter: %s",
5878 int device_number = 0;
5879 int adapters_created = 0;
5892 if ((++adapters_created > 10)
5895 msg(
M_FATAL,
"All %s adapters on this system are currently in use or disabled.",
5954 *dhcp_masq_post =
true;
5976 bool dhcp_masq =
false;
5977 bool dhcp_masq_post =
false;
6018open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
6025 "Some --dhcp-option or --dns options require DHCP server,"
6026 " which is not supported by the selected %s driver. They will be"
6037 const char *device_guid = NULL;
6145 if (!CancelIo(tt->
hand))
6147 msg(
M_WARN |
M_ERRNO,
"Warning: CancelIO failed on %s adapter", adaptertype);
6151 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped read event on %s adapter", adaptertype);
6154 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped write event on %s adapter", adaptertype);
6160 if (!CloseHandle(tt->
hand))
6162 msg(
M_WARN |
M_ERRNO,
"Warning: CloseHandle failed on %s adapter", adaptertype);
6238 "Warning: DeleteIPAddress[%u] failed on TAP-Windows adapter, status=%u : %s",
6265 {
"manual" }, {
"netsh" }, {
"ipapi" }, {
"dynamic" }, {
"adaptive" }
6289 return "[unknown --ip-win32 type]";
6318open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *
tt,
void argv_msg(const msglvl_t msglevel, const struct argv *a)
Write the arguments stored in a struct argv via the msg() command.
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
void argv_msg_prefix(const msglvl_t msglevel, const struct argv *a, const char *prefix)
Similar to argv_msg() but prefixes the messages being written with a given string.
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
bool argv_printf_cat(struct argv *argres, const char *format,...)
printf() inspired argv concatenation.
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
void free_buf(struct buffer *buf)
bool buf_printf(struct buffer *buf, const char *format,...)
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
char * format_hex_ex(const uint8_t *data, size_t size, size_t maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
struct buffer alloc_buf(size_t size)
bool checked_snprintf(char *str, size_t size, const char *format,...)
Like snprintf() but returns an boolean.
char * string_alloc(const char *str, struct gc_arena *gc)
static bool has_digit(const char *src)
#define ALLOC_OBJ(dptr, type)
static struct buffer clear_buf(void)
Return an empty struct buffer.
static bool buf_copy(struct buffer *dest, const struct buffer *src)
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
static char * format_hex(const uint8_t *data, size_t size, size_t maxoutput, struct gc_arena *gc)
static void strncpynt(char *dest, const char *src, size_t maxlen)
static void check_malloc_return(void *p)
static void gc_free(struct gc_arena *a)
static struct gc_arena gc_new(void)
#define TAP_WIN_MIN_MINOR
#define TAP_WIN_COMPONENT_ID
#define TAP_WIN_MIN_MAJOR
static int open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev)
static void close_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx)
bool build_dhcp_options_string(struct buffer *buf, const struct tuntap_options *o)
void env_set_destroy(struct env_set *es)
void setenv_int(struct env_set *es, const char *name, int value)
void setenv_str(struct env_set *es, const char *name, const char *value)
void env_set_add(struct env_set *es, const char *str)
struct env_set * env_set_create(struct gc_arena *gc)
void set_nonblock(socket_descriptor_t fd)
void set_cloexec(socket_descriptor_t fd)
static SERVICE_STATUS status
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)
void management_sleep(const int n)
A sleep function that services the management layer for n seconds rather than doing nothing.
#define OPENVPN_STATE_ASSIGN_IP
static void net_ctx_reset(openvpn_net_ctx_t *ctx)
static void net_ctx_free(openvpn_net_ctx_t *ctx)
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
const char * print_topology(const int topology)
const char * time_string(time_t t, tv_usec_t usec, bool show_usec, struct gc_arena *gc)
int netmask_to_netbits2(in_addr_t netmask)
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)
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)
void get_default_gateway(struct route_gateway_info *rgi, in_addr_t dest, openvpn_net_ctx_t *ctx)
Retrieves the best gateway for a given destination based on the routing table.
void delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt, const struct env_set *es, openvpn_net_ctx_t *ctx)
void route_ipv6_clear_host_bits(struct route_ipv6 *r6)
#define RT_METRIC_DEFINED
#define RGI_NETMASK_DEFINED
int openvpn_execve_check(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message)
int sockethandle_finalize(sockethandle_t sh, struct overlapped_io *io, struct buffer *buf, struct link_socket_actual *from)
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.
const char * print_in6_addr(struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
#define GETADDR_HOST_ORDER
#define GETADDR_FATAL_ON_SIGNAL
Wrapper structure for dynamically allocated memory.
int len
Length in bytes of the actual content within the allocated memory.
int offset
Offset in bytes of the actual content within the allocated memory.
Contains all state information for one tunnel.
const char * device_interface
struct device_instance_id_interface * next
LPBYTE net_cfg_instance_id
Packet geometry parameters.
Garbage collection arena used to keep track of dynamically allocated memory.
struct gc_entry * list
First element of the linked list of gc_entry structures.
struct man_connection connection
struct route_gateway_address gateway
enum tun_driver_type windows_driver
struct in6_addr dns6[N_DHCP_ADDR]
in_addr_t wins[N_DHCP_ADDR]
in_addr_t dns[N_DHCP_ADDR]
bool dhcp_masq_custom_offset
const char * domain_search_list[N_SEARCH_LIST_LEN]
struct rw_handle rw_handle
enum tun_driver_type backend_driver
The backend driver that used for this tun/tap device.
bool did_ifconfig_ipv6_setup
if the internal variables related to ifconfig-ipv6 of this struct have been set up.
struct tuntap_options options
struct in6_addr remote_ipv6
bool did_ifconfig_setup
if the internal variables related to ifconfig of this struct have been set up.
struct overlapped_io writes
in_addr_t adapter_netmask
struct overlapped_io reads
struct in6_addr local_ipv6
bool ipapi_context_defined
static const char * get_unspecified_device_guid(const int device_number, uint8_t *actual_name, int actual_name_size, const struct tap_reg *tap_reg_src, const struct panel_reg *panel_reg_src, enum tun_driver_type *windows_driver, struct gc_arena *gc)
void ipconfig_register_dns(const struct env_set *es)
void tun_show_debug(struct tuntap *tt)
static const struct tap_reg * get_tap_reg(struct gc_arena *gc)
static DWORD get_adapter_index_method_1(const char *guid)
static void tuntap_post_open(struct tuntap *tt, const char *device_guid)
static bool do_address_service(const bool add, const short family, const struct tuntap *tt)
static void clear_tuntap(struct tuntap *tuntap)
static const char * netsh_get_id(const char *dev_node, struct gc_arena *gc)
void open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt, openvpn_net_ctx_t *ctx)
int dev_type_enum(const char *dev, const char *dev_type)
static const struct panel_reg * get_panel_reg(struct gc_arena *gc)
void close_tun_handle(struct tuntap *tt)
void fork_register_dns_action(struct tuntap *tt)
static bool test_adapter_ip_netmask(const IP_ADAPTER_INFO *ai, const in_addr_t ip, const in_addr_t netmask)
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
static void netsh_enable_dhcp(DWORD adapter_index)
static const GUID GUID_DEVINTERFACE_NET
static bool do_create_adapter_service(HANDLE msg_channel, enum tun_driver_type driver_type)
Requests the interactive service to create a VPN adapter of the specified type.
void show_tap_win_adapters(msglvl_t msglevel, msglvl_t warnlevel)
bool dhcp_renew_by_adapter_index(const DWORD adapter_index)
static void tuntap_get_version_info(const struct tuntap *tt)
static bool service_enable_dhcp(const struct tuntap *tt)
static void netsh_delete_address_dns(const struct tuntap *tt, bool ipv6, struct gc_arena *gc)
static void exec_command(const char *prefix, const struct argv *a, int n, msglvl_t msglevel)
int ascii2ipset(const char *name)
const IP_ADAPTER_INFO * get_tun_adapter(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
static void check_addr_clash(const char *name, int type, in_addr_t public, in_addr_t local, in_addr_t remote_netmask)
bool is_adapter_up(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
static void tuntap_set_ptp(const struct tuntap *tt)
static void undo_ifconfig_ipv4(struct tuntap *tt, openvpn_net_ctx_t *ctx)
static bool tun_try_open_device(struct tuntap *tt, const char *device_guid, const struct device_instance_id_interface *device_instance_id_interface)
static DWORD get_adapter_index(const char *guid)
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)
const IP_ADAPTER_INFO * get_adapter_info(DWORD index, struct gc_arena *gc)
static bool dhcp_release(const struct tuntap *tt)
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)
static void fork_dhcp_action(struct tuntap *tt)
static void show_adapter(msglvl_t msglevel, const IP_ADAPTER_INFO *a, struct gc_arena *gc)
const char * tun_stat(const struct tuntap *tt, unsigned int rwflags, struct gc_arena *gc)
static bool get_adapter_ip_netmask(const IP_ADAPTER_INFO *ai, const int n, in_addr_t *ip, in_addr_t *netmask)
const IP_PER_ADAPTER_INFO * get_per_adapter_info(const DWORD index, struct gc_arena *gc)
static void ifconfig_sanity_check(bool tun_p2p, in_addr_t addr)
int tun_write_win32(struct tuntap *tt, struct buffer *buf)
#define DHCP_STATUS_DISABLED
static const char * get_device_guid(const char *name, uint8_t *actual_name, int actual_name_size, enum tun_driver_type *windows_driver, const struct tap_reg *tap_reg, const struct panel_reg *panel_reg, struct gc_arena *gc)
bool is_ip_in_adapter_subnet(const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask)
static void delete_temp_addresses(DWORD index)
static void tuntap_set_ip_addr(struct tuntap *tt, const char *device_guid, bool dhcp_masq_post)
const char * tap_win_getinfo(const struct tuntap *tt, struct gc_arena *gc)
static const struct tap_reg * get_adapter_by_name(const char *name, const struct tap_reg *tap_reg, const struct panel_reg *panel_reg)
static const IP_ADAPTER_INDEX_MAP * get_interface_info(DWORD index, struct gc_arena *gc)
static const IP_INTERFACE_INFO * get_interface_info_list(struct gc_arena *gc)
bool is_dev_type(const char *dev, const char *dev_type, const char *match_type)
static uint32_t dhcp_masq_addr(const in_addr_t local, const in_addr_t netmask, const int offset)
#define DHCP_STATUS_UNDEF
#define DHCP_STATUS_ENABLED
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)
static void tuntap_set_ip_props(const struct tuntap *tt, bool *dhcp_masq, bool *dhcp_masq_post)
static void register_dns_service(const struct tuntap *tt)
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
int tun_write_queue(struct tuntap *tt, struct buffer *buf)
bool dhcp_release_by_adapter_index(const DWORD adapter_index)
void delete_route_connected_v6_net(const struct tuntap *tt)
bool tun_standby(struct tuntap *tt)
static void tuntap_dhcp_mask(const struct tuntap *tt, const char *device_guid)
static void init_ip_addr_string2(IP_ADDR_STRING *dest, const IP_ADDR_STRING *src1, const IP_ADDR_STRING *src2)
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
const char * dev_type_string(const char *dev, const char *dev_type)
static const char ifconfig_warn_how_to_silence[]
static const struct device_instance_id_interface * get_device_instance_id_interface(struct gc_arena *gc)
void close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
static const char * guid_to_name(const char *guid, const struct panel_reg *panel_reg)
static DWORD get_adapter_index_method_2(const char *guid)
static int dhcp_status(DWORD index)
const IP_ADAPTER_INFO * get_adapter_info_list(struct gc_arena *gc)
void tap_allow_nonadmin_access(const char *dev_node)
bool tun_name_is_fixed(const char *dev)
static bool ip_addr_member_of(const in_addr_t addr, const IP_ADDR_STRING *ias)
static const char * format_ip_addr_string(const IP_ADDR_STRING *ip, struct gc_arena *gc)
const IP_ADAPTER_INFO * get_adapter(const IP_ADAPTER_INFO *ai, DWORD index)
static void at_least_one_tap_win(const struct tap_reg *tap_reg)
void show_adapters(msglvl_t msglevel)
static void add_route_connected_v6_net(struct tuntap *tt, const struct env_set *es)
void warn_on_use_of_common_subnets(openvpn_net_ctx_t *ctx)
static bool dhcp_renew(const struct tuntap *tt)
static void undo_ifconfig_ipv6(struct tuntap *tt, openvpn_net_ctx_t *ctx)
int tun_read_queue(struct tuntap *tt, int maxsize)
static void do_dns_domain_pwsh(bool add, const struct tuntap *tt)
void init_tun_post(struct tuntap *tt, const struct frame *frame, const struct tuntap_options *options)
static void tuntap_set_connected(const struct tuntap *tt)
static const struct tap_reg * get_adapter_by_guid(const char *guid, const struct tap_reg *tap_reg)
static void do_dns_domain_service(bool add, const struct tuntap *tt)
static void tuntap_get_mtu(struct tuntap *tt)
const char * ifconfig_options_string(const struct tuntap *tt, bool remote, bool disable, struct gc_arena *gc)
const char * guess_tuntap_dev(const char *dev, const char *dev_type, const char *dev_node, struct gc_arena *gc)
const char * ipset2ascii(int index)
void do_ifconfig_setenv(const struct tuntap *tt, struct env_set *es)
static bool do_set_mtu_service(const struct tuntap *tt, const short family, const int mtu)
void undo_ifconfig(struct tuntap *tt, openvpn_net_ctx_t *ctx)
undo_ifconfig - undo configuration of the tunnel interface
bool is_tun_p2p(const struct tuntap *tt)
static void windows_set_mtu(const int iface_index, const short family, const int mtu)
const char * ipset2ascii_all(struct gc_arena *gc)
static int get_adapter_n_ip_netmask(const IP_ADAPTER_INFO *ai)
void tun_standby_init(struct tuntap *tt)
void show_valid_win32_tun_subnets(void)
static void tap_allow_nonadmin_access_handle(const char *device_path, HANDLE hand)
void ip_addr_string_to_array(in_addr_t *dest, int *dest_len, const IP_ADDR_STRING *src)
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.
static const GUID GUID_DEVCLASS_NET
const char * print_tun_backend_driver(enum tun_driver_type driver)
Return a string representation of the tun backed driver type.
static void do_wins_service(bool add, const struct tuntap *tt)
static void netsh_command(const struct argv *a, int n, msglvl_t msglevel)
DWORD adapter_index_of_ip(const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count, in_addr_t *netmask)
static void do_dns_service(bool add, const short family, const struct tuntap *tt)
void tun_open_device(struct tuntap *tt, const char *dev_node, const char **device_guid, struct gc_arena *gc)
void verify_255_255_255_252(in_addr_t local, in_addr_t remote)
static bool ip_addr_one_to_one(const in_addr_t *a1, const int a1len, const IP_ADDR_STRING *ias)
ssize_t write_tun(struct tuntap *tt, uint8_t *buf, int len)
#define IPW32_SET_ADAPTIVE
#define DHCP_OPTIONS_DHCP_REQUIRED
#define N_SEARCH_LIST_LEN
#define TUN_ADAPTER_INDEX_INVALID
ssize_t read_tun(struct tuntap *tt, uint8_t *buf, int len)
#define IPW32_SET_DHCP_MASQ
static bool tuntap_is_dco_win(struct tuntap *tt)
#define DCO_WIN_REFERENCE_STRING
#define IPW32_SET_ADAPTIVE_TRY_NETSH
@ WINDOWS_DRIVER_UNSPECIFIED
@ DRIVER_UTUN
macOS internal tun driver
@ DRIVER_AFUNIX
using an AF_UNIX socket to pass packets from/to an external program.
@ WINDOWS_DRIVER_TAP_WINDOWS6
int get_interface_metric(const NET_IFINDEX index, const ADDRESS_FAMILY family, int *is_auto)
Return interface metric value for the specified interface index.
void overlapped_io_init(struct overlapped_io *o, const struct frame *frame, BOOL event_state)
void fork_to_self(const char *cmdline)
char * overlapped_io_state_ascii(const struct overlapped_io *o)
void overlapped_io_close(struct overlapped_io *o)
void netcmd_semaphore_release(void)
char * get_win_sys_path(void)
void netcmd_semaphore_lock(void)
bool send_msg_iservice(HANDLE pipe, const void *data, DWORD size, ack_message_t *ack, const char *context)
Send the size bytes in buffer data to the interactive service pipe and read the result in ack.
bool init_security_attributes_allow_all(struct security_attributes *obj)
#define IOSTATE_IMMEDIATE_RETURN
#define POWERSHELL_PATH_SUFFIX
#define WIN_IPCONFIG_PATH_SUFFIX
static bool overlapped_io_active(struct overlapped_io *o)
#define NETSH_PATH_SUFFIX