63 return "tap-windows6";
88 0x4d36e972L, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 }
91 0xcac88484, 0x7515, 0x4c03, { 0x82, 0xe6, 0x71, 0xa8, 0x7a, 0xba, 0xc3, 0x61 }
96#define NI_TEST_FIRST (1 << 0)
97#define NI_IP_NETMASK (1 << 1)
98#define NI_OPTIONS (1 << 2)
101 const in_addr_t netmask,
const unsigned int flags);
103static void windows_set_mtu(
const int iface_index,
const short family,
const int mtu);
106 DWORD adapter_index);
110static void exec_command(
const char *prefix,
const struct argv *a,
int n,
int msglevel);
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=%u if_index=%d]",
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 = %d) 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=%u if_name=%s]",
232 msg(
M_INFO,
"DNS domains %s using service", (add ?
"set" :
"deleted"));
245 int addr_len = add ? len : 0;
246 const char *ip_proto_name = family == AF_INET6 ?
"IPv6" :
"IPv4";
260 .addr_len = addr_len };
266 if (addr_len > _countof(dns.
addr))
268 addr_len = _countof(dns.
addr);
270 msg(
M_WARN,
"Number of %s DNS addresses sent to service truncated to %d", ip_proto_name,
274 for (
int i = 0;
i < addr_len; ++
i)
276 if (family == AF_INET6)
286 msg(
D_LOW,
"%s %s dns servers on '%s' (if_index = %d) using service",
296 msg(
M_WARN,
"TUN: %s %s dns failed using service: %s [status=%u if_name=%s]",
302 msg(
M_INFO,
"%s dns servers %s using service", ip_proto_name, (add ?
"set" :
"deleted"));
325 .addr_len = addr_len };
331 if (addr_len > _countof(wins.
addr))
333 addr_len = _countof(wins.
addr);
335 msg(
M_WARN,
"Number of WINS addresses sent to service truncated to %d", addr_len);
338 for (
int i = 0;
i < addr_len; ++
i)
343 msg(
D_LOW,
"%s WINS servers on '%s' (if_index = %d) using service",
353 msg(
M_WARN,
"TUN: %s WINS failed using service: %s [status=%u if_name=%s]",
359 msg(
M_INFO,
"WINS servers %s using service", (add ?
"set" :
"deleted"));
372 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
378 if (family == AF_INET6 && mtu < 1280)
381 "NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
391 msg(
M_NONFATAL,
"TUN: setting %s mtu using service failed: %s [status=%u if_index=%d]",
397 msg(
M_INFO,
"%s MTU set to %d on interface %d using service", family_name, mtu,
417 "%s%s -NoProfile -NonInteractive -Command Set-DnsClient -InterfaceIndex %lu -ConnectionSpecificSuffix '%s'",
469 msg(
M_NONFATAL,
"TUN: creating %s adapter using service failed: %s [status=%u]",
487static void solaris_error_close(
struct tuntap *tt,
const struct env_set *
es,
const char *actual,
493#if defined(TARGET_DARWIN)
494#include <sys/kern_control.h>
495#include <net/if_utun.h>
496#include <sys/sys_domain.h>
502is_dev_type(
const char *dev,
const char *dev_type,
const char *match_type)
511 return !strcmp(dev_type, match_type);
515 return !strncmp(dev, match_type, strlen(match_type));
550 return "[unknown-dev-type]";
588 const bool looks_like_netmask = ((addr & 0xFF000000) == 0xFF000000);
591 if (looks_like_netmask)
594 "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",
600 if (!looks_like_netmask)
603 "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",
616 in_addr_t remote_netmask)
620 msg(
M_INFO,
"CHECK_ADDR_CLASH type=%d public=%s local=%s, remote_netmask=%s",
631 const in_addr_t test_netmask = 0xFFFFFF00;
632 const in_addr_t public_net =
public & test_netmask;
633 const in_addr_t local_net = local & test_netmask;
634 const in_addr_t remote_net = remote_netmask & test_netmask;
636 if (
public == local ||
public == remote_netmask)
639 "WARNING: --%s address [%s] conflicts with --ifconfig address pair [%s, %s]. %s",
644 if (public_net == local_net || public_net == remote_net)
647 "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",
654 const in_addr_t public_network =
public & remote_netmask;
655 const in_addr_t virtual_network = local & remote_netmask;
656 if (public_network == virtual_network)
659 "WARNING: --%s address [%s] conflicts with --ifconfig subnet [%s, %s] -- local and remote addresses cannot be inside of the --ifconfig subnet. %s",
676 if ((rgi.
flags & needed) == needed)
679 if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100)
682 "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.");
696 if (
tt->did_ifconfig_setup && !disable)
775 msg(
M_FATAL,
"Error: problem with tun vs. tap setting");
801 setenv_str(
es,
"ifconfig_remote", ifconfig_remote_netmask);
805 setenv_str(
es,
"ifconfig_netmask", ifconfig_remote_netmask);
814 setenv_str(
es,
"ifconfig_ipv6_local", ifconfig_ipv6_local);
816 setenv_str(
es,
"ifconfig_ipv6_remote", ifconfig_ipv6_remote);
830 const char *dev_type,
832 const char *ifconfig_local_parm,
833 const char *ifconfig_remote_netmask_parm,
834 const char *ifconfig_ipv6_local_parm,
835 int ifconfig_ipv6_netbits_parm,
836 const char *ifconfig_ipv6_remote_parm,
837 struct addrinfo *local_public,
struct addrinfo *remote_public,
const bool strict_warn,
849 if (ifconfig_local_parm && ifconfig_remote_netmask_parm)
862 ifconfig_local_parm, 0, NULL, NULL);
866 ifconfig_remote_netmask_parm, 0, NULL, NULL);
873 struct addrinfo *curele;
881 for (curele = local_public; curele; curele = curele->ai_next)
883 if (curele->ai_family == AF_INET)
885 const in_addr_t local =
886 ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
891 for (curele = remote_public; curele; curele = curele->ai_next)
893 if (curele->ai_family == AF_INET)
895 const in_addr_t remote =
896 ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
921 if (ifconfig_ipv6_local_parm && ifconfig_ipv6_remote_parm)
927 if (inet_pton(AF_INET6, ifconfig_ipv6_local_parm, &tt->
local_ipv6) != 1
928 || inet_pton(AF_INET6, ifconfig_ipv6_remote_parm, &tt->
remote_ipv6) != 1)
930 msg(
M_FATAL,
"init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary",
931 ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm);
1010#if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || defined(TARGET_NETBSD) \
1011 || defined(TARGET_OPENBSD)
1022create_arbitrary_remote(
struct tuntap *tt)
1028 if (remote == tt->
local)
1050#if !defined(TARGET_LINUX)
1056#if defined(TARGET_LINUX)
1057 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1059 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1062 if (net_iface_up(ctx, ifname,
true) < 0)
1064 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1069 msg(
M_FATAL,
"Linux can't add IPv6 to interface %s", ifname);
1071#elif defined(TARGET_ANDROID)
1074 snprintf(out6,
sizeof(out6),
"%s/%d %d", ifconfig_ipv6_local, tt->
netbits_ipv6, tun_mtu);
1075 management_android_control(
management,
"IFCONFIG6", out6);
1076#elif defined(TARGET_SOLARIS)
1085 argv_printf(&
argv,
"%s %s inet6 plumb %s/%d %s mtu %d up", IFCONFIG_PATH, ifname,
1086 ifconfig_ipv6_local, tt->
netbits_ipv6, ifconfig_ipv6_remote, tun_mtu);
1096 solaris_error_close(tt,
es, ifname,
true);
1108 argv_printf(&
argv,
"%s %s inet6 addif %s/%d up", IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
1115 solaris_error_close(tt,
es, ifname,
true);
1120 argv_printf(&
argv,
"%s %s inet6 mtu %d", IFCONFIG_PATH, ifname, tun_mtu);
1124#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) || defined(TARGET_DARWIN) \
1125 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1126 argv_printf(&
argv,
"%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
1132#if defined(TARGET_FREEBSD) && __FreeBSD_version >= 1200000 && __FreeBSD_version < 1300000
1154#elif defined(TARGET_AIX)
1155 argv_printf(&
argv,
"%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
1166#elif defined(_WIN32)
1170 "******** NOTE: Please manually set the v6 IP of '%s' to %s (if it is not already set)",
1171 ifname, ifconfig_ipv6_local);
1200 argv_printf(&
argv,
"%s%s interface ipv6 set address %lu %s/%d store=active",
1219 "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.");
1222#if !defined(TARGET_LINUX)
1241#if !defined(_WIN32) && !defined(TARGET_ANDROID)
1248#if !defined(TARGET_LINUX)
1249 const char *ifconfig_local = NULL;
1250 const char *ifconfig_remote_netmask = NULL;
1261#if defined(TARGET_LINUX)
1262 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1264 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1267 if (net_iface_up(ctx, ifname,
true) < 0)
1269 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1276 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1283 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1286#elif defined(TARGET_ANDROID)
1289 snprintf(out,
sizeof(out),
"%s %s %d %s", ifconfig_local, ifconfig_remote_netmask, tun_mtu,
1291 management_android_control(
management,
"IFCONFIG", out);
1293#elif defined(TARGET_SOLARIS)
1301 argv_printf(&
argv,
"%s %s %s %s mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local,
1302 ifconfig_remote_netmask, tun_mtu);
1307 solaris_error_close(tt,
es, ifname,
false);
1310 argv_printf(&
argv,
"%s %s netmask 255.255.255.255", IFCONFIG_PATH, ifname);
1314 argv_printf(&
argv,
"%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH, ifname,
1315 ifconfig_local, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1319 argv_printf(&
argv,
"%s %s %s netmask %s up", IFCONFIG_PATH, ifname, ifconfig_local,
1320 ifconfig_remote_netmask);
1326 solaris_error_close(tt,
es, ifname,
false);
1342#elif defined(TARGET_OPENBSD)
1344 in_addr_t remote_end;
1355 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask 255.255.255.255 up -link0", IFCONFIG_PATH,
1356 ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1360 remote_end = create_arbitrary_remote(tt);
1361 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask %s up -link0", IFCONFIG_PATH, ifname,
1363 ifconfig_remote_netmask);
1367 argv_printf(&
argv,
"%s %s %s netmask %s mtu %d link0", IFCONFIG_PATH, ifname,
1368 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1385#elif defined(TARGET_NETBSD)
1386 in_addr_t remote_end = INADDR_ANY;
1390 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask 255.255.255.255 up", IFCONFIG_PATH, ifname,
1391 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1395 remote_end = create_arbitrary_remote(tt);
1396 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH, ifname,
1398 ifconfig_remote_netmask);
1407 argv_printf(&
argv,
"%s %s %s netmask %s mtu %d", IFCONFIG_PATH, ifname, ifconfig_local,
1408 ifconfig_remote_netmask, tun_mtu);
1425#elif defined(TARGET_DARWIN)
1433 msg(
M_INFO,
"NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
1439 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask 255.255.255.255 up", IFCONFIG_PATH, ifname,
1440 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1444 argv_printf(&
argv,
"%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH, ifname,
1445 ifconfig_local, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1449 argv_printf(&
argv,
"%s %s %s netmask %s mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local,
1450 ifconfig_remote_netmask, tun_mtu);
1468#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1473 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask 255.255.255.255 up", IFCONFIG_PATH, ifname,
1474 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1479 argv_printf(&
argv,
"%s %s %s/%d mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local, netbits,
1486#elif defined(TARGET_AIX)
1494 msg(
M_FATAL,
"no tun support on AIX (canthappen)");
1498 argv_printf(&
argv,
"%s %s %s netmask %s mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local,
1499 ifconfig_remote_netmask, tun_mtu);
1506#elif defined(_WIN32)
1510 "******** NOTE: Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
1511 ifname, ifconfig_local, ifconfig_remote_netmask);
1545#elif defined(TARGET_HAIKU)
1547 argv_printf(&
argv,
"%s %s inet %s %s mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local,
1548 ifconfig_remote_netmask, tun_mtu);
1554 "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.");
1557#if !defined(TARGET_LINUX)
1571#ifdef ENABLE_MANAGEMENT
1596#if defined(TARGET_LINUX)
1613#elif defined(TARGET_FREEBSD)
1631#if defined(TARGET_LINUX)
1636#elif defined(TARGET_FREEBSD)
1682#ifdef TARGET_SOLARIS
1687#if defined(TARGET_OPENBSD) || defined(TARGET_DARWIN)
1707#include <netinet/ip.h>
1711header_modify_read_write_return(
int len)
1715 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
1724write_tun_header(
struct tuntap *tt, uint8_t *buf,
int len)
1736 type = htonl(AF_INET6);
1740 type = htonl(AF_INET);
1743 iv[0].iov_base = &type;
1744 iv[0].iov_len =
sizeof(type);
1745 iv[1].iov_base = buf;
1746 iv[1].iov_len = len;
1748 return header_modify_read_write_return(writev(tt->fd, iv, 2));
1752 return write(tt->fd, buf, len);
1757read_tun_header(
struct tuntap *tt, uint8_t *buf,
int len)
1764 iv[0].iov_base = &type;
1765 iv[0].iov_len =
sizeof(type);
1766 iv[1].iov_base = buf;
1767 iv[1].iov_len = len;
1769 return header_modify_read_write_return(readv(tt->fd, iv, 2));
1773 return read(tt->fd, buf, len);
1784#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1786tun_dco_enabled(
struct tuntap *tt)
1793#if !(defined(_WIN32) || defined(TARGET_LINUX) || defined(TARGET_SOLARIS))
1795open_tun_generic(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt)
1798 char dynamic_name[256];
1799 bool dynamic_opened =
false;
1806 snprintf(tunname,
sizeof(tunname),
"%s", dev_node);
1818 for (
int i = 0;
i < 256; ++
i)
1822#if defined(TARGET_HAIKU)
1825 snprintf(tunname,
sizeof(tunname),
"/dev/%s%s%d", dev, sep,
i);
1826 snprintf(dynamic_name,
sizeof(dynamic_name),
"%s%s%d", dev, sep,
i);
1827 if ((tt->fd = open(tunname, O_RDWR)) > 0)
1829 dynamic_opened =
true;
1834 if (!dynamic_opened)
1836 msg(
M_FATAL,
"Cannot allocate TUN/TAP dev dynamically");
1844 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
1848 if (!dynamic_opened)
1851 if (if_nametoindex(dev) > 0)
1853 msg(
M_INFO,
"TUN/TAP device %s exists previously, keep at program end", dev);
1857 if ((tt->fd = open(tunname, O_RDWR)) < 0)
1859 msg(
M_ERR,
"Cannot open TUN/TAP dev %s", tunname);
1865 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
1872#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1874open_tun_dco_generic(
const char *dev,
const char *dev_type,
struct tuntap *tt,
1877 char dynamic_name[256];
1878 bool dynamic_opened =
false;
1888 if (strcmp(dev,
"tun") == 0)
1890 for (
int i = 0;
i < 256; ++
i)
1892 snprintf(dynamic_name,
sizeof(dynamic_name),
"%s%d", dev,
i);
1896 dynamic_opened =
true;
1897 msg(
M_INFO,
"DCO device %s opened", dynamic_name);
1901 else if (ret == -EPERM)
1906 if (!dynamic_opened)
1908 msg(
M_FATAL,
"Cannot allocate DCO dev dynamically");
1922 msg(
M_INFO,
"DCO device %s already exists, won't be destroyed at shutdown", dev);
1927 msg(
M_ERR,
"Cannot open DCO device %s: %s (%d)", dev, strerror(-ret), ret);
1931 msg(
M_INFO,
"DCO device %s opened", dev);
1940#if !(defined(_WIN32) || defined(TARGET_SOLARIS))
1942close_tun_generic(
struct tuntap *tt)
1954#if defined(TARGET_ANDROID)
1956open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
1959#define ANDROID_TUNNAME "vpnservice-tun"
1964 int oldtunfd = tt->fd;
1970 management_android_control(
management,
"DNS6SERVER",
1976 management_android_control(
management,
"DNSSERVER",
1988 buf_printf(&buf,
"%s %d",
tt->options.http_proxy,
tt->options.http_proxy_port);
2018 msg(
M_ERR,
"ERROR: Cannot open TUN");
2045#elif defined(TARGET_LINUX)
2047#ifndef HAVE_LINUX_SOCKIOS_H
2048#error header file linux/sockios.h required
2054open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *
tt,
2059 if (tun_dco_enabled(tt))
2061 open_tun_dco_generic(dev, dev_type, tt, ctx);
2068 const char *node = dev_node;
2071 node =
"/dev/net/tun";
2077 if ((tt->fd = open(node, O_RDWR)) < 0)
2079 msg(
M_ERR,
"ERROR: Cannot open TUN/TAP dev %s", node);
2086 ifr.ifr_flags = IFF_NO_PI;
2088#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2089 ifr.ifr_flags |= IFF_ONE_QUEUE;
2097 ifr.ifr_flags |= IFF_TUN;
2101 ifr.ifr_flags |= IFF_TAP;
2105 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device", dev);
2111 if (strcmp(dev,
"tun") && strcmp(dev,
"tap"))
2120 if (ioctl(tt->fd, TUNSETIFF, (
void *)&ifr) < 0)
2122 msg(
M_ERR,
"ERROR: Cannot ioctl TUNSETIFF %s", dev);
2125 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2130#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2133 struct ifreq netifr;
2136 if ((ctl_fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
2139 strncpynt(netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
2140 netifr.ifr_qlen = tt->
options.txqueuelen;
2141 if (ioctl(ctl_fd, SIOCSIFTXQLEN, (
void *)&netifr) >= 0)
2147 msg(
M_WARN |
M_ERRNO,
"Note: Cannot set tx queue length on %s", ifr.ifr_name);
2153 msg(
M_WARN |
M_ERRNO,
"Note: Cannot open control socket on %s", ifr.ifr_name);
2168open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2176#ifdef ENABLE_FEATURE_TUN_PERSIST
2180#define TUNSETGROUP _IOW('T', 206, int)
2184tuncfg(
const char *dev,
const char *dev_type,
const char *dev_node,
int persist_mode,
2195 open_tun(dev, dev_type, dev_node, tt, ctx);
2196 if (ioctl(tt->fd, TUNSETPERSIST, persist_mode) < 0)
2198 msg(
M_ERR,
"Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
2200 if (username != NULL)
2206 msg(
M_ERR,
"Cannot get user entry for %s", username);
2210 msg(
M_ERR,
"Cannot ioctl TUNSETOWNER(%s) %s", username, dev);
2213 if (groupname != NULL)
2219 msg(
M_ERR,
"Cannot get group entry for %s", groupname);
2223 msg(
M_ERR,
"Cannot ioctl TUNSETGROUP(%s) %s", groupname, dev);
2227 msg(
M_INFO,
"Persist state set to: %s", (persist_mode ?
"ON" :
"OFF"));
2237#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
2238 if (tun_dco_enabled(tt))
2243 close_tun_generic(tt);
2250 return write(tt->fd, buf, len);
2256 return read(tt->fd, buf, len);
2259#elif defined(TARGET_SOLARIS)
2262#error I need the symbol TUNNEWPPA from net/if_tun.h
2266open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2269 int if_fd = -1, ip_muxid = -1, arp_muxid = -1, arp_fd = -1, ppa = -1;
2272 const char *ip_node = NULL, *arp_node = NULL;
2273 const char *dev_tuntap_type;
2275 struct strioctl strioc_if, strioc_ppa;
2285 ip_node =
"/dev/udp";
2288 dev_node =
"/dev/tun";
2290 dev_tuntap_type =
"tun";
2291 link_type = I_PLINK;
2295 ip_node =
"/dev/udp";
2298 dev_node =
"/dev/tap";
2300 arp_node = dev_node;
2301 dev_tuntap_type =
"tap";
2302 link_type = I_PLINK;
2306 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device", dev);
2309 if ((tt->ip_fd = open(ip_node, O_RDWR, 0)) < 0)
2311 msg(
M_ERR,
"Can't open %s", ip_node);
2314 if ((tt->fd = open(dev_node, O_RDWR, 0)) < 0)
2316 msg(
M_ERR,
"Can't open %s", dev_node);
2324 while (*ptr && !isdigit((
int)*ptr))
2332 strioc_ppa.ic_cmd = TUNNEWPPA;
2333 strioc_ppa.ic_timout = 0;
2334 strioc_ppa.ic_len =
sizeof(ppa);
2335 strioc_ppa.ic_dp = (
char *)&ppa;
2339 bool found_one =
false;
2340 while (!found_one && ppa < 64)
2342 int new_ppa = ioctl(tt->fd, I_STR, &strioc_ppa);
2345 msg(
M_INFO,
"open_tun: got dynamic interface '%s%d'", dev_tuntap_type, new_ppa);
2350 if (errno != EEXIST)
2352 msg(
M_ERR,
"open_tun: unexpected error trying to find free %s interface",
2359 msg(
M_ERR,
"open_tun: could not find free %s interface, give up.", dev_tuntap_type);
2364 if ((ppa = ioctl(tt->fd, I_STR, &strioc_ppa)) < 0)
2366 msg(
M_ERR,
"Can't assign PPA for new interface (%s%d)", dev_tuntap_type, ppa);
2370 if ((if_fd = open(dev_node, O_RDWR, 0)) < 0)
2372 msg(
M_ERR,
"Can't open %s (2)", dev_node);
2375 if (ioctl(if_fd, I_PUSH,
"ip") < 0)
2377 msg(
M_ERR,
"Can't push IP module");
2383 if (ioctl(if_fd, IF_UNITSEL, (
char *)&ppa) < 0)
2385 msg(
M_ERR,
"Can't set PPA %d", ppa);
2392 snprintf(tt->
actual_name, 32,
"%s%d", dev_tuntap_type, ppa);
2396 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2403 if (ioctl(if_fd, SIOCSLIFNAME, &ifr) < 0)
2405 msg(
M_ERR,
"Can't set PPA %d", ppa);
2407 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2412 if (ioctl(if_fd, I_PUSH,
"arp") < 0)
2414 msg(
M_ERR,
"Can't push ARP module");
2420 if (ioctl(tt->ip_fd, I_POP, NULL) < 0)
2426 if (ioctl(tt->ip_fd, I_PUSH,
"arp") < 0)
2428 msg(
M_ERR,
"Can't push ARP module");
2432 if ((arp_fd = open(arp_node, O_RDWR, 0)) < 0)
2434 msg(
M_ERR,
"Can't open %s", arp_node);
2437 if (ioctl(arp_fd, I_PUSH,
"arp") < 0)
2439 msg(
M_ERR,
"Can't push ARP module");
2443 strioc_if.ic_cmd = SIOCSLIFNAME;
2444 strioc_if.ic_timout = 0;
2445 strioc_if.ic_len =
sizeof(ifr);
2446 strioc_if.ic_dp = (
char *)𝔦
2447 if (ioctl(arp_fd, I_STR, &strioc_if) < 0)
2449 msg(
M_ERR,
"Can't set ifname to arp");
2453 if ((ip_muxid = ioctl(tt->ip_fd, link_type, if_fd)) < 0)
2455 msg(
M_ERR,
"Can't link %s device to IP", dev_tuntap_type);
2460 if ((arp_muxid = ioctl(tt->ip_fd, link_type, arp_fd)) < 0)
2462 msg(
M_ERR,
"Can't link %s device to ARP", dev_tuntap_type);
2469 ifr.lifr_ip_muxid = ip_muxid;
2472 ifr.lifr_arp_muxid = arp_muxid;
2475 if (ioctl(tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0)
2479 ioctl(tt->ip_fd, I_PUNLINK, arp_muxid);
2481 ioctl(tt->ip_fd, I_PUNLINK, ip_muxid);
2482 msg(
M_ERR,
"Can't set multiplexor id");
2493solaris_close_tun(
struct tuntap *tt)
2511 if (ioctl(tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0)
2516 if (ioctl(tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0)
2523 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0)
2529 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0)
2553 solaris_close_tun(tt);
2562solaris_error_close(
struct tuntap *tt,
const struct env_set *
es,
const char *actual,
2588 sbuf.buf = (
char *)buf;
2589 return putmsg(tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
2599 sbuf.buf = (
char *)buf;
2600 return getmsg(tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
2603#elif defined(TARGET_OPENBSD)
2606open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2609 open_tun_generic(dev, dev_type, dev_node, tt);
2614 struct tuninfo info;
2616 if (ioctl(tt->fd, TUNGIFINFO, &info) < 0)
2622 info.flags |= IFF_MULTICAST;
2625 if (ioctl(tt->fd, TUNSIFINFO, &info) < 0)
2650 close_tun_generic(tt);
2662 close_tun_generic(tt);
2674 return write_tun_header(tt, buf, len);
2680 return read_tun_header(tt, buf, len);
2683#elif defined(TARGET_NETBSD)
2700open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2707 if (strcmp(dev,
"tap") == 0)
2710 if ((tt->fd = open(
"/dev/tap", O_RDWR)) < 0)
2712 msg(
M_FATAL,
"Cannot allocate NetBSD TAP dev dynamically");
2714 if (ioctl(tt->fd, TAPGIFNAME, (
void *)&ifr) < 0)
2716 msg(
M_FATAL,
"Cannot query NetBSD TAP device name");
2720 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2729 open_tun_generic(dev, dev_type, dev_node, tt);
2734 int i = IFF_POINTOPOINT | IFF_MULTICAST;
2735 ioctl(tt->fd, TUNSIFMODE, &
i);
2737 ioctl(tt->fd, TUNSLMODE, &
i);
2742 if (ioctl(tt->fd, TUNSIFHEAD, &
i) < 0)
2763 close_tun_generic(tt);
2775 close_tun_generic(tt);
2785netbsd_modify_read_write_return(
int len)
2789 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
2810 type = htonl(AF_INET6);
2814 type = htonl(AF_INET);
2817 iv[0].iov_base = (
char *)&type;
2818 iv[0].iov_len =
sizeof(type);
2819 iv[1].iov_base = buf;
2820 iv[1].iov_len = len;
2822 return netbsd_modify_read_write_return(writev(tt->fd, iv, 2));
2826 return write(tt->fd, buf, len);
2838 iv[0].iov_base = (
char *)&type;
2839 iv[0].iov_len =
sizeof(type);
2840 iv[1].iov_base = buf;
2841 iv[1].iov_len = len;
2843 return netbsd_modify_read_write_return(readv(tt->fd, iv, 2));
2847 return read(tt->fd, buf, len);
2851#elif defined(TARGET_FREEBSD)
2854freebsd_modify_read_write_return(
int len)
2858 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
2867open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2870 if (tun_dco_enabled(tt))
2872 open_tun_dco_generic(dev, dev_type, tt, ctx);
2876 open_tun_generic(dev, dev_type, dev_node, tt);
2881 int i = IFF_POINTOPOINT | IFF_MULTICAST;
2884 i = IFF_BROADCAST | IFF_MULTICAST;
2887 if (ioctl(tt->fd, TUNSIFMODE, &
i) < 0)
2894 if (ioctl(tt->fd, TUNSIFHEAD, &
i) < 0)
2916 close_tun_generic(tt);
2929 close_tun_generic(tt);
2947 iph = (
struct ip *)buf;
2951 type = htonl(AF_INET6);
2955 type = htonl(AF_INET);
2958 iv[0].iov_base = (
char *)&type;
2959 iv[0].iov_len =
sizeof(type);
2960 iv[1].iov_base = buf;
2961 iv[1].iov_len = len;
2963 return freebsd_modify_read_write_return(writev(tt->fd, iv, 2));
2967 return write(tt->fd, buf, len);
2979 iv[0].iov_base = (
char *)&type;
2980 iv[0].iov_len =
sizeof(type);
2981 iv[1].iov_base = buf;
2982 iv[1].iov_len = len;
2984 return freebsd_modify_read_write_return(readv(tt->fd, iv, 2));
2988 return read(tt->fd, buf, len);
2992#elif defined(TARGET_DRAGONFLY)
2995dragonfly_modify_read_write_return(
int len)
2999 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
3008open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3011 open_tun_generic(dev, dev_type, dev_node, tt);
3018 ioctl(tt->fd, TUNSLMODE, &
i);
3020 ioctl(tt->fd, TUNSIFHEAD, &
i);
3029 close_tun_generic(tt);
3042 iph = (
struct ip *)buf;
3046 type = htonl(AF_INET6);
3050 type = htonl(AF_INET);
3053 iv[0].iov_base = (
char *)&type;
3054 iv[0].iov_len =
sizeof(type);
3055 iv[1].iov_base = buf;
3056 iv[1].iov_len = len;
3058 return dragonfly_modify_read_write_return(writev(tt->fd, iv, 2));
3062 return write(tt->fd, buf, len);
3074 iv[0].iov_base = (
char *)&type;
3075 iv[0].iov_len =
sizeof(type);
3076 iv[1].iov_base = buf;
3077 iv[1].iov_len = len;
3079 return dragonfly_modify_read_write_return(readv(tt->fd, iv, 2));
3083 return read(tt->fd, buf, len);
3087#elif defined(TARGET_DARWIN)
3109utun_open_helper(
struct ctl_info ctlInfo,
int utunnum)
3111 struct sockaddr_ctl sc;
3114 fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
3118 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (socket(SYSPROTO_CONTROL))", utunnum);
3122 if (ioctl(fd, CTLIOCGINFO, &ctlInfo) == -1)
3125 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (ioctl(CTLIOCGINFO))", utunnum);
3130 sc.sc_id = ctlInfo.ctl_id;
3131 sc.sc_len =
sizeof(sc);
3132 sc.sc_family = AF_SYSTEM;
3133 sc.ss_sysaddr = AF_SYS_CONTROL;
3135 sc.sc_unit = utunnum + 1;
3141 if (connect(fd, (
struct sockaddr *)&sc,
sizeof(sc)) < 0)
3143 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (connect(AF_SYS_CONTROL))", utunnum);
3155open_darwin_utun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt)
3157 struct ctl_info ctlInfo;
3161 socklen_t utunname_len =
sizeof(utunname);
3165 if (dev_node && (strcmp(
"utun", dev_node) != 0))
3167 if (sscanf(dev_node,
"utun%d", &utunnum) != 1)
3170 "Cannot parse 'dev-node %s' please use 'dev-node utunX'"
3171 "to use a utun device number X",
3178 if (strlcpy(ctlInfo.ctl_name, UTUN_CONTROL_NAME,
sizeof(ctlInfo.ctl_name))
3179 >=
sizeof(ctlInfo.ctl_name))
3181 msg(
M_ERR,
"Opening utun: UTUN_CONTROL_NAME too long");
3187 for (utunnum = 0; utunnum < 255; utunnum++)
3191 ASSERT(snprintf(ifname,
sizeof(ifname),
"utun%d", utunnum) > 0);
3192 if (if_nametoindex(ifname))
3196 fd = utun_open_helper(ctlInfo, utunnum);
3207 fd = utun_open_helper(ctlInfo, utunnum);
3219 if (getsockopt(fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, utunname, &utunname_len))
3226 msg(
M_INFO,
"Opened utun device %s", utunname);
3231open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3235 if ((!dev_node && tt->
type ==
DEV_TYPE_TUN) || (dev_node && !strncmp(dev_node,
"utun", 4)))
3241 msg(
M_FATAL,
"Cannot use utun devices with --dev-type %s",
3247 open_darwin_utun(dev, dev_type, dev_node, tt);
3254 msg(
M_INFO,
"Failed to open utun device. Falling back to /dev/tun device");
3255 open_tun_generic(dev, dev_type, NULL, tt);
3271 if (dev_node && strcmp(dev_node,
"tun") == 0)
3276 open_tun_generic(dev, dev_type, dev_node, tt);
3292 argv_printf(&
argv,
"%s delete -inet6 %s", ROUTE_PATH, ifconfig_ipv6_local);
3297 close_tun_generic(tt);
3308 return write_tun_header(tt, buf, len);
3312 return write(tt->fd, buf, len);
3321 return read_tun_header(tt, buf, len);
3325 return read(tt->fd, buf, len);
3329#elif defined(TARGET_AIX)
3332open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3336 char dynamic_name[20];
3341 msg(
M_FATAL,
"no support for 'tun' devices on AIX");
3344 if (strncmp(dev,
"tap", 3) != 0 || dev_node)
3347 "'--dev %s' and/or '--dev-node' not supported on AIX, use '--dev tap0', 'tap1', etc.",
3351 if (strcmp(dev,
"tap") == 0)
3354 for (
i = 0;
i < 99;
i++)
3356 snprintf(tunname,
sizeof(tunname),
"/dev/tap%d",
i);
3357 if (access(tunname, F_OK) < 0 && errno == ENOENT)
3364 msg(
M_FATAL,
"cannot find unused tap device");
3367 snprintf(dynamic_name,
sizeof(dynamic_name),
"tap%d",
i);
3380 msg(
M_FATAL,
"TAP device name must be '--dev tapNNNN'");
3383 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
3388 if (access(tunname, F_OK) < 0 && errno == ENOENT)
3407 if ((tt->fd = open(tunname, O_RDWR)) < 0)
3409 msg(
M_ERR,
"Cannot open TAP device '%s'", tunname);
3414 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
3441 close_tun_generic(tt);
3454 return write(tt->fd, buf, len);
3460 return read(tt->fd, buf, len);
3463#elif defined(_WIN32)
3494 dmsg(
D_WIN32_IO,
"WIN32 I/O: TAP Read immediate return [%d,%d]", (
int)len,
3499 err = GetLastError();
3500 if (err == ERROR_IO_PENDING)
3512 dmsg(
D_WIN32_IO,
"WIN32 I/O: TAP Read error [%d] : %s", (
int)len,
3554 err = GetLastError();
3555 if (err == ERROR_IO_PENDING)
3587 err = GetLastError();
3605 HDEVINFO dev_info_set;
3611 SetupDiGetClassDevsEx(&
GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
3612 if (dev_info_set == INVALID_HANDLE_VALUE)
3614 err = GetLastError();
3615 msg(
M_FATAL,
"Error [%u] opening device information set key: %s", (
unsigned int)err,
3620 for (DWORD
i = 0;; ++
i)
3622 SP_DEVINFO_DATA device_info_data;
3625 char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3627 char device_instance_id[256];
3631 ULONG dev_interface_list_size;
3634 ZeroMemory(&device_info_data,
sizeof(SP_DEVINFO_DATA));
3635 device_info_data.cbSize =
sizeof(SP_DEVINFO_DATA);
3636 res = SetupDiEnumDeviceInfo(dev_info_set,
i, &device_info_data);
3639 if (GetLastError() == ERROR_NO_MORE_ITEMS)
3649 dev_key = SetupDiOpenDevRegKey(dev_info_set, &device_info_data, DICS_FLAG_GLOBAL, 0,
3650 DIREG_DRV, KEY_QUERY_VALUE);
3651 if (dev_key == INVALID_HANDLE_VALUE)
3658 status = RegQueryValueEx(dev_key, net_cfg_instance_id_string, NULL, &data_type,
3660 if (
status != ERROR_SUCCESS)
3665 len =
sizeof(device_instance_id);
3666 res = SetupDiGetDeviceInstanceId(dev_info_set, &device_info_data, device_instance_id, len,
3673 cr = CM_Get_Device_Interface_List_Size(&dev_interface_list_size,
3675 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3677 if (cr != CR_SUCCESS)
3682 char *dev_interface_list =
gc_malloc(dev_interface_list_size,
false,
gc);
3684 dev_interface_list, dev_interface_list_size,
3685 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3686 if (cr != CR_SUCCESS)
3691 char *dev_if = dev_interface_list;
3694 while (strlen(dev_if) > 0)
3712 last->
next = dev_iif;
3716 dev_if += strlen(dev_if) + 1;
3720 RegCloseKey(dev_key);
3723 SetupDiDestroyDeviceInfoList(dev_info_set);
3738 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ADAPTER_KEY, 0, KEY_READ, &adapter_key);
3740 if (
status != ERROR_SUCCESS)
3742 msg(
M_FATAL,
"Error opening registry key: %s", ADAPTER_KEY);
3748 char enum_name[256];
3749 char unit_string[256];
3751 char component_id_string[] =
"ComponentId";
3752 char component_id[256];
3753 char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3754 BYTE net_cfg_instance_id[256];
3757 len =
sizeof(enum_name);
3758 status = RegEnumKeyEx(adapter_key,
i, enum_name, &len, NULL, NULL, NULL, NULL);
3759 if (
status == ERROR_NO_MORE_ITEMS)
3763 else if (
status != ERROR_SUCCESS)
3765 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s", ADAPTER_KEY);
3768 snprintf(unit_string,
sizeof(unit_string),
"%s\\%s", ADAPTER_KEY, enum_name);
3770 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, unit_string, 0, KEY_READ, &unit_key);
3772 if (
status != ERROR_SUCCESS)
3778 len =
sizeof(component_id);
3779 status = RegQueryValueEx(unit_key, component_id_string, NULL, &data_type,
3780 (LPBYTE)component_id, &len);
3782 if (
status != ERROR_SUCCESS || data_type != REG_SZ)
3784 dmsg(
D_REGISTRY,
"Error opening registry key: %s\\%s", unit_string,
3785 component_id_string);
3789 len =
sizeof(net_cfg_instance_id);
3790 status = RegQueryValueEx(unit_key, net_cfg_instance_id_string, NULL, &data_type,
3791 net_cfg_instance_id, &len);
3793 if (
status == ERROR_SUCCESS && data_type == REG_SZ)
3797 if (strcasecmp(component_id, TAP_WIN_COMPONENT_ID) == 0
3798 || strcasecmp(component_id,
"root\\" TAP_WIN_COMPONENT_ID) == 0)
3802 else if (strcasecmp(component_id,
"ovpn-dco") == 0)
3830 RegCloseKey(unit_key);
3835 RegCloseKey(adapter_key);
3843 HKEY network_connections_key;
3849 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ,
3850 &network_connections_key);
3852 if (
status != ERROR_SUCCESS)
3854 msg(
M_FATAL,
"Error opening registry key: %s", NETWORK_CONNECTIONS_KEY);
3859 char enum_name[256];
3860 char connection_string[256];
3861 HKEY connection_key;
3862 WCHAR name_data[256];
3864 const WCHAR name_string[] = L
"Name";
3866 len =
sizeof(enum_name);
3867 status = RegEnumKeyEx(network_connections_key,
i, enum_name, &len, NULL, NULL, NULL, NULL);
3868 if (
status == ERROR_NO_MORE_ITEMS)
3872 else if (
status != ERROR_SUCCESS)
3874 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s", NETWORK_CONNECTIONS_KEY);
3877 snprintf(connection_string,
sizeof(connection_string),
"%s\\%s\\Connection",
3878 NETWORK_CONNECTIONS_KEY, enum_name);
3880 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, connection_string, 0, KEY_READ, &connection_key);
3882 if (
status != ERROR_SUCCESS)
3884 dmsg(
D_REGISTRY,
"Error opening registry key: %s", connection_string);
3888 len =
sizeof(name_data);
3889 status = RegQueryValueExW(connection_key, name_string, NULL, &name_type,
3890 (LPBYTE)name_data, &len);
3892 if (
status != ERROR_SUCCESS || name_type != REG_SZ)
3894 dmsg(
D_REGISTRY,
"Error opening registry key: %s\\%s\\%ls", NETWORK_CONNECTIONS_KEY,
3895 connection_string, name_string);
3904 n = WideCharToMultiByte(CP_UTF8, 0, name_data, -1, NULL, 0, NULL, NULL);
3906 WideCharToMultiByte(CP_UTF8, 0, name_data, -1,
name, n, NULL, NULL);
3921 RegCloseKey(connection_key);
3926 RegCloseKey(network_connections_key);
3938 const unsigned int mask = 3;
3939 const char *err = NULL;
3941 if (local == remote)
3943 err =
"must be different";
3946 if ((local & (~mask)) != (remote & (~mask)))
3949 "must exist within the same 255.255.255.252 subnet. This is a limitation of --dev tun when used with the TAP-WIN32 driver";
3952 if ((local & mask) == 0 || (local & mask) == 3 || (remote & mask) == 0 || (remote & mask) == 3)
3955 "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";
3964 "There is a problem in your selection of --ifconfig endpoints [local=%s, remote=%s]. The local and remote VPN endpoints %s. Try '" PACKAGE
3965 " --show-valid-subnets' option for more info.",
3976 printf(
"On Windows, point-to-point IP support (i.e. --dev tun)\n");
3977 printf(
"is emulated by the TAP-Windows driver. The major limitation\n");
3978 printf(
"imposed by this approach is that the --ifconfig local and\n");
3979 printf(
"remote endpoints must be part of the same 255.255.255.252\n");
3980 printf(
"subnet. The following list shows examples of endpoint\n");
3981 printf(
"pairs which satisfy this requirement. Only the final\n");
3982 printf(
"component of the IP address pairs is at issue.\n\n");
3983 printf(
"As an example, the following option would be correct:\n");
3984 printf(
" --ifconfig 10.7.0.5 10.7.0.6 (on host A)\n");
3985 printf(
" --ifconfig 10.7.0.6 10.7.0.5 (on host B)\n");
3986 printf(
"because [5,6] is part of the below list.\n\n");
3988 for (
i = 0;
i < 256;
i += 4)
3990 printf(
"[%3d,%3d] ",
i + 1,
i + 2);
4008 bool warn_panel_null =
false;
4009 bool warn_panel_dup =
false;
4010 bool warn_tap_dup =
false;
4021 msg(msglev,
"Available adapters [name, GUID, driver]:");
4041 warn_panel_dup =
true;
4043 else if (links == 0)
4047 warn_panel_null =
true;
4048 msg(msglev,
"[NULL] %s", tr->
guid);
4057 if (tr != tr1 && !strcmp(tr->
guid, tr1->
guid))
4059 warn_tap_dup =
true;
4067 msg(warnlev,
"WARNING: Some TAP-Windows adapters have duplicate GUIDs");
4073 "WARNING: Some TAP-Windows adapters have duplicate links from the Network Connections control panel");
4076 if (warn_panel_null)
4079 "WARNING: Some TAP-Windows adapters have no link from the Network Connections control panel");
4142 msg(
M_FATAL,
"There are no TAP-Windows or ovpn-dco adapters "
4143 "on this system. You should be able to create an adapter "
4144 "by using tapctl.exe utility.");
4154 const struct tap_reg *tap_reg_src,
4204 if (windows_driver !=
NULL)
4233 ASSERT(actual_name_size > 0);
4279const IP_ADAPTER_INFO *
4283 IP_ADAPTER_INFO *pi = NULL;
4286 if ((
status = GetAdaptersInfo(NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4288 msg(
M_INFO,
"GetAdaptersInfo #1 failed (status=%u) : %s", (
unsigned int)
status,
4293 pi = (PIP_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4294 if ((
status = GetAdaptersInfo(pi, &size)) != NO_ERROR)
4296 msg(
M_INFO,
"GetAdaptersInfo #2 failed (status=%u) : %s", (
unsigned int)
status,
4304const IP_PER_ADAPTER_INFO *
4308 IP_PER_ADAPTER_INFO *pi = NULL;
4313 if ((
status = GetPerAdapterInfo(index, NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4315 msg(
M_INFO,
"GetPerAdapterInfo #1 failed (status=%u) : %s", (
unsigned int)
status,
4320 pi = (PIP_PER_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4321 if ((
status = GetPerAdapterInfo((ULONG)index, pi, &size)) == ERROR_SUCCESS)
4327 msg(
M_INFO,
"GetPerAdapterInfo #2 failed (status=%u) : %s", (
unsigned int)
status,
4335static const IP_INTERFACE_INFO *
4339 IP_INTERFACE_INFO *ii = NULL;
4342 if ((
status = GetInterfaceInfo(NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)
4344 msg(
M_INFO,
"GetInterfaceInfo #1 failed (status=%u) : %s", (
unsigned int)
status,
4349 ii = (PIP_INTERFACE_INFO)
gc_malloc(size,
false,
gc);
4350 if ((
status = GetInterfaceInfo(ii, &size)) == NO_ERROR)
4356 msg(
M_INFO,
"GetInterfaceInfo #2 failed (status=%u) : %s", (
unsigned int)
status,
4363static const IP_ADAPTER_INDEX_MAP *
4370 for (
i = 0;
i < list->NumAdapters; ++
i)
4372 const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[
i];
4373 if (index == inter->Index)
4387const IP_ADAPTER_INFO *
4392 const IP_ADAPTER_INFO *a;
4395 for (a = ai; a != NULL; a = a->Next)
4397 if (a->Index == index)
4406const IP_ADAPTER_INFO *
4418 const IP_ADDR_STRING *ip = &ai->IpAddressList;
4442 const IP_ADDR_STRING *iplist = &ai->IpAddressList;
4452 iplist = iplist->Next;
4458 const char *ip_str = iplist->IpAddress.String;
4459 const char *netmask_str = iplist->IpMask.String;
4460 bool succeed1 =
false;
4461 bool succeed2 =
false;
4463 if (ip_str && netmask_str && strlen(ip_str) && strlen(netmask_str))
4465 *ip =
getaddr(getaddr_flags, ip_str, 0, &succeed1, NULL);
4466 *netmask =
getaddr(getaddr_flags, netmask_str, 0, &succeed2, NULL);
4467 ret = (succeed1 ==
true && succeed2 ==
true);
4480 in_addr_t ip_adapter = 0;
4481 in_addr_t netmask_adapter = 0;
4483 return (
status && ip_adapter == ip && netmask_adapter == netmask);
4491const IP_ADAPTER_INFO *
4517 for (
i = 0;
i < n; ++
i)
4519 in_addr_t ip, netmask;
4554 if (highest_netmask)
4556 *highest_netmask = 0;
4562 for (
i = 0;
i < n; ++
i)
4564 in_addr_t adapter_ip, adapter_netmask;
4567 if (adapter_ip && adapter_netmask
4568 && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))
4570 if (highest_netmask && adapter_netmask > *highest_netmask)
4572 *highest_netmask = adapter_netmask;
4587 in_addr_t highest_netmask = 0;
4588 int lowest_metric = INT_MAX;
4603 if (first || hn > highest_netmask)
4605 highest_netmask = hn;
4608 lowest_metric = metric;
4617 else if (hn == highest_netmask)
4623 if (metric >= 0 && metric < lowest_metric)
4626 lowest_metric = metric;
4633 dmsg(
D_ROUTE_DEBUG,
"DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d metric=%d",
4635 count ? *count : -1, lowest_metric);
4644 *netmask = highest_netmask;
4656#define DHCP_STATUS_UNDEF 0
4657#define DHCP_STATUS_ENABLED 1
4658#define DHCP_STATUS_DISABLED 2
4671 if (ai->DhcpEnabled)
4697 const IP_ADDR_STRING *ip = &a->IpAddressList;
4701 const DWORD
context = ip->Context;
4705 msg(
M_INFO,
"Successfully deleted previously set dynamic IP/netmask: %s/%s",
4706 ip->IpAddress.String, ip->IpMask.String);
4710 const char *empty =
"0.0.0.0";
4711 if (strcmp(ip->IpAddress.String, empty) || strcmp(ip->IpMask.String, empty))
4714 "NOTE: could not delete previously set dynamic IP/netmask: %s/%s (status=%u)",
4715 ip->IpAddress.String, ip->IpMask.String, (
unsigned int)
status);
4733 swprintf(wbuf,
SIZE(wbuf), L
"\\DEVICE\\TCPIP_%hs", guid);
4734 if (GetAdapterIndex(wbuf, &aindex) != NO_ERROR)
4740 index = (DWORD)aindex;
4755 if (!strcmp(guid,
list->AdapterName))
4757 index =
list->Index;
4778 msg(
M_INFO,
"NOTE: could not get adapter index for %s", guid);
4792 buf_printf(&out,
"%s", ip->IpAddress.String);
4793 if (
strlen(ip->IpMask.String))
4846 msg(msglev,
"SYSTEM ADAPTER LIST");
4849 const IP_ADAPTER_INFO *a;
4852 for (a = ai; a != NULL; a = a->Next)
4875 msg(
M_ERR,
"Error: init SA failed");
4878 status = SetKernelObjectSecurity(hand, DACL_SECURITY_INFORMATION, &
sa.sd);
4881 msg(
M_ERRNO,
"Error: SetKernelObjectSecurity failed on %s", device_path);
4885 msg(
M_INFO |
M_NOPREFIX,
"TAP-Windows device: %s [Non-admin access allowed]", device_path);
4895 const char *device_guid = NULL;
4897 uint8_t actual_buffer[256];
4898 char device_path[256];
4910 msg(
M_FATAL,
"TAP-Windows adapter '%s' not found", dev_node);
4914 snprintf(device_path,
sizeof(device_path),
"%s%s%s", USERMODEDEVICEDIR, device_guid,
4917 hand = CreateFile(device_path, MAXIMUM_ALLOWED, 0,
4918 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
4920 if (hand == INVALID_HANDLE_VALUE)
4922 msg(
M_ERR,
"CreateFile failed on TAP device: %s", device_path);
4930 int device_number = 0;
4944 snprintf(device_path,
sizeof(device_path),
"%s%s%s", USERMODEDEVICEDIR, device_guid,
4947 hand = CreateFile(device_path, MAXIMUM_ALLOWED, 0,
4948 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
4950 if (hand == INVALID_HANDLE_VALUE)
4952 msg(
M_WARN,
"CreateFile failed on TAP device: %s", device_path);
4978 DWORD
status = IpReleaseAddress((IP_ADAPTER_INDEX_MAP *)inter);
4987 "NOTE: Release of DHCP-assigned IP address lease on TAP-Windows adapter failed: %s (code=%u)",
5019 DWORD
status = IpRenewAddress((IP_ADAPTER_INDEX_MAP *)inter);
5028 "WARNING: Failed to renew DHCP IP address lease on TAP-Windows adapter: %s (code=%u)",
5054 for (
i = 0;
i < n; ++
i)
5068 msg(msglevel,
"%s: command failed", prefix);
5081 const char err[] =
"ERROR: Windows ipconfig command failed";
5106 const char *ip_str = src->IpAddress.String;
5108 bool succeed =
false;
5114 if (!ip_str || !strlen(ip_str))
5119 ip =
getaddr(getaddr_flags, ip_str, 0, &succeed, NULL);
5133 msg(
M_INFO,
"ip_addr_string_to_array [%d]", *dest_len);
5134 for (
i = 0;
i < *dest_len; ++
i)
5147 int a2len =
SIZE(a2);
5157 for (
i = 0;
i < a1len; ++
i)
5175 for (
i = 0;
i < len; ++
i)
5201 for (
int i = 0;
i < addr_len; ++
i)
5203 const char *fmt = (
i == 0) ?
"%s%s interface ipv6 set dns %lu static %s"
5204 :
"%s%s interface ipv6 add dns %lu %s";
5221 const IP_ADDR_STRING *current, DWORD adapter_index,
const bool test_first)
5225 bool delete_first =
false;
5226 bool is_dns = !strcmp(type,
"dns");
5233 delete_first =
true;
5238 delete_first =
true;
5253 for (
i = 0;
i < addr_len; ++
i)
5257 const char *fmt = count ?
"%s%s interface ip add %s %lu %s"
5258 :
"%s%s interface ip set %s %lu static %s";
5275 msg(
M_INFO,
"NETSH: %lu %s %s [already set]", adapter_index, type,
5293 dest[0].Next = NULL;
5298 dest[0].Next = &dest[1];
5299 dest[1].Next = NULL;
5305 const in_addr_t netmask,
const unsigned int flags)
5309 const IP_ADAPTER_INFO *ai = NULL;
5310 const IP_PER_ADAPTER_INFO *pai = NULL;
5323 msg(
M_INFO,
"NETSH: %lu %s/%s [already set]", adapter_index,
5340 IP_ADDR_STRING wins[2];
5346 if (ai && ai->HaveWins)
5392 msg(
M_NONFATAL,
"TUN: enabling dhcp using service failed: %s [status=%u if_index=%d]",
5397 msg(
M_INFO,
"DHCP enabled on interface %d using service",
dhcp.iface.index);
5411 MIB_IPINTERFACE_ROW ipiface;
5412 InitializeIpInterfaceEntry(&ipiface);
5413 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
5414 ipiface.Family = family;
5415 ipiface.InterfaceIndex = iface_index;
5416 if (family == AF_INET6 && mtu < 1280)
5419 "NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
5422 err = GetIpInterfaceEntry(&ipiface);
5423 if (err == NO_ERROR)
5425 if (family == AF_INET)
5427 ipiface.SitePrefixLength = 0;
5429 ipiface.NlMtu = mtu;
5430 err = SetIpInterfaceEntry(&ipiface);
5433 if (err != NO_ERROR)
5435 msg(
M_WARN,
"TUN: Setting %s mtu failed: %s [status=%lu if_index=%d]", family_name,
5440 msg(
M_INFO,
"%s MTU set to %d on interface %d using SetIpInterfaceEntry()", family_name,
5482 return BSTR(&actual);
5496 tt->standby_iter = 0;
5508 msg(
M_INFO,
"NOTE: now trying netsh (this may take some time)");
5531 msg(
M_WARN,
"write_dhcp_u8: buffer overflow building DHCP options");
5541 const unsigned int len,
bool *error)
5551 msg(
M_WARN,
"write_dhcp_u32_array: buffer overflow building DHCP options");
5557 msg(
M_WARN,
"write_dhcp_u32_array: size (%d) must be > 0 and <= 255", size);
5562 for (
i = 0;
i <
len; ++
i)
5576 msg(
M_WARN,
"write_dhcp_str: buffer overflow building DHCP options");
5582 msg(
M_WARN,
"write_dhcp_str: string '%s' must be > 0 bytes and <= 255 bytes",
str);
5614 msg(
M_WARN,
"write_dhcp_search_str: temp buffer overflow building DHCP options");
5626 if (*
ptr ==
'.' || *
ptr ==
'\0')
5644 msg(
M_WARN,
"write_search_dhcp_str: buffer overflow building DHCP options");
5650 msg(
M_WARN,
"write_dhcp_search_str: search domain string must be <= 255 bytes");
5668 if (
o->netbios_scope)
5673 if (
o->netbios_node_type)
5683 if (
o->domain_search_list_len > 0)
5695 msg(
M_WARN,
"build_dhcp_options_string: buffer overflow building DHCP options");
5710 if (
tt->options.dhcp_pre_release ||
tt->options.dhcp_renew)
5718 if (
tt->options.dhcp_pre_release)
5722 if (
tt->options.dhcp_renew)
5736 HANDLE msg_channel =
tt->options.msg_channel;
5750 msg(
M_WARN,
"Register_dns failed using service: %s [status=0x%x]",
5756 msg(
M_INFO,
"Register_dns request sent to the service");
5775 buf_printf(&
cmd,
"openvpn --verb %d --register-dns --rdns-internal", verb);
5789 dsa = (local | (~netmask)) + offset;
5793 dsa = (local & netmask) + offset;
5799 "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",
5803 if ((local & netmask) != (dsa & netmask))
5805 msg(
M_FATAL,
"ERROR: --ip-win32 dynamic [offset] : offset is outside of --ifconfig subnet");
5818 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_VERSION, &info,
sizeof(info), &info,
5819 sizeof(info), &len, NULL))
5821 msg(
D_TUNTAP_INFO,
"TAP-Windows Driver Version %d.%d %s", (
int)info[0], (
int)info[1],
5822 (info[2] ?
"(DEBUG)" :
""));
5824 if (!(info[0] == TAP_WIN_MIN_MAJOR && info[1] >= TAP_WIN_MIN_MINOR))
5827 "ERROR: This version of " PACKAGE_NAME
5828 " requires a TAP-Windows driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME
5829 " distribution, a reboot is probably required at this point to get Windows to see the new driver.",
5830 TAP_WIN_MIN_MAJOR, TAP_WIN_MIN_MINOR);
5839 "WARNING: Tap-Win32 driver version %d.%d does not support IPv6 in TUN mode. IPv6 will not work. Upgrade your Tap-Win32 driver.",
5840 (
int)info[0], (
int)info[1]);
5848 "ERROR: Tap-Win32 driver version %d.%d is buggy regarding small IPv4 packets in TUN mode. Upgrade your Tap-Win32 driver.",
5849 (
int)info[0], (
int)info[1]);
5858 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_MTU, &mtu,
sizeof(mtu), &mtu,
sizeof(mtu), &len,
5882 .iface = { .index = index, .name =
"" } };
5891 status = FlushIpNetTable(index);
5896 msg(
M_INFO,
"Successful ARP Flush on interface [%lu] %s", index, device_guid);
5901 "NOTE: FlushIpNetTable failed on interface [%lu] %s (status=%lu) : %s", index,
5916 "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'");
5938 const char *error_suffix =
5939 "I am having trouble using the Windows 'IP helper API' to automatically set the IP address -- consider using other --ip-win32 methods (not 'ipapi')";
5944 msg(
M_FATAL,
"ERROR: unable to get adapter index for interface %s -- %s", device_guid,
5952 "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'");
5965 "Succeeded in adding a temporary IP/netmask of %s/%s to interface %s using the Win32 IP Helper API",
5972 "ERROR: AddIPAddress %s/%s failed on interface %s, index=%lu, status=%lu (windows error: '%s') -- %s",
5988 sizeof(
status), &len, NULL))
5991 "WARNING: The TAP-Windows driver rejected a TAP_WIN_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
5997 msg(
M_INFO,
"Sleeping for %d seconds...", s);
6010 msg(
M_FATAL,
"ERROR: --dev tun also requires --ifconfig");
6021 ep[0] = htonl(tt->
local);
6025 status = DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_TUN, ep,
sizeof(ep), ep,
sizeof(ep),
6031 "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
6039 status ?
"SUCCEEDED" :
"FAILED");
6045 ep[0] = htonl(tt->
local);
6048 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT, ep,
sizeof(ep), ep,
6049 sizeof(ep), &len, NULL))
6052 "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun");
6067 ep[0] = htonl(tt->
local);
6097#ifndef SIMULATE_DHCP_FAILED
6098 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_DHCP_MASQ, ep,
sizeof(ep), ep,
sizeof(ep),
6102 "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode");
6106 "Notified TAP-Windows driver to set a DHCP IP/netmask of %s/%s on interface %s [DHCP-serv: %s, lease-time: %d]",
6121 "ERROR: The TAP-Windows driver rejected a TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call");
6126 msg(
M_WARN,
"DHCP option string not set due to error");
6173 snprintf(tuntap_device_path,
sizeof(tuntap_device_path),
"%s%s%s", USERMODEDEVICEDIR,
6174 device_guid, TAP_WIN_SUFFIX);
6175 path = tuntap_device_path;
6180 tt->
hand = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
6181 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
6182 if (tt->
hand == INVALID_HANDLE_VALUE)
6201 uint8_t actual_buffer[256];
6211 *device_guid =
get_device_guid(dev_node, actual_buffer,
sizeof(actual_buffer),
6216 msg(
M_FATAL,
"Adapter '%s' not found", dev_node);
6222 "Adapter '%s' is using %s driver, %s expected. If you want to use this device, adjust --windows-driver.",
6229 msg(
M_FATAL,
"Failed to open %s adapter: %s",
6235 int device_number = 0;
6236 int adapters_created = 0;
6249 if ((++adapters_created > 10)
6252 msg(
M_FATAL,
"All %s adapters on this system are currently in use or disabled.",
6311 *dhcp_masq_post =
true;
6333 bool dhcp_masq =
false;
6334 bool dhcp_masq_post =
false;
6375open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
6382 "Some --dhcp-option or --dns options require DHCP server,"
6383 " which is not supported by the selected %s driver. They will be"
6394 const char *device_guid = NULL;
6502 if (!CancelIo(tt->
hand))
6504 msg(
M_WARN |
M_ERRNO,
"Warning: CancelIO failed on %s adapter", adaptertype);
6508 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped read event on %s adapter", adaptertype);
6511 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped write event on %s adapter", adaptertype);
6517 if (!CloseHandle(tt->
hand))
6519 msg(
M_WARN |
M_ERRNO,
"Warning: CloseHandle failed on %s adapter", adaptertype);
6595 "Warning: DeleteIPAddress[%u] failed on TAP-Windows adapter, status=%u : %s",
6622 {
"manual" }, {
"netsh" }, {
"ipapi" }, {
"dynamic" }, {
"adaptive" }
6646 return "[unknown --ip-win32 type]";
6675open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *
tt,
void argv_msg(const int msglev, const struct argv *a)
Write the arguments stored in a struct argv via the msg() command.
void argv_msg_prefix(const int msglev, const struct argv *a, const char *prefix)
Similar to argv_msg() but prefixes the messages being written with a given string.
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
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,...)
char * format_hex_ex(const uint8_t *data, int size, int maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
struct buffer alloc_buf(size_t size)
char * string_alloc(const char *str, struct gc_arena *gc)
static bool has_digit(const char *src)
#define ALLOC_OBJ(dptr, type)
static char * format_hex(const uint8_t *data, int size, int maxoutput, struct gc_arena *gc)
static struct buffer clear_buf(void)
Return an empty struct buffer.
static bool buf_copy(struct buffer *dest, const struct buffer *src)
static bool buf_write_u32(struct buffer *dest, uint32_t data)
static bool buf_safe(const struct buffer *buf, size_t len)
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
static bool buf_write(struct buffer *dest, const void *src, size_t size)
static bool buf_write_u8(struct buffer *dest, uint8_t data)
#define ALLOC_OBJ_CLEAR_GC(dptr, type, 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)
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)
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, long usec, bool show_usec, struct gc_arena *gc)
#define OPENVPN_IPH_GET_VER(v)
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.
uint8_t * data
Pointer to the 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.
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)
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 void write_dhcp_u8(struct buffer *buf, const int type, const int data, bool *error)
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)
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 show_adapter(int msglev, const IP_ADAPTER_INFO *a, struct gc_arena *gc)
static bool build_dhcp_options_string(struct buffer *buf, const struct tuntap_options *o)
void show_tap_win_adapters(int msglev, int warnlev)
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)
void show_adapters(int msglev)
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 write_dhcp_search_str(struct buffer *buf, const int type, const char *const *str_array, int array_len, bool *error)
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)
static void write_dhcp_str(struct buffer *buf, const int type, const char *str, bool *error)
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)
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 exec_command(const char *prefix, const struct argv *a, int n, int msglevel)
static void undo_ifconfig_ipv6(struct tuntap *tt, openvpn_net_ctx_t *ctx)
static void write_dhcp_u32_array(struct buffer *buf, const int type, const uint32_t *data, const unsigned int len, bool *error)
static void netsh_command(const struct argv *a, int n, int msglevel)
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)
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)
#define IPW32_SET_ADAPTIVE
#define DHCP_OPTIONS_DHCP_REQUIRED
#define N_SEARCH_LIST_LEN
#define TUN_ADAPTER_INDEX_INVALID
#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 read_tun(struct tuntap *tt, uint8_t *buf, int len)
int write_tun(struct tuntap *tt, uint8_t *buf, int len)
void tuncfg(const char *dev, const char *dev_type, const char *dev_node, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options, openvpn_net_ctx_t *ctx)
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)
bool send_msg_iservice(HANDLE pipe, const void *data, size_t size, ack_message_t *ack, const char *context)
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 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