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);
133 if (addr.
family == AF_INET)
137 msg(
D_IFCONFIG,
"INET address service: %s %s/%d", add ?
"add" :
"remove",
144 msg(
D_IFCONFIG,
"INET6 address service: %s %s/%d", add ?
"add" :
"remove",
155 msg(
M_WARN,
"TUN: %s address failed using service: %s [status=%d if_index=%lu]",
202 size_t dstlen = strlen(
dns.domains);
204 size_t extra = dstlen ? 2 : 1;
205 if (dstlen + srclen + extra >
sizeof(
dns.domains))
207 msg(
M_WARN,
"DNS search domains sent to service truncated to %d", i);
212 dns.domains[dstlen++] =
',';
217 msg(
D_LOW,
"%s DNS domains on '%s' (if_index = %lu) using service",
218 (add ?
"Setting" :
"Deleting"),
dns.iface.name,
dns.iface.index);
226 msg(
M_WARN,
"TUN: %s DNS domains failed using service: %s [status=%d if_name=%s]",
232 msg(
M_INFO,
"DNS domains %s using service", (add ?
"set" :
"deleted"));
245 unsigned int addr_len = add ? len : 0;
246 const char *ip_proto_name = family == AF_INET6 ?
"IPv6" :
"IPv4";
260 .addr_len = addr_len };
265 if (addr_len > _countof(dns.
addr))
267 addr_len = _countof(dns.
addr);
269 msg(
M_WARN,
"Number of %s DNS addresses sent to service truncated to %u",
270 ip_proto_name, addr_len);
273 for (
unsigned int i = 0; i < addr_len; ++i)
275 if (family == AF_INET6)
285 msg(
D_LOW,
"%s %s dns servers on '%s' (if_index = %lu) using service",
295 msg(
M_WARN,
"TUN: %s %s dns failed using service: %s [status=%d if_name=%s]",
301 msg(
M_INFO,
"%s dns servers %s using service", ip_proto_name, (add ?
"set" :
"deleted"));
324 .addr_len = addr_len };
329 if (addr_len > _countof(wins.
addr))
331 addr_len = _countof(wins.
addr);
333 msg(
M_WARN,
"Number of WINS addresses sent to service truncated to %u", addr_len);
336 for (
unsigned int i = 0; i < addr_len; ++i)
341 msg(
D_LOW,
"%s WINS servers on '%s' (if_index = %lu) using service",
351 msg(
M_WARN,
"TUN: %s WINS failed using service: %s [status=%d if_name=%s]",
357 msg(
M_INFO,
"WINS servers %s using service", (add ?
"set" :
"deleted"));
370 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
376 if (family == AF_INET6 && mtu < 1280)
379 "NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
389 msg(
M_NONFATAL,
"TUN: setting %s mtu using service failed: %s [status=%d if_index=%lu]",
395 msg(
M_INFO,
"%s MTU set to %d on interface %lu using service", family_name, mtu,
415 "%s%s -NoProfile -NonInteractive -Command Set-DnsClient -InterfaceIndex %lu -ConnectionSpecificSuffix '%s'",
467 msg(
M_NONFATAL,
"TUN: creating %s adapter using service failed: %s [status=%d]",
485static void solaris_error_close(
struct tuntap *tt,
const struct env_set *es,
const char *actual,
491#if defined(TARGET_DARWIN)
492#include <sys/kern_control.h>
493#include <net/if_utun.h>
494#include <sys/sys_domain.h>
500is_dev_type(
const char *dev,
const char *dev_type,
const char *match_type)
509 return !strcmp(dev_type, match_type);
513 return !strncmp(dev, match_type, strlen(match_type));
548 return "[unknown-dev-type]";
586 const bool looks_like_netmask = ((addr & 0xFF000000) == 0xFF000000);
589 if (looks_like_netmask)
592 "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",
598 if (!looks_like_netmask)
601 "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",
618 msg(
M_INFO,
"CHECK_ADDR_CLASH type=%d public=%s local=%s, remote_netmask=%s",
629 const in_addr_t test_netmask = 0xFFFFFF00;
630 const in_addr_t public_net =
public & test_netmask;
631 const in_addr_t local_net = local & test_netmask;
632 const in_addr_t remote_net = remote_netmask & test_netmask;
634 if (
public == local ||
public == remote_netmask)
637 "WARNING: --%s address [%s] conflicts with --ifconfig address pair [%s, %s]. %s",
642 if (public_net == local_net || public_net == remote_net)
645 "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",
652 const in_addr_t public_network =
public & remote_netmask;
653 const in_addr_t virtual_network = local & remote_netmask;
654 if (public_network == virtual_network)
657 "WARNING: --%s address [%s] conflicts with --ifconfig subnet [%s, %s] -- local and remote addresses cannot be inside of the --ifconfig subnet. %s",
674 if ((rgi.
flags & needed) == needed)
677 if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100)
680 "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.");
694 if (
tt->did_ifconfig_setup && !disable)
773 msg(
M_FATAL,
"Error: problem with tun vs. tap setting");
796 setenv_str(es,
"ifconfig_local", ifconfig_local);
799 setenv_str(es,
"ifconfig_remote", ifconfig_remote_netmask);
803 setenv_str(es,
"ifconfig_netmask", ifconfig_remote_netmask);
812 setenv_str(es,
"ifconfig_ipv6_local", ifconfig_ipv6_local);
814 setenv_str(es,
"ifconfig_ipv6_remote", ifconfig_ipv6_remote);
828 const char *dev_type,
830 const char *ifconfig_local_parm,
831 const char *ifconfig_remote_netmask_parm,
832 const char *ifconfig_ipv6_local_parm,
833 int ifconfig_ipv6_netbits_parm,
834 const char *ifconfig_ipv6_remote_parm,
835 const struct addrinfo *local_public,
const struct addrinfo *remote_public,
const bool strict_warn,
847 if (ifconfig_local_parm && ifconfig_remote_netmask_parm)
860 ifconfig_local_parm, 0, NULL, NULL);
864 ifconfig_remote_netmask_parm, 0, NULL, NULL);
871 const struct addrinfo *curele;
879 for (curele = local_public; curele; curele = curele->ai_next)
881 if (curele->ai_family == AF_INET)
884 ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
889 for (curele = remote_public; curele; curele = curele->ai_next)
891 if (curele->ai_family == AF_INET)
894 ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
919 if (ifconfig_ipv6_local_parm && ifconfig_ipv6_remote_parm)
925 if (inet_pton(AF_INET6, ifconfig_ipv6_local_parm, &tt->
local_ipv6) != 1
926 || inet_pton(AF_INET6, ifconfig_ipv6_remote_parm, &tt->
remote_ipv6) != 1)
928 msg(
M_FATAL,
"init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary",
929 ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm);
1008#if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || defined(TARGET_NETBSD) \
1009 || defined(TARGET_OPENBSD)
1020create_arbitrary_remote(
const struct tuntap *tt)
1026 if (remote == tt->
local)
1048#if !defined(TARGET_LINUX)
1054#if defined(TARGET_LINUX)
1055 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1057 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1060 if (net_iface_up(ctx, ifname,
true) < 0)
1062 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1067 msg(
M_FATAL,
"Linux can't add IPv6 to interface %s", ifname);
1069#elif defined(TARGET_ANDROID)
1072 snprintf(out6,
sizeof(out6),
"%s/%d %d", ifconfig_ipv6_local, tt->
netbits_ipv6, tun_mtu);
1073 management_android_control(
management,
"IFCONFIG6", out6);
1074#elif defined(TARGET_SOLARIS)
1084 ifconfig_ipv6_local, tt->
netbits_ipv6, ifconfig_ipv6_remote, tun_mtu);
1094 solaris_error_close(tt, es, ifname,
true);
1113 solaris_error_close(tt, es, ifname,
true);
1122#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) || defined(TARGET_DARWIN) \
1123 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1130#if defined(TARGET_FREEBSD) && __FreeBSD_version >= 1200000 && __FreeBSD_version < 1300000
1152#elif defined(TARGET_AIX)
1164#elif defined(_WIN32)
1168 "******** NOTE: Please manually set the v6 IP of '%s' to %s (if it is not already set)",
1169 ifname, ifconfig_ipv6_local);
1198 argv_printf(&
argv,
"%s%s interface ipv6 set address %lu %s/%d store=active",
1217 "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.");
1220#if !defined(TARGET_LINUX)
1239#if !defined(_WIN32) && !defined(TARGET_ANDROID)
1246#if !defined(TARGET_LINUX)
1247 const char *ifconfig_local = NULL;
1248 const char *ifconfig_remote_netmask = NULL;
1259#if defined(TARGET_LINUX)
1260 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1262 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1265 if (net_iface_up(ctx, ifname,
true) < 0)
1267 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1274 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1281 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1284#elif defined(TARGET_ANDROID)
1287 snprintf(out,
sizeof(out),
"%s %s %d %s", ifconfig_local, ifconfig_remote_netmask, tun_mtu,
1289 management_android_control(
management,
"IFCONFIG", out);
1291#elif defined(TARGET_SOLARIS)
1300 ifconfig_remote_netmask, tun_mtu);
1305 solaris_error_close(tt, es, ifname,
false);
1313 ifconfig_local, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1318 ifconfig_remote_netmask);
1324 solaris_error_close(tt, es, ifname,
false);
1340#elif defined(TARGET_OPENBSD)
1354 ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1358 remote_end = create_arbitrary_remote(tt);
1361 ifconfig_remote_netmask);
1366 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1383#elif defined(TARGET_NETBSD)
1389 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1393 remote_end = create_arbitrary_remote(tt);
1396 ifconfig_remote_netmask);
1406 ifconfig_remote_netmask, tun_mtu);
1423#elif defined(TARGET_DARWIN)
1431 msg(
M_INFO,
"NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
1438 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1443 ifconfig_local, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1448 ifconfig_remote_netmask, tun_mtu);
1466#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1472 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1484#elif defined(TARGET_AIX)
1492 msg(
M_FATAL,
"no tun support on AIX (canthappen)");
1497 ifconfig_remote_netmask, tun_mtu);
1504#elif defined(_WIN32)
1508 "******** NOTE: Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
1509 ifname, ifconfig_local, ifconfig_remote_netmask);
1543#elif defined(TARGET_HAIKU)
1546 ifconfig_remote_netmask, tun_mtu);
1552 "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.");
1555#if !defined(TARGET_LINUX)
1569#ifdef ENABLE_MANAGEMENT
1594#if defined(TARGET_LINUX)
1611#elif defined(TARGET_FREEBSD)
1629#if defined(TARGET_LINUX)
1634#elif defined(TARGET_FREEBSD)
1680#ifdef TARGET_SOLARIS
1685#if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) || defined(TARGET_DARWIN)
1703#include <netinet/ip.h>
1706static inline ssize_t
1707header_modify_read_write_return(ssize_t len)
1711 return (
size_t)len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
1720write_tun_header(
const struct tuntap *tt,
const uint8_t *buf,
int len)
1726 const struct ip *iph = (
const struct ip *)buf;
1730 type = htonl(AF_INET6);
1734 type = htonl(AF_INET);
1739 iv[0].iov_base = &type;
1740 iv[0].iov_len =
sizeof(type);
1741 iv[1].iov_base = (
void *)buf;
1742 iv[1].iov_len = len;
1744 return header_modify_read_write_return(writev(tt->fd, iv, 2));
1748 return write(tt->fd, buf, len);
1753read_tun_header(
const struct tuntap *tt, uint8_t *buf,
int len)
1760 iv[0].iov_base = &type;
1761 iv[0].iov_len =
sizeof(type);
1762 iv[1].iov_base = buf;
1763 iv[1].iov_len = len;
1765 return header_modify_read_write_return(readv(tt->fd, iv, 2));
1769 return read(tt->fd, buf, len);
1777#if !defined(TARGET_DARWIN)
1781 return write_tun_header(tt, buf, len);
1787 return read_tun_header(tt, buf, len);
1799#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1801tun_dco_enabled(
const struct tuntap *tt)
1808#if !(defined(_WIN32) || defined(TARGET_LINUX) || defined(TARGET_SOLARIS) || defined(TARGET_ANDROID))
1810open_tun_generic(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt)
1813 char dynamic_name[256];
1814 bool dynamic_opened =
false;
1821 snprintf(tunname,
sizeof(tunname),
"%s", dev_node);
1833 for (
int i = 0; i < 256; ++i)
1836 const char *sep =
"";
1837#if defined(TARGET_HAIKU)
1840 snprintf(tunname,
sizeof(tunname),
"/dev/%s%s%d", dev, sep, i);
1841 snprintf(dynamic_name,
sizeof(dynamic_name),
"%s%s%d", dev, sep, i);
1842 if ((tt->fd = open(tunname, O_RDWR)) > 0)
1844 dynamic_opened =
true;
1849 if (!dynamic_opened)
1851 msg(
M_FATAL,
"Cannot allocate TUN/TAP dev dynamically");
1859 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
1863 if (!dynamic_opened)
1866 if (if_nametoindex(dev) > 0)
1868 msg(
M_INFO,
"TUN/TAP device %s exists previously, keep at program end", dev);
1872 if ((tt->fd = open(tunname, O_RDWR)) < 0)
1874 msg(
M_ERR,
"Cannot open TUN/TAP dev %s", tunname);
1880 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
1887#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1889open_tun_dco_generic(
const char *dev,
const char *dev_type,
struct tuntap *tt,
1892 char dynamic_name[256];
1902 if (strcmp(dev,
"tun") == 0)
1904 bool dynamic_opened =
false;
1906 for (
int i = 0; i < 256; ++i)
1908 snprintf(dynamic_name,
sizeof(dynamic_name),
"%s%d", dev, i);
1912 dynamic_opened =
true;
1913 msg(
M_INFO,
"DCO device %s opened", dynamic_name);
1917 else if (ret == -EPERM)
1922 if (!dynamic_opened)
1924 msg(
M_FATAL,
"Cannot allocate DCO dev dynamically");
1938 msg(
M_INFO,
"DCO device %s already exists, won't be destroyed at shutdown", dev);
1943 msg(
M_ERR,
"Cannot open DCO device %s: %s (%d)", dev, strerror(-ret), ret);
1947 msg(
M_INFO,
"DCO device %s opened", dev);
1956#if !(defined(_WIN32) || defined(TARGET_SOLARIS))
1958close_tun_generic(
struct tuntap *tt)
1970#if defined(TARGET_ANDROID)
1972open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
1975#define ANDROID_TUNNAME "vpnservice-tun"
1979 int oldtunfd = tt->fd;
1985 management_android_control(
management,
"DNS6SERVER",
1991 management_android_control(
management,
"DNSSERVER",
2003 buf_printf(&buf,
"%s %d",
tt->options.http_proxy,
tt->options.http_proxy_port);
2033 msg(
M_ERR,
"ERROR: Cannot open TUN");
2060#elif defined(TARGET_LINUX)
2065open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *
tt,
2070 if (tun_dco_enabled(tt))
2072 open_tun_dco_generic(dev, dev_type, tt, ctx);
2079 const char *node = dev_node;
2082 node =
"/dev/net/tun";
2088 if ((tt->fd = open(node, O_RDWR)) < 0)
2090 msg(
M_ERR,
"ERROR: Cannot open TUN/TAP dev %s", node);
2097 ifr.ifr_flags = IFF_NO_PI;
2099#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2100 ifr.ifr_flags |= IFF_ONE_QUEUE;
2103#ifdef IFF_BACKPRESSURE
2104 ifr.ifr_flags |= IFF_BACKPRESSURE;
2112 ifr.ifr_flags |= IFF_TUN;
2116 ifr.ifr_flags |= IFF_TAP;
2120 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device", dev);
2126 if (strcmp(dev,
"tun") && strcmp(dev,
"tap"))
2128 strlcpy(ifr.ifr_name, dev, IFNAMSIZ);
2135 if (ioctl(tt->fd, TUNSETIFF, (
void *)&ifr) < 0)
2137 msg(
M_ERR,
"ERROR: Cannot ioctl TUNSETIFF %s", dev);
2140 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2145#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2148 struct ifreq netifr;
2151 if ((ctl_fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
2154 strlcpy(netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
2155 netifr.ifr_qlen = tt->
options.txqueuelen;
2156 if (ioctl(ctl_fd, SIOCSIFTXQLEN, (
void *)&netifr) >= 0)
2162 msg(
M_WARN |
M_ERRNO,
"Note: Cannot set tx queue length on %s", ifr.ifr_name);
2168 msg(
M_WARN |
M_ERRNO,
"Note: Cannot open control socket on %s", ifr.ifr_name);
2183open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2191#ifdef ENABLE_FEATURE_TUN_PERSIST
2194tuncfg(
const char *dev,
const char *dev_type,
const char *dev_node,
int persist_mode,
2205 open_tun(dev, dev_type, dev_node, tt, ctx);
2206 if (ioctl(tt->fd, TUNSETPERSIST, persist_mode) < 0)
2208 msg(
M_ERR,
"Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
2210 if (username != NULL)
2216 msg(
M_ERR,
"Cannot get user entry for %s", username);
2220 msg(
M_ERR,
"Cannot ioctl TUNSETOWNER(%s) %s", username, dev);
2223 if (groupname != NULL)
2229 msg(
M_ERR,
"Cannot get group entry for %s", groupname);
2233 msg(
M_ERR,
"Cannot ioctl TUNSETGROUP(%s) %s", groupname, dev);
2237 msg(
M_INFO,
"Persist state set to: %s", (persist_mode ?
"ON" :
"OFF"));
2247#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
2248 if (tun_dco_enabled(tt))
2253 close_tun_generic(tt);
2260 return write(tt->fd, buf, len);
2266 return read(tt->fd, buf, len);
2269#elif defined(TARGET_SOLARIS)
2272#error I need the symbol TUNNEWPPA from net/if_tun.h
2276open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2279 int if_fd = -1, ip_muxid = -1, arp_muxid = -1, arp_fd = -1, ppa = -1;
2282 const char *ip_node = NULL, *arp_node = NULL;
2283 const char *dev_tuntap_type;
2285 struct strioctl strioc_if, strioc_ppa;
2295 ip_node =
"/dev/udp";
2298 dev_node =
"/dev/tun";
2300 dev_tuntap_type =
"tun";
2301 link_type = I_PLINK;
2305 ip_node =
"/dev/udp";
2308 dev_node =
"/dev/tap";
2310 arp_node = dev_node;
2311 dev_tuntap_type =
"tap";
2312 link_type = I_PLINK;
2316 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device", dev);
2319 if ((tt->ip_fd = open(ip_node, O_RDWR, 0)) < 0)
2321 msg(
M_ERR,
"Can't open %s", ip_node);
2324 if ((tt->fd = open(dev_node, O_RDWR, 0)) < 0)
2326 msg(
M_ERR,
"Can't open %s", dev_node);
2334 while (*ptr && !isdigit((
int)*ptr))
2342 strioc_ppa.ic_cmd = TUNNEWPPA;
2343 strioc_ppa.ic_timout = 0;
2344 strioc_ppa.ic_len =
sizeof(ppa);
2345 strioc_ppa.ic_dp = (
char *)&ppa;
2349 bool found_one =
false;
2350 while (!found_one && ppa < 64)
2352 int new_ppa = ioctl(tt->fd, I_STR, &strioc_ppa);
2355 msg(
M_INFO,
"open_tun: got dynamic interface '%s%d'", dev_tuntap_type, new_ppa);
2360 if (errno != EEXIST)
2362 msg(
M_ERR,
"open_tun: unexpected error trying to find free %s interface",
2369 msg(
M_ERR,
"open_tun: could not find free %s interface, give up.", dev_tuntap_type);
2374 if ((ppa = ioctl(tt->fd, I_STR, &strioc_ppa)) < 0)
2376 msg(
M_ERR,
"Can't assign PPA for new interface (%s%d)", dev_tuntap_type, ppa);
2380 if ((if_fd = open(dev_node, O_RDWR, 0)) < 0)
2382 msg(
M_ERR,
"Can't open %s (2)", dev_node);
2385 if (ioctl(if_fd, I_PUSH,
"ip") < 0)
2387 msg(
M_ERR,
"Can't push IP module");
2393 if (ioctl(if_fd, IF_UNITSEL, (
char *)&ppa) < 0)
2395 msg(
M_ERR,
"Can't set PPA %d", ppa);
2402 snprintf(tt->
actual_name, 32,
"%s%d", dev_tuntap_type, ppa);
2406 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2413 if (ioctl(if_fd, SIOCSLIFNAME, &ifr) < 0)
2415 msg(
M_ERR,
"Can't set PPA %d", ppa);
2417 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2422 if (ioctl(if_fd, I_PUSH,
"arp") < 0)
2424 msg(
M_ERR,
"Can't push ARP module");
2430 if (ioctl(tt->ip_fd, I_POP, NULL) < 0)
2436 if (ioctl(tt->ip_fd, I_PUSH,
"arp") < 0)
2438 msg(
M_ERR,
"Can't push ARP module");
2442 if ((arp_fd = open(arp_node, O_RDWR, 0)) < 0)
2444 msg(
M_ERR,
"Can't open %s", arp_node);
2447 if (ioctl(arp_fd, I_PUSH,
"arp") < 0)
2449 msg(
M_ERR,
"Can't push ARP module");
2453 strioc_if.ic_cmd = SIOCSLIFNAME;
2454 strioc_if.ic_timout = 0;
2455 strioc_if.ic_len =
sizeof(ifr);
2456 strioc_if.ic_dp = (
char *)𝔦
2457 if (ioctl(arp_fd, I_STR, &strioc_if) < 0)
2459 msg(
M_ERR,
"Can't set ifname to arp");
2463 if ((ip_muxid = ioctl(tt->ip_fd, link_type, if_fd)) < 0)
2465 msg(
M_ERR,
"Can't link %s device to IP", dev_tuntap_type);
2470 if ((arp_muxid = ioctl(tt->ip_fd, link_type, arp_fd)) < 0)
2472 msg(
M_ERR,
"Can't link %s device to ARP", dev_tuntap_type);
2479 ifr.lifr_ip_muxid = ip_muxid;
2482 ifr.lifr_arp_muxid = arp_muxid;
2485 if (ioctl(tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0)
2489 ioctl(tt->ip_fd, I_PUNLINK, arp_muxid);
2491 ioctl(tt->ip_fd, I_PUNLINK, ip_muxid);
2492 msg(
M_ERR,
"Can't set multiplexor id");
2503solaris_close_tun(
struct tuntap *tt)
2521 if (ioctl(tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0)
2526 if (ioctl(tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0)
2533 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0)
2539 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0)
2563 solaris_close_tun(tt);
2572solaris_error_close(
struct tuntap *tt,
const struct env_set *es,
const char *actual,
2598 sbuf.buf = (
char *)buf;
2599 return putmsg(tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
2609 sbuf.buf = (
char *)buf;
2610 return getmsg(tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
2613#elif defined(TARGET_OPENBSD)
2616open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2619 open_tun_generic(dev, dev_type, dev_node, tt);
2624 struct tuninfo info;
2626 if (ioctl(tt->fd, TUNGIFINFO, &info) < 0)
2632 info.flags |= IFF_MULTICAST;
2635 if (ioctl(tt->fd, TUNSIFINFO, &info) < 0)
2660 close_tun_generic(tt);
2672 close_tun_generic(tt);
2681#elif defined(TARGET_NETBSD)
2698open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2705 if (strcmp(dev,
"tap") == 0)
2708 if ((tt->fd = open(
"/dev/tap", O_RDWR)) < 0)
2710 msg(
M_FATAL,
"Cannot allocate NetBSD TAP dev dynamically");
2712 if (ioctl(tt->fd, TAPGIFNAME, (
void *)&ifr) < 0)
2714 msg(
M_FATAL,
"Cannot query NetBSD TAP device name");
2718 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2727 open_tun_generic(dev, dev_type, dev_node, tt);
2732 int i = IFF_POINTOPOINT | IFF_MULTICAST;
2733 ioctl(tt->fd, TUNSIFMODE, &i);
2735 ioctl(tt->fd, TUNSLMODE, &i);
2740 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0)
2761 close_tun_generic(tt);
2773 close_tun_generic(tt);
2782#elif defined(TARGET_FREEBSD)
2785open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2788 if (tun_dco_enabled(tt))
2790 open_tun_dco_generic(dev, dev_type, tt, ctx);
2794 open_tun_generic(dev, dev_type, dev_node, tt);
2799 int i = IFF_POINTOPOINT | IFF_MULTICAST;
2802 i = IFF_BROADCAST | IFF_MULTICAST;
2805 if (ioctl(tt->fd, TUNSIFMODE, &i) < 0)
2812 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0)
2834 close_tun_generic(tt);
2847 close_tun_generic(tt);
2856#elif defined(TARGET_DRAGONFLY)
2859open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2862 open_tun_generic(dev, dev_type, dev_node, tt);
2869 ioctl(tt->fd, TUNSLMODE, &i);
2871 ioctl(tt->fd, TUNSIFHEAD, &i);
2880 close_tun_generic(tt);
2884#elif defined(TARGET_DARWIN)
2906utun_open_helper(
struct ctl_info ctlInfo,
int utunnum)
2908 struct sockaddr_ctl sc;
2911 fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
2915 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (socket(SYSPROTO_CONTROL))", utunnum);
2919 if (ioctl(fd, CTLIOCGINFO, &ctlInfo) == -1)
2922 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (ioctl(CTLIOCGINFO))", utunnum);
2927 sc.sc_id = ctlInfo.ctl_id;
2928 sc.sc_len =
sizeof(sc);
2929 sc.sc_family = AF_SYSTEM;
2930 sc.ss_sysaddr = AF_SYS_CONTROL;
2932 sc.sc_unit = utunnum + 1;
2938 if (connect(fd, (
struct sockaddr *)&sc,
sizeof(sc)) < 0)
2940 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (connect(AF_SYS_CONTROL))", utunnum);
2952open_darwin_utun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt)
2954 struct ctl_info ctlInfo;
2958 socklen_t utunname_len =
sizeof(utunname);
2962 if (dev_node && (strcmp(
"utun", dev_node) != 0))
2964 if (sscanf(dev_node,
"utun%d", &utunnum) != 1)
2967 "Cannot parse 'dev-node %s' please use 'dev-node utunX'"
2968 "to use a utun device number X",
2975 if (
strlcpy(ctlInfo.ctl_name, UTUN_CONTROL_NAME,
sizeof(ctlInfo.ctl_name))
2976 >=
sizeof(ctlInfo.ctl_name))
2978 msg(
M_ERR,
"Opening utun: UTUN_CONTROL_NAME too long");
2984 for (utunnum = 0; utunnum < 255; utunnum++)
2988 ASSERT(snprintf(ifname,
sizeof(ifname),
"utun%d", utunnum) > 0);
2989 if (if_nametoindex(ifname))
2993 fd = utun_open_helper(ctlInfo, utunnum);
3004 fd = utun_open_helper(ctlInfo, utunnum);
3016 if (getsockopt(fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, utunname, &utunname_len))
3018 msg(
M_ERR,
"Error retrieving utun interface name");
3023 msg(
M_INFO,
"Opened utun device %s", utunname);
3028open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3032 if ((!dev_node && tt->
type ==
DEV_TYPE_TUN) || (dev_node && !strncmp(dev_node,
"utun", 4)))
3038 msg(
M_FATAL,
"Cannot use utun devices with --dev-type %s",
3044 open_darwin_utun(dev, dev_type, dev_node, tt);
3051 msg(
M_INFO,
"Failed to open utun device. Falling back to /dev/tun device");
3052 open_tun_generic(dev, dev_type, NULL, tt);
3068 if (dev_node && strcmp(dev_node,
"tun") == 0)
3073 open_tun_generic(dev, dev_type, dev_node, tt);
3094 close_tun_generic(tt);
3105 return write_tun_header(tt, buf, len);
3109 return write(tt->fd, buf, len);
3118 return read_tun_header(tt, buf, len);
3122 return read(tt->fd, buf, len);
3126#elif defined(TARGET_AIX)
3129open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3133 char dynamic_name[20];
3138 msg(
M_FATAL,
"no support for 'tun' devices on AIX");
3141 if (strncmp(dev,
"tap", 3) != 0 || dev_node)
3144 "'--dev %s' and/or '--dev-node' not supported on AIX, use '--dev tap0', 'tap1', etc.",
3148 if (strcmp(dev,
"tap") == 0)
3151 for (i = 0; i < 99; i++)
3153 snprintf(tunname,
sizeof(tunname),
"/dev/tap%d", i);
3154 if (access(tunname, F_OK) < 0 && errno == ENOENT)
3161 msg(
M_FATAL,
"cannot find unused tap device");
3164 snprintf(dynamic_name,
sizeof(dynamic_name),
"tap%d", i);
3177 msg(
M_FATAL,
"TAP device name must be '--dev tapNNNN'");
3180 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
3185 if (access(tunname, F_OK) < 0 && errno == ENOENT)
3204 if ((tt->fd = open(tunname, O_RDWR)) < 0)
3206 msg(
M_ERR,
"Cannot open TAP device '%s'", tunname);
3211 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
3238 close_tun_generic(tt);
3251 return write(tt->fd, buf, len);
3257 return read(tt->fd, buf, len);
3260#elif defined(_WIN32)
3289 dmsg(
D_WIN32_IO,
"WIN32 I/O: TAP Read immediate return [%d,%lu]", len,
3294 const int err = GetLastError();
3295 if (err == ERROR_IO_PENDING)
3348 const int err = GetLastError();
3349 if (err == ERROR_IO_PENDING)
3381 err = GetLastError();
3399 HDEVINFO dev_info_set;
3405 SetupDiGetClassDevsEx(&
GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
3406 if (dev_info_set == INVALID_HANDLE_VALUE)
3408 err = GetLastError();
3409 msg(
M_FATAL,
"Error [%lu] opening device information set key: %s", err,
3414 for (DWORD i = 0;; ++i)
3416 SP_DEVINFO_DATA device_info_data;
3419 const char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3421 char device_instance_id[256];
3425 ULONG dev_interface_list_size;
3428 ZeroMemory(&device_info_data,
sizeof(SP_DEVINFO_DATA));
3429 device_info_data.cbSize =
sizeof(SP_DEVINFO_DATA);
3430 res = SetupDiEnumDeviceInfo(dev_info_set, i, &device_info_data);
3433 if (GetLastError() == ERROR_NO_MORE_ITEMS)
3443 dev_key = SetupDiOpenDevRegKey(dev_info_set, &device_info_data, DICS_FLAG_GLOBAL, 0,
3444 DIREG_DRV, KEY_QUERY_VALUE);
3445 if (dev_key == INVALID_HANDLE_VALUE)
3452 status = RegQueryValueEx(dev_key, net_cfg_instance_id_string, NULL, &data_type,
3454 if (
status != ERROR_SUCCESS)
3459 len =
sizeof(device_instance_id);
3460 res = SetupDiGetDeviceInstanceId(dev_info_set, &device_info_data, device_instance_id, len,
3467 cr = CM_Get_Device_Interface_List_Size(&dev_interface_list_size,
3469 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3471 if (cr != CR_SUCCESS)
3476 char *dev_interface_list =
gc_malloc(dev_interface_list_size,
false,
gc);
3478 dev_interface_list, dev_interface_list_size,
3479 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3480 if (cr != CR_SUCCESS)
3485 char *dev_if = dev_interface_list;
3488 while (strlen(dev_if) > 0)
3506 last->
next = dev_iif;
3510 dev_if += strlen(dev_if) + 1;
3514 RegCloseKey(dev_key);
3517 SetupDiDestroyDeviceInfoList(dev_info_set);
3532 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ADAPTER_KEY, 0, KEY_READ, &adapter_key);
3534 if (
status != ERROR_SUCCESS)
3536 msg(
M_FATAL,
"Error opening registry key: %s", ADAPTER_KEY);
3542 char enum_name[256];
3543 char unit_string[256];
3545 const char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3546 BYTE net_cfg_instance_id[256];
3549 len =
sizeof(enum_name);
3550 status = RegEnumKeyEx(adapter_key, i, enum_name, &len, NULL, NULL, NULL, NULL);
3551 if (
status == ERROR_NO_MORE_ITEMS)
3555 else if (
status != ERROR_SUCCESS)
3557 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s", ADAPTER_KEY);
3560 if (!
checked_snprintf(unit_string,
sizeof(unit_string),
"%s\\%s", ADAPTER_KEY, enum_name))
3562 msg(
M_WARN,
"Error constructing unit string for %s", enum_name);
3566 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, unit_string, 0, KEY_READ, &unit_key);
3568 if (
status != ERROR_SUCCESS)
3574 const char component_id_string[] =
"ComponentId";
3575 char component_id[256];
3576 len =
sizeof(component_id);
3577 status = RegQueryValueEx(unit_key, component_id_string, NULL, &data_type,
3578 (LPBYTE)component_id, &len);
3580 if (
status != ERROR_SUCCESS || data_type != REG_SZ)
3582 dmsg(
D_REGISTRY,
"Error opening registry key: %s\\%s", unit_string,
3583 component_id_string);
3587 len =
sizeof(net_cfg_instance_id);
3588 status = RegQueryValueEx(unit_key, net_cfg_instance_id_string, NULL, &data_type,
3589 net_cfg_instance_id, &len);
3591 if (
status == ERROR_SUCCESS && data_type == REG_SZ)
3600 else if (strcasecmp(component_id,
"ovpn-dco") == 0)
3628 RegCloseKey(unit_key);
3633 RegCloseKey(adapter_key);
3641 HKEY network_connections_key;
3647 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ,
3648 &network_connections_key);
3650 if (
status != ERROR_SUCCESS)
3652 msg(
M_FATAL,
"Error opening registry key: %s", NETWORK_CONNECTIONS_KEY);
3657 char enum_name[256];
3658 char connection_string[256];
3659 HKEY connection_key;
3661 const WCHAR name_string[] = L
"Name";
3663 len =
sizeof(enum_name);
3664 status = RegEnumKeyEx(network_connections_key, i, enum_name, &len, NULL, NULL, NULL, NULL);
3665 if (
status == ERROR_NO_MORE_ITEMS)
3669 else if (
status != ERROR_SUCCESS)
3671 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s", NETWORK_CONNECTIONS_KEY);
3675 "%s\\%s\\Connection",
3676 NETWORK_CONNECTIONS_KEY, enum_name))
3678 msg(
M_WARN,
"Error constructing connection string for %s", enum_name);
3683 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, connection_string, 0, KEY_READ, &connection_key);
3685 if (
status != ERROR_SUCCESS)
3687 dmsg(
D_REGISTRY,
"Error opening registry key: %s", connection_string);
3691 WCHAR name_data[256];
3692 len =
sizeof(name_data);
3693 status = RegQueryValueExW(connection_key, name_string, NULL, &name_type,
3694 (LPBYTE)name_data, &len);
3696 if (
status != ERROR_SUCCESS || name_type != REG_SZ)
3698 dmsg(
D_REGISTRY,
"Error opening registry key: %s\\%s\\%ls", NETWORK_CONNECTIONS_KEY,
3699 connection_string, name_string);
3708 n = WideCharToMultiByte(CP_UTF8, 0, name_data, -1, NULL, 0, NULL, NULL);
3710 WideCharToMultiByte(CP_UTF8, 0, name_data, -1,
name, n, NULL, NULL);
3725 RegCloseKey(connection_key);
3730 RegCloseKey(network_connections_key);
3742 const unsigned int mask = 3;
3743 const char *err = NULL;
3745 if (local == remote)
3747 err =
"must be different";
3750 if ((local & (~mask)) != (remote & (~mask)))
3753 "must exist within the same 255.255.255.252 subnet. This is a limitation of --dev tun when used with the TAP-WIN32 driver";
3756 if ((local & mask) == 0 || (local & mask) == 3 || (remote & mask) == 0 || (remote & mask) == 3)
3759 "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";
3768 "There is a problem in your selection of --ifconfig endpoints [local=%s, remote=%s]. The local and remote VPN endpoints %s. Try '" PACKAGE
3769 " --show-valid-subnets' option for more info.",
3780 printf(
"On Windows, point-to-point IP support (i.e. --dev tun)\n");
3781 printf(
"is emulated by the TAP-Windows driver. The major limitation\n");
3782 printf(
"imposed by this approach is that the --ifconfig local and\n");
3783 printf(
"remote endpoints must be part of the same 255.255.255.252\n");
3784 printf(
"subnet. The following list shows examples of endpoint\n");
3785 printf(
"pairs which satisfy this requirement. Only the final\n");
3786 printf(
"component of the IP address pairs is at issue.\n\n");
3787 printf(
"As an example, the following option would be correct:\n");
3788 printf(
" --ifconfig 10.7.0.5 10.7.0.6 (on host A)\n");
3789 printf(
" --ifconfig 10.7.0.6 10.7.0.5 (on host B)\n");
3790 printf(
"because [5,6] is part of the below list.\n\n");
3792 for (i = 0; i < 256; i += 4)
3794 printf(
"[%3d,%3d] ", i + 1, i + 2);
3812 bool warn_panel_null =
false;
3813 bool warn_panel_dup =
false;
3814 bool warn_tap_dup =
false;
3823 msg(msglevel,
"Available adapters [name, GUID, driver]:");
3843 warn_panel_dup =
true;
3845 else if (links == 0)
3849 warn_panel_null =
true;
3850 msg(msglevel,
"[NULL] %s", tr->
guid);
3859 if (tr != tr1 && !strcmp(tr->
guid, tr1->
guid))
3861 warn_tap_dup =
true;
3869 msg(warnlevel,
"WARNING: Some TAP-Windows adapters have duplicate GUIDs");
3875 "WARNING: Some TAP-Windows adapters have duplicate links from the Network Connections control panel");
3878 if (warn_panel_null)
3881 "WARNING: Some TAP-Windows adapters have no link from the Network Connections control panel");
3944 msg(
M_FATAL,
"There are no TAP-Windows or ovpn-dco adapters "
3945 "on this system. You should be able to create an adapter "
3946 "by using tapctl.exe utility.");
3956 const struct tap_reg *tap_reg_src,
4006 if (windows_driver !=
NULL)
4035 ASSERT(actual_name_size > 0);
4081const IP_ADAPTER_INFO *
4085 IP_ADAPTER_INFO *pi = NULL;
4088 if ((
status = GetAdaptersInfo(NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4095 pi = (PIP_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4096 if ((
status = GetAdaptersInfo(pi, &size)) != NO_ERROR)
4106const IP_PER_ADAPTER_INFO *
4110 IP_PER_ADAPTER_INFO *pi = NULL;
4116 if ((
status = GetPerAdapterInfo(index, NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4123 pi = (PIP_PER_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4124 if ((
status = GetPerAdapterInfo(index, pi, &size)) == ERROR_SUCCESS)
4139static const IP_INTERFACE_INFO *
4143 IP_INTERFACE_INFO *ii = NULL;
4146 if ((
status = GetInterfaceInfo(NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)
4153 ii = (PIP_INTERFACE_INFO)
gc_malloc(size,
false,
gc);
4154 if ((
status = GetInterfaceInfo(ii, &size)) == NO_ERROR)
4168static const IP_ADAPTER_INDEX_MAP *
4175 for (i = 0; i < list->NumAdapters; ++i)
4177 const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[i];
4178 if (index == inter->Index)
4192const IP_ADAPTER_INFO *
4197 const IP_ADAPTER_INFO *a;
4200 for (a = ai; a != NULL; a = a->Next)
4202 if (a->Index == index)
4211const IP_ADAPTER_INFO *
4223 const IP_ADDR_STRING *ip = &ai->IpAddressList;
4247 const IP_ADDR_STRING *iplist = &ai->IpAddressList;
4257 iplist = iplist->Next;
4263 const char *ip_str = iplist->IpAddress.String;
4264 const char *netmask_str = iplist->IpMask.String;
4265 bool succeed1 =
false;
4266 bool succeed2 =
false;
4268 if (ip_str && netmask_str && strlen(ip_str) && strlen(netmask_str))
4270 *ip =
getaddr(getaddr_flags, ip_str, 0, &succeed1, NULL);
4271 *netmask =
getaddr(getaddr_flags, netmask_str, 0, &succeed2, NULL);
4272 ret = (succeed1 ==
true && succeed2 ==
true);
4288 return (
status && ip_adapter == ip && netmask_adapter == netmask);
4296const IP_ADAPTER_INFO *
4321 for (
int i = 0; i < n; ++i)
4357 if (highest_netmask)
4359 *highest_netmask = 0;
4365 for (
int i = 0; i < n; ++i)
4370 if (adapter_ip && adapter_netmask
4371 && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))
4373 if (highest_netmask && adapter_netmask > *highest_netmask)
4375 *highest_netmask = adapter_netmask;
4391 int lowest_metric = INT_MAX;
4406 if (first || hn > highest_netmask)
4408 highest_netmask = hn;
4411 lowest_metric = metric;
4420 else if (hn == highest_netmask)
4426 if (metric >= 0 && metric < lowest_metric)
4429 lowest_metric = metric;
4436 dmsg(
D_ROUTE_DEBUG,
"DEBUG: IP Locate: ip=%s nm=%s index=%lu count=%d metric=%d",
4438 count ? *count : -1, lowest_metric);
4447 *netmask = highest_netmask;
4459#define DHCP_STATUS_UNDEF 0
4460#define DHCP_STATUS_ENABLED 1
4461#define DHCP_STATUS_DISABLED 2
4474 if (ai->DhcpEnabled)
4500 const IP_ADDR_STRING *ip = &a->IpAddressList;
4504 const DWORD
context = ip->Context;
4508 msg(
M_INFO,
"Successfully deleted previously set dynamic IP/netmask: %s/%s",
4509 ip->IpAddress.String, ip->IpMask.String);
4513 const char *empty =
"0.0.0.0";
4514 if (strcmp(ip->IpAddress.String, empty) || strcmp(ip->IpMask.String, empty))
4517 "NOTE: could not delete previously set dynamic IP/netmask: %s/%s (status=%lu)",
4518 ip->IpAddress.String, ip->IpMask.String,
status);
4536 swprintf(wbuf,
SIZE(wbuf), L
"\\DEVICE\\TCPIP_%hs", guid);
4537 if (GetAdapterIndex(wbuf, &aindex) != NO_ERROR)
4543 index = (DWORD)aindex;
4558 if (!strcmp(guid,
list->AdapterName))
4560 index =
list->Index;
4581 msg(
M_INFO,
"NOTE: could not get adapter index for %s", guid);
4595 buf_printf(&out,
"%s", ip->IpAddress.String);
4596 if (
strlen(ip->IpMask.String))
4613 msg(msglevel,
"%s",
a->Description);
4614 msg(msglevel,
" Index = %lu",
a->Index);
4615 msg(msglevel,
" GUID = %s",
a->AdapterName);
4622 msg(msglevel,
" DHCP LEASE OBTAINED = %s",
time_string(
a->LeaseObtained, 0,
false,
gc));
4623 msg(msglevel,
" DHCP LEASE EXPIRES = %s",
time_string(
a->LeaseExpires, 0,
false,
gc));
4649 msg(msglevel,
"SYSTEM ADAPTER LIST");
4652 const IP_ADAPTER_INFO *a;
4655 for (a = ai; a != NULL; a = a->Next)
4678 msg(
M_ERR,
"Error: init SA failed");
4681 status = SetKernelObjectSecurity(hand, DACL_SECURITY_INFORMATION, &
sa.sd);
4684 msg(
M_ERRNO,
"Error: SetKernelObjectSecurity failed on %s", device_path);
4688 msg(
M_INFO |
M_NOPREFIX,
"TAP-Windows device: %s [Non-admin access allowed]", device_path);
4698 const char *device_guid = NULL;
4700 uint8_t actual_buffer[256];
4701 char device_path[256];
4713 msg(
M_FATAL,
"TAP-Windows adapter '%s' not found", dev_node);
4717 snprintf(device_path,
sizeof(device_path),
"%s%s%s", USERMODEDEVICEDIR, device_guid,
4720 hand = CreateFile(device_path, MAXIMUM_ALLOWED, 0,
4721 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
4723 if (hand == INVALID_HANDLE_VALUE)
4725 msg(
M_ERR,
"CreateFile failed on TAP device: %s", device_path);
4733 int device_number = 0;
4747 snprintf(device_path,
sizeof(device_path),
"%s%s%s", USERMODEDEVICEDIR, device_guid,
4750 hand = CreateFile(device_path, MAXIMUM_ALLOWED, 0,
4751 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
4753 if (hand == INVALID_HANDLE_VALUE)
4755 msg(
M_WARN,
"CreateFile failed on TAP device: %s", device_path);
4781 DWORD
status = IpReleaseAddress((IP_ADAPTER_INDEX_MAP *)inter);
4790 "NOTE: Release of DHCP-assigned IP address lease on TAP-Windows adapter failed: %s (code=%lu)",
4822 DWORD
status = IpRenewAddress((IP_ADAPTER_INDEX_MAP *)inter);
4831 "WARNING: Failed to renew DHCP IP address lease on TAP-Windows adapter: %s (code=%lu)",
4857 for (i = 0; i < n; ++i)
4871 msg(msglevel,
"%s: command failed", prefix);
4884 const char err[] =
"ERROR: Windows ipconfig command failed";
4909 const char *ip_str = src->IpAddress.String;
4911 bool succeed =
false;
4917 if (!ip_str || !strlen(ip_str))
4922 ip =
getaddr(getaddr_flags, ip_str, 0, &succeed, NULL);
4936 msg(
M_INFO,
"ip_addr_string_to_array [%d]", *dest_len);
4937 for (i = 0; i < *dest_len; ++i)
4960 for (
unsigned int i = 0; i < a1len; ++i)
4977 for (
unsigned int i = 0; i < len; ++i)
5004 for (
unsigned int i = 0; i < addr_len; ++i)
5006 const char *fmt = (i == 0) ?
"%s%s interface ipv6 set dns %lu static %s"
5007 :
"%s%s interface ipv6 add dns %lu %s";
5024 const IP_ADDR_STRING *current, DWORD adapter_index,
const bool test_first)
5028 bool delete_first =
false;
5029 bool is_dns = !strcmp(type,
"dns");
5036 delete_first =
true;
5041 delete_first =
true;
5055 for (
unsigned int i = 0; i < addr_len; ++i)
5059 const char *fmt = first ?
"%s%s interface ip set %s %lu static %s"
5060 :
"%s%s interface ip add %s %lu %s";
5077 msg(
M_INFO,
"NETSH: %lu %s %s [already set]", adapter_index, type,
5095 dest[0].Next = NULL;
5100 dest[0].Next = &dest[1];
5101 dest[1].Next = NULL;
5107 const in_addr_t netmask,
const unsigned int flags)
5111 const IP_ADAPTER_INFO *ai = NULL;
5112 const IP_PER_ADAPTER_INFO *pai = NULL;
5125 msg(
M_INFO,
"NETSH: %lu %s/%s [already set]", adapter_index,
5142 IP_ADDR_STRING wins[2];
5148 if (ai && ai->HaveWins)
5194 msg(
M_NONFATAL,
"TUN: enabling dhcp using service failed: %s [status=%d if_index=%lu]",
5199 msg(
M_INFO,
"DHCP enabled on interface %lu using service",
dhcp.iface.index);
5212 MIB_IPINTERFACE_ROW ipiface;
5213 InitializeIpInterfaceEntry(&ipiface);
5214 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
5215 ipiface.Family = family;
5216 ipiface.InterfaceIndex = iface_index;
5217 if (family == AF_INET6 && mtu < 1280)
5220 "NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
5223 err = GetIpInterfaceEntry(&ipiface);
5224 if (err == NO_ERROR)
5226 if (family == AF_INET)
5228 ipiface.SitePrefixLength = 0;
5230 ipiface.NlMtu = mtu;
5231 err = SetIpInterfaceEntry(&ipiface);
5234 if (err != NO_ERROR)
5237 msg(
M_WARN,
"TUN: Setting %s mtu failed: %s [status=%lu if_index=%d]", family_name,
5243 msg(
M_INFO,
"%s MTU set to %d on interface %d using SetIpInterfaceEntry()", family_name,
5285 return BSTR(&actual);
5299 tt->standby_iter = 0;
5311 msg(
M_INFO,
"NOTE: now trying netsh (this may take some time)");
5326 if (
tt->options.dhcp_pre_release ||
tt->options.dhcp_renew)
5334 if (
tt->options.dhcp_pre_release)
5338 if (
tt->options.dhcp_renew)
5352 HANDLE msg_channel =
tt->options.msg_channel;
5366 msg(
M_WARN,
"Register_dns failed using service: %s [status=0x%x]",
5372 msg(
M_INFO,
"Register_dns request sent to the service");
5391 buf_printf(&
cmd,
"openvpn --verb %d --register-dns --rdns-internal", verb);
5405 dsa = (local | (~netmask)) + offset;
5409 dsa = (local & netmask) + offset;
5415 "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",
5419 if ((local & netmask) != (dsa & netmask))
5421 msg(
M_FATAL,
"ERROR: --ip-win32 dynamic [offset] : offset is outside of --ifconfig subnet");
5434 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_VERSION, &info,
sizeof(info), &info,
5435 sizeof(info), &len, NULL))
5437 msg(
D_TUNTAP_INFO,
"TAP-Windows Driver Version %lu.%lu %s", info[0], info[1],
5438 (info[2] ?
"(DEBUG)" :
""));
5444 " requires a TAP-Windows driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME
5445 " distribution, a reboot is probably required at this point to get Windows to see the new driver.",
5455 "WARNING: Tap-Win32 driver version %lu.%lu does not support IPv6 in TUN mode. IPv6 will not work. Upgrade your Tap-Win32 driver.",
5464 "ERROR: Tap-Win32 driver version 9.8 is buggy regarding small IPv4 packets in TUN mode. Upgrade your Tap-Win32 driver.");
5473 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_MTU, &mtu,
sizeof(mtu), &mtu,
sizeof(mtu), &len,
5489 DWORD
status = (DWORD)-1;
5497 .iface = { .index = index, .name =
"" } };
5506 status = FlushIpNetTable(index);
5511 msg(
M_INFO,
"Successful ARP Flush on interface [%lu] %s", index, device_guid);
5513 else if (
status != (DWORD)-1)
5516 "NOTE: FlushIpNetTable failed on interface [%lu] %s (status=%lu) : %s", index,
5531 "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'");
5553 const char *error_suffix =
5554 "I am having trouble using the Windows 'IP helper API' to automatically set the IP address -- consider using other --ip-win32 methods (not 'ipapi')";
5559 msg(
M_FATAL,
"ERROR: unable to get adapter index for interface %s -- %s", device_guid,
5567 "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'");
5580 "Succeeded in adding a temporary IP/netmask of %s/%s to interface %s using the Win32 IP Helper API",
5587 "ERROR: AddIPAddress %s/%s failed on interface %s, index=%lu, status=%lu (windows error: '%s') -- %s",
5603 sizeof(
status), &len, NULL))
5606 "WARNING: The TAP-Windows driver rejected a TAP_WIN_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
5612 msg(
M_INFO,
"Sleeping for %d seconds...", s);
5625 msg(
M_FATAL,
"ERROR: --dev tun also requires --ifconfig");
5636 ep[0] = htonl(tt->
local);
5640 status = DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_TUN, ep,
sizeof(ep), ep,
sizeof(ep),
5646 "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
5654 status ?
"SUCCEEDED" :
"FAILED");
5660 ep[0] = htonl(tt->
local);
5663 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT, ep,
sizeof(ep), ep,
5664 sizeof(ep), &len, NULL))
5667 "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun");
5682 ep[0] = htonl(tt->
local);
5712#ifndef SIMULATE_DHCP_FAILED
5713 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_DHCP_MASQ, ep,
sizeof(ep), ep,
sizeof(ep),
5717 "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode");
5721 "Notified TAP-Windows driver to set a DHCP IP/netmask of %s/%s on interface %s [DHCP-serv: %s, lease-time: %d]",
5736 "ERROR: The TAP-Windows driver rejected a TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call");
5741 msg(
M_WARN,
"DHCP option string not set due to error");
5785 snprintf(tuntap_device_path,
sizeof(tuntap_device_path),
"%s%s%s", USERMODEDEVICEDIR,
5786 device_guid, TAP_WIN_SUFFIX);
5787 path = tuntap_device_path;
5792 tt->
hand = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
5793 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
5794 if (tt->
hand == INVALID_HANDLE_VALUE)
5813 uint8_t actual_buffer[256];
5823 *device_guid =
get_device_guid(dev_node, actual_buffer,
sizeof(actual_buffer),
5828 msg(
M_FATAL,
"Adapter '%s' not found", dev_node);
5834 "Adapter '%s' is using %s driver, %s expected.",
5841 msg(
M_FATAL,
"Failed to open %s adapter: %s",
5847 int device_number = 0;
5848 int adapters_created = 0;
5861 if ((++adapters_created > 10)
5864 msg(
M_FATAL,
"All %s adapters on this system are currently in use or disabled.",
5923 *dhcp_masq_post =
true;
5945 bool dhcp_masq =
false;
5946 bool dhcp_masq_post =
false;
5987open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
5994 "Some --dhcp-option or --dns options require DHCP server,"
5995 " which is not supported by the selected %s driver. They will be"
6006 const char *device_guid = NULL;
6114 if (!CancelIo(tt->
hand))
6116 msg(
M_WARN |
M_ERRNO,
"Warning: CancelIO failed on %s adapter", adaptertype);
6120 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped read event on %s adapter", adaptertype);
6123 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped write event on %s adapter", adaptertype);
6129 if (!CloseHandle(tt->
hand))
6131 msg(
M_WARN |
M_ERRNO,
"Warning: CloseHandle failed on %s adapter", adaptertype);
6208 "Warning: DeleteIPAddress[%lu] failed on TAP-Windows adapter, status=%lu : %s",
6235 {
"manual" }, {
"netsh" }, {
"ipapi" }, {
"dynamic" }, {
"adaptive" }
6259 return "[unknown --ip-win32 type]";
6288open_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)
Free the memory allocated for a buffer.
bool buf_printf(struct buffer *buf, const char *format,...)
printf-style append to a buffer with overflow check.
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Allocate memory and, optionally, zero it.
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Allocate a buffer of the given size under garbage collection.
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)
Format a binary buffer as a hex string.
struct buffer alloc_buf(size_t size)
Allocate a buffer of the given 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)
Duplicate a string, allocating memory under garbage collection.
static bool has_digit(const char *src)
Return true if the string contains at least one decimal digit.
#define ALLOC_OBJ(dptr, type)
Allocate memory for a single object of the given type.
#define BSTR(buf)
Return the buffer content pointer cast to char *.
static struct buffer clear_buf(void)
Return an empty, undefined struct buffer (all fields zero).
static bool buf_copy(struct buffer *dest, const struct buffer *src)
Copy the content of one buffer to the end of another.
#define BPTR(buf)
Return a pointer to the start of the buffer content.
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
Initialise a buffer with an externally provided writable memory region.
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Allocate and zero-initialise a garbage-collected object of the given type.
#define BLEN(buf)
Return the length of the buffer content in bytes.
static char * format_hex(const uint8_t *data, size_t size, size_t maxoutput, struct gc_arena *gc)
Format a binary buffer as a hex string with spaces every 4 bytes.
#define BCAP(buf)
Return the number of bytes available for appending to the buffer.
static void check_malloc_return(void *p)
Abort if a memory allocation returned NULL.
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
size_t strlcpy(char *dest, const char *src, size_t maxlen)
#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)
#define TUN_ADAPTER_INDEX_INVALID
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)
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.
#define GETADDR_HOST_ORDER
#define GETADDR_FATAL_ON_SIGNAL
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)
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)
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)
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 void netsh_set_dns6_servers(const struct in6_addr *addr_list, const unsigned int addr_len, DWORD adapter_index)
Set the ipv6 dns servers on the specified interface.
static bool do_address_service(const bool add, const short family, const struct tuntap *tt)
static void clear_tuntap(struct tuntap *tuntap)
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, const struct addrinfo *local_public, const struct addrinfo *remote_public, const bool strict_warn, struct env_set *es, openvpn_net_ctx_t *ctx, struct tuntap *tt)
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)
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 undo_ifconfig_ipv4(const struct tuntap *tt, openvpn_net_ctx_t *ctx)
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)
int tun_write_win32(struct tuntap *tt, const struct buffer *buf)
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 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)
static void fork_dhcp_action(struct tuntap *tt)
static void show_adapter(msglvl_t msglevel, const IP_ADAPTER_INFO *a, struct gc_arena *gc)
static void tuntap_get_mtu(const struct tuntap *tt)
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 bool ip_addr_one_to_one(const in_addr_t *a1, const unsigned int a1len, const IP_ADDR_STRING *ias)
static void undo_ifconfig_ipv6(const struct tuntap *tt, openvpn_net_ctx_t *ctx)
static void ifconfig_sanity_check(bool tun_p2p, in_addr_t addr)
static void ip_addr_string_to_array(in_addr_t *dest, unsigned int *dest_len, const IP_ADDR_STRING *src)
#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)
void fork_register_dns_action(const struct tuntap *tt)
int tun_write_queue(struct tuntap *tt, const struct buffer *buf)
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 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
bool dhcp_release_by_adapter_index(const DWORD adapter_index)
static void add_route_connected_v6_net(const struct tuntap *tt, const struct env_set *es)
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)
void warn_on_use_of_common_subnets(openvpn_net_ctx_t *ctx)
void undo_ifconfig(const struct tuntap *tt, openvpn_net_ctx_t *ctx)
undo_ifconfig - undo configuration of the tunnel interface
static bool dhcp_renew(const struct tuntap *tt)
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)
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)
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_show_debug(const struct tuntap *tt)
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)
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)
static void netsh_ifconfig_options(const char *type, const in_addr_t *addr_list, const unsigned int addr_len, const IP_ADDR_STRING *current, DWORD adapter_index, const bool test_first)
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)
#define IPW32_SET_ADAPTIVE
#define DHCP_OPTIONS_DHCP_REQUIRED
ssize_t read_tun(const struct tuntap *tt, uint8_t *buf, int len)
#define N_SEARCH_LIST_LEN
#define IPW32_SET_DHCP_MASQ
#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
static bool tuntap_is_dco_win(const struct tuntap *tt)
ssize_t write_tun(const struct tuntap *tt, const uint8_t *buf, int len)
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)
Initializes security attributes with a NULL DACL, allowing unrestricted access to the resulting objec...
#define IOSTATE_IMMEDIATE_RETURN
#define POWERSHELL_PATH_SUFFIX
#define WIN_IPCONFIG_PATH_SUFFIX
#define NETSH_PATH_SUFFIX
static bool overlapped_io_active(const struct overlapped_io *o)