64 return "tap-windows6";
91const static GUID
GUID_DEVCLASS_NET = { 0x4d36e972L, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 } };
92const static GUID
GUID_DEVINTERFACE_NET = { 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)
103 const in_addr_t netmask,
104 const unsigned int flags);
112 DWORD adapter_index);
116static void exec_command(
const char *prefix,
const struct argv *a,
int n,
int msglevel);
144 if (addr.
family == AF_INET)
149 add ?
"add" :
"remove",
157 add ?
"add" :
"remove",
168 msg(
M_WARN,
"TUN: %s address failed using service: %s [status=%u if_index=%d]",
212 msg(
D_LOW,
"%s dns domain on '%s' (if_index = %d) using service",
221 msg(
M_WARN,
"TUN: %s dns domain failed using service: %s [status=%u if_name=%s]",
227 msg(
M_INFO,
"DNS domain %s using service", (add ?
"set" :
"deleted"));
240 int addr_len = add ? len : 0;
241 const char *ip_proto_name = family == AF_INET6 ?
"IPv6" :
"IPv4";
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",
271 ip_proto_name, addr_len);
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"));
336 if (addr_len > _countof(wins.
addr))
338 addr_len = _countof(wins.
addr);
340 msg(
M_WARN,
"Number of WINS addresses sent to service truncated to %d",
344 for (
int i = 0; i < addr_len; ++i)
349 msg(
D_LOW,
"%s WINS servers on '%s' (if_index = %d) using service",
359 msg(
M_WARN,
"TUN: %s WINS failed using service: %s [status=%u if_name=%s]",
365 msg(
M_INFO,
"WINS servers %s using service", (add ?
"set" :
"deleted"));
378 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
390 if (family == AF_INET6 && mtu < 1280)
392 msg(
M_INFO,
"NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
402 msg(
M_NONFATAL,
"TUN: setting %s mtu using service failed: %s [status=%u if_index=%d]",
407 msg(
M_INFO,
"%s MTU set to %d on interface %d using service", family_name, mtu, mtu_msg.
iface.
index);
425 argv_printf(&
argv,
"%s%s nicconfig where (InterfaceIndex=%ld) call SetDNSDomain '%s'",
435static void solaris_error_close(
struct tuntap *tt,
const struct env_set *
es,
const char *actual,
bool unplumb_inet6);
440#if defined(TARGET_DARWIN)
441#include <sys/kern_control.h>
442#include <net/if_utun.h>
443#include <sys/sys_domain.h>
449is_dev_type(
const char *dev,
const char *dev_type,
const char *match_type)
458 return !strcmp(dev_type, match_type);
462 return !strncmp(dev, match_type, strlen(match_type));
497 return "[unknown-dev-type]";
507 const char *dev_type,
508 const char *dev_node,
538 const bool looks_like_netmask = ((addr & 0xFF000000) == 0xFF000000);
541 if (looks_like_netmask)
543 msg(
M_WARN,
"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",
550 if (!looks_like_netmask)
552 msg(
M_WARN,
"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",
568 in_addr_t remote_netmask)
572 msg(
M_INFO,
"CHECK_ADDR_CLASH type=%d public=%s local=%s, remote_netmask=%s",
583 const in_addr_t test_netmask = 0xFFFFFF00;
584 const in_addr_t public_net =
public &test_netmask;
585 const in_addr_t local_net = local & test_netmask;
586 const in_addr_t remote_net = remote_netmask & test_netmask;
588 if (
public == local ||
public == remote_netmask)
591 "WARNING: --%s address [%s] conflicts with --ifconfig address pair [%s, %s]. %s",
599 if (public_net == local_net || public_net == remote_net)
602 "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",
612 const in_addr_t public_network =
public &remote_netmask;
613 const in_addr_t virtual_network = local & remote_netmask;
614 if (public_network == virtual_network)
617 "WARNING: --%s address [%s] conflicts with --ifconfig subnet [%s, %s] -- local and remote addresses cannot be inside of the --ifconfig subnet. %s",
637 if ((rgi.
flags & needed) == needed)
640 if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100)
642 msg(
M_WARN,
"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.");
656 if (
tt->did_ifconfig_setup && !disable)
741 msg(
M_FATAL,
"Error: problem with tun vs. tap setting");
766 setenv_str(
es,
"ifconfig_remote", ifconfig_remote_netmask);
770 setenv_str(
es,
"ifconfig_netmask", ifconfig_remote_netmask);
779 setenv_str(
es,
"ifconfig_ipv6_local", ifconfig_ipv6_local);
781 setenv_str(
es,
"ifconfig_ipv6_remote", ifconfig_ipv6_remote);
795 const char *dev_type,
797 const char *ifconfig_local_parm,
798 const char *ifconfig_remote_netmask_parm,
799 const char *ifconfig_ipv6_local_parm,
800 int ifconfig_ipv6_netbits_parm,
801 const char *ifconfig_ipv6_remote_parm,
802 struct addrinfo *local_public,
803 struct addrinfo *remote_public,
804 const bool strict_warn,
818 if (ifconfig_local_parm && ifconfig_remote_netmask_parm)
844 ifconfig_remote_netmask_parm,
854 struct addrinfo *curele;
862 for (curele = local_public; curele; curele = curele->ai_next)
864 if (curele->ai_family == AF_INET)
866 const in_addr_t local = ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
875 for (curele = remote_public; curele; curele = curele->ai_next)
877 if (curele->ai_family == AF_INET)
879 const in_addr_t remote = ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
908 if (ifconfig_ipv6_local_parm && ifconfig_ipv6_remote_parm)
915 if (inet_pton( AF_INET6, ifconfig_ipv6_local_parm, &tt->
local_ipv6 ) != 1
916 || inet_pton( AF_INET6, ifconfig_ipv6_remote_parm, &tt->
remote_ipv6 ) != 1)
918 msg(
M_FATAL,
"init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary", ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm );
971 msg(
M_FATAL,
"Cannot allocate memory for ring buffer");
979 msg(
M_FATAL,
"Cannot create events for ring buffer");
1028#if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
1029 || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD)
1040create_arbitrary_remote(
struct tuntap *tt )
1046 if (remote == tt->
local)
1068#if !defined(TARGET_LINUX)
1074#if defined(TARGET_LINUX)
1075 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1077 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1080 if (net_iface_up(ctx, ifname,
true) < 0)
1082 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1085 if (net_addr_v6_add(ctx, ifname, &tt->
local_ipv6,
1088 msg(
M_FATAL,
"Linux can't add IPv6 to interface %s", ifname);
1090#elif defined(TARGET_ANDROID)
1093 snprintf(out6,
sizeof(out6),
"%s/%d %d",
1095 management_android_control(
management,
"IFCONFIG6", out6);
1096#elif defined(TARGET_SOLARIS)
1106 IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
1116 "Solaris ifconfig IPv6 (prepare) failed"))
1118 solaris_error_close(tt,
es, ifname,
true);
1137 solaris_error_close(tt,
es, ifname,
true);
1147#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
1148 || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
1149 || defined(TARGET_DRAGONFLY)
1150 argv_printf(&
argv,
"%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
1155 "generic BSD ifconfig inet6 failed");
1157#if defined(TARGET_FREEBSD) && __FreeBSD_version >= 1200000 \
1158 && __FreeBSD_version < 1300000
1178 "FreeBSD BSD 'ifconfig inet6 -ifdisabled' failed");
1181#elif defined(TARGET_AIX)
1182 argv_printf(&
argv,
"%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
1191 "generic BSD ifconfig inet6 failed");
1194#elif defined (_WIN32)
1197 msg(
M_INFO,
"******** NOTE: Please manually set the v6 IP of '%s' to %s (if it is not already set)",
1198 ifname, ifconfig_ipv6_local);
1227 argv_printf(&
argv,
"%s%s interface ipv6 set address %lu %s/%d store=active",
1229 ifconfig_ipv6_local, netbits);
1245 msg(
M_FATAL,
"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.");
1248#if !defined(TARGET_LINUX)
1267#if !defined(_WIN32) && !defined(TARGET_ANDROID)
1274#if !defined(TARGET_LINUX)
1275 const char *ifconfig_local = NULL;
1276 const char *ifconfig_remote_netmask = NULL;
1287#if defined(TARGET_LINUX)
1288 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1290 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1293 if (net_iface_up(ctx, ifname,
true) < 0)
1295 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1300 if (net_addr_ptp_v4_add(ctx, ifname, &tt->
local,
1303 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1308 if (net_addr_v4_add(ctx, ifname, &tt->
local,
1311 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1314#elif defined(TARGET_ANDROID)
1317 snprintf(out,
sizeof(out),
"%s %s %d %s", ifconfig_local,
1319 management_android_control(
management,
"IFCONFIG", out);
1321#elif defined(TARGET_SOLARIS)
1330 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1335 solaris_error_close(tt,
es, ifname,
false);
1344 ifname, ifconfig_local, ifconfig_local,
1345 ifconfig_remote_netmask, tun_mtu);
1350 IFCONFIG_PATH, ifname, ifconfig_local,
1351 ifconfig_remote_netmask);
1357 solaris_error_close(tt,
es, ifname,
false);
1373#elif defined(TARGET_OPENBSD)
1375 in_addr_t remote_end;
1387 "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
1388 IFCONFIG_PATH, ifname, ifconfig_local,
1389 ifconfig_remote_netmask, tun_mtu);
1393 remote_end = create_arbitrary_remote( tt );
1395 IFCONFIG_PATH, ifname, ifconfig_local,
1397 ifconfig_remote_netmask);
1402 IFCONFIG_PATH, ifname, ifconfig_local,
1403 ifconfig_remote_netmask, tun_mtu);
1420#elif defined(TARGET_NETBSD)
1421 in_addr_t remote_end = INADDR_ANY;
1426 IFCONFIG_PATH, ifname, ifconfig_local,
1427 ifconfig_remote_netmask, tun_mtu);
1431 remote_end = create_arbitrary_remote(tt);
1434 tun_mtu, ifconfig_remote_netmask);
1444 IFCONFIG_PATH, ifname, ifconfig_local,
1445 ifconfig_remote_netmask, tun_mtu);
1462#elif defined(TARGET_DARWIN)
1471 "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
1478 IFCONFIG_PATH, ifname, ifconfig_local,
1479 ifconfig_remote_netmask, tun_mtu);
1484 IFCONFIG_PATH, ifname, ifconfig_local, ifconfig_local,
1485 ifconfig_remote_netmask, tun_mtu);
1490 ifname, ifconfig_local, ifconfig_remote_netmask,
1509#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1515 IFCONFIG_PATH, ifname, ifconfig_local,
1516 ifconfig_remote_netmask, tun_mtu);
1522 ifname, ifconfig_local, netbits, tun_mtu );
1528#elif defined(TARGET_AIX)
1536 msg(
M_FATAL,
"no tun support on AIX (canthappen)");
1541 ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1548#elif defined (_WIN32)
1552 "******** NOTE: Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
1553 ifname, ifconfig_local,
1554 ifconfig_remote_netmask);
1587#elif defined(TARGET_HAIKU)
1590 ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1595 msg(
M_FATAL,
"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.");
1598#if !defined(TARGET_LINUX)
1612#ifdef ENABLE_MANAGEMENT
1642#if defined(TARGET_LINUX)
1650 msg(
M_WARN,
"Linux can't del IP from iface %s",
1658 msg(
M_WARN,
"Linux can't del IP from iface %s",
1662#elif defined(TARGET_FREEBSD)
1681#if defined(TARGET_LINUX)
1687#elif defined(TARGET_FREEBSD)
1733#ifdef TARGET_SOLARIS
1738#if defined(TARGET_OPENBSD) || defined(TARGET_DARWIN)
1758#include <netinet/ip.h>
1762header_modify_read_write_return(
int len)
1766 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
1775write_tun_header(
struct tuntap *tt, uint8_t *buf,
int len)
1787 type = htonl(AF_INET6);
1791 type = htonl(AF_INET);
1794 iv[0].iov_base = &type;
1795 iv[0].iov_len =
sizeof(type);
1796 iv[1].iov_base = buf;
1797 iv[1].iov_len = len;
1799 return header_modify_read_write_return(writev(tt->fd, iv, 2));
1803 return write(tt->fd, buf, len);
1808read_tun_header(
struct tuntap *tt, uint8_t *buf,
int len)
1815 iv[0].iov_base = &type;
1816 iv[0].iov_len =
sizeof(type);
1817 iv[1].iov_base = buf;
1818 iv[1].iov_len = len;
1820 return header_modify_read_write_return(readv(tt->fd, iv, 2));
1824 return read(tt->fd, buf, len);
1835#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1837tun_dco_enabled(
struct tuntap *tt)
1844#if !(defined(_WIN32) || defined(TARGET_LINUX) || defined(TARGET_SOLARIS))
1846open_tun_generic(
const char *dev,
const char *dev_type,
const char *dev_node,
1850 char dynamic_name[256];
1851 bool dynamic_opened =
false;
1858 snprintf(tunname,
sizeof(tunname),
"%s", dev_node);
1870 for (
int i = 0; i < 256; ++i)
1874#if defined(TARGET_HAIKU)
1877 snprintf(tunname,
sizeof(tunname),
1878 "/dev/%s%s%d", dev, sep, i);
1879 snprintf(dynamic_name,
sizeof(dynamic_name),
1880 "%s%s%d", dev, sep, i);
1881 if ((tt->fd = open(tunname, O_RDWR)) > 0)
1883 dynamic_opened =
true;
1888 if (!dynamic_opened)
1890 msg(
M_FATAL,
"Cannot allocate TUN/TAP dev dynamically");
1898 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
1902 if (!dynamic_opened)
1905 if (if_nametoindex( dev ) > 0)
1907 msg(
M_INFO,
"TUN/TAP device %s exists previously, keep at program end", dev );
1911 if ((tt->fd = open(tunname, O_RDWR)) < 0)
1913 msg(
M_ERR,
"Cannot open TUN/TAP dev %s", tunname);
1919 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
1927#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1929open_tun_dco_generic(
const char *dev,
const char *dev_type,
1932 char dynamic_name[256];
1933 bool dynamic_opened =
false;
1943 if (strcmp(dev,
"tun") == 0)
1945 for (
int i = 0; i < 256; ++i)
1947 snprintf(dynamic_name,
sizeof(dynamic_name),
1952 dynamic_opened =
true;
1953 msg(
M_INFO,
"DCO device %s opened", dynamic_name);
1957 else if (ret == -EPERM)
1962 if (!dynamic_opened)
1964 msg(
M_FATAL,
"Cannot allocate DCO dev dynamically");
1978 msg(
M_INFO,
"DCO device %s already exists, won't be destroyed at shutdown",
1984 msg(
M_ERR,
"Cannot open DCO device %s: %s (%d)", dev,
1985 strerror(-ret), ret);
1989 msg(
M_INFO,
"DCO device %s opened", dev);
1998#if !(defined(_WIN32) || defined(TARGET_SOLARIS))
2000close_tun_generic(
struct tuntap *tt)
2012#if defined (TARGET_ANDROID)
2014open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2017#define ANDROID_TUNNAME "vpnservice-tun"
2022 int oldtunfd = tt->fd;
2028 management_android_control(
management,
"DNS6SERVER",
2034 management_android_control(
management,
"DNSSERVER",
2046 buf_printf(&buf,
"%s %d",
tt->options.http_proxy,
tt->options.http_proxy_port);
2076 msg(
M_ERR,
"ERROR: Cannot open TUN");
2103#elif defined(TARGET_LINUX)
2105#ifndef HAVE_LINUX_SOCKIOS_H
2106#error header file linux/sockios.h required
2112open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *
tt,
2117 if (tun_dco_enabled(tt))
2119 open_tun_dco_generic(dev, dev_type, tt, ctx);
2126 const char *node = dev_node;
2129 node =
"/dev/net/tun";
2135 if ((tt->fd = open(node, O_RDWR)) < 0)
2137 msg(
M_ERR,
"ERROR: Cannot open TUN/TAP dev %s", node);
2144 ifr.ifr_flags = IFF_NO_PI;
2146#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2147 ifr.ifr_flags |= IFF_ONE_QUEUE;
2155 ifr.ifr_flags |= IFF_TUN;
2159 ifr.ifr_flags |= IFF_TAP;
2163 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device",
2170 if (strcmp(dev,
"tun") && strcmp(dev,
"tap"))
2179 if (ioctl(tt->fd, TUNSETIFF, (
void *) &ifr) < 0)
2181 msg(
M_ERR,
"ERROR: Cannot ioctl TUNSETIFF %s", dev);
2184 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2189#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2192 struct ifreq netifr;
2195 if ((ctl_fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
2198 strncpynt(netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
2199 netifr.ifr_qlen = tt->
options.txqueuelen;
2200 if (ioctl(ctl_fd, SIOCSIFTXQLEN, (
void *) &netifr) >= 0)
2206 msg(
M_WARN |
M_ERRNO,
"Note: Cannot set tx queue length on %s", ifr.ifr_name);
2212 msg(
M_WARN |
M_ERRNO,
"Note: Cannot open control socket on %s", ifr.ifr_name);
2227open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2235#ifdef ENABLE_FEATURE_TUN_PERSIST
2239#define TUNSETGROUP _IOW('T', 206, int)
2243tuncfg(
const char *dev,
const char *dev_type,
const char *dev_node,
2244 int persist_mode,
const char *username,
const char *groupname,
2254 open_tun(dev, dev_type, dev_node, tt, ctx);
2255 if (ioctl(tt->fd, TUNSETPERSIST, persist_mode) < 0)
2257 msg(
M_ERR,
"Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
2259 if (username != NULL)
2265 msg(
M_ERR,
"Cannot get user entry for %s", username);
2269 msg(
M_ERR,
"Cannot ioctl TUNSETOWNER(%s) %s", username, dev);
2272 if (groupname != NULL)
2278 msg(
M_ERR,
"Cannot get group entry for %s", groupname);
2282 msg(
M_ERR,
"Cannot ioctl TUNSETGROUP(%s) %s", groupname, dev);
2286 msg(
M_INFO,
"Persist state set to: %s", (persist_mode ?
"ON" :
"OFF"));
2296#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
2297 if (tun_dco_enabled(tt))
2302 close_tun_generic(tt);
2309 return write(tt->fd, buf, len);
2315 return read(tt->fd, buf, len);
2318#elif defined(TARGET_SOLARIS)
2321#error I need the symbol TUNNEWPPA from net/if_tun.h
2325open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2328 int if_fd = -1, ip_muxid = -1, arp_muxid = -1, arp_fd = -1, ppa = -1;
2331 const char *ip_node = NULL, *arp_node = NULL;
2332 const char *dev_tuntap_type;
2334 struct strioctl strioc_if, strioc_ppa;
2344 ip_node =
"/dev/udp";
2347 dev_node =
"/dev/tun";
2349 dev_tuntap_type =
"tun";
2350 link_type = I_PLINK;
2354 ip_node =
"/dev/udp";
2357 dev_node =
"/dev/tap";
2359 arp_node = dev_node;
2360 dev_tuntap_type =
"tap";
2361 link_type = I_PLINK;
2365 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device",
2369 if ((tt->ip_fd = open(ip_node, O_RDWR, 0)) < 0)
2371 msg(
M_ERR,
"Can't open %s", ip_node);
2374 if ((tt->fd = open(dev_node, O_RDWR, 0)) < 0)
2376 msg(
M_ERR,
"Can't open %s", dev_node);
2384 while (*ptr && !isdigit((
int) *ptr))
2392 strioc_ppa.ic_cmd = TUNNEWPPA;
2393 strioc_ppa.ic_timout = 0;
2394 strioc_ppa.ic_len =
sizeof(ppa);
2395 strioc_ppa.ic_dp = (
char *)&ppa;
2399 bool found_one =
false;
2400 while (!found_one && ppa < 64)
2402 int new_ppa = ioctl(tt->fd, I_STR, &strioc_ppa);
2405 msg(
M_INFO,
"open_tun: got dynamic interface '%s%d'", dev_tuntap_type, new_ppa );
2410 if (errno != EEXIST)
2412 msg(
M_ERR,
"open_tun: unexpected error trying to find free %s interface", dev_tuntap_type );
2418 msg(
M_ERR,
"open_tun: could not find free %s interface, give up.", dev_tuntap_type );
2423 if ((ppa = ioctl(tt->fd, I_STR, &strioc_ppa)) < 0)
2425 msg(
M_ERR,
"Can't assign PPA for new interface (%s%d)", dev_tuntap_type, ppa );
2429 if ((if_fd = open(dev_node, O_RDWR, 0)) < 0)
2431 msg(
M_ERR,
"Can't open %s (2)", dev_node);
2434 if (ioctl(if_fd, I_PUSH,
"ip") < 0)
2436 msg(
M_ERR,
"Can't push IP module");
2442 if (ioctl(if_fd, IF_UNITSEL, (
char *) &ppa) < 0)
2444 msg(
M_ERR,
"Can't set PPA %d", ppa);
2451 snprintf(tt->
actual_name, 32,
"%s%d", dev_tuntap_type, ppa);
2455 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2462 if (ioctl(if_fd, SIOCSLIFNAME, &ifr) < 0)
2464 msg(
M_ERR,
"Can't set PPA %d", ppa);
2466 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
2471 if (ioctl(if_fd, I_PUSH,
"arp") < 0)
2473 msg(
M_ERR,
"Can't push ARP module");
2479 if (ioctl(tt->ip_fd, I_POP, NULL) < 0)
2485 if (ioctl(tt->ip_fd, I_PUSH,
"arp") < 0)
2487 msg(
M_ERR,
"Can't push ARP module\n");
2491 if ((arp_fd = open(arp_node, O_RDWR, 0)) < 0)
2493 msg(
M_ERR,
"Can't open %s\n", arp_node);
2496 if (ioctl(arp_fd, I_PUSH,
"arp") < 0)
2498 msg(
M_ERR,
"Can't push ARP module\n");
2502 strioc_if.ic_cmd = SIOCSLIFNAME;
2503 strioc_if.ic_timout = 0;
2504 strioc_if.ic_len =
sizeof(ifr);
2505 strioc_if.ic_dp = (
char *)𝔦
2506 if (ioctl(arp_fd, I_STR, &strioc_if) < 0)
2508 msg(
M_ERR,
"Can't set ifname to arp\n");
2512 if ((ip_muxid = ioctl(tt->ip_fd, link_type, if_fd)) < 0)
2514 msg(
M_ERR,
"Can't link %s device to IP", dev_tuntap_type);
2519 if ((arp_muxid = ioctl(tt->ip_fd, link_type, arp_fd)) < 0)
2521 msg(
M_ERR,
"Can't link %s device to ARP", dev_tuntap_type);
2528 ifr.lifr_ip_muxid = ip_muxid;
2531 ifr.lifr_arp_muxid = arp_muxid;
2534 if (ioctl(tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0)
2538 ioctl(tt->ip_fd, I_PUNLINK, arp_muxid);
2540 ioctl(tt->ip_fd, I_PUNLINK, ip_muxid);
2541 msg(
M_ERR,
"Can't set multiplexor id");
2552solaris_close_tun(
struct tuntap *tt)
2571 if (ioctl(tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0)
2576 if (ioctl(tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0)
2583 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0)
2589 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0)
2613 solaris_close_tun(tt);
2623 const char *actual,
bool unplumb_inet6 )
2630 IFCONFIG_PATH, actual );
2652 sbuf.buf = (
char *)buf;
2653 return putmsg(tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
2663 sbuf.buf = (
char *)buf;
2664 return getmsg(tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
2667#elif defined(TARGET_OPENBSD)
2670open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2673 open_tun_generic(dev, dev_type, dev_node, tt);
2678 struct tuninfo info;
2680 if (ioctl(tt->fd, TUNGIFINFO, &info) < 0)
2686 info.flags |= IFF_MULTICAST;
2689 if (ioctl(tt->fd, TUNSIFINFO, &info) < 0)
2714 close_tun_generic(tt);
2727 close_tun_generic(tt);
2739 return write_tun_header(tt, buf, len);
2745 return read_tun_header(tt, buf, len);
2748#elif defined(TARGET_NETBSD)
2765open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2772 if (strcmp(dev,
"tap") == 0)
2775 if ((tt->fd = open(
"/dev/tap", O_RDWR)) < 0)
2777 msg(
M_FATAL,
"Cannot allocate NetBSD TAP dev dynamically");
2779 if (ioctl( tt->fd, TAPGIFNAME, (
void *)&ifr ) < 0)
2781 msg(
M_FATAL,
"Cannot query NetBSD TAP device name");
2785 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2794 open_tun_generic(dev, dev_type, dev_node, tt);
2799 int i = IFF_POINTOPOINT|IFF_MULTICAST;
2800 ioctl(tt->fd, TUNSIFMODE, &i);
2802 ioctl(tt->fd, TUNSLMODE, &i);
2807 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0)
2828 close_tun_generic(tt);
2841 close_tun_generic(tt);
2851netbsd_modify_read_write_return(
int len)
2855 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
2876 type = htonl(AF_INET6);
2880 type = htonl(AF_INET);
2883 iv[0].iov_base = (
char *)&type;
2884 iv[0].iov_len =
sizeof(type);
2885 iv[1].iov_base = buf;
2886 iv[1].iov_len = len;
2888 return netbsd_modify_read_write_return(writev(tt->fd, iv, 2));
2892 return write(tt->fd, buf, len);
2904 iv[0].iov_base = (
char *)&type;
2905 iv[0].iov_len =
sizeof(type);
2906 iv[1].iov_base = buf;
2907 iv[1].iov_len = len;
2909 return netbsd_modify_read_write_return(readv(tt->fd, iv, 2));
2913 return read(tt->fd, buf, len);
2917#elif defined(TARGET_FREEBSD)
2920freebsd_modify_read_write_return(
int len)
2924 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
2933open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2936 if (tun_dco_enabled(tt))
2938 open_tun_dco_generic(dev, dev_type, tt, ctx);
2942 open_tun_generic(dev, dev_type, dev_node, tt);
2947 int i = IFF_POINTOPOINT | IFF_MULTICAST;
2950 i = IFF_BROADCAST | IFF_MULTICAST;
2953 if (ioctl(tt->fd, TUNSIFMODE, &i) < 0)
2960 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0)
2982 close_tun_generic(tt);
2996 close_tun_generic(tt);
3000 "FreeBSD 'destroy tun interface' failed (non-critical)");
3015 iph = (
struct ip *) buf;
3019 type = htonl(AF_INET6);
3023 type = htonl(AF_INET);
3026 iv[0].iov_base = (
char *)&type;
3027 iv[0].iov_len =
sizeof(type);
3028 iv[1].iov_base = buf;
3029 iv[1].iov_len = len;
3031 return freebsd_modify_read_write_return(writev(tt->fd, iv, 2));
3035 return write(tt->fd, buf, len);
3047 iv[0].iov_base = (
char *)&type;
3048 iv[0].iov_len =
sizeof(type);
3049 iv[1].iov_base = buf;
3050 iv[1].iov_len = len;
3052 return freebsd_modify_read_write_return(readv(tt->fd, iv, 2));
3056 return read(tt->fd, buf, len);
3060#elif defined(TARGET_DRAGONFLY)
3063dragonfly_modify_read_write_return(
int len)
3067 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
3076open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3079 open_tun_generic(dev, dev_type, dev_node, tt);
3086 ioctl(tt->fd, TUNSLMODE, &i);
3088 ioctl(tt->fd, TUNSIFHEAD, &i);
3097 close_tun_generic(tt);
3110 iph = (
struct ip *) buf;
3114 type = htonl(AF_INET6);
3118 type = htonl(AF_INET);
3121 iv[0].iov_base = (
char *)&type;
3122 iv[0].iov_len =
sizeof(type);
3123 iv[1].iov_base = buf;
3124 iv[1].iov_len = len;
3126 return dragonfly_modify_read_write_return(writev(tt->fd, iv, 2));
3130 return write(tt->fd, buf, len);
3142 iv[0].iov_base = (
char *)&type;
3143 iv[0].iov_len =
sizeof(type);
3144 iv[1].iov_base = buf;
3145 iv[1].iov_len = len;
3147 return dragonfly_modify_read_write_return(readv(tt->fd, iv, 2));
3151 return read(tt->fd, buf, len);
3155#elif defined(TARGET_DARWIN)
3177utun_open_helper(
struct ctl_info ctlInfo,
int utunnum)
3179 struct sockaddr_ctl sc;
3182 fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
3191 if (ioctl(fd, CTLIOCGINFO, &ctlInfo) == -1)
3200 sc.sc_id = ctlInfo.ctl_id;
3201 sc.sc_len =
sizeof(sc);
3202 sc.sc_family = AF_SYSTEM;
3203 sc.ss_sysaddr = AF_SYS_CONTROL;
3205 sc.sc_unit = utunnum+1;
3211 if (connect(fd, (
struct sockaddr *)&sc,
sizeof(sc)) < 0)
3226open_darwin_utun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt)
3228 struct ctl_info ctlInfo;
3232 socklen_t utunname_len =
sizeof(utunname);
3236 if (dev_node && (strcmp(
"utun", dev_node) != 0 ))
3238 if (sscanf(dev_node,
"utun%d", &utunnum) != 1)
3240 msg(
M_FATAL,
"Cannot parse 'dev-node %s' please use 'dev-node utunX'"
3241 "to use a utun device number X", dev_node);
3248 if (strlcpy(ctlInfo.ctl_name, UTUN_CONTROL_NAME,
sizeof(ctlInfo.ctl_name)) >=
3249 sizeof(ctlInfo.ctl_name))
3251 msg(
M_ERR,
"Opening utun: UTUN_CONTROL_NAME too long");
3257 for (utunnum = 0; utunnum < 255; utunnum++)
3261 ASSERT(snprintf(ifname,
sizeof(ifname),
"utun%d", utunnum) > 0);
3262 if (if_nametoindex(ifname))
3266 fd = utun_open_helper(ctlInfo, utunnum);
3277 fd = utun_open_helper(ctlInfo, utunnum);
3289 if (getsockopt(fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, utunname, &utunname_len))
3296 msg(
M_INFO,
"Opened utun device %s", utunname);
3301open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3306 || (dev_node && !strncmp(dev_node,
"utun", 4)))
3313 msg(
M_FATAL,
"Cannot use utun devices with --dev-type %s",
3319 open_darwin_utun(dev, dev_type, dev_node, tt);
3326 msg(
M_INFO,
"Failed to open utun device. Falling back to /dev/tun device");
3327 open_tun_generic(dev, dev_type, NULL, tt);
3344 if (dev_node && strcmp(dev_node,
"tun")==0)
3349 open_tun_generic(dev, dev_type, dev_node, tt);
3363 const char *ifconfig_ipv6_local =
3367 ROUTE_PATH, ifconfig_ipv6_local );
3372 close_tun_generic(tt);
3383 return write_tun_header(tt, buf, len);
3387 return write(tt->fd, buf, len);
3396 return read_tun_header(tt, buf, len);
3400 return read(tt->fd, buf, len);
3404#elif defined(TARGET_AIX)
3407open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3411 char dynamic_name[20];
3416 msg(
M_FATAL,
"no support for 'tun' devices on AIX" );
3419 if (strncmp( dev,
"tap", 3 ) != 0 || dev_node)
3421 msg(
M_FATAL,
"'--dev %s' and/or '--dev-node' not supported on AIX, use '--dev tap0', 'tap1', etc.", dev );
3424 if (strcmp( dev,
"tap" ) == 0)
3427 for (i = 0; i<99; i++)
3429 snprintf(tunname,
sizeof(tunname),
"/dev/tap%d", i);
3430 if (access( tunname, F_OK ) < 0 && errno == ENOENT)
3437 msg(
M_FATAL,
"cannot find unused tap device" );
3440 snprintf( dynamic_name,
sizeof(dynamic_name),
"tap%d", i );
3447 while (isdigit(*p) )
3453 msg(
M_FATAL,
"TAP device name must be '--dev tapNNNN'" );
3456 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
3461 if (access( tunname, F_OK ) < 0 && errno == ENOENT)
3481 if ((tt->fd = open(tunname, O_RDWR)) < 0)
3483 msg(
M_ERR,
"Cannot open TAP device '%s'", tunname);
3488 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
3517 close_tun_generic(tt);
3530 return write(tt->fd, buf, len);
3536 return read(tt->fd, buf, len);
3539#elif defined(_WIN32)
3581 err = GetLastError();
3582 if (err == ERROR_IO_PENDING)
3638 dmsg(
D_WIN32_IO,
"WIN32 I/O: TAP Write immediate return [%d,%d]",
3644 err = GetLastError();
3645 if (err == ERROR_IO_PENDING)
3679 err = GetLastError();
3697 HDEVINFO dev_info_set;
3702 dev_info_set = SetupDiGetClassDevsEx(&
GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
3703 if (dev_info_set == INVALID_HANDLE_VALUE)
3705 err = GetLastError();
3710 for (DWORD i = 0;; ++i)
3712 SP_DEVINFO_DATA device_info_data;
3715 char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3717 char device_instance_id[256];
3721 ULONG dev_interface_list_size;
3724 ZeroMemory(&device_info_data,
sizeof(SP_DEVINFO_DATA));
3725 device_info_data.cbSize =
sizeof(SP_DEVINFO_DATA);
3726 res = SetupDiEnumDeviceInfo(dev_info_set, i, &device_info_data);
3729 if (GetLastError() == ERROR_NO_MORE_ITEMS)
3739 dev_key = SetupDiOpenDevRegKey(dev_info_set, &device_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE);
3740 if (dev_key == INVALID_HANDLE_VALUE)
3747 status = RegQueryValueEx(dev_key,
3748 net_cfg_instance_id_string,
3753 if (
status != ERROR_SUCCESS)
3758 len =
sizeof(device_instance_id);
3759 res = SetupDiGetDeviceInstanceId(dev_info_set, &device_info_data, device_instance_id, len, &len);
3765 cr = CM_Get_Device_Interface_List_Size(&dev_interface_list_size,
3768 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3770 if (cr != CR_SUCCESS)
3775 char *dev_interface_list =
gc_malloc(dev_interface_list_size,
false,
gc);
3778 dev_interface_list_size,
3779 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3780 if (cr != CR_SUCCESS)
3785 char *dev_if = dev_interface_list;
3788 while (strlen(dev_if) > 0)
3806 last->
next = dev_iif;
3810 dev_if += strlen(dev_if) + 1;
3814 RegCloseKey(dev_key);
3817 SetupDiDestroyDeviceInfoList(dev_info_set);
3839 if (
status != ERROR_SUCCESS)
3841 msg(
M_FATAL,
"Error opening registry key: %s", ADAPTER_KEY);
3847 char enum_name[256];
3848 char unit_string[256];
3850 char component_id_string[] =
"ComponentId";
3851 char component_id[256];
3852 char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3853 BYTE net_cfg_instance_id[256];
3856 len =
sizeof(enum_name);
3866 if (
status == ERROR_NO_MORE_ITEMS)
3870 else if (
status != ERROR_SUCCESS)
3872 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s",
3876 snprintf(unit_string,
sizeof(unit_string),
"%s\\%s",
3877 ADAPTER_KEY, enum_name);
3886 if (
status != ERROR_SUCCESS)
3892 len =
sizeof(component_id);
3893 status = RegQueryValueEx(
3895 component_id_string,
3898 (LPBYTE)component_id,
3901 if (
status != ERROR_SUCCESS || data_type != REG_SZ)
3904 unit_string, component_id_string);
3908 len =
sizeof(net_cfg_instance_id);
3909 status = RegQueryValueEx(
3911 net_cfg_instance_id_string,
3914 net_cfg_instance_id,
3917 if (
status == ERROR_SUCCESS && data_type == REG_SZ)
3921 if (strcasecmp(component_id, TAP_WIN_COMPONENT_ID) == 0
3922 || strcasecmp(component_id,
"root\\" TAP_WIN_COMPONENT_ID) == 0)
3930 else if (strcasecmp(component_id,
"ovpn-dco") == 0)
3958 RegCloseKey(unit_key);
3963 RegCloseKey(adapter_key);
3971 HKEY network_connections_key;
3979 NETWORK_CONNECTIONS_KEY,
3982 &network_connections_key);
3984 if (
status != ERROR_SUCCESS)
3986 msg(
M_FATAL,
"Error opening registry key: %s", NETWORK_CONNECTIONS_KEY);
3991 char enum_name[256];
3992 char connection_string[256];
3993 HKEY connection_key;
3994 WCHAR name_data[256];
3996 const WCHAR name_string[] = L
"Name";
3998 len =
sizeof(enum_name);
4000 network_connections_key,
4008 if (
status == ERROR_NO_MORE_ITEMS)
4012 else if (
status != ERROR_SUCCESS)
4014 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s",
4015 NETWORK_CONNECTIONS_KEY);
4018 snprintf(connection_string,
sizeof(connection_string),
4019 "%s\\%s\\Connection",
4020 NETWORK_CONNECTIONS_KEY, enum_name);
4029 if (
status != ERROR_SUCCESS)
4031 dmsg(
D_REGISTRY,
"Error opening registry key: %s", connection_string);
4035 len =
sizeof(name_data);
4036 status = RegQueryValueExW(
4044 if (
status != ERROR_SUCCESS || name_type != REG_SZ)
4047 NETWORK_CONNECTIONS_KEY, connection_string, name_string);
4056 n = WideCharToMultiByte(CP_UTF8, 0, name_data, -1, NULL, 0, NULL, NULL);
4058 WideCharToMultiByte(CP_UTF8, 0, name_data, -1,
name, n, NULL, NULL);
4073 RegCloseKey(connection_key);
4078 RegCloseKey(network_connections_key);
4090 const unsigned int mask = 3;
4091 const char *err = NULL;
4093 if (local == remote)
4095 err =
"must be different";
4098 if ((local & (~mask)) != (remote & (~mask)))
4100 err =
"must exist within the same 255.255.255.252 subnet. This is a limitation of --dev tun when used with the TAP-WIN32 driver";
4103 if ((local & mask) == 0
4104 || (local & mask) == 3
4105 || (remote & mask) == 0
4106 || (remote & mask) == 3)
4108 err =
"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";
4116 msg(
M_FATAL,
"There is a problem in your selection of --ifconfig endpoints [local=%s, remote=%s]. The local and remote VPN endpoints %s. Try '" PACKAGE
" --show-valid-subnets' option for more info.",
4129 printf(
"On Windows, point-to-point IP support (i.e. --dev tun)\n");
4130 printf(
"is emulated by the TAP-Windows driver. The major limitation\n");
4131 printf(
"imposed by this approach is that the --ifconfig local and\n");
4132 printf(
"remote endpoints must be part of the same 255.255.255.252\n");
4133 printf(
"subnet. The following list shows examples of endpoint\n");
4134 printf(
"pairs which satisfy this requirement. Only the final\n");
4135 printf(
"component of the IP address pairs is at issue.\n\n");
4136 printf(
"As an example, the following option would be correct:\n");
4137 printf(
" --ifconfig 10.7.0.5 10.7.0.6 (on host A)\n");
4138 printf(
" --ifconfig 10.7.0.6 10.7.0.5 (on host B)\n");
4139 printf(
"because [5,6] is part of the below list.\n\n");
4141 for (i = 0; i < 256; i += 4)
4143 printf(
"[%3d,%3d] ", i+1, i+2);
4161 bool warn_panel_null =
false;
4162 bool warn_panel_dup =
false;
4163 bool warn_tap_dup =
false;
4174 msg(msglev,
"Available adapters [name, GUID, driver]:");
4193 warn_panel_dup =
true;
4195 else if (links == 0)
4199 warn_panel_null =
true;
4200 msg(msglev,
"[NULL] %s", tr->
guid);
4209 if (tr != tr1 && !strcmp(tr->
guid, tr1->
guid))
4211 warn_tap_dup =
true;
4219 msg(warnlev,
"WARNING: Some TAP-Windows adapters have duplicate GUIDs");
4224 msg(warnlev,
"WARNING: Some TAP-Windows adapters have duplicate links from the Network Connections control panel");
4227 if (warn_panel_null)
4229 msg(warnlev,
"WARNING: Some TAP-Windows adapters have no link from the Network Connections control panel");
4291 msg(
M_FATAL,
"There are no TAP-Windows, Wintun or ovpn-dco adapters "
4292 "on this system. You should be able to create an adapter "
4293 "by using tapctl.exe utility.");
4303 uint8_t *actual_name,
4304 int actual_name_size,
4305 const struct tap_reg *tap_reg_src,
4356 if (windows_driver !=
NULL)
4389 ASSERT(actual_name_size > 0);
4435const IP_ADAPTER_INFO *
4439 IP_ADAPTER_INFO *pi = NULL;
4442 if ((
status = GetAdaptersInfo(NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4444 msg(
M_INFO,
"GetAdaptersInfo #1 failed (status=%u) : %s",
4450 pi = (PIP_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4451 if ((
status = GetAdaptersInfo(pi, &size)) != NO_ERROR)
4453 msg(
M_INFO,
"GetAdaptersInfo #2 failed (status=%u) : %s",
4462const IP_PER_ADAPTER_INFO *
4466 IP_PER_ADAPTER_INFO *pi = NULL;
4471 if ((
status = GetPerAdapterInfo(index, NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4473 msg(
M_INFO,
"GetPerAdapterInfo #1 failed (status=%u) : %s",
4479 pi = (PIP_PER_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4480 if ((
status = GetPerAdapterInfo((ULONG)index, pi, &size)) == ERROR_SUCCESS)
4486 msg(
M_INFO,
"GetPerAdapterInfo #2 failed (status=%u) : %s",
4495static const IP_INTERFACE_INFO *
4499 IP_INTERFACE_INFO *ii = NULL;
4502 if ((
status = GetInterfaceInfo(NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)
4504 msg(
M_INFO,
"GetInterfaceInfo #1 failed (status=%u) : %s",
4510 ii = (PIP_INTERFACE_INFO)
gc_malloc(size,
false,
gc);
4511 if ((
status = GetInterfaceInfo(ii, &size)) == NO_ERROR)
4517 msg(
M_INFO,
"GetInterfaceInfo #2 failed (status=%u) : %s",
4525static const IP_ADAPTER_INDEX_MAP *
4532 for (i = 0; i < list->NumAdapters; ++i)
4534 const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[i];
4535 if (index == inter->Index)
4549const IP_ADAPTER_INFO *
4554 const IP_ADAPTER_INFO *a;
4557 for (a = ai; a != NULL; a = a->Next)
4559 if (a->Index == index)
4568const IP_ADAPTER_INFO *
4580 const IP_ADDR_STRING *ip = &ai->IpAddressList;
4604 const IP_ADDR_STRING *iplist = &ai->IpAddressList;
4614 iplist = iplist->Next;
4620 const char *ip_str = iplist->IpAddress.String;
4621 const char *netmask_str = iplist->IpMask.String;
4622 bool succeed1 =
false;
4623 bool succeed2 =
false;
4625 if (ip_str && netmask_str && strlen(ip_str) && strlen(netmask_str))
4627 *ip =
getaddr(getaddr_flags, ip_str, 0, &succeed1, NULL);
4628 *netmask =
getaddr(getaddr_flags, netmask_str, 0, &succeed2, NULL);
4629 ret = (succeed1 ==
true && succeed2 ==
true);
4642 in_addr_t ip_adapter = 0;
4643 in_addr_t netmask_adapter = 0;
4645 return (
status && ip_adapter == ip && netmask_adapter == netmask);
4653const IP_ADAPTER_INFO *
4679 for (i = 0; i < n; ++i)
4681 in_addr_t ip, netmask;
4717 if (highest_netmask)
4719 *highest_netmask = 0;
4725 for (i = 0; i < n; ++i)
4727 in_addr_t adapter_ip, adapter_netmask;
4730 if (adapter_ip && adapter_netmask && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))
4732 if (highest_netmask && adapter_netmask > *highest_netmask)
4734 *highest_netmask = adapter_netmask;
4752 in_addr_t highest_netmask = 0;
4753 int lowest_metric = INT_MAX;
4768 if (first || hn > highest_netmask)
4770 highest_netmask = hn;
4773 lowest_metric = metric;
4782 else if (hn == highest_netmask)
4788 if (metric >= 0 && metric < lowest_metric)
4791 lowest_metric = metric;
4798 dmsg(
D_ROUTE_DEBUG,
"DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d metric=%d",
4802 count ? *count : -1,
4812 *netmask = highest_netmask;
4824#define DHCP_STATUS_UNDEF 0
4825#define DHCP_STATUS_ENABLED 1
4826#define DHCP_STATUS_DISABLED 2
4839 if (ai->DhcpEnabled)
4865 const IP_ADDR_STRING *ip = &a->IpAddressList;
4869 const DWORD
context = ip->Context;
4871 if ((
status = DeleteIPAddress((ULONG)
context)) == NO_ERROR)
4873 msg(
M_INFO,
"Successfully deleted previously set dynamic IP/netmask: %s/%s",
4874 ip->IpAddress.String,
4879 const char *empty =
"0.0.0.0";
4880 if (strcmp(ip->IpAddress.String, empty)
4881 || strcmp(ip->IpMask.String, empty))
4883 msg(
M_INFO,
"NOTE: could not delete previously set dynamic IP/netmask: %s/%s (status=%u)",
4884 ip->IpAddress.String,
4904 swprintf(wbuf,
SIZE(wbuf), L
"\\DEVICE\\TCPIP_%hs", guid);
4905 if (GetAdapterIndex(wbuf, &aindex) != NO_ERROR)
4911 index = (DWORD)aindex;
4926 if (!strcmp(guid,
list->AdapterName))
4928 index =
list->Index;
4949 msg(
M_INFO,
"NOTE: could not get adapter index for %s", guid);
4963 buf_printf(&out,
"%s", ip->IpAddress.String);
4964 if (
strlen(ip->IpMask.String))
5017 msg(msglev,
"SYSTEM ADAPTER LIST");
5020 const IP_ADAPTER_INFO *a;
5023 for (a = ai; a != NULL; a = a->Next)
5046 msg(
M_ERR,
"Error: init SA failed");
5049 status = SetKernelObjectSecurity(hand, DACL_SECURITY_INFORMATION, &
sa.sd);
5052 msg(
M_ERRNO,
"Error: SetKernelObjectSecurity failed on %s", device_path);
5066 const char *device_guid = NULL;
5068 uint8_t actual_buffer[256];
5069 char device_path[256];
5080 msg(
M_FATAL,
"TAP-Windows adapter '%s' not found", dev_node);
5084 snprintf(device_path,
sizeof(device_path),
"%s%s%s",
5095 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
5099 if (hand == INVALID_HANDLE_VALUE)
5101 msg(
M_ERR,
"CreateFile failed on TAP device: %s", device_path);
5109 int device_number = 0;
5116 sizeof(actual_buffer),
5128 snprintf(device_path,
sizeof(device_path),
"%s%s%s",
5139 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
5143 if (hand == INVALID_HANDLE_VALUE)
5145 msg(
M_WARN,
"CreateFile failed on TAP device: %s", device_path);
5171 DWORD
status = IpReleaseAddress((IP_ADAPTER_INDEX_MAP *)inter);
5179 msg(
M_WARN,
"NOTE: Release of DHCP-assigned IP address lease on TAP-Windows adapter failed: %s (code=%u)",
5211 DWORD
status = IpRenewAddress((IP_ADAPTER_INDEX_MAP *)inter);
5219 msg(
M_WARN,
"WARNING: Failed to renew DHCP IP address lease on TAP-Windows adapter: %s (code=%u)",
5245 for (i = 0; i < n; ++i)
5259 msg(msglevel,
"%s: command failed", prefix);
5272 const char err[] =
"ERROR: Windows ipconfig command failed";
5301 const char *ip_str = src->IpAddress.String;
5303 bool succeed =
false;
5309 if (!ip_str || !strlen(ip_str))
5314 ip =
getaddr(getaddr_flags, ip_str, 0, &succeed, NULL);
5328 msg(
M_INFO,
"ip_addr_string_to_array [%d]", *dest_len);
5329 for (i = 0; i < *dest_len; ++i)
5342 int a2len =
SIZE(a2);
5352 for (i = 0; i < a1len; ++i)
5370 for (i = 0; i < len; ++i)
5388 DWORD adapter_index)
5400 for (
int i = 0; i < addr_len; ++i)
5402 const char *fmt = (i == 0) ?
5403 "%s%s interface ipv6 set dns %lu static %s"
5404 :
"%s%s interface ipv6 add dns %lu %s";
5425 const in_addr_t *addr_list,
5427 const IP_ADDR_STRING *current,
5428 DWORD adapter_index,
5429 const bool test_first)
5433 bool delete_first =
false;
5434 bool is_dns = !strcmp(type,
"dns");
5441 delete_first =
true;
5446 delete_first =
true;
5464 for (i = 0; i < addr_len; ++i)
5468 const char *fmt = count ?
5469 "%s%s interface ip add %s %lu %s"
5470 :
"%s%s interface ip set %s %lu static %s";
5492 msg(
M_INFO,
"NETSH: %lu %s %s [already set]",
5512 dest[0].Next = NULL;
5517 dest[0].Next = &dest[1];
5518 dest[1].Next = NULL;
5524 DWORD adapter_index,
5526 const in_addr_t netmask,
5527 const unsigned int flags)
5531 const IP_ADAPTER_INFO *ai = NULL;
5532 const IP_PER_ADAPTER_INFO *pai = NULL;
5545 msg(
M_INFO,
"NETSH: %lu %s/%s [already set]",
5567 IP_ADDR_STRING wins[2];
5574 pai ? &pai->DnsServerList : NULL,
5577 if (ai && ai->HaveWins)
5601 "%s%s interface ip set address %lu dhcp",
5636 msg(
M_NONFATAL,
"TUN: enabling dhcp using service failed: %s [status=%u if_index=%d]",
5641 msg(
M_INFO,
"DHCP enabled on interface %d using service",
dhcp.iface.index);
5656 MIB_IPINTERFACE_ROW ipiface;
5657 InitializeIpInterfaceEntry(&ipiface);
5658 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
5659 ipiface.Family = family;
5660 ipiface.InterfaceIndex = iface_index;
5661 if (family == AF_INET6 && mtu < 1280)
5663 msg(
M_INFO,
"NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
5666 err = GetIpInterfaceEntry(&ipiface);
5667 if (err == NO_ERROR)
5669 if (family == AF_INET)
5671 ipiface.SitePrefixLength = 0;
5673 ipiface.NlMtu = mtu;
5674 err = SetIpInterfaceEntry(&ipiface);
5677 if (err != NO_ERROR)
5679 msg(
M_WARN,
"TUN: Setting %s mtu failed: %s [status=%lu if_index=%d]",
5684 msg(
M_INFO,
"%s MTU set to %d on interface %d using SetIpInterfaceEntry()", family_name, mtu, iface_index);
5722 return BSTR(&actual);
5736 tt->standby_iter = 0;
5748 msg(
M_INFO,
"NOTE: now trying netsh (this may take some time)");
5752 tt->adapter_netmask,
5774 msg(
M_WARN,
"write_dhcp_u8: buffer overflow building DHCP options");
5793 msg(
M_WARN,
"write_dhcp_u32_array: buffer overflow building DHCP options");
5799 msg(
M_WARN,
"write_dhcp_u32_array: size (%d) must be > 0 and <= 255", size);
5804 for (
i = 0;
i <
len; ++
i)
5818 msg(
M_WARN,
"write_dhcp_str: buffer overflow building DHCP options");
5824 msg(
M_WARN,
"write_dhcp_str: string '%s' must be > 0 bytes and <= 255 bytes",
str);
5856 msg(
M_WARN,
"write_dhcp_search_str: temp buffer overflow building DHCP options");
5868 if (*
ptr ==
'.' || *
ptr ==
'\0')
5886 msg(
M_WARN,
"write_search_dhcp_str: buffer overflow building DHCP options");
5892 msg(
M_WARN,
"write_dhcp_search_str: search domain string must be <= 255 bytes");
5910 if (
o->netbios_scope)
5915 if (
o->netbios_node_type)
5925 if (
o->domain_search_list_len > 0)
5928 o->domain_search_list_len,
5939 msg(
M_WARN,
"build_dhcp_options_string: buffer overflow building DHCP options");
5954 if (
tt->options.dhcp_pre_release ||
tt->options.dhcp_renew)
5962 if (
tt->options.dhcp_pre_release)
5966 if (
tt->options.dhcp_renew)
5980 HANDLE msg_channel =
tt->options.msg_channel;
5994 msg(
M_WARN,
"Register_dns failed using service: %s [status=0x%x]",
6000 msg(
M_INFO,
"Register_dns request sent to the service");
6033 msg(
M_NONFATAL,
"Register ring buffers failed using service: %s [status=0x%x]",
6039 msg(
M_INFO,
"Ring buffers registered via service");
6059 buf_printf(&
cmd,
"openvpn --verb %d --register-dns --rdns-internal", verb);
6073 dsa = (local | (~netmask)) + offset;
6077 dsa = (local & netmask) + offset;
6082 msg(
M_FATAL,
"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",
print_in_addr_t(dsa, 0, &
gc));
6085 if ((local & netmask) != (dsa & netmask))
6087 msg(
M_FATAL,
"ERROR: --ip-win32 dynamic [offset] : offset is outside of --ifconfig subnet");
6100 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_VERSION,
6101 &info,
sizeof(info),
6102 &info,
sizeof(info), &len, NULL))
6107 (info[2] ?
"(DEBUG)" :
""));
6110 if (!(info[0] == TAP_WIN_MIN_MAJOR && info[1] >= TAP_WIN_MIN_MINOR))
6112 msg(
M_FATAL,
"ERROR: This version of " PACKAGE_NAME
" requires a TAP-Windows driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME
" distribution, a reboot is probably required at this point to get Windows to see the new driver.",
6121 && info[0] == 9 && info[1] < 8)
6123 msg(
M_INFO,
"WARNING: Tap-Win32 driver version %d.%d does not support IPv6 in TUN mode. IPv6 will not work. Upgrade your Tap-Win32 driver.", (
int)info[0], (
int)info[1]);
6129 && info[0] == 9 && info[1] == 8)
6131 msg(
M_FATAL,
"ERROR: Tap-Win32 driver version %d.%d is buggy regarding small IPv4 packets in TUN mode. Upgrade your Tap-Win32 driver.", (
int)info[0], (
int)info[1]);
6140 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_MTU,
6142 &mtu,
sizeof(mtu), &len, NULL))
6150 const char *device_guid,
6151 bool dhcp_masq_post)
6172 .iface = {.index = index, .name =
"" }
6183 status = FlushIpNetTable(index);
6188 msg(
M_INFO,
"Successful ARP Flush on interface [%lu] %s",
6194 msg(
D_TUNTAP_INFO,
"NOTE: FlushIpNetTable failed on interface [%lu] %s (status=%lu) : %s",
6211 msg(
M_WARN,
"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'");
6233 const char *error_suffix =
"I am having trouble using the Windows 'IP helper API' to automatically set the IP address -- consider using other --ip-win32 methods (not 'ipapi')";
6238 msg(
M_FATAL,
"ERROR: unable to get adapter index for interface %s -- %s",
6246 msg(
M_WARN,
"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'");
6260 msg(
M_INFO,
"Succeeded in adding a temporary IP/netmask of %s/%s to interface %s using the Win32 IP Helper API",
6268 msg(
M_FATAL,
"ERROR: AddIPAddress %s/%s failed on interface %s, index=%lu, status=%lu (windows error: '%s') -- %s",
6289 FILE_MAP_ALL_ACCESS,
6295 FILE_MAP_ALL_ACCESS,
6312 switch (GetLastError())
6314 case ERROR_ACCESS_DENIED:
6315 msg(
M_FATAL,
"ERROR: Wintun requires SYSTEM privileges and therefore "
6316 "should be used with interactive service. If you want to "
6317 "use openvpn from command line, you need to do SYSTEM "
6318 "elevation yourself (for example with psexec).");
6321 case ERROR_ALREADY_INITIALIZED:
6322 msg(
M_NONFATAL,
"Adapter %s is already in use", device_guid);
6340 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_SET_MEDIA_STATUS,
6344 msg(
M_WARN,
"WARNING: The TAP-Windows driver rejected a TAP_WIN_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
6350 msg(
M_INFO,
"Sleeping for %d seconds...", s);
6363 msg(
M_FATAL,
"ERROR: --dev tun also requires --ifconfig");
6374 ep[0] = htonl(tt->
local);
6378 status = DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_TUN,
6380 ep,
sizeof(ep), &len, NULL);
6388 status ?
"SUCCEEDED" :
"FAILED");
6393 status ?
"SUCCEEDED" :
"FAILED");
6399 ep[0] = htonl(tt->
local);
6402 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT,
6404 ep,
sizeof(ep), &len, NULL))
6406 msg(
M_FATAL,
"ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun");
6421 ep[0] = htonl(tt->
local);
6447#ifndef SIMULATE_DHCP_FAILED
6448 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_DHCP_MASQ,
6450 ep,
sizeof(ep), &len, NULL))
6452 msg(
M_FATAL,
"ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode");
6455 msg(
M_INFO,
"Notified TAP-Windows driver to set a DHCP IP/netmask of %s/%s on interface %s [DHCP-serv: %s, lease-time: %d]",
6474 msg(
M_FATAL,
"ERROR: The TAP-Windows driver rejected a TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call");
6479 msg(
M_WARN,
"DHCP option string not set due to error");
6527 snprintf(tuntap_device_path,
sizeof(tuntap_device_path),
"%s%s%s",
6531 path = tuntap_device_path;
6536 tt->
hand = CreateFile(path,
6537 GENERIC_READ | GENERIC_WRITE,
6541 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
6543 if (tt->
hand == INVALID_HANDLE_VALUE)
6554 msg(
D_TUNTAP_INFO,
"Failed to register %s adapter ring buffers", device_guid);
6555 CloseHandle(tt->
hand);
6570 uint8_t actual_buffer[256];
6586 msg(
M_FATAL,
"Adapter '%s' not found", dev_node);
6591 msg(
M_FATAL,
"Adapter '%s' is using %s driver, %s expected. If you want to use this device, adjust --windows-driver.",
6602 int device_number = 0;
6610 sizeof(actual_buffer),
6664 *dhcp_masq_post =
true;
6689 bool dhcp_masq =
false;
6690 bool dhcp_masq_post =
false;
6731open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
6737 msg(
M_WARN,
"Some --dhcp-option or --dns options require DHCP server,"
6738 " which is not supported by the selected %s driver. They will be"
6748 const char *device_guid = NULL;
6816 "%s%s interface %s delete dns %lu all",
6819 ipv6 ?
"ipv6" :
"ipv4",
6827 "%s%s interface ipv4 delete winsservers %lu all",
6853 "%s%s interface %s delete address %lu %s store=active",
6856 ipv6 ?
"ipv6" :
"ipv4",
6872 if (!CancelIo(tt->
hand))
6874 msg(
M_WARN |
M_ERRNO,
"Warning: CancelIO failed on %s adapter", adaptertype);
6878 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped read event on %s adapter", adaptertype);
6881 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped write event on %s adapter", adaptertype);
6887 if (!CloseHandle(tt->
hand))
6889 msg(
M_WARN |
M_ERRNO,
"Warning: CloseHandle failed on %s adapter", adaptertype);
6973 msg(
M_WARN,
"Warning: DeleteIPAddress[%u] failed on TAP-Windows adapter, status=%u : %s",
7029 return "[unknown --ip-win32 type]";
7058open_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)
@ msg_register_ring_buffers
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)
static bool register_ring_buffers(HANDLE device, struct tun_ring *send_ring, struct tun_ring *receive_ring, HANDLE send_tail_moved, HANDLE receive_tail_moved)
Registers ring buffers used to exchange data between userspace openvpn process and wintun kernel driv...
int netmask_to_netbits2(in_addr_t netmask)
bool add_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
bool add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
void get_default_gateway(struct route_gateway_info *rgi, in_addr_t dest, openvpn_net_ctx_t *ctx)
Retrieves the best gateway for a given destination based on the routing table.
void delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt, const struct env_set *es, openvpn_net_ctx_t *ctx)
void route_ipv6_clear_host_bits(struct route_ipv6 *r6)
#define RT_METRIC_DEFINED
#define RGI_NETMASK_DEFINED
int openvpn_execve_check(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message)
int sockethandle_finalize(sockethandle_t sh, struct overlapped_io *io, struct buffer *buf, struct link_socket_actual *from)
const char * print_in6_addr(struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
in_addr_t getaddr(unsigned int flags, const char *hostname, int resolve_retry_seconds, bool *succeeded, struct signal_info *sig_info)
Translate an IPv4 addr or hostname from string form to in_addr_t.
#define GETADDR_HOST_ORDER
#define GETADDR_FATAL_ON_SIGNAL
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
Wintun ring buffer See https://github.com/WireGuard/wintun#ring-layout.
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
struct rw_handle rw_handle
enum tun_driver_type backend_driver
The backend driver that used for this tun/tap device.
HANDLE wintun_receive_ring_handle
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 tun_ring * wintun_receive_ring
struct overlapped_io reads
struct in6_addr local_ipv6
HANDLE wintun_send_ring_handle
struct tun_ring * wintun_send_ring
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
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 bool service_register_ring_buffers(const struct tuntap *tt)
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)
static bool wintun_register_ring_buffer(struct tuntap *tt, const char *device_guid)
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 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
#define WINTUN_COMPONENT_ID
@ 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)
int win32_version_info(void)
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