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);
134 if (addr.
family == AF_INET)
138 msg(
D_IFCONFIG,
"INET address service: %s %s/%d", add ?
"add" :
"remove",
145 msg(
D_IFCONFIG,
"INET6 address service: %s %s/%d", add ?
"add" :
"remove",
156 msg(
M_WARN,
"TUN: %s address failed using service: %s [status=%u if_index=%d]",
203 size_t dstlen = strlen(
dns.domains);
205 size_t extra = dstlen ? 2 : 1;
206 if (dstlen + srclen + extra >
sizeof(
dns.domains))
208 msg(
M_WARN,
"DNS search domains sent to service truncated to %d", i);
213 dns.domains[dstlen++] =
',';
218 msg(
D_LOW,
"%s DNS domains on '%s' (if_index = %d) using service",
219 (add ?
"Setting" :
"Deleting"),
dns.iface.name,
dns.iface.index);
227 msg(
M_WARN,
"TUN: %s DNS domains failed using service: %s [status=%u if_name=%s]",
233 msg(
M_INFO,
"DNS domains %s using service", (add ?
"set" :
"deleted"));
246 int addr_len = add ? len : 0;
247 const char *ip_proto_name = family == AF_INET6 ?
"IPv6" :
"IPv4";
261 .addr_len = addr_len };
267 if (addr_len > _countof(dns.
addr))
269 addr_len = _countof(dns.
addr);
271 msg(
M_WARN,
"Number of %s DNS addresses sent to service truncated to %d", ip_proto_name,
275 for (
int i = 0; i < addr_len; ++i)
277 if (family == AF_INET6)
287 msg(
D_LOW,
"%s %s dns servers on '%s' (if_index = %d) using service",
297 msg(
M_WARN,
"TUN: %s %s dns failed using service: %s [status=%u if_name=%s]",
303 msg(
M_INFO,
"%s dns servers %s using service", ip_proto_name, (add ?
"set" :
"deleted"));
326 .addr_len = addr_len };
332 if (addr_len > _countof(wins.
addr))
334 addr_len = _countof(wins.
addr);
336 msg(
M_WARN,
"Number of WINS addresses sent to service truncated to %d", addr_len);
339 for (
int i = 0; i < addr_len; ++i)
344 msg(
D_LOW,
"%s WINS servers on '%s' (if_index = %d) using service",
354 msg(
M_WARN,
"TUN: %s WINS failed using service: %s [status=%u if_name=%s]",
360 msg(
M_INFO,
"WINS servers %s using service", (add ?
"set" :
"deleted"));
373 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
379 if (family == AF_INET6 && mtu < 1280)
382 "NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
392 msg(
M_NONFATAL,
"TUN: setting %s mtu using service failed: %s [status=%u if_index=%d]",
398 msg(
M_INFO,
"%s MTU set to %d on interface %d using service", family_name, mtu,
418 "%s%s -NoProfile -NonInteractive -Command Set-DnsClient -InterfaceIndex %lu -ConnectionSpecificSuffix '%s'",
470 msg(
M_NONFATAL,
"TUN: creating %s adapter using service failed: %s [status=%u]",
488static void solaris_error_close(
struct tuntap *tt,
const struct env_set *
es,
const char *actual,
494#if defined(TARGET_DARWIN)
495#include <sys/kern_control.h>
496#include <net/if_utun.h>
497#include <sys/sys_domain.h>
503is_dev_type(
const char *dev,
const char *dev_type,
const char *match_type)
512 return !strcmp(dev_type, match_type);
516 return !strncmp(dev, match_type, strlen(match_type));
551 return "[unknown-dev-type]";
589 const bool looks_like_netmask = ((addr & 0xFF000000) == 0xFF000000);
592 if (looks_like_netmask)
595 "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",
601 if (!looks_like_netmask)
604 "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",
617 in_addr_t remote_netmask)
621 msg(
M_INFO,
"CHECK_ADDR_CLASH type=%d public=%s local=%s, remote_netmask=%s",
632 const in_addr_t test_netmask = 0xFFFFFF00;
633 const in_addr_t public_net =
public & test_netmask;
634 const in_addr_t local_net = local & test_netmask;
635 const in_addr_t remote_net = remote_netmask & test_netmask;
637 if (
public == local ||
public == remote_netmask)
640 "WARNING: --%s address [%s] conflicts with --ifconfig address pair [%s, %s]. %s",
645 if (public_net == local_net || public_net == remote_net)
648 "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",
655 const in_addr_t public_network =
public & remote_netmask;
656 const in_addr_t virtual_network = local & remote_netmask;
657 if (public_network == virtual_network)
660 "WARNING: --%s address [%s] conflicts with --ifconfig subnet [%s, %s] -- local and remote addresses cannot be inside of the --ifconfig subnet. %s",
677 if ((rgi.
flags & needed) == needed)
680 if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100)
683 "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.");
697 if (
tt->did_ifconfig_setup && !disable)
776 msg(
M_FATAL,
"Error: problem with tun vs. tap setting");
802 setenv_str(
es,
"ifconfig_remote", ifconfig_remote_netmask);
806 setenv_str(
es,
"ifconfig_netmask", ifconfig_remote_netmask);
815 setenv_str(
es,
"ifconfig_ipv6_local", ifconfig_ipv6_local);
817 setenv_str(
es,
"ifconfig_ipv6_remote", ifconfig_ipv6_remote);
831 const char *dev_type,
833 const char *ifconfig_local_parm,
834 const char *ifconfig_remote_netmask_parm,
835 const char *ifconfig_ipv6_local_parm,
836 int ifconfig_ipv6_netbits_parm,
837 const char *ifconfig_ipv6_remote_parm,
838 struct addrinfo *local_public,
struct addrinfo *remote_public,
const bool strict_warn,
850 if (ifconfig_local_parm && ifconfig_remote_netmask_parm)
863 ifconfig_local_parm, 0, NULL, NULL);
867 ifconfig_remote_netmask_parm, 0, NULL, NULL);
874 struct addrinfo *curele;
882 for (curele = local_public; curele; curele = curele->ai_next)
884 if (curele->ai_family == AF_INET)
886 const in_addr_t local =
887 ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
892 for (curele = remote_public; curele; curele = curele->ai_next)
894 if (curele->ai_family == AF_INET)
896 const in_addr_t remote =
897 ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
922 if (ifconfig_ipv6_local_parm && ifconfig_ipv6_remote_parm)
928 if (inet_pton(AF_INET6, ifconfig_ipv6_local_parm, &tt->
local_ipv6) != 1
929 || inet_pton(AF_INET6, ifconfig_ipv6_remote_parm, &tt->
remote_ipv6) != 1)
931 msg(
M_FATAL,
"init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary",
932 ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm);
1011#if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || defined(TARGET_NETBSD) \
1012 || defined(TARGET_OPENBSD)
1023create_arbitrary_remote(
struct tuntap *tt)
1029 if (remote == tt->
local)
1051#if !defined(TARGET_LINUX)
1057#if defined(TARGET_LINUX)
1058 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1060 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1063 if (net_iface_up(ctx, ifname,
true) < 0)
1065 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1070 msg(
M_FATAL,
"Linux can't add IPv6 to interface %s", ifname);
1072#elif defined(TARGET_ANDROID)
1075 snprintf(out6,
sizeof(out6),
"%s/%d %d", ifconfig_ipv6_local, tt->
netbits_ipv6, tun_mtu);
1076 management_android_control(
management,
"IFCONFIG6", out6);
1077#elif defined(TARGET_SOLARIS)
1086 argv_printf(&
argv,
"%s %s inet6 plumb %s/%d %s mtu %d up", IFCONFIG_PATH, ifname,
1087 ifconfig_ipv6_local, tt->
netbits_ipv6, ifconfig_ipv6_remote, tun_mtu);
1097 solaris_error_close(tt,
es, ifname,
true);
1109 argv_printf(&
argv,
"%s %s inet6 addif %s/%d up", IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
1116 solaris_error_close(tt,
es, ifname,
true);
1121 argv_printf(&
argv,
"%s %s inet6 mtu %d", IFCONFIG_PATH, ifname, tun_mtu);
1125#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) || defined(TARGET_DARWIN) \
1126 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1127 argv_printf(&
argv,
"%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
1133#if defined(TARGET_FREEBSD) && __FreeBSD_version >= 1200000 && __FreeBSD_version < 1300000
1155#elif defined(TARGET_AIX)
1156 argv_printf(&
argv,
"%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
1167#elif defined(_WIN32)
1171 "******** NOTE: Please manually set the v6 IP of '%s' to %s (if it is not already set)",
1172 ifname, ifconfig_ipv6_local);
1201 argv_printf(&
argv,
"%s%s interface ipv6 set address %lu %s/%d store=active",
1220 "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.");
1223#if !defined(TARGET_LINUX)
1242#if !defined(_WIN32) && !defined(TARGET_ANDROID)
1249#if !defined(TARGET_LINUX)
1250 const char *ifconfig_local = NULL;
1251 const char *ifconfig_remote_netmask = NULL;
1262#if defined(TARGET_LINUX)
1263 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1265 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1268 if (net_iface_up(ctx, ifname,
true) < 0)
1270 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1277 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1284 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1287#elif defined(TARGET_ANDROID)
1290 snprintf(out,
sizeof(out),
"%s %s %d %s", ifconfig_local, ifconfig_remote_netmask, tun_mtu,
1292 management_android_control(
management,
"IFCONFIG", out);
1294#elif defined(TARGET_SOLARIS)
1302 argv_printf(&
argv,
"%s %s %s %s mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local,
1303 ifconfig_remote_netmask, tun_mtu);
1308 solaris_error_close(tt,
es, ifname,
false);
1311 argv_printf(&
argv,
"%s %s netmask 255.255.255.255", IFCONFIG_PATH, ifname);
1315 argv_printf(&
argv,
"%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH, ifname,
1316 ifconfig_local, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1320 argv_printf(&
argv,
"%s %s %s netmask %s up", IFCONFIG_PATH, ifname, ifconfig_local,
1321 ifconfig_remote_netmask);
1327 solaris_error_close(tt,
es, ifname,
false);
1343#elif defined(TARGET_OPENBSD)
1345 in_addr_t remote_end;
1356 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask 255.255.255.255 up -link0", IFCONFIG_PATH,
1357 ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1361 remote_end = create_arbitrary_remote(tt);
1362 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask %s up -link0", IFCONFIG_PATH, ifname,
1364 ifconfig_remote_netmask);
1368 argv_printf(&
argv,
"%s %s %s netmask %s mtu %d link0", IFCONFIG_PATH, ifname,
1369 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1386#elif defined(TARGET_NETBSD)
1387 in_addr_t remote_end = INADDR_ANY;
1391 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask 255.255.255.255 up", IFCONFIG_PATH, ifname,
1392 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1396 remote_end = create_arbitrary_remote(tt);
1397 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH, ifname,
1399 ifconfig_remote_netmask);
1408 argv_printf(&
argv,
"%s %s %s netmask %s mtu %d", IFCONFIG_PATH, ifname, ifconfig_local,
1409 ifconfig_remote_netmask, tun_mtu);
1426#elif defined(TARGET_DARWIN)
1434 msg(
M_INFO,
"NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
1440 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask 255.255.255.255 up", IFCONFIG_PATH, ifname,
1441 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1445 argv_printf(&
argv,
"%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH, ifname,
1446 ifconfig_local, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1450 argv_printf(&
argv,
"%s %s %s netmask %s mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local,
1451 ifconfig_remote_netmask, tun_mtu);
1469#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1474 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask 255.255.255.255 up", IFCONFIG_PATH, ifname,
1475 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1480 argv_printf(&
argv,
"%s %s %s/%d mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local, netbits,
1487#elif defined(TARGET_AIX)
1495 msg(
M_FATAL,
"no tun support on AIX (canthappen)");
1499 argv_printf(&
argv,
"%s %s %s netmask %s mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local,
1500 ifconfig_remote_netmask, tun_mtu);
1507#elif defined(_WIN32)
1511 "******** NOTE: Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
1512 ifname, ifconfig_local, ifconfig_remote_netmask);
1546#elif defined(TARGET_HAIKU)
1548 argv_printf(&
argv,
"%s %s inet %s %s mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local,
1549 ifconfig_remote_netmask, tun_mtu);
1555 "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.");
1558#if !defined(TARGET_LINUX)
1572#ifdef ENABLE_MANAGEMENT
1597#if defined(TARGET_LINUX)
1614#elif defined(TARGET_FREEBSD)
1632#if defined(TARGET_LINUX)
1637#elif defined(TARGET_FREEBSD)
1683#ifdef TARGET_SOLARIS
1688#if defined(TARGET_OPENBSD) || defined(TARGET_DARWIN)
1708#include <netinet/ip.h>
1712header_modify_read_write_return(
int len)
1716 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
1724#if defined(__GNUC__) || defined(__clang__)
1725#pragma GCC diagnostic push
1726#pragma GCC diagnostic ignored "-Wconversion"
1730write_tun_header(
struct tuntap *tt, uint8_t *buf,
int len)
1742 type = htonl(AF_INET6);
1746 type = htonl(AF_INET);
1749 iv[0].iov_base = &type;
1750 iv[0].iov_len =
sizeof(type);
1751 iv[1].iov_base = buf;
1752 iv[1].iov_len = len;
1754 return header_modify_read_write_return(writev(tt->fd, iv, 2));
1758 return write(tt->fd, buf, len);
1763read_tun_header(
struct tuntap *tt, uint8_t *buf,
int len)
1770 iv[0].iov_base = &type;
1771 iv[0].iov_len =
sizeof(type);
1772 iv[1].iov_base = buf;
1773 iv[1].iov_len = len;
1775 return header_modify_read_write_return(readv(tt->fd, iv, 2));
1779 return read(tt->fd, buf, len);
1783#if defined(__GNUC__) || defined(__clang__)
1784#pragma GCC diagnostic pop
1795#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1797tun_dco_enabled(
struct tuntap *tt)
1804#if !(defined(_WIN32) || defined(TARGET_LINUX) || defined(TARGET_SOLARIS))
1806open_tun_generic(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt)
1809 char dynamic_name[256];
1810 bool dynamic_opened =
false;
1817 snprintf(tunname,
sizeof(tunname),
"%s", dev_node);
1829 for (
int i = 0; i < 256; ++i)
1833#if defined(TARGET_HAIKU)
1836 snprintf(tunname,
sizeof(tunname),
"/dev/%s%s%d", dev, sep, i);
1837 snprintf(dynamic_name,
sizeof(dynamic_name),
"%s%s%d", dev, sep, i);
1838 if ((tt->fd = open(tunname, O_RDWR)) > 0)
1840 dynamic_opened =
true;
1845 if (!dynamic_opened)
1847 msg(
M_FATAL,
"Cannot allocate TUN/TAP dev dynamically");
1855 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
1859 if (!dynamic_opened)
1862 if (if_nametoindex(dev) > 0)
1864 msg(
M_INFO,
"TUN/TAP device %s exists previously, keep at program end", dev);
1868 if ((tt->fd = open(tunname, O_RDWR)) < 0)
1870 msg(
M_ERR,
"Cannot open TUN/TAP dev %s", tunname);
1876 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
1883#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1885open_tun_dco_generic(
const char *dev,
const char *dev_type,
struct tuntap *tt,
1888 char dynamic_name[256];
1889 bool dynamic_opened =
false;
1899 if (strcmp(dev,
"tun") == 0)
1901 for (
int i = 0; i < 256; ++i)
1903 snprintf(dynamic_name,
sizeof(dynamic_name),
"%s%d", dev, i);
1907 dynamic_opened =
true;
1908 msg(
M_INFO,
"DCO device %s opened", dynamic_name);
1912 else if (ret == -EPERM)
1917 if (!dynamic_opened)
1919 msg(
M_FATAL,
"Cannot allocate DCO dev dynamically");
1933 msg(
M_INFO,
"DCO device %s already exists, won't be destroyed at shutdown", dev);
1938 msg(
M_ERR,
"Cannot open DCO device %s: %s (%d)", dev, strerror(-ret), ret);
1942 msg(
M_INFO,
"DCO device %s opened", dev);
1951#if !(defined(_WIN32) || defined(TARGET_SOLARIS))
1953close_tun_generic(
struct tuntap *tt)
1965#if defined(TARGET_ANDROID)
1967open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
1970#define ANDROID_TUNNAME "vpnservice-tun"
1975 int oldtunfd = tt->fd;
1981 management_android_control(
management,
"DNS6SERVER",
1987 management_android_control(
management,
"DNSSERVER",
1999 buf_printf(&buf,
"%s %d",
tt->options.http_proxy,
tt->options.http_proxy_port);
2029 msg(
M_ERR,
"ERROR: Cannot open TUN");
2056#elif defined(TARGET_LINUX)
2058#ifndef HAVE_LINUX_SOCKIOS_H
2059#error header file linux/sockios.h required
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;
2108 ifr.ifr_flags |= IFF_TUN;
2112 ifr.ifr_flags |= IFF_TAP;
2116 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device", dev);
2122 if (strcmp(dev,
"tun") && strcmp(dev,
"tap"))
2131 if (ioctl(tt->fd, TUNSETIFF, (
void *)&ifr) < 0)
2133 msg(
M_ERR,
"ERROR: Cannot ioctl TUNSETIFF %s", dev);
2136 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2141#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2144 struct ifreq netifr;
2147 if ((ctl_fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
2150 strncpynt(netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
2151 netifr.ifr_qlen = tt->
options.txqueuelen;
2152 if (ioctl(ctl_fd, SIOCSIFTXQLEN, (
void *)&netifr) >= 0)
2158 msg(
M_WARN |
M_ERRNO,
"Note: Cannot set tx queue length on %s", ifr.ifr_name);
2164 msg(
M_WARN |
M_ERRNO,
"Note: Cannot open control socket on %s", ifr.ifr_name);
2179open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2187#ifdef ENABLE_FEATURE_TUN_PERSIST
2191#define TUNSETGROUP _IOW('T', 206, int)
2195tuncfg(
const char *dev,
const char *dev_type,
const char *dev_node,
int persist_mode,
2206 open_tun(dev, dev_type, dev_node, tt, ctx);
2207 if (ioctl(tt->fd, TUNSETPERSIST, persist_mode) < 0)
2209 msg(
M_ERR,
"Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
2211 if (username != NULL)
2217 msg(
M_ERR,
"Cannot get user entry for %s", username);
2221 msg(
M_ERR,
"Cannot ioctl TUNSETOWNER(%s) %s", username, dev);
2224 if (groupname != NULL)
2230 msg(
M_ERR,
"Cannot get group entry for %s", groupname);
2234 msg(
M_ERR,
"Cannot ioctl TUNSETGROUP(%s) %s", groupname, dev);
2238 msg(
M_INFO,
"Persist state set to: %s", (persist_mode ?
"ON" :
"OFF"));
2248#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
2249 if (tun_dco_enabled(tt))
2254 close_tun_generic(tt);
2258#if defined(__GNUC__) || defined(__clang__)
2259#pragma GCC diagnostic push
2260#pragma GCC diagnostic ignored "-Wconversion"
2266 return write(tt->fd, buf, len);
2272 return read(tt->fd, buf, len);
2275#if defined(__GNUC__) || defined(__clang__)
2276#pragma GCC diagnostic pop
2279#elif defined(TARGET_SOLARIS)
2282#error I need the symbol TUNNEWPPA from net/if_tun.h
2286open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2289 int if_fd = -1, ip_muxid = -1, arp_muxid = -1, arp_fd = -1, ppa = -1;
2292 const char *ip_node = NULL, *arp_node = NULL;
2293 const char *dev_tuntap_type;
2295 struct strioctl strioc_if, strioc_ppa;
2305 ip_node =
"/dev/udp";
2308 dev_node =
"/dev/tun";
2310 dev_tuntap_type =
"tun";
2311 link_type = I_PLINK;
2315 ip_node =
"/dev/udp";
2318 dev_node =
"/dev/tap";
2320 arp_node = dev_node;
2321 dev_tuntap_type =
"tap";
2322 link_type = I_PLINK;
2326 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device", dev);
2329 if ((tt->ip_fd = open(ip_node, O_RDWR, 0)) < 0)
2331 msg(
M_ERR,
"Can't open %s", ip_node);
2334 if ((tt->fd = open(dev_node, O_RDWR, 0)) < 0)
2336 msg(
M_ERR,
"Can't open %s", dev_node);
2344 while (*ptr && !isdigit((
int)*ptr))
2352 strioc_ppa.ic_cmd = TUNNEWPPA;
2353 strioc_ppa.ic_timout = 0;
2354 strioc_ppa.ic_len =
sizeof(ppa);
2355 strioc_ppa.ic_dp = (
char *)&ppa;
2359 bool found_one =
false;
2360 while (!found_one && ppa < 64)
2362 int new_ppa = ioctl(tt->fd, I_STR, &strioc_ppa);
2365 msg(
M_INFO,
"open_tun: got dynamic interface '%s%d'", dev_tuntap_type, new_ppa);
2370 if (errno != EEXIST)
2372 msg(
M_ERR,
"open_tun: unexpected error trying to find free %s interface",
2379 msg(
M_ERR,
"open_tun: could not find free %s interface, give up.", dev_tuntap_type);
2384 if ((ppa = ioctl(tt->fd, I_STR, &strioc_ppa)) < 0)
2386 msg(
M_ERR,
"Can't assign PPA for new interface (%s%d)", dev_tuntap_type, ppa);
2390 if ((if_fd = open(dev_node, O_RDWR, 0)) < 0)
2392 msg(
M_ERR,
"Can't open %s (2)", dev_node);
2395 if (ioctl(if_fd, I_PUSH,
"ip") < 0)
2397 msg(
M_ERR,
"Can't push IP module");
2403 if (ioctl(if_fd, IF_UNITSEL, (
char *)&ppa) < 0)
2405 msg(
M_ERR,
"Can't set PPA %d", ppa);
2412 snprintf(tt->
actual_name, 32,
"%s%d", dev_tuntap_type, ppa);
2416 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2423 if (ioctl(if_fd, SIOCSLIFNAME, &ifr) < 0)
2425 msg(
M_ERR,
"Can't set PPA %d", ppa);
2427 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2432 if (ioctl(if_fd, I_PUSH,
"arp") < 0)
2434 msg(
M_ERR,
"Can't push ARP module");
2440 if (ioctl(tt->ip_fd, I_POP, NULL) < 0)
2446 if (ioctl(tt->ip_fd, I_PUSH,
"arp") < 0)
2448 msg(
M_ERR,
"Can't push ARP module");
2452 if ((arp_fd = open(arp_node, O_RDWR, 0)) < 0)
2454 msg(
M_ERR,
"Can't open %s", arp_node);
2457 if (ioctl(arp_fd, I_PUSH,
"arp") < 0)
2459 msg(
M_ERR,
"Can't push ARP module");
2463 strioc_if.ic_cmd = SIOCSLIFNAME;
2464 strioc_if.ic_timout = 0;
2465 strioc_if.ic_len =
sizeof(ifr);
2466 strioc_if.ic_dp = (
char *)𝔦
2467 if (ioctl(arp_fd, I_STR, &strioc_if) < 0)
2469 msg(
M_ERR,
"Can't set ifname to arp");
2473 if ((ip_muxid = ioctl(tt->ip_fd, link_type, if_fd)) < 0)
2475 msg(
M_ERR,
"Can't link %s device to IP", dev_tuntap_type);
2480 if ((arp_muxid = ioctl(tt->ip_fd, link_type, arp_fd)) < 0)
2482 msg(
M_ERR,
"Can't link %s device to ARP", dev_tuntap_type);
2489 ifr.lifr_ip_muxid = ip_muxid;
2492 ifr.lifr_arp_muxid = arp_muxid;
2495 if (ioctl(tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0)
2499 ioctl(tt->ip_fd, I_PUNLINK, arp_muxid);
2501 ioctl(tt->ip_fd, I_PUNLINK, ip_muxid);
2502 msg(
M_ERR,
"Can't set multiplexor id");
2513solaris_close_tun(
struct tuntap *tt)
2531 if (ioctl(tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0)
2536 if (ioctl(tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0)
2543 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0)
2549 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0)
2573 solaris_close_tun(tt);
2582solaris_error_close(
struct tuntap *tt,
const struct env_set *
es,
const char *actual,
2608 sbuf.buf = (
char *)buf;
2609 return putmsg(tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
2619 sbuf.buf = (
char *)buf;
2620 return getmsg(tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
2623#elif defined(TARGET_OPENBSD)
2626open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2629 open_tun_generic(dev, dev_type, dev_node, tt);
2634 struct tuninfo info;
2636 if (ioctl(tt->fd, TUNGIFINFO, &info) < 0)
2642 info.flags |= IFF_MULTICAST;
2645 if (ioctl(tt->fd, TUNSIFINFO, &info) < 0)
2670 close_tun_generic(tt);
2682 close_tun_generic(tt);
2694 return write_tun_header(tt, buf, len);
2700 return read_tun_header(tt, buf, len);
2703#elif defined(TARGET_NETBSD)
2720open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2727 if (strcmp(dev,
"tap") == 0)
2730 if ((tt->fd = open(
"/dev/tap", O_RDWR)) < 0)
2732 msg(
M_FATAL,
"Cannot allocate NetBSD TAP dev dynamically");
2734 if (ioctl(tt->fd, TAPGIFNAME, (
void *)&ifr) < 0)
2736 msg(
M_FATAL,
"Cannot query NetBSD TAP device name");
2740 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2749 open_tun_generic(dev, dev_type, dev_node, tt);
2754 int i = IFF_POINTOPOINT | IFF_MULTICAST;
2755 ioctl(tt->fd, TUNSIFMODE, &i);
2757 ioctl(tt->fd, TUNSLMODE, &i);
2762 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0)
2783 close_tun_generic(tt);
2795 close_tun_generic(tt);
2805netbsd_modify_read_write_return(
int len)
2809 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
2830 type = htonl(AF_INET6);
2834 type = htonl(AF_INET);
2837 iv[0].iov_base = (
char *)&type;
2838 iv[0].iov_len =
sizeof(type);
2839 iv[1].iov_base = buf;
2840 iv[1].iov_len = len;
2842 return netbsd_modify_read_write_return(writev(tt->fd, iv, 2));
2846 return write(tt->fd, buf, len);
2858 iv[0].iov_base = (
char *)&type;
2859 iv[0].iov_len =
sizeof(type);
2860 iv[1].iov_base = buf;
2861 iv[1].iov_len = len;
2863 return netbsd_modify_read_write_return(readv(tt->fd, iv, 2));
2867 return read(tt->fd, buf, len);
2871#elif defined(TARGET_FREEBSD)
2874freebsd_modify_read_write_return(
int len)
2878 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
2887open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2890 if (tun_dco_enabled(tt))
2892 open_tun_dco_generic(dev, dev_type, tt, ctx);
2896 open_tun_generic(dev, dev_type, dev_node, tt);
2901 int i = IFF_POINTOPOINT | IFF_MULTICAST;
2904 i = IFF_BROADCAST | IFF_MULTICAST;
2907 if (ioctl(tt->fd, TUNSIFMODE, &i) < 0)
2914 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0)
2936 close_tun_generic(tt);
2949 close_tun_generic(tt);
2958#if defined(__GNUC__) || defined(__clang__)
2959#pragma GCC diagnostic push
2960#pragma GCC diagnostic ignored "-Wconversion"
2972 iph = (
struct ip *)buf;
2976 type = htonl(AF_INET6);
2980 type = htonl(AF_INET);
2983 iv[0].iov_base = (
char *)&type;
2984 iv[0].iov_len =
sizeof(type);
2985 iv[1].iov_base = buf;
2986 iv[1].iov_len = len;
2988 return freebsd_modify_read_write_return(writev(tt->fd, iv, 2));
2992 return write(tt->fd, buf, len);
3004 iv[0].iov_base = (
char *)&type;
3005 iv[0].iov_len =
sizeof(type);
3006 iv[1].iov_base = buf;
3007 iv[1].iov_len = len;
3009 return freebsd_modify_read_write_return(readv(tt->fd, iv, 2));
3013 return read(tt->fd, buf, len);
3017#if defined(__GNUC__) || defined(__clang__)
3018#pragma GCC diagnostic pop
3021#elif defined(TARGET_DRAGONFLY)
3024dragonfly_modify_read_write_return(
int len)
3028 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
3037open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3040 open_tun_generic(dev, dev_type, dev_node, tt);
3047 ioctl(tt->fd, TUNSLMODE, &i);
3049 ioctl(tt->fd, TUNSIFHEAD, &i);
3058 close_tun_generic(tt);
3071 iph = (
struct ip *)buf;
3075 type = htonl(AF_INET6);
3079 type = htonl(AF_INET);
3082 iv[0].iov_base = (
char *)&type;
3083 iv[0].iov_len =
sizeof(type);
3084 iv[1].iov_base = buf;
3085 iv[1].iov_len = len;
3087 return dragonfly_modify_read_write_return(writev(tt->fd, iv, 2));
3091 return write(tt->fd, buf, len);
3103 iv[0].iov_base = (
char *)&type;
3104 iv[0].iov_len =
sizeof(type);
3105 iv[1].iov_base = buf;
3106 iv[1].iov_len = len;
3108 return dragonfly_modify_read_write_return(readv(tt->fd, iv, 2));
3112 return read(tt->fd, buf, len);
3116#elif defined(TARGET_DARWIN)
3138utun_open_helper(
struct ctl_info ctlInfo,
int utunnum)
3140 struct sockaddr_ctl sc;
3143 fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
3147 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (socket(SYSPROTO_CONTROL))", utunnum);
3151 if (ioctl(fd, CTLIOCGINFO, &ctlInfo) == -1)
3154 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (ioctl(CTLIOCGINFO))", utunnum);
3159 sc.sc_id = ctlInfo.ctl_id;
3160 sc.sc_len =
sizeof(sc);
3161 sc.sc_family = AF_SYSTEM;
3162 sc.ss_sysaddr = AF_SYS_CONTROL;
3164 sc.sc_unit = utunnum + 1;
3170 if (connect(fd, (
struct sockaddr *)&sc,
sizeof(sc)) < 0)
3172 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (connect(AF_SYS_CONTROL))", utunnum);
3184open_darwin_utun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt)
3186 struct ctl_info ctlInfo;
3190 socklen_t utunname_len =
sizeof(utunname);
3194 if (dev_node && (strcmp(
"utun", dev_node) != 0))
3196 if (sscanf(dev_node,
"utun%d", &utunnum) != 1)
3199 "Cannot parse 'dev-node %s' please use 'dev-node utunX'"
3200 "to use a utun device number X",
3207 if (strlcpy(ctlInfo.ctl_name, UTUN_CONTROL_NAME,
sizeof(ctlInfo.ctl_name))
3208 >=
sizeof(ctlInfo.ctl_name))
3210 msg(
M_ERR,
"Opening utun: UTUN_CONTROL_NAME too long");
3216 for (utunnum = 0; utunnum < 255; utunnum++)
3220 ASSERT(snprintf(ifname,
sizeof(ifname),
"utun%d", utunnum) > 0);
3221 if (if_nametoindex(ifname))
3225 fd = utun_open_helper(ctlInfo, utunnum);
3236 fd = utun_open_helper(ctlInfo, utunnum);
3248 if (getsockopt(fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, utunname, &utunname_len))
3255 msg(
M_INFO,
"Opened utun device %s", utunname);
3260open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3264 if ((!dev_node && tt->
type ==
DEV_TYPE_TUN) || (dev_node && !strncmp(dev_node,
"utun", 4)))
3270 msg(
M_FATAL,
"Cannot use utun devices with --dev-type %s",
3276 open_darwin_utun(dev, dev_type, dev_node, tt);
3283 msg(
M_INFO,
"Failed to open utun device. Falling back to /dev/tun device");
3284 open_tun_generic(dev, dev_type, NULL, tt);
3300 if (dev_node && strcmp(dev_node,
"tun") == 0)
3305 open_tun_generic(dev, dev_type, dev_node, tt);
3309#if defined(__GNUC__) || defined(__clang__)
3310#pragma GCC diagnostic push
3311#pragma GCC diagnostic ignored "-Wconversion"
3326 argv_printf(&
argv,
"%s delete -inet6 %s", ROUTE_PATH, ifconfig_ipv6_local);
3331 close_tun_generic(tt);
3342 return write_tun_header(tt, buf, len);
3346 return write(tt->fd, buf, len);
3355 return read_tun_header(tt, buf, len);
3359 return read(tt->fd, buf, len);
3363#if defined(__GNUC__) || defined(__clang__)
3364#pragma GCC diagnostic pop
3367#elif defined(TARGET_AIX)
3370open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3374 char dynamic_name[20];
3379 msg(
M_FATAL,
"no support for 'tun' devices on AIX");
3382 if (strncmp(dev,
"tap", 3) != 0 || dev_node)
3385 "'--dev %s' and/or '--dev-node' not supported on AIX, use '--dev tap0', 'tap1', etc.",
3389 if (strcmp(dev,
"tap") == 0)
3392 for (i = 0; i < 99; i++)
3394 snprintf(tunname,
sizeof(tunname),
"/dev/tap%d", i);
3395 if (access(tunname, F_OK) < 0 && errno == ENOENT)
3402 msg(
M_FATAL,
"cannot find unused tap device");
3405 snprintf(dynamic_name,
sizeof(dynamic_name),
"tap%d", i);
3418 msg(
M_FATAL,
"TAP device name must be '--dev tapNNNN'");
3421 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
3426 if (access(tunname, F_OK) < 0 && errno == ENOENT)
3445 if ((tt->fd = open(tunname, O_RDWR)) < 0)
3447 msg(
M_ERR,
"Cannot open TAP device '%s'", tunname);
3452 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
3479 close_tun_generic(tt);
3492 return write(tt->fd, buf, len);
3498 return read(tt->fd, buf, len);
3501#elif defined(_WIN32)
3532 dmsg(
D_WIN32_IO,
"WIN32 I/O: TAP Read immediate return [%d,%d]", (
int)len,
3537 err = GetLastError();
3538 if (err == ERROR_IO_PENDING)
3550 dmsg(
D_WIN32_IO,
"WIN32 I/O: TAP Read error [%d] : %s", (
int)len,
3592 err = GetLastError();
3593 if (err == ERROR_IO_PENDING)
3625 err = GetLastError();
3643 HDEVINFO dev_info_set;
3649 SetupDiGetClassDevsEx(&
GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
3650 if (dev_info_set == INVALID_HANDLE_VALUE)
3652 err = GetLastError();
3653 msg(
M_FATAL,
"Error [%u] opening device information set key: %s", (
unsigned int)err,
3658 for (DWORD i = 0;; ++i)
3660 SP_DEVINFO_DATA device_info_data;
3663 char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3665 char device_instance_id[256];
3669 ULONG dev_interface_list_size;
3672 ZeroMemory(&device_info_data,
sizeof(SP_DEVINFO_DATA));
3673 device_info_data.cbSize =
sizeof(SP_DEVINFO_DATA);
3674 res = SetupDiEnumDeviceInfo(dev_info_set, i, &device_info_data);
3677 if (GetLastError() == ERROR_NO_MORE_ITEMS)
3687 dev_key = SetupDiOpenDevRegKey(dev_info_set, &device_info_data, DICS_FLAG_GLOBAL, 0,
3688 DIREG_DRV, KEY_QUERY_VALUE);
3689 if (dev_key == INVALID_HANDLE_VALUE)
3696 status = RegQueryValueEx(dev_key, net_cfg_instance_id_string, NULL, &data_type,
3698 if (
status != ERROR_SUCCESS)
3703 len =
sizeof(device_instance_id);
3704 res = SetupDiGetDeviceInstanceId(dev_info_set, &device_info_data, device_instance_id, len,
3711 cr = CM_Get_Device_Interface_List_Size(&dev_interface_list_size,
3713 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3715 if (cr != CR_SUCCESS)
3720 char *dev_interface_list =
gc_malloc(dev_interface_list_size,
false,
gc);
3722 dev_interface_list, dev_interface_list_size,
3723 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3724 if (cr != CR_SUCCESS)
3729 char *dev_if = dev_interface_list;
3732 while (strlen(dev_if) > 0)
3750 last->
next = dev_iif;
3754 dev_if += strlen(dev_if) + 1;
3758 RegCloseKey(dev_key);
3761 SetupDiDestroyDeviceInfoList(dev_info_set);
3776 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ADAPTER_KEY, 0, KEY_READ, &adapter_key);
3778 if (
status != ERROR_SUCCESS)
3780 msg(
M_FATAL,
"Error opening registry key: %s", ADAPTER_KEY);
3786 char enum_name[256];
3787 char unit_string[256];
3789 char component_id_string[] =
"ComponentId";
3790 char component_id[256];
3791 char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3792 BYTE net_cfg_instance_id[256];
3795 len =
sizeof(enum_name);
3796 status = RegEnumKeyEx(adapter_key, i, enum_name, &len, NULL, NULL, NULL, NULL);
3797 if (
status == ERROR_NO_MORE_ITEMS)
3801 else if (
status != ERROR_SUCCESS)
3803 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s", ADAPTER_KEY);
3806 snprintf(unit_string,
sizeof(unit_string),
"%s\\%s", ADAPTER_KEY, enum_name);
3808 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, unit_string, 0, KEY_READ, &unit_key);
3810 if (
status != ERROR_SUCCESS)
3816 len =
sizeof(component_id);
3817 status = RegQueryValueEx(unit_key, component_id_string, NULL, &data_type,
3818 (LPBYTE)component_id, &len);
3820 if (
status != ERROR_SUCCESS || data_type != REG_SZ)
3822 dmsg(
D_REGISTRY,
"Error opening registry key: %s\\%s", unit_string,
3823 component_id_string);
3827 len =
sizeof(net_cfg_instance_id);
3828 status = RegQueryValueEx(unit_key, net_cfg_instance_id_string, NULL, &data_type,
3829 net_cfg_instance_id, &len);
3831 if (
status == ERROR_SUCCESS && data_type == REG_SZ)
3835 if (strcasecmp(component_id, TAP_WIN_COMPONENT_ID) == 0
3836 || strcasecmp(component_id,
"root\\" TAP_WIN_COMPONENT_ID) == 0)
3840 else if (strcasecmp(component_id,
"ovpn-dco") == 0)
3868 RegCloseKey(unit_key);
3873 RegCloseKey(adapter_key);
3881 HKEY network_connections_key;
3887 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ,
3888 &network_connections_key);
3890 if (
status != ERROR_SUCCESS)
3892 msg(
M_FATAL,
"Error opening registry key: %s", NETWORK_CONNECTIONS_KEY);
3897 char enum_name[256];
3898 char connection_string[256];
3899 HKEY connection_key;
3900 WCHAR name_data[256];
3902 const WCHAR name_string[] = L
"Name";
3904 len =
sizeof(enum_name);
3905 status = RegEnumKeyEx(network_connections_key, i, enum_name, &len, NULL, NULL, NULL, NULL);
3906 if (
status == ERROR_NO_MORE_ITEMS)
3910 else if (
status != ERROR_SUCCESS)
3912 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s", NETWORK_CONNECTIONS_KEY);
3915 snprintf(connection_string,
sizeof(connection_string),
"%s\\%s\\Connection",
3916 NETWORK_CONNECTIONS_KEY, enum_name);
3918 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, connection_string, 0, KEY_READ, &connection_key);
3920 if (
status != ERROR_SUCCESS)
3922 dmsg(
D_REGISTRY,
"Error opening registry key: %s", connection_string);
3926 len =
sizeof(name_data);
3927 status = RegQueryValueExW(connection_key, name_string, NULL, &name_type,
3928 (LPBYTE)name_data, &len);
3930 if (
status != ERROR_SUCCESS || name_type != REG_SZ)
3932 dmsg(
D_REGISTRY,
"Error opening registry key: %s\\%s\\%ls", NETWORK_CONNECTIONS_KEY,
3933 connection_string, name_string);
3942 n = WideCharToMultiByte(CP_UTF8, 0, name_data, -1, NULL, 0, NULL, NULL);
3944 WideCharToMultiByte(CP_UTF8, 0, name_data, -1,
name, n, NULL, NULL);
3959 RegCloseKey(connection_key);
3964 RegCloseKey(network_connections_key);
3976 const unsigned int mask = 3;
3977 const char *err = NULL;
3979 if (local == remote)
3981 err =
"must be different";
3984 if ((local & (~mask)) != (remote & (~mask)))
3987 "must exist within the same 255.255.255.252 subnet. This is a limitation of --dev tun when used with the TAP-WIN32 driver";
3990 if ((local & mask) == 0 || (local & mask) == 3 || (remote & mask) == 0 || (remote & mask) == 3)
3993 "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";
4002 "There is a problem in your selection of --ifconfig endpoints [local=%s, remote=%s]. The local and remote VPN endpoints %s. Try '" PACKAGE
4003 " --show-valid-subnets' option for more info.",
4014 printf(
"On Windows, point-to-point IP support (i.e. --dev tun)\n");
4015 printf(
"is emulated by the TAP-Windows driver. The major limitation\n");
4016 printf(
"imposed by this approach is that the --ifconfig local and\n");
4017 printf(
"remote endpoints must be part of the same 255.255.255.252\n");
4018 printf(
"subnet. The following list shows examples of endpoint\n");
4019 printf(
"pairs which satisfy this requirement. Only the final\n");
4020 printf(
"component of the IP address pairs is at issue.\n\n");
4021 printf(
"As an example, the following option would be correct:\n");
4022 printf(
" --ifconfig 10.7.0.5 10.7.0.6 (on host A)\n");
4023 printf(
" --ifconfig 10.7.0.6 10.7.0.5 (on host B)\n");
4024 printf(
"because [5,6] is part of the below list.\n\n");
4026 for (i = 0; i < 256; i += 4)
4028 printf(
"[%3d,%3d] ", i + 1, i + 2);
4046 bool warn_panel_null =
false;
4047 bool warn_panel_dup =
false;
4048 bool warn_tap_dup =
false;
4059 msg(msglevel,
"Available adapters [name, GUID, driver]:");
4079 warn_panel_dup =
true;
4081 else if (links == 0)
4085 warn_panel_null =
true;
4086 msg(msglevel,
"[NULL] %s", tr->
guid);
4095 if (tr != tr1 && !strcmp(tr->
guid, tr1->
guid))
4097 warn_tap_dup =
true;
4105 msg(warnlevel,
"WARNING: Some TAP-Windows adapters have duplicate GUIDs");
4111 "WARNING: Some TAP-Windows adapters have duplicate links from the Network Connections control panel");
4114 if (warn_panel_null)
4117 "WARNING: Some TAP-Windows adapters have no link from the Network Connections control panel");
4180 msg(
M_FATAL,
"There are no TAP-Windows or ovpn-dco adapters "
4181 "on this system. You should be able to create an adapter "
4182 "by using tapctl.exe utility.");
4192 const struct tap_reg *tap_reg_src,
4242 if (windows_driver !=
NULL)
4271 ASSERT(actual_name_size > 0);
4317const IP_ADAPTER_INFO *
4321 IP_ADAPTER_INFO *pi = NULL;
4324 if ((
status = GetAdaptersInfo(NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4326 msg(
M_INFO,
"GetAdaptersInfo #1 failed (status=%u) : %s", (
unsigned int)
status,
4331 pi = (PIP_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4332 if ((
status = GetAdaptersInfo(pi, &size)) != NO_ERROR)
4334 msg(
M_INFO,
"GetAdaptersInfo #2 failed (status=%u) : %s", (
unsigned int)
status,
4342const IP_PER_ADAPTER_INFO *
4346 IP_PER_ADAPTER_INFO *pi = NULL;
4351 if ((
status = GetPerAdapterInfo(index, NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4353 msg(
M_INFO,
"GetPerAdapterInfo #1 failed (status=%u) : %s", (
unsigned int)
status,
4358 pi = (PIP_PER_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4359 if ((
status = GetPerAdapterInfo((ULONG)index, pi, &size)) == ERROR_SUCCESS)
4365 msg(
M_INFO,
"GetPerAdapterInfo #2 failed (status=%u) : %s", (
unsigned int)
status,
4373static const IP_INTERFACE_INFO *
4377 IP_INTERFACE_INFO *ii = NULL;
4380 if ((
status = GetInterfaceInfo(NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)
4382 msg(
M_INFO,
"GetInterfaceInfo #1 failed (status=%u) : %s", (
unsigned int)
status,
4387 ii = (PIP_INTERFACE_INFO)
gc_malloc(size,
false,
gc);
4388 if ((
status = GetInterfaceInfo(ii, &size)) == NO_ERROR)
4394 msg(
M_INFO,
"GetInterfaceInfo #2 failed (status=%u) : %s", (
unsigned int)
status,
4401static const IP_ADAPTER_INDEX_MAP *
4408 for (i = 0; i < list->NumAdapters; ++i)
4410 const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[i];
4411 if (index == inter->Index)
4425const IP_ADAPTER_INFO *
4430 const IP_ADAPTER_INFO *a;
4433 for (a = ai; a != NULL; a = a->Next)
4435 if (a->Index == index)
4444const IP_ADAPTER_INFO *
4456 const IP_ADDR_STRING *ip = &ai->IpAddressList;
4480 const IP_ADDR_STRING *iplist = &ai->IpAddressList;
4490 iplist = iplist->Next;
4496 const char *ip_str = iplist->IpAddress.String;
4497 const char *netmask_str = iplist->IpMask.String;
4498 bool succeed1 =
false;
4499 bool succeed2 =
false;
4501 if (ip_str && netmask_str && strlen(ip_str) && strlen(netmask_str))
4503 *ip =
getaddr(getaddr_flags, ip_str, 0, &succeed1, NULL);
4504 *netmask =
getaddr(getaddr_flags, netmask_str, 0, &succeed2, NULL);
4505 ret = (succeed1 ==
true && succeed2 ==
true);
4518 in_addr_t ip_adapter = 0;
4519 in_addr_t netmask_adapter = 0;
4521 return (
status && ip_adapter == ip && netmask_adapter == netmask);
4529const IP_ADAPTER_INFO *
4555 for (i = 0; i < n; ++i)
4557 in_addr_t ip, netmask;
4592 if (highest_netmask)
4594 *highest_netmask = 0;
4600 for (i = 0; i < n; ++i)
4602 in_addr_t adapter_ip, adapter_netmask;
4605 if (adapter_ip && adapter_netmask
4606 && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))
4608 if (highest_netmask && adapter_netmask > *highest_netmask)
4610 *highest_netmask = adapter_netmask;
4625 in_addr_t highest_netmask = 0;
4626 int lowest_metric = INT_MAX;
4641 if (first || hn > highest_netmask)
4643 highest_netmask = hn;
4646 lowest_metric = metric;
4655 else if (hn == highest_netmask)
4661 if (metric >= 0 && metric < lowest_metric)
4664 lowest_metric = metric;
4671 dmsg(
D_ROUTE_DEBUG,
"DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d metric=%d",
4673 count ? *count : -1, lowest_metric);
4682 *netmask = highest_netmask;
4694#define DHCP_STATUS_UNDEF 0
4695#define DHCP_STATUS_ENABLED 1
4696#define DHCP_STATUS_DISABLED 2
4709 if (ai->DhcpEnabled)
4735 const IP_ADDR_STRING *ip = &a->IpAddressList;
4739 const DWORD
context = ip->Context;
4743 msg(
M_INFO,
"Successfully deleted previously set dynamic IP/netmask: %s/%s",
4744 ip->IpAddress.String, ip->IpMask.String);
4748 const char *empty =
"0.0.0.0";
4749 if (strcmp(ip->IpAddress.String, empty) || strcmp(ip->IpMask.String, empty))
4752 "NOTE: could not delete previously set dynamic IP/netmask: %s/%s (status=%u)",
4753 ip->IpAddress.String, ip->IpMask.String, (
unsigned int)
status);
4771 swprintf(wbuf,
SIZE(wbuf), L
"\\DEVICE\\TCPIP_%hs", guid);
4772 if (GetAdapterIndex(wbuf, &aindex) != NO_ERROR)
4778 index = (DWORD)aindex;
4793 if (!strcmp(guid,
list->AdapterName))
4795 index =
list->Index;
4816 msg(
M_INFO,
"NOTE: could not get adapter index for %s", guid);
4830 buf_printf(&out,
"%s", ip->IpAddress.String);
4831 if (
strlen(ip->IpMask.String))
4848 msg(msglevel,
"%s",
a->Description);
4849 msg(msglevel,
" Index = %d", (
int)
a->Index);
4850 msg(msglevel,
" GUID = %s",
a->AdapterName);
4857 msg(msglevel,
" DHCP LEASE OBTAINED = %s",
time_string(
a->LeaseObtained, 0,
false,
gc));
4858 msg(msglevel,
" DHCP LEASE EXPIRES = %s",
time_string(
a->LeaseExpires, 0,
false,
gc));
4884 msg(msglevel,
"SYSTEM ADAPTER LIST");
4887 const IP_ADAPTER_INFO *a;
4890 for (a = ai; a != NULL; a = a->Next)
4913 msg(
M_ERR,
"Error: init SA failed");
4916 status = SetKernelObjectSecurity(hand, DACL_SECURITY_INFORMATION, &
sa.sd);
4919 msg(
M_ERRNO,
"Error: SetKernelObjectSecurity failed on %s", device_path);
4923 msg(
M_INFO |
M_NOPREFIX,
"TAP-Windows device: %s [Non-admin access allowed]", device_path);
4933 const char *device_guid = NULL;
4935 uint8_t actual_buffer[256];
4936 char device_path[256];
4948 msg(
M_FATAL,
"TAP-Windows adapter '%s' not found", dev_node);
4952 snprintf(device_path,
sizeof(device_path),
"%s%s%s", USERMODEDEVICEDIR, device_guid,
4955 hand = CreateFile(device_path, MAXIMUM_ALLOWED, 0,
4956 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
4958 if (hand == INVALID_HANDLE_VALUE)
4960 msg(
M_ERR,
"CreateFile failed on TAP device: %s", device_path);
4968 int device_number = 0;
4982 snprintf(device_path,
sizeof(device_path),
"%s%s%s", USERMODEDEVICEDIR, device_guid,
4985 hand = CreateFile(device_path, MAXIMUM_ALLOWED, 0,
4986 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
4988 if (hand == INVALID_HANDLE_VALUE)
4990 msg(
M_WARN,
"CreateFile failed on TAP device: %s", device_path);
5016 DWORD
status = IpReleaseAddress((IP_ADAPTER_INDEX_MAP *)inter);
5025 "NOTE: Release of DHCP-assigned IP address lease on TAP-Windows adapter failed: %s (code=%u)",
5057 DWORD
status = IpRenewAddress((IP_ADAPTER_INDEX_MAP *)inter);
5066 "WARNING: Failed to renew DHCP IP address lease on TAP-Windows adapter: %s (code=%u)",
5092 for (i = 0; i < n; ++i)
5106 msg(msglevel,
"%s: command failed", prefix);
5119 const char err[] =
"ERROR: Windows ipconfig command failed";
5144 const char *ip_str = src->IpAddress.String;
5146 bool succeed =
false;
5152 if (!ip_str || !strlen(ip_str))
5157 ip =
getaddr(getaddr_flags, ip_str, 0, &succeed, NULL);
5171 msg(
M_INFO,
"ip_addr_string_to_array [%d]", *dest_len);
5172 for (i = 0; i < *dest_len; ++i)
5185 int a2len =
SIZE(a2);
5195 for (i = 0; i < a1len; ++i)
5213 for (i = 0; i < len; ++i)
5239 for (
int i = 0; i < addr_len; ++i)
5241 const char *fmt = (i == 0) ?
"%s%s interface ipv6 set dns %lu static %s"
5242 :
"%s%s interface ipv6 add dns %lu %s";
5259 const IP_ADDR_STRING *current, DWORD adapter_index,
const bool test_first)
5263 bool delete_first =
false;
5264 bool is_dns = !strcmp(type,
"dns");
5271 delete_first =
true;
5276 delete_first =
true;
5291 for (i = 0; i < addr_len; ++i)
5295 const char *fmt = count ?
"%s%s interface ip add %s %lu %s"
5296 :
"%s%s interface ip set %s %lu static %s";
5313 msg(
M_INFO,
"NETSH: %lu %s %s [already set]", adapter_index, type,
5331 dest[0].Next = NULL;
5336 dest[0].Next = &dest[1];
5337 dest[1].Next = NULL;
5343 const in_addr_t netmask,
const unsigned int flags)
5347 const IP_ADAPTER_INFO *ai = NULL;
5348 const IP_PER_ADAPTER_INFO *pai = NULL;
5361 msg(
M_INFO,
"NETSH: %lu %s/%s [already set]", adapter_index,
5378 IP_ADDR_STRING wins[2];
5384 if (ai && ai->HaveWins)
5430 msg(
M_NONFATAL,
"TUN: enabling dhcp using service failed: %s [status=%u if_index=%d]",
5435 msg(
M_INFO,
"DHCP enabled on interface %d using service",
dhcp.iface.index);
5449 MIB_IPINTERFACE_ROW ipiface;
5450 InitializeIpInterfaceEntry(&ipiface);
5451 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
5452 ipiface.Family = family;
5453 ipiface.InterfaceIndex = iface_index;
5454 if (family == AF_INET6 && mtu < 1280)
5457 "NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
5460 err = GetIpInterfaceEntry(&ipiface);
5461 if (err == NO_ERROR)
5463 if (family == AF_INET)
5465 ipiface.SitePrefixLength = 0;
5467 ipiface.NlMtu = mtu;
5468 err = SetIpInterfaceEntry(&ipiface);
5471 if (err != NO_ERROR)
5473 msg(
M_WARN,
"TUN: Setting %s mtu failed: %s [status=%lu if_index=%d]", family_name,
5478 msg(
M_INFO,
"%s MTU set to %d on interface %d using SetIpInterfaceEntry()", family_name,
5520 return BSTR(&actual);
5534 tt->standby_iter = 0;
5546 msg(
M_INFO,
"NOTE: now trying netsh (this may take some time)");
5561 if (
tt->options.dhcp_pre_release ||
tt->options.dhcp_renew)
5569 if (
tt->options.dhcp_pre_release)
5573 if (
tt->options.dhcp_renew)
5587 HANDLE msg_channel =
tt->options.msg_channel;
5601 msg(
M_WARN,
"Register_dns failed using service: %s [status=0x%x]",
5607 msg(
M_INFO,
"Register_dns request sent to the service");
5626 buf_printf(&
cmd,
"openvpn --verb %d --register-dns --rdns-internal", verb);
5640 dsa = (local | (~netmask)) + offset;
5644 dsa = (local & netmask) + offset;
5650 "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",
5654 if ((local & netmask) != (dsa & netmask))
5656 msg(
M_FATAL,
"ERROR: --ip-win32 dynamic [offset] : offset is outside of --ifconfig subnet");
5669 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_VERSION, &info,
sizeof(info), &info,
5670 sizeof(info), &len, NULL))
5672 msg(
D_TUNTAP_INFO,
"TAP-Windows Driver Version %d.%d %s", (
int)info[0], (
int)info[1],
5673 (info[2] ?
"(DEBUG)" :
""));
5675 if (!(info[0] == TAP_WIN_MIN_MAJOR && info[1] >= TAP_WIN_MIN_MINOR))
5678 "ERROR: This version of " PACKAGE_NAME
5679 " requires a TAP-Windows driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME
5680 " distribution, a reboot is probably required at this point to get Windows to see the new driver.",
5681 TAP_WIN_MIN_MAJOR, TAP_WIN_MIN_MINOR);
5690 "WARNING: Tap-Win32 driver version %d.%d does not support IPv6 in TUN mode. IPv6 will not work. Upgrade your Tap-Win32 driver.",
5691 (
int)info[0], (
int)info[1]);
5699 "ERROR: Tap-Win32 driver version %d.%d is buggy regarding small IPv4 packets in TUN mode. Upgrade your Tap-Win32 driver.",
5700 (
int)info[0], (
int)info[1]);
5709 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_MTU, &mtu,
sizeof(mtu), &mtu,
sizeof(mtu), &len,
5733 .iface = { .index = index, .name =
"" } };
5742 status = FlushIpNetTable(index);
5747 msg(
M_INFO,
"Successful ARP Flush on interface [%lu] %s", index, device_guid);
5752 "NOTE: FlushIpNetTable failed on interface [%lu] %s (status=%lu) : %s", index,
5767 "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'");
5789 const char *error_suffix =
5790 "I am having trouble using the Windows 'IP helper API' to automatically set the IP address -- consider using other --ip-win32 methods (not 'ipapi')";
5795 msg(
M_FATAL,
"ERROR: unable to get adapter index for interface %s -- %s", device_guid,
5803 "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'");
5816 "Succeeded in adding a temporary IP/netmask of %s/%s to interface %s using the Win32 IP Helper API",
5823 "ERROR: AddIPAddress %s/%s failed on interface %s, index=%lu, status=%lu (windows error: '%s') -- %s",
5839 sizeof(
status), &len, NULL))
5842 "WARNING: The TAP-Windows driver rejected a TAP_WIN_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
5848 msg(
M_INFO,
"Sleeping for %d seconds...", s);
5861 msg(
M_FATAL,
"ERROR: --dev tun also requires --ifconfig");
5872 ep[0] = htonl(tt->
local);
5876 status = DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_TUN, ep,
sizeof(ep), ep,
sizeof(ep),
5882 "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
5890 status ?
"SUCCEEDED" :
"FAILED");
5896 ep[0] = htonl(tt->
local);
5899 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT, ep,
sizeof(ep), ep,
5900 sizeof(ep), &len, NULL))
5903 "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun");
5918 ep[0] = htonl(tt->
local);
5948#ifndef SIMULATE_DHCP_FAILED
5949 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_DHCP_MASQ, ep,
sizeof(ep), ep,
sizeof(ep),
5953 "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode");
5957 "Notified TAP-Windows driver to set a DHCP IP/netmask of %s/%s on interface %s [DHCP-serv: %s, lease-time: %d]",
5972 "ERROR: The TAP-Windows driver rejected a TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call");
5977 msg(
M_WARN,
"DHCP option string not set due to error");
6024 snprintf(tuntap_device_path,
sizeof(tuntap_device_path),
"%s%s%s", USERMODEDEVICEDIR,
6025 device_guid, TAP_WIN_SUFFIX);
6026 path = tuntap_device_path;
6031 tt->
hand = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
6032 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
6033 if (tt->
hand == INVALID_HANDLE_VALUE)
6052 uint8_t actual_buffer[256];
6062 *device_guid =
get_device_guid(dev_node, actual_buffer,
sizeof(actual_buffer),
6067 msg(
M_FATAL,
"Adapter '%s' not found", dev_node);
6073 "Adapter '%s' is using %s driver, %s expected. If you want to use this device, adjust --windows-driver.",
6080 msg(
M_FATAL,
"Failed to open %s adapter: %s",
6086 int device_number = 0;
6087 int adapters_created = 0;
6100 if ((++adapters_created > 10)
6103 msg(
M_FATAL,
"All %s adapters on this system are currently in use or disabled.",
6162 *dhcp_masq_post =
true;
6184 bool dhcp_masq =
false;
6185 bool dhcp_masq_post =
false;
6226open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
6233 "Some --dhcp-option or --dns options require DHCP server,"
6234 " which is not supported by the selected %s driver. They will be"
6245 const char *device_guid = NULL;
6353 if (!CancelIo(tt->
hand))
6355 msg(
M_WARN |
M_ERRNO,
"Warning: CancelIO failed on %s adapter", adaptertype);
6359 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped read event on %s adapter", adaptertype);
6362 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped write event on %s adapter", adaptertype);
6368 if (!CloseHandle(tt->
hand))
6370 msg(
M_WARN |
M_ERRNO,
"Warning: CloseHandle failed on %s adapter", adaptertype);
6446 "Warning: DeleteIPAddress[%u] failed on TAP-Windows adapter, status=%u : %s",
6473 {
"manual" }, {
"netsh" }, {
"ipapi" }, {
"dynamic" }, {
"adaptive" }
6497 return "[unknown --ip-win32 type]";
6526open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *
tt,
void argv_msg(const msglvl_t msglevel, const struct argv *a)
Write the arguments stored in a struct argv via the msg() command.
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
void argv_msg_prefix(const msglvl_t msglevel, const struct argv *a, const char *prefix)
Similar to argv_msg() but prefixes the messages being written with a given string.
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
bool argv_printf_cat(struct argv *argres, const char *format,...)
printf() inspired argv concatenation.
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
void free_buf(struct buffer *buf)
bool buf_printf(struct buffer *buf, const char *format,...)
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 void buf_set_write(struct buffer *buf, uint8_t *data, int size)
#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)
bool build_dhcp_options_string(struct buffer *buf, const struct tuntap_options *o)
void env_set_destroy(struct env_set *es)
void setenv_int(struct env_set *es, const char *name, int value)
void setenv_str(struct env_set *es, const char *name, const char *value)
void env_set_add(struct env_set *es, const char *str)
struct env_set * env_set_create(struct gc_arena *gc)
void set_nonblock(socket_descriptor_t fd)
void set_cloexec(socket_descriptor_t fd)
static SERVICE_STATUS status
void management_set_state(struct management *man, const int state, const char *detail, const in_addr_t *tun_local_ip, const struct in6_addr *tun_local_ip6, const struct openvpn_sockaddr *local, const struct openvpn_sockaddr *remote)
void management_sleep(const int n)
A sleep function that services the management layer for n seconds rather than doing nothing.
#define OPENVPN_STATE_ASSIGN_IP
static void net_ctx_reset(openvpn_net_ctx_t *ctx)
static void net_ctx_free(openvpn_net_ctx_t *ctx)
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
const char * print_topology(const int topology)
const char * time_string(time_t t, 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.
int len
Length in bytes of the actual content within the allocated memory.
int offset
Offset in bytes of the actual content within the allocated memory.
Contains all state information for one tunnel.
const char * device_interface
struct device_instance_id_interface * next
LPBYTE net_cfg_instance_id
Packet geometry parameters.
Garbage collection arena used to keep track of dynamically allocated memory.
struct gc_entry * list
First element of the linked list of gc_entry structures.
struct man_connection connection
struct route_gateway_address gateway
enum tun_driver_type windows_driver
struct in6_addr dns6[N_DHCP_ADDR]
in_addr_t wins[N_DHCP_ADDR]
in_addr_t dns[N_DHCP_ADDR]
bool dhcp_masq_custom_offset
const char * domain_search_list[N_SEARCH_LIST_LEN]
struct rw_handle rw_handle
enum tun_driver_type backend_driver
The backend driver that used for this tun/tap device.
bool did_ifconfig_ipv6_setup
if the internal variables related to ifconfig-ipv6 of this struct have been set up.
struct tuntap_options options
struct in6_addr remote_ipv6
bool did_ifconfig_setup
if the internal variables related to ifconfig of this struct have been set up.
struct overlapped_io writes
in_addr_t adapter_netmask
struct overlapped_io reads
struct in6_addr local_ipv6
bool ipapi_context_defined
static const char * get_unspecified_device_guid(const int device_number, uint8_t *actual_name, int actual_name_size, const struct tap_reg *tap_reg_src, const struct panel_reg *panel_reg_src, enum tun_driver_type *windows_driver, struct gc_arena *gc)
void ipconfig_register_dns(const struct env_set *es)
void tun_show_debug(struct tuntap *tt)
static const struct tap_reg * get_tap_reg(struct gc_arena *gc)
static DWORD get_adapter_index_method_1(const char *guid)
static void tuntap_post_open(struct tuntap *tt, const char *device_guid)
static bool do_address_service(const bool add, const short family, const struct tuntap *tt)
static void clear_tuntap(struct tuntap *tuntap)
static const char * netsh_get_id(const char *dev_node, struct gc_arena *gc)
void open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt, openvpn_net_ctx_t *ctx)
int dev_type_enum(const char *dev, const char *dev_type)
static const struct panel_reg * get_panel_reg(struct gc_arena *gc)
void close_tun_handle(struct tuntap *tt)
void fork_register_dns_action(struct tuntap *tt)
static bool test_adapter_ip_netmask(const IP_ADAPTER_INFO *ai, const in_addr_t ip, const in_addr_t netmask)
static void do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu, const struct env_set *es, openvpn_net_ctx_t *ctx)
do_ifconfig_ipv6 - perform platform specific ifconfig6 commands
static void netsh_enable_dhcp(DWORD adapter_index)
static const GUID GUID_DEVINTERFACE_NET
static bool do_create_adapter_service(HANDLE msg_channel, enum tun_driver_type driver_type)
Requests the interactive service to create a VPN adapter of the specified type.
void show_tap_win_adapters(msglvl_t msglevel, msglvl_t warnlevel)
bool dhcp_renew_by_adapter_index(const DWORD adapter_index)
static void tuntap_get_version_info(const struct tuntap *tt)
static bool service_enable_dhcp(const struct tuntap *tt)
static void netsh_delete_address_dns(const struct tuntap *tt, bool ipv6, struct gc_arena *gc)
static void exec_command(const char *prefix, const struct argv *a, int n, msglvl_t msglevel)
int ascii2ipset(const char *name)
const IP_ADAPTER_INFO * get_tun_adapter(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
static void check_addr_clash(const char *name, int type, in_addr_t public, in_addr_t local, in_addr_t remote_netmask)
bool is_adapter_up(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
static void tuntap_set_ptp(const struct tuntap *tt)
static void undo_ifconfig_ipv4(struct tuntap *tt, openvpn_net_ctx_t *ctx)
static bool tun_try_open_device(struct tuntap *tt, const char *device_guid, const struct device_instance_id_interface *device_instance_id_interface)
static DWORD get_adapter_index(const char *guid)
static void netsh_ifconfig(const struct tuntap_options *to, DWORD adapter_index, const in_addr_t ip, const in_addr_t netmask, const unsigned int flags)
const IP_ADAPTER_INFO * get_adapter_info(DWORD index, struct gc_arena *gc)
static bool dhcp_release(const struct tuntap *tt)
struct tuntap * init_tun(const char *dev, const char *dev_type, int topology, const char *ifconfig_local_parm, const char *ifconfig_remote_netmask_parm, const char *ifconfig_ipv6_local_parm, int ifconfig_ipv6_netbits_parm, const char *ifconfig_ipv6_remote_parm, struct addrinfo *local_public, struct addrinfo *remote_public, const bool strict_warn, struct env_set *es, openvpn_net_ctx_t *ctx, struct tuntap *tt)
static void fork_dhcp_action(struct tuntap *tt)
static void show_adapter(msglvl_t msglevel, const IP_ADAPTER_INFO *a, struct gc_arena *gc)
const char * tun_stat(const struct tuntap *tt, unsigned int rwflags, struct gc_arena *gc)
static bool get_adapter_ip_netmask(const IP_ADAPTER_INFO *ai, const int n, in_addr_t *ip, in_addr_t *netmask)
const IP_PER_ADAPTER_INFO * get_per_adapter_info(const DWORD index, struct gc_arena *gc)
static void ifconfig_sanity_check(bool tun_p2p, in_addr_t addr)
int tun_write_win32(struct tuntap *tt, struct buffer *buf)
#define DHCP_STATUS_DISABLED
static const char * get_device_guid(const char *name, uint8_t *actual_name, int actual_name_size, enum tun_driver_type *windows_driver, const struct tap_reg *tap_reg, const struct panel_reg *panel_reg, struct gc_arena *gc)
bool is_ip_in_adapter_subnet(const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask)
static void delete_temp_addresses(DWORD index)
static void tuntap_set_ip_addr(struct tuntap *tt, const char *device_guid, bool dhcp_masq_post)
const char * tap_win_getinfo(const struct tuntap *tt, struct gc_arena *gc)
static const struct tap_reg * get_adapter_by_name(const char *name, const struct tap_reg *tap_reg, const struct panel_reg *panel_reg)
static const IP_ADAPTER_INDEX_MAP * get_interface_info(DWORD index, struct gc_arena *gc)
static const IP_INTERFACE_INFO * get_interface_info_list(struct gc_arena *gc)
bool is_dev_type(const char *dev, const char *dev_type, const char *match_type)
static uint32_t dhcp_masq_addr(const in_addr_t local, const in_addr_t netmask, const int offset)
#define DHCP_STATUS_UNDEF
#define DHCP_STATUS_ENABLED
static void netsh_ifconfig_options(const char *type, const in_addr_t *addr_list, const int addr_len, const IP_ADDR_STRING *current, DWORD adapter_index, const bool test_first)
static void tuntap_set_ip_props(const struct tuntap *tt, bool *dhcp_masq, bool *dhcp_masq_post)
static void register_dns_service(const struct tuntap *tt)
static void do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu, const struct env_set *es, openvpn_net_ctx_t *ctx)
do_ifconfig_ipv4 - perform platform specific ifconfig commands
int tun_write_queue(struct tuntap *tt, struct buffer *buf)
bool dhcp_release_by_adapter_index(const DWORD adapter_index)
void delete_route_connected_v6_net(const struct tuntap *tt)
bool tun_standby(struct tuntap *tt)
static void tuntap_dhcp_mask(const struct tuntap *tt, const char *device_guid)
static void init_ip_addr_string2(IP_ADDR_STRING *dest, const IP_ADDR_STRING *src1, const IP_ADDR_STRING *src2)
void do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu, const struct env_set *es, openvpn_net_ctx_t *ctx)
do_ifconfig - configure the tunnel interface
const char * dev_type_string(const char *dev, const char *dev_type)
static const char ifconfig_warn_how_to_silence[]
static const struct device_instance_id_interface * get_device_instance_id_interface(struct gc_arena *gc)
void close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
static const char * guid_to_name(const char *guid, const struct panel_reg *panel_reg)
static DWORD get_adapter_index_method_2(const char *guid)
static int dhcp_status(DWORD index)
const IP_ADAPTER_INFO * get_adapter_info_list(struct gc_arena *gc)
void tap_allow_nonadmin_access(const char *dev_node)
bool tun_name_is_fixed(const char *dev)
static bool ip_addr_member_of(const in_addr_t addr, const IP_ADDR_STRING *ias)
static const char * format_ip_addr_string(const IP_ADDR_STRING *ip, struct gc_arena *gc)
const IP_ADAPTER_INFO * get_adapter(const IP_ADAPTER_INFO *ai, DWORD index)
static void at_least_one_tap_win(const struct tap_reg *tap_reg)
void show_adapters(msglvl_t msglevel)
static void add_route_connected_v6_net(struct tuntap *tt, const struct env_set *es)
void warn_on_use_of_common_subnets(openvpn_net_ctx_t *ctx)
static bool dhcp_renew(const struct tuntap *tt)
static void undo_ifconfig_ipv6(struct tuntap *tt, openvpn_net_ctx_t *ctx)
int tun_read_queue(struct tuntap *tt, int maxsize)
static void do_dns_domain_pwsh(bool add, const struct tuntap *tt)
void init_tun_post(struct tuntap *tt, const struct frame *frame, const struct tuntap_options *options)
static void tuntap_set_connected(const struct tuntap *tt)
static const struct tap_reg * get_adapter_by_guid(const char *guid, const struct tap_reg *tap_reg)
static void do_dns_domain_service(bool add, const struct tuntap *tt)
static void tuntap_get_mtu(struct tuntap *tt)
const char * ifconfig_options_string(const struct tuntap *tt, bool remote, bool disable, struct gc_arena *gc)
const char * guess_tuntap_dev(const char *dev, const char *dev_type, const char *dev_node, struct gc_arena *gc)
const char * ipset2ascii(int index)
void do_ifconfig_setenv(const struct tuntap *tt, struct env_set *es)
static bool do_set_mtu_service(const struct tuntap *tt, const short family, const int mtu)
void undo_ifconfig(struct tuntap *tt, openvpn_net_ctx_t *ctx)
undo_ifconfig - undo configuration of the tunnel interface
bool is_tun_p2p(const struct tuntap *tt)
static void windows_set_mtu(const int iface_index, const short family, const int mtu)
const char * ipset2ascii_all(struct gc_arena *gc)
static int get_adapter_n_ip_netmask(const IP_ADAPTER_INFO *ai)
void tun_standby_init(struct tuntap *tt)
void show_valid_win32_tun_subnets(void)
static void tap_allow_nonadmin_access_handle(const char *device_path, HANDLE hand)
void ip_addr_string_to_array(in_addr_t *dest, int *dest_len, const IP_ADDR_STRING *src)
static void netsh_set_dns6_servers(const struct in6_addr *addr_list, const int addr_len, DWORD adapter_index)
Set the ipv6 dns servers on the specified interface.
static const GUID GUID_DEVCLASS_NET
const char * print_tun_backend_driver(enum tun_driver_type driver)
Return a string representation of the tun backed driver type.
static void do_wins_service(bool add, const struct tuntap *tt)
static void netsh_command(const struct argv *a, int n, msglvl_t msglevel)
DWORD adapter_index_of_ip(const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count, in_addr_t *netmask)
static void do_dns_service(bool add, const short family, const struct tuntap *tt)
void tun_open_device(struct tuntap *tt, const char *dev_node, const char **device_guid, struct gc_arena *gc)
void verify_255_255_255_252(in_addr_t local, in_addr_t remote)
static bool ip_addr_one_to_one(const in_addr_t *a1, const int a1len, const IP_ADDR_STRING *ias)
#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)
void overlapped_io_close(struct overlapped_io *o)
void netcmd_semaphore_release(void)
char * get_win_sys_path(void)
void netcmd_semaphore_lock(void)
bool send_msg_iservice(HANDLE pipe, const void *data, DWORD size, ack_message_t *ack, const char *context)
Send the size bytes in buffer data to the interactive service pipe and read the result in ack.
bool init_security_attributes_allow_all(struct security_attributes *obj)
#define IOSTATE_IMMEDIATE_RETURN
#define POWERSHELL_PATH_SUFFIX
#define WIN_IPCONFIG_PATH_SUFFIX
static bool overlapped_io_active(struct overlapped_io *o)
#define NETSH_PATH_SUFFIX