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,
416 argv_printf(&
argv,
"%s%s nicconfig where (InterfaceIndex=%ld) call SetDNSDomain '%s'",
466 msg(
M_NONFATAL,
"TUN: creating %s adapter using service failed: %s [status=%u]",
484static void solaris_error_close(
struct tuntap *tt,
const struct env_set *
es,
const char *actual,
490#if defined(TARGET_DARWIN)
491#include <sys/kern_control.h>
492#include <net/if_utun.h>
493#include <sys/sys_domain.h>
499is_dev_type(
const char *dev,
const char *dev_type,
const char *match_type)
508 return !strcmp(dev_type, match_type);
512 return !strncmp(dev, match_type, strlen(match_type));
547 return "[unknown-dev-type]";
585 const bool looks_like_netmask = ((addr & 0xFF000000) == 0xFF000000);
588 if (looks_like_netmask)
591 "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",
597 if (!looks_like_netmask)
600 "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",
613 in_addr_t remote_netmask)
617 msg(
M_INFO,
"CHECK_ADDR_CLASH type=%d public=%s local=%s, remote_netmask=%s",
628 const in_addr_t test_netmask = 0xFFFFFF00;
629 const in_addr_t public_net =
public & test_netmask;
630 const in_addr_t local_net = local & test_netmask;
631 const in_addr_t remote_net = remote_netmask & test_netmask;
633 if (
public == local ||
public == remote_netmask)
636 "WARNING: --%s address [%s] conflicts with --ifconfig address pair [%s, %s]. %s",
641 if (public_net == local_net || public_net == remote_net)
644 "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",
651 const in_addr_t public_network =
public & remote_netmask;
652 const in_addr_t virtual_network = local & remote_netmask;
653 if (public_network == virtual_network)
656 "WARNING: --%s address [%s] conflicts with --ifconfig subnet [%s, %s] -- local and remote addresses cannot be inside of the --ifconfig subnet. %s",
673 if ((rgi.
flags & needed) == needed)
676 if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100)
679 "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.");
693 if (
tt->did_ifconfig_setup && !disable)
772 msg(
M_FATAL,
"Error: problem with tun vs. tap setting");
798 setenv_str(
es,
"ifconfig_remote", ifconfig_remote_netmask);
802 setenv_str(
es,
"ifconfig_netmask", ifconfig_remote_netmask);
811 setenv_str(
es,
"ifconfig_ipv6_local", ifconfig_ipv6_local);
813 setenv_str(
es,
"ifconfig_ipv6_remote", ifconfig_ipv6_remote);
827 const char *dev_type,
829 const char *ifconfig_local_parm,
830 const char *ifconfig_remote_netmask_parm,
831 const char *ifconfig_ipv6_local_parm,
832 int ifconfig_ipv6_netbits_parm,
833 const char *ifconfig_ipv6_remote_parm,
834 struct addrinfo *local_public,
struct addrinfo *remote_public,
const bool strict_warn,
846 if (ifconfig_local_parm && ifconfig_remote_netmask_parm)
859 ifconfig_local_parm, 0, NULL, NULL);
863 ifconfig_remote_netmask_parm, 0, NULL, NULL);
870 struct addrinfo *curele;
878 for (curele = local_public; curele; curele = curele->ai_next)
880 if (curele->ai_family == AF_INET)
882 const in_addr_t local =
883 ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
888 for (curele = remote_public; curele; curele = curele->ai_next)
890 if (curele->ai_family == AF_INET)
892 const in_addr_t remote =
893 ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
918 if (ifconfig_ipv6_local_parm && ifconfig_ipv6_remote_parm)
924 if (inet_pton(AF_INET6, ifconfig_ipv6_local_parm, &tt->
local_ipv6) != 1
925 || inet_pton(AF_INET6, ifconfig_ipv6_remote_parm, &tt->
remote_ipv6) != 1)
927 msg(
M_FATAL,
"init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary",
928 ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm);
1007#if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || defined(TARGET_NETBSD) \
1008 || defined(TARGET_OPENBSD)
1019create_arbitrary_remote(
struct tuntap *tt)
1025 if (remote == tt->
local)
1047#if !defined(TARGET_LINUX)
1053#if defined(TARGET_LINUX)
1054 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1056 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1059 if (net_iface_up(ctx, ifname,
true) < 0)
1061 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1066 msg(
M_FATAL,
"Linux can't add IPv6 to interface %s", ifname);
1068#elif defined(TARGET_ANDROID)
1071 snprintf(out6,
sizeof(out6),
"%s/%d %d", ifconfig_ipv6_local, tt->
netbits_ipv6, tun_mtu);
1072 management_android_control(
management,
"IFCONFIG6", out6);
1073#elif defined(TARGET_SOLARIS)
1082 argv_printf(&
argv,
"%s %s inet6 plumb %s/%d %s mtu %d up", IFCONFIG_PATH, ifname,
1083 ifconfig_ipv6_local, tt->
netbits_ipv6, ifconfig_ipv6_remote, tun_mtu);
1093 solaris_error_close(tt,
es, ifname,
true);
1105 argv_printf(&
argv,
"%s %s inet6 addif %s/%d up", IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
1112 solaris_error_close(tt,
es, ifname,
true);
1117 argv_printf(&
argv,
"%s %s inet6 mtu %d", IFCONFIG_PATH, ifname, tun_mtu);
1121#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) || defined(TARGET_DARWIN) \
1122 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1123 argv_printf(&
argv,
"%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
1129#if defined(TARGET_FREEBSD) && __FreeBSD_version >= 1200000 && __FreeBSD_version < 1300000
1151#elif defined(TARGET_AIX)
1152 argv_printf(&
argv,
"%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
1163#elif defined(_WIN32)
1167 "******** NOTE: Please manually set the v6 IP of '%s' to %s (if it is not already set)",
1168 ifname, ifconfig_ipv6_local);
1197 argv_printf(&
argv,
"%s%s interface ipv6 set address %lu %s/%d store=active",
1216 "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.");
1219#if !defined(TARGET_LINUX)
1238#if !defined(_WIN32) && !defined(TARGET_ANDROID)
1245#if !defined(TARGET_LINUX)
1246 const char *ifconfig_local = NULL;
1247 const char *ifconfig_remote_netmask = NULL;
1258#if defined(TARGET_LINUX)
1259 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1261 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1264 if (net_iface_up(ctx, ifname,
true) < 0)
1266 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1273 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1280 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1283#elif defined(TARGET_ANDROID)
1286 snprintf(out,
sizeof(out),
"%s %s %d %s", ifconfig_local, ifconfig_remote_netmask, tun_mtu,
1288 management_android_control(
management,
"IFCONFIG", out);
1290#elif defined(TARGET_SOLARIS)
1298 argv_printf(&
argv,
"%s %s %s %s mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local,
1299 ifconfig_remote_netmask, tun_mtu);
1304 solaris_error_close(tt,
es, ifname,
false);
1307 argv_printf(&
argv,
"%s %s netmask 255.255.255.255", IFCONFIG_PATH, ifname);
1311 argv_printf(&
argv,
"%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH, ifname,
1312 ifconfig_local, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1316 argv_printf(&
argv,
"%s %s %s netmask %s up", IFCONFIG_PATH, ifname, ifconfig_local,
1317 ifconfig_remote_netmask);
1323 solaris_error_close(tt,
es, ifname,
false);
1339#elif defined(TARGET_OPENBSD)
1341 in_addr_t remote_end;
1352 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask 255.255.255.255 up -link0", IFCONFIG_PATH,
1353 ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1357 remote_end = create_arbitrary_remote(tt);
1358 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask %s up -link0", IFCONFIG_PATH, ifname,
1360 ifconfig_remote_netmask);
1364 argv_printf(&
argv,
"%s %s %s netmask %s mtu %d link0", IFCONFIG_PATH, ifname,
1365 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1382#elif defined(TARGET_NETBSD)
1383 in_addr_t remote_end = INADDR_ANY;
1387 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask 255.255.255.255 up", IFCONFIG_PATH, ifname,
1388 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1392 remote_end = create_arbitrary_remote(tt);
1393 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH, ifname,
1395 ifconfig_remote_netmask);
1404 argv_printf(&
argv,
"%s %s %s netmask %s mtu %d", IFCONFIG_PATH, ifname, ifconfig_local,
1405 ifconfig_remote_netmask, tun_mtu);
1422#elif defined(TARGET_DARWIN)
1430 msg(
M_INFO,
"NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
1436 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask 255.255.255.255 up", IFCONFIG_PATH, ifname,
1437 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1441 argv_printf(&
argv,
"%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH, ifname,
1442 ifconfig_local, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1446 argv_printf(&
argv,
"%s %s %s netmask %s mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local,
1447 ifconfig_remote_netmask, tun_mtu);
1465#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1470 argv_printf(&
argv,
"%s %s %s %s mtu %d netmask 255.255.255.255 up", IFCONFIG_PATH, ifname,
1471 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1476 argv_printf(&
argv,
"%s %s %s/%d mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local, netbits,
1483#elif defined(TARGET_AIX)
1491 msg(
M_FATAL,
"no tun support on AIX (canthappen)");
1495 argv_printf(&
argv,
"%s %s %s netmask %s mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local,
1496 ifconfig_remote_netmask, tun_mtu);
1503#elif defined(_WIN32)
1507 "******** NOTE: Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
1508 ifname, ifconfig_local, ifconfig_remote_netmask);
1542#elif defined(TARGET_HAIKU)
1544 argv_printf(&
argv,
"%s %s inet %s %s mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local,
1545 ifconfig_remote_netmask, tun_mtu);
1551 "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.");
1554#if !defined(TARGET_LINUX)
1568#ifdef ENABLE_MANAGEMENT
1593#if defined(TARGET_LINUX)
1610#elif defined(TARGET_FREEBSD)
1628#if defined(TARGET_LINUX)
1633#elif defined(TARGET_FREEBSD)
1679#ifdef TARGET_SOLARIS
1684#if defined(TARGET_OPENBSD) || defined(TARGET_DARWIN)
1704#include <netinet/ip.h>
1708header_modify_read_write_return(
int len)
1712 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
1721write_tun_header(
struct tuntap *tt, uint8_t *buf,
int len)
1733 type = htonl(AF_INET6);
1737 type = htonl(AF_INET);
1740 iv[0].iov_base = &type;
1741 iv[0].iov_len =
sizeof(type);
1742 iv[1].iov_base = buf;
1743 iv[1].iov_len = len;
1745 return header_modify_read_write_return(writev(tt->fd, iv, 2));
1749 return write(tt->fd, buf, len);
1754read_tun_header(
struct tuntap *tt, uint8_t *buf,
int len)
1761 iv[0].iov_base = &type;
1762 iv[0].iov_len =
sizeof(type);
1763 iv[1].iov_base = buf;
1764 iv[1].iov_len = len;
1766 return header_modify_read_write_return(readv(tt->fd, iv, 2));
1770 return read(tt->fd, buf, len);
1781#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1783tun_dco_enabled(
struct tuntap *tt)
1790#if !(defined(_WIN32) || defined(TARGET_LINUX) || defined(TARGET_SOLARIS))
1792open_tun_generic(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt)
1795 char dynamic_name[256];
1796 bool dynamic_opened =
false;
1803 snprintf(tunname,
sizeof(tunname),
"%s", dev_node);
1815 for (
int i = 0;
i < 256; ++
i)
1819#if defined(TARGET_HAIKU)
1822 snprintf(tunname,
sizeof(tunname),
"/dev/%s%s%d", dev, sep,
i);
1823 snprintf(dynamic_name,
sizeof(dynamic_name),
"%s%s%d", dev, sep,
i);
1824 if ((tt->fd = open(tunname, O_RDWR)) > 0)
1826 dynamic_opened =
true;
1831 if (!dynamic_opened)
1833 msg(
M_FATAL,
"Cannot allocate TUN/TAP dev dynamically");
1841 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
1845 if (!dynamic_opened)
1848 if (if_nametoindex(dev) > 0)
1850 msg(
M_INFO,
"TUN/TAP device %s exists previously, keep at program end", dev);
1854 if ((tt->fd = open(tunname, O_RDWR)) < 0)
1856 msg(
M_ERR,
"Cannot open TUN/TAP dev %s", tunname);
1862 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
1869#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1871open_tun_dco_generic(
const char *dev,
const char *dev_type,
struct tuntap *tt,
1874 char dynamic_name[256];
1875 bool dynamic_opened =
false;
1885 if (strcmp(dev,
"tun") == 0)
1887 for (
int i = 0;
i < 256; ++
i)
1889 snprintf(dynamic_name,
sizeof(dynamic_name),
"%s%d", dev,
i);
1893 dynamic_opened =
true;
1894 msg(
M_INFO,
"DCO device %s opened", dynamic_name);
1898 else if (ret == -EPERM)
1903 if (!dynamic_opened)
1905 msg(
M_FATAL,
"Cannot allocate DCO dev dynamically");
1919 msg(
M_INFO,
"DCO device %s already exists, won't be destroyed at shutdown", dev);
1924 msg(
M_ERR,
"Cannot open DCO device %s: %s (%d)", dev, strerror(-ret), ret);
1928 msg(
M_INFO,
"DCO device %s opened", dev);
1937#if !(defined(_WIN32) || defined(TARGET_SOLARIS))
1939close_tun_generic(
struct tuntap *tt)
1951#if defined(TARGET_ANDROID)
1953open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
1956#define ANDROID_TUNNAME "vpnservice-tun"
1961 int oldtunfd = tt->fd;
1967 management_android_control(
management,
"DNS6SERVER",
1973 management_android_control(
management,
"DNSSERVER",
1985 buf_printf(&buf,
"%s %d",
tt->options.http_proxy,
tt->options.http_proxy_port);
2015 msg(
M_ERR,
"ERROR: Cannot open TUN");
2042#elif defined(TARGET_LINUX)
2044#ifndef HAVE_LINUX_SOCKIOS_H
2045#error header file linux/sockios.h required
2051open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *
tt,
2056 if (tun_dco_enabled(tt))
2058 open_tun_dco_generic(dev, dev_type, tt, ctx);
2065 const char *node = dev_node;
2068 node =
"/dev/net/tun";
2074 if ((tt->fd = open(node, O_RDWR)) < 0)
2076 msg(
M_ERR,
"ERROR: Cannot open TUN/TAP dev %s", node);
2083 ifr.ifr_flags = IFF_NO_PI;
2085#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2086 ifr.ifr_flags |= IFF_ONE_QUEUE;
2094 ifr.ifr_flags |= IFF_TUN;
2098 ifr.ifr_flags |= IFF_TAP;
2102 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device", dev);
2108 if (strcmp(dev,
"tun") && strcmp(dev,
"tap"))
2117 if (ioctl(tt->fd, TUNSETIFF, (
void *)&ifr) < 0)
2119 msg(
M_ERR,
"ERROR: Cannot ioctl TUNSETIFF %s", dev);
2122 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2127#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2130 struct ifreq netifr;
2133 if ((ctl_fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
2136 strncpynt(netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
2137 netifr.ifr_qlen = tt->
options.txqueuelen;
2138 if (ioctl(ctl_fd, SIOCSIFTXQLEN, (
void *)&netifr) >= 0)
2144 msg(
M_WARN |
M_ERRNO,
"Note: Cannot set tx queue length on %s", ifr.ifr_name);
2150 msg(
M_WARN |
M_ERRNO,
"Note: Cannot open control socket on %s", ifr.ifr_name);
2165open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2173#ifdef ENABLE_FEATURE_TUN_PERSIST
2177#define TUNSETGROUP _IOW('T', 206, int)
2181tuncfg(
const char *dev,
const char *dev_type,
const char *dev_node,
int persist_mode,
2192 open_tun(dev, dev_type, dev_node, tt, ctx);
2193 if (ioctl(tt->fd, TUNSETPERSIST, persist_mode) < 0)
2195 msg(
M_ERR,
"Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
2197 if (username != NULL)
2203 msg(
M_ERR,
"Cannot get user entry for %s", username);
2207 msg(
M_ERR,
"Cannot ioctl TUNSETOWNER(%s) %s", username, dev);
2210 if (groupname != NULL)
2216 msg(
M_ERR,
"Cannot get group entry for %s", groupname);
2220 msg(
M_ERR,
"Cannot ioctl TUNSETGROUP(%s) %s", groupname, dev);
2224 msg(
M_INFO,
"Persist state set to: %s", (persist_mode ?
"ON" :
"OFF"));
2234#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
2235 if (tun_dco_enabled(tt))
2240 close_tun_generic(tt);
2247 return write(tt->fd, buf, len);
2253 return read(tt->fd, buf, len);
2256#elif defined(TARGET_SOLARIS)
2259#error I need the symbol TUNNEWPPA from net/if_tun.h
2263open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2266 int if_fd = -1, ip_muxid = -1, arp_muxid = -1, arp_fd = -1, ppa = -1;
2269 const char *ip_node = NULL, *arp_node = NULL;
2270 const char *dev_tuntap_type;
2272 struct strioctl strioc_if, strioc_ppa;
2282 ip_node =
"/dev/udp";
2285 dev_node =
"/dev/tun";
2287 dev_tuntap_type =
"tun";
2288 link_type = I_PLINK;
2292 ip_node =
"/dev/udp";
2295 dev_node =
"/dev/tap";
2297 arp_node = dev_node;
2298 dev_tuntap_type =
"tap";
2299 link_type = I_PLINK;
2303 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device", dev);
2306 if ((tt->ip_fd = open(ip_node, O_RDWR, 0)) < 0)
2308 msg(
M_ERR,
"Can't open %s", ip_node);
2311 if ((tt->fd = open(dev_node, O_RDWR, 0)) < 0)
2313 msg(
M_ERR,
"Can't open %s", dev_node);
2321 while (*ptr && !isdigit((
int)*ptr))
2329 strioc_ppa.ic_cmd = TUNNEWPPA;
2330 strioc_ppa.ic_timout = 0;
2331 strioc_ppa.ic_len =
sizeof(ppa);
2332 strioc_ppa.ic_dp = (
char *)&ppa;
2336 bool found_one =
false;
2337 while (!found_one && ppa < 64)
2339 int new_ppa = ioctl(tt->fd, I_STR, &strioc_ppa);
2342 msg(
M_INFO,
"open_tun: got dynamic interface '%s%d'", dev_tuntap_type, new_ppa);
2347 if (errno != EEXIST)
2349 msg(
M_ERR,
"open_tun: unexpected error trying to find free %s interface",
2356 msg(
M_ERR,
"open_tun: could not find free %s interface, give up.", dev_tuntap_type);
2361 if ((ppa = ioctl(tt->fd, I_STR, &strioc_ppa)) < 0)
2363 msg(
M_ERR,
"Can't assign PPA for new interface (%s%d)", dev_tuntap_type, ppa);
2367 if ((if_fd = open(dev_node, O_RDWR, 0)) < 0)
2369 msg(
M_ERR,
"Can't open %s (2)", dev_node);
2372 if (ioctl(if_fd, I_PUSH,
"ip") < 0)
2374 msg(
M_ERR,
"Can't push IP module");
2380 if (ioctl(if_fd, IF_UNITSEL, (
char *)&ppa) < 0)
2382 msg(
M_ERR,
"Can't set PPA %d", ppa);
2389 snprintf(tt->
actual_name, 32,
"%s%d", dev_tuntap_type, ppa);
2393 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2400 if (ioctl(if_fd, SIOCSLIFNAME, &ifr) < 0)
2402 msg(
M_ERR,
"Can't set PPA %d", ppa);
2404 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2409 if (ioctl(if_fd, I_PUSH,
"arp") < 0)
2411 msg(
M_ERR,
"Can't push ARP module");
2417 if (ioctl(tt->ip_fd, I_POP, NULL) < 0)
2423 if (ioctl(tt->ip_fd, I_PUSH,
"arp") < 0)
2425 msg(
M_ERR,
"Can't push ARP module");
2429 if ((arp_fd = open(arp_node, O_RDWR, 0)) < 0)
2431 msg(
M_ERR,
"Can't open %s", arp_node);
2434 if (ioctl(arp_fd, I_PUSH,
"arp") < 0)
2436 msg(
M_ERR,
"Can't push ARP module");
2440 strioc_if.ic_cmd = SIOCSLIFNAME;
2441 strioc_if.ic_timout = 0;
2442 strioc_if.ic_len =
sizeof(ifr);
2443 strioc_if.ic_dp = (
char *)𝔦
2444 if (ioctl(arp_fd, I_STR, &strioc_if) < 0)
2446 msg(
M_ERR,
"Can't set ifname to arp");
2450 if ((ip_muxid = ioctl(tt->ip_fd, link_type, if_fd)) < 0)
2452 msg(
M_ERR,
"Can't link %s device to IP", dev_tuntap_type);
2457 if ((arp_muxid = ioctl(tt->ip_fd, link_type, arp_fd)) < 0)
2459 msg(
M_ERR,
"Can't link %s device to ARP", dev_tuntap_type);
2466 ifr.lifr_ip_muxid = ip_muxid;
2469 ifr.lifr_arp_muxid = arp_muxid;
2472 if (ioctl(tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0)
2476 ioctl(tt->ip_fd, I_PUNLINK, arp_muxid);
2478 ioctl(tt->ip_fd, I_PUNLINK, ip_muxid);
2479 msg(
M_ERR,
"Can't set multiplexor id");
2490solaris_close_tun(
struct tuntap *tt)
2508 if (ioctl(tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0)
2513 if (ioctl(tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0)
2520 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0)
2526 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0)
2550 solaris_close_tun(tt);
2559solaris_error_close(
struct tuntap *tt,
const struct env_set *
es,
const char *actual,
2585 sbuf.buf = (
char *)buf;
2586 return putmsg(tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
2596 sbuf.buf = (
char *)buf;
2597 return getmsg(tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
2600#elif defined(TARGET_OPENBSD)
2603open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2606 open_tun_generic(dev, dev_type, dev_node, tt);
2611 struct tuninfo info;
2613 if (ioctl(tt->fd, TUNGIFINFO, &info) < 0)
2619 info.flags |= IFF_MULTICAST;
2622 if (ioctl(tt->fd, TUNSIFINFO, &info) < 0)
2647 close_tun_generic(tt);
2659 close_tun_generic(tt);
2671 return write_tun_header(tt, buf, len);
2677 return read_tun_header(tt, buf, len);
2680#elif defined(TARGET_NETBSD)
2697open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2704 if (strcmp(dev,
"tap") == 0)
2707 if ((tt->fd = open(
"/dev/tap", O_RDWR)) < 0)
2709 msg(
M_FATAL,
"Cannot allocate NetBSD TAP dev dynamically");
2711 if (ioctl(tt->fd, TAPGIFNAME, (
void *)&ifr) < 0)
2713 msg(
M_FATAL,
"Cannot query NetBSD TAP device name");
2717 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2726 open_tun_generic(dev, dev_type, dev_node, tt);
2731 int i = IFF_POINTOPOINT | IFF_MULTICAST;
2732 ioctl(tt->fd, TUNSIFMODE, &
i);
2734 ioctl(tt->fd, TUNSLMODE, &
i);
2739 if (ioctl(tt->fd, TUNSIFHEAD, &
i) < 0)
2760 close_tun_generic(tt);
2772 close_tun_generic(tt);
2782netbsd_modify_read_write_return(
int len)
2786 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
2807 type = htonl(AF_INET6);
2811 type = htonl(AF_INET);
2814 iv[0].iov_base = (
char *)&type;
2815 iv[0].iov_len =
sizeof(type);
2816 iv[1].iov_base = buf;
2817 iv[1].iov_len = len;
2819 return netbsd_modify_read_write_return(writev(tt->fd, iv, 2));
2823 return write(tt->fd, buf, len);
2835 iv[0].iov_base = (
char *)&type;
2836 iv[0].iov_len =
sizeof(type);
2837 iv[1].iov_base = buf;
2838 iv[1].iov_len = len;
2840 return netbsd_modify_read_write_return(readv(tt->fd, iv, 2));
2844 return read(tt->fd, buf, len);
2848#elif defined(TARGET_FREEBSD)
2851freebsd_modify_read_write_return(
int len)
2855 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
2864open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2867 if (tun_dco_enabled(tt))
2869 open_tun_dco_generic(dev, dev_type, tt, ctx);
2873 open_tun_generic(dev, dev_type, dev_node, tt);
2878 int i = IFF_POINTOPOINT | IFF_MULTICAST;
2881 i = IFF_BROADCAST | IFF_MULTICAST;
2884 if (ioctl(tt->fd, TUNSIFMODE, &
i) < 0)
2891 if (ioctl(tt->fd, TUNSIFHEAD, &
i) < 0)
2913 close_tun_generic(tt);
2926 close_tun_generic(tt);
2944 iph = (
struct ip *)buf;
2948 type = htonl(AF_INET6);
2952 type = htonl(AF_INET);
2955 iv[0].iov_base = (
char *)&type;
2956 iv[0].iov_len =
sizeof(type);
2957 iv[1].iov_base = buf;
2958 iv[1].iov_len = len;
2960 return freebsd_modify_read_write_return(writev(tt->fd, iv, 2));
2964 return write(tt->fd, buf, len);
2976 iv[0].iov_base = (
char *)&type;
2977 iv[0].iov_len =
sizeof(type);
2978 iv[1].iov_base = buf;
2979 iv[1].iov_len = len;
2981 return freebsd_modify_read_write_return(readv(tt->fd, iv, 2));
2985 return read(tt->fd, buf, len);
2989#elif defined(TARGET_DRAGONFLY)
2992dragonfly_modify_read_write_return(
int len)
2996 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
3005open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3008 open_tun_generic(dev, dev_type, dev_node, tt);
3015 ioctl(tt->fd, TUNSLMODE, &
i);
3017 ioctl(tt->fd, TUNSIFHEAD, &
i);
3026 close_tun_generic(tt);
3039 iph = (
struct ip *)buf;
3043 type = htonl(AF_INET6);
3047 type = htonl(AF_INET);
3050 iv[0].iov_base = (
char *)&type;
3051 iv[0].iov_len =
sizeof(type);
3052 iv[1].iov_base = buf;
3053 iv[1].iov_len = len;
3055 return dragonfly_modify_read_write_return(writev(tt->fd, iv, 2));
3059 return write(tt->fd, buf, len);
3071 iv[0].iov_base = (
char *)&type;
3072 iv[0].iov_len =
sizeof(type);
3073 iv[1].iov_base = buf;
3074 iv[1].iov_len = len;
3076 return dragonfly_modify_read_write_return(readv(tt->fd, iv, 2));
3080 return read(tt->fd, buf, len);
3084#elif defined(TARGET_DARWIN)
3106utun_open_helper(
struct ctl_info ctlInfo,
int utunnum)
3108 struct sockaddr_ctl sc;
3111 fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
3115 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (socket(SYSPROTO_CONTROL))", utunnum);
3119 if (ioctl(fd, CTLIOCGINFO, &ctlInfo) == -1)
3122 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (ioctl(CTLIOCGINFO))", utunnum);
3127 sc.sc_id = ctlInfo.ctl_id;
3128 sc.sc_len =
sizeof(sc);
3129 sc.sc_family = AF_SYSTEM;
3130 sc.ss_sysaddr = AF_SYS_CONTROL;
3132 sc.sc_unit = utunnum + 1;
3138 if (connect(fd, (
struct sockaddr *)&sc,
sizeof(sc)) < 0)
3140 msg(
M_INFO |
M_ERRNO,
"Opening utun%d failed (connect(AF_SYS_CONTROL))", utunnum);
3152open_darwin_utun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt)
3154 struct ctl_info ctlInfo;
3158 socklen_t utunname_len =
sizeof(utunname);
3162 if (dev_node && (strcmp(
"utun", dev_node) != 0))
3164 if (sscanf(dev_node,
"utun%d", &utunnum) != 1)
3167 "Cannot parse 'dev-node %s' please use 'dev-node utunX'"
3168 "to use a utun device number X",
3175 if (strlcpy(ctlInfo.ctl_name, UTUN_CONTROL_NAME,
sizeof(ctlInfo.ctl_name))
3176 >=
sizeof(ctlInfo.ctl_name))
3178 msg(
M_ERR,
"Opening utun: UTUN_CONTROL_NAME too long");
3184 for (utunnum = 0; utunnum < 255; utunnum++)
3188 ASSERT(snprintf(ifname,
sizeof(ifname),
"utun%d", utunnum) > 0);
3189 if (if_nametoindex(ifname))
3193 fd = utun_open_helper(ctlInfo, utunnum);
3204 fd = utun_open_helper(ctlInfo, utunnum);
3216 if (getsockopt(fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, utunname, &utunname_len))
3223 msg(
M_INFO,
"Opened utun device %s", utunname);
3228open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3232 if ((!dev_node && tt->
type ==
DEV_TYPE_TUN) || (dev_node && !strncmp(dev_node,
"utun", 4)))
3238 msg(
M_FATAL,
"Cannot use utun devices with --dev-type %s",
3244 open_darwin_utun(dev, dev_type, dev_node, tt);
3251 msg(
M_INFO,
"Failed to open utun device. Falling back to /dev/tun device");
3252 open_tun_generic(dev, dev_type, NULL, tt);
3268 if (dev_node && strcmp(dev_node,
"tun") == 0)
3273 open_tun_generic(dev, dev_type, dev_node, tt);
3289 argv_printf(&
argv,
"%s delete -inet6 %s", ROUTE_PATH, ifconfig_ipv6_local);
3294 close_tun_generic(tt);
3305 return write_tun_header(tt, buf, len);
3309 return write(tt->fd, buf, len);
3318 return read_tun_header(tt, buf, len);
3322 return read(tt->fd, buf, len);
3326#elif defined(TARGET_AIX)
3329open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3333 char dynamic_name[20];
3338 msg(
M_FATAL,
"no support for 'tun' devices on AIX");
3341 if (strncmp(dev,
"tap", 3) != 0 || dev_node)
3344 "'--dev %s' and/or '--dev-node' not supported on AIX, use '--dev tap0', 'tap1', etc.",
3348 if (strcmp(dev,
"tap") == 0)
3351 for (
i = 0;
i < 99;
i++)
3353 snprintf(tunname,
sizeof(tunname),
"/dev/tap%d",
i);
3354 if (access(tunname, F_OK) < 0 && errno == ENOENT)
3361 msg(
M_FATAL,
"cannot find unused tap device");
3364 snprintf(dynamic_name,
sizeof(dynamic_name),
"tap%d",
i);
3377 msg(
M_FATAL,
"TAP device name must be '--dev tapNNNN'");
3380 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
3385 if (access(tunname, F_OK) < 0 && errno == ENOENT)
3404 if ((tt->fd = open(tunname, O_RDWR)) < 0)
3406 msg(
M_ERR,
"Cannot open TAP device '%s'", tunname);
3411 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
3438 close_tun_generic(tt);
3451 return write(tt->fd, buf, len);
3457 return read(tt->fd, buf, len);
3460#elif defined(_WIN32)
3491 dmsg(
D_WIN32_IO,
"WIN32 I/O: TAP Read immediate return [%d,%d]", (
int)len,
3496 err = GetLastError();
3497 if (err == ERROR_IO_PENDING)
3509 dmsg(
D_WIN32_IO,
"WIN32 I/O: TAP Read error [%d] : %s", (
int)len,
3551 err = GetLastError();
3552 if (err == ERROR_IO_PENDING)
3584 err = GetLastError();
3602 HDEVINFO dev_info_set;
3608 SetupDiGetClassDevsEx(&
GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
3609 if (dev_info_set == INVALID_HANDLE_VALUE)
3611 err = GetLastError();
3612 msg(
M_FATAL,
"Error [%u] opening device information set key: %s", (
unsigned int)err,
3617 for (DWORD
i = 0;; ++
i)
3619 SP_DEVINFO_DATA device_info_data;
3622 char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3624 char device_instance_id[256];
3628 ULONG dev_interface_list_size;
3631 ZeroMemory(&device_info_data,
sizeof(SP_DEVINFO_DATA));
3632 device_info_data.cbSize =
sizeof(SP_DEVINFO_DATA);
3633 res = SetupDiEnumDeviceInfo(dev_info_set,
i, &device_info_data);
3636 if (GetLastError() == ERROR_NO_MORE_ITEMS)
3646 dev_key = SetupDiOpenDevRegKey(dev_info_set, &device_info_data, DICS_FLAG_GLOBAL, 0,
3647 DIREG_DRV, KEY_QUERY_VALUE);
3648 if (dev_key == INVALID_HANDLE_VALUE)
3655 status = RegQueryValueEx(dev_key, net_cfg_instance_id_string, NULL, &data_type,
3657 if (
status != ERROR_SUCCESS)
3662 len =
sizeof(device_instance_id);
3663 res = SetupDiGetDeviceInstanceId(dev_info_set, &device_info_data, device_instance_id, len,
3670 cr = CM_Get_Device_Interface_List_Size(&dev_interface_list_size,
3672 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3674 if (cr != CR_SUCCESS)
3679 char *dev_interface_list =
gc_malloc(dev_interface_list_size,
false,
gc);
3681 dev_interface_list, dev_interface_list_size,
3682 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3683 if (cr != CR_SUCCESS)
3688 char *dev_if = dev_interface_list;
3691 while (strlen(dev_if) > 0)
3709 last->
next = dev_iif;
3713 dev_if += strlen(dev_if) + 1;
3717 RegCloseKey(dev_key);
3720 SetupDiDestroyDeviceInfoList(dev_info_set);
3735 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ADAPTER_KEY, 0, KEY_READ, &adapter_key);
3737 if (
status != ERROR_SUCCESS)
3739 msg(
M_FATAL,
"Error opening registry key: %s", ADAPTER_KEY);
3745 char enum_name[256];
3746 char unit_string[256];
3748 char component_id_string[] =
"ComponentId";
3749 char component_id[256];
3750 char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3751 BYTE net_cfg_instance_id[256];
3754 len =
sizeof(enum_name);
3755 status = RegEnumKeyEx(adapter_key,
i, enum_name, &len, NULL, NULL, NULL, NULL);
3756 if (
status == ERROR_NO_MORE_ITEMS)
3760 else if (
status != ERROR_SUCCESS)
3762 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s", ADAPTER_KEY);
3765 snprintf(unit_string,
sizeof(unit_string),
"%s\\%s", ADAPTER_KEY, enum_name);
3767 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, unit_string, 0, KEY_READ, &unit_key);
3769 if (
status != ERROR_SUCCESS)
3775 len =
sizeof(component_id);
3776 status = RegQueryValueEx(unit_key, component_id_string, NULL, &data_type,
3777 (LPBYTE)component_id, &len);
3779 if (
status != ERROR_SUCCESS || data_type != REG_SZ)
3781 dmsg(
D_REGISTRY,
"Error opening registry key: %s\\%s", unit_string,
3782 component_id_string);
3786 len =
sizeof(net_cfg_instance_id);
3787 status = RegQueryValueEx(unit_key, net_cfg_instance_id_string, NULL, &data_type,
3788 net_cfg_instance_id, &len);
3790 if (
status == ERROR_SUCCESS && data_type == REG_SZ)
3794 if (strcasecmp(component_id, TAP_WIN_COMPONENT_ID) == 0
3795 || strcasecmp(component_id,
"root\\" TAP_WIN_COMPONENT_ID) == 0)
3799 else if (strcasecmp(component_id,
"ovpn-dco") == 0)
3827 RegCloseKey(unit_key);
3832 RegCloseKey(adapter_key);
3840 HKEY network_connections_key;
3846 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ,
3847 &network_connections_key);
3849 if (
status != ERROR_SUCCESS)
3851 msg(
M_FATAL,
"Error opening registry key: %s", NETWORK_CONNECTIONS_KEY);
3856 char enum_name[256];
3857 char connection_string[256];
3858 HKEY connection_key;
3859 WCHAR name_data[256];
3861 const WCHAR name_string[] = L
"Name";
3863 len =
sizeof(enum_name);
3864 status = RegEnumKeyEx(network_connections_key,
i, enum_name, &len, NULL, NULL, NULL, NULL);
3865 if (
status == ERROR_NO_MORE_ITEMS)
3869 else if (
status != ERROR_SUCCESS)
3871 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s", NETWORK_CONNECTIONS_KEY);
3874 snprintf(connection_string,
sizeof(connection_string),
"%s\\%s\\Connection",
3875 NETWORK_CONNECTIONS_KEY, enum_name);
3877 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, connection_string, 0, KEY_READ, &connection_key);
3879 if (
status != ERROR_SUCCESS)
3881 dmsg(
D_REGISTRY,
"Error opening registry key: %s", connection_string);
3885 len =
sizeof(name_data);
3886 status = RegQueryValueExW(connection_key, name_string, NULL, &name_type,
3887 (LPBYTE)name_data, &len);
3889 if (
status != ERROR_SUCCESS || name_type != REG_SZ)
3891 dmsg(
D_REGISTRY,
"Error opening registry key: %s\\%s\\%ls", NETWORK_CONNECTIONS_KEY,
3892 connection_string, name_string);
3901 n = WideCharToMultiByte(CP_UTF8, 0, name_data, -1, NULL, 0, NULL, NULL);
3903 WideCharToMultiByte(CP_UTF8, 0, name_data, -1,
name, n, NULL, NULL);
3918 RegCloseKey(connection_key);
3923 RegCloseKey(network_connections_key);
3935 const unsigned int mask = 3;
3936 const char *err = NULL;
3938 if (local == remote)
3940 err =
"must be different";
3943 if ((local & (~mask)) != (remote & (~mask)))
3946 "must exist within the same 255.255.255.252 subnet. This is a limitation of --dev tun when used with the TAP-WIN32 driver";
3949 if ((local & mask) == 0 || (local & mask) == 3 || (remote & mask) == 0 || (remote & mask) == 3)
3952 "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";
3961 "There is a problem in your selection of --ifconfig endpoints [local=%s, remote=%s]. The local and remote VPN endpoints %s. Try '" PACKAGE
3962 " --show-valid-subnets' option for more info.",
3973 printf(
"On Windows, point-to-point IP support (i.e. --dev tun)\n");
3974 printf(
"is emulated by the TAP-Windows driver. The major limitation\n");
3975 printf(
"imposed by this approach is that the --ifconfig local and\n");
3976 printf(
"remote endpoints must be part of the same 255.255.255.252\n");
3977 printf(
"subnet. The following list shows examples of endpoint\n");
3978 printf(
"pairs which satisfy this requirement. Only the final\n");
3979 printf(
"component of the IP address pairs is at issue.\n\n");
3980 printf(
"As an example, the following option would be correct:\n");
3981 printf(
" --ifconfig 10.7.0.5 10.7.0.6 (on host A)\n");
3982 printf(
" --ifconfig 10.7.0.6 10.7.0.5 (on host B)\n");
3983 printf(
"because [5,6] is part of the below list.\n\n");
3985 for (
i = 0;
i < 256;
i += 4)
3987 printf(
"[%3d,%3d] ",
i + 1,
i + 2);
4005 bool warn_panel_null =
false;
4006 bool warn_panel_dup =
false;
4007 bool warn_tap_dup =
false;
4018 msg(msglev,
"Available adapters [name, GUID, driver]:");
4038 warn_panel_dup =
true;
4040 else if (links == 0)
4044 warn_panel_null =
true;
4045 msg(msglev,
"[NULL] %s", tr->
guid);
4054 if (tr != tr1 && !strcmp(tr->
guid, tr1->
guid))
4056 warn_tap_dup =
true;
4064 msg(warnlev,
"WARNING: Some TAP-Windows adapters have duplicate GUIDs");
4070 "WARNING: Some TAP-Windows adapters have duplicate links from the Network Connections control panel");
4073 if (warn_panel_null)
4076 "WARNING: Some TAP-Windows adapters have no link from the Network Connections control panel");
4139 msg(
M_FATAL,
"There are no TAP-Windows or ovpn-dco adapters "
4140 "on this system. You should be able to create an adapter "
4141 "by using tapctl.exe utility.");
4151 const struct tap_reg *tap_reg_src,
4201 if (windows_driver !=
NULL)
4230 ASSERT(actual_name_size > 0);
4276const IP_ADAPTER_INFO *
4280 IP_ADAPTER_INFO *pi = NULL;
4283 if ((
status = GetAdaptersInfo(NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4285 msg(
M_INFO,
"GetAdaptersInfo #1 failed (status=%u) : %s", (
unsigned int)
status,
4290 pi = (PIP_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4291 if ((
status = GetAdaptersInfo(pi, &size)) != NO_ERROR)
4293 msg(
M_INFO,
"GetAdaptersInfo #2 failed (status=%u) : %s", (
unsigned int)
status,
4301const IP_PER_ADAPTER_INFO *
4305 IP_PER_ADAPTER_INFO *pi = NULL;
4310 if ((
status = GetPerAdapterInfo(index, NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4312 msg(
M_INFO,
"GetPerAdapterInfo #1 failed (status=%u) : %s", (
unsigned int)
status,
4317 pi = (PIP_PER_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4318 if ((
status = GetPerAdapterInfo((ULONG)index, pi, &size)) == ERROR_SUCCESS)
4324 msg(
M_INFO,
"GetPerAdapterInfo #2 failed (status=%u) : %s", (
unsigned int)
status,
4332static const IP_INTERFACE_INFO *
4336 IP_INTERFACE_INFO *ii = NULL;
4339 if ((
status = GetInterfaceInfo(NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)
4341 msg(
M_INFO,
"GetInterfaceInfo #1 failed (status=%u) : %s", (
unsigned int)
status,
4346 ii = (PIP_INTERFACE_INFO)
gc_malloc(size,
false,
gc);
4347 if ((
status = GetInterfaceInfo(ii, &size)) == NO_ERROR)
4353 msg(
M_INFO,
"GetInterfaceInfo #2 failed (status=%u) : %s", (
unsigned int)
status,
4360static const IP_ADAPTER_INDEX_MAP *
4367 for (
i = 0;
i < list->NumAdapters; ++
i)
4369 const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[
i];
4370 if (index == inter->Index)
4384const IP_ADAPTER_INFO *
4389 const IP_ADAPTER_INFO *a;
4392 for (a = ai; a != NULL; a = a->Next)
4394 if (a->Index == index)
4403const IP_ADAPTER_INFO *
4415 const IP_ADDR_STRING *ip = &ai->IpAddressList;
4439 const IP_ADDR_STRING *iplist = &ai->IpAddressList;
4449 iplist = iplist->Next;
4455 const char *ip_str = iplist->IpAddress.String;
4456 const char *netmask_str = iplist->IpMask.String;
4457 bool succeed1 =
false;
4458 bool succeed2 =
false;
4460 if (ip_str && netmask_str && strlen(ip_str) && strlen(netmask_str))
4462 *ip =
getaddr(getaddr_flags, ip_str, 0, &succeed1, NULL);
4463 *netmask =
getaddr(getaddr_flags, netmask_str, 0, &succeed2, NULL);
4464 ret = (succeed1 ==
true && succeed2 ==
true);
4477 in_addr_t ip_adapter = 0;
4478 in_addr_t netmask_adapter = 0;
4480 return (
status && ip_adapter == ip && netmask_adapter == netmask);
4488const IP_ADAPTER_INFO *
4514 for (
i = 0;
i < n; ++
i)
4516 in_addr_t ip, netmask;
4551 if (highest_netmask)
4553 *highest_netmask = 0;
4559 for (
i = 0;
i < n; ++
i)
4561 in_addr_t adapter_ip, adapter_netmask;
4564 if (adapter_ip && adapter_netmask
4565 && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))
4567 if (highest_netmask && adapter_netmask > *highest_netmask)
4569 *highest_netmask = adapter_netmask;
4584 in_addr_t highest_netmask = 0;
4585 int lowest_metric = INT_MAX;
4600 if (first || hn > highest_netmask)
4602 highest_netmask = hn;
4605 lowest_metric = metric;
4614 else if (hn == highest_netmask)
4620 if (metric >= 0 && metric < lowest_metric)
4623 lowest_metric = metric;
4630 dmsg(
D_ROUTE_DEBUG,
"DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d metric=%d",
4632 count ? *count : -1, lowest_metric);
4641 *netmask = highest_netmask;
4653#define DHCP_STATUS_UNDEF 0
4654#define DHCP_STATUS_ENABLED 1
4655#define DHCP_STATUS_DISABLED 2
4668 if (ai->DhcpEnabled)
4694 const IP_ADDR_STRING *ip = &a->IpAddressList;
4698 const DWORD
context = ip->Context;
4702 msg(
M_INFO,
"Successfully deleted previously set dynamic IP/netmask: %s/%s",
4703 ip->IpAddress.String, ip->IpMask.String);
4707 const char *empty =
"0.0.0.0";
4708 if (strcmp(ip->IpAddress.String, empty) || strcmp(ip->IpMask.String, empty))
4711 "NOTE: could not delete previously set dynamic IP/netmask: %s/%s (status=%u)",
4712 ip->IpAddress.String, ip->IpMask.String, (
unsigned int)
status);
4730 swprintf(wbuf,
SIZE(wbuf), L
"\\DEVICE\\TCPIP_%hs", guid);
4731 if (GetAdapterIndex(wbuf, &aindex) != NO_ERROR)
4737 index = (DWORD)aindex;
4752 if (!strcmp(guid,
list->AdapterName))
4754 index =
list->Index;
4775 msg(
M_INFO,
"NOTE: could not get adapter index for %s", guid);
4789 buf_printf(&out,
"%s", ip->IpAddress.String);
4790 if (
strlen(ip->IpMask.String))
4843 msg(msglev,
"SYSTEM ADAPTER LIST");
4846 const IP_ADAPTER_INFO *a;
4849 for (a = ai; a != NULL; a = a->Next)
4872 msg(
M_ERR,
"Error: init SA failed");
4875 status = SetKernelObjectSecurity(hand, DACL_SECURITY_INFORMATION, &
sa.sd);
4878 msg(
M_ERRNO,
"Error: SetKernelObjectSecurity failed on %s", device_path);
4882 msg(
M_INFO |
M_NOPREFIX,
"TAP-Windows device: %s [Non-admin access allowed]", device_path);
4892 const char *device_guid = NULL;
4894 uint8_t actual_buffer[256];
4895 char device_path[256];
4907 msg(
M_FATAL,
"TAP-Windows adapter '%s' not found", dev_node);
4911 snprintf(device_path,
sizeof(device_path),
"%s%s%s", USERMODEDEVICEDIR, device_guid,
4914 hand = CreateFile(device_path, MAXIMUM_ALLOWED, 0,
4915 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
4917 if (hand == INVALID_HANDLE_VALUE)
4919 msg(
M_ERR,
"CreateFile failed on TAP device: %s", device_path);
4927 int device_number = 0;
4941 snprintf(device_path,
sizeof(device_path),
"%s%s%s", USERMODEDEVICEDIR, device_guid,
4944 hand = CreateFile(device_path, MAXIMUM_ALLOWED, 0,
4945 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
4947 if (hand == INVALID_HANDLE_VALUE)
4949 msg(
M_WARN,
"CreateFile failed on TAP device: %s", device_path);
4975 DWORD
status = IpReleaseAddress((IP_ADAPTER_INDEX_MAP *)inter);
4984 "NOTE: Release of DHCP-assigned IP address lease on TAP-Windows adapter failed: %s (code=%u)",
5016 DWORD
status = IpRenewAddress((IP_ADAPTER_INDEX_MAP *)inter);
5025 "WARNING: Failed to renew DHCP IP address lease on TAP-Windows adapter: %s (code=%u)",
5051 for (
i = 0;
i < n; ++
i)
5065 msg(msglevel,
"%s: command failed", prefix);
5078 const char err[] =
"ERROR: Windows ipconfig command failed";
5103 const char *ip_str = src->IpAddress.String;
5105 bool succeed =
false;
5111 if (!ip_str || !strlen(ip_str))
5116 ip =
getaddr(getaddr_flags, ip_str, 0, &succeed, NULL);
5130 msg(
M_INFO,
"ip_addr_string_to_array [%d]", *dest_len);
5131 for (
i = 0;
i < *dest_len; ++
i)
5144 int a2len =
SIZE(a2);
5154 for (
i = 0;
i < a1len; ++
i)
5172 for (
i = 0;
i < len; ++
i)
5198 for (
int i = 0;
i < addr_len; ++
i)
5200 const char *fmt = (
i == 0) ?
"%s%s interface ipv6 set dns %lu static %s"
5201 :
"%s%s interface ipv6 add dns %lu %s";
5218 const IP_ADDR_STRING *current, DWORD adapter_index,
const bool test_first)
5222 bool delete_first =
false;
5223 bool is_dns = !strcmp(type,
"dns");
5230 delete_first =
true;
5235 delete_first =
true;
5250 for (
i = 0;
i < addr_len; ++
i)
5254 const char *fmt = count ?
"%s%s interface ip add %s %lu %s"
5255 :
"%s%s interface ip set %s %lu static %s";
5272 msg(
M_INFO,
"NETSH: %lu %s %s [already set]", adapter_index, type,
5290 dest[0].Next = NULL;
5295 dest[0].Next = &dest[1];
5296 dest[1].Next = NULL;
5302 const in_addr_t netmask,
const unsigned int flags)
5306 const IP_ADAPTER_INFO *ai = NULL;
5307 const IP_PER_ADAPTER_INFO *pai = NULL;
5320 msg(
M_INFO,
"NETSH: %lu %s/%s [already set]", adapter_index,
5337 IP_ADDR_STRING wins[2];
5343 if (ai && ai->HaveWins)
5389 msg(
M_NONFATAL,
"TUN: enabling dhcp using service failed: %s [status=%u if_index=%d]",
5394 msg(
M_INFO,
"DHCP enabled on interface %d using service",
dhcp.iface.index);
5408 MIB_IPINTERFACE_ROW ipiface;
5409 InitializeIpInterfaceEntry(&ipiface);
5410 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
5411 ipiface.Family = family;
5412 ipiface.InterfaceIndex = iface_index;
5413 if (family == AF_INET6 && mtu < 1280)
5416 "NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
5419 err = GetIpInterfaceEntry(&ipiface);
5420 if (err == NO_ERROR)
5422 if (family == AF_INET)
5424 ipiface.SitePrefixLength = 0;
5426 ipiface.NlMtu = mtu;
5427 err = SetIpInterfaceEntry(&ipiface);
5430 if (err != NO_ERROR)
5432 msg(
M_WARN,
"TUN: Setting %s mtu failed: %s [status=%lu if_index=%d]", family_name,
5437 msg(
M_INFO,
"%s MTU set to %d on interface %d using SetIpInterfaceEntry()", family_name,
5479 return BSTR(&actual);
5493 tt->standby_iter = 0;
5505 msg(
M_INFO,
"NOTE: now trying netsh (this may take some time)");
5528 msg(
M_WARN,
"write_dhcp_u8: buffer overflow building DHCP options");
5538 const unsigned int len,
bool *error)
5548 msg(
M_WARN,
"write_dhcp_u32_array: buffer overflow building DHCP options");
5554 msg(
M_WARN,
"write_dhcp_u32_array: size (%d) must be > 0 and <= 255", size);
5559 for (
i = 0;
i <
len; ++
i)
5573 msg(
M_WARN,
"write_dhcp_str: buffer overflow building DHCP options");
5579 msg(
M_WARN,
"write_dhcp_str: string '%s' must be > 0 bytes and <= 255 bytes",
str);
5611 msg(
M_WARN,
"write_dhcp_search_str: temp buffer overflow building DHCP options");
5623 if (*
ptr ==
'.' || *
ptr ==
'\0')
5641 msg(
M_WARN,
"write_search_dhcp_str: buffer overflow building DHCP options");
5647 msg(
M_WARN,
"write_dhcp_search_str: search domain string must be <= 255 bytes");
5665 if (
o->netbios_scope)
5670 if (
o->netbios_node_type)
5680 if (
o->domain_search_list_len > 0)
5692 msg(
M_WARN,
"build_dhcp_options_string: buffer overflow building DHCP options");
5707 if (
tt->options.dhcp_pre_release ||
tt->options.dhcp_renew)
5715 if (
tt->options.dhcp_pre_release)
5719 if (
tt->options.dhcp_renew)
5733 HANDLE msg_channel =
tt->options.msg_channel;
5747 msg(
M_WARN,
"Register_dns failed using service: %s [status=0x%x]",
5753 msg(
M_INFO,
"Register_dns request sent to the service");
5772 buf_printf(&
cmd,
"openvpn --verb %d --register-dns --rdns-internal", verb);
5786 dsa = (local | (~netmask)) + offset;
5790 dsa = (local & netmask) + offset;
5796 "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",
5800 if ((local & netmask) != (dsa & netmask))
5802 msg(
M_FATAL,
"ERROR: --ip-win32 dynamic [offset] : offset is outside of --ifconfig subnet");
5815 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_VERSION, &info,
sizeof(info), &info,
5816 sizeof(info), &len, NULL))
5818 msg(
D_TUNTAP_INFO,
"TAP-Windows Driver Version %d.%d %s", (
int)info[0], (
int)info[1],
5819 (info[2] ?
"(DEBUG)" :
""));
5821 if (!(info[0] == TAP_WIN_MIN_MAJOR && info[1] >= TAP_WIN_MIN_MINOR))
5824 "ERROR: This version of " PACKAGE_NAME
5825 " requires a TAP-Windows driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME
5826 " distribution, a reboot is probably required at this point to get Windows to see the new driver.",
5827 TAP_WIN_MIN_MAJOR, TAP_WIN_MIN_MINOR);
5836 "WARNING: Tap-Win32 driver version %d.%d does not support IPv6 in TUN mode. IPv6 will not work. Upgrade your Tap-Win32 driver.",
5837 (
int)info[0], (
int)info[1]);
5845 "ERROR: Tap-Win32 driver version %d.%d is buggy regarding small IPv4 packets in TUN mode. Upgrade your Tap-Win32 driver.",
5846 (
int)info[0], (
int)info[1]);
5855 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_MTU, &mtu,
sizeof(mtu), &mtu,
sizeof(mtu), &len,
5879 .iface = { .index = index, .name =
"" } };
5888 status = FlushIpNetTable(index);
5893 msg(
M_INFO,
"Successful ARP Flush on interface [%lu] %s", index, device_guid);
5898 "NOTE: FlushIpNetTable failed on interface [%lu] %s (status=%lu) : %s", index,
5913 "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'");
5935 const char *error_suffix =
5936 "I am having trouble using the Windows 'IP helper API' to automatically set the IP address -- consider using other --ip-win32 methods (not 'ipapi')";
5941 msg(
M_FATAL,
"ERROR: unable to get adapter index for interface %s -- %s", device_guid,
5949 "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'");
5962 "Succeeded in adding a temporary IP/netmask of %s/%s to interface %s using the Win32 IP Helper API",
5969 "ERROR: AddIPAddress %s/%s failed on interface %s, index=%lu, status=%lu (windows error: '%s') -- %s",
5985 sizeof(
status), &len, NULL))
5988 "WARNING: The TAP-Windows driver rejected a TAP_WIN_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
5994 msg(
M_INFO,
"Sleeping for %d seconds...", s);
6007 msg(
M_FATAL,
"ERROR: --dev tun also requires --ifconfig");
6018 ep[0] = htonl(tt->
local);
6022 status = DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_TUN, ep,
sizeof(ep), ep,
sizeof(ep),
6028 "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
6036 status ?
"SUCCEEDED" :
"FAILED");
6042 ep[0] = htonl(tt->
local);
6045 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT, ep,
sizeof(ep), ep,
6046 sizeof(ep), &len, NULL))
6049 "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun");
6064 ep[0] = htonl(tt->
local);
6094#ifndef SIMULATE_DHCP_FAILED
6095 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_DHCP_MASQ, ep,
sizeof(ep), ep,
sizeof(ep),
6099 "ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode");
6103 "Notified TAP-Windows driver to set a DHCP IP/netmask of %s/%s on interface %s [DHCP-serv: %s, lease-time: %d]",
6118 "ERROR: The TAP-Windows driver rejected a TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call");
6123 msg(
M_WARN,
"DHCP option string not set due to error");
6170 snprintf(tuntap_device_path,
sizeof(tuntap_device_path),
"%s%s%s", USERMODEDEVICEDIR,
6171 device_guid, TAP_WIN_SUFFIX);
6172 path = tuntap_device_path;
6177 tt->
hand = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
6178 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
6179 if (tt->
hand == INVALID_HANDLE_VALUE)
6198 uint8_t actual_buffer[256];
6208 *device_guid =
get_device_guid(dev_node, actual_buffer,
sizeof(actual_buffer),
6213 msg(
M_FATAL,
"Adapter '%s' not found", dev_node);
6219 "Adapter '%s' is using %s driver, %s expected. If you want to use this device, adjust --windows-driver.",
6226 msg(
M_FATAL,
"Failed to open %s adapter: %s",
6232 int device_number = 0;
6233 int adapters_created = 0;
6246 if ((++adapters_created > 10)
6249 msg(
M_FATAL,
"All %s adapters on this system are currently in use or disabled.",
6308 *dhcp_masq_post =
true;
6330 bool dhcp_masq =
false;
6331 bool dhcp_masq_post =
false;
6372open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
6379 "Some --dhcp-option or --dns options require DHCP server,"
6380 " which is not supported by the selected %s driver. They will be"
6391 const char *device_guid = NULL;
6499 if (!CancelIo(tt->
hand))
6501 msg(
M_WARN |
M_ERRNO,
"Warning: CancelIO failed on %s adapter", adaptertype);
6505 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped read event on %s adapter", adaptertype);
6508 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped write event on %s adapter", adaptertype);
6514 if (!CloseHandle(tt->
hand))
6516 msg(
M_WARN |
M_ERRNO,
"Warning: CloseHandle failed on %s adapter", adaptertype);
6592 "Warning: DeleteIPAddress[%u] failed on TAP-Windows adapter, status=%u : %s",
6619 {
"manual" }, {
"netsh" }, {
"ipapi" }, {
"dynamic" }, {
"adaptive" }
6643 return "[unknown --ip-win32 type]";
6672open_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 void do_dns_domain_wmic(bool add, const struct tuntap *tt)
static bool tun_try_open_device(struct tuntap *tt, const char *device_guid, const struct device_instance_id_interface *device_instance_id_interface)
static 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)
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 WIN_IPCONFIG_PATH_SUFFIX
static bool overlapped_io_active(struct overlapped_io *o)
#define NETSH_PATH_SUFFIX