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