64 return "tap-windows6";
88const static GUID
GUID_DEVCLASS_NET = { 0x4d36e972L, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 } };
89const static GUID
GUID_DEVINTERFACE_NET = { 0xcac88484, 0x7515, 0x4c03, { 0x82, 0xe6, 0x71, 0xa8, 0x7a, 0xba, 0xc3, 0x61 } };
93#define NI_TEST_FIRST (1<<0)
94#define NI_IP_NETMASK (1<<1)
95#define NI_OPTIONS (1<<2)
100 const in_addr_t netmask,
101 const unsigned int flags);
109 DWORD adapter_index);
113static void exec_command(
const char *prefix,
const struct argv *a,
int n,
int msglevel);
141 if (addr.
family == AF_INET)
146 add ?
"add" :
"remove",
154 add ?
"add" :
"remove",
165 msg(
M_WARN,
"TUN: %s address failed using service: %s [status=%u if_index=%d]",
216 size_t dstlen = strlen(
dns.domains);
218 size_t extra = dstlen ? 2 : 1;
219 if (dstlen + srclen + extra >
sizeof(
dns.domains))
221 msg(
M_WARN,
"DNS search domains sent to service truncated to %d", i);
226 dns.domains[dstlen++] =
',';
231 msg(
D_LOW,
"%s DNS domains on '%s' (if_index = %d) using service",
232 (add ?
"Setting" :
"Deleting"),
dns.iface.name,
dns.iface.index);
240 msg(
M_WARN,
"TUN: %s DNS domains failed using service: %s [status=%u if_name=%s]",
246 msg(
M_INFO,
"DNS domains %s using service", (add ?
"set" :
"deleted"));
259 int addr_len = add ? len : 0;
260 const char *ip_proto_name = family == AF_INET6 ?
"IPv6" :
"IPv4";
285 if (addr_len > _countof(dns.
addr))
287 addr_len = _countof(dns.
addr);
289 msg(
M_WARN,
"Number of %s DNS addresses sent to service truncated to %d",
290 ip_proto_name, addr_len);
293 for (
int i = 0; i < addr_len; ++i)
295 if (family == AF_INET6)
305 msg(
D_LOW,
"%s %s dns servers on '%s' (if_index = %d) using service",
315 msg(
M_WARN,
"TUN: %s %s dns failed using service: %s [status=%u if_name=%s]",
321 msg(
M_INFO,
"%s dns servers %s using service", ip_proto_name, (add ?
"set" :
"deleted"));
355 if (addr_len > _countof(wins.
addr))
357 addr_len = _countof(wins.
addr);
359 msg(
M_WARN,
"Number of WINS addresses sent to service truncated to %d",
363 for (
int i = 0; i < addr_len; ++i)
368 msg(
D_LOW,
"%s WINS servers on '%s' (if_index = %d) using service",
378 msg(
M_WARN,
"TUN: %s WINS failed using service: %s [status=%u if_name=%s]",
384 msg(
M_INFO,
"WINS servers %s using service", (add ?
"set" :
"deleted"));
397 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
409 if (family == AF_INET6 && mtu < 1280)
411 msg(
M_INFO,
"NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
421 msg(
M_NONFATAL,
"TUN: setting %s mtu using service failed: %s [status=%u if_index=%d]",
426 msg(
M_INFO,
"%s MTU set to %d on interface %d using service", family_name, mtu, mtu_msg.
iface.
index);
444 argv_printf(&
argv,
"%s%s nicconfig where (InterfaceIndex=%ld) call SetDNSDomain '%s'",
498 msg(
M_NONFATAL,
"TUN: creating %s adapter using service failed: %s [status=%u]",
515static void solaris_error_close(
struct tuntap *tt,
const struct env_set *
es,
const char *actual,
bool unplumb_inet6);
520#if defined(TARGET_DARWIN)
521#include <sys/kern_control.h>
522#include <net/if_utun.h>
523#include <sys/sys_domain.h>
529is_dev_type(
const char *dev,
const char *dev_type,
const char *match_type)
538 return !strcmp(dev_type, match_type);
542 return !strncmp(dev, match_type, strlen(match_type));
577 return "[unknown-dev-type]";
587 const char *dev_type,
588 const char *dev_node,
618 const bool looks_like_netmask = ((addr & 0xFF000000) == 0xFF000000);
621 if (looks_like_netmask)
623 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",
630 if (!looks_like_netmask)
632 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",
648 in_addr_t remote_netmask)
652 msg(
M_INFO,
"CHECK_ADDR_CLASH type=%d public=%s local=%s, remote_netmask=%s",
663 const in_addr_t test_netmask = 0xFFFFFF00;
664 const in_addr_t public_net =
public &test_netmask;
665 const in_addr_t local_net = local & test_netmask;
666 const in_addr_t remote_net = remote_netmask & test_netmask;
668 if (
public == local ||
public == remote_netmask)
671 "WARNING: --%s address [%s] conflicts with --ifconfig address pair [%s, %s]. %s",
679 if (public_net == local_net || public_net == remote_net)
682 "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",
692 const in_addr_t public_network =
public &remote_netmask;
693 const in_addr_t virtual_network = local & remote_netmask;
694 if (public_network == virtual_network)
697 "WARNING: --%s address [%s] conflicts with --ifconfig subnet [%s, %s] -- local and remote addresses cannot be inside of the --ifconfig subnet. %s",
717 if ((rgi.
flags & needed) == needed)
720 if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100)
722 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.");
736 if (
tt->did_ifconfig_setup && !disable)
821 msg(
M_FATAL,
"Error: problem with tun vs. tap setting");
846 setenv_str(
es,
"ifconfig_remote", ifconfig_remote_netmask);
850 setenv_str(
es,
"ifconfig_netmask", ifconfig_remote_netmask);
859 setenv_str(
es,
"ifconfig_ipv6_local", ifconfig_ipv6_local);
861 setenv_str(
es,
"ifconfig_ipv6_remote", ifconfig_ipv6_remote);
875 const char *dev_type,
877 const char *ifconfig_local_parm,
878 const char *ifconfig_remote_netmask_parm,
879 const char *ifconfig_ipv6_local_parm,
880 int ifconfig_ipv6_netbits_parm,
881 const char *ifconfig_ipv6_remote_parm,
882 struct addrinfo *local_public,
883 struct addrinfo *remote_public,
884 const bool strict_warn,
898 if (ifconfig_local_parm && ifconfig_remote_netmask_parm)
924 ifconfig_remote_netmask_parm,
934 struct addrinfo *curele;
942 for (curele = local_public; curele; curele = curele->ai_next)
944 if (curele->ai_family == AF_INET)
946 const in_addr_t local = ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
955 for (curele = remote_public; curele; curele = curele->ai_next)
957 if (curele->ai_family == AF_INET)
959 const in_addr_t remote = ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
988 if (ifconfig_ipv6_local_parm && ifconfig_ipv6_remote_parm)
995 if (inet_pton( AF_INET6, ifconfig_ipv6_local_parm, &tt->
local_ipv6 ) != 1
996 || inet_pton( AF_INET6, ifconfig_ipv6_remote_parm, &tt->
remote_ipv6 ) != 1)
998 msg(
M_FATAL,
"init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary", ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm );
1079#if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
1080 || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD)
1091create_arbitrary_remote(
struct tuntap *tt )
1097 if (remote == tt->
local)
1119#if !defined(TARGET_LINUX)
1125#if defined(TARGET_LINUX)
1126 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1128 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1131 if (net_iface_up(ctx, ifname,
true) < 0)
1133 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1136 if (net_addr_v6_add(ctx, ifname, &tt->
local_ipv6,
1139 msg(
M_FATAL,
"Linux can't add IPv6 to interface %s", ifname);
1141#elif defined(TARGET_ANDROID)
1144 snprintf(out6,
sizeof(out6),
"%s/%d %d",
1146 management_android_control(
management,
"IFCONFIG6", out6);
1147#elif defined(TARGET_SOLARIS)
1157 IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
1167 "Solaris ifconfig IPv6 (prepare) failed"))
1169 solaris_error_close(tt,
es, ifname,
true);
1188 solaris_error_close(tt,
es, ifname,
true);
1198#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
1199 || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
1200 || defined(TARGET_DRAGONFLY)
1201 argv_printf(&
argv,
"%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
1206 "generic BSD ifconfig inet6 failed");
1208#if defined(TARGET_FREEBSD) && __FreeBSD_version >= 1200000 \
1209 && __FreeBSD_version < 1300000
1229 "FreeBSD BSD 'ifconfig inet6 -ifdisabled' failed");
1232#elif defined(TARGET_AIX)
1233 argv_printf(&
argv,
"%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
1242 "generic BSD ifconfig inet6 failed");
1245#elif defined (_WIN32)
1248 msg(
M_INFO,
"******** NOTE: Please manually set the v6 IP of '%s' to %s (if it is not already set)",
1249 ifname, ifconfig_ipv6_local);
1278 argv_printf(&
argv,
"%s%s interface ipv6 set address %lu %s/%d store=active",
1280 ifconfig_ipv6_local, netbits);
1296 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.");
1299#if !defined(TARGET_LINUX)
1318#if !defined(_WIN32) && !defined(TARGET_ANDROID)
1325#if !defined(TARGET_LINUX)
1326 const char *ifconfig_local = NULL;
1327 const char *ifconfig_remote_netmask = NULL;
1338#if defined(TARGET_LINUX)
1339 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1341 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1344 if (net_iface_up(ctx, ifname,
true) < 0)
1346 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1351 if (net_addr_ptp_v4_add(ctx, ifname, &tt->
local,
1354 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1359 if (net_addr_v4_add(ctx, ifname, &tt->
local,
1362 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1365#elif defined(TARGET_ANDROID)
1368 snprintf(out,
sizeof(out),
"%s %s %d %s", ifconfig_local,
1370 management_android_control(
management,
"IFCONFIG", out);
1372#elif defined(TARGET_SOLARIS)
1381 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1386 solaris_error_close(tt,
es, ifname,
false);
1395 ifname, ifconfig_local, ifconfig_local,
1396 ifconfig_remote_netmask, tun_mtu);
1401 IFCONFIG_PATH, ifname, ifconfig_local,
1402 ifconfig_remote_netmask);
1408 solaris_error_close(tt,
es, ifname,
false);
1424#elif defined(TARGET_OPENBSD)
1426 in_addr_t remote_end;
1438 "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
1439 IFCONFIG_PATH, ifname, ifconfig_local,
1440 ifconfig_remote_netmask, tun_mtu);
1444 remote_end = create_arbitrary_remote( tt );
1446 IFCONFIG_PATH, ifname, ifconfig_local,
1448 ifconfig_remote_netmask);
1453 IFCONFIG_PATH, ifname, ifconfig_local,
1454 ifconfig_remote_netmask, tun_mtu);
1471#elif defined(TARGET_NETBSD)
1472 in_addr_t remote_end = INADDR_ANY;
1477 IFCONFIG_PATH, ifname, ifconfig_local,
1478 ifconfig_remote_netmask, tun_mtu);
1482 remote_end = create_arbitrary_remote(tt);
1485 tun_mtu, ifconfig_remote_netmask);
1495 IFCONFIG_PATH, ifname, ifconfig_local,
1496 ifconfig_remote_netmask, tun_mtu);
1513#elif defined(TARGET_DARWIN)
1522 "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
1529 IFCONFIG_PATH, ifname, ifconfig_local,
1530 ifconfig_remote_netmask, tun_mtu);
1535 IFCONFIG_PATH, ifname, ifconfig_local, ifconfig_local,
1536 ifconfig_remote_netmask, tun_mtu);
1541 ifname, ifconfig_local, ifconfig_remote_netmask,
1560#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1566 IFCONFIG_PATH, ifname, ifconfig_local,
1567 ifconfig_remote_netmask, tun_mtu);
1573 ifname, ifconfig_local, netbits, tun_mtu );
1579#elif defined(TARGET_AIX)
1587 msg(
M_FATAL,
"no tun support on AIX (canthappen)");
1592 ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1599#elif defined (_WIN32)
1603 "******** NOTE: Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
1604 ifname, ifconfig_local,
1605 ifconfig_remote_netmask);
1638#elif defined(TARGET_HAIKU)
1641 ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1646 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.");
1649#if !defined(TARGET_LINUX)
1663#ifdef ENABLE_MANAGEMENT
1693#if defined(TARGET_LINUX)
1701 msg(
M_WARN,
"Linux can't del IP from iface %s",
1709 msg(
M_WARN,
"Linux can't del IP from iface %s",
1713#elif defined(TARGET_FREEBSD)
1732#if defined(TARGET_LINUX)
1738#elif defined(TARGET_FREEBSD)
1784#ifdef TARGET_SOLARIS
1789#if defined(TARGET_OPENBSD) || defined(TARGET_DARWIN)
1809#include <netinet/ip.h>
1813header_modify_read_write_return(
int len)
1817 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
1826write_tun_header(
struct tuntap *tt, uint8_t *buf,
int len)
1838 type = htonl(AF_INET6);
1842 type = htonl(AF_INET);
1845 iv[0].iov_base = &type;
1846 iv[0].iov_len =
sizeof(type);
1847 iv[1].iov_base = buf;
1848 iv[1].iov_len = len;
1850 return header_modify_read_write_return(writev(tt->fd, iv, 2));
1854 return write(tt->fd, buf, len);
1859read_tun_header(
struct tuntap *tt, uint8_t *buf,
int len)
1866 iv[0].iov_base = &type;
1867 iv[0].iov_len =
sizeof(type);
1868 iv[1].iov_base = buf;
1869 iv[1].iov_len = len;
1871 return header_modify_read_write_return(readv(tt->fd, iv, 2));
1875 return read(tt->fd, buf, len);
1886#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1888tun_dco_enabled(
struct tuntap *tt)
1895#if !(defined(_WIN32) || defined(TARGET_LINUX) || defined(TARGET_SOLARIS))
1897open_tun_generic(
const char *dev,
const char *dev_type,
const char *dev_node,
1901 char dynamic_name[256];
1902 bool dynamic_opened =
false;
1909 snprintf(tunname,
sizeof(tunname),
"%s", dev_node);
1921 for (
int i = 0; i < 256; ++i)
1925#if defined(TARGET_HAIKU)
1928 snprintf(tunname,
sizeof(tunname),
1929 "/dev/%s%s%d", dev, sep, i);
1930 snprintf(dynamic_name,
sizeof(dynamic_name),
1931 "%s%s%d", dev, sep, i);
1932 if ((tt->fd = open(tunname, O_RDWR)) > 0)
1934 dynamic_opened =
true;
1939 if (!dynamic_opened)
1941 msg(
M_FATAL,
"Cannot allocate TUN/TAP dev dynamically");
1949 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
1953 if (!dynamic_opened)
1956 if (if_nametoindex( dev ) > 0)
1958 msg(
M_INFO,
"TUN/TAP device %s exists previously, keep at program end", dev );
1962 if ((tt->fd = open(tunname, O_RDWR)) < 0)
1964 msg(
M_ERR,
"Cannot open TUN/TAP dev %s", tunname);
1970 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
1978#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1980open_tun_dco_generic(
const char *dev,
const char *dev_type,
1983 char dynamic_name[256];
1984 bool dynamic_opened =
false;
1994 if (strcmp(dev,
"tun") == 0)
1996 for (
int i = 0; i < 256; ++i)
1998 snprintf(dynamic_name,
sizeof(dynamic_name),
2003 dynamic_opened =
true;
2004 msg(
M_INFO,
"DCO device %s opened", dynamic_name);
2008 else if (ret == -EPERM)
2013 if (!dynamic_opened)
2015 msg(
M_FATAL,
"Cannot allocate DCO dev dynamically");
2029 msg(
M_INFO,
"DCO device %s already exists, won't be destroyed at shutdown",
2035 msg(
M_ERR,
"Cannot open DCO device %s: %s (%d)", dev,
2036 strerror(-ret), ret);
2040 msg(
M_INFO,
"DCO device %s opened", dev);
2049#if !(defined(_WIN32) || defined(TARGET_SOLARIS))
2051close_tun_generic(
struct tuntap *tt)
2063#if defined (TARGET_ANDROID)
2065open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2068#define ANDROID_TUNNAME "vpnservice-tun"
2073 int oldtunfd = tt->fd;
2079 management_android_control(
management,
"DNS6SERVER",
2085 management_android_control(
management,
"DNSSERVER",
2097 buf_printf(&buf,
"%s %d",
tt->options.http_proxy,
tt->options.http_proxy_port);
2127 msg(
M_ERR,
"ERROR: Cannot open TUN");
2154#elif defined(TARGET_LINUX)
2156#ifndef HAVE_LINUX_SOCKIOS_H
2157#error header file linux/sockios.h required
2163open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *
tt,
2168 if (tun_dco_enabled(tt))
2170 open_tun_dco_generic(dev, dev_type, tt, ctx);
2177 const char *node = dev_node;
2180 node =
"/dev/net/tun";
2186 if ((tt->fd = open(node, O_RDWR)) < 0)
2188 msg(
M_ERR,
"ERROR: Cannot open TUN/TAP dev %s", node);
2195 ifr.ifr_flags = IFF_NO_PI;
2197#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2198 ifr.ifr_flags |= IFF_ONE_QUEUE;
2206 ifr.ifr_flags |= IFF_TUN;
2210 ifr.ifr_flags |= IFF_TAP;
2214 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device",
2221 if (strcmp(dev,
"tun") && strcmp(dev,
"tap"))
2230 if (ioctl(tt->fd, TUNSETIFF, (
void *) &ifr) < 0)
2232 msg(
M_ERR,
"ERROR: Cannot ioctl TUNSETIFF %s", dev);
2235 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2240#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2243 struct ifreq netifr;
2246 if ((ctl_fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
2249 strncpynt(netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
2250 netifr.ifr_qlen = tt->
options.txqueuelen;
2251 if (ioctl(ctl_fd, SIOCSIFTXQLEN, (
void *) &netifr) >= 0)
2257 msg(
M_WARN |
M_ERRNO,
"Note: Cannot set tx queue length on %s", ifr.ifr_name);
2263 msg(
M_WARN |
M_ERRNO,
"Note: Cannot open control socket on %s", ifr.ifr_name);
2278open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2286#ifdef ENABLE_FEATURE_TUN_PERSIST
2290#define TUNSETGROUP _IOW('T', 206, int)
2294tuncfg(
const char *dev,
const char *dev_type,
const char *dev_node,
2295 int persist_mode,
const char *username,
const char *groupname,
2305 open_tun(dev, dev_type, dev_node, tt, ctx);
2306 if (ioctl(tt->fd, TUNSETPERSIST, persist_mode) < 0)
2308 msg(
M_ERR,
"Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
2310 if (username != NULL)
2316 msg(
M_ERR,
"Cannot get user entry for %s", username);
2320 msg(
M_ERR,
"Cannot ioctl TUNSETOWNER(%s) %s", username, dev);
2323 if (groupname != NULL)
2329 msg(
M_ERR,
"Cannot get group entry for %s", groupname);
2333 msg(
M_ERR,
"Cannot ioctl TUNSETGROUP(%s) %s", groupname, dev);
2337 msg(
M_INFO,
"Persist state set to: %s", (persist_mode ?
"ON" :
"OFF"));
2347#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
2348 if (tun_dco_enabled(tt))
2353 close_tun_generic(tt);
2360 return write(tt->fd, buf, len);
2366 return read(tt->fd, buf, len);
2369#elif defined(TARGET_SOLARIS)
2372#error I need the symbol TUNNEWPPA from net/if_tun.h
2376open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2379 int if_fd = -1, ip_muxid = -1, arp_muxid = -1, arp_fd = -1, ppa = -1;
2382 const char *ip_node = NULL, *arp_node = NULL;
2383 const char *dev_tuntap_type;
2385 struct strioctl strioc_if, strioc_ppa;
2395 ip_node =
"/dev/udp";
2398 dev_node =
"/dev/tun";
2400 dev_tuntap_type =
"tun";
2401 link_type = I_PLINK;
2405 ip_node =
"/dev/udp";
2408 dev_node =
"/dev/tap";
2410 arp_node = dev_node;
2411 dev_tuntap_type =
"tap";
2412 link_type = I_PLINK;
2416 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device",
2420 if ((tt->ip_fd = open(ip_node, O_RDWR, 0)) < 0)
2422 msg(
M_ERR,
"Can't open %s", ip_node);
2425 if ((tt->fd = open(dev_node, O_RDWR, 0)) < 0)
2427 msg(
M_ERR,
"Can't open %s", dev_node);
2435 while (*ptr && !isdigit((
int) *ptr))
2443 strioc_ppa.ic_cmd = TUNNEWPPA;
2444 strioc_ppa.ic_timout = 0;
2445 strioc_ppa.ic_len =
sizeof(ppa);
2446 strioc_ppa.ic_dp = (
char *)&ppa;
2450 bool found_one =
false;
2451 while (!found_one && ppa < 64)
2453 int new_ppa = ioctl(tt->fd, I_STR, &strioc_ppa);
2456 msg(
M_INFO,
"open_tun: got dynamic interface '%s%d'", dev_tuntap_type, new_ppa );
2461 if (errno != EEXIST)
2463 msg(
M_ERR,
"open_tun: unexpected error trying to find free %s interface", dev_tuntap_type );
2469 msg(
M_ERR,
"open_tun: could not find free %s interface, give up.", dev_tuntap_type );
2474 if ((ppa = ioctl(tt->fd, I_STR, &strioc_ppa)) < 0)
2476 msg(
M_ERR,
"Can't assign PPA for new interface (%s%d)", dev_tuntap_type, ppa );
2480 if ((if_fd = open(dev_node, O_RDWR, 0)) < 0)
2482 msg(
M_ERR,
"Can't open %s (2)", dev_node);
2485 if (ioctl(if_fd, I_PUSH,
"ip") < 0)
2487 msg(
M_ERR,
"Can't push IP module");
2493 if (ioctl(if_fd, IF_UNITSEL, (
char *) &ppa) < 0)
2495 msg(
M_ERR,
"Can't set PPA %d", ppa);
2502 snprintf(tt->
actual_name, 32,
"%s%d", dev_tuntap_type, ppa);
2506 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2513 if (ioctl(if_fd, SIOCSLIFNAME, &ifr) < 0)
2515 msg(
M_ERR,
"Can't set PPA %d", ppa);
2517 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
2522 if (ioctl(if_fd, I_PUSH,
"arp") < 0)
2524 msg(
M_ERR,
"Can't push ARP module");
2530 if (ioctl(tt->ip_fd, I_POP, NULL) < 0)
2536 if (ioctl(tt->ip_fd, I_PUSH,
"arp") < 0)
2538 msg(
M_ERR,
"Can't push ARP module\n");
2542 if ((arp_fd = open(arp_node, O_RDWR, 0)) < 0)
2544 msg(
M_ERR,
"Can't open %s\n", arp_node);
2547 if (ioctl(arp_fd, I_PUSH,
"arp") < 0)
2549 msg(
M_ERR,
"Can't push ARP module\n");
2553 strioc_if.ic_cmd = SIOCSLIFNAME;
2554 strioc_if.ic_timout = 0;
2555 strioc_if.ic_len =
sizeof(ifr);
2556 strioc_if.ic_dp = (
char *)𝔦
2557 if (ioctl(arp_fd, I_STR, &strioc_if) < 0)
2559 msg(
M_ERR,
"Can't set ifname to arp\n");
2563 if ((ip_muxid = ioctl(tt->ip_fd, link_type, if_fd)) < 0)
2565 msg(
M_ERR,
"Can't link %s device to IP", dev_tuntap_type);
2570 if ((arp_muxid = ioctl(tt->ip_fd, link_type, arp_fd)) < 0)
2572 msg(
M_ERR,
"Can't link %s device to ARP", dev_tuntap_type);
2579 ifr.lifr_ip_muxid = ip_muxid;
2582 ifr.lifr_arp_muxid = arp_muxid;
2585 if (ioctl(tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0)
2589 ioctl(tt->ip_fd, I_PUNLINK, arp_muxid);
2591 ioctl(tt->ip_fd, I_PUNLINK, ip_muxid);
2592 msg(
M_ERR,
"Can't set multiplexor id");
2603solaris_close_tun(
struct tuntap *tt)
2622 if (ioctl(tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0)
2627 if (ioctl(tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0)
2634 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0)
2640 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0)
2664 solaris_close_tun(tt);
2674 const char *actual,
bool unplumb_inet6 )
2681 IFCONFIG_PATH, actual );
2703 sbuf.buf = (
char *)buf;
2704 return putmsg(tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
2714 sbuf.buf = (
char *)buf;
2715 return getmsg(tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
2718#elif defined(TARGET_OPENBSD)
2721open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2724 open_tun_generic(dev, dev_type, dev_node, tt);
2729 struct tuninfo info;
2731 if (ioctl(tt->fd, TUNGIFINFO, &info) < 0)
2737 info.flags |= IFF_MULTICAST;
2740 if (ioctl(tt->fd, TUNSIFINFO, &info) < 0)
2765 close_tun_generic(tt);
2778 close_tun_generic(tt);
2790 return write_tun_header(tt, buf, len);
2796 return read_tun_header(tt, buf, len);
2799#elif defined(TARGET_NETBSD)
2816open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2823 if (strcmp(dev,
"tap") == 0)
2826 if ((tt->fd = open(
"/dev/tap", O_RDWR)) < 0)
2828 msg(
M_FATAL,
"Cannot allocate NetBSD TAP dev dynamically");
2830 if (ioctl( tt->fd, TAPGIFNAME, (
void *)&ifr ) < 0)
2832 msg(
M_FATAL,
"Cannot query NetBSD TAP device name");
2836 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2845 open_tun_generic(dev, dev_type, dev_node, tt);
2850 int i = IFF_POINTOPOINT|IFF_MULTICAST;
2851 ioctl(tt->fd, TUNSIFMODE, &i);
2853 ioctl(tt->fd, TUNSLMODE, &i);
2858 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0)
2879 close_tun_generic(tt);
2892 close_tun_generic(tt);
2902netbsd_modify_read_write_return(
int len)
2906 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
2927 type = htonl(AF_INET6);
2931 type = htonl(AF_INET);
2934 iv[0].iov_base = (
char *)&type;
2935 iv[0].iov_len =
sizeof(type);
2936 iv[1].iov_base = buf;
2937 iv[1].iov_len = len;
2939 return netbsd_modify_read_write_return(writev(tt->fd, iv, 2));
2943 return write(tt->fd, buf, len);
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 netbsd_modify_read_write_return(readv(tt->fd, iv, 2));
2964 return read(tt->fd, buf, len);
2968#elif defined(TARGET_FREEBSD)
2971freebsd_modify_read_write_return(
int len)
2975 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
2984open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2987 if (tun_dco_enabled(tt))
2989 open_tun_dco_generic(dev, dev_type, tt, ctx);
2993 open_tun_generic(dev, dev_type, dev_node, tt);
2998 int i = IFF_POINTOPOINT | IFF_MULTICAST;
3001 i = IFF_BROADCAST | IFF_MULTICAST;
3004 if (ioctl(tt->fd, TUNSIFMODE, &i) < 0)
3011 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0)
3033 close_tun_generic(tt);
3047 close_tun_generic(tt);
3051 "FreeBSD 'destroy tun interface' failed (non-critical)");
3066 iph = (
struct ip *) buf;
3070 type = htonl(AF_INET6);
3074 type = htonl(AF_INET);
3077 iv[0].iov_base = (
char *)&type;
3078 iv[0].iov_len =
sizeof(type);
3079 iv[1].iov_base = buf;
3080 iv[1].iov_len = len;
3082 return freebsd_modify_read_write_return(writev(tt->fd, iv, 2));
3086 return write(tt->fd, buf, len);
3098 iv[0].iov_base = (
char *)&type;
3099 iv[0].iov_len =
sizeof(type);
3100 iv[1].iov_base = buf;
3101 iv[1].iov_len = len;
3103 return freebsd_modify_read_write_return(readv(tt->fd, iv, 2));
3107 return read(tt->fd, buf, len);
3111#elif defined(TARGET_DRAGONFLY)
3114dragonfly_modify_read_write_return(
int len)
3118 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
3127open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3130 open_tun_generic(dev, dev_type, dev_node, tt);
3137 ioctl(tt->fd, TUNSLMODE, &i);
3139 ioctl(tt->fd, TUNSIFHEAD, &i);
3148 close_tun_generic(tt);
3161 iph = (
struct ip *) buf;
3165 type = htonl(AF_INET6);
3169 type = htonl(AF_INET);
3172 iv[0].iov_base = (
char *)&type;
3173 iv[0].iov_len =
sizeof(type);
3174 iv[1].iov_base = buf;
3175 iv[1].iov_len = len;
3177 return dragonfly_modify_read_write_return(writev(tt->fd, iv, 2));
3181 return write(tt->fd, buf, len);
3193 iv[0].iov_base = (
char *)&type;
3194 iv[0].iov_len =
sizeof(type);
3195 iv[1].iov_base = buf;
3196 iv[1].iov_len = len;
3198 return dragonfly_modify_read_write_return(readv(tt->fd, iv, 2));
3202 return read(tt->fd, buf, len);
3206#elif defined(TARGET_DARWIN)
3228utun_open_helper(
struct ctl_info ctlInfo,
int utunnum)
3230 struct sockaddr_ctl sc;
3233 fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
3242 if (ioctl(fd, CTLIOCGINFO, &ctlInfo) == -1)
3251 sc.sc_id = ctlInfo.ctl_id;
3252 sc.sc_len =
sizeof(sc);
3253 sc.sc_family = AF_SYSTEM;
3254 sc.ss_sysaddr = AF_SYS_CONTROL;
3256 sc.sc_unit = utunnum+1;
3262 if (connect(fd, (
struct sockaddr *)&sc,
sizeof(sc)) < 0)
3277open_darwin_utun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt)
3279 struct ctl_info ctlInfo;
3283 socklen_t utunname_len =
sizeof(utunname);
3287 if (dev_node && (strcmp(
"utun", dev_node) != 0 ))
3289 if (sscanf(dev_node,
"utun%d", &utunnum) != 1)
3291 msg(
M_FATAL,
"Cannot parse 'dev-node %s' please use 'dev-node utunX'"
3292 "to use a utun device number X", dev_node);
3299 if (strlcpy(ctlInfo.ctl_name, UTUN_CONTROL_NAME,
sizeof(ctlInfo.ctl_name)) >=
3300 sizeof(ctlInfo.ctl_name))
3302 msg(
M_ERR,
"Opening utun: UTUN_CONTROL_NAME too long");
3308 for (utunnum = 0; utunnum < 255; utunnum++)
3312 ASSERT(snprintf(ifname,
sizeof(ifname),
"utun%d", utunnum) > 0);
3313 if (if_nametoindex(ifname))
3317 fd = utun_open_helper(ctlInfo, utunnum);
3328 fd = utun_open_helper(ctlInfo, utunnum);
3340 if (getsockopt(fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, utunname, &utunname_len))
3347 msg(
M_INFO,
"Opened utun device %s", utunname);
3352open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3357 || (dev_node && !strncmp(dev_node,
"utun", 4)))
3364 msg(
M_FATAL,
"Cannot use utun devices with --dev-type %s",
3370 open_darwin_utun(dev, dev_type, dev_node, tt);
3377 msg(
M_INFO,
"Failed to open utun device. Falling back to /dev/tun device");
3378 open_tun_generic(dev, dev_type, NULL, tt);
3395 if (dev_node && strcmp(dev_node,
"tun")==0)
3400 open_tun_generic(dev, dev_type, dev_node, tt);
3414 const char *ifconfig_ipv6_local =
3418 ROUTE_PATH, ifconfig_ipv6_local );
3423 close_tun_generic(tt);
3434 return write_tun_header(tt, buf, len);
3438 return write(tt->fd, buf, len);
3447 return read_tun_header(tt, buf, len);
3451 return read(tt->fd, buf, len);
3455#elif defined(TARGET_AIX)
3458open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3462 char dynamic_name[20];
3467 msg(
M_FATAL,
"no support for 'tun' devices on AIX" );
3470 if (strncmp( dev,
"tap", 3 ) != 0 || dev_node)
3472 msg(
M_FATAL,
"'--dev %s' and/or '--dev-node' not supported on AIX, use '--dev tap0', 'tap1', etc.", dev );
3475 if (strcmp( dev,
"tap" ) == 0)
3478 for (i = 0; i<99; i++)
3480 snprintf(tunname,
sizeof(tunname),
"/dev/tap%d", i);
3481 if (access( tunname, F_OK ) < 0 && errno == ENOENT)
3488 msg(
M_FATAL,
"cannot find unused tap device" );
3491 snprintf( dynamic_name,
sizeof(dynamic_name),
"tap%d", i );
3498 while (isdigit(*p) )
3504 msg(
M_FATAL,
"TAP device name must be '--dev tapNNNN'" );
3507 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
3512 if (access( tunname, F_OK ) < 0 && errno == ENOENT)
3532 if ((tt->fd = open(tunname, O_RDWR)) < 0)
3534 msg(
M_ERR,
"Cannot open TAP device '%s'", tunname);
3539 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
3568 close_tun_generic(tt);
3581 return write(tt->fd, buf, len);
3587 return read(tt->fd, buf, len);
3590#elif defined(_WIN32)
3632 err = GetLastError();
3633 if (err == ERROR_IO_PENDING)
3689 dmsg(
D_WIN32_IO,
"WIN32 I/O: TAP Write immediate return [%d,%d]",
3695 err = GetLastError();
3696 if (err == ERROR_IO_PENDING)
3730 err = GetLastError();
3748 HDEVINFO dev_info_set;
3753 dev_info_set = SetupDiGetClassDevsEx(&
GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
3754 if (dev_info_set == INVALID_HANDLE_VALUE)
3756 err = GetLastError();
3761 for (DWORD i = 0;; ++i)
3763 SP_DEVINFO_DATA device_info_data;
3766 char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3768 char device_instance_id[256];
3772 ULONG dev_interface_list_size;
3775 ZeroMemory(&device_info_data,
sizeof(SP_DEVINFO_DATA));
3776 device_info_data.cbSize =
sizeof(SP_DEVINFO_DATA);
3777 res = SetupDiEnumDeviceInfo(dev_info_set, i, &device_info_data);
3780 if (GetLastError() == ERROR_NO_MORE_ITEMS)
3790 dev_key = SetupDiOpenDevRegKey(dev_info_set, &device_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE);
3791 if (dev_key == INVALID_HANDLE_VALUE)
3798 status = RegQueryValueEx(dev_key,
3799 net_cfg_instance_id_string,
3804 if (
status != ERROR_SUCCESS)
3809 len =
sizeof(device_instance_id);
3810 res = SetupDiGetDeviceInstanceId(dev_info_set, &device_info_data, device_instance_id, len, &len);
3816 cr = CM_Get_Device_Interface_List_Size(&dev_interface_list_size,
3819 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3821 if (cr != CR_SUCCESS)
3826 char *dev_interface_list =
gc_malloc(dev_interface_list_size,
false,
gc);
3829 dev_interface_list_size,
3830 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3831 if (cr != CR_SUCCESS)
3836 char *dev_if = dev_interface_list;
3839 while (strlen(dev_if) > 0)
3857 last->
next = dev_iif;
3861 dev_if += strlen(dev_if) + 1;
3865 RegCloseKey(dev_key);
3868 SetupDiDestroyDeviceInfoList(dev_info_set);
3890 if (
status != ERROR_SUCCESS)
3892 msg(
M_FATAL,
"Error opening registry key: %s", ADAPTER_KEY);
3898 char enum_name[256];
3899 char unit_string[256];
3901 char component_id_string[] =
"ComponentId";
3902 char component_id[256];
3903 char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3904 BYTE net_cfg_instance_id[256];
3907 len =
sizeof(enum_name);
3917 if (
status == ERROR_NO_MORE_ITEMS)
3921 else if (
status != ERROR_SUCCESS)
3923 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s",
3927 snprintf(unit_string,
sizeof(unit_string),
"%s\\%s",
3928 ADAPTER_KEY, enum_name);
3937 if (
status != ERROR_SUCCESS)
3943 len =
sizeof(component_id);
3944 status = RegQueryValueEx(
3946 component_id_string,
3949 (LPBYTE)component_id,
3952 if (
status != ERROR_SUCCESS || data_type != REG_SZ)
3955 unit_string, component_id_string);
3959 len =
sizeof(net_cfg_instance_id);
3960 status = RegQueryValueEx(
3962 net_cfg_instance_id_string,
3965 net_cfg_instance_id,
3968 if (
status == ERROR_SUCCESS && data_type == REG_SZ)
3972 if (strcasecmp(component_id, TAP_WIN_COMPONENT_ID) == 0
3973 || strcasecmp(component_id,
"root\\" TAP_WIN_COMPONENT_ID) == 0)
3977 else if (strcasecmp(component_id,
"ovpn-dco") == 0)
4005 RegCloseKey(unit_key);
4010 RegCloseKey(adapter_key);
4018 HKEY network_connections_key;
4026 NETWORK_CONNECTIONS_KEY,
4029 &network_connections_key);
4031 if (
status != ERROR_SUCCESS)
4033 msg(
M_FATAL,
"Error opening registry key: %s", NETWORK_CONNECTIONS_KEY);
4038 char enum_name[256];
4039 char connection_string[256];
4040 HKEY connection_key;
4041 WCHAR name_data[256];
4043 const WCHAR name_string[] = L
"Name";
4045 len =
sizeof(enum_name);
4047 network_connections_key,
4055 if (
status == ERROR_NO_MORE_ITEMS)
4059 else if (
status != ERROR_SUCCESS)
4061 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s",
4062 NETWORK_CONNECTIONS_KEY);
4065 snprintf(connection_string,
sizeof(connection_string),
4066 "%s\\%s\\Connection",
4067 NETWORK_CONNECTIONS_KEY, enum_name);
4076 if (
status != ERROR_SUCCESS)
4078 dmsg(
D_REGISTRY,
"Error opening registry key: %s", connection_string);
4082 len =
sizeof(name_data);
4083 status = RegQueryValueExW(
4091 if (
status != ERROR_SUCCESS || name_type != REG_SZ)
4094 NETWORK_CONNECTIONS_KEY, connection_string, name_string);
4103 n = WideCharToMultiByte(CP_UTF8, 0, name_data, -1, NULL, 0, NULL, NULL);
4105 WideCharToMultiByte(CP_UTF8, 0, name_data, -1,
name, n, NULL, NULL);
4120 RegCloseKey(connection_key);
4125 RegCloseKey(network_connections_key);
4137 const unsigned int mask = 3;
4138 const char *err = NULL;
4140 if (local == remote)
4142 err =
"must be different";
4145 if ((local & (~mask)) != (remote & (~mask)))
4147 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";
4150 if ((local & mask) == 0
4151 || (local & mask) == 3
4152 || (remote & mask) == 0
4153 || (remote & mask) == 3)
4155 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";
4163 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.",
4176 printf(
"On Windows, point-to-point IP support (i.e. --dev tun)\n");
4177 printf(
"is emulated by the TAP-Windows driver. The major limitation\n");
4178 printf(
"imposed by this approach is that the --ifconfig local and\n");
4179 printf(
"remote endpoints must be part of the same 255.255.255.252\n");
4180 printf(
"subnet. The following list shows examples of endpoint\n");
4181 printf(
"pairs which satisfy this requirement. Only the final\n");
4182 printf(
"component of the IP address pairs is at issue.\n\n");
4183 printf(
"As an example, the following option would be correct:\n");
4184 printf(
" --ifconfig 10.7.0.5 10.7.0.6 (on host A)\n");
4185 printf(
" --ifconfig 10.7.0.6 10.7.0.5 (on host B)\n");
4186 printf(
"because [5,6] is part of the below list.\n\n");
4188 for (i = 0; i < 256; i += 4)
4190 printf(
"[%3d,%3d] ", i+1, i+2);
4208 bool warn_panel_null =
false;
4209 bool warn_panel_dup =
false;
4210 bool warn_tap_dup =
false;
4221 msg(msglev,
"Available adapters [name, GUID, driver]:");
4240 warn_panel_dup =
true;
4242 else if (links == 0)
4246 warn_panel_null =
true;
4247 msg(msglev,
"[NULL] %s", tr->
guid);
4256 if (tr != tr1 && !strcmp(tr->
guid, tr1->
guid))
4258 warn_tap_dup =
true;
4266 msg(warnlev,
"WARNING: Some TAP-Windows adapters have duplicate GUIDs");
4271 msg(warnlev,
"WARNING: Some TAP-Windows adapters have duplicate links from the Network Connections control panel");
4274 if (warn_panel_null)
4276 msg(warnlev,
"WARNING: Some TAP-Windows adapters have no link from the Network Connections control panel");
4338 msg(
M_FATAL,
"There are no TAP-Windows or ovpn-dco adapters "
4339 "on this system. You should be able to create an adapter "
4340 "by using tapctl.exe utility.");
4350 uint8_t *actual_name,
4351 int actual_name_size,
4352 const struct tap_reg *tap_reg_src,
4403 if (windows_driver !=
NULL)
4436 ASSERT(actual_name_size > 0);
4482const IP_ADAPTER_INFO *
4486 IP_ADAPTER_INFO *pi = NULL;
4489 if ((
status = GetAdaptersInfo(NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4491 msg(
M_INFO,
"GetAdaptersInfo #1 failed (status=%u) : %s",
4497 pi = (PIP_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4498 if ((
status = GetAdaptersInfo(pi, &size)) != NO_ERROR)
4500 msg(
M_INFO,
"GetAdaptersInfo #2 failed (status=%u) : %s",
4509const IP_PER_ADAPTER_INFO *
4513 IP_PER_ADAPTER_INFO *pi = NULL;
4518 if ((
status = GetPerAdapterInfo(index, NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4520 msg(
M_INFO,
"GetPerAdapterInfo #1 failed (status=%u) : %s",
4526 pi = (PIP_PER_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4527 if ((
status = GetPerAdapterInfo((ULONG)index, pi, &size)) == ERROR_SUCCESS)
4533 msg(
M_INFO,
"GetPerAdapterInfo #2 failed (status=%u) : %s",
4542static const IP_INTERFACE_INFO *
4546 IP_INTERFACE_INFO *ii = NULL;
4549 if ((
status = GetInterfaceInfo(NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)
4551 msg(
M_INFO,
"GetInterfaceInfo #1 failed (status=%u) : %s",
4557 ii = (PIP_INTERFACE_INFO)
gc_malloc(size,
false,
gc);
4558 if ((
status = GetInterfaceInfo(ii, &size)) == NO_ERROR)
4564 msg(
M_INFO,
"GetInterfaceInfo #2 failed (status=%u) : %s",
4572static const IP_ADAPTER_INDEX_MAP *
4579 for (i = 0; i < list->NumAdapters; ++i)
4581 const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[i];
4582 if (index == inter->Index)
4596const IP_ADAPTER_INFO *
4601 const IP_ADAPTER_INFO *a;
4604 for (a = ai; a != NULL; a = a->Next)
4606 if (a->Index == index)
4615const IP_ADAPTER_INFO *
4627 const IP_ADDR_STRING *ip = &ai->IpAddressList;
4651 const IP_ADDR_STRING *iplist = &ai->IpAddressList;
4661 iplist = iplist->Next;
4667 const char *ip_str = iplist->IpAddress.String;
4668 const char *netmask_str = iplist->IpMask.String;
4669 bool succeed1 =
false;
4670 bool succeed2 =
false;
4672 if (ip_str && netmask_str && strlen(ip_str) && strlen(netmask_str))
4674 *ip =
getaddr(getaddr_flags, ip_str, 0, &succeed1, NULL);
4675 *netmask =
getaddr(getaddr_flags, netmask_str, 0, &succeed2, NULL);
4676 ret = (succeed1 ==
true && succeed2 ==
true);
4689 in_addr_t ip_adapter = 0;
4690 in_addr_t netmask_adapter = 0;
4692 return (
status && ip_adapter == ip && netmask_adapter == netmask);
4700const IP_ADAPTER_INFO *
4726 for (i = 0; i < n; ++i)
4728 in_addr_t ip, netmask;
4764 if (highest_netmask)
4766 *highest_netmask = 0;
4772 for (i = 0; i < n; ++i)
4774 in_addr_t adapter_ip, adapter_netmask;
4777 if (adapter_ip && adapter_netmask && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))
4779 if (highest_netmask && adapter_netmask > *highest_netmask)
4781 *highest_netmask = adapter_netmask;
4799 in_addr_t highest_netmask = 0;
4800 int lowest_metric = INT_MAX;
4815 if (first || hn > highest_netmask)
4817 highest_netmask = hn;
4820 lowest_metric = metric;
4829 else if (hn == highest_netmask)
4835 if (metric >= 0 && metric < lowest_metric)
4838 lowest_metric = metric;
4845 dmsg(
D_ROUTE_DEBUG,
"DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d metric=%d",
4849 count ? *count : -1,
4859 *netmask = highest_netmask;
4871#define DHCP_STATUS_UNDEF 0
4872#define DHCP_STATUS_ENABLED 1
4873#define DHCP_STATUS_DISABLED 2
4886 if (ai->DhcpEnabled)
4912 const IP_ADDR_STRING *ip = &a->IpAddressList;
4916 const DWORD
context = ip->Context;
4918 if ((
status = DeleteIPAddress((ULONG)
context)) == NO_ERROR)
4920 msg(
M_INFO,
"Successfully deleted previously set dynamic IP/netmask: %s/%s",
4921 ip->IpAddress.String,
4926 const char *empty =
"0.0.0.0";
4927 if (strcmp(ip->IpAddress.String, empty)
4928 || strcmp(ip->IpMask.String, empty))
4930 msg(
M_INFO,
"NOTE: could not delete previously set dynamic IP/netmask: %s/%s (status=%u)",
4931 ip->IpAddress.String,
4951 swprintf(wbuf,
SIZE(wbuf), L
"\\DEVICE\\TCPIP_%hs", guid);
4952 if (GetAdapterIndex(wbuf, &aindex) != NO_ERROR)
4958 index = (DWORD)aindex;
4973 if (!strcmp(guid,
list->AdapterName))
4975 index =
list->Index;
4996 msg(
M_INFO,
"NOTE: could not get adapter index for %s", guid);
5010 buf_printf(&out,
"%s", ip->IpAddress.String);
5011 if (
strlen(ip->IpMask.String))
5064 msg(msglev,
"SYSTEM ADAPTER LIST");
5067 const IP_ADAPTER_INFO *a;
5070 for (a = ai; a != NULL; a = a->Next)
5093 msg(
M_ERR,
"Error: init SA failed");
5096 status = SetKernelObjectSecurity(hand, DACL_SECURITY_INFORMATION, &
sa.sd);
5099 msg(
M_ERRNO,
"Error: SetKernelObjectSecurity failed on %s", device_path);
5113 const char *device_guid = NULL;
5115 uint8_t actual_buffer[256];
5116 char device_path[256];
5127 msg(
M_FATAL,
"TAP-Windows adapter '%s' not found", dev_node);
5131 snprintf(device_path,
sizeof(device_path),
"%s%s%s",
5142 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
5146 if (hand == INVALID_HANDLE_VALUE)
5148 msg(
M_ERR,
"CreateFile failed on TAP device: %s", device_path);
5156 int device_number = 0;
5163 sizeof(actual_buffer),
5175 snprintf(device_path,
sizeof(device_path),
"%s%s%s",
5186 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
5190 if (hand == INVALID_HANDLE_VALUE)
5192 msg(
M_WARN,
"CreateFile failed on TAP device: %s", device_path);
5218 DWORD
status = IpReleaseAddress((IP_ADAPTER_INDEX_MAP *)inter);
5226 msg(
M_WARN,
"NOTE: Release of DHCP-assigned IP address lease on TAP-Windows adapter failed: %s (code=%u)",
5258 DWORD
status = IpRenewAddress((IP_ADAPTER_INDEX_MAP *)inter);
5266 msg(
M_WARN,
"WARNING: Failed to renew DHCP IP address lease on TAP-Windows adapter: %s (code=%u)",
5292 for (i = 0; i < n; ++i)
5306 msg(msglevel,
"%s: command failed", prefix);
5319 const char err[] =
"ERROR: Windows ipconfig command failed";
5348 const char *ip_str = src->IpAddress.String;
5350 bool succeed =
false;
5356 if (!ip_str || !strlen(ip_str))
5361 ip =
getaddr(getaddr_flags, ip_str, 0, &succeed, NULL);
5375 msg(
M_INFO,
"ip_addr_string_to_array [%d]", *dest_len);
5376 for (i = 0; i < *dest_len; ++i)
5389 int a2len =
SIZE(a2);
5399 for (i = 0; i < a1len; ++i)
5417 for (i = 0; i < len; ++i)
5435 DWORD adapter_index)
5447 for (
int i = 0; i < addr_len; ++i)
5449 const char *fmt = (i == 0) ?
5450 "%s%s interface ipv6 set dns %lu static %s"
5451 :
"%s%s interface ipv6 add dns %lu %s";
5469 const in_addr_t *addr_list,
5471 const IP_ADDR_STRING *current,
5472 DWORD adapter_index,
5473 const bool test_first)
5477 bool delete_first =
false;
5478 bool is_dns = !strcmp(type,
"dns");
5485 delete_first =
true;
5490 delete_first =
true;
5508 for (i = 0; i < addr_len; ++i)
5512 const char *fmt = count ?
5513 "%s%s interface ip add %s %lu %s"
5514 :
"%s%s interface ip set %s %lu static %s";
5535 msg(
M_INFO,
"NETSH: %lu %s %s [already set]",
5555 dest[0].Next = NULL;
5560 dest[0].Next = &dest[1];
5561 dest[1].Next = NULL;
5567 DWORD adapter_index,
5569 const in_addr_t netmask,
5570 const unsigned int flags)
5574 const IP_ADAPTER_INFO *ai = NULL;
5575 const IP_PER_ADAPTER_INFO *pai = NULL;
5588 msg(
M_INFO,
"NETSH: %lu %s/%s [already set]",
5610 IP_ADDR_STRING wins[2];
5617 pai ? &pai->DnsServerList : NULL,
5620 if (ai && ai->HaveWins)
5644 "%s%s interface ip set address %lu dhcp",
5679 msg(
M_NONFATAL,
"TUN: enabling dhcp using service failed: %s [status=%u if_index=%d]",
5684 msg(
M_INFO,
"DHCP enabled on interface %d using service",
dhcp.iface.index);
5699 MIB_IPINTERFACE_ROW ipiface;
5700 InitializeIpInterfaceEntry(&ipiface);
5701 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
5702 ipiface.Family = family;
5703 ipiface.InterfaceIndex = iface_index;
5704 if (family == AF_INET6 && mtu < 1280)
5706 msg(
M_INFO,
"NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
5709 err = GetIpInterfaceEntry(&ipiface);
5710 if (err == NO_ERROR)
5712 if (family == AF_INET)
5714 ipiface.SitePrefixLength = 0;
5716 ipiface.NlMtu = mtu;
5717 err = SetIpInterfaceEntry(&ipiface);
5720 if (err != NO_ERROR)
5722 msg(
M_WARN,
"TUN: Setting %s mtu failed: %s [status=%lu if_index=%d]",
5727 msg(
M_INFO,
"%s MTU set to %d on interface %d using SetIpInterfaceEntry()", family_name, mtu, iface_index);
5765 return BSTR(&actual);
5779 tt->standby_iter = 0;
5791 msg(
M_INFO,
"NOTE: now trying netsh (this may take some time)");
5795 tt->adapter_netmask,
5817 msg(
M_WARN,
"write_dhcp_u8: buffer overflow building DHCP options");
5836 msg(
M_WARN,
"write_dhcp_u32_array: buffer overflow building DHCP options");
5842 msg(
M_WARN,
"write_dhcp_u32_array: size (%d) must be > 0 and <= 255", size);
5847 for (
i = 0;
i <
len; ++
i)
5861 msg(
M_WARN,
"write_dhcp_str: buffer overflow building DHCP options");
5867 msg(
M_WARN,
"write_dhcp_str: string '%s' must be > 0 bytes and <= 255 bytes",
str);
5899 msg(
M_WARN,
"write_dhcp_search_str: temp buffer overflow building DHCP options");
5911 if (*
ptr ==
'.' || *
ptr ==
'\0')
5929 msg(
M_WARN,
"write_search_dhcp_str: buffer overflow building DHCP options");
5935 msg(
M_WARN,
"write_dhcp_search_str: search domain string must be <= 255 bytes");
5953 if (
o->netbios_scope)
5958 if (
o->netbios_node_type)
5968 if (
o->domain_search_list_len > 0)
5971 o->domain_search_list_len,
5982 msg(
M_WARN,
"build_dhcp_options_string: buffer overflow building DHCP options");
5997 if (
tt->options.dhcp_pre_release ||
tt->options.dhcp_renew)
6005 if (
tt->options.dhcp_pre_release)
6009 if (
tt->options.dhcp_renew)
6023 HANDLE msg_channel =
tt->options.msg_channel;
6037 msg(
M_WARN,
"Register_dns failed using service: %s [status=0x%x]",
6043 msg(
M_INFO,
"Register_dns request sent to the service");
6062 buf_printf(&
cmd,
"openvpn --verb %d --register-dns --rdns-internal", verb);
6076 dsa = (local | (~netmask)) + offset;
6080 dsa = (local & netmask) + offset;
6085 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));
6088 if ((local & netmask) != (dsa & netmask))
6090 msg(
M_FATAL,
"ERROR: --ip-win32 dynamic [offset] : offset is outside of --ifconfig subnet");
6103 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_VERSION,
6104 &info,
sizeof(info),
6105 &info,
sizeof(info), &len, NULL))
6110 (info[2] ?
"(DEBUG)" :
""));
6113 if (!(info[0] == TAP_WIN_MIN_MAJOR && info[1] >= TAP_WIN_MIN_MINOR))
6115 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.",
6124 && info[0] == 9 && info[1] < 8)
6126 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]);
6132 && info[0] == 9 && info[1] == 8)
6134 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]);
6143 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_MTU,
6145 &mtu,
sizeof(mtu), &len, NULL))
6153 const char *device_guid,
6154 bool dhcp_masq_post)
6175 .iface = {.index = index, .name =
"" }
6186 status = FlushIpNetTable(index);
6191 msg(
M_INFO,
"Successful ARP Flush on interface [%lu] %s",
6197 msg(
D_TUNTAP_INFO,
"NOTE: FlushIpNetTable failed on interface [%lu] %s (status=%lu) : %s",
6214 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'");
6236 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')";
6241 msg(
M_FATAL,
"ERROR: unable to get adapter index for interface %s -- %s",
6249 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'");
6263 msg(
M_INFO,
"Succeeded in adding a temporary IP/netmask of %s/%s to interface %s using the Win32 IP Helper API",
6271 msg(
M_FATAL,
"ERROR: AddIPAddress %s/%s failed on interface %s, index=%lu, status=%lu (windows error: '%s') -- %s",
6291 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_SET_MEDIA_STATUS,
6295 msg(
M_WARN,
"WARNING: The TAP-Windows driver rejected a TAP_WIN_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
6301 msg(
M_INFO,
"Sleeping for %d seconds...", s);
6314 msg(
M_FATAL,
"ERROR: --dev tun also requires --ifconfig");
6325 ep[0] = htonl(tt->
local);
6329 status = DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_TUN,
6331 ep,
sizeof(ep), &len, NULL);
6339 status ?
"SUCCEEDED" :
"FAILED");
6344 status ?
"SUCCEEDED" :
"FAILED");
6350 ep[0] = htonl(tt->
local);
6353 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT,
6355 ep,
sizeof(ep), &len, NULL))
6357 msg(
M_FATAL,
"ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun");
6372 ep[0] = htonl(tt->
local);
6398#ifndef SIMULATE_DHCP_FAILED
6399 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_DHCP_MASQ,
6401 ep,
sizeof(ep), &len, NULL))
6403 msg(
M_FATAL,
"ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode");
6406 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]",
6425 msg(
M_FATAL,
"ERROR: The TAP-Windows driver rejected a TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call");
6430 msg(
M_WARN,
"DHCP option string not set due to error");
6477 snprintf(tuntap_device_path,
sizeof(tuntap_device_path),
"%s%s%s",
6481 path = tuntap_device_path;
6486 tt->
hand = CreateFile(path,
6487 GENERIC_READ | GENERIC_WRITE,
6491 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
6493 if (tt->
hand == INVALID_HANDLE_VALUE)
6509 uint8_t actual_buffer[256];
6523 msg(
M_FATAL,
"Adapter '%s' not found", dev_node);
6528 msg(
M_FATAL,
"Adapter '%s' is using %s driver, %s expected. If you want to use this device, adjust --windows-driver.",
6539 int device_number = 0;
6540 int adapters_created = 0;
6548 sizeof(actual_buffer),
6617 *dhcp_masq_post =
true;
6642 bool dhcp_masq =
false;
6643 bool dhcp_masq_post =
false;
6684open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
6690 msg(
M_WARN,
"Some --dhcp-option or --dns options require DHCP server,"
6691 " which is not supported by the selected %s driver. They will be"
6701 const char *device_guid = NULL;
6769 "%s%s interface %s delete dns %lu all",
6772 ipv6 ?
"ipv6" :
"ipv4",
6780 "%s%s interface ipv4 delete winsservers %lu all",
6806 "%s%s interface %s delete address %lu %s store=active",
6809 ipv6 ?
"ipv6" :
"ipv4",
6825 if (!CancelIo(tt->
hand))
6827 msg(
M_WARN |
M_ERRNO,
"Warning: CancelIO failed on %s adapter", adaptertype);
6831 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped read event on %s adapter", adaptertype);
6834 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped write event on %s adapter", adaptertype);
6840 if (!CloseHandle(tt->
hand))
6842 msg(
M_WARN |
M_ERRNO,
"Warning: CloseHandle failed on %s adapter", adaptertype);
6916 msg(
M_WARN,
"Warning: DeleteIPAddress[%u] failed on TAP-Windows adapter, status=%u : %s",
6972 return "[unknown --ip-win32 type]";
7001open_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)
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
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